static/shared: copy pkgsite static files

Static files are copied from x/pkgsite, so that the same styles can be
reused for the frontend.

Change-Id: I71291eb9c017bfbf2e9c40d9baf0dc65ebb274ec
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/464616
Run-TryBot: Julie Qiu <julieqiu@google.com>
Reviewed-by: Julie Qiu <julieqiu@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Julie Qiu <julieqiu@google.com>
diff --git a/static/shared/breadcrumb/breadcrumb.css b/static/shared/breadcrumb/breadcrumb.css
new file mode 100644
index 0000000..42f8dd3
--- /dev/null
+++ b/static/shared/breadcrumb/breadcrumb.css
@@ -0,0 +1,26 @@
+/*!
+ * 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.
+ */
+
+.go-Breadcrumb ol {
+  line-height: 1.5rem;
+  white-space: initial;
+}
+.go-Breadcrumb li {
+  align-items: center;
+  color: var(--color-text-subtle);
+  display: inline-flex;
+  font-size: 0.875rem;
+}
+.go-Breadcrumb li:not(:last-child)::after {
+  content: '>';
+  padding: 0 0.5rem;
+}
+.go-Breadcrumb li:last-child > a {
+  color: var(--color-text-subtle);
+}
+.go-Breadcrumb li > .go-Clipboard {
+  margin: 0 0.5rem;
+}
diff --git a/static/shared/breadcrumb/breadcrumb.md b/static/shared/breadcrumb/breadcrumb.md
new file mode 100644
index 0000000..0d69bac
--- /dev/null
+++ b/static/shared/breadcrumb/breadcrumb.md
@@ -0,0 +1,30 @@
+## Breadcrumbs
+
+---
+
+```html
+<nav class="go-Breadcrumb" aria-label="Breadcrumb">
+  <ol>
+    <li><a href="#" data-gtmc="breadcrumb link">Discover Packages</a></li>
+    <li><a href="#" data-gtmc="breadcrumb link">Standard Library</a></li>
+    <li><a href="#" data-gtmc="breadcrumb link">net</a></li>
+    <li>
+      <a href="#" data-gtmc="breadcrumb link" aria-current="location">http</a>
+      <button
+        class="go-Button go-Button--inline go-Clipboard js-clipboard"
+        aria-label="Copy Path to Clipboard"
+        data-to-copy="hello"
+        data-gtmc="clipboard button"
+      >
+        <img
+          class="go-Icon go-Icon--accented"
+          height="24"
+          width="24"
+          src="/static/shared/icon/content_copy_gm_grey_24dp.svg"
+          alt=""
+        />
+      </button>
+    </li>
+  </ol>
+</nav>
+```
diff --git a/static/shared/button/button.css b/static/shared/button/button.css
new file mode 100644
index 0000000..0a2f5bf
--- /dev/null
+++ b/static/shared/button/button.css
@@ -0,0 +1,86 @@
+/*!
+ * 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.
+ */
+
+button:focus:not([disabled]) {
+  border-color: var(--color-brand-primary);
+  -webkit-box-shadow: var(--focus-box-shadow);
+  box-shadow: var(--focus-box-shadow);
+  outline: transparent;
+}
+
+.go-Button {
+  align-items: center;
+  background-color: var(--color-button);
+  border: 0.0625rem solid transparent;
+  border-radius: var(--border-radius);
+  color: var(--color-button-text);
+  cursor: pointer;
+  display: inline-flex;
+  font-weight: 500;
+  gap: 0.25rem;
+}
+.go-Button:not(.go-Button--inline) {
+  padding: 0.5rem;
+}
+
+.go-Button--accented {
+  background-color: var(--color-button-accented);
+  color: var(--color-button-accented-text);
+}
+.go-Button--inverted,
+.go-Button--text,
+.go-Button--inline {
+  background-color: var(--color-button-inverted);
+  color: var(--color-button-inverted-text);
+}
+.go-Button--inline {
+  background-color: transparent;
+}
+
+.go-Button--inverted {
+  border: var(--border);
+}
+
+.go-Button:hover {
+  box-shadow: var(--focus-box-shadow);
+  filter: contrast(0.95);
+}
+.go-Button--inline:hover {
+  box-shadow: none;
+  text-decoration: underline var(--color-button-inverted-text);
+}
+.go-Button:focus {
+  filter: contrast(0.95);
+}
+.go-Button--inverted:focus {
+  border-color: var(--color-button-inverted-text);
+}
+.go-Button:active {
+  box-shadow: none;
+  filter: contrast(0.85);
+}
+
+.go-Button:disabled {
+  background-color: var(--color-button-disabled);
+  box-shadow: none;
+  color: var(--color-button-text-disabled);
+  cursor: initial;
+  filter: none;
+  text-decoration: none;
+}
+.go-Button--accented:disabled {
+  background-color: var(--color-button-accented-disabled);
+  color: var(--color-button-accented-text-disabled);
+}
+.go-Button--inverted:disabled,
+.go-Button--text:disabled,
+.go-Button--inline:disabled {
+  background-color: var(--color-button-inverted-disabled);
+  color: var(--color-button-inverted-text-disabled);
+}
+.go-Button--inline:disabled {
+  background-color: transparent;
+}
diff --git a/static/shared/button/button.md b/static/shared/button/button.md
new file mode 100644
index 0000000..36800b8
--- /dev/null
+++ b/static/shared/button/button.md
@@ -0,0 +1,53 @@
+## Buttons
+
+---
+
+### Primary {#button-primary}
+
+```html
+<button class="go-Button">Primary</button>
+```
+
+```html
+<button class="go-Button" disabled>Primary</button>
+```
+
+### Inverted {#button-inverted}
+
+```html
+<button class="go-Button go-Button--inverted">Inverted</button>
+```
+
+```html
+<button class="go-Button go-Button--inverted" disabled>Inverted</button>
+```
+
+### Accented {#button-accented}
+
+```html
+<button class="go-Button go-Button--accented">Accented</button>
+```
+
+```html
+<button class="go-Button go-Button--accented" disabled>Accented</button>
+```
+
+### Text {#button-text}
+
+```html
+<button class="go-Button go-Button--text">Text</button>
+```
+
+```html
+<button class="go-Button go-Button--text" disabled>Text</button>
+```
+
+### Inline {#button-inline}
+
+```html
+<button class="go-Button go-Button--inline">Inline</button>
+```
+
+```html
+<button class="go-Button go-Button--inline" disabled>Inline</button>
+```
diff --git a/static/shared/carousel/carousel.css b/static/shared/carousel/carousel.css
new file mode 100644
index 0000000..1c454e2
--- /dev/null
+++ b/static/shared/carousel/carousel.css
@@ -0,0 +1,73 @@
+/*!
+ * 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.
+ */
+
+.go-Carousel {
+  align-items: center;
+  display: flex;
+  flex-direction: column;
+  position: relative;
+  text-align: center;
+}
+.go-Carousel-slide {
+  margin: 0.5rem 3rem;
+}
+.go-Carousel-slide[aria-hidden] {
+  display: none;
+}
+.go-Carousel-prevSlide {
+  left: 0;
+}
+.go-Carousel-nextSlide {
+  right: 0;
+}
+.go-Carousel-prevSlide,
+.go-Carousel-nextSlide {
+  background-color: transparent;
+  border-radius: var(--border-radius);
+  font-size: 1.5rem;
+  height: 2.75rem;
+  margin-top: -1.375rem;
+  opacity: 0;
+  position: absolute;
+  top: 50%;
+  width: 2.75rem;
+}
+.go-Carousel-prevSlide:hover,
+.go-Carousel-nextSlide:hover {
+  background-color: var(--color-background-accented);
+  cursor: pointer;
+}
+.go-Carousel:hover .go-Carousel-prevSlide,
+.go-Carousel:hover .go-Carousel-nextSlide,
+.go-Carousel:focus-within .go-Carousel-prevSlide,
+.go-Carousel:focus-within .go-Carousel-nextSlide {
+  opacity: 1;
+}
+.go-Carousel-dots {
+  display: flex;
+  font-size: 0.4375rem;
+  gap: 0.5rem;
+}
+.go-Carousel-dot {
+  background-color: var(--color-border);
+  border-radius: 2rem;
+  height: 0.4375rem;
+  width: 0.4375rem;
+}
+.go-Carousel-dot--active,
+.go-Carousel-dot:hover {
+  background-color: var(--color-text-subtle);
+}
+.go-Carousel-obscured {
+  border: 0;
+  clip: rect(0 0 0 0);
+  height: 0.0625rem;
+  margin: -0.0625rem;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 0.0625rem;
+}
diff --git a/static/shared/carousel/carousel.md b/static/shared/carousel/carousel.md
new file mode 100644
index 0000000..03bf45d
--- /dev/null
+++ b/static/shared/carousel/carousel.md
@@ -0,0 +1,42 @@
+## Carousel
+
+---
+
+### With Heading
+
+```html
+<section class="go-Carousel js-carousel" data-slide-index="0">
+  <h5>Search Tips</h2>
+  <ul>
+    <li class="go-Carousel-slide">
+      <p>Search for a package by name, for example “logrus”</p>
+    </li>
+    <li class="go-Carousel-slide" aria-hidden>
+      <p>Search for a symbol by name, for example "sql.DB"</p>
+    </li>
+    <li class="go-Carousel-slide" aria-hidden>
+      <p>Search for a symbol in a path, for example "#error golang.org/x"</p>
+    </li>
+  </ul>
+</section>
+```
+
+### Aria Label
+
+Use aria-label to create an accessible label that is visually hidden.
+
+```html
+<section class="go-Carousel js-carousel" aria-label="Search Tips Carousel" data-slide-index="0">
+  <ul>
+    <li class="go-Carousel-slide">
+      <p>Search for a package by name, for example “logrus”</p>
+    </li>
+    <li class="go-Carousel-slide" aria-hidden>
+      <p>Search for a symbol by name, for example "sql.DB"</p>
+    </li>
+    <li class="go-Carousel-slide" aria-hidden>
+      <p>Search for a symbol in a path, for example "#error golang.org/x"</p>
+    </li>
+  </ul>
+</section>
+```
diff --git a/static/shared/carousel/carousel.test.ts b/static/shared/carousel/carousel.test.ts
new file mode 100644
index 0000000..b62b799
--- /dev/null
+++ b/static/shared/carousel/carousel.test.ts
@@ -0,0 +1,73 @@
+/**
+ * @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 { parse } from '../../markdown';
+import { CarouselController } from './carousel';
+
+describe('Tooltip', () => {
+  let carousel: HTMLDetailsElement;
+  let prevArrow: HTMLButtonElement;
+  let nextArrow: HTMLButtonElement;
+  let dots: HTMLElement[];
+  let slides: HTMLElement[];
+  let liveRegion: HTMLElement;
+
+  beforeEach(async () => {
+    document.body.innerHTML = await parse(__dirname + '/carousel.md');
+    carousel = document.querySelector('.js-carousel');
+    new CarouselController(carousel);
+    prevArrow = carousel.querySelector('.go-Carousel-prevSlide');
+    nextArrow = carousel.querySelector('.go-Carousel-nextSlide');
+    dots = Array.from(carousel.querySelectorAll('.go-Carousel-dot'));
+    slides = Array.from(carousel.querySelectorAll('.go-Carousel-slide'));
+    liveRegion = carousel.querySelector('[aria-live]');
+  });
+
+  afterEach(() => {
+    document.body.innerHTML = '';
+  });
+
+  it('generates arrows, dots, and live region', () => {
+    expect(prevArrow).toBeDefined();
+    expect(nextArrow).toBeDefined();
+    expect(dots).toBeDefined();
+    expect(liveRegion).toBeDefined();
+  });
+
+  it('shows only the first slide', () => {
+    expect(slides[0].getAttribute('aria-hidden')).toBeFalsy();
+    expect(slides[1].getAttribute('aria-hidden')).toBeTruthy();
+    expect(slides[2].getAttribute('aria-hidden')).toBeTruthy();
+  });
+
+  it('shows next slide on next arrow click', () => {
+    nextArrow.click();
+    expect(slides[0].getAttribute('aria-hidden')).toBeTruthy();
+    expect(slides[1].getAttribute('aria-hidden')).toBeFalsy();
+    expect(slides[2].getAttribute('aria-hidden')).toBeTruthy();
+  });
+
+  it('shows prev slide on prev arrow click', () => {
+    prevArrow.click();
+    expect(slides[0].getAttribute('aria-hidden')).toBeTruthy();
+    expect(slides[1].getAttribute('aria-hidden')).toBeTruthy();
+    expect(slides[2].getAttribute('aria-hidden')).toBeFalsy();
+  });
+
+  it('sets active slide on dot click', () => {
+    dots[1].click();
+    expect(slides[0].getAttribute('aria-hidden')).toBeTruthy();
+    expect(slides[1].getAttribute('aria-hidden')).toBeFalsy();
+    expect(slides[2].getAttribute('aria-hidden')).toBeTruthy();
+  });
+
+  it('updates live region', () => {
+    expect(liveRegion.textContent).toContain('Slide 1 of 3');
+    dots[1].click();
+    expect(liveRegion.textContent).toContain('Slide 2 of 3');
+  });
+});
diff --git a/static/shared/carousel/carousel.ts b/static/shared/carousel/carousel.ts
new file mode 100644
index 0000000..d311e4e
--- /dev/null
+++ b/static/shared/carousel/carousel.ts
@@ -0,0 +1,116 @@
+/**
+ * @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.
+ */
+
+/**
+ * Carousel Controller adds event listeners, accessibility enhancements, and
+ * control elements to a carousel component.
+ */
+export class CarouselController {
+  /**
+   * slides is a collection of slides in the carousel.
+   */
+  private slides: HTMLLIElement[];
+  /**
+   * dots is a collection of dot navigation controls, added to the carousel
+   * by this controller.
+   */
+  private dots: HTMLElement[];
+  /**
+   * liveRegion is a visually hidden element that notifies assitive devices
+   * of visual changes to the carousel. They are added to the carousel by
+   * this controller.
+   */
+  private liveRegion: HTMLElement;
+  /**
+   * activeIndex is the 0-index of the currently active slide.
+   */
+  private activeIndex: number;
+
+  constructor(private el: HTMLElement) {
+    this.slides = Array.from(el.querySelectorAll('.go-Carousel-slide'));
+    this.dots = [];
+    this.liveRegion = document.createElement('div');
+    this.activeIndex = Number(el.getAttribute('data-slide-index') ?? 0);
+
+    this.initSlides();
+    this.initArrows();
+    this.initDots();
+    this.initLiveRegion();
+  }
+
+  private initSlides() {
+    for (const [i, v] of this.slides.entries()) {
+      if (i === this.activeIndex) continue;
+      v.setAttribute('aria-hidden', 'true');
+    }
+  }
+
+  private initArrows() {
+    const arrows = document.createElement('ul');
+    arrows.classList.add('go-Carousel-arrows');
+    arrows.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>
+    `;
+    arrows
+      .querySelector('.go-Carousel-prevSlide')
+      ?.addEventListener('click', () => this.setActive(this.activeIndex - 1));
+    arrows
+      .querySelector('.go-Carousel-nextSlide')
+      ?.addEventListener('click', () => this.setActive(this.activeIndex + 1));
+    this.el.append(arrows);
+  }
+
+  private initDots() {
+    const dots = document.createElement('ul');
+    dots.classList.add('go-Carousel-dots');
+    for (let i = 0; i < this.slides.length; i++) {
+      const li = document.createElement('li');
+      const button = document.createElement('button');
+      button.classList.add('go-Carousel-dot');
+      if (i === this.activeIndex) {
+        button.classList.add('go-Carousel-dot--active');
+      }
+      button.innerHTML = `<span class="go-Carousel-obscured">Slide ${i + 1}</span>`;
+      button.addEventListener('click', () => this.setActive(i));
+      li.append(button);
+      dots.append(li);
+      this.dots.push(button);
+    }
+    this.el.append(dots);
+  }
+
+  private 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);
+  }
+
+  private setActive = (index: number) => {
+    this.activeIndex = (index + this.slides.length) % this.slides.length;
+    this.el.setAttribute('data-slide-index', String(this.activeIndex));
+    for (const d of this.dots) {
+      d.classList.remove('go-Carousel-dot--active');
+    }
+    this.dots[this.activeIndex].classList.add('go-Carousel-dot--active');
+    for (const s of this.slides) {
+      s.setAttribute('aria-hidden', 'true');
+    }
+    this.slides[this.activeIndex].removeAttribute('aria-hidden');
+    this.liveRegion.textContent = 'Slide ' + (this.activeIndex + 1) + ' of ' + this.slides.length;
+  };
+}
diff --git a/static/shared/chip/chip.css b/static/shared/chip/chip.css
new file mode 100644
index 0000000..6681cba
--- /dev/null
+++ b/static/shared/chip/chip.css
@@ -0,0 +1,44 @@
+/*!
+ * 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.
+ */
+
+.go-Chip {
+  background: var(--color-button);
+  border: 0.0625rem solid var(--color-button);
+  border-radius: 1.25rem;
+  color: var(--color-button-text);
+  font-size: 0.75rem;
+  padding: 0.125rem 0.625rem;
+}
+.go-Chip--accented {
+  background: var(--color-button-accented);
+  border: 0.0625rem solid var(--color-button-accented);
+  color: var(--color-button-accented-text);
+}
+.go-Chip--inverted {
+  background: var(--color-button-inverted);
+  border: var(--border);
+  color: var(--color-text);
+}
+.go-Chip--highlighted {
+  background: var(--color-background-highlighted-link);
+  border-color: var(--color-background-highlighted-link);
+  color: var(--color-brand-primary);
+}
+.go-Chip--alert {
+  background: var(--pink);
+  border: 0.0625rem solid var(--pink);
+  color: var(--color-text-inverted);
+}
+.go-Chip--vuln {
+  background: var(--pink-light);
+  border: 0.0625rem solid var(--pink-light);
+  color: var(--color-text-inverted);
+}
+.go-Chip--subtle {
+  background-color: var(--color-background-accented);
+  border-color: transparent;
+  color: var(--color-text-subtle);
+}
diff --git a/static/shared/chip/chip.md b/static/shared/chip/chip.md
new file mode 100644
index 0000000..27bb63b
--- /dev/null
+++ b/static/shared/chip/chip.md
@@ -0,0 +1,27 @@
+## Chips
+
+---
+
+```html #chip-primary
+<span class="go-Chip">Primary</span>
+```
+
+```html #chip-inverted
+<span class="go-Chip go-Chip--inverted">Inverted</span>
+```
+
+```html #chip-highlighted
+<span class="go-Chip go-Chip--highlighted">Highlighted</span>
+```
+
+```html #chip-warning
+<span class="go-Chip go-Chip--accented">Warning</span>
+```
+
+```html #chip-alert
+<span class="go-Chip go-Chip--alert">Alert</span>
+```
+
+```html #chip-subtle
+<span class="go-Chip go-Chip--subtle">Subtle</span>
+```
diff --git a/static/shared/clipboard/clipboard.css b/static/shared/clipboard/clipboard.css
new file mode 100644
index 0000000..6408d71
--- /dev/null
+++ b/static/shared/clipboard/clipboard.css
@@ -0,0 +1,42 @@
+/*!
+ * 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.
+ */
+
+.go-Clipboard {
+  position: relative;
+}
+.go-Clipboard::before {
+  background-color: var(--color-background-inverted);
+  border-radius: var(--border-radius);
+  color: var(--color-text-inverted);
+  content: attr(data-tooltip);
+  display: block;
+  font-size: 0.9em;
+  left: calc(100% + 0.125rem);
+  padding: 0.25rem 0.3rem;
+  position: absolute;
+  text-transform: uppercase;
+  top: 0.125rem;
+  white-space: nowrap;
+  z-index: 1000;
+}
+.go-Clipboard::after {
+  border-bottom: 0.25rem solid transparent;
+  border-left: 0;
+  border-right: 0.25rem solid var(--color-background-inverted);
+  border-top: 0.25rem solid transparent;
+  content: '';
+  display: block;
+  position: absolute;
+  right: -0.125rem;
+  top: 0.5625rem;
+  z-index: 1000;
+}
+.go-Clipboard:not([data-tooltip])::before,
+.go-Clipboard:not([data-tooltip])::after,
+.go-Clipboard[data-tooltip='']::before,
+.go-Clipboard[data-tooltip='']::after {
+  display: none;
+}
diff --git a/static/shared/clipboard/clipboard.md b/static/shared/clipboard/clipboard.md
new file mode 100644
index 0000000..31fe29f
--- /dev/null
+++ b/static/shared/clipboard/clipboard.md
@@ -0,0 +1,62 @@
+## Clipboard
+
+---
+
+Use an aria-label on buttons to provide context about the data being copied.
+
+### Button {#clipboard-button}
+
+```html
+<button
+  class="go-Button go-Button--inline go-Clipboard js-clipboard"
+  data-to-copy="hello, world!"
+  aria-label="Copy _DATA_ to Clipboard"
+  data-gtmc="clipboard button"
+>
+  <img
+    class="go-Icon"
+    height="24"
+    width="24"
+    src="/static/shared/icon/content_copy_gm_grey_24dp.svg"
+    alt=""
+  />
+</button>
+```
+
+```html
+<button
+  class="go-Button go-Button--inverted go-Clipboard js-clipboard"
+  data-to-copy="hello, world!"
+  aria-label="Copy _DATA_ to Clipboard"
+  data-gtmc="clipboard button"
+>
+  <img
+    class="go-Icon"
+    height="24"
+    width="24"
+    src="/static/shared/icon/content_copy_gm_grey_24dp.svg"
+    alt=""
+  />
+</button>
+```
+
+### Input {#clipboard-input}
+
+```html
+<div class="go-InputGroup">
+  <input class="go-Input" value="hello, world!" readonly />
+  <button
+    class="go-Button go-Button--inverted go-Clipboard js-clipboard"
+    aria-label="Copy to Clipboard"
+    data-gtmc="clipboard button"
+  >
+    <img
+      class="go-Icon"
+      height="24"
+      width="24"
+      src="/static/shared/icon/content_copy_gm_grey_24dp.svg"
+      alt=""
+    />
+  </button>
+</div>
+```
diff --git a/static/shared/clipboard/clipboard.test.ts b/static/shared/clipboard/clipboard.test.ts
new file mode 100644
index 0000000..33729ff
--- /dev/null
+++ b/static/shared/clipboard/clipboard.test.ts
@@ -0,0 +1,48 @@
+/**
+ * @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 { parse } from '../../markdown';
+import { ClipboardController } from './clipboard';
+
+describe('ClipboardController', () => {
+  const buttons: HTMLButtonElement[] = [];
+  const controllers: ClipboardController[] = [];
+  const dataToCopy = 'hello, world!';
+
+  beforeAll(async () => {
+    document.body.innerHTML = await parse(__dirname + '/clipboard.md');
+    for (const button of document.querySelectorAll<HTMLButtonElement>('.js-clipboard')) {
+      buttons.push(button);
+      controllers.push(new ClipboardController(button));
+    }
+  });
+
+  afterAll(() => {
+    document.body.innerHTML = '';
+  });
+
+  it('copys data-to-copy when clicked', () => {
+    Object.assign(navigator, { clipboard: { writeText: () => Promise.resolve() } });
+    jest.spyOn(navigator.clipboard, 'writeText');
+    buttons[0].click();
+    expect(navigator.clipboard.writeText).toHaveBeenCalledWith(dataToCopy);
+  });
+
+  it('copys input value when clicked', () => {
+    Object.assign(navigator, { clipboard: { writeText: () => Promise.resolve() } });
+    jest.spyOn(navigator.clipboard, 'writeText');
+    buttons[2].click();
+    expect(navigator.clipboard.writeText).toHaveBeenCalledWith(dataToCopy);
+  });
+
+  it('shows error when clicked if clipboard is undefined', () => {
+    Object.assign(navigator, { clipboard: undefined });
+    jest.spyOn(controllers[1], 'showTooltipText');
+    buttons[1].click();
+    expect(controllers[1].showTooltipText).toHaveBeenCalledWith('Unable to copy', 1000);
+  });
+});
diff --git a/static/shared/clipboard/clipboard.ts b/static/shared/clipboard/clipboard.ts
new file mode 100644
index 0000000..0afa223
--- /dev/null
+++ b/static/shared/clipboard/clipboard.ts
@@ -0,0 +1,61 @@
+/**
+ * @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.
+ */
+
+/**
+ * This class decorates an element to copy arbitrary data attached via a data-
+ * attribute to the clipboard.
+ */
+export class ClipboardController {
+  /**
+   * The data to be copied to the clipboard.
+   */
+  private data: string;
+
+  /**
+   * @param el The element that will trigger copying text to the clipboard. The text is
+   * expected to be within its data-to-copy attribute.
+   */
+  constructor(private el: HTMLButtonElement) {
+    this.data = el.dataset['toCopy'] ?? el.innerText;
+    // if data-to-copy is empty and the button is part of an input group
+    // capture the value of the input.
+    if (!this.data && el.parentElement?.classList.contains('go-InputGroup')) {
+      this.data = (this.data || el.parentElement?.querySelector('input')?.value) ?? '';
+    }
+    el.addEventListener('click', e => this.handleCopyClick(e));
+  }
+
+  /**
+   * Handles when the primary element is clicked.
+   */
+  handleCopyClick(e: MouseEvent): void {
+    e.preventDefault();
+    const TOOLTIP_SHOW_DURATION_MS = 1000;
+
+    // This API is not available on iOS.
+    if (!navigator.clipboard) {
+      this.showTooltipText('Unable to copy', TOOLTIP_SHOW_DURATION_MS);
+      return;
+    }
+    navigator.clipboard
+      .writeText(this.data)
+      .then(() => {
+        this.showTooltipText('Copied!', TOOLTIP_SHOW_DURATION_MS);
+      })
+      .catch(() => {
+        this.showTooltipText('Unable to copy', TOOLTIP_SHOW_DURATION_MS);
+      });
+  }
+
+  /**
+   * Shows the given text in a tooltip for a specified amount of time, in milliseconds.
+   */
+  showTooltipText(text: string, durationMs: number): void {
+    this.el.setAttribute('data-tooltip', text);
+    setTimeout(() => this.el.setAttribute('data-tooltip', ''), durationMs);
+  }
+}
diff --git a/static/shared/color/color-intent.md b/static/shared/color/color-intent.md
new file mode 100644
index 0000000..a7f9eb9
--- /dev/null
+++ b/static/shared/color/color-intent.md
@@ -0,0 +1,115 @@
+## Color Intents
+
+---
+
+### Brand {#color-intent-brand}
+
+<span style="display:contents;">
+  <go-color id="--color-brand-primary"></go-color>
+</span>
+
+### Background {#color-intent-background}
+
+<span style="display:contents;">
+  <go-color id="--color-background"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-background-inverted"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-background-accented"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-background-highlighted"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-background-warning"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-background-alert"></go-color>
+</span>
+
+### Border {#color-intent-border}
+
+<span style="display:contents;">
+  <go-color id="--color-border"></go-color>
+</span>
+
+### Text {#color-intent-text}
+
+<span style="display:contents;">
+  <go-color id="--color-text"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-text-subtle"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-text-inverted"></go-color>
+</span>
+
+### Input {#color-intent-input}
+
+<span style="display:contents;">
+  <go-color id="--color-input"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-input-text"></go-color>
+</span>
+
+### Button {#color-intent-button}
+
+<span style="display:contents;">
+  <go-color id="--color-button"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-disabled"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-text"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-text-disabled"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-inverted"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-inverted-disabled"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-inverted-text"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-inverted-text-disabled"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-accented"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-accented-disabled"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-accented-text"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--color-button-accented-text-disabled"></go-color>
+</span>
diff --git a/static/shared/color/color.css b/static/shared/color/color.css
new file mode 100644
index 0000000..bc7554a
--- /dev/null
+++ b/static/shared/color/color.css
@@ -0,0 +1,66 @@
+/*!
+ * 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.
+ */
+
+:root {
+  /* Colors */
+  --gray-1: #202224;
+  --gray-2: #3e4042;
+  --gray-3: #555759;
+  --gray-4: #6e7072;
+  --gray-5: #848688;
+  --gray-6: #aaacae;
+  --gray-7: #c6c8ca;
+  --gray-8: #dcdee0;
+  --gray-9: #f0f1f2;
+  --gray-10: #f8f8f8;
+  --turq-light: #5dc9e2;
+  --turq-med: #50b7e0;
+  --turq-dark: #007d9c;
+  --blue: #bfeaf4;
+  --blue-light: #f2fafd;
+  --black: #000;
+  --green: #3a6e11;
+  --green-light: #5fda64;
+  --pink: #c85e7a;
+  --pink-light: #fdecf1;
+  --purple: #542c7d;
+  --slate: #253443; /* Footer background. */
+  --white: #fff;
+  --yellow: #fceea5;
+  --yellow-light: #fff8cc;
+
+  /* Color Intents */
+  --color-brand-primary: var(--turq-dark);
+  --color-background: var(--white);
+  --color-background-inverted: var(--slate);
+  --color-background-accented: var(--gray-10);
+  --color-background-highlighted: var(--blue);
+  --color-background-highlighted-link: var(--blue-light);
+  --color-background-info: var(--gray-9);
+  --color-background-warning: var(--yellow-light);
+  --color-background-alert: var(--pink-light);
+  --color-border: var(--gray-7);
+  --color-text: var(--gray-1);
+  --color-text-subtle: var(--gray-4);
+  --color-text-inverted: var(--white);
+  --color-code-comment: var(--green);
+
+  /* Interactive Colors */
+  --color-input: var(--color-background);
+  --color-input-text: var(--color-text);
+  --color-button: var(--turq-dark);
+  --color-button-disabled: var(--gray-9);
+  --color-button-text: var(--white);
+  --color-button-text-disabled: var(--gray-3);
+  --color-button-inverted: var(--color-background);
+  --color-button-inverted-disabled: var(--color-background);
+  --color-button-inverted-text: var(--color-brand-primary);
+  --color-button-inverted-text-disabled: var(--color-text-subtle);
+  --color-button-accented: var(--yellow);
+  --color-button-accented-disabled: var(--gray-9);
+  --color-button-accented-text: var(--gray-1);
+  --color-button-accented-text-disabled: var(--gray-3);
+}
diff --git a/static/shared/color/color.md b/static/shared/color/color.md
new file mode 100644
index 0000000..73fb5fc
--- /dev/null
+++ b/static/shared/color/color.md
@@ -0,0 +1,116 @@
+## Colors
+
+---
+
+Prefer the use of Color Intent over Color variables where possible. Color Intents are themed and
+adjust for dark mode.
+
+### Gray {#colors-gray}
+
+<span style="display:contents;">
+  <go-color id="--gray-1"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-2"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-3"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-4"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-5"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-6"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-7"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-8"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-9"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--gray-10"></go-color>
+</span>
+
+### Brand {#colors-brand}
+
+<span style="display:contents;">
+  <go-color id="--turq-light"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--turq-med"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--turq-dark"></go-color>
+</span>
+
+### Other {#colors-other}
+
+<span style="display:contents;">
+  <go-color id="--blue"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--blue-light"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--black"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--green"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--green-light"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--pink"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--pink-light"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--purple"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--purple-light"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--slate"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--white"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--yellow"></go-color>
+</span>
+
+<span style="display:contents;">
+  <go-color id="--yellow-light"></go-color>
+</span>
diff --git a/static/shared/form/form.css b/static/shared/form/form.css
new file mode 100644
index 0000000..4df4de2
--- /dev/null
+++ b/static/shared/form/form.css
@@ -0,0 +1,116 @@
+/*!
+ * 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.
+ */
+
+select:focus:not([disabled]),
+input:focus:not([disabled]) {
+  border-color: var(--color-brand-primary);
+  -webkit-box-shadow: var(--focus-box-shadow);
+  box-shadow: var(--focus-box-shadow);
+  outline: transparent;
+  z-index: 2;
+}
+
+input::placeholder {
+  color: var(--color-text-subtle);
+}
+
+.go-Form {
+  align-items: start;
+  display: flex;
+  flex-direction: column;
+  gap: 1rem;
+}
+
+.go-Label {
+  display: flex;
+  flex-direction: column;
+  gap: 0.5rem;
+}
+.go-Label--inline {
+  align-items: center;
+  flex-direction: row;
+}
+.go-Label legend {
+  margin-bottom: 0.5rem;
+}
+.go-Label--inline legend {
+  float: left;
+  margin-bottom: 0;
+}
+.go-Input,
+.go-Select {
+  background: var(--color-input);
+  border: var(--border);
+  border-radius: var(--border-radius);
+  color: var(--color-input-text);
+}
+.go-Input {
+  padding: 0.40625rem 0.5rem;
+}
+.go-Select {
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  background: url('/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg') right no-repeat;
+  background-color: var(--color-background);
+  background-position: right center;
+  border-radius: var(--border-radius);
+  margin: 0;
+  padding: 0.34375rem 1.25rem 0.34375rem 0.5rem;
+}
+
+.go-InputGroup {
+  display: flex;
+}
+.go-InputGroup .go-Input {
+  flex: 1;
+}
+.go-InputGroup > :not(:first-child, :last-child) {
+  border-radius: 0;
+  margin-left: -0.0625rem;
+}
+.go-InputGroup > :first-child {
+  border-bottom-right-radius: 0;
+  border-top-right-radius: 0;
+}
+.go-InputGroup > :last-child {
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+  margin-left: -0.0625rem;
+}
+.go-InputGroup > *:hover,
+.go-InputGroup > *:focus {
+  z-index: 1;
+}
+
+.go-ShortcutKey {
+  display: flex;
+  position: relative;
+}
+.go-ShortcutKey .go-Input {
+  flex-grow: 1;
+}
+.go-ShortcutKey::after {
+  align-self: center;
+  background-color: var(--color-background-accented);
+  border-radius: 0.5rem;
+  color: var(--gray-6);
+  content: attr(data-shortcut);
+  content: attr(data-shortcut) / attr(data-shortcut-alt);
+  display: none;
+  font-size: 0.75rem;
+  padding: 0.0625rem 0;
+  position: absolute;
+  right: 0.75rem;
+  text-align: center;
+  width: 1.5rem;
+  z-index: 1;
+}
+@media only screen and (min-width: 52rem) {
+  .go-ShortcutKey::after {
+    display: initial;
+  }
+}
diff --git a/static/shared/form/form.md b/static/shared/form/form.md
new file mode 100644
index 0000000..936c587
--- /dev/null
+++ b/static/shared/form/form.md
@@ -0,0 +1,128 @@
+## Forms
+
+---
+
+### Input {#form-input}
+
+```html
+<input class="go-Input" placeholder="Placeholder text" />
+```
+
+### Input w/ Label {#form-input-label}
+
+```html
+<label class="go-Label">
+  URL
+  <input class="go-Input" placeholder="e.g., https://pkg.go.dev/net/http" />
+</label>
+```
+
+### Input w/ Shortcut Key {#form-input-shortcut}
+
+```html
+<div class="go-ShortcutKey" data-shortcut="/" data-shortcut-alt="search">
+  <input class="go-Input" placeholder="e.g., https://pkg.go.dev/net/http" />
+</div>
+```
+
+### Select w/ Inline Label {#form-select}
+
+```html
+<label class="go-Label go-Label--inline">
+  Rendered for
+  <select class="go-Select">
+    <option>linux/amd64</option>
+    <option>windows/amd64</option>
+    <option>darwin/amd64</option>
+    <option>js/wasm</option>
+  </select>
+</label>
+```
+
+### Input Groups {#form-groups}
+
+```html
+<form
+  class="go-InputGroup"
+  action="#forms"
+  data-gtmc="search form"
+  aria-label="Search for a package"
+  role="search"
+>
+  <input name="q" class="go-Input" placeholder="Search for a package" />
+  <button class="go-Button go-Button--inverted" aria-label="Submit search">
+    <img
+      class="go-Icon"
+      height="24"
+      width="24"
+      src="/static/shared/icon/search_gm_grey_24dp.svg"
+      alt=""
+    />
+  </button>
+</form>
+```
+
+```html
+<form
+  class="go-InputGroup"
+  action="#forms"
+  data-gtmc="search form"
+  aria-label="Search for a package"
+  role="search"
+>
+  <input name="q" class="go-Input" placeholder="Search for a package" />
+  <button class="go-Button">Submit</button>
+</form>
+```
+
+```html
+<div class="go-InputGroup">
+  <button class="go-Button go-Button--inverted" data-gtmc="menu button" aria-label="Open menu">
+    <img
+      class="go-Icon"
+      height="24"
+      width="24"
+      src="/static/shared/icon/filter_list_gm_grey_24dp.svg"
+      alt=""
+    />
+  </button>
+  <button class="go-Button go-Button--inverted" data-gtmc="menu button">Share</button>
+  <button class="go-Button go-Button--inverted" data-gtmc="menu button">Format</button>
+  <button class="go-Button go-Button--inverted" data-gtmc="menu button">Run</button>
+  <button class="go-Button go-Button--inverted" data-gtmc="menu button" aria-label="Search">
+    <img
+      class="go-Icon"
+      height="24"
+      width="24"
+      src="/static/shared/icon/search_gm_grey_24dp.svg"
+      alt=""
+    />
+  </button>
+</div>
+```
+
+```html
+<fieldset class="go-Label go-Label--inline">
+  <legend>Label</legend>
+  <div class="go-InputGroup">
+    <button class="go-Button go-Button--inverted" data-gtmc="menu button" aria-label="Open menu">
+      <img
+        class="go-Icon"
+        height="24"
+        width="24"
+        src="/static/shared/icon/filter_list_gm_grey_24dp.svg"
+        alt=""
+      />
+    </button>
+    <button class="go-Button go-Button--inverted" data-gtmc="menu button" aria-label="Search">
+      <img
+        class="go-Icon"
+        height="24"
+        width="24"
+        src="/static/shared/icon/search_gm_grey_24dp.svg"
+        alt=""
+      />
+    </button>
+  </div>
+</fieldset>
+```
diff --git a/static/shared/gopher/airplane-1200x945.svg b/static/shared/gopher/airplane-1200x945.svg
new file mode 100644
index 0000000..275283a
--- /dev/null
+++ b/static/shared/gopher/airplane-1200x945.svg
@@ -0,0 +1 @@
+<svg viewBox="0 0 1200 945" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2"><path d="M811 927c-4-1-11-3-14-4-7-3-23-12-35-20-10-6-12-8-12-9-1-1-3-2-4-2-2-1-5-3-7-5-13.823-6.912-28.998-19.998-40-31-8-5-15-11-22-17-3-2-11-8-18-14-23.578-17.427-46.246-36.246-67-57-4-3-10-7-12-10-14.3-9.533-13.184-10.638-27-21-8.686-8.686-9.993-8.669-24-4-10.285 2.236-20.648 4.1-31 6-2.387.438-4.353-.32-6.125 2-2.625 3.436-4.696 7.265-6.875 11-4 8-4 9-3 13 0 2 3 6 6 9 5.328 6.659 20 21.344 20 32 3.552 5.92 4.288 16.413 4 23-.478 10.941-1.368 23.278-9 32-10 12-22 21-32 22-3 0-8 1-10 2-12 2-13 2-15 0l-3-3h-1c-2 1-11-1-13-3-2-1-5-3-8-5-14.272-8.92-23.364-26.642-25-43 0-6 0-13 1-16v-8l-1-2 2-2c1-1 3-4 4-6 0-3 3-7 5-11 4-6 4-6 3-12 0-7-3-12-11-19-6.34-6.34-15.705-6.478-24-7-4.477-.282-10.363-.637-14 3-2 1-5 3-5 4-1 2-12 10-19 13-7.726 5.795-17.398-.196-25.625 3.75C302.22 776.141 298.508 789 287 789h-1v-1s2-3 5-6c9-11 11-15 7-18-6.865-6.865-20.118 13-25 13h-1v-1c0-1 3-4 7-8 10-9 11-12 6-19-2-2-4-7-4-9-1-3-3-7-4-8-9.798-6.532-21.839-8.075-32.625-12.125-7.128-2.676-7.424-4.57-13.546-8.795-1.195-.826-2.377-2.08-3.829-2.08h-1v2s3 5 6 9c9 9 15 18 15 20 0 0 1 1 1 2 5 5 16 24 20 34 3 6 6 14 8 17 3 7 3 13 0 17-1 2-2 4-2 5-8.517 12.296-20.837 11.568-32 2-1.789-1.789-24-16.507-24-25l-4-6c-8-15-10-18-14-30-9.49-22.144-10.381-47.144-18-70-2-4-3-4-11-7-6-1-14-5-16-8-4.539-4.539-2.519-17.962 0-23 7.288-10.932-3.601-21.772-10-30-14-16-24-29-26-32-3-6-11-18-14-22-7-10-19-33-22-41-4-13-4-18-3-24 2.268-7.937 6.132-15.556 15.805-12.171 1.915.67 3.455 2.127 5.195 3.171 18.572 9.286 29.634 28.668 38.299 46.61 3.081 6.379 6.755 12.578 8.701 19.39 2 8 10 29 13 37 1.282 3.845 2.074 10.148 4 14 2 3 4 8 5 12 2 4 4 9 5 10l2 1 3-1c3-2 10-19 13-33 4-17 6-22 9-23 7.141-7.141 9.419-17.551 12.75-26.625 1.232-3.355 3.496-10.498 7.25-12.375 2-2 11-13 14-17 1-2 3-5 5-6 1 0 4-4 6-6 2-3 4-6 5-8 5-5 2-7-29-31-7.928-5.285-16.265-12.265-23-19-4.561-1.52-7.439-6.48-12-8-2-1-5-4-7-6-3-1-7-5-10-7-11.658-5.829-18.587-13.19-29-21-9-7-17-14-18-18-1-1-2-6-3-10 0-9.501 2.849-24 15-24 3-1 8-2 12-3 3.788-1.337 25.045-3.047 20.54-13.352-1.06-2.425-2.622-4.598-3.97-6.876-3.401-5.75-6.68-11.577-10.277-17.207-3.597-5.632-7.061-11.393-11.293-16.565-6-6-16-19-27-32-7.063-7.063-9.317-12.78-8-22 1-10 3-13 18-24 5-4 15-11 19-12l10-5c11-5 30-12 38-13 3-1 9-2 12-3 5.211 0 28.294-1.823 33-3 17-3 37-2 51 2 13 5 35 17 56 33 3 3 8 6 12 8 3 2 9 6 13 9 10 8 28 21 33 24 2 1 8 6 13 10 5 3 15 10 22 15 6 4 15 10 18 13 4 2 9 6 12 7l4 2 2-1c0-12.429 9.324-25.408 18-33 11-7 15-9 30-7l6 1v-1c0-2 23-19 26-19l8-4c7-3 8-4 11-10 1.82-2.73 3.833-5.426 6.381-7.493 5.981-4.85 11.76 4.774 13.619 8.493 3 4 3 4 14 7 11 2 31 8 40 12 2 1 6 3 9 5 7 6 18 13 23 15 2 1 5 2 7 2 1-1 5-1 9-2 4 0 6 0 9 2 8.637 4.318 18.088 12.401 11.587 22.907-2.324 3.756-5.263 7.184-8.587 10.093-4 5-4 5-4 18 1 14 1 14-2 21-6.854 13.708-3.462 16.385-8 30-2 10 0 12 11 6 9-4 19-14 26-25 6-8 10-12 18-17 5-3 7-5 9-10 7-12 10-14 23-18 9-2 17 0 44 10 11 4 17 8 25 13 2.588 1.849 7.653 5.36 11.068 5.566 11.949.721 18.209-9.981 23.932-18.566 6-11 9-14 19-21 4-3 7-9 12-9 0 0 3-1 5-2 1.083-1.083 16.356-10 19-10 10-6 33-12 40-11 14.29 2.382 29.991 10.991 40 21 3.584 0 11.414 10.349 13 12 2 0 6 4 8 9 1 3 3 7 4 8 8 9 12 45 8 64-1 5-2 12-3 17 0 5-2 12-3 17-1.412 3.529-1.74 7.414-3 11-3.065 8.725-5.138 11.221-10 19-3 3-3 4-2 6 0 1 5 6 11 12 22 21 43 44 48 52 1 2 4 6 6 10 8 10 9 21 3 29-2 3-4 4-10 6-6.326 1.054-14.524 6.397-21 7-5.285.492-22.08-2.032-27-4-13.874-6.937-14.373-5.567-28-13-11-5-23-11-25-12-3-2-6-4-7-5l-4-2c-1 0-3-1-5-2-6.905-6.905-11.439-.468-18 5-14 12-19 15-32 22-6 3-13 7-16 9-2.25 2.25-24.376 17.782-26 19-4 4-7 6-11 7-2 1-6 2-8 3-5 3-4 6 5 13 4 4 11 10 15 15 5 4 12 10 16 14 13 10 30 24 37 29 3 3 12 10 18 17 13.647 12.282 25.416 29.168 16 48-3 7-11 16-20 23-12.134 9.1-11.775 9.632-17 24-2.713 9.947-8.778 26.177 1 34 3 2 10 7 15 10 12 8 17 14 22 22 3.58 7.16 5.824 21.764 1 29-2 5-11 13-18 16-45 20-80 33-93 35-4 1-13 1-20 2-8 0-16 1-18 1-2 1-7 0-10 0zM83 700c-1.581-1.581-2-4-3-6-.333-.667-.255-2-1-2-3-2-9-27-11-45-4-37-2-62 7-80 2-3 3-7 4-9l1-4h2l-1 3c0 2-2 6-3 10-8 18-9 34-7 64 1.463 26.342 3.722 29.533 10 55 .82 3.327 1.341 8.341 4 11 1 2 2 4 2 6v2h-1s-2-2-3-5zm-30-62c0-7.364-.959-14.71-2-22-2-24 1-44 9-60 6-14 10-20 13-20h1v3h-1s-2 3-4 7c-3 4-5 9-6 11-3 4-7 16-8 23-2 10-1 46 1 53 0 2 0 4-1 4l-1 2-1-1zm886-441c0-2.907 4.981-5.341 6.75-6.375 4.941-2.886 19.103-10.478 23.25-14.625 2-1 5-2 9-2 4-1 11-2 16-4 20-7 31-9 54-11 20-1 22-1 29 0 11.498 2.3 27.183 2.637 37 10l10 5c3 1 7 4 9 6 2 1 5 4 8 5 2 1 5 3 5 4l1 2v1h-1l-8-4c-4-3-8-5-8-5-1 0-2-1-3-1-2-3-19-12-26-13-4-1-9-3-11-3-6-2-34-2-42-1-4 1-12 2-16 2-11 1-27 5-47 12-8.989 2.996-16.266 2.633-25 7-6.726 2.883-13.825 5.825-19 11l-2 1v-1zm-41-26c0-1 8-8 15-12 3-3 10-8 16-13 14-10 21-15 30-17 4-2 11-4 15-5 3-2 9-4 12-5 2 0 11-3 18-6 15-5 25-8 36-8 3-1 11-2 16-3 7.546-2.322 14.874-3.669 22.774-3.953 3.027-.109 10.226-.031 10.226 4.953v1l-2-1c-5-2-18-1-32 4-5 1-12 2-15 3-5.082 0-16.806 2.403-22 5-2 0-9 2-16 5-6 3-13 5-13 5-1 0-2 1-3 2l-1 1h-2c-1-1-19 5-26 8-13.671 6.835-26.81 15.858-39 25-10 8-15 11-18 11h-2v-1z" fill="#0e0e0e" fill-rule="nonzero"/><path d="M809 922c-7-2-18-8-22-11-2-2-5-3-7-4-3-2-23-15-31-21-3.399-3.399-7.993-5.344-12-8-12.089-8.013-12.273-7.465-23-17-24-19-26-20-33-26-4-2-11-7-14-10-15-12-18-14-24-19-5.035-2.518-22.383-17.383-25-20-5-4-11-9-12-11-2-3-5-6-8-8-5-4-11-9-15-13-1-2-6-6-17-15-2.247-1.966-9.223-6.07-8.459-10.562.974-5.722 9.107-2.79 11.459-.438 10.018 5.009 18.254 13.003 27 20 36 31 51 43 58 49 10 10 37 32 46 39 4.472 2.236 8.007 5.99 12 9 17.674 13.324 35.822 26.043 53 40 8 7 22 16 27 18 2 1 9 3 15 4 17 3 36 2 58-4 15-4 19-5 39-12 11-4 24-8 29-10 5-1 14-4 19-7 5-2 9-4 10-4h2l1 2c1 5-5 9-22 17-6 2-13 5-17 7-3 2-6 3-7 3 0 0-2 1-5 2-9 4-46 16-59 19-22.814 3.802-22.741 2-46 2zm9-17c-8 0-18-3-23-6-6-2-17-10-22-14-2-2-8-6-12-9-5-4-11-9-14-12-3-2-11-8-17-13-6.853-3.916-9.264-6.697-15-12-1.424-1.317-3.697-4-6-4-1-1-4-3-7-6-4.192-6.288-25.784-22.088-31-26-7-6-13-10-38-30-14-11-33-27-36-30-1-2-6-6-11-10l-9-9c-1-3 0-5 3-6 7-1 17-5 23-8 3-1 10-4 15-6 4-2 12-4 16-6 9.537-6.358 15.28.21 23 6 10 8 24 19 28 22 5 4 26 21 30 25 11.368 12.992 26.465 21.279 41 30 10.726 7.15 19.164 10.582 30 16 .117.039 19.555 4.555 21 6 3 1 9 9 14 18 23 39 32 52 36 54 2 0 9-3 9-6 1-2-1-12-3-18-6.312-13.772-13.121-28.364-18-43-3.556-9.779 2.403-14.282 11-17 10.382-3.282 17.8-6.08 28-2 9 4 14 8 16 13v11c-1.188 7.72-1.43 15.567-1.625 23.375-.139 5.544-.173 11.137.625 16.625 1.61 11.063 10.536 1.902 12.484-2.501 2.106-4.757 6.558-21.062 9.516-25.499 3-9 7-9 15-1 2 1 6 4 9 6 7 3 14 9 16 14 6.151 12.303-7.63 25.726-19 28-1 0-3 1-4 2-3 2-14 7-37 14-4 1-9 3-12 4-3 2-8 3-10 3-3 1-10 3-16 4-14 5-34 7-45 6zm-369-28c-5-1-11-2-13-3l-9-3c-5-3-15-13-19-20-5-8-6-15-6-28 1-10 1-11 4-18 3.844-9.61 8.804-17.483 18-23 9-6 29-12 35-10 3 0 21 9 27 13 7 5 16 18 18 26 3 10 2 15-3 30-3 11-5 15-8 18-8 10-22 17-31 18h-13zm19-33c3.169-1.584 10.061-5.373 10.375-10 .248-3.66-.07-7.344-.375-11 0-12 0-13-3-16-3-4-10-9-14-10-2 0-5 1-9 3-3.062 1.413-7.63 3.631-10.36 6.169-7.543 7.012-7.693 20.41-2.64 28.831.995 1.493 3.49 5.875 5 7 1.255.936 2.787 1.506 4.313 1.859 5.988 1.388 13.653 2.554 19.687.141zm386 22c-6-8-14-20-16-24 0-1-2-5-3-7-4.549-7.278-13.594-22.051-17-30-.487-1.136 1.386-3.329 2.25-3.625 2.172-.745 4.455-1.294 6.75-1.375 4.825-.169 5.674 1.123 8 5 3 2 6 8 7 12 2 4 6 12 8 17 11 22 13 30 11 33-1 3-4 2-7-1zm50-19c-1-3 0-13 4-34 1-5 2-16 2-23 1-17 2-20 5-22 3-3 10-4 11-2 3 2 2 6-3 23-2 9-5 21-6 26-1 9-7 29-8 32-1 1-2 2-3 2h-1l-1-2zm-652-29c-5-3-13-8-15-12-1-1-2-3-3-3 0 0-3-3-5-6-1.671-3.342-3.924-7.413-7-10 0-1-2-3-3-6-9-13-11-20-22-61-2-6-3-14-4-17 0-4-2-12-3-19-2-7-3-13-3-14l1-1 1 1c1 1 4 6 7 12 3 5 7 12 9 15 3 3 8 10 13 16 4 5 10 13 14 17 7 9 12 17 23 38 8.193 16.386 10.588 20.924 14 39 .536 2.842-1.08 6.08-3 8-3 4-9 5-14 3zm553-24c-3.113 0-15.814-2.271-18-3-17-8-26-13-37-21-6-5-14-10-16-11-3-2-10-8-16-13-14.872-14.872-23.396-21.166-40-34-3.956-3.058-7.528-6.764-12-9-20-14-29-21-42-32-4-3-10-8-14-10-4-3-12-9-17-15-11-10-30-25-39-30-24.216-15.135-42.575-38.345-67-53-8-6-14-10-30-23-2-1-8-6-14-11-7-5-13-10-15-12-3-1-8-6-12-9-5.576-3.834-11.079-7.787-16.375-12-4.125-3.282-7.756-8.565-12.625-11l-3-1v-1c0-1-4-4-9-8-5-3-10-7-11-9-2-1-6-5-10-8-9.372-12.496-23.203-21.042-36-30-4-2-11-8-16-12-16-14-33-27-45-35-12.158-7.599-22.176-18.588-35-25-11.165-8.374-21.278-18.065-32-27-14-10-29-23-32-27-1-2-6-6-10-9-12-11-27-27-31-34-3-6-4-12-1-13h1l1 2c1 2 2 4 4 4 1 1 8 8 15 16 14 14 20 20 38 34 11.482 7.655 21.518 17.345 33 25 3 3 12 9 18 14 7 5 17 12 22 16 16 10 21 14 44 33 12 10 24 20 27 22 4 3 8 7 11 9 8.541 8.541 18.568 15.455 28 23 16 15 27 23 57 44 3 3 9 7 14 11 4 3 11 8 15 11 4 2 12 9 18 14 7 5 16 12 21 15 4 4 13 11 20 16 4.802 4.162 9.361 8.638 14.5 12.375 2.061 1.498 7.597 1.722 9.5 3.625 0 1 2 2 4 3 2 2 9 7 15 12 7 5 16 13 21 16 5 4 11 9 13 12 2 2 8 6 12 9 20.137 15.49 40.082 31.23 60 47 14.659 11.606 28.162 23.921 44 34 5 4 12 10 16 13 3 4 7 7 7 7 1 0 19 14 26 20 12 12 33 27 39 30 17.404 4.351 41.14 7.43 58-1 9-6 83-31 95-33 3.302-1.101 6.707-1.875 10-3 1.383-.473 6.486-4.029 8-1h1l-1 3c-2 4-8 7-17 12-5 2-9 4-9 5-1 0-4 2-7 3-4 0-14 4-23 8-9 3-19 7-22 8-7.987 1.997-19.971 11-29 11-3 1-10 3-16 5-11 3-22 5-27 3zm89-7c-2-2-5-5-5-6l-1-1 1-2c2.743-2.743 7.514-4.325 11.224-4.948 1.825-.307 4.135.254 5.023 2.059 1.571 3.192.566 6.637-.247 9.889-2 6-4 6-11 2zm-474-15c-1-1-3-3-4-5-3-5-10-13-15-18-4-5-7-11-6-14 0-2.815 4.313-3.235 5.866-3.277 9.19-.249 24.979.585 34.134-.723 4-1 15-2 24-3 14-1 16-2 22-4 7-3 8-4 10-1 2 1 1 5-4 15-4 7-9 19-9 25-1 2-2 4-3 5l-1 1-5-2c-10.874-5.437-31.29-2.474-41 4-4 2-6 2-8 1zm383 0c-4-1-9-2-12-3-11-6-20-12-27-17-4-3-10-8-14-10-3-3-7-6-8-8-1-1-3-4-6-6-6-5-33-26-40-32-3-3-10-8-15-12-30-20-31-21-44-33-2-2-11-9-19-15-9-6-18-13-21-15-3-3-8-7-12-9-7.517-7.517-15.834-14.195-24-21-3.841-3.201-8.464-5.464-12-9-5-4-12-9-16-12-8-5-15-11-25-19-3-2-8-6-12-9-4-2-7-5-8-6 0-1-4-4-8-6-11.455-11.455-26.04-19.28-39-29-8-5-11-8-33-24-6-5-15-11-20-15-5-3-12-8-16-12-4-3-7-6-8-6 0 0-5-4-11-10-6-5-13-11-14-12-2-1-6-3-9-6-22.095-19.333-36.73-32.076-60-50-7.495-5.773-24.23-16.23-31-23-3-2-7-5-10-7-13-8-34-24-42-32-4-3-8-6-10-7-4.298-1.719-7.926-4.85-11.47-7.828C150.418 276.474 138.957 259.957 125 246c-4-5-5-11-2-17 3-5 12-12 27-19 13-7 20-9 35-13 6-2 14-4 18-5 5-2 8-2 58-5 8 0 12 0 16 1 16.051 8.025 17.362 4.47 33 13 27 15 39 23 43 27 1 2 5 5 9 8 4 2 8 6 11 8 4 4 7 7 39 28 12 8 26 17 29 20 4 2 13 9 21 14 14 10 18 13 22 23 3 6 3 7 3 13-2.72 8.161-5.194 29.548-6 36-1 15-1 16 1 22 2 4 4 9 6 11 3.792 6.635 13.631 15.932 20 20 3.394 2.168 7.546 2.928 11 5 12 7 12 7 25 10 17 3 35 5 51 4 8 0 15-1 16-1 0-3.029 3.821-2.51 5.621-2.355 12.112 1.048 23.936 1.587 35.379 6.355 7 3 14 7 15 8 2 1 6 4 10 8 4 3 10 7 12 9 3 1 5 4 6 4l6 6c3 1 11 7 18 13 16.659 13.883 33.898 28.932 52 41 5 4 15 12 22 18 7 5 15 12 18 14 16 12 27 21 32 25 3 3 9 8 14 11 8.515 8.515 18.485 15.485 27 24 7 5 26 22 41 35 6 5 15 13 20 16 7 6 14 14 16 19 3.775 3.775 1.333 18.532-3.056 20.952-8.799 4.852-25.24 10.125-34.944 13.048-2.514.757-6.927.927-9 3-2 1-6 3-9 4-3 0-6 2-7 2-6.613 2.48-14.123 3.082-20 7-4 1-9 3-12 4-2 0-9 3-14 5-7 3-12 5-29 9-4 1-9 1-20 0zm-471-24c3-2 8-3 14-1 8 3 6 7-7 15-6 3-9 4-13 5-2.49 0-5.732.558-8-1-1.306-.897-1.215-3.546-1-4.75.559-3.124 1.387-6.735 4.25-8.625 3.317-2.19 7.828-1.703 10.75-4.625zm-30 11c-4-4-4-6-1-11 3-4 6-4 9 0 .553.553 1.114 1.115 1.536 1.773 2.021 3.157 1.361 6.397-.911 9.227-1.086 1.353-2.699 3-4.625 3 0 0-2-2-4-3zm-13-12c-3-2-5-9-3-10 2-3 11-2 13 2 1 4-4 10-8 10 0 0-2-1-2-2zm69-6c-4 0-8-1-9 0-2 0-14-2-18-3-4-2-4-4-3-14v-14l1-7-2-1h-1v3c0 5-3 22-4 24-3.342 5.012-7.019 4.491-12 2-1-2-1-3 0-9 1-8 2-17 4-33v-9h-3v7c-2 13-3 26-4 33-2 10-3 11-13 8-9-3-15-5-15-7l-1-2 2-2c3-2 13-24 15-32 1-3 2-7 2-9 4.729-18.916 5.774-39.739.25-58.625-3.097-10.588-8.48-21.494-13.25-31.375-5.264-11.844-16.382-26.953-29-32-10.362-5.181-8.912-7.217-19.25-12.125-2.716-1.289-6.772.247-9.139-2.301-2.318-2.495 1.683-7.938 2.571-9.141 3.426-4.642 13.682-15.297 16.818-18.433 10-9 15-13 25-19 6-4 12-7 13-7 0 0 4-2 8-5 13.526-8.695 32.694-20.107 50-20 4.346.027 8.789 3.707 12 6 12 10 21 16 24 17 8.028 8.028 17.135 14.908 26 22 5 3 10 7 12 8 1 2 5 4 7 6 .96.32 20.921 14.947 21 15 4 3 11 8 27 22 3 2 8 6 10 8 3 2 11 10 18 16 7 7 16 15 21 17 6.248 4.686 11.752 10.314 18 15 11 10 12 11 7 15-7.861 4.866-17.855 8.122-22.359 17.016-3.2 6.317 2.378 10.984 8.359 10.984 7-1 25-6 32-10 6-3 7-3 12-3 5 1 17 7 20 11 3 3 17 13 18 13l8 6c4 4 9 8 11 10 2 3 4 5 4 6-1 2-10 7-21 10-4 2-10 4-13 5-18 7-22 8-28 10-4 0-12 2-17 3-13 4-25 7-34 9-4 1-9 3-11 4-2.246 1.021-4.538 2.134-6.984 2.453-9.347 1.219-7.296-9.013-10.016-14.453-3-3-4-3-14 1-1.693.423-16.243 2.622-19 4-3 0-9 2-15 2-7 1-16 1-20 2-11.119 0-24.001-.124-35 2-3.908.755-3.222 10.222-5 12-3 1-22 2-29 0zm-102-22c-10-3-17-6-20-10-9-7-27-25-27-26v-2h4c5 0 14-2 19-4 3-2 13-12 15-15 5.952-17.855 4.527-37.982-12-49-10-7-17-10-26-10-5-1-9-2-9-2-1-1-1-3 0-5 0-2 0-5 1-7 1-8 14-37 18-40 7.017-4.678 22.999.999 28 6 2 1 6 5 10 7 12.547 9.411 19.672 17.565 27 31 3 7 7 15 7 19 3 11 6 39 4 43-1 1-2 7-2 15-2 17-5 24-12 35-5 8-6 9-11 11-7 4-11 4-14 3zm-90-49c-7.444-3.722-11.362-16.532-3.781-22.141C169.441 642.516 178.206 641 187 641c3.028.303 7.332.697 10.125 2.125 5.271 2.694 6.218 9.368 5.875 14.625-.107 1.645-.68 5.93-2 7.25-2 3-5 2-12-4-3-3-7-6-8-6h-2v2c-.687 0-.861 1.57-.875 1.875-.13 2.79.031 5.596-.25 8.375-.097.957-.195 2.07-.875 2.75-1 3-6 3-11 0zm44 1c-4.283-8.566.973-19.036-5-27-3-6-8-11-10-12-7-1-8-8-3-14 4-6 10-9 17-9 7-1 12 1 22 7 9 6 12 10 13 20 1 7 1 8 0 15-3 10-4 12-9 15-6 4-10 5-17 6-5 0-7 0-8-1zm319-20l-2-1v-2c0-1.777 2.046-4.436 3.25-5.5 6.153-5.435 9.535-7.899 17-11.375 3.342-1.556 7.887-2.975 11.578-1.438 3.728 1.554 11.003 8.207 4.172 10.938A218.176 218.176 0 01551 645c-16 6-19 7-22 6zm-368-22c-1-1-6-8-11-15-6-7-13-16-15-19-3-4-8-12-12-16-6.614-8.267-10.401-19.401-18-27-9.786-15.378-18.184-29.393-19.648-47.666-1.248-15.568 19.495-6.345 24.648-.334 8 9 21 27 26 38 6 13 11 26 14 34 8 21 16 48 16 53v3h-1c-1 0-3-1-4-3zm683-38c-17-12-25-18-33-24-5-4-13-10-17-14-13-10-28-22-28-23-1-1-16-14-23-19-10-7-16-11-24-18-.453-.226-14.761-9.761-16-11-2-3-8-7-12-10-5-4-10-8-11-9l-3-3 3-7c1-3 4-9 5-13 0-3 2-7 3-8 1 0 5-2 9-2 6-1 11-2 32-6 5-1 14-3 19-3 5-1 13-3 17-4 5.959 0 31.04-2.434 35-3 22-5 21-5 19 14v2l6 2c5 2 8 2 16 1 6-1 14-1 18-2 3-1 13-2 22-3 8-1 17-3 19-3 3-1 7-1 9-1 2 1 8 0 14-1 13-2 11-2 33 0 24 1 37 5 38 10v2l-2 1c-2 1-15 2-53 2-28 1-53 1-55 2-3.956.989-14.709 5.801-12.5 12.375 1.07 3.185 6.193 7.548 8.5 9.625 5 4 13 10 18 14 5 3 11 8 14 10 2 2 10 8 18 13 6.885 4.711 13.543 9.75 20.125 14.875 1.732 1.348 5.904 5.459 5.875 8.125-.023 2.153-4.399 6.909-5.659 8.149-9.38 9.229-20.863 17.474-32.341 23.851-7.168 4.301-21.497 15.832-31 19-2 1-6 4-9 5-8.311 5.541-23.919 18.041-34 13zm205-37c-12-4-33-15-55-29-6.289-3.145-13.028-6.028-18-11-7-6-13-10-22-16-16-10-21-14-25-17-2-2-5-4-5-4s-3-2-5-4c-6.483-4.322-21.03-16.03-26-21l-6-6 1-1c0-1.121 1.418-1.955 2.5-2.25 2.744-.748 5.656-.726 8.5-.75 27.332-.227 54.667-.002 82 0 11.168.001 15.333-1 26 3 4 2 9 5 12 6 6 5 31 28 37 36 3 3 9 10 14 15 10 9 16 18 22 31 4 9 4 11-1 16-2 3-4 4-11 6-12 3-20 3-31-1zm-27-2c-3-2-7-4-10-6-4.669-1.556-8.708-4.592-13-7-9.375-5.259-18.884-10.303-28-16-4-3-10-7-13-9-4-2-10-6-13-10-9.68-8.066-20.052-15.274-30.375-22.5-7.284-5.099-8.371-3.246-14.625-9.5-5-3-10-8-12-10-7-5-8-6-8-8v-2h2c1-1 6 1 11 5l5 5c8.527 4.264 14.473 12.736 23 17 3 3 9 7 14 10 6.779 6.779 19.158 13.733 27 19 28.574 19.192 27.746 20.36 58 37 7 3 12 7 12 8v1h-3c-1 0-5-1-7-2zm-768-68c-7-4-14-10-28-22-8.693-8.693-12.761-10.071-22-17-7-5-10-7-21-14-3-3-8-7-10-9-4.16-2.774-7.847-6.215-12-9-2.192-1.47-9-2.938-9-7-8.148-8.148-24-16.388-24-30v-3l1-1c5.254 0 8.839 6.032 12 9 9.267 8.701 14.416 12.944 25 20 6.76 6.76 30.816 24.012 35 27 6 5 14 11 17 14 3 2 9 7 14 11 17 13 33 26 34 29l2 2-1 2c-2 2-5 1-13-2zm17-8c-2-1-7-5-11-8-3-3-11-9-16-13-5-3-11-8-13-10-2-1-6-4-9-5-3-2-5-4-6-4-1-2-9-9-16-13-5-4-12-10-33-28-5-5-11-10-13-11-6.601-4.401-30.276-23.945-10-28 9.524-2.597 19.19-4.902 29-6 1.367-.153 2.518 1.299 3.375 2.375 1.726 2.169 15.862 29.269 23.625 17.625 1-3 1-3-3-13-2-8-3-10-2-11l1-2 2 1c2 1 23 16 33 24 3 3 8 6 11 7 2.754 1.377 5.938 4.938 8 7 5 3 21 15 29 22 3 3 8 7 10 8 10 7 24 19 27 23 3 3 6 18 4 20-1.068 3.205-5.881 5.673-8.5 7-4.788 2.425-9.739 4.522-14.5 7-7.131 3.713-17.334 12.933-26 6zm54-21c-1 0-1-3-2-5 0-3 0-5 1-6l2-1 2 2c2 2 3 6 0 9-1 2-3 3-3 1zm338-7c-3-1-6-3-8-4-1-2-3-2-5-2-1 1-4 0-7 0-4-2-9-1-27 0-15 1-22 1-23 0l-1-1 1-2 1-2-3-3c-5-5-14-8-19-5-2 1-3 1-5 0-1-1-3-1-3 0h-1l1 4c0 4-2 6-7 9-4.389 1.755-11.174.247-15.235-1.088-19.517-6.415-39.58-17.239-49.765-35.912-4-8-4-8-4-18 1-17 4-34 5-35 2-3 5-2 7 1 2 2 2 7 0 11 0 3 4 7 9 8 4 1 4 1 7-2 5.431-7.241 16.582-4.279 23 0 8 7 20 12 28 12 13 2 23-2 37-14 6-6 7-6 12-6 5 1 7 1 10 4 8.583 5.364 9.796 11.322 13 21 2.525 7.627 3.748 17.874 12 22 1 1 8 3 16 5 7 2 13 4 14 4 2 2 1 5-1 15-4 13-4 15-7 16-3 2-3 2-10-1zm-91-4c-3-2-2-4 2-9 3-4 4-4 7-4 2 1 4 1 6 2l3 2v1c-.284.851-1.38 2.116-2.047 2.672-3.33 2.778-4.322 3.435-8.219 5.344-.812.398-2.799 1.044-3.734.984l-4-1zm441-3c-3-2-9-7-12-11-6-5-9-7-14-9-12.031-5.156-25.457-2.579-38-3-10.643-.357-23.629-4.186-34 1-3 0-10 1-17 2-8 0-15 1-16 1-3 2-41 4-46 3-2 0-5-1-6-1-2-2-1-8 2-13 8.607-17.214 19.316-34.503 32-49 4-3 8-8 10-11 22-37 36-51 63-64 6-3 13-6 17-6 8.886-2.962 19.588-5.345 29-4 15 3 27 10 41 28 5 6 9 11 10 15 1 3 3 7 4 9 6.945 11.111 6.434 25.614 6 38-.351 10.016-.352 20.114-2 30 0 5-1 12-2 14 0 6-6 22-8 26-2.286 3.048-6.896 7.449-11 8-1.797.241-6.649-3.324-8-4zm-320-19l-2-2 1-3c1-1 6-5 15-9 7-4 15-8 16-10 4-3 8-9 15-19 6.047-8.063 21.201-27.377 33.612-19.992 5.812 3.458 6.656 6.655 11.388 10.992 6 6 14 13 16 16 6 5 14 14 14 16v2l-1 1c-11.785 0-24.459-.27-35 5-7 2-24 5-36 6-6 1-14 2-18 3-4 0-9 1-13 2-4 0-8 1-9 2-4 1-5 1-8-1zm-30-13c-12-3-17-8-19-19 0-2-2-8-3-13-.486-1.783-2.554-8.073-1.375-10.125 1.369-2.383 6.524-1.696 8.375-1.875 10.575-1.024 20.071-1.745 30-6 3-2 6-3 8-3h2v1c1 1 0 4 0 6-2.428 8.498-6.872 32.643 9.391 27.085 2.59-.885 5.332-1.567 7.609-3.085 7-4 20-14 25-22 10-14 16-19 23-21 2.37-1.58 5.161-2.772 8-3 3.766-.302 7.911 3.179 6 7 0 0-4 3-9 6-5 2-11 6-14 9-10.505 8.754-8.431 10.397-17 21-7.882 9.754-11.711 13.356-23 19-8 5-10 5-19 6-13 1-14 1-22 0zm163-16c-15.484-8.602-26.704-19.704-39-32 0-1 1-4 3-6 7-8 6-14 0-21-4.877-6.503-11.975-3.756-19-2-11.122 3.707-7.991-6.221-2.234-9.829 9.021-5.657 21.333-5.371 31.234-3.171 11 3 33 12 39 17 3 2 8 6 11 8 10 5 10 8 4 20-7 13-21 31-24 31l-4-2zm-267-19c-11-4-18-8-21-13-1-3-1-10 0-10l1-1 1 1s2 2 4 5c3 4 12 9 19 11 2 0 6 0 10-2 8-2 15-6 20-16 4.901-8.169 5.991-18.011 0-26-3-7-10-12-19-15-8-3-17-2-26 1-2.519 1.44-5.277 2.62-7.375 4.625-3.37 3.22-6.706 14.267-12.625 6.375-1-1-4-3-5-4-5-2-6-5-5-10 1-3 2-7 2-10 2-9-4-18-13-22-3 0-6-2-6-2l-1-1 2-2c1-1 3-1 8-1 10 1 19 6 30 15 8 7 8 8 21 12 7 2 16 5 19 5 7 2 14 7 22 14 9.033 10.324 14.096 24.857 6 37-5 9-16 19-23 22-8 3-19 4-26 1zm-52-7a4.828 4.828 0 01-1.045-.958c-2.112-2.579.388-6.042 2.045-8.042.57-.688 1.733-2.254 2.875-2.25 1.052.004 1.71 1.627 2.125 2.25 2 2 2 6-1 9-2 3-3 2-5 0zm-320-6c-1.302-3.907-1.935-3.507-4-7-5.066-8.568-5.546-10.091-10-19-3-5-5-10-5-11l-1-2 1-1c4-1 14 9 17 18 1 2 3 8 5 14 2 5 4 10 4 11-2 2-4 1-7-3zm368-5c-6-4-10-8-11-13-1-10 2-22 9-27 3.114-2.076 7.448-2.339 11-2 12.122 1.158 24.931 6.102 26 20 2 9-2 16-12 22-7.36 2.944-16.041 5.219-23 0zm5-15c4-3 1-9-5-9h-3l-1 2c-1 3 1 7 3 8 3 1 4 1 6-1zm69 16c-2.216-.511-11.498-.909-13.032-5.697-.814-2.542-.974-12.182 3.032-12.303 2.107-.064 4.114 1.057 6 2 7 3 13 3 28 2 14-1 20-3 34-9 5-2 7-3 8-2l2 1-1 2c-1 5-19 18-29 21-9 3-27 4-38 1zm-107-1c-2.362 0-4.145-1.881-6-3-2.301-1.389-4.596-2.798-7-4-3.591-1.539-7.018-4.339-7.705-8.408-.144-.852-.075-1.739.065-2.591.17-1.036.417-2.078.857-3.031 2.205-4.769 6.065-3.201 9.783-.97 2 2 6 3 9 4 6 1 9 4 10 9 1 6-3 10-9 9zm254-15l1-3 3-1c1.982 0 4.025.183 5.563 1.591a20.269 20.269 0 011.837 1.927c.421.501.806 1.297.725 1.982-.187 1.574-2.059 2.7-3.125 3.5-.92.92-2.051 2.198-3.5 2.25-1.232.044-2.358-1.145-3.103-1.909-1.403-1.44-2.397-3.291-2.397-5.341zm-143-3c-8-2-11-4-17-14-4-9-13-18-21-22-3-2-11-5-17-7-7-2-15-5-17-5-2-1-6-2-7-3-3 0-16-13-19-18l-1-2 3-3c13.4-16.08 36.751-20 56-20 18-1 19-1 26 1 8 2 16 6 18 8 1 0 4 1 6 1 4 1 6 2 8 4 2 1 6 4 9 6 2 2 6 5 9 7 4 5 5 7 2 12l-1 3 4 5c4 4 5 6 7 12 .641 3.848 3.583 13.209 10 10 5-1 8 5 5 10-3 3-21 13-27 14-8 1-31 2-36 1zm-116-7c-3-2-4-5-1-7 2-3 5-2 8 0 2 3 3 4 0 6-1 2-4 2-7 1zm-30-16c-4.529-4.529-7.821-12.864-5.762-19.266 2.44-7.582 8.987-13.79 16.762-15.734 6-1 9-1 12 3 3 3 4 17 2 22-2.614 6.969-9.834 14.184-17.892 13.074-3.66-.504-4.069-1.048-7.108-3.074zm5-7c.701-.654 1.736-1.591 2.347-2.438 1.255-1.738 1.461-4.292.777-6.305-.81-2.384-3.188-5.636-5.96-3.622-2.035 1.479-3.767 3.987-2.83 6.596.374 1.043 1.207 2.19 1.916 3.019.845.989 2.188 2.75 3.75 2.75zm197-3c-1.946 0-2.323-3.072-1.313-4.234 2.188-2.517 4.321-4.27 7.313-5.766l3-2v-4l-6-1c-4 0-8 0-9-1h-2v-2c1.252-3.757 6.299-5.781 9.844-6.328 6.637-1.024 16.624-.98 18.375 7.344.402 1.913.199 4.101-.219 5.984-2 5-13 15-18 15 0 0-2-1-2-2zm-109-69c-2-1-1-5 1-7 1.966-1.475 5.781-2.815 7.313 0 .224.412.39.858.507 1.313.115.444.179.905.184 1.363.017 1.552-1.004 2.807-1.004 4.324-1 1-7 1-8 0zM451 837c-3-1-5.845-3.873-8-6-.93-.918-2.385-2.489-2.625-3.875-.349-2.015-.294-4.081-.375-6.125-.064-1.614-.056-4.189.5-5.75 1.207-3.388 5.195-6.249 7.861-8.145 4.369-3.106 10.516-6.1 15.849-3.437 3.411 1.703 5.925 5.135 7.79 8.332 3 5 3 10-1 17-5 11-10 13-20 8z" fill="#fff" fill-rule="nonzero"/></svg>
\ No newline at end of file
diff --git a/static/shared/gopher/gopher.css b/static/shared/gopher/gopher.css
new file mode 100644
index 0000000..14c2644
--- /dev/null
+++ b/static/shared/gopher/gopher.css
@@ -0,0 +1,18 @@
+/*!
+ * 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.
+ */
+
+.go-GopherMessage img {
+  display: block;
+  height: 15rem;
+  margin: 0 auto;
+  padding: 1.25rem 0;
+  width: 15rem;
+}
+.go-GopherMessage p {
+  font-weight: 600;
+  margin: auto;
+  text-align: center;
+}
diff --git a/static/shared/gopher/gopher.tmpl b/static/shared/gopher/gopher.tmpl
new file mode 100644
index 0000000..456b79a
--- /dev/null
+++ b/static/shared/gopher/gopher.tmpl
@@ -0,0 +1,13 @@
+<!--
+  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 "gopher-airplane"}}
+  <div class="go-GopherMessage">
+    <img width="1200" height="945"src="/static/shared/gopher/airplane-1200x945.svg"
+        alt="The Go Gopher">
+    {{if .}}<p data-test-id="gopher-message">{{.}}</p>{{end}}
+  </div>
+{{end}}
diff --git a/static/shared/gopher/package-search-700x300.jpeg b/static/shared/gopher/package-search-700x300.jpeg
new file mode 100644
index 0000000..2be4db5
--- /dev/null
+++ b/static/shared/gopher/package-search-700x300.jpeg
Binary files differ
diff --git a/static/shared/gopher/pilot-bust-1431x901.svg b/static/shared/gopher/pilot-bust-1431x901.svg
new file mode 100644
index 0000000..a654dc7
--- /dev/null
+++ b/static/shared/gopher/pilot-bust-1431x901.svg
@@ -0,0 +1 @@
+<svg viewBox="0 0 1431 901" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2"><path d="M335.6 867.8c-.6-33-1.1-47.7-2.2-69.6-.6-10.6-.7-11.2-2.4-10-1 .7-5.7 4.6-10.6 8.6-15.4 12.5-25.1 16.2-47.4 17.7-12.7.9-17.2 2.1-32 9-7.5 3.5-15.5 6.8-17.8 7.5-3.1.8-15.6.9-45 .4l-40.7-.7-9.5 4c-18.4 7.8-31.9 11-41.5 9.8-9-1.2-21.4-4.4-26.4-7-11.5-5.8-23.1-18.3-38.8-42-19.7-29.6-24.6-42-19.2-48.9 1.2-1.5 4.9-4.1 8.3-5.8 11.3-5.6 11.9-6.4 14.1-17.1 1.2-6 7.3-8.4 13.3-5.3 3.7 2 9.4 8.1 13.4 14.6 4.4 7.1 4.6 7.5 6.9 20.5 2.8 15.5 8.5 38.9 10.8 44 1.8 4 2.4 4.5 7.7 6.1 8.5 2.4 23.5 1.5 32.9-2.1 3.9-1.4 12.2-4 18.5-5.6 11.1-2.9 12.5-3.1 36.5-3.4 35-.4 54.8-3.6 62.5-10.1 7-5.9 28-56.1 35.4-84.8 5.2-19.7 5.7-30.9 2.2-46.5-5.3-23.4-13.3-77.8-14.3-96.6-.6-11.5 1-23.3 6-46l2.2-10-5.1-5.2c-6.2-6.1-11.4-15.1-14.4-24.8-3-9.6-3.8-28.1-1.6-38.4.9-4.1 1.5-7.5 1.3-7.6-.1-.1-3.1-2.2-6.7-4.7-22-15.4-33.1-36.4-33.3-62.8-.1-13.6 1.3-22.8 5.9-37 4.6-14.5 10.8-24.6 21.3-35 10.1-10 18.1-14.9 30.8-19 13.1-4.2 20.8-5.3 38.3-5.3h15.6l2.3-11.1c3.4-16.3 8.6-32.9 13.7-43.4 7.5-15.5 20.5-27 45.1-39.9 8.5-4.4 12.6-7.4 19.3-13.8 5.3-5.1 14.5-12.1 24.5-18.8 18.3-12.1 35.8-26.7 47.2-39.4 11.3-12.7 14.6-15.6 26.8-23.7 18.8-12.5 55-31.8 79.1-42.1 14.6-6.3 23-8.3 62.4-14.9 18.4-3.2 39.1-6.9 46-8.4C689.2.6 690.3.5 723.5.5c35.9 0 51.2.9 82.5 5.1 21.1 2.8 34.6 6 44 10.2 6.9 3.2 34.5 13.3 62 22.7 43.7 15.1 57 19.9 62.5 22.7 14.2 7.1 36.1 24.7 70 56.3 20.2 18.8 22 20.2 42.9 34.5 32.3 22 35.4 26.2 48.7 67.5 12.3 38.2 11 35 14.5 34.8 5.6-.3 24.6 1.7 31.3 3.3 3.6.8 11.2 3.8 16.8 6.5 21.8 10.7 35.3 28.8 43.1 57.8 2.1 8.1 2.6 11.8 2.6 24.1.1 13.4-.1 15.2-2.8 23.3-4.6 14-14.3 27.1-25.6 34.8l-5.1 3.4.8 10c1.3 16.4.8 39-1.1 48.4-1.8 8.9-6.1 19.3-9.2 22.5-1.6 1.7-1.8 3.2-1.6 10.2.4 8.1-1.6 26.9-4.3 40.7-1.3 7-1.3 7.3 1 11.2 1.3 2.2 5.1 7.2 8.5 11 3.4 3.9 7 8.7 8.1 10.8 5.5 10.4 8.6 35.4 7.5 60-1.3 29.3-4.8 40.9-26.6 86.4-8.6 18-11.4 25.6-10.6 29.7.8 4.3 5.3 10.7 10.6 15.1 6.7 5.6 29 20.3 40.9 26.9 7.7 4.4 12.9 8.3 20.5 15.5 13.2 12.5 18.7 15.5 28.1 15.5 12.6-.1 19.7-5.3 28.4-21 7.6-13.7 11-18 26.9-34.5 15.4-15.9 23.6-22.5 35.2-28.4 19.8-10 37.8-9.9 49.2.3 5.7 5.2 7.8 9.2 7.8 15.1 0 5.5-1.3 8.4-6.2 13.7-8.2 8.9-22 16.5-44.2 24.3-13.7 4.9-18.2 7.7-29.8 19.1l-10.6 10.5-4.1 12.8c-2.2 7-5.3 14.6-7 17-6.8 9.8-24.2 23.7-31.5 25.1-2.5.5-5.8-.2-13-2.8-11.8-4.3-21-6.3-35.2-7.5-18.2-1.7-31.8-7.6-66.6-29.4-16.9-10.5-27.8-16.7-29.3-16.7-.3 0-.3 14.5.1 32.3.4 17.7.4 36.1 0 41l-.8 8.7H336.3l-.7-33.2z" fill="#0a0a0a" fill-rule="nonzero"/><g fill="#fefefe" fill-rule="nonzero"><path d="M348 874.8c0-14.5-.7-42.9-1.5-63.3l-1.4-37 3.7-3c13.5-10.9 22.7-22.5 31.7-39.8 6.6-12.9 6.9-15.6 2.8-35.8-4.9-24.8-3.7-39.6 5.9-75.9 1.7-6.3 3.3-12.5 3.6-13.7.2-1.3.8-2.3 1.1-2.3.4 0 5.4 2.4 11.2 5.4 12.3 6.5 27.3 11.8 41.3 14.8 8.1 1.7 13.6 2.1 27.6 2.2 36.6.1 71.3-8.2 103.4-24.6 10.3-5.3 29.9-17.9 31.3-20.1.4-.6 1.2 2.6 1.9 7.1 2.7 19.2 13 30 32 33.5l6.9 1.3-.3 7.5c-.1 4.1-.7 16.4-1.2 27.4-1.5 32-1.4 37.2 1.4 43.1 6.6 14.1 24 21.9 41 18.4 7.5-1.5 19.9-7.9 26.2-13.4l4.9-4.3 4.4 3.4c9.7 7.4 24.6 12.6 36.1 12.5 15.9-.1 29.1-10.4 33.7-26.4 2.3-8.3 2.8-35.4.9-53.4-.9-8.3-1.6-15.6-1.6-16.2 0-.7 1.2-1.2 2.8-1.2 4.6 0 15.6-2.7 20.5-5 11.2-5.3 19.3-16.8 21.8-31.2.7-4 1.3-7.4 1.5-7.6.1-.2 2.8 1.3 6 3.4 16 10.2 42.3 20.6 65.4 25.8 21.5 4.8 32.9 6 57 6 24.9.1 33.7-1.2 51.9-7.6 21.5-7.5 49.1-24.7 63-39.2 1.9-2 3.8-3.6 4.2-3.6.4 0 1 4.6 1.3 10.3 1.9 28.8 5.2 44.5 12.6 59.2 8 16.1 9.4 22.4 9.4 45.5l.1 19.5-5.1 17.5c-7.1 24.1-9.6 36.5-9.8 48.5-.1 8.7.2 10.6 2.3 14.4 4.8 9.1 17.7 20.5 33.8 30l7.3 4.3.2 43.7.3 43.6v14.95c4.5.9-86 3.267-390.7 3.367L348 914.264V874.8z"/><path d="M1288.5 863.9c-9.3-3.7-23.3-6.8-35.4-7.9-19.1-1.6-30.4-6.5-65.8-28.6-10.1-6.3-25.1-15-33.4-19.4-26.6-14.2-40.8-24.9-45.5-34.6-2.5-5-2.6-6.2-2.1-13.4.8-9.8 4.4-26.3 10.4-46.9 4.1-14.3 4.5-16.8 5-29.9.9-23.2-2.5-40.5-10.8-55.7-6.9-12.7-10.5-31.3-11.5-59.5l-.6-16.5 5.8-7c9.6-11.7 18.8-26.7 24.2-39.3l2.3-5.3 4.7.8c2.6.4 11.9.7 20.7.6 15.3-.1 23.9-1.3 32.9-4.9 1.8-.7 1.9-.3 1.2 8.2-.3 4.9-1.8 16.3-3.2 25.4-1.4 9-2.3 17.7-2 19.3.7 3.4 5 9.8 12.9 19 3.3 3.8 6.8 9.2 7.9 11.9 3.2 8.4 4.8 22.9 4.8 42.8 0 34-2.1 41.6-24.5 89.5-5.7 12.1-10.8 23.8-11.4 26-3.6 13.4 1.7 24.2 18.2 36.4 10.2 7.6 27 18.4 38.7 24.9 4.6 2.5 11.7 8.1 18.4 14.2 6.3 5.9 13.5 11.5 17 13.3 5.7 3 6.8 3.2 16.1 3.2 8.9 0 10.6-.3 15.7-2.8 7.4-3.6 15.4-12.4 21.3-23.2 2.6-4.7 6.3-10.7 8.3-13.4 4.6-6 28-30.7 28.5-30.1.2.3 2.3 6 4.5 12.8l4.1 12.2-5.7 3.6c-7.1 4.6-25.8 22.7-28.2 27.4-.9 1.9-3.1 8-4.8 13.5-3.6 11.5-7.2 17.5-14.5 24.1-6.4 5.8-15 11.4-17.4 11.4-1-.1-4-1-6.8-2.1zM77.5 833.4c-10.4-2.2-16.8-5.6-24.2-12.6-7.8-7.5-15.4-17.3-26.3-34-8.1-12.2-18-30.7-18-33.4 0-.7 3.5-3.1 7.8-5.3 10.6-5.3 14.7-10.2 16.4-19.6.4-1.7 1-1.4 4.6 2.4 6.5 7.1 8.7 12.3 11.7 27.6 5.4 28.8 10.4 45.2 14.8 49.4 8 7.5 31.7 8.7 48.8 2.5 19.8-7.2 22.1-7.6 52.9-8.4 46.7-1.3 64-5.5 71.8-17.8 11.3-17.5 31.6-70.9 36.2-94.9 2.9-15.5 2.5-29-1.8-48.8-6.4-30.2-13.7-85.3-12.7-96 .6-6.2 7-40.4 7.7-41 .2-.2 4.1 1 8.8 2.6 10.8 3.6 21.3 5.2 30.7 4.7 4.8-.2 7.3 0 7.3.8 0 .6 2 5.2 4.5 10.2 12.5 25.9 39.2 56.8 62.9 73.1 3.5 2.4 4.6 3.7 4.1 4.9-1.3 3.4-9.5 36.1-11.7 46.7-3.1 15.5-3 31.5.6 49.4 3.5 18.2 3.4 21.5-1 30.4-4.7 9.4-13.2 22.1-18.6 27.7-2.4 2.5-11.1 10.4-19.2 17.5-34.1 29.8-37.2 31.5-62.2 33.5-16.9 1.3-21.2 2.5-36.9 10.2l-13 6.3-44.5.1-44.5.2-12.5 5c-20.9 8.5-29.4 9.8-44.5 6.6zM1375.5 785.8c-3.7-10-4.4-13.2-3.3-13.9 1.9-1.2 2.6-.3 4.3 5.9.9 3.1 1.8 6.5 2.1 7.5.6 2-2.4 2.5-3.1.5zM1380.7 782.6c-.4-1 1.3-2 5.6-3.6 9.5-3.4 23.7-10.8 28.5-14.7 7.2-5.9 8.8-11.1 5.2-17.1-5.7-9.4-24.3-9.7-43.7-.7-8.6 4-10.7 2.9-3.1-1.5 11.9-6.8 25.5-10 34.3-8.1 9.4 2.1 17.5 9.3 17.5 15.5 0 8.6-11.6 18.1-33.3 27.4-5.4 2.3-9.9 4.2-10.1 4.2-.2 0-.6-.6-.9-1.4z"/><path d="M1378.2 774.3c-1.1-3.7-.9-5.3 1-5.3 1.7 0 18.1-7.9 20-9.7 2.5-2.2 2.3-5.1-.5-5.8-2.3-.6-10 1.5-19.5 5.4l-5.3 2.1-1.8-4.2-1.8-4.3 4.6-2.4c7.3-3.8 18-7.1 25.1-7.7 5.4-.5 7.5-.3 11.3 1.4 5.1 2.3 9 7.4 8.1 10.7-1 3.7-10.1 11.1-18.6 15.3-8.7 4.2-18.5 8.2-20.4 8.2-.6 0-1.6-1.6-2.2-3.7z"/><path d="M1369.6 769.3c-2.3-2.3 4.7-6.4 19.3-11.3 12.2-4.1 11.8-1.5-.6 4.3-10.9 5-18 7.7-18.7 7zM1365.6 756.5c-3.1-9.5-1.6-10.9 2.4-2.1 3.4 7.5 3.5 8.2 1.6 8.9-1.1.4-2.1-1.4-4-6.8zM672.3 707.4c-4.9-1.8-12-8.5-13-12.3-.7-2.6 1.3-60.3 2.3-67.7l.6-4.2 5.8-.6c3.3-.4 8.3-1.4 11.2-2.2 16.2-4.5 24.1-6.3 30.7-6.9l7.3-.7-.3 38.7-.4 38.7-6 5.6c-11.6 10.8-27.3 15.6-38.2 11.6zM754.1 705.5c-8.1-1.8-17.6-6.3-22.2-10.6l-3.7-3.4.5-39.4.6-39.4 7.8.7c9.7.8 44.1 6.5 45.1 7.4.4.4 1.4 8.1 2.3 17.2 2.1 20.4 1.7 45-.9 52.1-4.6 12.6-15.6 18.4-29.5 15.4zM453.8 616.5c-43.5-6.8-87.7-37.3-116.7-80.4-16.4-24.3-20-36.7-20.8-72.2-.6-25.1.4-39.1 4.2-58.4 11.4-57.3 38.8-101 81.4-129.6 49-33 132.7-53.8 248.6-61.9 31.8-2.2 107.8-3.3 140.9-2.1 138.2 5 222.7 27 270 70.2 33.4 30.6 55.2 72.2 63.6 121.3 6 35.2 4 78.4-4.7 99-3.5 8.5-12 22.7-18.8 31.6-26.9 34.8-59.3 57.1-97 66.7-10.5 2.7-12.1 2.8-34 2.8-28.6 0-44.5-2.2-70.4-9.7-18.9-5.4-39.3-14.7-52.6-23.9-6.4-4.4-7.2-5.4-9-10.6-5.2-15.2-21.8-29.7-44.9-38.9l-8-3.3-1.1-4.9c-1.3-5.7-4.1-9.9-9.3-14-17.4-13.8-52.1-18.1-79.7-10-20.3 5.9-32.2 18.1-29.5 30.2l.7 3.3-8.6 3.9c-18.5 8.3-35 22.2-41.9 35.2-2.6 4.9-5.1 7.7-11 12.4-19.6 15.7-43 27.7-68.4 35.4-27.3 8.2-60.7 11.3-83 7.9zm83.7-50.9c29.7-5.2 58.3-17.2 80.7-33.8 11.1-8.2 30.3-25.4 37-33.1 17.2-19.7 27.5-39.9 32.9-64.7 3.1-13.7 3.3-39.7.6-53.3-9.1-44.9-38-81.8-79.8-101.6-39.3-18.7-79.7-19.9-123.9-3.8-66.2 24.1-109.2 65.8-122.5 118.7-3.7 14.8-4.8 24.2-4.7 41 .1 16.9 1.6 28 5.7 40.9 13.5 42.7 49.3 74.4 97.5 86.6 8.3 2.1 12.5 2.8 27.5 4.9 6.1.9 41.3-.4 49-1.8zm413-18.6c37.9-3.7 70.6-17.5 93.5-39.6 18.4-17.7 29.5-39.4 33.7-65.8 2.4-15.5 1.4-48.9-2.1-65.3-14.4-68.2-64.7-110.1-147.6-122.8-14.5-2.2-48.3-3.1-59.1-1.6-47 6.8-86.5 33-109.3 72.8-13.1 22.8-18.3 44.6-17.3 73.1.6 18.3 2.7 29.3 8.7 44.7 9.5 24.5 27.9 48 49.7 63.7 10.4 7.5 35 20.7 48.3 26 32.7 12.8 68.2 18 101.5 14.8z"/><path d="M480.2 557.4c-24.5-3.5-48.5-13.1-67.2-26.7-14.4-10.5-30.4-30.5-37-46.3-11.8-28.3-12.8-63.9-2.8-95.3 7.1-22.5 17.4-38.9 35.7-57.1 10.8-10.7 22.1-20.2 22.1-18.7 0 .3-1.6 2.5-3.7 4.9-9.6 11.4-19.2 28.7-24.1 43.5-5.7 16.8-6.7 23.8-6.7 45.3.1 17 .4 20.7 2.4 29 7 28.4 20.6 52 41.3 71.5 26.5 24.9 59.6 38.6 96.8 40.2 13.1.5 30-.6 34.5-2.3.8-.3 1.5-.1 1.5.4 0 1.2-14.5 6.1-25.5 8.7-19.5 4.5-47.9 5.8-67.3 2.9z"/><path d="M527.5 535.4c-17.2-2.5-29.8-6.2-43.4-12.5-39.8-18.6-67.6-54.5-74.7-96.4-2.4-14.3-1.5-37.3 2-50.5 6.5-24.4 16.8-42.3 34.5-60.1 34.1-34 84.4-47.5 132.1-35.4 50.9 13 89.1 52.6 99.1 103 2.1 10.4 1.8 36.8-.5 47.3-5.4 25.2-17.3 47-35.6 65.2-18.8 18.9-42.4 31.5-70 37.5-7.3 1.6-36.9 2.9-43.5 1.9zm110.6-82.6c12.1-6 21.1-16.9 24.3-29.3 6.9-26.1-10.1-52-37.1-56.7-21.6-3.7-43.4 9.8-50.3 31.1-1.9 6.1-2.2 8.6-1.8 16.7.5 8.4 1 10.3 4.2 16.9 5.9 11.9 15.2 19.9 28.1 24.1 2.5.9 7.8 1.3 14.6 1.1 9.9-.2 11-.4 18-3.9z"/><path d="M627.8 428.4c-3.1-1.6-5.8-6.1-5.8-9.5 0-3.4 3.8-8.6 7.1-9.8 6-2.1 13 1.7 14.4 7.9.9 4-1.7 9.6-5.4 11.4-3.7 2-6.8 2-10.3 0zM912.5 538.4c-18.5-2.1-25.8-4.4-13.7-4.4 10.9 0 27.8-3.4 42.2-8.5 42.7-15.1 77-50.6 89.8-93 4.6-15 5.7-23.3 5.6-41-.1-12.5-.6-18.3-2.3-26.5-4-18.9-11.8-36.8-23.2-53-6.8-9.7-24.4-27.2-33.7-33.5-4-2.7-6.9-5.1-6.4-5.3 1.6-.5 19.7 7.4 28.7 12.5 30.2 17.2 52.1 43.1 62.5 74.1 8.9 26.7 11 65.2 5 90.1-11.9 48.9-53.3 80.6-115 88.1-7.8.9-32.4 1.2-39.5.4z"/><path d="M880 522.3c-51.6-3.7-96.5-34.8-116.1-80.3-6.8-15.7-9-26.1-9.6-45-.4-12.4-.1-18.7 1.1-25.5 8.4-48.5 46.6-90.1 95.1-103.6 18.9-5.2 43.3-6.6 62.2-3.3 50.5 8.5 92.4 44.5 106.7 91.4 7.5 24.7 7.2 51.4-.9 75.7-6.1 18.2-15.1 33.4-28.2 47.3-23.4 24.9-54.3 39.8-88.8 43-10.7 1-12.2 1-21.5.3zM980.2 441c12.3-4.6 23.2-15.9 27.4-28.2 2.8-8.2 2.5-21.5-.6-30.1-4.6-12.9-15.6-23.4-29-27.7-5.8-1.9-8.6-2.2-16.4-1.8-8.3.3-10.2.8-16.8 4.1-9.7 4.7-16.8 11.8-21.5 21.5-3.2 6.4-3.7 8.5-4.1 16.4-.6 11.1 1.5 19.5 6.7 27.6 6.5 9.9 17.7 17.9 28.4 20.2 6.7 1.4 19.5.5 25.9-2z"/><path d="M971.3 412.5c-3.2-3.2-3.5-3.9-3-7.8 1.5-11.3 16-13.4 20.4-3 2.8 6.9-2.3 14.3-9.9 14.3-3.2 0-4.7-.7-7.5-3.5zM646.5 610.9c-7.7-1.2-15.6-5.1-18.9-9.4-3.6-4.7-6-14.5-5.2-21.5 1.4-11.8 9.9-24.1 23.2-33.6 5.9-4.2 25.7-14.4 28-14.4.6 0 3.8 1.6 7 3.5 21.6 13 61.7 13.9 85.6 1.9 3.7-1.9 8.3-4.7 10.2-6.4l3.4-3.1 6.7 2.5c13 5 22.7 10.7 30.1 18.1 9.9 9.8 11.9 14.3 11.9 27 0 8.9-.4 10.7-2.9 16.3-7.8 17-23.1 20.3-62.1 13.3-30.8-5.5-58.7-5.2-77.3.9-14.3 4.7-29 6.5-39.7 4.9zM290.1 500.9c-22.4-4.4-35.5-15.2-41.9-34.7-2.1-6.5-2.5-9.6-2.6-20.2 0-6.9.2-13 .6-13.5.4-.7 5.1-.6 14.5.3 12 1.1 41.3 1.2 45 .1 1-.3 1.4 5.5 1.7 25.6.3 22.6 1 31.8 3.1 41.3.5 2.1.4 2.2-7.7 2.1-4.6-.1-10.3-.5-12.7-1zM1139 492.1c-3-.3-5.4-1-5.3-1.6 2.4-15 3.4-29.6 3.1-47.7l-.3-20.8 3.5.8c7.5 1.6 29.2.5 45.4-2.2 8.7-1.5 16.1-2.4 16.5-2.1 1.3 1.4.6 41.8-.8 47.5-2.1 8.5-5.5 15.3-8.9 18.2-8.5 7.2-30.1 10.4-53.2 7.9zM279.3 423.4c.3-1.1 1.8-7.3 3.2-13.9 3.6-16.3 10.1-42.3 13-52.1 5.4-17.8 20.8-45.6 47.9-86.6l1.8-2.8-2.8-1.1c-4.2-1.6-17.4-4.9-19.6-4.9-3 0-3-2-.3-14.1 3.6-16.2 8-30.1 12.5-39.5 6.1-12.8 18.3-23.5 39.1-34.8l8.6-4.6.7 3.1c.3 1.7.6 5.7.6 8.8 0 7.9 2.6 31.5 5 45.2 2.3 13.7 6.1 27.2 9.5 34.3l2.5 5.1-2.2 1.5c-16.6 11.1-37 30.2-47.9 45-20.7 28.1-34.8 62.8-40.5 100.2-1.4 8.9-2.2 11.7-3.4 11.7-.8 0-7.5.4-14.9.7-12.7.6-13.3.6-12.8-1.2z"/><path d="M256.5 416.7c-24.4-9.9-39.4-26.4-44.1-48.8-4.5-21 2.8-52 16.3-69.9 10.7-14.1 28.1-23.2 49.8-26.1 14.5-1.9 47.4.7 46.8 3.7-.1.6-4.2 7.4-9.1 15.3-5 7.8-11.2 18.3-13.8 23.2l-4.9 8.9-4.5-.7c-18.2-2.6-30.5 2.3-33.8 13.3-2.1 7.1-1.5 16.3 1.3 22.1 2.3 4.5 8.7 11.7 15.2 17l2.2 1.8-2.8 12c-1.6 6.6-3.9 16.4-5.1 21.8-1.7 7.5-2.5 9.7-3.8 9.7-.9 0-5.3-1.5-9.7-3.3zM1141 413.7c-4.7-1-5.5-1.5-5.8-3.7-.9-7.2-5.6-28.7-8.2-37.3-16.7-56.1-53.4-101.8-100.5-125.4-4.9-2.5-9.1-4.6-9.2-4.7-.2-.2 2.4-6.5 5.8-14.2 3.3-7.6 7.8-18.4 10.1-23.9 3.1-7.8 26.3-58 27.3-59.3.1-.2 4.7 2.8 10.1 6.6 5.5 3.8 15 10.4 21.2 14.7 11.5 8 20.7 17.6 25.1 26.3 1 2.1 5.9 16.3 10.9 31.7 5 15.4 9.4 28.8 9.7 29.7.5 1.3 0 1.9-2.2 2.4-7.5 1.6-18 4.6-19.2 5.4-1.1.6.9 5.7 9.8 25 22.5 48.6 29.9 67.4 32.7 83 1.8 10.1 4 41 3.1 43.4-.5 1.3-2 1.6-7.9 1.5-4 0-9.8-.6-12.8-1.2z"/><path d="M1173.6 399.3c-.3-4.3-1.1-12.9-1.7-19.1-.6-6.3-.9-11.5-.7-11.6.2-.2 2.8-1.7 5.8-3.4 6.7-3.7 13.5-10.3 16.3-15.7 4.8-9 1.6-22.9-7-30.5-6.5-5.7-12.3-7.3-24.9-6.9l-10.5.4-9.8-21.3c-5.4-11.7-9.6-21.4-9.2-21.6 1.4-.9 16.6-2.6 23.1-2.6 38 0 62.8 18.4 73.6 54.5 2.1 6.9 2.8 11.9 3.1 21.5.6 14.1-.6 20.9-5.4 30.8-3.9 8-15.9 19.8-24.8 24.4-6.3 3.3-22.7 8.8-26 8.8-.9 0-1.5-2.3-1.9-7.7zM402.2 254.3c-6-15.6-10.2-39.8-12.3-70.7l-1.3-17.9 8-7.6c4.7-4.6 14.3-11.9 23.9-18.3 19-12.5 33.2-24.5 51.5-43.5 17.6-18.2 29.4-26 72.5-47.8 36.7-18.6 41.3-20 95-28.9 14.9-2.5 32.8-5.7 39.9-7.1 7-1.4 12.9-2.5 13.1-2.5.7 0 1.5 5.5 3.9 26 5.6 47.8 5.9 52.8 6.1 105.5.1 27.5.5 52.5.9 55.6l.8 5.7-15.8.6c-122.7 5-210.4 22-270.4 52.7-6.4 3.2-12 5.9-12.3 5.9-.3 0-1.9-3.5-3.5-7.7zM1000.4 236c-35.5-13.7-89.9-24.5-147.9-29.4-36.8-3.2-54.1-3.9-98-4l-45-.1-.7-13.5c-.4-7.4-.6-31.7-.6-54 .2-43.2-.6-55.3-6.7-104.9-1.4-10.7-2.2-19.7-1.9-20 1-1.1 51.7-.4 66.4.8 33.4 2.7 58.8 6.4 70.5 10.1 3.3 1 11.4 4.1 18 6.8 10.7 4.4 43.9 16.3 70.5 25.3 20.3 6.8 41.7 14.7 46.6 17.2 11.3 5.7 37.8 27.4 68.6 56.1l15.7 14.6-2.8 6.3c-1.6 3.4-6.3 13.4-10.6 22.2-4.2 8.8-9.8 21.2-12.4 27.5-10 24-18.4 43-19 42.9-.3 0-5.2-1.8-10.7-3.9z"/></g></svg>
\ No newline at end of file
diff --git a/static/shared/icon/alert_gm_grey_24dp.svg b/static/shared/icon/alert_gm_grey_24dp.svg
new file mode 100644
index 0000000..d5adf84
--- /dev/null
+++ b/static/shared/icon/alert_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><g><rect fill="none" height="24" width="24" y="0"/></g><g><g><path d="M21.26,18L13.73,4.99c-0.77-1.33-2.69-1.33-3.46,0L2.74,18c-0.77,1.33,0.19,3,1.73,3h15.06C21.07,21,22.03,19.33,21.26,18 z M4.47,19L12,5.99L19.53,19H4.47z"/><path d="M11,11v2c0,0.55,0.45,1,1,1c0.55,0,1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,10,11,10.45,11,11z"/><circle cx="12" cy="17" r="1"/></g></g></svg>
\ No newline at end of file
diff --git a/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg b/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg
new file mode 100644
index 0000000..4f24323
--- /dev/null
+++ b/static/shared/icon/arrow_drop_down_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M7 10l5 5 5-5H7z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/arrow_drop_up_gm_grey_24dp.svg b/static/shared/icon/arrow_drop_up_gm_grey_24dp.svg
new file mode 100644
index 0000000..6f1b558
--- /dev/null
+++ b/static/shared/icon/arrow_drop_up_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M7 14l5-5 5 5H7z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/arrow_left_alt_gm_grey_24dp.svg b/static/shared/icon/arrow_left_alt_gm_grey_24dp.svg
new file mode 100644
index 0000000..257c171
--- /dev/null
+++ b/static/shared/icon/arrow_left_alt_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><g><rect fill="none" height="24" width="24"/></g><g><polygon fill-rule="evenodd" points="10,18 11.41,16.59 7.83,13 20,13 20,11 7.83,11 11.41,7.41 10,6 4,12"/></g></svg>
\ No newline at end of file
diff --git a/static/shared/icon/arrow_left_gm_grey_24dp.svg b/static/shared/icon/arrow_left_gm_grey_24dp.svg
new file mode 100644
index 0000000..5f099d0
--- /dev/null
+++ b/static/shared/icon/arrow_left_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M14 7l-5 5 5 5V7z"/><path d="M24 0v24H0V0h24z" fill="none" opacity=".87"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/arrow_right_alt_gm_grey_24dp.svg b/static/shared/icon/arrow_right_alt_gm_grey_24dp.svg
new file mode 100644
index 0000000..f94fb16
--- /dev/null
+++ b/static/shared/icon/arrow_right_alt_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M14 6l-1.41 1.41L16.17 11H4v2h12.17l-3.58 3.59L14 18l6-6z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/arrow_right_gm_grey_24dp.svg b/static/shared/icon/arrow_right_gm_grey_24dp.svg
new file mode 100644
index 0000000..7460cb0
--- /dev/null
+++ b/static/shared/icon/arrow_right_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 17l5-5-5-5v10z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/brightness_2_gm_grey_24dp.svg b/static/shared/icon/brightness_2_gm_grey_24dp.svg
new file mode 100644
index 0000000..76e555b
--- /dev/null
+++ b/static/shared/icon/brightness_2_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 2c-1.82 0-3.53.5-5 1.35C7.99 5.08 10 8.3 10 12s-2.01 6.92-5 8.65C6.47 21.5 8.18 22 10 22c5.52 0 10-4.48 10-10S15.52 2 10 2z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/brightness_6_gm_grey_24dp.svg b/static/shared/icon/brightness_6_gm_grey_24dp.svg
new file mode 100644
index 0000000..fbde09f
--- /dev/null
+++ b/static/shared/icon/brightness_6_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 15.31L23.31 12 20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69zM12 18V6c3.31 0 6 2.69 6 6s-2.69 6-6 6z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/call_split_gm_grey_24dp.svg b/static/shared/icon/call_split_gm_grey_24dp.svg
new file mode 100644
index 0000000..8839733
--- /dev/null
+++ b/static/shared/icon/call_split_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 6V4H4v6h2V7.42l5 4.99V20h2v-8.41L7.42 6zm4-2v2h2.58l-3.17 3.17 1.42 1.42L18 7.42V10h2V4z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/cancel_gm_grey_24dp.svg b/static/shared/icon/cancel_gm_grey_24dp.svg
new file mode 100644
index 0000000..3b5d677
--- /dev/null
+++ b/static/shared/icon/cancel_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none" opacity=".87"/><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3.59-13L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/check_circle_gm_grey_24dp.svg b/static/shared/icon/check_circle_gm_grey_24dp.svg
new file mode 100644
index 0000000..c05117b
--- /dev/null
+++ b/static/shared/icon/check_circle_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-2-5.8l-2.6-2.6L6 13l4 4 8-8-1.4-1.4z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/chrome_reader_mode_gm_grey_24dp.svg b/static/shared/icon/chrome_reader_mode_gm_grey_24dp.svg
new file mode 100644
index 0000000..7c4537a
--- /dev/null
+++ b/static/shared/icon/chrome_reader_mode_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 18V6h7v12H4zm16 0h-7V6h7v12zm-6-9.5h5V10h-5zm0 2.5h5v1.5h-5zm0 2.5h5V15h-5zm-7.25-.81"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/close_gm_grey_24dp.svg b/static/shared/icon/close_gm_grey_24dp.svg
new file mode 100644
index 0000000..6840fbe
--- /dev/null
+++ b/static/shared/icon/close_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/code_gm_grey_24dp.svg b/static/shared/icon/code_gm_grey_24dp.svg
new file mode 100644
index 0000000..dfeed30
--- /dev/null
+++ b/static/shared/icon/code_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M16 6l-1.41 1.41L19.17 12l-4.58 4.59L16 18l6-6zM8 18l1.41-1.41L4.83 12l4.58-4.59L8 6l-6 6z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/content_copy_gm_grey_24dp.svg b/static/shared/icon/content_copy_gm_grey_24dp.svg
new file mode 100644
index 0000000..8c8a652
--- /dev/null
+++ b/static/shared/icon/content_copy_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M18 21H4V7H2v14c0 1.1.9 2 2 2h14v-2zm3-4V3c0-1.1-.9-2-2-2H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2zm-2 0H8V3h11v14z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/depsdev-logo.svg b/static/shared/icon/depsdev-logo.svg
new file mode 100644
index 0000000..304e267
--- /dev/null
+++ b/static/shared/icon/depsdev-logo.svg
@@ -0,0 +1,5 @@
+<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5872 16.2042L15.8035 18.4205C16.0642 18.6735 16.0642 19.0877 15.8111 19.3484L15.8035 19.3561L3.34168 31.8102C3.08861 32.0633 2.67449 32.0633 2.42142 31.8102L0.189803 29.5786C-0.0632676 29.3255 -0.0632676 28.9114 0.189803 28.6583L12.6516 16.1965C12.9047 15.9358 13.3188 15.9358 13.5795 16.1889C13.5795 16.1965 13.5872 16.2042 13.5872 16.2042Z" fill="#1AAC94"/>
+<circle cx="17" cy="15" r="13" stroke="#32E0C4" stroke-width="4"/>
+<circle cx="17" cy="15" r="4" stroke="#32E0C4" stroke-width="4"/>
+</svg>
diff --git a/static/shared/icon/favicon.ico b/static/shared/icon/favicon.ico
new file mode 100644
index 0000000..8d22584
--- /dev/null
+++ b/static/shared/icon/favicon.ico
Binary files differ
diff --git a/static/shared/icon/filter_list_gm_grey_24dp.svg b/static/shared/icon/filter_list_gm_grey_24dp.svg
new file mode 100644
index 0000000..884b9e3
--- /dev/null
+++ b/static/shared/icon/filter_list_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/folder_gm_grey_24dp.svg b/static/shared/icon/folder_gm_grey_24dp.svg
new file mode 100644
index 0000000..bcbf551
--- /dev/null
+++ b/static/shared/icon/folder_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/help_gm_grey_24dp.svg b/static/shared/icon/help_gm_grey_24dp.svg
new file mode 100644
index 0000000..be81972
--- /dev/null
+++ b/static/shared/icon/help_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/horizontal_split_gm_grey_24dp.svg b/static/shared/icon/horizontal_split_gm_grey_24dp.svg
new file mode 100644
index 0000000..2c9e9d2
--- /dev/null
+++ b/static/shared/icon/horizontal_split_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M21 5H3v2h18V5zm0 4H3v2h18V9zm0 4H3v6h18v-6z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/icon.css b/static/shared/icon/icon.css
new file mode 100644
index 0000000..8a0c212
--- /dev/null
+++ b/static/shared/icon/icon.css
@@ -0,0 +1,26 @@
+/*!
+ * 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.
+ */
+
+.depsdev-Icon {
+  height: 1.125em;
+  vertical-align: text-bottom;
+  width: auto;
+}
+
+.go-Icon {
+  filter: none;
+  height: 1.125em;
+  vertical-align: text-bottom;
+  width: auto;
+}
+.go-Icon--accented {
+  filter: brightness(0) invert(45%) sepia(94%) saturate(6735%) hue-rotate(176deg) brightness(94%)
+    contrast(101%);
+}
+.go-Icon--inverted {
+  filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg)
+    brightness(103%) contrast(107%);
+}
diff --git a/static/shared/icon/icon.md b/static/shared/icon/icon.md
new file mode 100644
index 0000000..8e53dd8
--- /dev/null
+++ b/static/shared/icon/icon.md
@@ -0,0 +1,139 @@
+## Icons
+
+---
+
+<span style="display:contents;">
+  <go-icon name="alert"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="arrow_drop_up"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="arrow_drop_down"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="arrow_left"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="arrow_left_alt"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="arrow_right"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="arrow_right_alt"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="brightness_2"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="brightness_6"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="call_split"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="cancel"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="check_circle"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="chrome_reader_mode"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="close"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="code"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="content_copy"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="filter_list"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="folder"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="help"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="info"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="insert_drive_file"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="keyboard"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="launch"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="light_mode"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="list"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="menu"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="more_vert"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="navigate_before"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="navigate_next"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="responsive_layout"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="search"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="star"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="table_rows"></go-icon>
+</span>
+
+<span style="display:contents;">
+  <go-icon name="toolbar"></go-icon>
+</span>
diff --git a/static/shared/icon/info_gm_grey_24dp.svg b/static/shared/icon/info_gm_grey_24dp.svg
new file mode 100644
index 0000000..ba73bf2
--- /dev/null
+++ b/static/shared/icon/info_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/insert_drive_file_gm_grey_24dp.svg b/static/shared/icon/insert_drive_file_gm_grey_24dp.svg
new file mode 100644
index 0000000..dd8ca81
--- /dev/null
+++ b/static/shared/icon/insert_drive_file_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/keyboard_grey_24dp.svg b/static/shared/icon/keyboard_grey_24dp.svg
new file mode 100644
index 0000000..faea75d
--- /dev/null
+++ b/static/shared/icon/keyboard_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/><path d="M0 0h24v24H0zm0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/launch_gm_grey_24dp.svg b/static/shared/icon/launch_gm_grey_24dp.svg
new file mode 100644
index 0000000..656d73e
--- /dev/null
+++ b/static/shared/icon/launch_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/light_mode_gm_grey_24dp.svg b/static/shared/icon/light_mode_gm_grey_24dp.svg
new file mode 100644
index 0000000..e5cd8da
--- /dev/null
+++ b/static/shared/icon/light_mode_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><rect fill="none" height="24" width="24"/><path d="M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0 c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2 c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1 C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06 c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41 l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41 c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36 c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/list_gm_grey_24dp.svg b/static/shared/icon/list_gm_grey_24dp.svg
new file mode 100644
index 0000000..2385eb0
--- /dev/null
+++ b/static/shared/icon/list_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none" opacity=".87"/><path d="M0 0h24v24H0V0z" fill="none"/><path d="M4 13c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0 4c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm0-8c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1zm3 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/menu_gm_grey_24dp.svg b/static/shared/icon/menu_gm_grey_24dp.svg
new file mode 100644
index 0000000..6b49702
--- /dev/null
+++ b/static/shared/icon/menu_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/more_vert_gm_grey_24dp.svg b/static/shared/icon/more_vert_gm_grey_24dp.svg
new file mode 100644
index 0000000..0e809ca
--- /dev/null
+++ b/static/shared/icon/more_vert_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/navigate_before_gm_grey_24dp.svg b/static/shared/icon/navigate_before_gm_grey_24dp.svg
new file mode 100644
index 0000000..f790237
--- /dev/null
+++ b/static/shared/icon/navigate_before_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12l4.58-4.59z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/navigate_next_gm_grey_24dp.svg b/static/shared/icon/navigate_next_gm_grey_24dp.svg
new file mode 100644
index 0000000..b44fd75
--- /dev/null
+++ b/static/shared/icon/navigate_next_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6-6-6z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/responsive_layout_gm_grey_24dp.svg b/static/shared/icon/responsive_layout_gm_grey_24dp.svg
new file mode 100644
index 0000000..b58b9ec
--- /dev/null
+++ b/static/shared/icon/responsive_layout_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><rect fill="none" height="24" width="24"/><g><rect fill="none" height="24" width="24"/><g><g><path d="M8,2v6H2v14h20V2H8z M8,20H4V10h4V20z M20,20h-4V8h-6V4h10V20z"/></g></g></g></svg>
\ No newline at end of file
diff --git a/static/shared/icon/search_gm_grey_24dp.svg b/static/shared/icon/search_gm_grey_24dp.svg
new file mode 100644
index 0000000..aa154bf
--- /dev/null
+++ b/static/shared/icon/search_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20.49 19l-5.73-5.73C15.53 12.2 16 10.91 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.41 0 2.7-.47 3.77-1.24L19 20.49 20.49 19zM5 9.5C5 7.01 7.01 5 9.5 5S14 7.01 14 9.5 11.99 14 9.5 14 5 11.99 5 9.5z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/side_navigation_gm_grey_24dp.svg b/static/shared/icon/side_navigation_gm_grey_24dp.svg
new file mode 100644
index 0000000..39b7de1
--- /dev/null
+++ b/static/shared/icon/side_navigation_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><g><rect fill="none" height="24" width="24"/><path d="M2,22h20V2H2V22z M20,20h-8V4h8V20z"/></g></svg>
\ No newline at end of file
diff --git a/static/shared/icon/star_gm_grey_24dp.svg b/static/shared/icon/star_gm_grey_24dp.svg
new file mode 100644
index 0000000..d0bde17
--- /dev/null
+++ b/static/shared/icon/star_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none"/><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/table_rows_gm_grey_24dp.svg b/static/shared/icon/table_rows_gm_grey_24dp.svg
new file mode 100644
index 0000000..22035ec
--- /dev/null
+++ b/static/shared/icon/table_rows_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><rect fill="none" height="24" width="24"/><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,5v3H5V5H19z M19,10v4H5v-4H19z M5,19v-3h14v3H5z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/toolbar_gm_grey_24dp.svg b/static/shared/icon/toolbar_gm_grey_24dp.svg
new file mode 100644
index 0000000..bb2d026
--- /dev/null
+++ b/static/shared/icon/toolbar_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0z" fill="none"/><path d="M2 2v20h20V2H2zm2 2h16v3H4V4zm0 16V9h16v11H4z"/></svg>
\ No newline at end of file
diff --git a/static/shared/icon/vertical_split_gm_grey_24dp.svg b/static/shared/icon/vertical_split_gm_grey_24dp.svg
new file mode 100644
index 0000000..1deb958
--- /dev/null
+++ b/static/shared/icon/vertical_split_gm_grey_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#455A64"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M3 13h8v2H3zm0 4h8v2H3zm0-8h8v2H3zm0-4h8v2H3zm18 0h-8v14h8V5z"/></svg>
\ No newline at end of file
diff --git a/static/shared/jump/jump.ts b/static/shared/jump/jump.ts
new file mode 100644
index 0000000..d671a56
--- /dev/null
+++ b/static/shared/jump/jump.ts
@@ -0,0 +1,298 @@
+/*!
+ * @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.
+ */
+
+// This file implements the behavior of the "jump to symbol" dialog for Go
+// package documentation, as well as the simple dialog that displays keyboard
+// shortcuts.
+
+// The DOM for the dialogs is at the bottom of static/frontend/unit/main/_modals.tmpl.
+// The CSS is in static/frontend/unit/main/_modals.css.
+
+// The dialog is activated by pressing the 'f' key. It presents a list
+// (#JumpDialog-list) of all Go symbols displayed in the documentation.
+// Entering text in the dialog's text box (#JumpDialog-filter) restricts the
+// list to symbols containing the text. Clicking on an symbol jumps to
+// its documentation.
+
+// This code is based on
+// https://go.googlesource.com/gddo/+/refs/heads/master/gddo-server/assets/site.js.
+// It was modified to remove the dependence on jquery and bootstrap.
+
+import { keyboard } from '../keyboard/keyboard';
+
+export function initModals(): void {
+  const jumpDialog = document.querySelector<HTMLDialogElement>('.JumpDialog');
+  const jumpBody = jumpDialog?.querySelector<HTMLDivElement>('.JumpDialog-body');
+  const jumpList = jumpDialog?.querySelector<HTMLDivElement>('.JumpDialog-list');
+  const jumpFilter = jumpDialog?.querySelector<HTMLInputElement>('.JumpDialog-input');
+  const doc = document.querySelector<HTMLDivElement>('.js-documentation');
+
+  interface JumpListItem {
+    link: HTMLAnchorElement;
+    name: string;
+    kind: string;
+    lower: string;
+  }
+
+  let jumpListItems: JumpListItem[] | undefined; // All the symbols in the doc; computed only once.
+
+  // collectJumpListItems returns a list of items, one for each symbol in the
+  // documentation on the current page.
+  //
+  // It uses the data-kind attribute generated in the documentation HTML to find
+  // the symbols and their id attributes.
+  //
+  // If there are no data-kind attributes, then we have older doc; fall back to
+  // a less precise method.
+  function collectJumpListItems() {
+    const items = [];
+    if (!doc) return;
+    for (const el of doc.querySelectorAll('[data-kind]')) {
+      items.push(newJumpListItem(el));
+    }
+
+    // Clicking on any of the links closes the dialog.
+    for (const item of items) {
+      item.link.addEventListener('click', function () {
+        jumpDialog?.close();
+      });
+    }
+    // Sort case-insensitively by symbol name.
+    items.sort(function (a, b) {
+      return a.lower.localeCompare(b.lower);
+    });
+    return items;
+  }
+
+  // newJumpListItem creates a new item for the DOM element el.
+  // An item is an object with:
+  // - name: the element's id (which is the symbol name)
+  // - kind: the element's kind (function, variable, etc.),
+  // - link: a link ('a' tag) to the element
+  // - lower: the name in lower case, just for sorting
+  function newJumpListItem(el: Element): JumpListItem {
+    const a = document.createElement('a');
+    const name = el.getAttribute('id');
+    a.setAttribute('href', '#' + name);
+    a.setAttribute('tabindex', '-1');
+    a.setAttribute('data-gtmc', 'jump to link');
+    const kind = el.getAttribute('data-kind');
+    return {
+      link: a,
+      name: name ?? '',
+      kind: kind ?? '',
+      lower: name?.toLowerCase() ?? '', // for sorting
+    };
+  }
+
+  let lastFilterValue: string; // The last contents of the filter text box.
+  let activeJumpItem = -1; // The index of the currently active item in the list.
+
+  // updateJumpList sets the elements of the dialog list to
+  // everything whose name contains filter.
+  function updateJumpList(filter: string) {
+    lastFilterValue = filter;
+    if (!jumpListItems) {
+      jumpListItems = collectJumpListItems();
+    }
+    setActiveJumpItem(-1);
+
+    // Remove all children from list.
+    while (jumpList?.firstChild) {
+      jumpList.firstChild.remove();
+    }
+
+    if (filter) {
+      // A filter is set. We treat the filter as a substring that can appear in
+      // an item name (case insensitive), and find the following matches - in
+      // order of priority:
+      //
+      // 1. Exact matches (the filter matches the item's name exactly)
+      // 2. Prefix matches (the item's name starts with filter)
+      // 3. Infix matches (the filter is a substring of the item's name)
+      const filterLowerCase = filter.toLowerCase();
+
+      const exactMatches = [];
+      const prefixMatches = [];
+      const infixMatches = [];
+
+      // makeLinkHtml creates the link name HTML for a list item. item is the DOM
+      // item. item.name.substr(boldStart, boldEnd) will be bolded.
+      const makeLinkHtml = (item: JumpListItem, boldStart: number, boldEnd: number) => {
+        return (
+          item.name.substring(0, boldStart) +
+          '<b>' +
+          item.name.substring(boldStart, boldEnd) +
+          '</b>' +
+          item.name.substring(boldEnd)
+        );
+      };
+
+      for (const item of jumpListItems ?? []) {
+        const nameLowerCase = item.name.toLowerCase();
+
+        if (nameLowerCase === filterLowerCase) {
+          item.link.innerHTML = makeLinkHtml(item, 0, item.name.length);
+          exactMatches.push(item);
+        } else if (nameLowerCase.startsWith(filterLowerCase)) {
+          item.link.innerHTML = makeLinkHtml(item, 0, filter.length);
+          prefixMatches.push(item);
+        } else {
+          const index = nameLowerCase.indexOf(filterLowerCase);
+          if (index > -1) {
+            item.link.innerHTML = makeLinkHtml(item, index, index + filter.length);
+            infixMatches.push(item);
+          }
+        }
+      }
+
+      for (const item of exactMatches.concat(prefixMatches).concat(infixMatches)) {
+        jumpList?.appendChild(item.link);
+      }
+    } else {
+      if (!jumpListItems || jumpListItems.length === 0) {
+        const msg = document.createElement('i');
+        msg.innerHTML = 'There are no symbols on this page.';
+        jumpList?.appendChild(msg);
+      }
+      // No filter set; display all items in their existing order.
+      for (const item of jumpListItems ?? []) {
+        item.link.innerHTML = item.name + ' <i>' + item.kind + '</i>';
+        jumpList?.appendChild(item.link);
+      }
+    }
+
+    if (jumpBody) {
+      jumpBody.scrollTop = 0;
+    }
+    if (jumpListItems?.length && jumpList && jumpList.children.length > 0) {
+      setActiveJumpItem(0);
+    }
+  }
+
+  // Set the active jump item to n.
+  function setActiveJumpItem(n: number) {
+    const cs = jumpList?.children as HTMLCollectionOf<HTMLElement> | null | undefined;
+    if (!cs || !jumpBody) {
+      return;
+    }
+    if (activeJumpItem >= 0) {
+      cs[activeJumpItem].classList.remove('JumpDialog-active');
+    }
+    if (n >= cs.length) {
+      n = cs.length - 1;
+    }
+    if (n >= 0) {
+      cs[n].classList.add('JumpDialog-active');
+
+      // Scroll so the active item is visible.
+      // For some reason cs[n].scrollIntoView() doesn't behave as I'd expect:
+      // it moves the entire dialog box in the viewport.
+
+      // Get the top and bottom of the active item relative to jumpBody.
+      const activeTop = cs[n].offsetTop - cs[0].offsetTop;
+      const activeBottom = activeTop + cs[n].clientHeight;
+      if (activeTop < jumpBody.scrollTop) {
+        // Off the top; scroll up.
+        jumpBody.scrollTop = activeTop;
+      } else if (activeBottom > jumpBody.scrollTop + jumpBody.clientHeight) {
+        // Off the bottom; scroll down.
+        jumpBody.scrollTop = activeBottom - jumpBody.clientHeight;
+      }
+    }
+    activeJumpItem = n;
+  }
+
+  // Increment the activeJumpItem by delta.
+  function incActiveJumpItem(delta: number) {
+    if (activeJumpItem < 0) {
+      return;
+    }
+    let n = activeJumpItem + delta;
+    if (n < 0) {
+      n = 0;
+    }
+    setActiveJumpItem(n);
+  }
+
+  // Pressing a key in the filter updates the list (if the filter actually changed).
+  jumpFilter?.addEventListener('keyup', function () {
+    if (jumpFilter.value.toUpperCase() != lastFilterValue.toUpperCase()) {
+      updateJumpList(jumpFilter.value);
+    }
+  });
+
+  // Pressing enter in the filter selects the first element in the list.
+  jumpFilter?.addEventListener('keydown', function (event) {
+    const upArrow = 38;
+    const downArrow = 40;
+    const enterKey = 13;
+    switch (event.which) {
+      case upArrow:
+        incActiveJumpItem(-1);
+        event.preventDefault();
+        break;
+      case downArrow:
+        incActiveJumpItem(1);
+        event.preventDefault();
+        break;
+      case enterKey:
+        if (activeJumpItem >= 0) {
+          if (jumpList) {
+            (jumpList.children[activeJumpItem] as HTMLElement).click();
+            event.preventDefault();
+          }
+        }
+        break;
+    }
+  });
+
+  const shortcutsDialog = document.querySelector<HTMLDialogElement>('.ShortcutsDialog');
+
+  // - Pressing 'f' or 'F' opens the jump-to-symbol dialog.
+  // - Pressing '?' opens up the shortcut dialog.
+  // Ignore a keypress if a dialog is already open, or if it is pressed on a
+  // component that wants to consume it.
+  keyboard
+    .on('f', 'open jump to modal', e => {
+      if (jumpDialog?.open || shortcutsDialog?.open) {
+        return;
+      }
+      e.preventDefault();
+      if (jumpFilter) {
+        jumpFilter.value = '';
+      }
+      jumpDialog?.showModal?.();
+      jumpFilter?.focus();
+      updateJumpList('');
+    })
+    .on('?', 'open shortcuts modal', () => {
+      if (jumpDialog?.open || shortcutsDialog?.open) {
+        return;
+      }
+      shortcutsDialog?.showModal?.();
+    });
+
+  const jumpOutlineInput = document.querySelector('.js-jumpToInput');
+  if (jumpOutlineInput) {
+    jumpOutlineInput.addEventListener('click', () => {
+      if (jumpFilter) {
+        jumpFilter.value = '';
+      }
+      updateJumpList('');
+      if (jumpDialog?.open || shortcutsDialog?.open) {
+        return;
+      }
+      jumpDialog?.showModal?.();
+      jumpFilter?.focus();
+    });
+  }
+
+  document.querySelector('.js-openShortcuts')?.addEventListener('click', () => {
+    shortcutsDialog?.showModal?.();
+  });
+}
diff --git a/static/shared/logo/go-blue-gradient.svg b/static/shared/logo/go-blue-gradient.svg
new file mode 100644
index 0000000..baaae77
--- /dev/null
+++ b/static/shared/logo/go-blue-gradient.svg
@@ -0,0 +1 @@
+<svg height="77" viewBox="0 0 206 77" width="206" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" x1="100%" x2="0%" y1="50%" y2="50%"><stop offset="0" stop-color="#00a29c"/><stop offset="1" stop-color="#00add8"/></linearGradient><path d="m127.481483 31.4343267c1.445351-4.5790807 3.790459-8.9059246 6.918517-13 7.3-9.59999996 16.1-14.59999996 28-16.69999996 10.2-1.8 19.8-.8 28.5 5.1 7.9 5.39999996 12.8 12.69999996 14.1 22.29999996 1.7 13.5-2.2 24.5-11.5 33.9-6.6 6.7-14.7 10.9-24 12.8-2.7.5-5.4.6-8 .9-9.1-.2-17.4-2.8-24.4-8.8-4.923224-4.2556681-8.314592-9.4861534-9.999798-15.5752516-1.1695 2.3617137-2.567865 4.6235348-4.200202 6.7752516-7.2 9.5-16.6 15.4-28.5 17-9.8 1.3-18.9-.6-26.9-6.6-7.4-5.6-11.6-13-12.7-22.2-1.3-10.9 1.9-20.7 8.5-29.3 7.1-9.29999996 16.5-15.19999996 28-17.29999996 9.4-1.70000001 18.4-.6 26.5 4.9 5.3 3.5 9.1 8.29999996 11.6 14.09999996.6.9.2 1.4-1 1.7-6.3 1.6-10.6 2.8-16.8 4.4-1.5.4-1.6.5-2.9-1-1.5-1.7-2.6-2.8-4.7-3.8-6.3-3.1-12.4-2.2-18.1 1.5-6.8 4.4-10.3 10.9-10.2 19 .1 8 5.6 14.6 13.5 15.7 6.8.9 12.5-1.5 17-6.6.9-1.1 1.7-2.3 2.7-3.7-3.6 0-8.1 0-19.3 0-2.1 0-2.6-1.3-1.9-3 1.3-3.1 3.7-8.3 5.1-10.9.3-.6 1-1.6 2.5-1.6zm-111.981483-8.2c-.4 0-.5-.2-.3-.5l2.1-2.7c.2-.3.7-.5 1.1-.5h35.7c.4 0 .5.3.3.6l-1.7 2.6c-.2.3-.7.6-1 .6zm-15.1 9.2c-.4 0-.5-.2-.3-.5l2.1-2.7c.2-.3.7-.5 1.1-.5h45.6c.4 0 .6.3.5.6l-.8 2.4c-.1.4-.5.6-.9.6zm24.2 9.2c-.4 0-.5-.3-.3-.6l1.4-2.5c.2-.3.6-.6 1-.6h20c.4 0 .6.3.6.7l-.2 2.4c0 .4-.4.7-.7.7zm160.7-5.3c-.1-1.3-.1-2.3-.3-3.3-1.8-9.9-10.9-15.5-20.4-13.3-9.3 2.1-15.3 8-17.5 17.4-1.8 7.8 2 15.7 9.2 18.9 5.5 2.4 11 2.1 16.3-.6 7.9-4.1 12.2-10.5 12.7-19.1z" fill="url(#a)"/></svg>
diff --git a/static/shared/logo/go-blue.svg b/static/shared/logo/go-blue.svg
new file mode 100644
index 0000000..da6ea83
--- /dev/null
+++ b/static/shared/logo/go-blue.svg
@@ -0,0 +1 @@
+<svg height="78" viewBox="0 0 207 78" width="207" xmlns="http://www.w3.org/2000/svg"><g fill="#00acd7" fill-rule="evenodd"><path d="m16.2 24.1c-.4 0-.5-.2-.3-.5l2.1-2.7c.2-.3.7-.5 1.1-.5h35.7c.4 0 .5.3.3.6l-1.7 2.6c-.2.3-.7.6-1 .6z"/><path d="m1.1 33.3c-.4 0-.5-.2-.3-.5l2.1-2.7c.2-.3.7-.5 1.1-.5h45.6c.4 0 .6.3.5.6l-.8 2.4c-.1.4-.5.6-.9.6z"/><path d="m25.3 42.5c-.4 0-.5-.3-.3-.6l1.4-2.5c.2-.3.6-.6 1-.6h20c.4 0 .6.3.6.7l-.2 2.4c0 .4-.4.7-.7.7z"/><g transform="translate(55)"><path d="m74.1 22.3c-6.3 1.6-10.6 2.8-16.8 4.4-1.5.4-1.6.5-2.9-1-1.5-1.7-2.6-2.8-4.7-3.8-6.3-3.1-12.4-2.2-18.1 1.5-6.8 4.4-10.3 10.9-10.2 19 .1 8 5.6 14.6 13.5 15.7 6.8.9 12.5-1.5 17-6.6.9-1.1 1.7-2.3 2.7-3.7-3.6 0-8.1 0-19.3 0-2.1 0-2.6-1.3-1.9-3 1.3-3.1 3.7-8.3 5.1-10.9.3-.6 1-1.6 2.5-1.6h36.4c-.2 2.7-.2 5.4-.6 8.1-1.1 7.2-3.8 13.8-8.2 19.6-7.2 9.5-16.6 15.4-28.5 17-9.8 1.3-18.9-.6-26.9-6.6-7.4-5.6-11.6-13-12.7-22.2-1.3-10.9 1.9-20.7 8.5-29.3 7.1-9.3 16.5-15.2 28-17.3 9.4-1.7 18.4-.6 26.5 4.9 5.3 3.5 9.1 8.3 11.6 14.1.6.9.2 1.4-1 1.7z"/><path d="m107.2 77.6c-9.1-.2-17.4-2.8-24.4-8.8-5.9-5.1-9.6-11.6-10.8-19.3-1.8-11.3 1.3-21.3 8.1-30.2 7.3-9.6 16.1-14.6 28-16.7 10.2-1.8 19.8-.8 28.5 5.1 7.9 5.4 12.8 12.7 14.1 22.3 1.7 13.5-2.2 24.5-11.5 33.9-6.6 6.7-14.7 10.9-24 12.8-2.7.5-5.4.6-8 .9zm23.8-40.4c-.1-1.3-.1-2.3-.3-3.3-1.8-9.9-10.9-15.5-20.4-13.3-9.3 2.1-15.3 8-17.5 17.4-1.8 7.8 2 15.7 9.2 18.9 5.5 2.4 11 2.1 16.3-.6 7.9-4.1 12.2-10.5 12.7-19.1z" fill-rule="nonzero"/></g></g></svg>
\ No newline at end of file
diff --git a/static/shared/logo/go-white.svg b/static/shared/logo/go-white.svg
new file mode 100644
index 0000000..727a62e
--- /dev/null
+++ b/static/shared/logo/go-white.svg
@@ -0,0 +1 @@
+<svg height="78" viewBox="0 0 207 78" width="207" xmlns="http://www.w3.org/2000/svg"><g fill="#ffffff" fill-rule="evenodd"><path d="m16.2 24.1c-.4 0-.5-.2-.3-.5l2.1-2.7c.2-.3.7-.5 1.1-.5h35.7c.4 0 .5.3.3.6l-1.7 2.6c-.2.3-.7.6-1 .6z"/><path d="m1.1 33.3c-.4 0-.5-.2-.3-.5l2.1-2.7c.2-.3.7-.5 1.1-.5h45.6c.4 0 .6.3.5.6l-.8 2.4c-.1.4-.5.6-.9.6z"/><path d="m25.3 42.5c-.4 0-.5-.3-.3-.6l1.4-2.5c.2-.3.6-.6 1-.6h20c.4 0 .6.3.6.7l-.2 2.4c0 .4-.4.7-.7.7z"/><g transform="translate(55)"><path d="m74.1 22.3c-6.3 1.6-10.6 2.8-16.8 4.4-1.5.4-1.6.5-2.9-1-1.5-1.7-2.6-2.8-4.7-3.8-6.3-3.1-12.4-2.2-18.1 1.5-6.8 4.4-10.3 10.9-10.2 19 .1 8 5.6 14.6 13.5 15.7 6.8.9 12.5-1.5 17-6.6.9-1.1 1.7-2.3 2.7-3.7-3.6 0-8.1 0-19.3 0-2.1 0-2.6-1.3-1.9-3 1.3-3.1 3.7-8.3 5.1-10.9.3-.6 1-1.6 2.5-1.6h36.4c-.2 2.7-.2 5.4-.6 8.1-1.1 7.2-3.8 13.8-8.2 19.6-7.2 9.5-16.6 15.4-28.5 17-9.8 1.3-18.9-.6-26.9-6.6-7.4-5.6-11.6-13-12.7-22.2-1.3-10.9 1.9-20.7 8.5-29.3 7.1-9.3 16.5-15.2 28-17.3 9.4-1.7 18.4-.6 26.5 4.9 5.3 3.5 9.1 8.3 11.6 14.1.6.9.2 1.4-1 1.7z"/><path d="m107.2 77.6c-9.1-.2-17.4-2.8-24.4-8.8-5.9-5.1-9.6-11.6-10.8-19.3-1.8-11.3 1.3-21.3 8.1-30.2 7.3-9.6 16.1-14.6 28-16.7 10.2-1.8 19.8-.8 28.5 5.1 7.9 5.4 12.8 12.7 14.1 22.3 1.7 13.5-2.2 24.5-11.5 33.9-6.6 6.7-14.7 10.9-24 12.8-2.7.5-5.4.6-8 .9zm23.8-40.4c-.1-1.3-.1-2.3-.3-3.3-1.8-9.9-10.9-15.5-20.4-13.3-9.3 2.1-15.3 8-17.5 17.4-1.8 7.8 2 15.7 9.2 18.9 5.5 2.4 11 2.1 16.3-.6 7.9-4.1 12.2-10.5 12.7-19.1z" fill-rule="nonzero"/></g></g></svg>
\ No newline at end of file
diff --git a/static/shared/logo/google-white.svg b/static/shared/logo/google-white.svg
new file mode 100644
index 0000000..d017d2a
--- /dev/null
+++ b/static/shared/logo/google-white.svg
@@ -0,0 +1 @@
+<svg width="74" height="24" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" fill-rule="evenodd"><path d="M.128 9.276c0-5.105 4.32-9.261 9.457-9.261 2.842 0 4.865 1.107 6.388 2.552l-1.796 1.785c-1.091-1.017-2.569-1.807-4.592-1.807-3.75 0-6.683 3.004-6.683 6.731s2.932 6.732 6.683 6.732c2.432 0 3.82-.971 4.706-1.853.727-.722 1.204-1.761 1.386-3.184H9.585V8.44h8.57c.091.451.137.993.137 1.58 0 1.898-.523 4.248-2.206 5.92-1.636 1.693-3.728 2.597-6.5 2.597-5.139 0-9.458-4.156-9.458-9.262M25.218 16.189c-1.819 0-3.387-1.491-3.387-3.615 0-2.146 1.568-3.614 3.387-3.614 1.818 0 3.387 1.468 3.387 3.614 0 2.124-1.569 3.615-3.387 3.615m0-9.578c-3.32 0-6.024 2.507-6.024 5.963 0 3.434 2.705 5.964 6.024 5.964 3.318 0 6.024-2.53 6.024-5.964 0-3.456-2.706-5.963-6.024-5.963M38.36 16.189c-1.82 0-3.388-1.491-3.388-3.615 0-2.146 1.569-3.614 3.387-3.614 1.819 0 3.387 1.468 3.387 3.614 0 2.124-1.568 3.615-3.387 3.615m0-9.578c-3.319 0-6.024 2.507-6.024 5.963 0 3.434 2.705 5.964 6.024 5.964s6.024-2.53 6.024-5.964c0-3.456-2.705-5.963-6.024-5.963M51.466 16.189c-1.818 0-3.341-1.514-3.341-3.592 0-2.1 1.523-3.637 3.341-3.637 1.796 0 3.206 1.536 3.206 3.637 0 2.078-1.41 3.592-3.206 3.592zm3.024-9.217v.972h-.091c-.591-.7-1.728-1.333-3.16-1.333-3 0-5.751 2.62-5.751 5.986 0 3.343 2.75 5.941 5.75 5.941 1.433 0 2.57-.633 3.16-1.356h.092v.859c0 2.281-1.228 3.501-3.206 3.501-1.614 0-2.614-1.152-3.023-2.123l-2.296.949c.66 1.581 2.41 3.524 5.32 3.524 3.091 0 5.705-1.808 5.705-6.212V6.972h-2.5zM61.446 18.176h-2.637V.647h2.637zM68.47 8.915c1.046 0 1.932.52 2.228 1.265l-5.365 2.214c-.068-2.305 1.796-3.48 3.137-3.48m.205 7.275c-1.342 0-2.296-.61-2.91-1.807l8.025-3.298-.273-.678c-.5-1.333-2.024-3.795-5.138-3.795-3.092 0-5.66 2.417-5.66 5.963 0 3.344 2.546 5.964 5.956 5.964 2.75 0 4.342-1.672 5-2.643L71.63 14.54c-.682.994-1.614 1.649-2.955 1.649"/></g></svg>
\ No newline at end of file
diff --git a/static/shared/message/message.css b/static/shared/message/message.css
new file mode 100644
index 0000000..b2ed112
--- /dev/null
+++ b/static/shared/message/message.css
@@ -0,0 +1,27 @@
+/*!
+ * 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.
+ */
+
+.go-Message {
+  color: var(--color-text);
+  font-size: 0.875rem;
+  line-height: 1.5rem;
+  padding: 0.25rem 0.5rem;
+  width: 100%;
+}
+.go-Message--notice {
+  background-color: var(--color-background-info);
+}
+.go-Message--warning {
+  background-color: var(--color-background-warning);
+  color: var(--gray-1);
+}
+.go-Message--alert {
+  background-color: var(--color-background-alert);
+}
+
+.go-Message > .go-Icon {
+  vertical-align: text-top;
+}
diff --git a/static/shared/message/message.md b/static/shared/message/message.md
new file mode 100644
index 0000000..1a53a97
--- /dev/null
+++ b/static/shared/message/message.md
@@ -0,0 +1,46 @@
+## Messages
+
+---
+
+### Notice {#message-notice}
+
+```html
+<div class="go-Message go-Message--notice">
+  <img
+    class="go-Icon"
+    height="24"
+    width="24"
+    src="/static/shared/icon/info_gm_grey_24dp.svg"
+    alt="Notice"
+  />&nbsp; The highest tagged major version is v3.
+</div>
+```
+
+### Warning {#message-warning}
+
+```html
+<div class="go-Message go-Message--warning">
+  <img
+    class="go-Icon"
+    height="24"
+    width="24"
+    src="/static/shared/icon/alert_gm_grey_24dp.svg"
+    alt="Warning"
+  />&nbsp; <strong>Retracted:</strong> This version of Syntax has been retracted.
+</div>
+```
+
+### Alert {#message-alert}
+
+```html
+<div class="go-Message go-Message--alert">
+  <img
+    class="go-Icon"
+    height="24"
+    width="24"
+    src="/static/shared/icon/alert_gm_grey_24dp.svg"
+    alt="Alert"
+  />&nbsp;
+  <strong>Critical error</strong>
+</div>
+```
diff --git a/static/shared/modal/modal.css b/static/shared/modal/modal.css
new file mode 100644
index 0000000..eec7b20
--- /dev/null
+++ b/static/shared/modal/modal.css
@@ -0,0 +1,60 @@
+/*!
+ * 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('../../../third_party/dialog-polyfill/dialog-polyfill.css');
+
+.go-Modal {
+  background: var(--color-background);
+  border: var(--border);
+  border-radius: var(--border-radius);
+  bottom: 0;
+  box-shadow: var(--box-shadow);
+  color: var(--color-text);
+  display: flex;
+  flex-direction: column;
+  gap: 1rem;
+  max-height: 100%;
+  max-width: 100%;
+  position: fixed;
+  top: 0;
+}
+.go-Modal > form {
+  display: contents;
+}
+.go-Modal--small {
+  width: 20rem;
+}
+.go-Modal--md {
+  width: 30rem;
+}
+.go-Modal--lg {
+  width: 40rem;
+}
+.go-Modal-header {
+  display: flex;
+  justify-content: space-between;
+}
+.go-Modal-header h2 {
+  font-size: 1.15rem;
+  line-height: 1.25rem;
+}
+.go-Modal-body {
+  flex-grow: 1;
+  min-height: 2rem;
+  min-width: 18rem;
+}
+.go-Modal-actions {
+  text-align: right;
+}
+
+/* Safari only */
+@media not all and (min-resolution: 0.001dpcm) {
+  @supports (-webkit-appearance: none) {
+    .go-Modal {
+      padding-bottom: 0;
+    }
+  }
+}
diff --git a/static/shared/modal/modal.md b/static/shared/modal/modal.md
new file mode 100644
index 0000000..cd1f8d4
--- /dev/null
+++ b/static/shared/modal/modal.md
@@ -0,0 +1,107 @@
+## Modals
+
+---
+
+The size modifer class is optional. The base modal will grow to fit the inner content.
+
+### Small {#modal-small}
+
+```html
+<dialog id="example-modal-id1" class="go-Modal go-Modal--sm js-modal">
+  <form method="dialog">
+    <div class="go-Modal-header">
+      <h2>Small Modal</h2>
+      <button
+        class="go-Button go-Button--inline"
+        type="button"
+        data-modal-close
+        data-gtmc="modal button"
+        aria-label="Close"
+      >
+        <img
+          class="go-Icon"
+          height="24"
+          width="24"
+          src="/static/shared/icon/close_gm_grey_24dp.svg"
+          alt=""
+        />
+      </button>
+    </div>
+    <div class="go-Modal-body">
+      <p>Hello, world!</p>
+    </div>
+    <div class="go-Modal-actions">
+      <button class="go-Button" data-modal-close data-gtmc="modal button">Submit</button>
+    </div>
+  </form>
+</dialog>
+<button class="go-Button" aria-controls="example-modal-id1" data-gtmc="modal button">Open</button>
+```
+
+### Medium {#modal-medium}
+
+```html
+<dialog id="example-modal-id2" class="go-Modal go-Modal--md js-modal">
+  <form method="dialog">
+    <div class="go-Modal-header">
+      <h2>Medium Modal</h2>
+      <button
+        class="go-Button go-Button--inline"
+        type="button"
+        data-modal-close
+        data-gtmc="modal button"
+        aria-label="Close"
+      >
+        <img
+          class="go-Icon"
+          height="24"
+          width="24"
+          src="/static/shared/icon/close_gm_grey_24dp.svg"
+          alt=""
+        />
+      </button>
+    </div>
+    <div class="go-Modal-body">
+      <p>Hello, world!</p>
+    </div>
+    <div class="go-Modal-actions">
+      <button class="go-Button" data-modal-close data-gtmc="modal button">Submit</button>
+    </div>
+  </form>
+</dialog>
+<button class="go-Button" aria-controls="example-modal-id2">Open</button>
+```
+
+### Large {#modal-large}
+
+```html
+<dialog id="example-modal-id3" class="go-Modal go-Modal--lg js-modal">
+  <form method="dialog">
+    <div class="go-Modal-header">
+      <h2>Large Modal</h2>
+      <button
+        class="go-Button go-Button--inline"
+        type="button"
+        data-modal-close
+        data-gtmc="modal button"
+        aria-label="Close"
+      >
+        <img
+          class="go-Icon"
+          height="24"
+          width="24"
+          src="/static/shared/icon/close_gm_grey_24dp.svg"
+          alt=""
+        />
+      </button>
+    </div>
+    <div class="go-Modal-body">
+      <p>Hello, world!</p>
+    </div>
+    <div class="go-Modal-actions">
+      <button class="go-Button" data-modal-close data-gtmc="modal button">Submit</button>
+    </div>
+  </form>
+</dialog>
+<button class="go-Button" aria-controls="example-modal-id3" data-gtmc="modal button">Open</button>
+```
diff --git a/static/shared/modal/modal.test.ts b/static/shared/modal/modal.test.ts
new file mode 100644
index 0000000..841d79c
--- /dev/null
+++ b/static/shared/modal/modal.test.ts
@@ -0,0 +1,37 @@
+/**
+ * @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 { parse } from '../../markdown';
+import { ModalController } from './modal';
+
+describe('Modal', () => {
+  let modal: HTMLDialogElement;
+  let openButton: HTMLButtonElement;
+  let closeButton: HTMLButtonElement;
+
+  beforeEach(async () => {
+    document.body.innerHTML = await parse(__dirname + '/modal.md');
+    modal = document.querySelector('#example-modal-id1');
+    openButton = document.querySelector('[aria-controls="example-modal-id1"]');
+    new ModalController(modal);
+    openButton.click();
+    closeButton = document.querySelector('[data-modal-close]');
+  });
+
+  afterEach(() => {
+    document.body.innerHTML = '';
+  });
+
+  it('opens', () => {
+    expect(modal.getAttribute('opened')).toBeTruthy();
+  });
+
+  it('closes on cancel', async () => {
+    closeButton.click();
+    expect(modal.getAttribute('opened')).toBeFalsy();
+  });
+});
diff --git a/static/shared/modal/modal.ts b/static/shared/modal/modal.ts
new file mode 100644
index 0000000..91d8feb
--- /dev/null
+++ b/static/shared/modal/modal.ts
@@ -0,0 +1,51 @@
+/**
+ * @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.
+ */
+
+interface Window {
+  dialogPolyfill?: {
+    registerDialog: (el: HTMLDialogElement) => void;
+  };
+}
+
+declare const window: Window;
+
+/**
+ * ModalController registers a dialog element with the polyfill if
+ * necessary for the current browser, add adds event listeners to
+ * close and open modals.
+ */
+export class ModalController {
+  constructor(private el: HTMLDialogElement) {
+    if (window.dialogPolyfill) {
+      window.dialogPolyfill.registerDialog(el);
+    }
+    this.init();
+  }
+
+  init() {
+    const button = document.querySelector<HTMLButtonElement>(`[aria-controls="${this.el.id}"]`);
+    if (button) {
+      button.addEventListener('click', () => {
+        if (this.el.showModal) {
+          this.el.showModal();
+        } else {
+          this.el.setAttribute('opened', 'true');
+        }
+        this.el.querySelector('input')?.focus();
+      });
+    }
+    for (const btn of this.el.querySelectorAll<HTMLButtonElement>('[data-modal-close]')) {
+      btn.addEventListener('click', () => {
+        if (this.el.close) {
+          this.el.close();
+        } else {
+          this.el.removeAttribute('opened');
+        }
+      });
+    }
+  }
+}
diff --git a/static/shared/outline/__snapshots__/select.test.ts.snap b/static/shared/outline/__snapshots__/select.test.ts.snap
new file mode 100644
index 0000000..d4f74e3
--- /dev/null
+++ b/static/shared/outline/__snapshots__/select.test.ts.snap
@@ -0,0 +1,97 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`creates select nav from tree 1`] = `
+<label
+  aria-label="Menu"
+  class="go-Label"
+>
+  <select
+    class="go-Select js-selectNav"
+  >
+    <optgroup
+      label="Outline"
+    >
+      <option
+        label="Level 1"
+        value="#one"
+      >
+        Level 1
+      </option>
+    </optgroup>
+    <optgroup
+      label="Level 1"
+    >
+      <option
+        label="Level 2-1"
+        value="#two-one"
+      >
+        Level 2-1
+      </option>
+      <option
+        label="Level 2-2"
+        value="#two-two"
+      >
+        Level 2-2
+      </option>
+      <option
+        label="Level 2-3"
+        value="#two-three"
+      >
+        Level 2-3
+      </option>
+    </optgroup>
+    <optgroup
+      label="Level 2-2"
+    >
+      <option
+        label="Level 3-1"
+        value="#three-one"
+      >
+        Level 3-1
+      </option>
+    </optgroup>
+    <optgroup
+      label="Level 3-1"
+    >
+      <option
+        label="Level 4-1"
+        value="#four-one"
+      >
+        Level 4-1
+      </option>
+      <option
+        label="Level 4-2"
+        value="#four-two"
+      >
+        Level 4-2
+      </option>
+    </optgroup>
+    <optgroup
+      label="Level 2-3"
+    >
+      <option
+        label="Level 3-2"
+        value="#three-two"
+      >
+        Level 3-2
+      </option>
+    </optgroup>
+    <optgroup
+      label="Level 3-2"
+    >
+      <option
+        label="Level 4-3"
+        value="#four-three"
+      >
+        Level 4-3
+      </option>
+      <option
+        label="Level 4-4"
+        value="#four-four"
+      >
+        Level 4-4
+      </option>
+    </optgroup>
+  </select>
+</label>
+`;
diff --git a/static/shared/outline/__snapshots__/tree.test.ts.snap b/static/shared/outline/__snapshots__/tree.test.ts.snap
new file mode 100644
index 0000000..1732086
--- /dev/null
+++ b/static/shared/outline/__snapshots__/tree.test.ts.snap
@@ -0,0 +1,248 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`creates tree nav from ul 1`] = `
+<ul
+  class="go-Tree js-tree"
+  role="tree"
+  style="--js-tree-height: 0px;"
+>
+  
+  
+  <li
+    role="none"
+  >
+    
+    
+    <a
+      aria-expanded="false"
+      aria-level="1"
+      aria-owns="_nav_group_Level_1"
+      class="focus"
+      href="#one"
+      role="treeitem"
+      tabindex="0"
+    >
+      Level 1
+    </a>
+    
+    
+    <ul
+      id="_nav_group_Level_1"
+      role="group"
+    >
+      
+      
+      <li
+        role="none"
+      >
+        
+        
+        <a
+          aria-level="2"
+          href="#two-one"
+          role="treeitem"
+          tabindex="-1"
+        >
+          Level 2-1
+        </a>
+        
+      
+      </li>
+      
+      
+      <li
+        role="none"
+      >
+        
+        
+        <a
+          aria-expanded="false"
+          aria-level="2"
+          aria-owns="Level_1_nav_group_Level_2_2"
+          href="#two-two"
+          role="treeitem"
+          tabindex="-1"
+        >
+          Level 2-2
+        </a>
+        
+        
+        <ul
+          id="Level_1_nav_group_Level_2_2"
+          role="group"
+        >
+          
+          
+          <li
+            role="none"
+          >
+            
+            
+            <a
+              aria-expanded="false"
+              aria-level="3"
+              aria-owns="Level_2_2_nav_group_Level_3_1"
+              href="#three-one"
+              role="treeitem"
+              tabindex="-1"
+            >
+              Level 3-1
+            </a>
+            
+            
+            <ul
+              id="Level_2_2_nav_group_Level_3_1"
+              role="group"
+            >
+              
+              
+              <li
+                role="none"
+              >
+                
+                
+                <a
+                  aria-level="4"
+                  href="#four-one"
+                  role="treeitem"
+                  tabindex="-1"
+                >
+                  Level 4-1
+                </a>
+                
+              
+              </li>
+              
+              
+              <li
+                role="none"
+              >
+                
+                
+                <a
+                  aria-level="4"
+                  href="#four-two"
+                  role="treeitem"
+                  tabindex="-1"
+                >
+                  Level 4-2
+                </a>
+                
+              
+              </li>
+              
+            
+            </ul>
+            
+          
+          </li>
+          
+        
+        </ul>
+        
+      
+      </li>
+      
+      
+      <li
+        role="none"
+      >
+        
+        
+        <a
+          aria-expanded="false"
+          aria-level="2"
+          aria-owns="Level_1_nav_group_Level_2_3"
+          href="#two-three"
+          role="treeitem"
+          tabindex="-1"
+        >
+          Level 2-3
+        </a>
+        
+        
+        <ul
+          id="Level_1_nav_group_Level_2_3"
+          role="group"
+        >
+          
+          
+          <li
+            role="none"
+          >
+            
+            
+            <a
+              aria-expanded="false"
+              aria-level="3"
+              aria-owns="Level_2_3_nav_group_Level_3_2"
+              href="#three-two"
+              role="treeitem"
+              tabindex="-1"
+            >
+              Level 3-2
+            </a>
+            
+            
+            <ul
+              id="Level_2_3_nav_group_Level_3_2"
+              role="group"
+            >
+              
+              
+              <li
+                role="none"
+              >
+                
+                
+                <a
+                  aria-level="4"
+                  href="#four-three"
+                  role="treeitem"
+                  tabindex="-1"
+                >
+                  Level 4-3
+                </a>
+                
+              
+              </li>
+              
+              
+              <li
+                role="none"
+              >
+                
+                
+                <a
+                  aria-level="4"
+                  href="#four-four"
+                  role="treeitem"
+                  tabindex="-1"
+                >
+                  Level 4-4
+                </a>
+                
+              
+              </li>
+              
+            
+            </ul>
+            
+          
+          </li>
+          
+        
+        </ul>
+        
+      
+      </li>
+      
+    
+    </ul>
+    
+  
+  </li>
+  
+
+</ul>
+`;
diff --git a/static/shared/outline/outline.md b/static/shared/outline/outline.md
new file mode 100644
index 0000000..da253bd
--- /dev/null
+++ b/static/shared/outline/outline.md
@@ -0,0 +1,56 @@
+## Outline
+
+---
+
+### Tree {#outline-tree}
+
+```html
+<ul class="go-Tree js-tree" role="tree">
+  <li>
+    <a href="#one">Level 1</a>
+    <ul>
+      <li>
+        <a href="#two-one">Level 2-1</a>
+      </li>
+      <li>
+        <a href="#two-two">Level 2-2</a>
+        <ul>
+          <li>
+            <a href="#three-one">Level 3-1</a>
+            <ul>
+              <li>
+                <a href="#four-one">Level 4-1</a>
+              </li>
+              <li>
+                <a href="#four-two">Level 4-2</a>
+              </li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+      <li>
+        <a href="#two-three">Level 2-3</a>
+        <ul>
+          <li>
+            <a href="#three-two">Level 3-2</a>
+            <ul>
+              <li>
+                <a href="#four-three">Level 4-3</a>
+              </li>
+              <li>
+                <a href="#four-four">Level 4-4</a>
+              </li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+</ul>
+```
+
+### Select {#outline-select}
+
+```html
+<div class="js-select"></div>
+```
diff --git a/static/shared/outline/select.test.ts b/static/shared/outline/select.test.ts
new file mode 100644
index 0000000..3b26880
--- /dev/null
+++ b/static/shared/outline/select.test.ts
@@ -0,0 +1,34 @@
+/**
+ * @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 { parse } from '../../markdown';
+import { TreeNavController } from './tree';
+import { makeSelectNav } from './select';
+
+const observe = jest.fn();
+window.IntersectionObserver = jest.fn(() => ({
+  observe,
+})) as any;
+
+let treeEl: HTMLElement;
+let tree: TreeNavController;
+let selectNav: HTMLElement;
+
+beforeEach(async () => {
+  document.body.innerHTML = await parse(__dirname + '/outline.md');
+  treeEl = document.querySelector('.js-tree') as HTMLElement;
+  tree = new TreeNavController(treeEl);
+  selectNav = makeSelectNav(tree);
+});
+
+afterEach(() => {
+  document.body.innerHTML = '';
+});
+
+it('creates select nav from tree', () => {
+  expect(selectNav).toMatchSnapshot();
+});
diff --git a/static/shared/outline/select.ts b/static/shared/outline/select.ts
new file mode 100644
index 0000000..9f56211
--- /dev/null
+++ b/static/shared/outline/select.ts
@@ -0,0 +1,61 @@
+/**
+ * @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 { TreeNavController } from './tree.js';
+
+export class SelectNavController {
+  constructor(private el: Element) {
+    this.el.addEventListener('change', e => {
+      const target = e.target as HTMLSelectElement;
+      let href = target.value;
+      if (!target.value.startsWith('/')) {
+        href = '/' + href;
+      }
+      window.location.href = href;
+    });
+  }
+}
+
+export function makeSelectNav(tree: TreeNavController): HTMLLabelElement {
+  const label = document.createElement('label');
+  label.classList.add('go-Label');
+  label.setAttribute('aria-label', 'Menu');
+  const select = document.createElement('select');
+  select.classList.add('go-Select', 'js-selectNav');
+  label.appendChild(select);
+  const outline = document.createElement('optgroup');
+  outline.label = 'Outline';
+  select.appendChild(outline);
+  const groupMap: Record<string, HTMLOptGroupElement> = {};
+  let group: HTMLOptGroupElement;
+  for (const t of tree.treeitems) {
+    if (Number(t.depth) > 4) continue;
+    if (t.groupTreeitem) {
+      group = groupMap[t.groupTreeitem.label];
+      if (!group) {
+        group = groupMap[t.groupTreeitem.label] = document.createElement('optgroup');
+        group.label = t.groupTreeitem.label;
+        select.appendChild(group);
+      }
+    } else {
+      group = outline;
+    }
+    const o = document.createElement('option');
+    o.label = t.label;
+    o.textContent = t.label;
+    o.value = (t.el as HTMLAnchorElement).href.replace(window.location.origin, '').replace('/', '');
+    group.appendChild(o);
+  }
+  tree.addObserver(t => {
+    const hash = (t.el as HTMLAnchorElement).hash;
+    const value = select.querySelector<HTMLOptionElement>(`[value$="${hash}"]`)?.value;
+    if (value) {
+      select.value = value;
+    }
+  }, 50);
+  return label;
+}
diff --git a/static/shared/outline/tree.css b/static/shared/outline/tree.css
new file mode 100644
index 0000000..3dd1e40
--- /dev/null
+++ b/static/shared/outline/tree.css
@@ -0,0 +1,119 @@
+/*!
+ * 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.
+ */
+
+.go-Tree {
+  --js-tree-height: 0;
+
+  display: flex;
+  flex-direction: column;
+}
+
+.go-Tree ul {
+  list-style: none;
+  padding-left: 0;
+}
+.go-Tree li:last-of-type {
+  padding-bottom: 0.25rem;
+}
+.go-Tree a + ul {
+  display: none;
+}
+.go-Tree a[aria-expanded='true'] + ul[role='group'] {
+  display: block;
+}
+.go-Tree a[aria-level='1'] + ul[role='group'] {
+  max-height: calc(
+    100vh - var(--js-tree-height, 0) - var(--js-sticky-header-height, 3.5rem) - 5rem
+  );
+  overflow-y: auto;
+  padding: 0.5rem 0.25rem 0 0.25rem;
+}
+.go-Tree a {
+  color: var(--color-text-subtle);
+  display: block;
+  line-height: 1.5rem;
+  overflow: hidden;
+  padding: 0.125rem 0 0.125rem 1.25rem;
+  position: relative;
+  text-overflow: ellipsis;
+  user-select: none;
+  white-space: nowrap;
+}
+.go-Tree > li > a,
+.go-Tree a[aria-level='1'] {
+  display: block;
+  font-size: 1rem;
+  font-weight: 500;
+  line-height: 2.5rem;
+  padding: 0 1rem;
+}
+.go-Tree a:focus,
+.go-Tree a:hover {
+  text-decoration: underline;
+  z-index: 1;
+}
+.go-Tree a[aria-selected='true'] {
+  color: var(--color-text);
+  font-weight: 500;
+}
+.go-Tree a[aria-level='1'][aria-selected='true'],
+.go-Tree a[aria-level='1'][aria-expanded='true'] {
+  background-color: var(--color-background-accented);
+}
+.go-Tree a[aria-level='3'][aria-expanded='true'] {
+  margin-bottom: 0.375em;
+}
+.go-Tree a[aria-level='2'] {
+  margin-bottom: 0.25rem;
+  position: relative;
+}
+.go-Tree a[aria-level='3'] {
+  padding-left: 2.5rem;
+}
+.go-Tree a[aria-level='4'] {
+  border-left: 0.125rem solid var(--color-background-accented);
+  margin-left: 2.5rem;
+  padding-left: 0.5rem;
+}
+.go-Tree a[aria-selected='true'][aria-level='2']:not([aria-expanded])::before,
+.go-Tree a[aria-selected='true'][aria-level='3']:not([aria-expanded])::before {
+  background-color: var(--color-brand-primary);
+  border-radius: 50%;
+  content: '';
+  display: block;
+  height: 0.3125rem;
+  left: 0.4688rem;
+  position: absolute;
+  top: 0.75rem;
+  width: 0.3125rem;
+}
+.go-Tree a[aria-expanded][aria-owns][aria-level='2']::before,
+.go-Tree a[aria-expanded][aria-owns][aria-level='3']::before {
+  border-bottom: 0.25rem solid transparent;
+  border-left: 0.25rem solid var(--color-border);
+  border-right: 0;
+  border-top: 0.25rem solid transparent;
+  content: '';
+  display: block;
+  height: 0;
+  left: 0.5rem;
+  position: absolute;
+  top: 0.625rem;
+  transition: transform 0.1s linear;
+  width: 0;
+}
+.go-Tree a[aria-expanded='true'][aria-level='2']::before,
+.go-Tree a[aria-expanded='true'][aria-level='3']::before {
+  transform: rotate(90deg);
+}
+.go-Tree a[aria-expanded][aria-level='3']:not([empty])::before,
+.go-Tree a[aria-selected][aria-level='3']:not([empty])::before {
+  left: 1.5rem;
+  top: 0.75rem;
+}
+.go-Tree a[aria-selected='true'][aria-level='4'] {
+  border-left: 0.125rem solid var(--color-brand-primary);
+}
diff --git a/static/shared/outline/tree.test.ts b/static/shared/outline/tree.test.ts
new file mode 100644
index 0000000..9b5d243
--- /dev/null
+++ b/static/shared/outline/tree.test.ts
@@ -0,0 +1,162 @@
+/**
+ * @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 { parse } from '../../markdown';
+import { TreeNavController } from './tree';
+
+const observe = jest.fn();
+window.IntersectionObserver = jest.fn(() => ({
+  observe,
+})) as any;
+
+let treeEl: HTMLElement;
+let a1: HTMLElement;
+let a21: HTMLElement;
+let a22: HTMLElement;
+let a23: HTMLElement;
+let a31: HTMLElement;
+let a41: HTMLElement;
+let a42: HTMLElement;
+
+beforeEach(async () => {
+  document.body.innerHTML = await parse(__dirname + '/outline.md');
+  treeEl = document.querySelector('.js-tree') as HTMLElement;
+  new TreeNavController(treeEl);
+  a1 = a('#one');
+  a21 = a('#two-one');
+  a22 = a('#two-two');
+  a23 = a('#two-three');
+  a31 = a('#three-one');
+  a41 = a('#four-one');
+  a42 = a('#four-two');
+  a1.focus();
+});
+
+afterEach(() => {
+  document.body.innerHTML = '';
+});
+
+it('creates tree nav from ul', () => {
+  expect(treeEl).toMatchSnapshot();
+});
+
+it('adds role=group attribute to ul elements', () => {
+  for (const ul of treeEl.querySelectorAll('ul')) {
+    expect(attr(ul, 'role')).toBe('group');
+  }
+});
+
+it('adds role=none attribute to li elements', () => {
+  for (const ul of treeEl.querySelectorAll('li')) {
+    expect(attr(ul, 'role')).toBe('none');
+  }
+});
+
+it('adds role=treeitem attribute to a elements', () => {
+  for (const ul of treeEl.querySelectorAll('a')) {
+    expect(attr(ul, 'role')).toBe('treeitem');
+  }
+});
+
+it('adds aria-expanded role to tree items with children', () => {
+  expect(attr(a1, 'aria-expanded')).toBe('false');
+  expect(attr(a22, 'aria-expanded')).toBe('false');
+  expect(attr(a31, 'aria-expanded')).toBe('false');
+});
+
+it('does not add aria-expanded role to tree items with children', () => {
+  expect(attr(a21, 'aria-expanded')).toBeNull();
+  expect(attr(a41, 'aria-expanded')).toBeNull();
+  expect(attr(a42, 'aria-expanded')).toBeNull();
+});
+
+it('adds aria-level to tree items', () => {
+  expect(attr(a1, 'aria-level')).toBe('1');
+  expect(attr(a21, 'aria-level')).toBe('2');
+  expect(attr(a22, 'aria-level')).toBe('2');
+  expect(attr(a31, 'aria-level')).toBe('3');
+  expect(attr(a41, 'aria-level')).toBe('4');
+  expect(attr(a42, 'aria-level')).toBe('4');
+});
+
+it('focuses tree item on click', () => {
+  a1.click();
+  expect(attr(a1, 'aria-expanded')).toBe('true');
+  expect(attr(a1, 'aria-selected')).toBe('true');
+});
+
+it('closes unfocused branches', () => {
+  a1.click();
+  expect(attr(a1, 'aria-expanded')).toBe('true');
+  expect(attr(a1, 'aria-selected')).toBe('true');
+  a22.click();
+  expect(attr(a22, 'aria-expanded')).toBe('true');
+  expect(attr(a22, 'aria-selected')).toBe('true');
+  a21.click();
+  expect(attr(a22, 'aria-expanded')).toBe('false');
+  expect(attr(a22, 'aria-selected')).toBe('false');
+});
+
+it('navigates treeitems with the keyboard', () => {
+  keydown(a1, 'ArrowRight'); // expand a1
+  expect(attr(a1, 'aria-expanded')).toBe('true');
+
+  keydown(a1, 'ArrowRight'); // focus a21
+  expect(attr(a1, 'tabindex')).toBe('-1');
+  expect(attr(a21, 'tabindex')).toBe('0');
+
+  keydown(a21, 'ArrowDown'); // focus a22
+  expect(attr(a21, 'tabindex')).toBe('-1');
+  expect(attr(a22, 'tabindex')).toBe('0');
+
+  keydown(a22, 'ArrowRight'); // expand a22
+  expect(attr(a22, 'aria-expanded')).toBe('true');
+
+  keydown(a22, 'ArrowRight'); // focus a31
+  expect(attr(a22, 'tabindex')).toBe('-1');
+  expect(attr(a31, 'tabindex')).toBe('0');
+
+  keydown(a31, 'ArrowUp'); // focus a22
+  expect(attr(a31, 'tabindex')).toBe('-1');
+  expect(attr(a22, 'tabindex')).toBe('0');
+
+  keydown(a22, 'ArrowUp'); // focus a21
+  expect(attr(a22, 'tabindex')).toBe('-1');
+  expect(attr(a21, 'tabindex')).toBe('0');
+
+  keydown(a21, 'ArrowLeft'); // focus a1
+  expect(attr(a21, 'tabindex')).toBe('-1');
+  expect(attr(a1, 'tabindex')).toBe('0');
+
+  keydown(a1, 'End'); // focus a31
+  expect(attr(a1, 'tabindex')).toBe('-1');
+  expect(attr(a23, 'tabindex')).toBe('0');
+
+  keydown(a23, 'Home'); // focus a1
+  expect(attr(a31, 'tabindex')).toBe('-1');
+  expect(attr(a1, 'tabindex')).toBe('0');
+});
+
+it('expands sibling items with * key', () => {
+  keydown(a1, 'ArrowRight');
+  keydown(a1, 'ArrowDown');
+  keydown(a21, '*');
+  expect(attr(a22, 'aria-expanded')).toBe('true');
+  expect(attr(a23, 'aria-expanded')).toBe('true');
+});
+
+function a(href: string): HTMLElement {
+  return document.querySelector(`[href="${href}"]`);
+}
+
+function attr(el: Element, name: string): string {
+  return el.getAttribute(name);
+}
+
+function keydown(el: Element, key: string): void {
+  el.dispatchEvent(new KeyboardEvent('keydown', { key }));
+}
diff --git a/static/shared/outline/tree.tmpl b/static/shared/outline/tree.tmpl
new file mode 100644
index 0000000..6f048f9
--- /dev/null
+++ b/static/shared/outline/tree.tmpl
@@ -0,0 +1,24 @@
+<!--
+  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 "treeitems"}}
+  {{range .}}
+    <li>
+      <a href="#{{.ID}}">{{.Text}}</a>
+      {{if and .Children (lt .Level 4)}}
+        <ul>
+          {{template "treeitems" .Children}}
+        </ul>
+      {{end}}
+    </li>
+  {{end}}
+{{end}}
+
+{{define "tree-nav"}}
+  <ul class="go-Tree js-tree" role="tree">
+    {{template "treeitems" .}}
+  </ul>
+{{end}}
diff --git a/static/shared/outline/tree.ts b/static/shared/outline/tree.ts
new file mode 100644
index 0000000..fbacbe0
--- /dev/null
+++ b/static/shared/outline/tree.ts
@@ -0,0 +1,483 @@
+/**
+ * @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.
+ */
+
+/**
+ * TreeNavController is the navigation tree component of the documentation page.
+ * It adds accessiblity attributes to a tree, observes the heading elements
+ * focus the topmost link for headings visible on the page, and implements the
+ * WAI-ARIA Treeview Design Pattern with full
+ * [keyboard support](https://www.w3.org/TR/wai-aria-practices/examples/treeview/treeview-2/treeview-2a.html#kbd_label).
+ */
+export class TreeNavController {
+  treeitems: TreeItem[];
+
+  /**
+   * firstChars is the first character of each treeitem in the same order
+   * as this.treeitems. We use this array to set focus by character when
+   * navigating the tree with a keyboard.
+   */
+  private firstChars: string[];
+  private firstTreeitem: TreeItem | null;
+  private lastTreeitem: TreeItem | null;
+  private observerCallbacks: ((t: TreeItem) => void)[];
+
+  constructor(private el: HTMLElement) {
+    this.treeitems = [];
+    this.firstChars = [];
+    this.firstTreeitem = null;
+    this.lastTreeitem = null;
+    this.observerCallbacks = [];
+    this.init();
+  }
+
+  private init(): void {
+    this.handleResize();
+    window.addEventListener('resize', this.handleResize);
+    this.findTreeItems();
+    this.updateVisibleTreeitems();
+    this.observeTargets();
+    if (this.firstTreeitem) {
+      this.firstTreeitem.el.tabIndex = 0;
+    }
+  }
+
+  private handleResize = (): void => {
+    this.el.style.setProperty('--js-tree-height', '100vh');
+    this.el.style.setProperty('--js-tree-height', this.el.clientHeight + 'px');
+  };
+
+  private observeTargets() {
+    this.addObserver(treeitem => {
+      this.expandTreeitem(treeitem);
+      this.setSelected(treeitem);
+      // TODO: Fix scroll issue in https://golang.org/issue/47450.
+      // treeitem.el.scrollIntoView({ block: 'nearest' });
+    });
+
+    const targets = new Map<string, boolean>();
+    const observer = new IntersectionObserver(
+      entries => {
+        for (const entry of entries) {
+          targets.set(entry.target.id, entry.isIntersecting || entry.intersectionRatio === 1);
+        }
+        for (const [id, isIntersecting] of targets) {
+          if (isIntersecting) {
+            const active = this.treeitems.find(t =>
+              (t.el as HTMLAnchorElement)?.href.endsWith(`#${id}`)
+            );
+            if (active) {
+              for (const fn of this.observerCallbacks) {
+                fn(active);
+              }
+            }
+            break;
+          }
+        }
+      },
+      {
+        threshold: 1.0,
+        rootMargin: '-60px 0px 0px 0px',
+      }
+    );
+
+    for (const href of this.treeitems.map(t => t.el.getAttribute('href'))) {
+      if (href) {
+        const id = href.replace(window.location.origin, '').replace('/', '').replace('#', '');
+        const target = document.getElementById(id);
+        if (target) {
+          observer.observe(target);
+        }
+      }
+    }
+  }
+
+  addObserver(fn: (t: TreeItem) => void, delay = 200): void {
+    this.observerCallbacks.push(debounce(fn, delay));
+  }
+
+  setFocusToNextItem(currentItem: TreeItem): void {
+    let nextItem = null;
+    for (let i = currentItem.index + 1; i < this.treeitems.length; i++) {
+      const ti = this.treeitems[i];
+      if (ti.isVisible) {
+        nextItem = ti;
+        break;
+      }
+    }
+    if (nextItem) {
+      this.setFocusToItem(nextItem);
+    }
+  }
+
+  setFocusToPreviousItem(currentItem: TreeItem): void {
+    let prevItem = null;
+    for (let i = currentItem.index - 1; i > -1; i--) {
+      const ti = this.treeitems[i];
+      if (ti.isVisible) {
+        prevItem = ti;
+        break;
+      }
+    }
+    if (prevItem) {
+      this.setFocusToItem(prevItem);
+    }
+  }
+
+  setFocusToParentItem(currentItem: TreeItem): void {
+    if (currentItem.groupTreeitem) {
+      this.setFocusToItem(currentItem.groupTreeitem);
+    }
+  }
+
+  setFocusToFirstItem(): void {
+    this.firstTreeitem && this.setFocusToItem(this.firstTreeitem);
+  }
+
+  setFocusToLastItem(): void {
+    this.lastTreeitem && this.setFocusToItem(this.lastTreeitem);
+  }
+
+  setSelected(currentItem: TreeItem): void {
+    for (const l1 of this.el.querySelectorAll('[aria-expanded="true"]')) {
+      if (l1 === currentItem.el) continue;
+      if (!l1.nextElementSibling?.contains(currentItem.el)) {
+        l1.setAttribute('aria-expanded', 'false');
+      }
+    }
+    for (const l1 of this.el.querySelectorAll('[aria-selected]')) {
+      if (l1 !== currentItem.el) {
+        l1.setAttribute('aria-selected', 'false');
+      }
+    }
+    currentItem.el.setAttribute('aria-selected', 'true');
+    this.updateVisibleTreeitems();
+    this.setFocusToItem(currentItem, false);
+  }
+
+  expandTreeitem(treeitem: TreeItem): void {
+    let currentItem: TreeItem | null = treeitem;
+    while (currentItem) {
+      if (currentItem.isExpandable) {
+        currentItem.el.setAttribute('aria-expanded', 'true');
+      }
+      currentItem = currentItem.groupTreeitem;
+    }
+    this.updateVisibleTreeitems();
+  }
+
+  expandAllSiblingItems(currentItem: TreeItem): void {
+    for (const ti of this.treeitems) {
+      if (ti.groupTreeitem === currentItem.groupTreeitem && ti.isExpandable) {
+        this.expandTreeitem(ti);
+      }
+    }
+  }
+
+  collapseTreeitem(currentItem: TreeItem): void {
+    let groupTreeitem = null;
+
+    if (currentItem.isExpanded()) {
+      groupTreeitem = currentItem;
+    } else {
+      groupTreeitem = currentItem.groupTreeitem;
+    }
+
+    if (groupTreeitem) {
+      groupTreeitem.el.setAttribute('aria-expanded', 'false');
+      this.updateVisibleTreeitems();
+      this.setFocusToItem(groupTreeitem);
+    }
+  }
+
+  setFocusByFirstCharacter(currentItem: TreeItem, char: string): void {
+    let start: number, index: number;
+    char = char.toLowerCase();
+
+    // Get start index for search based on position of currentItem
+    start = currentItem.index + 1;
+    if (start === this.treeitems.length) {
+      start = 0;
+    }
+
+    // Check remaining slots in the menu
+    index = this.getIndexFirstChars(start, char);
+
+    // If not found in remaining slots, check from beginning
+    if (index === -1) {
+      index = this.getIndexFirstChars(0, char);
+    }
+
+    // If match was found...
+    if (index > -1) {
+      this.setFocusToItem(this.treeitems[index]);
+    }
+  }
+
+  private findTreeItems() {
+    const findItems = (el: HTMLElement, group: TreeItem | null) => {
+      let ti = group;
+      let curr = el.firstElementChild as HTMLElement;
+      while (curr) {
+        if (curr.tagName === 'A' || curr.tagName === 'SPAN') {
+          ti = new TreeItem(curr, this, group);
+          this.treeitems.push(ti);
+          this.firstChars.push(ti.label.substring(0, 1).toLowerCase());
+        }
+        if (curr.firstElementChild) {
+          findItems(curr, ti);
+        }
+        curr = curr.nextElementSibling as HTMLElement;
+      }
+    };
+    findItems(this.el as HTMLElement, null);
+    this.treeitems.map((ti, idx) => (ti.index = idx));
+  }
+
+  private updateVisibleTreeitems(): void {
+    this.firstTreeitem = this.treeitems[0];
+
+    for (const ti of this.treeitems) {
+      let parent = ti.groupTreeitem;
+      ti.isVisible = true;
+      while (parent && parent.el !== this.el) {
+        if (!parent.isExpanded()) {
+          ti.isVisible = false;
+        }
+        parent = parent.groupTreeitem;
+      }
+      if (ti.isVisible) {
+        this.lastTreeitem = ti;
+      }
+    }
+  }
+
+  private setFocusToItem(treeitem: TreeItem, focusEl = true) {
+    treeitem.el.tabIndex = 0;
+    if (focusEl) {
+      treeitem.el.focus();
+    }
+    for (const ti of this.treeitems) {
+      if (ti !== treeitem) {
+        ti.el.tabIndex = -1;
+      }
+    }
+  }
+
+  private getIndexFirstChars(startIndex: number, char: string): number {
+    for (let i = startIndex; i < this.firstChars.length; i++) {
+      if (this.treeitems[i].isVisible && char === this.firstChars[i]) {
+        return i;
+      }
+    }
+    return -1;
+  }
+}
+
+class TreeItem {
+  el: HTMLElement;
+  groupTreeitem: TreeItem | null;
+  label: string;
+  isExpandable: boolean;
+  isVisible: boolean;
+  depth: number;
+  index: number;
+
+  private tree: TreeNavController;
+  private isInGroup: boolean;
+
+  constructor(el: HTMLElement, treeObj: TreeNavController, group: TreeItem | null) {
+    el.tabIndex = -1;
+    this.el = el;
+    this.groupTreeitem = group;
+    this.label = el.textContent?.trim() ?? '';
+    this.tree = treeObj;
+    this.depth = (group?.depth || 0) + 1;
+    this.index = 0;
+
+    const parent = el.parentElement;
+    if (parent?.tagName.toLowerCase() === 'li') {
+      parent?.setAttribute('role', 'none');
+    }
+    el.setAttribute('aria-level', this.depth + '');
+    if (el.getAttribute('aria-label')) {
+      this.label = el?.getAttribute('aria-label')?.trim() ?? '';
+    }
+
+    this.isExpandable = false;
+    this.isVisible = false;
+    this.isInGroup = !!group;
+
+    let curr = el.nextElementSibling;
+    while (curr) {
+      if (curr.tagName.toLowerCase() == 'ul') {
+        const groupId = `${group?.label ?? ''} nav group ${this.label}`.replace(/[\W_]+/g, '_');
+        el.setAttribute('aria-owns', groupId);
+        el.setAttribute('aria-expanded', 'false');
+        curr.setAttribute('role', 'group');
+        curr.setAttribute('id', groupId);
+        this.isExpandable = true;
+        break;
+      }
+
+      curr = curr.nextElementSibling;
+    }
+    this.init();
+  }
+
+  private init() {
+    this.el.tabIndex = -1;
+    if (!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() {
+    if (this.isExpandable) {
+      return this.el.getAttribute('aria-expanded') === 'true';
+    }
+
+    return false;
+  }
+
+  isSelected() {
+    return this.el.getAttribute('aria-selected') === 'true';
+  }
+
+  private handleClick(event: MouseEvent) {
+    // only process click events that directly happened on this treeitem
+    if (event.target !== this.el && event.target !== this.el.firstElementChild) {
+      return;
+    }
+    if (this.isExpandable) {
+      if (this.isExpanded() && this.isSelected()) {
+        this.tree.collapseTreeitem(this);
+      } else {
+        this.tree.expandTreeitem(this);
+      }
+      event.stopPropagation();
+    }
+    this.tree.setSelected(this);
+  }
+
+  private handleFocus() {
+    let el = this.el;
+    if (this.isExpandable) {
+      el = (el.firstElementChild as HTMLElement) ?? el;
+    }
+    el.classList.add('focus');
+  }
+
+  private handleBlur() {
+    let el = this.el;
+    if (this.isExpandable) {
+      el = (el.firstElementChild as HTMLElement) ?? el;
+    }
+    el.classList.remove('focus');
+  }
+
+  private handleKeydown(event: KeyboardEvent) {
+    if (event.altKey || event.ctrlKey || event.metaKey) {
+      return;
+    }
+
+    let captured = false;
+    switch (event.key) {
+      case ' ':
+      case 'Enter':
+        if (this.isExpandable) {
+          if (this.isExpanded() && this.isSelected()) {
+            this.tree.collapseTreeitem(this);
+          } else {
+            this.tree.expandTreeitem(this);
+          }
+          captured = true;
+        } else {
+          event.stopPropagation();
+        }
+        this.tree.setSelected(this);
+        break;
+
+      case 'ArrowUp':
+        this.tree.setFocusToPreviousItem(this);
+        captured = true;
+        break;
+
+      case 'ArrowDown':
+        this.tree.setFocusToNextItem(this);
+        captured = true;
+        break;
+
+      case 'ArrowRight':
+        if (this.isExpandable) {
+          if (this.isExpanded()) {
+            this.tree.setFocusToNextItem(this);
+          } else {
+            this.tree.expandTreeitem(this);
+          }
+        }
+        captured = true;
+        break;
+
+      case 'ArrowLeft':
+        if (this.isExpandable && this.isExpanded()) {
+          this.tree.collapseTreeitem(this);
+          captured = true;
+        } else {
+          if (this.isInGroup) {
+            this.tree.setFocusToParentItem(this);
+            captured = true;
+          }
+        }
+        break;
+
+      case 'Home':
+        this.tree.setFocusToFirstItem();
+        captured = true;
+        break;
+
+      case 'End':
+        this.tree.setFocusToLastItem();
+        captured = true;
+        break;
+
+      default:
+        if (event.key.length === 1 && event.key.match(/\S/)) {
+          if (event.key == '*') {
+            this.tree.expandAllSiblingItems(this);
+          } else {
+            this.tree.setFocusByFirstCharacter(this, event.key);
+          }
+          captured = true;
+        }
+        break;
+    }
+
+    if (captured) {
+      event.stopPropagation();
+      event.preventDefault();
+    }
+  }
+}
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+function debounce<T extends (...args: any[]) => any>(func: T, wait: number) {
+  let timeout: ReturnType<typeof setTimeout> | null;
+  return (...args: Parameters<T>) => {
+    const later = () => {
+      timeout = null;
+      func(...args);
+    };
+    if (timeout) {
+      clearTimeout(timeout);
+    }
+    timeout = setTimeout(later, wait);
+  };
+}
diff --git a/static/shared/reset.css b/static/shared/reset.css
new file mode 100644
index 0000000..f5bf9bc
--- /dev/null
+++ b/static/shared/reset.css
@@ -0,0 +1,152 @@
+/*!
+ * 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.
+ */
+
+/*!
+ * http://meyerweb.com/eric/tools/css/reset/
+ * v2.0 | 20110126
+ * License: none (public domain)
+ */
+
+html,
+body,
+button,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+input,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+dialog,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+  border: 0;
+  font: inherit;
+  font-size: 100%;
+  margin: 0;
+  padding: 0;
+  vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+  display: block;
+}
+
+body {
+  line-height: 1;
+}
+
+ol,
+ul {
+  list-style: none;
+}
+
+blockquote,
+q {
+  quotes: none;
+}
+
+blockquote::before,
+blockquote::after,
+q::before,
+q::after {
+  content: '';
+  content: none;
+}
+
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+*,
+::before,
+::after {
+  box-sizing: border-box;
+}
diff --git a/static/shared/shared.css b/static/shared/shared.css
new file mode 100644
index 0000000..4229bf8
--- /dev/null
+++ b/static/shared/shared.css
@@ -0,0 +1,100 @@
+/*!
+ * 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('./reset.css');
+
+/**
+ * Typography should be imported first in the list below to ensure expected
+ * CSS rule inheritance on text elements.
+ */
+@import url('./typography/typography.css');
+@import url('./button/button.css');
+@import url('./breadcrumb/breadcrumb.css');
+@import url('./carousel/carousel.css');
+@import url('./chip/chip.css');
+@import url('./clipboard/clipboard.css');
+@import url('./color/color.css');
+@import url('./footer/footer.css');
+@import url('./form/form.css');
+@import url('./gopher/gopher.css');
+@import url('./header/header.css');
+@import url('./icon/icon.css');
+@import url('./message/message.css');
+@import url('./modal/modal.css');
+@import url('./outline/tree.css');
+@import url('./tabnav/tabnav.css');
+@import url('./tooltip/tooltip.css');
+
+:root {
+  /* Padding at the left and right of the viewport. */
+  --gutter: 1.5rem;
+
+  /* Margin between containers in the grid layout. */
+  --gap: 1rem;
+
+  /* The margin placed above elements scrolled to by clicking hash links. */
+  --scroll-margin: calc(
+    var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 2rem
+  );
+
+  /* Default styles for page elements. */
+  --border: 0.0625rem solid var(--color-border);
+  --border-radius: 0.25rem;
+  --box-shadow: 0 0 0.375rem 0 rgb(0 0 0 / 25%);
+  --focus-box-shadow: 0 0 0.0625rem 0.0625rem rgb(0 112 210 / 60%);
+}
+
+@media (min-width: 50rem) {
+  :root {
+    --gap: 2rem;
+    --scroll-margin: calc(
+      var(--js-sticky-header-height, 3.5rem) + var(--js-sticky-nav-height, 0) + 1rem
+    );
+  }
+}
+
+*:target {
+  scroll-margin-top: var(--scroll-margin);
+}
+
+body {
+  background-color: var(--color-background);
+  display: flex;
+  flex-direction: column;
+  min-height: 100vh;
+  min-width: 23.5rem;
+
+  /**
+   * This is used to programatically detect whether overflow needs to be altered
+   * to prevent jitter when focusing within fixed elements on iOS.
+   * It also must be set to 'touch' for the fix to work.
+   */
+  -webkit-overflow-scrolling: touch;
+}
+
+.go-Container {
+  display: flex;
+  flex-direction: column;
+  flex-grow: 1;
+  height: 100%;
+  margin-bottom: 5rem;
+}
+
+.go-Content {
+  display: flex;
+  flex-flow: column;
+  gap: 1rem;
+  margin: 0 auto;
+  max-width: 63rem;
+  min-height: 32rem;
+  padding: 2rem var(--gutter);
+  width: 100%;
+}
+
+.go-Content--center {
+  justify-content: center;
+  margin: auto;
+}
diff --git a/static/shared/table/table.test.ts b/static/shared/table/table.test.ts
new file mode 100644
index 0000000..681bc01
--- /dev/null
+++ b/static/shared/table/table.test.ts
@@ -0,0 +1,150 @@
+/*!
+ * @license
+ * 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.
+ */
+
+import { ExpandableRowsTableController } from './table';
+
+describe('ExpandableRowsTableController', () => {
+  let table: HTMLTableElement;
+  let toggle1: HTMLButtonElement;
+  let toggle2: HTMLButtonElement;
+  let toggleAll: HTMLButtonElement;
+
+  beforeEach(() => {
+    document.body.innerHTML = `
+      <div>
+        <button class="js-toggleAll">Expand all</button>
+      </div>
+      <table class="js-table">
+        <tbody>
+          <tr>
+            <th>Toggle</th>
+            <th>Foo</th>
+            <th>Bar</th>
+          </tr>
+          <tr>
+            <td></td>
+            <td data-id="label-id-1">Hello World</td>
+            <td>Simple row with no toggle or hidden elements</td>
+          </tr>
+          <tr data-aria-controls="hidden-row-id-1 hidden-row-id-2">
+            <td>
+              <button
+                type="button"
+                aria-expanded="false"
+                aria-label="2 more from"
+                data-aria-controls="hidden-row-id-1 hidden-row-id-2"
+                data-aria-labelledby="toggle-id-1 label-id-2"
+                data-id="toggle-id-1"
+              >
+                +
+              </button>
+            </td>
+            <td data-id="label-id-2">
+              <span>Baz</span>
+            </td>
+            <td></td>
+          </tr>
+          <tr data-id="hidden-row-id-1">
+            <td></td>
+            <td>First hidden row</td>
+            <td></td>
+          </tr>
+          <tr data-id="hidden-row-id-2">
+            <td></td>
+            <td>Second hidden row</td>
+            <td></td>
+          </tr>
+          <tr data-aria-controls="hidden-row-id-3">
+            <td>
+              <button
+                type="button"
+                aria-expanded="false"
+                aria-label="2 more from"
+                data-aria-controls="hidden-row-id-3"
+                data-aria-labelledby="toggle-id-2 label-id-3"
+                data-id="toggle-id-2"
+              >
+                +
+              </button>
+            </td>
+            <td data-id="label-id-3">
+              <span>Baz</span>
+            </td>
+            <td></td>
+          </tr>
+          <tr data-id="hidden-row-id-3">
+            <td></td>
+            <td>First hidden row</td>
+            <td></td>
+          </tr>
+        </tbody>
+      </table>
+    `;
+    table = document.querySelector<HTMLTableElement>('.js-table');
+    toggleAll = document.querySelector<HTMLButtonElement>('.js-toggleAll');
+    new ExpandableRowsTableController(table, toggleAll);
+    toggle1 = document.querySelector<HTMLButtonElement>('#toggle-id-1');
+    toggle2 = document.querySelector<HTMLButtonElement>('#toggle-id-2');
+  });
+
+  afterEach(() => {
+    document.body.innerHTML = '';
+  });
+
+  it('sets data-aria-* and data-id attributes to regular html attributes', () => {
+    expect(document.querySelector('#label-id-1')).toBeTruthy();
+    expect(
+      document.querySelector('[aria-controls="hidden-row-id-1 hidden-row-id-2"]')
+    ).toBeTruthy();
+    expect(document.querySelector('[aria-labelledby="toggle-id-1 label-id-2"]')).toBeTruthy();
+    expect(document.querySelector('#toggle-id-1')).toBeTruthy();
+    expect(document.querySelector('#label-id-2')).toBeTruthy();
+    expect(document.querySelector('#hidden-row-id-1')).toBeTruthy();
+    expect(document.querySelector('#hidden-row-id-2')).toBeTruthy();
+  });
+
+  it('hides rows with unexpanded toggles', () => {
+    expect(document.querySelector('#hidden-row-id-1').classList).toContain('hidden');
+    expect(document.querySelector('#hidden-row-id-2').classList).toContain('hidden');
+  });
+
+  it('shows rows with expanded toggles', () => {
+    toggleAll.click();
+    expect(document.querySelector('#hidden-row-id-1').classList).toContain('visible');
+    expect(document.querySelector('#hidden-row-id-2').classList).toContain('visible');
+  });
+
+  it('expands rows when entering text search', () => {
+    document.dispatchEvent(new KeyboardEvent('keydown', { key: 'f', ctrlKey: true }));
+    expect(document.querySelector('#hidden-row-id-1').classList).toContain('visible');
+    expect(document.querySelector('#hidden-row-id-2').classList).toContain('visible');
+  });
+
+  it('toggle expands and collapses all elements', async () => {
+    jest.useFakeTimers();
+    toggleAll.click();
+    jest.runAllTimers();
+    expect(document.querySelector('#hidden-row-id-1').classList).toContain('visible');
+    expect(document.querySelector('#hidden-row-id-2').classList).toContain('visible');
+    expect(toggleAll.innerText).toBe('Collapse all');
+    toggleAll.click();
+    jest.runAllTimers();
+    expect(document.querySelector('#hidden-row-id-1').classList).toContain('hidden');
+    expect(document.querySelector('#hidden-row-id-2').classList).toContain('hidden');
+    expect(toggleAll.innerText).toBe('Expand all');
+  });
+
+  it('toggle changes text only when all items expanded', () => {
+    jest.useFakeTimers();
+    toggle1.click();
+    jest.runAllTimers();
+    expect(toggleAll.innerText).toBe('Expand all');
+    toggle2.click();
+    jest.runAllTimers();
+    expect(toggleAll.innerText).toBe('Collapse all');
+  });
+});
diff --git a/static/shared/table/table.ts b/static/shared/table/table.ts
new file mode 100644
index 0000000..7675b65
--- /dev/null
+++ b/static/shared/table/table.ts
@@ -0,0 +1,126 @@
+/*!
+ * @license
+ * 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.
+ */
+
+/**
+ * Controller for a table element with expandable rows. Adds event listeners to
+ * a toggle within a table row that controls visiblity of additional related
+ * rows in the table.
+ *
+ * @example
+ * ```typescript
+ * import {ExpandableRowsTableController} from '/static/js/table';
+ *
+ * const el = document .querySelector<HTMLTableElement>('.js-myTableElement')
+ * new ExpandableRowsTableController(el));
+ * ```
+ */
+export class ExpandableRowsTableController {
+  private rows: HTMLTableRowElement[];
+  private toggles: HTMLButtonElement[];
+
+  /**
+   * Create a table controller.
+   * @param table - The table element to which the controller binds.
+   */
+  constructor(private table: HTMLTableElement, private toggleAll?: HTMLButtonElement | null) {
+    this.rows = Array.from(table.querySelectorAll<HTMLTableRowElement>('[data-aria-controls]'));
+    this.toggles = Array.from(this.table.querySelectorAll('[aria-expanded]'));
+    this.setAttributes();
+    this.attachEventListeners();
+    this.update();
+  }
+
+  /**
+   * setAttributes sets data-aria-* and data-id attributes to regular
+   * html attributes as a workaround for limitations from safehtml.
+   */
+  private setAttributes() {
+    for (const a of ['data-aria-controls', 'data-aria-labelledby', 'data-id']) {
+      this.table.querySelectorAll(`[${a}]`).forEach(t => {
+        t.setAttribute(a.replace('data-', ''), t.getAttribute(a) ?? '');
+        t.removeAttribute(a);
+      });
+    }
+  }
+
+  private attachEventListeners() {
+    this.rows.forEach(t => {
+      t.addEventListener('click', e => {
+        this.handleToggleClick(e);
+      });
+    });
+    this.toggleAll?.addEventListener('click', () => {
+      this.expandAllItems();
+    });
+
+    document.addEventListener('keydown', e => {
+      if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
+        this.expandAllItems();
+      }
+    });
+  }
+
+  private handleToggleClick(e: MouseEvent) {
+    let target = e.currentTarget as HTMLTableRowElement | null;
+    if (!target?.hasAttribute('aria-expanded')) {
+      target = this.table.querySelector(
+        `button[aria-controls="${target?.getAttribute('aria-controls')}"]`
+      );
+    }
+    const isExpanded = target?.getAttribute('aria-expanded') === 'true';
+    target?.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
+    e.stopPropagation();
+    this.update();
+  }
+
+  expandAllItems = (): void => {
+    this.toggles.map(t => t.setAttribute('aria-expanded', 'true'));
+    this.update();
+  };
+
+  private collapseAllItems = () => {
+    this.toggles.map(t => t.setAttribute('aria-expanded', 'false'));
+    this.update();
+  };
+
+  private update = () => {
+    this.updateVisibleItems();
+    setTimeout(() => this.updateGlobalToggle());
+  };
+
+  private updateVisibleItems() {
+    this.rows.map(t => {
+      const isExpanded = t?.getAttribute('aria-expanded') === 'true';
+      const rowIds = t?.getAttribute('aria-controls')?.trimEnd().split(' ');
+      rowIds?.map(id => {
+        const target = document.getElementById(`${id}`);
+        if (isExpanded) {
+          target?.classList.add('visible');
+          target?.classList.remove('hidden');
+        } else {
+          target?.classList.add('hidden');
+          target?.classList.remove('visible');
+        }
+      });
+    });
+  }
+
+  private updateGlobalToggle() {
+    if (!this.toggleAll) return;
+    if (this.rows.some(t => t.hasAttribute('aria-expanded'))) {
+      this.toggleAll.style.display = 'block';
+    }
+    const someCollapsed = this.toggles.some(el => el.getAttribute('aria-expanded') === 'false');
+    if (someCollapsed) {
+      this.toggleAll.innerText = 'Expand all';
+      this.toggleAll.onclick = this.expandAllItems;
+    } else {
+      this.toggleAll.innerText = 'Collapse all';
+      this.toggleAll.onclick = this.collapseAllItems;
+    }
+  }
+}
diff --git a/static/shared/tabnav/tabnav.css b/static/shared/tabnav/tabnav.css
new file mode 100644
index 0000000..b669fb7
--- /dev/null
+++ b/static/shared/tabnav/tabnav.css
@@ -0,0 +1,37 @@
+/*!
+ * 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.
+ */
+
+.go-TabNav {
+  margin: 0 0 0.5rem 0;
+}
+.go-TabNav ul {
+  display: flex;
+  gap: 2rem;
+}
+.go-TabNav li {
+  border-bottom: 0.25rem transparent solid;
+  display: flex;
+  font-size: 1rem;
+  height: 2.375rem;
+  padding: 0 0.25rem;
+}
+.go-TabNav li[aria-current] {
+  border-color: var(--color-brand-primary);
+}
+.go-TabNav li:hover {
+  border-color: var(--color-brand-primary);
+}
+.go-TabNav a {
+  align-items: center;
+  color: var(--color-text-subtle);
+  display: inline-flex;
+}
+.go-TabNav li:hover a {
+  text-decoration: none;
+}
+.go-TabNav li[aria-current] a {
+  color: var(--color-text);
+}
diff --git a/static/shared/tabnav/tabnav.md b/static/shared/tabnav/tabnav.md
new file mode 100644
index 0000000..fa42c72
--- /dev/null
+++ b/static/shared/tabnav/tabnav.md
@@ -0,0 +1,13 @@
+## Tab Nav
+
+---
+
+```html
+<nav class="go-TabNav">
+  <ul>
+    <li aria-current="page"><a href="#nav-tab">Package</a></li>
+    <li><a href="#nav-tab">Symbol</a></li>
+  </ul>
+  <hr />
+</nav>
+```
diff --git a/static/shared/tooltip/tooltip.css b/static/shared/tooltip/tooltip.css
new file mode 100644
index 0000000..df6e23c
--- /dev/null
+++ b/static/shared/tooltip/tooltip.css
@@ -0,0 +1,37 @@
+/*!
+ * 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.
+ */
+
+.go-Tooltip {
+  border-radius: var(--border-radius);
+  cursor: pointer;
+  display: inline-block;
+  position: relative;
+}
+.go-Tooltip > summary {
+  list-style: none;
+}
+.go-Tooltip > summary::-webkit-details-marker,
+.go-Tooltip > summary::marker {
+  display: none;
+}
+.go-Tooltip > summary > img {
+  vertical-align: text-bottom;
+}
+.go-Tooltip p {
+  background: var(--color-background) 80%;
+  border: var(--border);
+  border-radius: var(--border-radius);
+  color: var(--color-text);
+  font-size: 0.75rem;
+  letter-spacing: 0.01875rem;
+  line-height: 1rem;
+  padding: 0.5rem;
+  position: absolute;
+  top: 1.5rem;
+  white-space: normal;
+  width: 12rem;
+  z-index: 100;
+}
diff --git a/static/shared/tooltip/tooltip.md b/static/shared/tooltip/tooltip.md
new file mode 100644
index 0000000..7c6dc2c
--- /dev/null
+++ b/static/shared/tooltip/tooltip.md
@@ -0,0 +1,22 @@
+## Tooltips
+
+---
+
+```html
+<details class="go-Tooltip js-tooltip" data-gtmc="tooltip">
+  <summary>
+    Valid <a href="#tooltips">go.mod</a> file
+    <img
+      class="go-Icon"
+      height="24"
+      width="24"
+      src="/static/shared/icon/help_gm_grey_24dp.svg"
+      alt=""
+    />
+  </summary>
+  <p>
+    The Go module system was introduced in Go 1.11 and is the official dependency management
+    solution for Go.
+  </p>
+</details>
+```
diff --git a/static/shared/tooltip/tooltip.test.ts b/static/shared/tooltip/tooltip.test.ts
new file mode 100644
index 0000000..a9086bc
--- /dev/null
+++ b/static/shared/tooltip/tooltip.test.ts
@@ -0,0 +1,40 @@
+/**
+ * @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 { parse } from '../../markdown';
+import { ToolTipController } from './tooltip';
+
+describe('Tooltip', () => {
+  let tooltip: HTMLDetailsElement;
+  let summary: HTMLElement;
+
+  beforeEach(async () => {
+    document.body.innerHTML = await parse(__dirname + '/tooltip.md');
+    tooltip = document.querySelector('.js-tooltip');
+    summary = tooltip.firstElementChild as HTMLElement;
+    new ToolTipController(tooltip);
+    summary.click();
+  });
+
+  afterEach(() => {
+    document.body.innerHTML = '';
+  });
+
+  it('opens', () => {
+    expect(tooltip.open).toBeTruthy();
+  });
+
+  it('closes on click', () => {
+    summary.click();
+    expect(tooltip.open).toBeFalsy();
+  });
+
+  it('closes on outside click', () => {
+    document.body.click();
+    expect(tooltip.open).toBeFalsy();
+  });
+});
diff --git a/static/shared/tooltip/tooltip.ts b/static/shared/tooltip/tooltip.ts
new file mode 100644
index 0000000..c45dcd2
--- /dev/null
+++ b/static/shared/tooltip/tooltip.ts
@@ -0,0 +1,20 @@
+/**
+ * @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.
+ */
+
+/**
+ * ToolTipController handles closing tooltips on external clicks.
+ */
+export class ToolTipController {
+  constructor(private el: HTMLDetailsElement) {
+    document.addEventListener('click', e => {
+      const insideTooltip = this.el.contains(e.target as Element);
+      if (!insideTooltip) {
+        this.el.removeAttribute('open');
+      }
+    });
+  }
+}
diff --git a/static/shared/typography/typography.css b/static/shared/typography/typography.css
new file mode 100644
index 0000000..2b656b1
--- /dev/null
+++ b/static/shared/typography/typography.css
@@ -0,0 +1,119 @@
+/*!
+ * 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.
+ */
+
+body {
+  color: var(--color-text);
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif,
+    'Apple Color Emoji', 'Segoe UI Emoji';
+  font-size: 1rem;
+  line-height: normal;
+}
+h1 {
+  font-size: 1.5rem;
+}
+h2 {
+  font-size: 1.375rem;
+}
+h3 {
+  font-size: 1.25rem;
+}
+h4 {
+  font-size: 1.125rem;
+}
+h5 {
+  font-size: 1rem;
+}
+h6 {
+  font-size: 0.875rem;
+}
+
+h1,
+h2,
+h3,
+h4 {
+  font-weight: 600;
+  line-height: 1.25em;
+  word-break: break-word;
+}
+h5,
+h6 {
+  font-weight: 500;
+  line-height: 1.3em;
+  word-break: break-word;
+}
+
+hr {
+  border: none;
+  border-bottom: var(--border);
+  margin: 0;
+  width: 100%;
+}
+
+p {
+  font-size: 1rem;
+  line-height: 1.5rem;
+  max-width: 60rem;
+}
+strong {
+  font-weight: 600;
+}
+
+.go-textSubtle {
+  color: var(--color-text-subtle);
+}
+.go-textTitle {
+  font-size: 1.125rem;
+  font-weight: 600;
+  line-height: 1.25rem;
+}
+.go-textLabel {
+  font-size: 0.875rem;
+  font-weight: 600;
+  line-height: 1rem;
+}
+.go-textPagination {
+  font-size: 0.875rem;
+  line-height: 1rem;
+}
+code,
+pre,
+textarea.code {
+  font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+  font-size: 0.875rem;
+  line-height: 1.5em;
+}
+pre,
+textarea.code {
+  background-color: var(--color-background-accented);
+  border: var(--border);
+  border-radius: var(--border-radius);
+  color: var(--color-text);
+  overflow-x: auto;
+  padding: 0.625rem;
+  tab-size: 4;
+  white-space: pre;
+}
+
+button,
+input,
+select,
+textarea {
+  font: inherit;
+}
+
+a,
+a:link,
+a:visited {
+  color: var(--color-brand-primary);
+  text-decoration: none;
+}
+a:hover {
+  color: var(--color-brand-primary);
+  text-decoration: underline;
+}
+a:hover > * {
+  text-decoration: underline;
+}
diff --git a/static/shared/typography/typography.md b/static/shared/typography/typography.md
new file mode 100644
index 0000000..7bd0fee
--- /dev/null
+++ b/static/shared/typography/typography.md
@@ -0,0 +1,55 @@
+## Typography
+
+---
+
+```html {#h1}
+<h1>Heading 1</h1>
+```
+
+```html {#h2}
+<h2>Heading 2</h2>
+```
+
+```html {#h3}
+<h3>Heading 3</h3>
+```
+
+```html {#h4}
+<h4>Heading 4</h4>
+```
+
+```html {#h5}
+<h5>Heading 5</h5>
+```
+
+```html {#h6}
+<h6>Heading 6</h6>
+```
+
+```html {#paragraph}
+<p>Paragraph</p>
+```
+
+```html {#subtle-text}
+<div class="go-textSubtle">Subtle text</div>
+```
+
+```html {#label-text}
+<div class="go-textLabel">Label text</div>
+```
+
+```html {#pagination-text}
+<div class="go-textPagination">Pagination text</div>
+```
+
+```html {#code-text}
+<code>Code text</code>
+```
+
+```html {#pre-text}
+<pre>Preformated text</pre>
+```
+
+```html {#link-text}
+<a href="#typography" data-gtmc="_ link">Link</a>
+```
diff --git a/static/shared/vuln/vuln.tmpl b/static/shared/vuln/vuln.tmpl
new file mode 100644
index 0000000..40a03a6
--- /dev/null
+++ b/static/shared/vuln/vuln.tmpl
@@ -0,0 +1,18 @@
+<!--
+  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 "vuln-message"}}
+  <div class="go-Message go-Message--alert">
+    <img
+        class="go-Icon"
+        height="24"
+        width="24"
+        src="/static/shared/icon/alert_gm_grey_24dp.svg"
+        alt="Alert"
+    />&nbsp;
+    <a href="/vuln/{{.ID}}">{{.ID}}</a>: {{.Details}}
+  </div>
+{{end}}