diff --git a/CHANGELOG.md b/CHANGELOG.md
index db26aa8e847a3b666d11591f91c658fedb1fefe0..c10e99427e99350f2c2012e0972ec4ab4abf502f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,12 @@
     sendNote.
 * Fixed style for gitlab-heatmap partial to match overall theme.
 * Fixed `Uncaught ReferenceError: ga is not defined` error in web console.
+* Added W3C specification styling for writing W3C recomendations directly.
+* Added used-by shortcode for displaying brands you've worked with.
+* Fixed bug where using the tabbed shortcode across different pages may cause
+    a nonexistant tab to be selected.
+* Added project type with layouts for rendering projects in a more visually
+    appealing way.
 
 ## 2.1.0
 
diff --git a/README.md b/README.md
index 7623624c3fe5bc9079a4244d5c43e76a53c82fb9..8d1cdbe1979d86493d06b29dacc1e6d8cd59b256 100644
--- a/README.md
+++ b/README.md
@@ -161,3 +161,33 @@ All that is left now is to push your code to your GitLab repo. At that point the
 # Development
 
 Please see the `CONTRIBUTING.md` file for instructions regarding development and contribution.
+
+# W3C Specifications
+
+Now supports W3C specifications such as `working_draft` and `unofficial_draft`. Example with front matter:
+
+```
+---
+date: '2023-10-06T06:54:34'
+title: Semantic Versioning
+subtitle: v3.0.0, W3C Working Draft, 30 March 2024
+draft: false
+type: page
+w3c: working_draft
+w3c_latest_version: https://semantic-versioning.org
+w3c_feedback: ["https://git.qoto.org/semantic-versioning/semantic-versioning/-/issues"]
+w3c_editors:
+   "Jeffrey Phillips Freemam": "https://JeffreyFreeman.me"
+---
+
+{{<container>}}
+
+{{<w3c-header>}}
+
+## Foo
+
+Blah, blah....
+
+{{<container>}}
+
+```
diff --git a/api/gitlab/proxy.ts b/api/gitlab/proxy.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bc8eeb81ce8d8ff3451b6861c977c75efe36d8d6
--- /dev/null
+++ b/api/gitlab/proxy.ts
@@ -0,0 +1,52 @@
+import type { VercelRequest, VercelResponse } from '@vercel/node';
+
+interface AuthToken {
+  token: string,
+  uri: string,
+}
+
+export default async function (req: VercelRequest, res: VercelResponse) {
+  const { body, query, method, url, headers } = req
+
+  const gitlab_tokens_var = process.env.GITLAB_ENDPOINT_TOKENS
+  var array: String[] = []
+  var authTokenArray: Array<AuthToken> = []
+  let endpointURI = new URL(query.url.toString())
+
+  if(gitlab_tokens_var) {
+    array = gitlab_tokens_var!.split(",")
+  }
+
+  // Parse environment variable $GITLAB_ENDPOINT_TOKENS
+  // into authTokenArray
+  for(var i = 0; i < array.length; i++) {
+    let token: string = array[i].split(/:(.*)/s)[0]
+    let uri: string = array[i].split(/:(.*)/s)[1]
+    authTokenArray.push({ token: token, uri: uri })
+  }
+
+  // Check authTokenArray for token to add to query
+  var injectToken: String = ""
+
+  for(var i = 0; i < authTokenArray.length; i++) {
+    let uri: URL = new URL(authTokenArray[i]['uri'])
+    if(uri.hostname == endpointURI.hostname) {
+      injectToken = authTokenArray[i].token
+    }
+  }
+
+  var apiResult: Response = await fetch(endpointURI.toString(), {
+    method: "GET",
+    headers: { "PRIVATE-TOKEN": injectToken.toString(),
+                "Content-Type": "application/json",
+                "Accept": "application/json" },
+  })
+
+  let resultJson = await apiResult.json()
+
+  console.log(resultJson)
+
+  res.statusCode = 200
+  res.setHeader("Content-Type", 'application/json')
+  res.send(resultJson)
+};
diff --git a/layouts/partials/body_project_list.html b/layouts/partials/body_project_list.html
new file mode 100644
index 0000000000000000000000000000000000000000..f571d726c4f0de4f14a20e0acd857a34d59faf74
--- /dev/null
+++ b/layouts/partials/body_project_list.html
@@ -0,0 +1,16 @@
+<section class="section-lg">
+  <div class="container">
+    <div class="row center">
+      <div class="col center-text">
+        <h2>{{ .Params.heading }}</h2>
+        <p>{{ .Params.subheading }}</p>
+      </div>
+    </div>
+    <div id="cal-heatmap-container">
+      <div id="cal-heatmap" class="cal-heatmap"></div>
+      <div id="cal-heatmap-legend" class="cal-heatmap-legend"></div>
+    </div>
+    
+    {{ partial "projects_for_section.html" . }}
+  </div>
+</section>
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index 6fc49411b63846775fad289f90235814a9a41695..ad673f333fbdd250c1ae26a37c9c2a7f3f105310 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -126,7 +126,13 @@
 <link rel="stylesheet" href="/css/glyphicons.css">
 <link rel="stylesheet" href="/css/pseudocode.css">
 <link rel="stylesheet" href="/javascripts/cal-heatmap/cal-heatmap.css">
+<link rel="stylesheet" href="/css/gitlab-widgets/gitlab-widgets.css">
 <link rel="stylesheet" href="/css/main.css">
+{{ if eq .Params.w3c "working_draft" -}}
+<link rel="stylesheet" href="/css/W3C-WD.css">
+{{ else if eq .Params.w3c "unofficial_draft" -}}
+<link rel="stylesheet" href="/css/W3C-UD.css">
+{{ end -}}
 
 {{ range .AlternativeOutputFormats -}}
 <link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
@@ -136,6 +142,7 @@
 <script type="text/javascript" src="/javascripts/pseudocode.js"></script>
 <script type="text/javascript" src="/javascripts/jquery.js"></script>
 <script type="text/javascript" src="/javascripts/head.js"></script>
+<script type="module" src="/javascripts/gitlab-widgets/gitlab-widgets.js"></script>
 <script type="text/javascript" >
 document.addEventListener("DOMContentLoaded", function() {
     var blocks = document.getElementsByClassName("pseudocode");
@@ -200,16 +207,20 @@ document.addEventListener("DOMContentLoaded", function() {
     const dataMap = new Map(Object.entries(data));
 
     for ( let i = 1; i < dataSources.length ; i++) {
-      let dataNew = JSON.parse(getJSON(dataSources[i]));
-      let dataMapNew = new Map(Object.entries(dataNew));
+      try {
+        let dataNew = JSON.parse(getJSON(dataSources[i]));
+        let dataMapNew = new Map(Object.entries(dataNew));
 
-      for (let [key, value] of dataMapNew) {
-        let valueOld = dataMap.get(key);
-        if( valueOld ) {
-          dataMap.set(key, valueOld + value);
-        } else {
-          dataMap.set(key, value);
+        for (let [key, value] of dataMapNew) {
+          let valueOld = dataMap.get(key);
+          if( valueOld ) {
+            dataMap.set(key, valueOld + value);
+          } else {
+            dataMap.set(key, value);
+          }
         }
+      } catch(error) {
+        console.error(error, error.stack)
       }
     }
 
diff --git a/layouts/partials/projects_for_section.html b/layouts/partials/projects_for_section.html
new file mode 100644
index 0000000000000000000000000000000000000000..a21a41ac08ddfe74b2d7f3f361f23b50bbcb5001
--- /dev/null
+++ b/layouts/partials/projects_for_section.html
@@ -0,0 +1,19 @@
+{{ range $index, $element := .Data.Pages }}
+  {{- if math.ModBool $index 3 }}{{- if ne $index 0 }}</div>{{ end }}<div class="row">{{ end }}
+    <div class="col">
+      <a class="card" {{ if .Content }}href="{{ .Permalink }}"{{ else if .Params.repoUrl }}href="{{ .Params.repoUrl }}"{{ end }}>
+        <div class="card__body">
+          <h4 style="margin:0;text-transform:capitalize">{{ .Title}}</h4>
+          <small>{{- if .Params.description }}{{ .Params.description }}{{ else }}{{.Content }} {{ end }}</small>
+        </div>
+        {{- if (or (.Params.repoPath) (.Params.projLang) )}}
+        <hr style="margin:15px 0 10px 0">
+        <div style="display:flex;flex-direction:row;justify-content:space-between;padding:0 15px 10px 15px;font-size:0.8em">
+          <div>{{ .Params.repoPath }}</div>
+          <div>{{ .Params.projLang }}</div>
+        </div>
+        {{- end }}
+      </a>
+    </div>
+{{ end }}
+</div>
diff --git a/layouts/project/list.html b/layouts/project/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..b250d3f9d0c8f73c8c55e5307b278b8481688498
--- /dev/null
+++ b/layouts/project/list.html
@@ -0,0 +1,3 @@
+{{ partial "top_list_generic.html" . }}
+{{ partial "body_project_list.html" . }}
+{{ partial "bottom_list.html" . }}
diff --git a/layouts/project/single.html b/layouts/project/single.html
new file mode 100644
index 0000000000000000000000000000000000000000..6ba1fb76d9e3a5129f3965378d5e4a34454d044f
--- /dev/null
+++ b/layouts/project/single.html
@@ -0,0 +1,3 @@
+{{ partial "top_home.html" . }}
+{{ .Content }}
+{{ partial "bottom_home.html" . }}
diff --git a/layouts/shortcodes/advisement-box.html b/layouts/shortcodes/advisement-box.html
new file mode 100644
index 0000000000000000000000000000000000000000..eb7f29cfdf106b96afc00fe500f4b3f01562ee7c
--- /dev/null
+++ b/layouts/shortcodes/advisement-box.html
@@ -0,0 +1,3 @@
+<div class="advisement">
+    {{ .Inner }}
+</div>
\ No newline at end of file
diff --git a/layouts/shortcodes/algorithm.html b/layouts/shortcodes/algorithm.html
new file mode 100644
index 0000000000000000000000000000000000000000..591f5377e6c46740817208c5b63d2e4884732505
--- /dev/null
+++ b/layouts/shortcodes/algorithm.html
@@ -0,0 +1,4 @@
+<div class="algorithm">
+    {{ .Inner }}
+</div>
+  
\ No newline at end of file
diff --git a/layouts/shortcodes/example-box.html b/layouts/shortcodes/example-box.html
new file mode 100644
index 0000000000000000000000000000000000000000..4b702ae2f4511a5c1ed1d068d2517332800df907
--- /dev/null
+++ b/layouts/shortcodes/example-box.html
@@ -0,0 +1,3 @@
+<div class="example">
+    {{ .Inner }}
+</div>
\ No newline at end of file
diff --git a/layouts/shortcodes/example-tab.html b/layouts/shortcodes/example-tab.html
new file mode 100644
index 0000000000000000000000000000000000000000..b8871a75af3c6d458d9a03f2b40b290f7dea1b98
--- /dev/null
+++ b/layouts/shortcodes/example-tab.html
@@ -0,0 +1,9 @@
+<div class="code-with-header tab-pane" title={{ with .Get "title" }}{{ . }}{{ end }}>
+  {{ with .Get "title" }}<div class="code-header">{{ . }}</div>{{ end }}
+  <div class="scrollbar-container">
+    <div class="codeBlockWrapper_2QGZ">
+      {{ .Inner }}
+      {{ with .Get "add_copy" }}<button type="button" aria-label="Copy code to clipboard" class="copyButton_1BYj">Copy</button>{{ end }}
+    </div>
+  </div>
+</div>
diff --git a/layouts/shortcodes/figure.html b/layouts/shortcodes/figure.html
index 6a2cd5c579c62fbe457315cbd13392ca44a4bf4e..595e3a598f8e75a39c7b5415b399b2ad49e4f1d0 100644
--- a/layouts/shortcodes/figure.html
+++ b/layouts/shortcodes/figure.html
@@ -1,5 +1,5 @@
 <figure>
-    {{- if .Get "src" }}<a href="{{ .Get "src" }}">{{ end }}
+    {{- if .Get "link" }}<a href="{{ .Get "link" }}">{{ end }}
     <img
     {{ with .Get "src" }}src="{{ . }}"{{ end }}
     {{ with .Get "alt" }}alt="{{ range (split . " ") }}{{ . }} {{ end }}"{{ end }}
@@ -10,6 +10,6 @@
     {{ with .Get "width" }}width="{{ . }}"{{ end }}
     {{ with .Get "height" }}height="{{ . }}"{{ end }}
     {{ with .Get "layout" }}layout="{{ . }}"{{ end }} />
-    {{- if .Get "src" }}</a>{{ end }}
+    {{- if .Get "link" }}</a>{{ end }}
     {{ with  .Get "caption" }}<figcaption>{{ . }}</figcaption>{{ end }}
 </figure>
diff --git a/layouts/shortcodes/gitlab-overview.html b/layouts/shortcodes/gitlab-overview.html
new file mode 100644
index 0000000000000000000000000000000000000000..837010ab82a467b1bc0a33a3d422178c16199b2b
--- /dev/null
+++ b/layouts/shortcodes/gitlab-overview.html
@@ -0,0 +1,64 @@
+<div class="gitlab-overview-container">
+  <!-- Adds widget arguments to DOM -->
+
+  {{ range $key, $value := $.Params }}
+    <input type="hidden" id={{ $key }} value={{ $value }}></input>
+  {{ end }}
+
+  {{ if isset .Params `displayCount` }}
+    <input type="hidden" class="displayCount" value={{ .Get "displayCount" }}></input>
+  {{ end }}
+
+  {{ if isset .Params `stats` }}
+    <input type="hidden" id="stats" value={{ .Get "stats" }}></input>
+  {{ end }}
+
+  <!-- End of widget arguments -->
+
+  <h1 class="project-name"></h1>
+  <!--
+  <h2 class="project-header">Overview</h2>
+  -->
+
+  <div class="gitlab-overview" class="gitlab-overview">
+    
+    <div id="overview">
+      <span class="label">Releases:</span>
+      <span class="gitlab-overview-release-list"></span>
+    </div>
+
+    <table class="gitlab-progress-list">
+      <th>Release</th>
+      <th>Completion</th>
+      <th>Due Date</th>
+      <th class="percentage-column">Percentage</th>
+    </table>
+
+    <div class="gitlab-overview-footer">
+      <div class="footer-element">
+        <span class="label">Commits:</span>
+        <span id="commits"></span>
+      </div>
+      <div class="footer-element">
+        <span class="label">Tickets:</span>
+        <span id="issues">
+          <span id="issue-count"></span>
+          <span>/</span>
+          <span id="issue-total"></span>
+        </span>
+      </div>
+      <div class="footer-element">
+        <span class="label">MR:</span>
+        <span id="merge-requests">
+          <span id="mr-count"></span>
+          <span>/</span>
+          <span id="mr-total"></span>
+        </span>
+      </div>
+      <div class="footer-element">
+        <span class="label">Stars:</span>
+        <span id="stars"></span>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/layouts/shortcodes/gitlab-single-version.html b/layouts/shortcodes/gitlab-single-version.html
new file mode 100644
index 0000000000000000000000000000000000000000..0d3cbc79d4d8d33748470e86998129629cb6b23e
--- /dev/null
+++ b/layouts/shortcodes/gitlab-single-version.html
@@ -0,0 +1,56 @@
+<div class="gitlab-single-version-container">
+  <!-- Adds widget arguments to DOM -->
+
+  {{ range $key, $value := $.Params }}
+    <input type="hidden" id={{ $key }} value={{ $value }}></input>
+  {{ end }}
+
+  {{ if isset .Params `stats` }}
+    <input type="hidden" id="stats" value={{ .Get "stats" }}></input>
+  {{ end }}
+
+  <!-- End of widget arguments -->
+
+  <h1 class="release-name">Test</h1>
+
+  <div class="gitlab-single-version-overview" class="gitlab-overview">
+
+    <table class="gitlab-milestone-progress">
+      <th>Release</th>
+      <th class="completion-tableheader">Completion</th>
+      <th class="due-date-tableheader">Due Date</th>
+      <th class="percentage-column">Percentage</th>
+      <tr class="gitlab-single-version-entry">
+        <td class="title"></td>
+        <td class="percentage-complete"></td>
+        <td class="due-date"></td>
+        <td class="progress-bar">
+          <progress></progress>
+        </td>
+      </tr>
+    </table>
+
+    <div class="gitlab-overview-footer">
+      <div class="footer-element">
+        <span class="label">Commits:</span>
+        <span id="commits"></span>
+      </div>
+      <div class="footer-element">
+        <span class="label">Tickets:</span>
+        <span id="issues">
+          <span id="issue-count"></span>
+          <span>/</span>
+          <span id="issue-total"></span>
+        </span>
+      </div>
+      <div class="footer-element">
+        <span class="label">MR:</span>
+        <span id="merge-requests">
+          <span id="mr-count"></span>
+          <span>/</span>
+          <span id="mr-total"></span>
+        </span>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/layouts/shortcodes/note-box.html b/layouts/shortcodes/note-box.html
new file mode 100644
index 0000000000000000000000000000000000000000..0c5b6e09ca6d98f12e5f877be25b400f8c8c03a9
--- /dev/null
+++ b/layouts/shortcodes/note-box.html
@@ -0,0 +1,3 @@
+<div class="note">
+    {{ .Inner }}
+</div>
\ No newline at end of file
diff --git a/layouts/shortcodes/text-box.html b/layouts/shortcodes/text-box.html
new file mode 100644
index 0000000000000000000000000000000000000000..9648df06815300947f32cbe65787e0280dd9e0ce
--- /dev/null
+++ b/layouts/shortcodes/text-box.html
@@ -0,0 +1,6 @@
+<div class="text-box">
+  <blockquote>
+       {{ .Inner }}
+  </blockquote>
+  {{ if .Get "source" }}<cite>{{ .Get "source" }}</cite>{{ end }}
+</div>
diff --git a/layouts/shortcodes/titled-side.html b/layouts/shortcodes/titled-side.html
index 77b92dab9d5ccc3d48f86fc3b7deffae1f00ff8c..6bcd33d54213c183024daab1ec5eeb4bb2434c20 100644
--- a/layouts/shortcodes/titled-side.html
+++ b/layouts/shortcodes/titled-side.html
@@ -1,7 +1,7 @@
 <header class="titled-side">
   <div class="container">
     <div class="row titled-side__inner">
-      <div class="col col--5 titled-side--title center-text">
+      <div class="col col--6 titled-side--title center-text">
         <h2>{{ .Get 0 }}</h2>
         <p >{{ .Get 1 }}</p>
         <div>
@@ -9,7 +9,7 @@
           <a class="button button-primary titled-side-content" to="{{ .Get 5 }}" href="{{ .Get 5 }}">{{ .Get 4 }}</a>
         </div>
       </div>
-      <div class="col col--7 titled-side--content">
+      <div class="col col--6 titled-side--content">
         {{ .Inner }}
       </div>
     </div>
diff --git a/layouts/shortcodes/used-by-entry.html b/layouts/shortcodes/used-by-entry.html
new file mode 100644
index 0000000000000000000000000000000000000000..e603973b70bf20d26852d92434ee55b641a9f710
--- /dev/null
+++ b/layouts/shortcodes/used-by-entry.html
@@ -0,0 +1,10 @@
+<img class="brand-logo"
+    {{ with .Get "src" }}src="{{ . }}"{{ end }}
+    {{ with .Get "alt" }}alt="{{ range (split . " ") }}{{ . }} {{ end }}"{{ end }}
+    {{ with .Get "attribution" }}attribution="{{ range (split . " ") }}{{ . }} {{ end }}"{{ end }}
+    {{ with .Get "srcset" }}srcset="{{ range (split . " ") }}{{ . }} {{ end }}"{{ end }}
+    {{ with .Get "tabindex" }}tabindex="{{ . }}"{{ end }}
+    {{ with .Get "role" }}role="{{ . }}"{{ end }}
+    {{ with .Get "width" }}width="{{ . }}"{{ end }}
+    {{ with .Get "height" }}height="{{ . }}"{{ end }}
+    {{ with .Get "layout" }}layout="{{ . }}"{{ end }} />
\ No newline at end of file
diff --git a/layouts/shortcodes/used-by.html b/layouts/shortcodes/used-by.html
new file mode 100644
index 0000000000000000000000000000000000000000..8a571c044a72bf5a209e4864c44e234095d4566a
--- /dev/null
+++ b/layouts/shortcodes/used-by.html
@@ -0,0 +1,8 @@
+<section class="separator brands-box">
+  <div class="container">
+    <span class="brand-logos">
+      {{ .Inner }}
+    </span>
+    <div class="brand-text">{{- if .Get "caption" }}{{ .Get "caption" }}{{ else }}Brands that have used our technology{{ end }}</div>
+  </div>
+</section>
diff --git a/layouts/shortcodes/w3c-header.html b/layouts/shortcodes/w3c-header.html
new file mode 100644
index 0000000000000000000000000000000000000000..d0100f328c8def0a4d05dcba6d165802dfbb75e2
--- /dev/null
+++ b/layouts/shortcodes/w3c-header.html
@@ -0,0 +1,40 @@
+<div class="head">
+    <div class="w3c_logo"><a class="logo" href="https://www.w3.org/"><img alt="W3C" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" width="72"> </a> </div>
+    <h1 id="title">{{ if .Page.Title }}{{ .Page.Title }}{{ end }}</h1>
+    {{ if .Page.Params.Subtitle }}<h2 id="subtitle">{{ .Page.Params.Subtitle}}</h2>{{ end }}
+    <div>
+        <dl>
+            <dt>This version:
+            </dt>
+            <dd>
+                <a class="u-url" href="{{.Page.Permalink}}">{{.Page.Permalink}}</a>
+            </dd>
+            <dt>
+                Latest version:
+            </dt>
+            <dd>
+                <a href="{{.Page.Params.w3c_latest_version}}">{{.Page.Params.w3c_latest_version}}</a>
+            </dd>
+            <dt>
+                Previous Version:
+            </dt>
+            <dd>
+                <a href="{{ if .Page.Params.w3c_previous_version }}{{.Page.Params.w3c_previous_version}}{{else}}{{.Page.Permalink}}{{end}}" rel="previous">{{ if .Page.Params.w3c_previous_version }}{{.Page.Params.w3c_previous_version}}{{else}}{{.Page.Permalink}}{{end}}</a>
+            </dd>{{ if .Page.Params.w3c_feedback -}}<dt>
+                Feedback:
+            </dt>{{range .Page.Params.w3c_feedback}}<dd><a href="{{.}}">{{.}}</a></dd>{{end -}}{{end -}}
+            {{ if .Page.Params.w3c_editors -}}<dt class="editor">Editors:
+            </dt>{{ range $key, $value := .Page.Params.w3c_editors }}<dd><a href="{{$value}}">{{$key | title}}</a></dd>{{end -}}{{end -}}
+        </dl>
+    </div>
+    <div></div>
+    <p class="copyright">Copyright © 2024 - Present<sup>®</sup>(<a
+            href="http://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a
+            href="http://www.ercim.eu/"><abbr
+                title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a
+            href="http://www.keio.ac.jp/">Keio</a>, <a href="http://ev.buaa.edu.cn/">Beihang</a>). W3C <a
+            href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a
+            href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a
+            href="https://www.w3.org/Consortium/Legal/copyright-documents">document use</a> rules apply. </p>
+    <hr title="Separator for header">
+</div>
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 4c4b2ab001a20b01cabbf307758f03bc3361c266..e9e876ddc8bd9bacf578936cfa77bd0762abc4a1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,17 +1,17 @@
 {
-  "name": "flear.org",
+  "name": "fedipage",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
-      "name": "flear.org",
+      "name": "fedipage",
       "dependencies": {
         "@firebase/app-types": "^0.9.0",
         "@polymath-ai/client": "*",
         "@polymath-ai/host": "*",
-        "@types/node": "^20.8.2",
         "@vercel/analytics": "^1.0.2",
         "@vercel/edge": "^1.1.0",
+        "@vercel/functions": "^1.4.0",
         "@vercel/node": "^3.0.7",
         "@vercel/og": "^0.5.17",
         "activitypub-core-types": "^0.3.2",
@@ -19,17 +19,19 @@
         "file-drop-element": "^1.0.1",
         "firebase-admin": "^11.11.0",
         "hugo-bin": "^0.115.0",
+        "jquery": "^3.7.1",
         "multiparty": "^4.2.3",
+        "next": "^14.2.5",
         "node-fetch": "^3.3.2",
         "pinch-zoom-element": "^1.1.1",
-        "ts-node": "^10.9.1",
         "uuid": "^9.0.1",
-        "vercel": "^32.4.1",
-        "whatwg-flora-tmpl": "^1.0.3"
+        "vercel": "^32.7.2",
+        "whatwg-flora-tmpl": "^1.0.3",
+        "xmlhttprequest": "^1.8.0"
       },
       "devDependencies": {
         "@types/multiparty": "^0.0.34",
-        "typescript": "^5.2.2"
+        "typescript": "^5.5.4"
       },
       "engines": {
         "node": ">= 18.0.0"
@@ -85,20 +87,28 @@
         "node": ">=16"
       }
     },
+    "node_modules/@edge-runtime/ponyfill": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/ponyfill/-/ponyfill-2.4.1.tgz",
+      "integrity": "sha512-ZbR/EViY3gg2rmEAQTKPa6mXl4aR1/+cFcQe4r1segCjEbTAxT6PWu40odbu/KlZKSysEb2O/BWIC2lJgSJOMQ==",
+      "engines": {
+        "node": ">=16"
+      }
+    },
     "node_modules/@edge-runtime/primitives": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-3.1.1.tgz",
-      "integrity": "sha512-ROO22py+KdAfzqWZu6CtVMC4qV6mS0W1jPI51jGXE+uenyBUN7cQTWB9ReQc8Bm4cnjqmhajvpqEx3j7Y9iSOg==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-4.0.5.tgz",
+      "integrity": "sha512-t7QiN5d/KpXgCvIfSt6Nm9Hj3WVdNgc5CpOD73jasY+9EvTI7Ngdj5cXvjcHrPcmYWJZMySPgeEeoL/1N/Llag==",
       "engines": {
         "node": ">=16"
       }
     },
     "node_modules/@edge-runtime/vm": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.1.1.tgz",
-      "integrity": "sha512-6NJRRG04/91qnWLZj+wZm27q6fJkTbkZdIJdo/Ig++GTxkAv8Wh/45nIcz9Xg7AzIAMpAkflFdiCrCoZ3hp1Iw==",
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.1.7.tgz",
+      "integrity": "sha512-hUMFbDQ/nZN+1TLMi6iMO1QFz9RSV8yGG8S42WFPFma1d7VSNE0eMdJUmwjmtav22/iQkzHMmu6oTSfAvRGS8g==",
       "dependencies": {
-        "@edge-runtime/primitives": "3.1.1"
+        "@edge-runtime/primitives": "4.0.5"
       },
       "engines": {
         "node": ">=16"
@@ -399,6 +409,146 @@
         }
       }
     },
+    "node_modules/@next/env": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz",
+      "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA=="
+    },
+    "node_modules/@next/swc-darwin-arm64": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz",
+      "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-darwin-x64": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz",
+      "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-linux-arm64-gnu": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz",
+      "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-linux-arm64-musl": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz",
+      "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-linux-x64-gnu": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz",
+      "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-linux-x64-musl": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz",
+      "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-win32-arm64-msvc": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz",
+      "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-win32-ia32-msvc": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz",
+      "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@next/swc-win32-x64-msvc": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz",
+      "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -588,6 +738,20 @@
         "url": "https://github.com/sindresorhus/is?sponsor=1"
       }
     },
+    "node_modules/@swc/counter": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+      "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
+    },
+    "node_modules/@swc/helpers": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
+      "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
+      "dependencies": {
+        "@swc/counter": "^0.1.3",
+        "tslib": "^2.4.0"
+      }
+    },
     "node_modules/@szmarczak/http-timer": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
@@ -813,9 +977,9 @@
       "integrity": "sha512-BZFxVrv24VbNNl5xMxqUojQIegEeXMI6rX3rg1uVLYUEXsuKNBSAEQf4BWEcjQDp/8aYJOj6m8V4PUA3x/cxgg=="
     },
     "node_modules/@vercel/build-utils": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-7.2.2.tgz",
-      "integrity": "sha512-CUMgVKTJCba5tGe+KZaVvwGUCsuSeuNEmPIzMggIMDtzdqllRu8+QjjIhEI+unHoYvUgGfen6Z5lMeMo9Ne0qQ=="
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-7.3.0.tgz",
+      "integrity": "sha512-RJwqrGYSk75auHZqWmlSL+a5JsWv+4SF1AxNQJ+KpF3XWZ/8yThkN/jHBfNxMmW6VvNczSVtMaXI0/2Sess6Eg=="
     },
     "node_modules/@vercel/edge": {
       "version": "1.1.0",
@@ -823,9 +987,9 @@
       "integrity": "sha512-84H2EavY5Kul9Ef1DnTH0XEG5vChqcXjyqoRLVPjjZjLWw47sMapzXXQH09pybcshR+8AKqULGvFqPTWuRh3Rw=="
     },
     "node_modules/@vercel/error-utils": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.1.tgz",
-      "integrity": "sha512-ZUVpRFArh5eyKpJmdfEuCaMpZKQvZgUq0pQ7PdK8m5FgRYEvF4I0TMJH3JnkbYaMMUH82aYWZr+/hFJtEBcmTQ=="
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.2.tgz",
+      "integrity": "sha512-Sj0LFafGpYr6pfCqrQ82X6ukRl5qpmVrHM/191kNYFqkkB9YkjlMAj6QcEsvCG259x4QZ7Tya++0AB85NDPbKQ=="
     },
     "node_modules/@vercel/fun": {
       "version": "1.1.0",
@@ -1028,6 +1192,22 @@
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
     },
+    "node_modules/@vercel/functions": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@vercel/functions/-/functions-1.4.0.tgz",
+      "integrity": "sha512-Ln6SpIkms1UJg306X2kbEMyG9ol+mjDr2xx389cvsBxgFyFMI9Bm+LYOG4N3TSik4FI59MECyyc4oz7AIAYmqQ==",
+      "engines": {
+        "node": ">= 16"
+      },
+      "peerDependencies": {
+        "@aws-sdk/credential-provider-web-identity": "*"
+      },
+      "peerDependenciesMeta": {
+        "@aws-sdk/credential-provider-web-identity": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@vercel/gatsby-plugin-vercel-analytics": {
       "version": "1.0.11",
       "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-analytics/-/gatsby-plugin-vercel-analytics-1.0.11.tgz",
@@ -1037,13 +1217,13 @@
       }
     },
     "node_modules/@vercel/gatsby-plugin-vercel-builder": {
-      "version": "2.0.7",
-      "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-builder/-/gatsby-plugin-vercel-builder-2.0.7.tgz",
-      "integrity": "sha512-hzaWLdBeb/QnGRE17ldaxeXMTLroaiJTlaW2G3HwvaK8sXA9e+jmcfAw8fjN3BNMnkFU523CnE7InqmjKH4TfQ==",
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-builder/-/gatsby-plugin-vercel-builder-2.0.12.tgz",
+      "integrity": "sha512-S1RkywrUItewqg06T3L4cgYfiwi2BFngHIIerhOYhVuD9A+yfMgxnH5dkbu6nujmV1SEws+Q92wSiPfLPmO0eA==",
       "dependencies": {
         "@sinclair/typebox": "0.25.24",
-        "@vercel/build-utils": "7.2.2",
-        "@vercel/routing-utils": "3.0.0",
+        "@vercel/build-utils": "7.3.0",
+        "@vercel/routing-utils": "3.1.0",
         "esbuild": "0.14.47",
         "etag": "1.8.1",
         "fs-extra": "11.1.0"
@@ -1074,17 +1254,17 @@
       }
     },
     "node_modules/@vercel/gatsby-plugin-vercel-builder/node_modules/universalify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
       "engines": {
         "node": ">= 10.0.0"
       }
     },
     "node_modules/@vercel/go": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vercel/go/-/go-3.0.3.tgz",
-      "integrity": "sha512-XhrmpsACxNo64ojhscL//Mq+XEfm3VXlx/UIUcHzJJXdvFnz7DEzh1zs0AtdpVgZbYhPQ7rW3GIejaHrIJnN5w=="
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@vercel/go/-/go-3.0.4.tgz",
+      "integrity": "sha512-hMIJm2xwU1HT56YRNF8HNOnIFNH7WnGl1l2D6lc6UJk7XdCCh1Dm0nsqLqki2SprTUh3I+53pTQaqgRsFGf06A=="
     },
     "node_modules/@vercel/hydrogen": {
       "version": "1.0.1",
@@ -1096,9 +1276,9 @@
       }
     },
     "node_modules/@vercel/next": {
-      "version": "4.0.10",
-      "resolved": "https://registry.npmjs.org/@vercel/next/-/next-4.0.10.tgz",
-      "integrity": "sha512-+Z+R7Dev1OFU9Rm8R4h34W0/RdSHeZ4dvkv50lS7TneRj1Ab1zLlqupyG0tEdSP5/Nvb/OZ4ixvTiLqw9oo8oA==",
+      "version": "4.0.15",
+      "resolved": "https://registry.npmjs.org/@vercel/next/-/next-4.0.15.tgz",
+      "integrity": "sha512-BxMxIJrya7MS6IWrQIaQaYHPmq7WoZFLX909RBpNoAG5wgzrTrW756d2EsibBwGo7sQYBv2atyI5GqBIHzYbWg==",
       "dependencies": {
         "@vercel/nft": "0.24.2"
       }
@@ -1128,20 +1308,20 @@
       }
     },
     "node_modules/@vercel/node": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/@vercel/node/-/node-3.0.7.tgz",
-      "integrity": "sha512-0KrDGi6z+qPtCyC7wSHmHDU/ot352AJpAeAO1OIEYqYFsYwzvwuyu7TbGGwiUbtolij4/EBUCls3YmwADM/vKw==",
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/@vercel/node/-/node-3.0.12.tgz",
+      "integrity": "sha512-OiNHiUe1LX/CfDrQ07ntPsoYhJiC38mEeErYeqA6YNVAz3QGdX3pthiaIig2KPqeeYkEx5bSkVIqQtQOTJBuLQ==",
       "dependencies": {
         "@edge-runtime/node-utils": "2.2.1",
-        "@edge-runtime/primitives": "3.1.1",
-        "@edge-runtime/vm": "3.1.1",
+        "@edge-runtime/primitives": "4.0.5",
+        "@edge-runtime/vm": "3.1.7",
         "@types/node": "14.18.33",
-        "@vercel/build-utils": "7.2.2",
-        "@vercel/error-utils": "2.0.1",
+        "@vercel/build-utils": "7.3.0",
+        "@vercel/error-utils": "2.0.2",
         "@vercel/nft": "0.24.2",
         "@vercel/static-config": "3.0.0",
         "async-listen": "3.0.0",
-        "edge-runtime": "2.5.1",
+        "edge-runtime": "2.5.7",
         "esbuild": "0.14.47",
         "etag": "1.8.1",
         "exit-hook": "2.2.1",
@@ -1150,7 +1330,7 @@
         "ts-morph": "12.0.0",
         "ts-node": "10.9.1",
         "typescript": "4.9.5",
-        "undici": "5.23.0"
+        "undici": "5.26.5"
       }
     },
     "node_modules/@vercel/node/node_modules/@types/node": {
@@ -1203,17 +1383,17 @@
       }
     },
     "node_modules/@vercel/python": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@vercel/python/-/python-4.0.2.tgz",
-      "integrity": "sha512-mmUeR3GBuDnaJK3IIHRoPl3bNevcWO3N/YrNAx+zxLPSHzfzmCLZbFVVXbzoKBi/cALiOPcApVhlQXwU26y7xg=="
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/@vercel/python/-/python-4.1.0.tgz",
+      "integrity": "sha512-EIQXK5zL6fce0Barh74gc7xyLtRyvgmLZDIVQ8yJLtFxPlPCRY3GXkdJ7Jdcw8Pd0uuVF0vIHatv18xSLbcwtg=="
     },
     "node_modules/@vercel/redwood": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/@vercel/redwood/-/redwood-2.0.4.tgz",
-      "integrity": "sha512-f0dzR8xQ34MKTzLmUygfu6vngCaRozN0z2Aao1sQ7sIC0+UExgiL0qJ9syejWwDv7IxK4yZ0w1WvztrHtAMa9Q==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vercel/redwood/-/redwood-2.0.5.tgz",
+      "integrity": "sha512-9iWTxfMkC7yNnwN2xxOdptiIDAgXe1V1fh3aw92MWt5PBRcFY9RqgIPF7Q3Qa7yzQFgpbHwCnSTqWO+HCEuFtw==",
       "dependencies": {
         "@vercel/nft": "0.24.2",
-        "@vercel/routing-utils": "3.0.0",
+        "@vercel/routing-utils": "3.1.0",
         "semver": "6.3.1"
       }
     },
@@ -1226,9 +1406,9 @@
       }
     },
     "node_modules/@vercel/remix-builder": {
-      "version": "2.0.9",
-      "resolved": "https://registry.npmjs.org/@vercel/remix-builder/-/remix-builder-2.0.9.tgz",
-      "integrity": "sha512-/wgZrnKGZYJ8Z1tgAQc2UUhF+51tGwSHw9PnAhnaY5KclLiBrnXSjKqUAXW8GyaM4IB1ZjPXoI5oARKKUGu8kQ==",
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/@vercel/remix-builder/-/remix-builder-2.0.14.tgz",
+      "integrity": "sha512-c+ILERSRq404sf6kt0qWhYhuxWkkoTEm2FdLoUnVs21K6kzGtJMJbUExEHoPZvN9a0tq86ZU86jVvRZV6WL0cQ==",
       "dependencies": {
         "@vercel/nft": "0.24.2",
         "@vercel/static-config": "3.0.0",
@@ -1236,9 +1416,9 @@
       }
     },
     "node_modules/@vercel/routing-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@vercel/routing-utils/-/routing-utils-3.0.0.tgz",
-      "integrity": "sha512-u+SoHnL+RzRQIRP+YxvigzzKXQcbgYQF9qCTIuWuoLw5h9thIYWcDJvz3KxrUzxjGZ3dWboXA29KAlT6eeaeFw==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@vercel/routing-utils/-/routing-utils-3.1.0.tgz",
+      "integrity": "sha512-Ci5xTjVTJY/JLZXpCXpLehMft97i9fH34nu9PGav6DtwkVUF6TOPX86U0W0niQjMZ5n6/ZP0BwcJK2LOozKaGw==",
       "dependencies": {
         "path-to-regexp": "6.1.0"
       },
@@ -1274,17 +1454,17 @@
       "integrity": "sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw=="
     },
     "node_modules/@vercel/ruby": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/@vercel/ruby/-/ruby-2.0.2.tgz",
-      "integrity": "sha512-MqFynhtZ905L210DWAbgkiEQEK39LTtp9eL2Nm6PjzhjNzU6hV0UfK8Z24vU9CC6J4mrUTTZx396fH7XTYJWqg=="
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@vercel/ruby/-/ruby-2.0.4.tgz",
+      "integrity": "sha512-EpZyfF6wFGzFDmubFIh/EZtYpKindmXx/69xSfKEBTVU0afgljyOOICbyZePe5tvigfOEBLSLgrt/2nN+MlLtA=="
     },
     "node_modules/@vercel/static-build": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/@vercel/static-build/-/static-build-2.0.8.tgz",
-      "integrity": "sha512-46//Pxez7mc+UdOZgNv6y9lPSBehMdvCxajb/nvquptDMNH543Itospu9lyt448EQoS7HVE1NSPI21iiCboqvA==",
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/@vercel/static-build/-/static-build-2.0.14.tgz",
+      "integrity": "sha512-l5eQtJbk5Pc+P8XARDnpcbX4LnK3bGy7uf6S1aFOD4h6F8iBdg0agWTufZnq5BI91pcPVICPazM5BYhigIEznQ==",
       "dependencies": {
         "@vercel/gatsby-plugin-vercel-analytics": "1.0.11",
-        "@vercel/gatsby-plugin-vercel-builder": "2.0.7",
+        "@vercel/gatsby-plugin-vercel-builder": "2.0.12",
         "@vercel/static-config": "3.0.0",
         "ts-morph": "12.0.0"
       }
@@ -2112,6 +2292,25 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001643",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz",
+      "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ]
+    },
     "node_modules/catharsis": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
@@ -2278,6 +2477,11 @@
         "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
+    "node_modules/client-only": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+      "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
+    },
     "node_modules/cliui": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -2649,16 +2853,16 @@
       }
     },
     "node_modules/edge-runtime": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.1.tgz",
-      "integrity": "sha512-E0kY1Dqvwvk9yh7dvR56KnCjXf/dlbrrGjO5Sjnz9Ja3WqYT3csv2B8O4erxJiOWfWy9NTukBk4Kb3yrR66gBw==",
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.7.tgz",
+      "integrity": "sha512-gA4qSVP0sNwJlkdQ2nahDPASlSl8twUd17o+JolPa1EtXpLTGzIpOETvodgJwXIxa+zaD8bnAXCdsWrx2PhlVQ==",
       "dependencies": {
         "@edge-runtime/format": "2.2.0",
-        "@edge-runtime/vm": "3.1.1",
+        "@edge-runtime/ponyfill": "2.4.1",
+        "@edge-runtime/vm": "3.1.7",
         "async-listen": "3.0.1",
         "mri": "1.2.0",
         "picocolors": "1.0.0",
-        "pretty-bytes": "5.6.0",
         "pretty-ms": "7.0.1",
         "signal-exit": "4.0.2",
         "time-span": "4.0.0"
@@ -4344,6 +4548,11 @@
         "url": "https://github.com/sponsors/panva"
       }
     },
+    "node_modules/jquery": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
+      "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
+    },
     "node_modules/js-string-escape": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@@ -4352,6 +4561,12 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "peer": true
+    },
     "node_modules/js-yaml": {
       "version": "3.14.1",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
@@ -4653,6 +4868,18 @@
       "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
       "optional": true
     },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "peer": true,
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
     "node_modules/lowercase-keys": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
@@ -5017,6 +5244,72 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/nanoid": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/next": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz",
+      "integrity": "sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==",
+      "dependencies": {
+        "@next/env": "14.2.5",
+        "@swc/helpers": "0.5.5",
+        "busboy": "1.6.0",
+        "caniuse-lite": "^1.0.30001579",
+        "graceful-fs": "^4.2.11",
+        "postcss": "8.4.31",
+        "styled-jsx": "5.1.1"
+      },
+      "bin": {
+        "next": "dist/bin/next"
+      },
+      "engines": {
+        "node": ">=18.17.0"
+      },
+      "optionalDependencies": {
+        "@next/swc-darwin-arm64": "14.2.5",
+        "@next/swc-darwin-x64": "14.2.5",
+        "@next/swc-linux-arm64-gnu": "14.2.5",
+        "@next/swc-linux-arm64-musl": "14.2.5",
+        "@next/swc-linux-x64-gnu": "14.2.5",
+        "@next/swc-linux-x64-musl": "14.2.5",
+        "@next/swc-win32-arm64-msvc": "14.2.5",
+        "@next/swc-win32-ia32-msvc": "14.2.5",
+        "@next/swc-win32-x64-msvc": "14.2.5"
+      },
+      "peerDependencies": {
+        "@opentelemetry/api": "^1.1.0",
+        "@playwright/test": "^1.41.2",
+        "react": "^18.2.0",
+        "react-dom": "^18.2.0",
+        "sass": "^1.3.0"
+      },
+      "peerDependenciesMeta": {
+        "@opentelemetry/api": {
+          "optional": true
+        },
+        "@playwright/test": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/node-domexception": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -5505,6 +5798,33 @@
       "resolved": "https://registry.npmjs.org/pointer-tracker/-/pointer-tracker-2.5.3.tgz",
       "integrity": "sha512-LiJUeIbzk4dXq678YeyrZ++mdY17q4n/2sBHfU9wIuvmSzdiPgMvmvWN2g8mY4J7YwYOIrqrZUWP/MfFHVwYtg=="
     },
+    "node_modules/postcss": {
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.6",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
     "node_modules/postcss-value-parser": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@@ -5519,17 +5839,6 @@
         "node": ">= 0.8.0"
       }
     },
-    "node_modules/pretty-bytes": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
-      "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/pretty-ms": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz",
@@ -5774,6 +6083,31 @@
         "node": ">=0.6"
       }
     },
+    "node_modules/react": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+      "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+      "peer": true,
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-dom": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+      "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+      "peer": true,
+      "dependencies": {
+        "loose-envify": "^1.1.0",
+        "scheduler": "^0.23.2"
+      },
+      "peerDependencies": {
+        "react": "^18.3.1"
+      }
+    },
     "node_modules/readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -5987,6 +6321,15 @@
         "node": ">=16"
       }
     },
+    "node_modules/scheduler": {
+      "version": "0.23.2",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+      "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+      "peer": true,
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      }
+    },
     "node_modules/seek-bzip": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
@@ -6203,6 +6546,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/source-map-js": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -6424,6 +6775,28 @@
       "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
       "optional": true
     },
+    "node_modules/styled-jsx": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
+      "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
+      "dependencies": {
+        "client-only": "0.0.1"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "peerDependencies": {
+        "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
+      },
+      "peerDependenciesMeta": {
+        "@babel/core": {
+          "optional": true
+        },
+        "babel-plugin-macros": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/supertap": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz",
@@ -6727,9 +7100,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
-      "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+      "version": "5.5.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
+      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -6788,16 +7161,24 @@
       "optional": true
     },
     "node_modules/undici": {
-      "version": "5.23.0",
-      "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz",
-      "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==",
+      "version": "5.26.5",
+      "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz",
+      "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==",
       "dependencies": {
-        "busboy": "^1.6.0"
+        "@fastify/busboy": "^2.0.0"
       },
       "engines": {
         "node": ">=14.0"
       }
     },
+    "node_modules/undici/node_modules/@fastify/busboy": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
+      "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
+      "engines": {
+        "node": ">=14"
+      }
+    },
     "node_modules/unicode-trie": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
@@ -6854,21 +7235,21 @@
       "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
     },
     "node_modules/vercel": {
-      "version": "32.4.1",
-      "resolved": "https://registry.npmjs.org/vercel/-/vercel-32.4.1.tgz",
-      "integrity": "sha512-cULmLvceDaluXz2usPtPYhb9y/jwjWolAjBBbG1DLGQmxVlnHVHTOJrYPaq2ioujQpU0yi92+RQPdzjzOY6aEg==",
+      "version": "32.7.2",
+      "resolved": "https://registry.npmjs.org/vercel/-/vercel-32.7.2.tgz",
+      "integrity": "sha512-esyeo67OZ/f7usKFCrx6NSjsvpo/BP/C8Mfron2uiCb4vXVcjkwOM7TwliHx6b0DbXjpzomdGVUHKRs34VNn2Q==",
       "dependencies": {
-        "@vercel/build-utils": "7.2.2",
+        "@vercel/build-utils": "7.3.0",
         "@vercel/fun": "1.1.0",
-        "@vercel/go": "3.0.3",
+        "@vercel/go": "3.0.4",
         "@vercel/hydrogen": "1.0.1",
-        "@vercel/next": "4.0.10",
-        "@vercel/node": "3.0.7",
-        "@vercel/python": "4.0.2",
-        "@vercel/redwood": "2.0.4",
-        "@vercel/remix-builder": "2.0.9",
-        "@vercel/ruby": "2.0.2",
-        "@vercel/static-build": "2.0.8",
+        "@vercel/next": "4.0.15",
+        "@vercel/node": "3.0.12",
+        "@vercel/python": "4.1.0",
+        "@vercel/redwood": "2.0.5",
+        "@vercel/remix-builder": "2.0.14",
+        "@vercel/ruby": "2.0.4",
+        "@vercel/static-build": "2.0.14",
         "chokidar": "3.3.1"
       },
       "bin": {
@@ -7080,6 +7461,14 @@
       "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
       "optional": true
     },
+    "node_modules/xmlhttprequest": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+      "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/y18n": {
       "version": "5.0.8",
       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -7216,17 +7605,22 @@
         "@edge-runtime/cookies": "3.4.1"
       }
     },
+    "@edge-runtime/ponyfill": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/ponyfill/-/ponyfill-2.4.1.tgz",
+      "integrity": "sha512-ZbR/EViY3gg2rmEAQTKPa6mXl4aR1/+cFcQe4r1segCjEbTAxT6PWu40odbu/KlZKSysEb2O/BWIC2lJgSJOMQ=="
+    },
     "@edge-runtime/primitives": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-3.1.1.tgz",
-      "integrity": "sha512-ROO22py+KdAfzqWZu6CtVMC4qV6mS0W1jPI51jGXE+uenyBUN7cQTWB9ReQc8Bm4cnjqmhajvpqEx3j7Y9iSOg=="
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-4.0.5.tgz",
+      "integrity": "sha512-t7QiN5d/KpXgCvIfSt6Nm9Hj3WVdNgc5CpOD73jasY+9EvTI7Ngdj5cXvjcHrPcmYWJZMySPgeEeoL/1N/Llag=="
     },
     "@edge-runtime/vm": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.1.1.tgz",
-      "integrity": "sha512-6NJRRG04/91qnWLZj+wZm27q6fJkTbkZdIJdo/Ig++GTxkAv8Wh/45nIcz9Xg7AzIAMpAkflFdiCrCoZ3hp1Iw==",
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.1.7.tgz",
+      "integrity": "sha512-hUMFbDQ/nZN+1TLMi6iMO1QFz9RSV8yGG8S42WFPFma1d7VSNE0eMdJUmwjmtav22/iQkzHMmu6oTSfAvRGS8g==",
       "requires": {
-        "@edge-runtime/primitives": "3.1.1"
+        "@edge-runtime/primitives": "4.0.5"
       }
     },
     "@fastify/busboy": {
@@ -7466,6 +7860,65 @@
         }
       }
     },
+    "@next/env": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz",
+      "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA=="
+    },
+    "@next/swc-darwin-arm64": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz",
+      "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==",
+      "optional": true
+    },
+    "@next/swc-darwin-x64": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz",
+      "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==",
+      "optional": true
+    },
+    "@next/swc-linux-arm64-gnu": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz",
+      "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==",
+      "optional": true
+    },
+    "@next/swc-linux-arm64-musl": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz",
+      "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==",
+      "optional": true
+    },
+    "@next/swc-linux-x64-gnu": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz",
+      "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==",
+      "optional": true
+    },
+    "@next/swc-linux-x64-musl": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz",
+      "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==",
+      "optional": true
+    },
+    "@next/swc-win32-arm64-msvc": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz",
+      "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==",
+      "optional": true
+    },
+    "@next/swc-win32-ia32-msvc": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz",
+      "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==",
+      "optional": true
+    },
+    "@next/swc-win32-x64-msvc": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz",
+      "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==",
+      "optional": true
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -7630,6 +8083,20 @@
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz",
       "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g=="
     },
+    "@swc/counter": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+      "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
+    },
+    "@swc/helpers": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
+      "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
+      "requires": {
+        "@swc/counter": "^0.1.3",
+        "tslib": "^2.4.0"
+      }
+    },
     "@szmarczak/http-timer": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
@@ -7849,9 +8316,9 @@
       "integrity": "sha512-BZFxVrv24VbNNl5xMxqUojQIegEeXMI6rX3rg1uVLYUEXsuKNBSAEQf4BWEcjQDp/8aYJOj6m8V4PUA3x/cxgg=="
     },
     "@vercel/build-utils": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-7.2.2.tgz",
-      "integrity": "sha512-CUMgVKTJCba5tGe+KZaVvwGUCsuSeuNEmPIzMggIMDtzdqllRu8+QjjIhEI+unHoYvUgGfen6Z5lMeMo9Ne0qQ=="
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-7.3.0.tgz",
+      "integrity": "sha512-RJwqrGYSk75auHZqWmlSL+a5JsWv+4SF1AxNQJ+KpF3XWZ/8yThkN/jHBfNxMmW6VvNczSVtMaXI0/2Sess6Eg=="
     },
     "@vercel/edge": {
       "version": "1.1.0",
@@ -7859,9 +8326,9 @@
       "integrity": "sha512-84H2EavY5Kul9Ef1DnTH0XEG5vChqcXjyqoRLVPjjZjLWw47sMapzXXQH09pybcshR+8AKqULGvFqPTWuRh3Rw=="
     },
     "@vercel/error-utils": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.1.tgz",
-      "integrity": "sha512-ZUVpRFArh5eyKpJmdfEuCaMpZKQvZgUq0pQ7PdK8m5FgRYEvF4I0TMJH3JnkbYaMMUH82aYWZr+/hFJtEBcmTQ=="
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.2.tgz",
+      "integrity": "sha512-Sj0LFafGpYr6pfCqrQ82X6ukRl5qpmVrHM/191kNYFqkkB9YkjlMAj6QcEsvCG259x4QZ7Tya++0AB85NDPbKQ=="
     },
     "@vercel/fun": {
       "version": "1.1.0",
@@ -8023,6 +8490,12 @@
         }
       }
     },
+    "@vercel/functions": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@vercel/functions/-/functions-1.4.0.tgz",
+      "integrity": "sha512-Ln6SpIkms1UJg306X2kbEMyG9ol+mjDr2xx389cvsBxgFyFMI9Bm+LYOG4N3TSik4FI59MECyyc4oz7AIAYmqQ==",
+      "requires": {}
+    },
     "@vercel/gatsby-plugin-vercel-analytics": {
       "version": "1.0.11",
       "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-analytics/-/gatsby-plugin-vercel-analytics-1.0.11.tgz",
@@ -8032,13 +8505,13 @@
       }
     },
     "@vercel/gatsby-plugin-vercel-builder": {
-      "version": "2.0.7",
-      "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-builder/-/gatsby-plugin-vercel-builder-2.0.7.tgz",
-      "integrity": "sha512-hzaWLdBeb/QnGRE17ldaxeXMTLroaiJTlaW2G3HwvaK8sXA9e+jmcfAw8fjN3BNMnkFU523CnE7InqmjKH4TfQ==",
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-builder/-/gatsby-plugin-vercel-builder-2.0.12.tgz",
+      "integrity": "sha512-S1RkywrUItewqg06T3L4cgYfiwi2BFngHIIerhOYhVuD9A+yfMgxnH5dkbu6nujmV1SEws+Q92wSiPfLPmO0eA==",
       "requires": {
         "@sinclair/typebox": "0.25.24",
-        "@vercel/build-utils": "7.2.2",
-        "@vercel/routing-utils": "3.0.0",
+        "@vercel/build-utils": "7.3.0",
+        "@vercel/routing-utils": "3.1.0",
         "esbuild": "0.14.47",
         "etag": "1.8.1",
         "fs-extra": "11.1.0"
@@ -8064,16 +8537,16 @@
           }
         },
         "universalify": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-          "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+          "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="
         }
       }
     },
     "@vercel/go": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@vercel/go/-/go-3.0.3.tgz",
-      "integrity": "sha512-XhrmpsACxNo64ojhscL//Mq+XEfm3VXlx/UIUcHzJJXdvFnz7DEzh1zs0AtdpVgZbYhPQ7rW3GIejaHrIJnN5w=="
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@vercel/go/-/go-3.0.4.tgz",
+      "integrity": "sha512-hMIJm2xwU1HT56YRNF8HNOnIFNH7WnGl1l2D6lc6UJk7XdCCh1Dm0nsqLqki2SprTUh3I+53pTQaqgRsFGf06A=="
     },
     "@vercel/hydrogen": {
       "version": "1.0.1",
@@ -8085,9 +8558,9 @@
       }
     },
     "@vercel/next": {
-      "version": "4.0.10",
-      "resolved": "https://registry.npmjs.org/@vercel/next/-/next-4.0.10.tgz",
-      "integrity": "sha512-+Z+R7Dev1OFU9Rm8R4h34W0/RdSHeZ4dvkv50lS7TneRj1Ab1zLlqupyG0tEdSP5/Nvb/OZ4ixvTiLqw9oo8oA==",
+      "version": "4.0.15",
+      "resolved": "https://registry.npmjs.org/@vercel/next/-/next-4.0.15.tgz",
+      "integrity": "sha512-BxMxIJrya7MS6IWrQIaQaYHPmq7WoZFLX909RBpNoAG5wgzrTrW756d2EsibBwGo7sQYBv2atyI5GqBIHzYbWg==",
       "requires": {
         "@vercel/nft": "0.24.2"
       }
@@ -8111,20 +8584,20 @@
       }
     },
     "@vercel/node": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/@vercel/node/-/node-3.0.7.tgz",
-      "integrity": "sha512-0KrDGi6z+qPtCyC7wSHmHDU/ot352AJpAeAO1OIEYqYFsYwzvwuyu7TbGGwiUbtolij4/EBUCls3YmwADM/vKw==",
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/@vercel/node/-/node-3.0.12.tgz",
+      "integrity": "sha512-OiNHiUe1LX/CfDrQ07ntPsoYhJiC38mEeErYeqA6YNVAz3QGdX3pthiaIig2KPqeeYkEx5bSkVIqQtQOTJBuLQ==",
       "requires": {
         "@edge-runtime/node-utils": "2.2.1",
-        "@edge-runtime/primitives": "3.1.1",
-        "@edge-runtime/vm": "3.1.1",
+        "@edge-runtime/primitives": "4.0.5",
+        "@edge-runtime/vm": "3.1.7",
         "@types/node": "14.18.33",
-        "@vercel/build-utils": "7.2.2",
-        "@vercel/error-utils": "2.0.1",
+        "@vercel/build-utils": "7.3.0",
+        "@vercel/error-utils": "2.0.2",
         "@vercel/nft": "0.24.2",
         "@vercel/static-config": "3.0.0",
         "async-listen": "3.0.0",
-        "edge-runtime": "2.5.1",
+        "edge-runtime": "2.5.7",
         "esbuild": "0.14.47",
         "etag": "1.8.1",
         "exit-hook": "2.2.1",
@@ -8133,7 +8606,7 @@
         "ts-morph": "12.0.0",
         "ts-node": "10.9.1",
         "typescript": "4.9.5",
-        "undici": "5.23.0"
+        "undici": "5.26.5"
       },
       "dependencies": {
         "@types/node": {
@@ -8167,17 +8640,17 @@
       }
     },
     "@vercel/python": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@vercel/python/-/python-4.0.2.tgz",
-      "integrity": "sha512-mmUeR3GBuDnaJK3IIHRoPl3bNevcWO3N/YrNAx+zxLPSHzfzmCLZbFVVXbzoKBi/cALiOPcApVhlQXwU26y7xg=="
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/@vercel/python/-/python-4.1.0.tgz",
+      "integrity": "sha512-EIQXK5zL6fce0Barh74gc7xyLtRyvgmLZDIVQ8yJLtFxPlPCRY3GXkdJ7Jdcw8Pd0uuVF0vIHatv18xSLbcwtg=="
     },
     "@vercel/redwood": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/@vercel/redwood/-/redwood-2.0.4.tgz",
-      "integrity": "sha512-f0dzR8xQ34MKTzLmUygfu6vngCaRozN0z2Aao1sQ7sIC0+UExgiL0qJ9syejWwDv7IxK4yZ0w1WvztrHtAMa9Q==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@vercel/redwood/-/redwood-2.0.5.tgz",
+      "integrity": "sha512-9iWTxfMkC7yNnwN2xxOdptiIDAgXe1V1fh3aw92MWt5PBRcFY9RqgIPF7Q3Qa7yzQFgpbHwCnSTqWO+HCEuFtw==",
       "requires": {
         "@vercel/nft": "0.24.2",
-        "@vercel/routing-utils": "3.0.0",
+        "@vercel/routing-utils": "3.1.0",
         "semver": "6.3.1"
       },
       "dependencies": {
@@ -8189,9 +8662,9 @@
       }
     },
     "@vercel/remix-builder": {
-      "version": "2.0.9",
-      "resolved": "https://registry.npmjs.org/@vercel/remix-builder/-/remix-builder-2.0.9.tgz",
-      "integrity": "sha512-/wgZrnKGZYJ8Z1tgAQc2UUhF+51tGwSHw9PnAhnaY5KclLiBrnXSjKqUAXW8GyaM4IB1ZjPXoI5oARKKUGu8kQ==",
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/@vercel/remix-builder/-/remix-builder-2.0.14.tgz",
+      "integrity": "sha512-c+ILERSRq404sf6kt0qWhYhuxWkkoTEm2FdLoUnVs21K6kzGtJMJbUExEHoPZvN9a0tq86ZU86jVvRZV6WL0cQ==",
       "requires": {
         "@vercel/nft": "0.24.2",
         "@vercel/static-config": "3.0.0",
@@ -8199,9 +8672,9 @@
       }
     },
     "@vercel/routing-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@vercel/routing-utils/-/routing-utils-3.0.0.tgz",
-      "integrity": "sha512-u+SoHnL+RzRQIRP+YxvigzzKXQcbgYQF9qCTIuWuoLw5h9thIYWcDJvz3KxrUzxjGZ3dWboXA29KAlT6eeaeFw==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@vercel/routing-utils/-/routing-utils-3.1.0.tgz",
+      "integrity": "sha512-Ci5xTjVTJY/JLZXpCXpLehMft97i9fH34nu9PGav6DtwkVUF6TOPX86U0W0niQjMZ5n6/ZP0BwcJK2LOozKaGw==",
       "requires": {
         "ajv": "^6.0.0",
         "path-to-regexp": "6.1.0"
@@ -8233,17 +8706,17 @@
       }
     },
     "@vercel/ruby": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/@vercel/ruby/-/ruby-2.0.2.tgz",
-      "integrity": "sha512-MqFynhtZ905L210DWAbgkiEQEK39LTtp9eL2Nm6PjzhjNzU6hV0UfK8Z24vU9CC6J4mrUTTZx396fH7XTYJWqg=="
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@vercel/ruby/-/ruby-2.0.4.tgz",
+      "integrity": "sha512-EpZyfF6wFGzFDmubFIh/EZtYpKindmXx/69xSfKEBTVU0afgljyOOICbyZePe5tvigfOEBLSLgrt/2nN+MlLtA=="
     },
     "@vercel/static-build": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/@vercel/static-build/-/static-build-2.0.8.tgz",
-      "integrity": "sha512-46//Pxez7mc+UdOZgNv6y9lPSBehMdvCxajb/nvquptDMNH543Itospu9lyt448EQoS7HVE1NSPI21iiCboqvA==",
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/@vercel/static-build/-/static-build-2.0.14.tgz",
+      "integrity": "sha512-l5eQtJbk5Pc+P8XARDnpcbX4LnK3bGy7uf6S1aFOD4h6F8iBdg0agWTufZnq5BI91pcPVICPazM5BYhigIEznQ==",
       "requires": {
         "@vercel/gatsby-plugin-vercel-analytics": "1.0.11",
-        "@vercel/gatsby-plugin-vercel-builder": "2.0.7",
+        "@vercel/gatsby-plugin-vercel-builder": "2.0.12",
         "@vercel/static-config": "3.0.0",
         "ts-morph": "12.0.0"
       }
@@ -8821,6 +9294,11 @@
       "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
       "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="
     },
+    "caniuse-lite": {
+      "version": "1.0.30001643",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz",
+      "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg=="
+    },
     "catharsis": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
@@ -8930,6 +9408,11 @@
         }
       }
     },
+    "client-only": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+      "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
+    },
     "cliui": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -9214,16 +9697,16 @@
       }
     },
     "edge-runtime": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.1.tgz",
-      "integrity": "sha512-E0kY1Dqvwvk9yh7dvR56KnCjXf/dlbrrGjO5Sjnz9Ja3WqYT3csv2B8O4erxJiOWfWy9NTukBk4Kb3yrR66gBw==",
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.7.tgz",
+      "integrity": "sha512-gA4qSVP0sNwJlkdQ2nahDPASlSl8twUd17o+JolPa1EtXpLTGzIpOETvodgJwXIxa+zaD8bnAXCdsWrx2PhlVQ==",
       "requires": {
         "@edge-runtime/format": "2.2.0",
-        "@edge-runtime/vm": "3.1.1",
+        "@edge-runtime/ponyfill": "2.4.1",
+        "@edge-runtime/vm": "3.1.7",
         "async-listen": "3.0.1",
         "mri": "1.2.0",
         "picocolors": "1.0.0",
-        "pretty-bytes": "5.6.0",
         "pretty-ms": "7.0.1",
         "signal-exit": "4.0.2",
         "time-span": "4.0.0"
@@ -10310,11 +10793,22 @@
       "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.2.tgz",
       "integrity": "sha512-IY73F228OXRl9ar3jJagh7Vnuhj/GzBunPiZP13K0lOl7Am9SoWW3kEzq3MCllJMTtZqHTiDXQvoRd4U95aU6A=="
     },
+    "jquery": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
+      "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
+    },
     "js-string-escape": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
       "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg=="
     },
+    "js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "peer": true
+    },
     "js-yaml": {
       "version": "3.14.1",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
@@ -10578,6 +11072,15 @@
       "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
       "optional": true
     },
+    "loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "peer": true,
+      "requires": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      }
+    },
     "lowercase-keys": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
@@ -10836,6 +11339,34 @@
         "uid-safe": "2.1.5"
       }
     },
+    "nanoid": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
+    },
+    "next": {
+      "version": "14.2.5",
+      "resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz",
+      "integrity": "sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==",
+      "requires": {
+        "@next/env": "14.2.5",
+        "@next/swc-darwin-arm64": "14.2.5",
+        "@next/swc-darwin-x64": "14.2.5",
+        "@next/swc-linux-arm64-gnu": "14.2.5",
+        "@next/swc-linux-arm64-musl": "14.2.5",
+        "@next/swc-linux-x64-gnu": "14.2.5",
+        "@next/swc-linux-x64-musl": "14.2.5",
+        "@next/swc-win32-arm64-msvc": "14.2.5",
+        "@next/swc-win32-ia32-msvc": "14.2.5",
+        "@next/swc-win32-x64-msvc": "14.2.5",
+        "@swc/helpers": "0.5.5",
+        "busboy": "1.6.0",
+        "caniuse-lite": "^1.0.30001579",
+        "graceful-fs": "^4.2.11",
+        "postcss": "8.4.31",
+        "styled-jsx": "5.1.1"
+      }
+    },
     "node-domexception": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -11170,6 +11701,16 @@
       "resolved": "https://registry.npmjs.org/pointer-tracker/-/pointer-tracker-2.5.3.tgz",
       "integrity": "sha512-LiJUeIbzk4dXq678YeyrZ++mdY17q4n/2sBHfU9wIuvmSzdiPgMvmvWN2g8mY4J7YwYOIrqrZUWP/MfFHVwYtg=="
     },
+    "postcss": {
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+      "requires": {
+        "nanoid": "^3.3.6",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      }
+    },
     "postcss-value-parser": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@@ -11181,11 +11722,6 @@
       "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
       "optional": true
     },
-    "pretty-bytes": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
-      "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg=="
-    },
     "pretty-ms": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz",
@@ -11361,6 +11897,25 @@
         }
       }
     },
+    "react": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+      "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+      "peer": true,
+      "requires": {
+        "loose-envify": "^1.1.0"
+      }
+    },
+    "react-dom": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+      "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+      "peer": true,
+      "requires": {
+        "loose-envify": "^1.1.0",
+        "scheduler": "^0.23.2"
+      }
+    },
     "readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -11496,6 +12051,15 @@
         "yoga-wasm-web": "^0.3.3"
       }
     },
+    "scheduler": {
+      "version": "0.23.2",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+      "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+      "peer": true,
+      "requires": {
+        "loose-envify": "^1.1.0"
+      }
+    },
     "seek-bzip": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
@@ -11633,6 +12197,11 @@
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
       "optional": true
     },
+    "source-map-js": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg=="
+    },
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -11819,6 +12388,14 @@
       "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
       "optional": true
     },
+    "styled-jsx": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
+      "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
+      "requires": {
+        "client-only": "0.0.1"
+      }
+    },
     "supertap": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz",
@@ -12032,9 +12609,9 @@
       }
     },
     "typescript": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
-      "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w=="
+      "version": "5.5.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
+      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q=="
     },
     "uc.micro": {
       "version": "1.0.6",
@@ -12077,11 +12654,18 @@
       "optional": true
     },
     "undici": {
-      "version": "5.23.0",
-      "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz",
-      "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==",
+      "version": "5.26.5",
+      "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz",
+      "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==",
       "requires": {
-        "busboy": "^1.6.0"
+        "@fastify/busboy": "^2.0.0"
+      },
+      "dependencies": {
+        "@fastify/busboy": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
+          "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="
+        }
       }
     },
     "unicode-trie": {
@@ -12127,21 +12711,21 @@
       "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
     },
     "vercel": {
-      "version": "32.4.1",
-      "resolved": "https://registry.npmjs.org/vercel/-/vercel-32.4.1.tgz",
-      "integrity": "sha512-cULmLvceDaluXz2usPtPYhb9y/jwjWolAjBBbG1DLGQmxVlnHVHTOJrYPaq2ioujQpU0yi92+RQPdzjzOY6aEg==",
+      "version": "32.7.2",
+      "resolved": "https://registry.npmjs.org/vercel/-/vercel-32.7.2.tgz",
+      "integrity": "sha512-esyeo67OZ/f7usKFCrx6NSjsvpo/BP/C8Mfron2uiCb4vXVcjkwOM7TwliHx6b0DbXjpzomdGVUHKRs34VNn2Q==",
       "requires": {
-        "@vercel/build-utils": "7.2.2",
+        "@vercel/build-utils": "7.3.0",
         "@vercel/fun": "1.1.0",
-        "@vercel/go": "3.0.3",
+        "@vercel/go": "3.0.4",
         "@vercel/hydrogen": "1.0.1",
-        "@vercel/next": "4.0.10",
-        "@vercel/node": "3.0.7",
-        "@vercel/python": "4.0.2",
-        "@vercel/redwood": "2.0.4",
-        "@vercel/remix-builder": "2.0.9",
-        "@vercel/ruby": "2.0.2",
-        "@vercel/static-build": "2.0.8",
+        "@vercel/next": "4.0.15",
+        "@vercel/node": "3.0.12",
+        "@vercel/python": "4.1.0",
+        "@vercel/redwood": "2.0.5",
+        "@vercel/remix-builder": "2.0.14",
+        "@vercel/ruby": "2.0.4",
+        "@vercel/static-build": "2.0.14",
         "chokidar": "3.3.1"
       },
       "dependencies": {
@@ -12296,6 +12880,11 @@
       "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
       "optional": true
     },
+    "xmlhttprequest": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+      "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA=="
+    },
     "y18n": {
       "version": "5.0.8",
       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/package.json b/package.json
index f0d13c709f845d57fbce4c49cd20c68071e43ada..4ee9f96bf20f3814a4b0cc0cb07400ba11c299c4 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
     "@polymath-ai/host": "*",
     "@vercel/analytics": "^1.0.2",
     "@vercel/edge": "^1.1.0",
+    "@vercel/functions": "^1.4.0",
     "@vercel/node": "^3.0.7",
     "@vercel/og": "^0.5.17",
     "activitypub-core-types": "^0.3.2",
@@ -14,19 +15,22 @@
     "file-drop-element": "^1.0.1",
     "firebase-admin": "^11.11.0",
     "hugo-bin": "^0.115.0",
+    "jquery": "^3.7.1",
     "multiparty": "^4.2.3",
+    "next": "^14.2.5",
     "node-fetch": "^3.3.2",
     "pinch-zoom-element": "^1.1.1",
     "uuid": "^9.0.1",
-    "vercel": "^32.4.1",
-    "whatwg-flora-tmpl": "^1.0.3"
+    "vercel": "^32.7.2",
+    "whatwg-flora-tmpl": "^1.0.3",
+    "xmlhttprequest": "^1.8.0"
   },
   "engines": {
     "node": ">= 18.0.0"
   },
   "devDependencies": {
     "@types/multiparty": "^0.0.34",
-    "typescript": "^5.2.2"
+    "typescript": "^5.5.4"
   },
   "type": "module"
 }
diff --git a/static/css/W3C-UD.css b/static/css/W3C-UD.css
new file mode 100644
index 0000000000000000000000000000000000000000..6a31f126283dbdd508eb91db2ee77f1276755d20
--- /dev/null
+++ b/static/css/W3C-UD.css
@@ -0,0 +1,14 @@
+
+/* Style for an "Unofficial Draft" */
+
+@import "w3c-base.css";
+
+body {
+  background: url(images/UD) no-repeat fixed,
+              url(images/UD-watermark-light-draft) repeat-y center left fixed,
+              url(images/UD-watermark-light-unofficial) repeat-y center right fixed;
+  background-image: url(images/UD),
+                    var(--draft-watermark),
+                    var(--unofficial-watermark);
+  background-color: var(--bg);
+}
diff --git a/static/css/W3C-WD.css b/static/css/W3C-WD.css
new file mode 100644
index 0000000000000000000000000000000000000000..0087e1a9a00c062c25b8c9913a8c0979b1ddc273
--- /dev/null
+++ b/static/css/W3C-WD.css
@@ -0,0 +1,10 @@
+
+/* Style for a "Working Draft" */
+
+@import "w3c-base.css";
+
+body {
+  background-image: url(/images/WD);
+  background-position-x: left;
+  background-position-y: 100px;
+}
diff --git a/static/css/gitlab-widgets/gitlab-widgets.css b/static/css/gitlab-widgets/gitlab-widgets.css
new file mode 100644
index 0000000000000000000000000000000000000000..d9386e118a7fec1bebae108db9be92535a488f20
--- /dev/null
+++ b/static/css/gitlab-widgets/gitlab-widgets.css
@@ -0,0 +1,153 @@
+/* Gitlab overview widget css */
+
+.project-name {
+  font-size: 36px !important;
+  text-align: center;
+  background-color: #gray;
+}
+
+.project-header {
+  font-size: 32px !important;
+  text-align: center;
+  margin-bottom: 0;
+}
+
+.gitlab-overview #overview {
+  width: 50%;
+  padding-top: 1em;
+  padding-bottom: 1em;
+  margin: auto;
+  display: flex;
+}
+
+.gitlab-overview .label {
+  font-weight: bold;
+}
+
+.borderedWidget {
+  border-color: #333333;
+  border-width: 1px;
+  border-style: solid;
+  border-radius: 25px;
+}
+
+#overview-release-list span {
+  margin: auto;
+}
+
+.gitlab-overview-release-list {
+  width: 80%;
+  display: flex;
+}
+
+.gitlab-overview-release-list a {
+  width: 100%;
+  text-align: center;
+}
+
+
+.gitlab-progress-list {
+  width: 90%;
+  margin: auto;
+}
+
+.gitlab-progress-list .gitlabOverviewEntry {
+  width: auto;
+  margin: 0 0;
+}
+
+.gitlab-progress-list tr td {
+  white-space: nowrap;
+}
+
+.gitlab-progress-list .percentage-column {
+  width: 100%;
+}
+
+.gitlab-progress-list .gitlabOverviewEntry span {
+  width: 15em;
+}
+
+.gitlab-progress-list .gitlabOverviewEntry progress {
+  width: 100%;
+  margin: 0 0;
+}
+
+.gitlab-progress-list .gitlabOverviewEntry td {
+  padding: 1em;
+}
+
+.gitlab-overview-footer {
+  display: flex;
+  justify-content: space-between;
+  margin: auto;
+  width: 90%;
+  padding-top: 1em;
+}
+
+/*
+@media (max-width: 1200px) {
+  .gitlab-overview-footer .footer-element {
+    font-size: 0.8em;
+  }
+
+  .gitlab-overview-footer .footer-element span {
+    display: block;
+  }
+}
+*/
+
+.gitlab-overview-footer .footer-element {
+  display: inline-block;
+  width: 100%;
+  padding-left: 1em;
+  padding-right: 1em;
+}
+
+.gitlab-overview-footer .footer-element span {
+  padding: 0.2em;
+  text-align: center;
+  width: 100%;
+  display: block;
+}
+
+.gitlab-overview-footer #commits {
+  text-align: center;
+}
+
+.gitlab-overview-footer #issues {
+  text-align: center;
+  padding-top: 0;
+  display: flex;
+}
+
+.gitlab-overview-footer #issues span {
+  display: inline;
+}
+
+.gitlab-overview-footer #merge-requests {
+  text-align: center;
+  padding-top: 0;
+  display: flex;
+}
+
+.gitlab-overview-footer #merge-requests span {
+  display: inline;
+}
+
+.gitlab-overview-footer #stars {
+  text-align: center;
+}
+
+.green {
+  color: green;
+}
+
+.red {
+  color: red;
+}
+
+/* Gitlab single version css */
+.gitlab-single-version-overview {
+
+}
diff --git a/static/css/main.css b/static/css/main.css
index a8d5cdae85fd28b1132224d61bf676d177bb7e36..3b95df699291842c81f99efaa9d9740f5d7e9087 100644
--- a/static/css/main.css
+++ b/static/css/main.css
@@ -5,20 +5,20 @@
     --ifm-light-value:15%;
     --ifm-lighter-value:30%;
     --ifm-lightest-value:50%;
-    --ifm-color-primary:#3578e5;
-    --ifm-color-primary-dark:#306cce;
-    --ifm-color-primary-darker:#2d66c3;
-    --ifm-color-primary-darkest:#2554a0;
-    --ifm-color-primary-light:#538ce9;
-    --ifm-color-primary-lighter:#72a1ed;
-    --ifm-color-primary-lightest:#9abcf2;
-    --ifm-color-secondary:#ebedf0;
-    --ifm-color-secondary-dark:#d4d5d8;
-    --ifm-color-secondary-darker:#c8c9cc;
-    --ifm-color-secondary-darkest:#a4a6a8;
-    --ifm-color-secondary-light:#eef0f2;
-    --ifm-color-secondary-lighter:#f1f2f5;
-    --ifm-color-secondary-lightest:#f5f6f8;
+    --ifm-color-primary:#37D4B4;
+    --ifm-color-primary-dark:#29A78D;
+    --ifm-color-primary-darker:#1F8570;
+    --ifm-color-primary-darkest:#1F846F;
+    --ifm-color-primary-light:#37D4B4;
+    --ifm-color-primary-lighter:#37D4B4;
+    --ifm-color-primary-lightest:#37D4B4;
+    --ifm-color-secondary:#D4AF37;
+    --ifm-color-secondary-dark:#8D7421;
+    --ifm-color-secondary-darker:#8D7421;
+    --ifm-color-secondary-darkest:#8D7421;
+    --ifm-color-secondary-light:#D4AF37;
+    --ifm-color-secondary-lighter:#D4AF37;
+    --ifm-color-secondary-lightest:#f5D4AF37f6f8;
     --ifm-color-success:#00a400;
     --ifm-color-success-dark:#009400;
     --ifm-color-success-darker:#008b00;
@@ -973,7 +973,7 @@ section {
 
 .separator {
     background-color: var(--custom-background-color-diff);
-    padding: 50px 0;
+    padding: 35px 0;
 }
 
 /*******************************************************************************
@@ -1082,7 +1082,7 @@ section {
     vertical-align:middle;
     white-space:nowrap
 }
-.button,.button:hover{
+.button,.button:hover,a[href].button,a.button:visited {
     color:#fff;
     color:var(--ifm-button-color);
     outline:0;
@@ -1178,6 +1178,26 @@ section {
     margin-bottom: 0.25em;
 }
 
+/*******************************************************************************
+** Brands Section
+*******************************************************************************/
+
+.brands-box {
+  text-align: center;
+}
+
+.brand-logos {
+  display: inline-block;
+  height: 100%;
+  vertical-align: middle;
+}
+
+.brand-logo {
+  vertical-align: middle;
+  max-height: 50px;
+  padding: 10px;
+}
+
 /*******************************************************************************
 ** Cards Section
 *******************************************************************************/
@@ -2238,6 +2258,67 @@ div#ch-tooltip {
   display: flex;
 }
 
+/* Adding pretty text boxes */
+
+.text-box {
+  text-align: left;
+	color: #3f3f5a;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+  padding-left: 5em;
+}
+
+.text-box > blockquote {
+	font-size: 1.5rem;
+	max-width: 600px;
+	line-height: 1.4;
+	position: relative;
+	padding: .5rem;
+  border-left: none;
+  font-style: normal;
+  margin: auto;
+  text-align: start;
+}
+
+.text-box > blockquote:before,
+.text-box > blockquote:after {
+	position: absolute;
+	color: #ccc;
+	font-size: 8rem;
+	width: 4rem;
+	height: 4rem;
+}
+
+.text-box > blockquote:before {
+	/* content: '“'; */
+	left: -5rem;
+	top: -2rem;
+}
+
+.text-box > blockquote:after {
+	/* content: '”'; */
+	right: 0;
+	bottom: 1rem;
+}
+
+.text-box > cite {
+	line-height: 3;
+	text-align: right;
+  font-size: 2rem;
+  margin: auto;
+}
+
+.text-box > cite:before {
+	content: '- ';
+  font-size: 2rem;
+}
+
+.text-box-highlight {
+  color: var(--ifm-color-secondary);
+}
+
 /* Adding pretty quote boxes */
 
 .quote-box {
@@ -2472,6 +2553,14 @@ li.navbar-menu-item > .button {
   display: none;
 }
 
+  /*****************************************************************************
+  ** Titled-side section
+  *****************************************************************************/
+
+  .titled-side--content img {
+    width: 20em;
+  }
+
 /*******************************************************************************
 ********************************************************************************
 ** Media specific css (max-width)
@@ -2695,8 +2784,12 @@ li.navbar-menu-item > .button {
   }
 }
 
-
-
+  /*****************************************************************************
+  ** W3C formatting
+  *****************************************************************************/
+.w3c_logo {
+  margin-left: 90%;
+}
 
 /*******************************************************************************
 ********************************************************************************
@@ -2877,6 +2970,7 @@ li.navbar-menu-item > .button {
         text-rendering: optimizeLegibility;
     }
   }
+
 }
 
 @media (min-width: 992px) {
diff --git a/static/css/w3c-base.css b/static/css/w3c-base.css
new file mode 100644
index 0000000000000000000000000000000000000000..d4ee6ac66b0835b90d2621097ac3f6e4790f33d6
--- /dev/null
+++ b/static/css/w3c-base.css
@@ -0,0 +1,1589 @@
+/******************************************************************************
+ *                   Style sheet for the W3C specifications                   *
+ *
+ * Special classes handled by this style sheet include:
+ *
+ * Indices
+ *   - .toc for the Table of Contents (<ol class="toc">)
+ *     + <span class="secno"> for the section numbers
+ *   - #toc for the Table of Contents (<nav id="toc">)
+ *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
+ *   - table.index for Index Tables (e.g. for properties or elements)
+ *
+ * Structural Markup
+ *   - table.data for general data tables
+ *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
+ *     -> use <table class='complex data'> for extra-complex tables
+ *     -> use <td class='long'> for paragraph-length cell content
+ *     -> use <td class='pre'> when manual line breaks/indentation would help readability
+ *   - dl.switch for switch statements
+ *   - ol.algorithm for algorithms (helps to visualize nesting)
+ *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
+ *     -> .sidefigure for right-floated figures
+ *   - ins/del
+ *     -> ins/del[cite] for candidate and proposed changes (amendments)
+ *
+ * Code
+ *   - pre and code
+ *
+ * Special Sections
+ *   - .note       for informative notes             (div, p, span, aside, details)
+ *   - .example    for informative examples          (div, p, pre, span)
+ *   - .issue      for issues                        (div, p, span)
+ *   - .advisement for loud normative statements     (div, p, strong)
+ *   - .annoying-warning for spec obsoletion notices (div, aside, details)
+ *   - .correction for "candidate corrections"       (div, aside, details, section)
+ *   - .addition   for "candidate additions"         (div, aside, details, section)
+ *   - .correction.proposed for "proposed corrections" (div, aside, details, section)
+ *   - .addition.proposed   for "proposed additions"   (div, aside, details, section)
+ *
+ * Definition Boxes
+ *   - pre.def   for WebIDL definitions
+ *   - table.def for tables that define other entities (e.g. CSS properties)
+ *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
+ *
+ * Numbering
+ *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
+ *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
+ *   - ::before styled for CSS-generated issue/example/figure numbers:
+ *     -> Documents wishing to use this only need to add
+ *        figcaption::before,
+ *        .caption::before { content: "Figure "  counter(figure) " ";  }
+ *        .example::before { content: "Example " counter(example) " "; }
+ *        .issue::before   { content: "Issue "   counter(issue) " ";   }
+ *
+ * Header Stuff (ignore, just don't conflict with these classes)
+ *   - .head for the header
+ *   - .copyright for the copyright
+ *
+ * Outdated warning for old specs
+ *
+ * Miscellaneous
+ *   - .overlarge for things that should be as wide as possible, even if
+ *     that overflows the body text area. This can be used on an item or
+ *     on its container, depending on the effect desired.
+ *     Note that this styling basically doesn't help at all when printing,
+ *     since A4 paper isn't much wider than the max-width here.
+ *     It's better to design things to fit into a narrower measure if possible.
+ *
+ *   - js-added ToC jump links (see fixup.js)
+ * 
+ *   - .uname and .codepoint for character names and examples
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************/
+/*                                  Colors                                    */
+/******************************************************************************/
+
+/* Any --*-text not paired with a --*-bg is assumed to have a transparent bg */
+:root {
+	--text: black;
+	--bg: white;
+
+	/* Absolute URLs due to https://bugs.webkit.org/show_bug.cgi?id=230243 */
+	--unofficial-watermark: url(/images/UD-watermark-light-unofficial.svg);
+	--draft-watermark: url(/images/UD-watermark-light-draft.svg);
+
+	--logo-bg: #1a5e9a;
+	--logo-active-bg: #c00;
+	--logo-text: white;
+
+	--tocnav-normal-text: #707070;
+	--tocnav-normal-bg: var(--bg);
+	--tocnav-hover-text: var(--tocnav-normal-text);
+	--tocnav-hover-bg: #f8f8f8;
+	--tocnav-active-text: #c00;
+	--tocnav-active-bg: var(--tocnav-normal-bg);
+
+	--tocsidebar-text: var(--text);
+	--tocsidebar-bg: #f7f8f9;
+	--tocsidebar-shadow: rgba(0,0,0,.1);
+	--tocsidebar-heading-text: hsla(203,20%,40%,.7);
+
+	--toclink-text: var(--text);
+	--toclink-underline: #3980b5;
+	--toclink-visited-text: var(--toclink-text);
+	--toclink-visited-underline: #054572;
+
+	--heading-text: #005a9c;
+
+	--hr-text: var(--text);
+
+	--algo-border: #def;
+
+	--del-text: #AA0000;
+	--del-bg: transparent;
+	--ins-text: #006100;
+	--ins-bg: transparent;
+
+	--a-normal-text: #034575;
+	--a-normal-underline: #707070;
+	--a-visited-text: var(--a-normal-text);
+	--a-visited-underline: #bbb;
+	--a-hover-bg: rgba(75%, 75%, 75%, .25);
+	--a-active-text: #c00;
+	--a-active-underline: #c00;
+
+	--blockquote-border: silver;
+	--blockquote-bg: transparent;
+	--blockquote-text: var(--text);
+
+	--issue-border: #e05252;
+	--issue-bg: #fbe9e9;
+	--issue-text: var(--text);
+	--issueheading-text: #831616;
+
+	--example-border: #e0cb52;
+	--example-bg: #fcfaee;
+	--example-text: var(--text);
+	--exampleheading-text: #574b0f;
+
+	--note-border: #52e052;
+	--note-bg: #e9fbe9;
+	--note-text: var(--text);
+	--noteheading-text: hsl(120, 70%, 22%);
+	--notesummary-underline: silver;
+
+	--advisement-border: orange;
+	--advisement-bg: #fec;
+	--advisement-text: var(--text);
+	--advisementheading-text: #b35f00;
+
+	--amendment-border: #330099;
+	--amendment-bg: #F5F0FF;
+	--amendment-text: var(--text);
+	--amendmentheading-text: #220066;
+
+	--warning-border: red;
+	--warning-bg: hsla(40,100%,50%,0.95);
+	--warning-text: var(--text);
+
+	--def-border: #8ccbf2;
+	--def-bg: #def;
+	--def-text: var(--text);
+	--defrow-border: #bbd7e9;
+
+	--datacell-border: silver;
+
+	--indexinfo-text: #707070;
+
+	--indextable-hover-text: black;
+	--indextable-hover-bg: #f7f8f9;
+
+	--outdatedspec-bg: rgba(0, 0, 0, .5);
+	--outdatedspec-text: black;
+	--outdated-bg: maroon;
+	--outdated-text: white;
+	--outdated-shadow: red;
+
+	--editedrec-bg: darkorange;
+}
+
+/******************************************************************************/
+/*                                   Body                                     */
+/******************************************************************************/
+
+	body {
+		counter-reset: example figure issue;
+
+		/* Layout */
+		max-width: 50em;             /* limit line length to 50em for readability   */
+		margin: 0 auto 4em;          /* center text within page, space for footers  */
+		padding: 1.6em 1.5em 0 50px; /* assume 16px font size for downlevel clients */
+		padding: 1.6em 1.5em 0 calc(26px + 1.5em); /* leave space for status flag   */
+
+		/* Typography */
+		line-height: 1.5;
+		font-family: sans-serif;
+		widows: 2;
+		orphans: 2;
+		word-wrap: break-word;
+		overflow-wrap: break-word;
+
+		/* Colors */
+		color: black;
+		color: var(--text);
+		background: white top left fixed no-repeat;
+		background-color: var(--bg);
+		background-size: 25px auto;
+	}
+
+/******************************************************************************/
+/*                         Front Matter & Navigation                          */
+/******************************************************************************/
+
+/** Header ********************************************************************/
+
+	div.head { margin-bottom: 1em; }
+	div.head hr { border-style: solid; }
+
+	div.head h1 {
+		font-weight: bold;
+		margin: 0 0 .1em;
+		font-size: 220%;
+	}
+
+	#w3c-state {
+		margin-top: 0;
+		margin-bottom: 1.5em;
+		font: 140% sans-serif;   /* Reset all font styling to clear out UA styles */
+		font-family: inherit;    /* Inherit the font family. */
+		line-height: 1.2;        /* Keep wrapped headings compact */
+		hyphens: manual;         /* Hyphenated headings look weird */
+		color: #005a9c;
+		color: var(--heading-text);
+	}
+
+/** W3C Logo ******************************************************************/
+
+	.head p:not(.copyright):first-child {
+		margin: 0;
+	}
+
+	.head p:not(.copyright):first-child > a,
+	.head > a:first-child {
+		float: right;
+		margin: 0.4rem 0 0.2rem .4rem;
+	}
+
+	.head img[src*="logos/W3C"] {
+		display: block;
+		border: solid #1a5e9a;
+		border: solid var(--logo-bg);
+		border-width: .65rem .7rem .6rem;
+		border-radius: .4rem;
+		background: #1a5e9a;
+		background: var(--logo-bg);
+		color: white;
+		color: var(--logo-text);
+		font-weight: bold;
+	}
+
+	.head a:hover > img[src*="logos/W3C"],
+	.head a:focus > img[src*="logos/W3C"] {
+		opacity: .8;
+	}
+
+	.head a:active > img[src*="logos/W3C"] {
+		background: #c00;
+		background: var(--logo-active-bg);
+		border-color: #c00;
+		border-color: var(--logo-active-bg);
+	}
+
+	/* see also additional rules in Link Styling section */
+
+/** Copyright *****************************************************************/
+
+	p.copyright,
+	p.copyright small { font-size: small; }
+
+/** Back to Top / ToC Toggle **************************************************/
+
+	@media print {
+		#toc-nav {
+			display: none;
+		}
+	}
+	@media not print {
+		#toc-nav {
+			position: fixed;
+			z-index: 3;
+			bottom: 0; left: 0;
+			margin: 0;
+			min-width: 1.33em;
+			border-top-right-radius: 2rem;
+			box-shadow: 0 0 2px;
+			font-size: 1.5em;
+		}
+		#toc-nav > a {
+			display: block;
+			white-space: nowrap;
+
+			height: 1.33em;
+			padding: .1em 0.3em;
+			margin: 0;
+
+			box-shadow: 0 0 2px;
+			border: none;
+			border-top-right-radius: 1.33em;
+
+			color: #707070;
+			color: var(--tocnav-normal-text);
+			background: white;
+			background: var(--tocnav-normal-bg);
+		}
+		#toc-nav > a:hover,
+		#toc-nav > a:focus {
+			color: black;
+			color: var(--tocnav-hover-text);
+			background: #f8f8f8;
+			background: var(--tocnav-hover-bg);
+		}
+		#toc-nav > a:active {
+			color: #c00;
+			color: var(--tocnav-active-text);
+			background: white;
+			background: var(--tocnav-active-bg);
+		}
+
+		#toc-nav > #toc-jump,
+		#toc-nav > #toc-toggle {
+			padding-bottom: 2em;
+			margin-bottom: -1.9em;
+		}
+
+		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
+		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
+			padding-bottom: 1.5rem;
+		}
+
+		#toc-nav:not(:hover) > a:not(:focus) > span + span {
+			/* Ideally this uses :focus-within on #toc-nav */
+			display: none;
+		}
+		#toc-nav > a > span + span {
+			padding-right: 0.2em;
+		}
+	}
+
+/** ToC Sidebar ***************************************************************/
+
+	/* Floating sidebar */
+	@media screen {
+		body.toc-sidebar #toc {
+			position: fixed;
+			top: 0; bottom: 0;
+			left: 0;
+			width: 23.5em;
+			max-width: 80%;
+			max-width: calc(100% - 2em - 26px);
+			overflow: auto;
+			padding: 0 1em;
+			padding-left: 42px;
+			padding-left: calc(1em + 26px);
+			color: black;
+			color: var(--tocsidebar-text);
+			background: inherit;
+			background-color: #f7f8f9;
+			background-color: var(--tocsidebar-bg);
+			z-index: 1;
+			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
+			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
+		}
+		body.toc-sidebar #toc h2 {
+			margin-top: .8rem;
+			font-variant: small-caps;
+			font-variant: all-small-caps;
+			text-transform: lowercase;
+			font-weight: bold;
+			color: gray;
+			color: hsla(203,20%,40%,.7);
+			color: var(--tocsidebar-heading-text);
+		}
+		body.toc-sidebar #toc-jump:not(:focus) {
+			width: 0;
+			height: 0;
+			padding: 0;
+			position: absolute;
+			overflow: hidden;
+		}
+	}
+	/* Hide main scroller when only the ToC is visible anyway */
+	@media screen and (max-width: 28em) {
+		body.toc-sidebar {
+			overflow: hidden;
+		}
+	}
+
+	/* Sidebar with its own space */
+	@media screen and (min-width: 78em) {
+		body:not(.toc-inline) #toc {
+			position: fixed;
+			top: 0; bottom: 0;
+			left: 0;
+			width: 23.5em;
+			overflow: auto;
+			padding: 0 1em;
+			padding-left: 42px;
+			padding-left: calc(1em + 26px);
+			color: black;
+			color: var(--tocsidebar-text);
+			background: inherit;
+			background-color: #f7f8f9;
+			background-color: var(--tocsidebar-bg);
+			z-index: 1;
+			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
+			box-shadow: -.1em 0 .25em var(--tocsidebar-shadow) inset;
+		}
+		body:not(.toc-inline) #toc h2 {
+			margin-top: .8rem;
+			font-variant: small-caps;
+			font-variant: all-small-caps;
+			text-transform: lowercase;
+			font-weight: bold;
+			color: gray;
+			color: hsla(203,20%,40%,.7);
+			color: var(--tocsidebar-heading-text);
+		}
+
+		body:not(.toc-inline) {
+			padding-left: 29em;
+		}
+		/* See also Overflow section at the bottom */
+
+		body:not(.toc-inline) #toc-jump:not(:focus) {
+			width: 0;
+			height: 0;
+			padding: 0;
+			position: absolute;
+			overflow: hidden;
+		}
+	}
+	@media screen and (min-width: 90em) {
+		body:not(.toc-inline) {
+			margin: 0 4em;
+		}
+	}
+
+/******************************************************************************/
+/*                                Sectioning                                  */
+/******************************************************************************/
+
+/** Headings ******************************************************************/
+
+	h1, h2, h3, h4, h5, h6, dt {
+		page-break-after: avoid;
+		page-break-inside: avoid;
+		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
+		font-family: inherit;    /* Inherit the font family. */
+		line-height: 1.2;        /* Keep wrapped headings compact */
+		hyphens: manual;         /* Hyphenated headings look weird */
+	}
+
+	h2, h3, h4, h5, h6 {
+		margin-top: 3rem;
+	}
+
+	h1, h2, h3 {
+		color: #005a9c;
+		color: var(--heading-text);
+	}
+
+	h1 { font-size: 170%; }
+	h2 { font-size: 140%; }
+	h3 { font-size: 120%; }
+	h4 { font-weight: bold; }
+	h5 { font-style: italic; }
+	h6 { font-variant: small-caps; }
+	dt { font-weight: bold; }
+
+/** Subheadings ***************************************************************/
+
+	h1 + h2,
+	#subtitle {
+		/* #subtitle is a subtitle in an H2 under the H1 */
+		margin-top: 0;
+	}
+	h2 + h3,
+	h3 + h4,
+	h4 + h5,
+	h5 + h6 {
+		margin-top: 1.2em; /* = 1 x line-height */
+	}
+
+/** Section divider ***********************************************************/
+
+	:not(.head) > :not(.head) + hr {
+		font-size: 1.5em;
+		text-align: center;
+		margin: 1em auto;
+		height: auto;
+		color: black;
+		color: var(--hr-text);
+		border: transparent solid 0;
+		background: transparent;
+	}
+	:not(.head) > hr::before {
+		content: "\2727\2003\2003\2727\2003\2003\2727";
+	}
+
+/******************************************************************************/
+/*                            Paragraphs and Lists                            */
+/******************************************************************************/
+
+	p {
+		margin: 1em 0;
+	}
+
+	dd > p:first-child,
+	li > p:first-child {
+		margin-top: 0;
+	}
+
+	ul, ol {
+		margin-left: 0;
+		padding-left: 2em;
+	}
+
+	li {
+		margin: 0.25em 0 0.5em;
+		padding: 0;
+	}
+
+	dl dd {
+		margin: 0 0 .5em 2em;
+	}
+
+	.head dd + dd { /* compact for header */
+		margin-top: -.5em;
+	}
+
+	/* Style for algorithms */
+	ol.algorithm ol:not(.algorithm),
+	.algorithm > ol ol:not(.algorithm) {
+	 border-left: 0.5em solid #def;
+	 border-left: 0.5em solid var(--algo-border);
+	}
+
+	/* Style for switch/case <dl>s */
+	dl.switch > dd > ol.only {
+	 margin-left: 0;
+	}
+	dl.switch > dd > ol.algorithm {
+	 margin-left: -2em;
+	}
+	dl.switch {
+	 padding-left: 2em;
+	}
+	dl.switch > dt {
+	 margin-top: 1em;
+	}
+	dl.switch > dt + dt {
+	 margin-top: 0;
+	}
+
+	/* For older browsers */
+	dl.switch > dt::before {
+	 content: '\21AA';
+	 padding: 0 0.5em 0 0;
+	 display: inline-block;
+	 width: 1em;
+	 text-align: right;
+	 line-height: 0.5em;
+	}
+	dl.switch > dt {
+	 text-indent: -1.5em;
+	}
+	:where(dl.switch > dt > *) {
+		text-indent: 0; /* break inheritance on e.g. list children */
+	}
+	/* Undo above styling and use list-style for proper bullets */
+	@supports (list-style: "\21AA  ") {
+		dl.switch > dt {
+			display: list-item;
+			list-style: "\21AA  ";
+			margin-left: -1.5em;
+			text-indent: 0;
+		}
+		dl.switch > dt::before {
+			content: none;
+		}
+		dl {
+			/* don't accidentally increment the implied list-item counter */
+			counter-reset: list-item;
+		}
+	}
+
+
+/** Terminology Markup ********************************************************/
+
+
+/******************************************************************************/
+/*                                 Inline Markup                              */
+/******************************************************************************/
+
+/** Terminology Markup ********************************************************/
+	dfn   { /* Defining instance */
+		font-weight: bolder;
+	}
+	a > i { /* Instance of term */
+		font-style: normal;
+	}
+	dt dfn code, code.idl {
+		font-size: inherit;
+	}
+	dfn var {
+		font-style: normal;
+	}
+
+/** Change Marking ************************************************************/
+
+	del {
+		color: #AA0000;
+		color: var(--del-text);
+		background: transparent;
+		background: var(--del-bg);
+		text-decoration: line-through;
+	}
+	ins {
+		color: #006100;
+		color: var(--ins-text);
+		background: transparent;
+		background: var(--ins-bg);
+		text-decoration: underline;
+		text-decoration-style: dashed;
+	}
+	ins:not(#dontusethisid) *,
+	del:not(#dontusethisid) * {
+		color: inherit;
+	}
+	ins:not([hidden]).diff-inactive,
+	del:not([hidden]).diff-inactive {
+		all: unset;
+	}
+	ins:not(.diff-inactive) *,
+	del:not(.diff-inactive) * {
+		color: inherit;
+	}
+
+	/* for amendments (candidate/proposed changes) */
+	.amendment ins, .correction ins, .addition ins,
+	ins[cite] { text-decoration-style: dotted; }
+	.amendment del, .correction del, .addition del,
+	del[cite] { text-decoration-style: dotted; }
+	.amendment.proposed ins, .correction.proposed ins, .addition.proposed ins,
+	ins[cite].proposed { text-decoration-style: double; }
+	.amendment.proposed del, .correction.proposed del, .addition.proposed del,
+	del[cite].proposed { text-decoration-style: double; }
+
+/** Miscellaneous improvements to inline formatting ***************************/
+
+	sup {
+		vertical-align: super;
+		font-size: 80%;
+	}
+
+/******************************************************************************/
+/*                                    Code                                    */
+/******************************************************************************/
+
+/** General monospace/pre rules ***********************************************/
+
+	pre, code, samp {
+		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
+		font-size: .9em;
+		hyphens: none;
+		text-transform: none;
+		text-align: left;
+		text-align: start;
+		font-variant: normal;
+		orphans: 3;
+		widows: 3;
+		page-break-before: avoid;
+	}
+	pre code,
+	code code {
+		font-size: 100%;
+	}
+
+	pre {
+		margin-top: 1em;
+		margin-bottom: 1em;
+		overflow: auto;
+	}
+
+/** Inline Code fragments *****************************************************/
+
+  /* Do something nice. */
+
+/******************************************************************************/
+/*                                    Links                                   */
+/******************************************************************************/
+
+/** General Hyperlinks ********************************************************/
+
+	/* We hyperlink a lot, so make it less intrusive */
+	a[href] {
+		color: #034575;
+		color: var(--a-normal-text);
+		text-decoration-color: #707070;
+		text-decoration-color: var(--a-normal-underline);
+		text-decoration-skip-ink: none;
+	}
+	a:visited {
+		color: #034575;
+		color: var(--a-visited-text);
+		text-decoration-color: #bbb;
+		text-decoration-color: var(--a-visited-underline);
+	}
+
+	/* Indicate interaction with the link */
+	a[href]:focus,
+	a[href]:hover {
+		text-decoration-thickness: 2px;
+		text-decoration-skip-ink: none;
+	}
+	a[href]:active {
+		color: #c00;
+		color: var(--a-active-text);
+		text-decoration-color: #c00;
+		text-decoration-color: var(--a-active-underline);
+	}
+
+	/* Backout above styling for W3C logo */
+	.head p:not(.copyright):first-child > a,
+	.head > a:first-child {
+		border: none;
+		text-decoration: none;
+		background: transparent;
+	}
+
+/******************************************************************************/
+/*                                    Images                                  */
+/******************************************************************************/
+
+	img {
+		border-style: none;
+	}
+
+	/* For autogen numbers, add
+	   .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
+	*/
+
+	figure, .figure, .sidefigure {
+		page-break-inside: avoid;
+		text-align: center;
+		margin: 2.5em 0;
+	}
+	.figure img,    .sidefigure img,    figure img,
+	.figure object, .sidefigure object, figure object,
+        .figure svg,    .sidefigure svg,    figure svg {
+		max-width: 100%;
+		margin: auto;
+		height: auto;
+	}
+	.figure pre, .sidefigure pre, figure pre {
+		text-align: left;
+		display: table;
+		margin: 1em auto;
+	}
+	.figure table, figure table {
+		margin: auto;
+	}
+	@media screen and (min-width: 20em) {
+		.sidefigure {
+			float: right;
+			width: 50%;
+			margin: 0 0 0.5em 0.5em;
+		}
+	}
+	.caption, figcaption, caption {
+		font-style: italic;
+		font-size: 90%;
+	}
+	.caption::before, figcaption::before, figcaption > .marker {
+		font-weight: bold;
+	}
+	.caption, figcaption {
+		counter-increment: figure;
+	}
+
+	/* DL list is indented 2em, but figure inside it is not */
+	dd > .figure, dd > figure { margin-left: -2em; }
+
+/******************************************************************************/
+/*                             Colored Boxes                                  */
+/******************************************************************************/
+
+	.issue, .note, .example, .advisement, blockquote,
+	.amendment, .correction, .addition {
+		padding: .5em;
+		border: .5em;
+		border-left-style: solid;
+		page-break-inside: avoid;
+		margin: 1em auto;
+	}
+	span.issue, span.note {
+		padding: .1em .5em .15em;
+		border-right-style: solid;
+	}
+
+	.note  > p:first-child,
+	.issue > p:first-child,
+	blockquote > :first-child,
+	.amendment > p:first-child,
+	.correction > p:first-child,
+	.addition > p:first-child {
+		margin-top: 0;
+	}
+	.note  > p:last-child,
+	.issue > p:last-child,
+	blockquote > :last-child,
+	.amendment > p:last-child,
+	.correction > p:last-child,
+	.addition > p:last-child {
+		margin-bottom: 0;
+	}
+
+	.issue::before, .issue > .marker,
+	.example::before, .example > .marker,
+	.note::before, .note > .marker,
+	details.note > summary > .marker,
+	.amendment::before, .amendment > .marker,
+	details.amendment > summary > .marker,
+	.correction::before, .correction > .marker,
+	details.correction > summary > .marker,
+	.addition::before, .addition > .marker,
+	details.addition > summary > .marker {
+		text-transform: uppercase;
+		padding-right: 1em;
+	}
+
+	.example::before, .example > .marker {
+		display: block;
+		padding-right: 0em;
+	}
+
+/** Blockquotes ***************************************************************/
+
+	blockquote {
+		border-color: silver;
+		border-color: var(--blockquote-border);
+		background: var(--blockquote-bg);
+		color: var(--blockquote-text);
+	}
+
+/** Open issue ****************************************************************/
+
+	.issue {
+		border-color: #e05252;
+		border-color: var(--issue-border);
+		background: #fbe9e9;
+		background: var(--issue-bg);
+		color: black;
+		color: var(--issue-text);
+		counter-increment: issue;
+		overflow: auto;
+	}
+	.issue::before, .issue > .marker {
+		color: #831616;
+		color: var(--issueheading-text);
+	}
+	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
+	   or use class="marker" to mark up the issue number in source. */
+
+/** Example *******************************************************************/
+
+	.example {
+		border-color: #e0cb52;
+		border-color: var(--example-border);
+		background: #fcfaee;
+		background: var(--example-bg);
+		color: black;
+		color: var(--example-text);
+		counter-increment: example;
+		overflow: auto;
+		clear: both;
+	}
+	.example::before, .example > .marker {
+		color: #574b0f;
+		color: var(--exampleheading-text);
+	}
+	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
+	   or use class="marker" to mark up the example number in source. */
+
+/** Non-normative Note ********************************************************/
+
+	.note {
+		border-color: #52e052;
+		border-color: var(--note-border);
+		background: #e9fbe9;
+		background: var(--note-bg);
+		color: black;
+		color: var(--note-text);
+		overflow: auto;
+	}
+
+	.note::before, .note > .marker,
+	details.note > summary {
+		color: hsl(120, 70%, 22%);
+		color: var(--noteheading-text);
+	}
+	/* Add .note::before { content: "Note "; } for autogen label,
+	   or use class="marker" to mark up the label in source. */
+
+	details.note[open] > summary {
+		border-bottom: 1px silver solid;
+		border-bottom: 1px var(--notesummary-underline) solid;
+	}
+
+/** Advisement Box ************************************************************/
+	/*  for attention-grabbing normative statements */
+
+	.advisement {
+		border-color: orange;
+		border-color: var(--advisement-border);
+		border-style: none solid;
+		background: #fec;
+		background: var(--advisement-bg);
+		color: black;
+		color: var(--advisement-text);
+	}
+	strong.advisement {
+		display: block;
+		text-align: center;
+	}
+	.advisement::before, .advisement > .marker {
+		color: #b35f00;
+		color: var(--advisementheading-text);
+	}
+
+/** Amendment Box *************************************************************/
+
+	.amendment, .correction, .addition {
+		border-color: #330099;
+		border-color: var(--amendment-border);
+		background: #F5F0FF;
+		background: var(--amendment-bg);
+	}
+	.amendment.proposed, .correction.proposed, .addition.proposed {
+		border-style: solid;
+		border-block-width: 0.25em;
+	}
+	.amendment::before, .amendment > .marker,
+	details.amendment > summary::before, details.amendment > summary > .marker,
+	.correction::before, .correction > .marker,
+	details.correction > summary::before, details.correction > summary > .marker,
+	.addition::before, .addition > .marker,
+	details.addition > summary::before, details.addition > summary > .marker {
+		color: #220066;
+		color: var(--amendmentheading-text);
+	}
+	.amendment.proposed::before, .amendment.proposed > .marker,
+	details.amendment.proposed > summary::before, details.amendment.proposed > summary > .marker,
+	.correction.proposed::before, .correction.proposed > .marker,
+	details.correction.proposed > summary::before, details.correction.proposed > summary > .marker,
+	.addition.proposed::before, .addition.proposed > .marker,
+	details.addition.proposed > summary::before, details.addition.proposed > summary > .marker {
+		font-weight: bold;
+	}
+
+/** Spec Obsoletion Notice ****************************************************/
+	/* obnoxious obsoletion notice for older/abandoned specs. */
+
+	details:not([hidden]) {
+		display: block;
+	}
+	summary {
+		font-weight: bolder;
+	}
+
+	.annoying-warning:not(details),
+	details.annoying-warning:not([open]) > summary,
+	details.annoying-warning[open] {
+		background: hsla(40,100%,50%,0.95);
+		background: var(--warning-bg);
+		color: black;
+		color: var(--warning-text);
+		padding: .75em 1em;
+		border: red;
+		border: var(--warning-border);
+		border-style: solid none;
+		box-shadow: 0 2px 8px black;
+		text-align: center;
+	}
+	.annoying-warning :last-child {
+		margin-bottom: 0;
+	}
+
+@media not print {
+	details.annoying-warning[open] {
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 2em;
+		z-index: 1000;
+	}
+}
+
+	details.annoying-warning:not([open]) > summary {
+		text-align: center;
+	}
+
+/** Entity Definition Boxes ***************************************************/
+
+	.def {
+		padding: .5em 1em;
+		background: #def;
+		background: var(--def-bg);
+		margin: 1.2em 0;
+		border-left: 0.5em solid #8ccbf2;
+		border-left: 0.5em solid var(--def-border);
+		color: black;
+		color: var(--def-text);
+	}
+
+/******************************************************************************/
+/*                                    Tables                                  */
+/******************************************************************************/
+
+	th, td {
+		text-align: left;
+		text-align: start;
+	}
+
+/** Property/Descriptor Definition Tables *************************************/
+
+	table.def {
+		/* inherits .def box styling, see above */
+		width: 100%;
+		border-spacing: 0;
+	}
+
+	table.def td,
+	table.def th {
+		padding: 0.5em;
+		vertical-align: baseline;
+		border-bottom: 1px solid #bbd7e9;
+		border-bottom: 1px solid var(--defrow-border);
+	}
+
+	table.def > tbody > tr:last-child th,
+	table.def > tbody > tr:last-child td {
+		border-bottom: 0;
+	}
+
+	table.def th {
+		font-style: italic;
+		font-weight: normal;
+		padding-left: 1em;
+		width: 3em;
+	}
+
+	/* For when values are extra-complex and need formatting for readability */
+	table td.pre {
+		white-space: pre-wrap;
+	}
+
+	/* A footnote at the bottom of a def table */
+	table.def td.footnote {
+		padding-top: 0.6em;
+	}
+	table.def td.footnote::before {
+		content: " ";
+		display: block;
+		height: 0.6em;
+		width: 4em;
+		border-top: thin solid;
+	}
+
+/** Data tables (and properly marked-up index tables) *************************/
+	/*
+		 <table class="data"> highlights structural relationships in a table
+		 when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)
+
+		 Use class="complex data" for particularly complicated tables --
+		 (This will draw more lines: busier, but clearer.)
+
+		 Use class="long" on table cells with paragraph-like contents
+		 (This will adjust text alignment accordingly.)
+		 Alternately use class="longlastcol" on tables, to have the last column assume "long".
+	*/
+
+	table {
+		word-wrap: normal;
+		overflow-wrap: normal;
+		hyphens: manual;
+	}
+
+	table.data,
+	table.index {
+		margin: 1em auto;
+		border-collapse: collapse;
+		border: hidden;
+		width: 100%;
+	}
+	table.data caption,
+	table.index caption {
+		max-width: 50em;
+		margin: 0 auto 1em;
+	}
+
+	table.data td,  table.data th,
+	table.index td, table.index th {
+		padding: 0.5em 1em;
+		border-width: 1px;
+		border-color: silver;
+		border-color: var(--datacell-border);
+		border-top-style: solid;
+	}
+
+	table.data thead td:empty {
+		padding: 0;
+		border: 0;
+	}
+
+	table.data  thead,
+	table.index thead,
+	table.data  tbody,
+	table.index tbody {
+		border-bottom: 2px solid;
+	}
+
+	table.data colgroup,
+	table.index colgroup {
+		border-left: 2px solid;
+	}
+
+	table.data  tbody th:first-child,
+	table.index tbody th:first-child  {
+		border-right: 2px solid;
+		border-top: 1px solid silver;
+		border-top: 1px solid var(--datacell-border);
+		padding-right: 1em;
+	}
+
+	table.data th[colspan],
+	table.data td[colspan] {
+		text-align: center;
+	}
+
+	table.complex.data th,
+	table.complex.data td {
+		border: 1px solid silver;
+		border: 1px solid var(--datacell-border);
+		text-align: center;
+	}
+
+	table.data.longlastcol td:last-child,
+	table.data td.long {
+	 vertical-align: baseline;
+	 text-align: left;
+	}
+
+	table.data img {
+		vertical-align: middle;
+	}
+
+
+/*
+Alternate table alignment rules
+
+	table.data,
+	table.index {
+		text-align: center;
+	}
+
+	table.data  thead th[scope="row"],
+	table.index thead th[scope="row"] {
+		text-align: right;
+	}
+
+	table.data  tbody th:first-child,
+	table.index tbody th:first-child  {
+		text-align: right;
+	}
+
+Possible extra rowspan handling
+
+	table.data  tbody th[rowspan]:not([rowspan='1']),
+	table.index tbody th[rowspan]:not([rowspan='1']),
+	table.data  tbody td[rowspan]:not([rowspan='1']),
+	table.index tbody td[rowspan]:not([rowspan='1']) {
+		border-left: 1px solid silver;
+	}
+
+	table.data  tbody th[rowspan]:first-child,
+	table.index tbody th[rowspan]:first-child,
+	table.data  tbody td[rowspan]:first-child,
+	table.index tbody td[rowspan]:first-child{
+		border-left: 0;
+		border-right: 1px solid silver;
+	}
+*/
+
+/******************************************************************************/
+/*                                  Indices                                   */
+/******************************************************************************/
+
+
+/** Table of Contents *********************************************************/
+
+	.toc a {
+		color: black;
+		color: var(--toclink-text);
+		/* More spacing; use padding to make it part of the click target. */
+		padding: 0.1rem 1px 0;
+		/* Larger, more consistently-sized click target */
+		display: block;
+		/* Switch to using border-bottom */
+		text-decoration: none;
+		border-bottom: 3px solid transparent;
+		margin-bottom: -2px;
+	}
+	.toc a:visited {
+		color: black;
+		color: var(--toclink-visited-text);
+	}
+	.toc a:focus,
+	.toc a:hover {
+		background: #f8f8f8;
+		background: rgba(75%, 75%, 75%, .25);
+		background: var(--a-hover-bg);
+		border-bottom-color: #3980b5;
+		border-bottom-color: var(--toclink-underline);
+	}
+	.toc a:visited:focus,
+	.toc a:visited:hover {
+		border-bottom-color: #054572;
+		border-bottom-color: var(--toclink-visited-underline);
+	}
+
+	.toc, .toc ol, .toc ul, .toc li {
+		list-style: none; /* Numbers must be inlined into source */
+		/* because generated content isn't search/selectable and markers can't do multilevel yet */
+		margin:  0;
+		padding: 0;
+	}
+	.toc {
+		line-height: 1.1em; /* consistent spacing */
+	}
+
+	/* ToC not indented until third level, but font style & margins show hierarchy */
+	.toc > li             { font-weight: bold;   }
+	.toc > li li          { font-weight: normal; }
+	.toc > li li li       { font-size:   95%;    }
+	.toc > li li li li    { font-size:   90%;    }
+	.toc > li li li li li { font-size:   85%;    }
+
+	.toc > li             { margin: 1.5rem 0;    }
+	.toc > li li          { margin: 0.3rem 0;    }
+	.toc > li li li       { margin-left: 2rem;   }
+
+	/* Section numbers in a column of their own */
+	.toc .secno {
+		float: left;
+		width: 4rem;
+		white-space: nowrap;
+	}
+	.toc > li li li li .secno {
+		font-size: 85%;
+	}
+	.toc > li li li li li .secno {
+		font-size: 100%;
+	}
+
+	:not(li) > .toc              { margin-left:  5rem; }
+	.toc .secno                  { margin-left: -5rem; }
+	.toc > li li li .secno       { margin-left: -7rem; }
+	.toc > li li li li .secno    { margin-left: -9rem; }
+	.toc > li li li li li .secno { margin-left: -11rem; }
+
+	/* Tighten up indentation in narrow ToCs */
+	@media (max-width: 30em) {
+		:not(li) > .toc              { margin-left:  4rem; }
+		.toc .secno                  { margin-left: -4rem; }
+		.toc > li li li              { margin-left:  1rem; }
+		.toc > li li li .secno       { margin-left: -5rem; }
+		.toc > li li li li .secno    { margin-left: -6rem; }
+		.toc > li li li li li .secno { margin-left: -7rem; }
+	}
+	@media screen and (min-width: 78em) {
+		body:not(.toc-inline) :not(li) > .toc              { margin-left:  4rem; }
+		body:not(.toc-inline) .toc .secno                  { margin-left: -4rem; }
+		body:not(.toc-inline) .toc > li li li              { margin-left:  1rem; }
+		body:not(.toc-inline) .toc > li li li .secno       { margin-left: -5rem; }
+		body:not(.toc-inline) .toc > li li li li .secno    { margin-left: -6rem; }
+		body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
+	}
+	body.toc-sidebar #toc :not(li) > .toc              { margin-left:  4rem; }
+	body.toc-sidebar #toc .toc .secno                  { margin-left: -4rem; }
+	body.toc-sidebar #toc .toc > li li li              { margin-left:  1rem; }
+	body.toc-sidebar #toc .toc > li li li .secno       { margin-left: -5rem; }
+	body.toc-sidebar #toc .toc > li li li li .secno    { margin-left: -6rem; }
+	body.toc-sidebar #toc .toc > li li li li li .secno { margin-left: -7rem; }
+
+	.toc li {
+		clear: both;
+	}
+
+
+/** Index *********************************************************************/
+
+	/* Index Lists: Layout */
+	ul.index       { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
+	ul.index li    { margin-left: 0; list-style: none; break-inside: avoid; }
+	ul.index li li { margin-left: 1em; }
+	ul.index dl    { margin-top: 0; }
+	ul.index dt    { margin: .2em 0 .2em 20px;}
+	ul.index dd    { margin: .2em 0 .2em 40px;}
+	/* Index Lists: Typography */
+	ul.index ul,
+	ul.index dl { font-size: smaller; }
+	@media not print {
+		ul.index li a + span {
+			white-space: nowrap;
+			color: transparent;
+		}
+		ul.index li a:hover + span,
+		ul.index li a:focus + span {
+			color: #707070;
+			color: var(--indexinfo-text);
+		}
+	}
+
+/** Index Tables *****************************************************/
+	/* See also the data table styling section, which this effectively subclasses */
+
+	table.index {
+		font-size: small;
+		border-collapse: collapse;
+		border-spacing: 0;
+		text-align: left;
+		margin: 1em 0;
+	}
+
+	table.index td,
+	table.index th {
+		padding: 0.4em;
+	}
+
+	table.index tr:hover td:not([rowspan]),
+	table.index tr:hover th:not([rowspan]) {
+		color: black;
+		color: var(--indextable-hover-text);
+		background: #f7f8f9;
+		background: var(--indextable-hover-bg);
+	}
+
+	/* The link in the first column in the property table (formerly a TD) */
+	table.index th:first-child a {
+		font-weight: bold;
+	}
+
+/** Unicode characters and character sequences *******************************/
+
+	.codepoint bdi {
+		line-height: 1em;
+		font-size: 1.25em;
+		padding-inline: 0.25em;
+	}
+	
+	.codepoint img {
+		height: 2em;
+		margin-inline: 0.25em;
+		vertical-align: bottom;
+	}
+
+	.uname {
+		font-family: Arial, monospace;
+		font-size: 0.75em;                    
+		letter-spacing: 0.03em;
+		color: brown;
+	}
+
+/** Outdated warning **********************************************************/
+
+.outdated-spec {
+	color: black;
+	color: var(--outdatedspec-text);
+	background-color: rgba(0,0,0,0.5);
+	background-color: var(--outdatedspec-bg);
+}
+
+.outdated-warning {
+	position: fixed;
+	bottom: 50%;
+	left: 0;
+	right: 0;
+	margin: 0 auto;
+	width: 50%;
+	background: maroon;
+	background: var(--outdated-bg);
+	color: white;
+	color: var(--outdated-text);
+	border-radius: 1em;
+	box-shadow: 0 0 1em red;
+	box-shadow: 0 0 1em var(--outdated-shadow);
+	padding: 2em;
+	text-align: center;
+	z-index: 2;
+}
+
+.outdated-warning a {
+	color: currentcolor;
+	background: transparent;
+}
+
+.edited-rec-warning {
+	background: darkorange;
+	background: var(--editedrec-bg);
+	box-shadow: 0 0 1em;
+}
+
+.outdated-warning button {
+	position: absolute;
+	top: 0;
+	right:0;
+	margin: 0;
+	border: 0;
+	padding: 0.25em 0.5em;
+	background: transparent;
+	color: white;
+	color: var(--outdated-text);
+	font:1em sans-serif;
+	text-align:center;
+}
+
+.outdated-warning span {
+	display: block;
+}
+
+.outdated-collapsed {
+	bottom: 0;
+	border-radius: 0;
+	width: 100%;
+	padding: 0;
+}
+
+/******************************************************************************/
+/*                                    Print                                   */
+/******************************************************************************/
+
+	@media print {
+		/* Pages have their own margins. */
+		html {
+			margin: 0;
+		}
+		/* Serif for print. */
+		body {
+			font-family: serif;
+		}
+
+		.outdated-warning {
+			position: absolute;
+			border-style: solid;
+			border-color: red;
+		}
+
+		.outdated-warning input {
+			display: none;
+		}
+	}
+	@page {
+		margin: 1.5cm 1.1cm;
+	}
+
+/******************************************************************************/
+/*                                    Legacy                                  */
+/******************************************************************************/
+
+	/* This rule is inherited from past style sheets. No idea what it's for. */
+	.hide { display: none; }
+
+
+
+/******************************************************************************/
+/*                             Overflow Control                               */
+/******************************************************************************/
+
+	.figure .caption, .sidefigure .caption, figcaption {
+		/* in case figure is overlarge, limit caption to 50em */
+		max-width: 50rem;
+		margin-left: auto;
+		margin-right: auto;
+	}
+	.overlarge {
+		/* Magic to create good item positioning:
+		   "content column" is 50ems wide at max; less on smaller screens.
+		   Extra space (after ToC + content) is empty on the right.
+
+		   1. When item < content column, centers item in column.
+		   2. When content < item < available, left-aligns.
+		   3. When item > available, fills available and is scrollable.
+		*/
+		display: grid;
+		grid-template-columns: minmax(0, 50em);
+	}
+	.overlarge > table {
+		/* limit preferred width of table */
+		max-width: 50em;
+		margin-left: auto;
+		margin-right: auto;
+	}
+
+	@media (min-width: 55em) {
+		.overlarge {
+			margin-right: calc(13px + 26.5rem - 50vw);
+			max-width: none;
+		}
+	}
+	@media screen and (min-width: 78em) {
+		body:not(.toc-inline) .overlarge {
+			/* 30.5em body padding 50em content area */
+			margin-right: calc(40em - 50vw) !important;
+		}
+	}
+	@media screen and (min-width: 90em) {
+		body:not(.toc-inline) .overlarge {
+			/* 4em html margin 30.5em body padding 50em content area */
+			margin-right: calc(84.5em - 100vw) !important;
+		}
+	}
+
+	@media not print {
+		.overlarge {
+			overflow-x: auto;
+			/* See Lea Verou's explanation background-attachment:
+			 * http://lea.verou.me/2012/04/background-attachment-local/
+			 *
+			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
+			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
+			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
+			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
+			            white;
+			background-repeat: no-repeat;
+			*/
+		}
+	}
+
+/******************************************************************************/
+/*                             Dark mode toggle                               */
+/******************************************************************************/
+
+	#toc-theme-toggle input {
+		position: absolute;
+		clip: rect(1px, 1px, 1px, 1px);
+		clip-path: inset(0px 0px 99.9% 99.9%);
+		overflow: hidden;
+		height: 1px;
+		width: 1px;
+		padding: 0;
+		border: 0;
+	}
+
+	#toc-theme-toggle img {
+		background-color: transparent;
+        }
+
+	#toc-theme-toggle span {
+		padding: 5px;
+		border-radius: 30px;
+	}
+
+	#toc-theme-toggle input:checked + span {
+		background-color: var(--logo-bg);
+		color: var(--logo-text);
+		padding: 3px 10px;
+	}
+
+	@media (prefers-reduced-motion: reduce) {
+		body.toc-sidebar #toc {
+			position: absolute;
+			overflow: initial;
+			bottom: unset;
+		}
+	}
diff --git a/static/images/UD-watermark-dark-draft.svg b/static/images/UD-watermark-dark-draft.svg
new file mode 100644
index 0000000000000000000000000000000000000000..05f8d428ce90bbe6aca58dac91dd828d0d22bd7f
--- /dev/null
+++ b/static/images/UD-watermark-dark-draft.svg
@@ -0,0 +1,7 @@
+<svg xmlns='http://www.w3.org/2000/svg' width='80' height='400'>
+ <g transform='translate(50 200) rotate(-90) translate(-40 -190)'
+    style='font: 750 70px Arial, sans-serif; letter-spacing: 3px'
+    fill='#100808' stroke='#100808' stroke-width='3'>
+  <text x='50%' y='50%' style='text-anchor: middle'>DRAFT</text>
+ </g>
+</svg>
diff --git a/static/images/UD-watermark-dark-unofficial.svg b/static/images/UD-watermark-dark-unofficial.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d7105cef45afe116d8957073f30fcc30e5eea05a
--- /dev/null
+++ b/static/images/UD-watermark-dark-unofficial.svg
@@ -0,0 +1,7 @@
+<svg xmlns='http://www.w3.org/2000/svg' width='80' height='600'>
+ <g transform='translate(50 300) rotate(-90) translate(-40 -290)'
+    style='font: 750 70px Arial, sans-serif; letter-spacing: 3px'
+    fill='#100808' stroke='#100808' stroke-width='3'>
+  <text x='50%' y='50%' style='text-anchor: middle'>UNOFFICIAL</text>
+ </g>
+</svg>
diff --git a/static/images/UD-watermark-dark.svg b/static/images/UD-watermark-dark.svg
new file mode 100644
index 0000000000000000000000000000000000000000..07adbd442fd63dbbd776da951c6d421bfbf8fd38
--- /dev/null
+++ b/static/images/UD-watermark-dark.svg
@@ -0,0 +1,8 @@
+<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'>
+ <g transform='translate(200 200) rotate(-45) translate(-200 -200)'
+    style='font: 750 70px Arial, sans-serif; letter-spacing: 3px'
+    fill='#100808' stroke='#100808' stroke-width='3'>
+  <text x='53%' y='220' style='text-anchor: middle'>UNOFFICIAL</text>
+  <text x='53%' y='305' style='text-anchor: middle'>DRAFT</text>
+ </g>
+</svg>
diff --git a/static/images/UD-watermark-light-draft.svg b/static/images/UD-watermark-light-draft.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c19a4a2fdbe2900e0f53d23fdc3ddb5d52420fc0
--- /dev/null
+++ b/static/images/UD-watermark-light-draft.svg
@@ -0,0 +1,7 @@
+<svg xmlns='http://www.w3.org/2000/svg' width='80' height='400'>
+ <g transform='translate(50 200) rotate(-90) translate(-40 -190)'
+    style='font: 750 70px Arial, sans-serif; letter-spacing: 3px'
+    fill='#FDEDED' stroke='#FDEDED' stroke-width='3'>
+  <text x='50%' y='50%' style='text-anchor: middle'>DRAFT</text>
+ </g>
+</svg>
diff --git a/static/images/UD-watermark-light-unofficial.svg b/static/images/UD-watermark-light-unofficial.svg
new file mode 100644
index 0000000000000000000000000000000000000000..ac7b25f6ebb5746574d185bcbb5b561fb9218d06
--- /dev/null
+++ b/static/images/UD-watermark-light-unofficial.svg
@@ -0,0 +1,7 @@
+<svg xmlns='http://www.w3.org/2000/svg' width='80' height='600'>
+ <g transform='translate(50 300) rotate(-90) translate(-40 -290)'
+    style='font: 750 70px Arial, sans-serif; letter-spacing: 3px'
+    fill='#FDEDED' stroke='#FDEDED' stroke-width='3'>
+  <text x='50%' y='50%' style='text-anchor: middle'>UNOFFICIAL</text>
+ </g>
+</svg>
diff --git a/static/images/UD-watermark-light.svg b/static/images/UD-watermark-light.svg
new file mode 100644
index 0000000000000000000000000000000000000000..f247c9b121e2b7fd62c575e95b2640a8cb4c7913
--- /dev/null
+++ b/static/images/UD-watermark-light.svg
@@ -0,0 +1,8 @@
+<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'>
+ <g transform='translate(200 200) rotate(-45) translate(-200 -200)'
+    style='font: 750 70px Arial, sans-serif; letter-spacing: 3px'
+    fill='#FDEDED' stroke='#FDEDED' stroke-width='3'>
+  <text x='53%' y='220' style='text-anchor: middle'>UNOFFICIAL</text>
+  <text x='53%' y='305' style='text-anchor: middle'>DRAFT</text>
+ </g>
+</svg>
diff --git a/static/images/UD-watermark.png b/static/images/UD-watermark.png
new file mode 100644
index 0000000000000000000000000000000000000000..17916dba0b09f33887e9992b9e28c998cf9e31de
Binary files /dev/null and b/static/images/UD-watermark.png differ
diff --git a/static/images/UD.png b/static/images/UD.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c1ecc2590e4826a3563aa06137e3d9bf69ece89
Binary files /dev/null and b/static/images/UD.png differ
diff --git a/static/images/W3C-wok.png b/static/images/W3C-wok.png
new file mode 100644
index 0000000000000000000000000000000000000000..c96510438623715a8fa812c9e7173d9d12cacd7d
Binary files /dev/null and b/static/images/W3C-wok.png differ
diff --git a/static/images/W3C-wok.svg b/static/images/W3C-wok.svg
new file mode 100644
index 0000000000000000000000000000000000000000..9feefc57e62f53b669bf10c4081c973421d0306f
--- /dev/null
+++ b/static/images/W3C-wok.svg
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   version="1.1"
+   id="Layer_1"
+   viewBox="0 0 154 113"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <defs
+     id="defs25" />
+  <rect
+     x="0"
+     y="0"
+     width="154"
+     height="113"
+     fill="red"
+     id="rect4" />
+  <g
+     transform="translate(0,12.5)"
+     id="g18">
+    <g
+       id="g16">
+      <path
+         fill="#ffffff"
+         d="M 100.383,38.538 C 97.871,34.401 94.166,31.544 89.276,29.975 l 13.933,-24 V 1.366 H 76.076 66.492 66.2 L 52.548,47.757 38.905,1.366 H 29.019 L 33.539,16.519 24.312,47.757 10.665,1.366 H 0.782 L 23.37,77.59 h 0.942 L 38.429,30.354 52.548,77.59 h 0.94 L 72.829,12.325 73.738,10.778 H 89.655 L 76.467,33.545 v 4.518 h 3.772 c 4.836,0 8.373,1.475 10.636,4.426 1.945,2.506 2.915,6.051 2.915,10.631 0,4.143 -0.907,7.688 -2.726,10.635 -1.819,2.951 -4.047,4.42 -6.683,4.42 -2.506,0 -4.692,-0.829 -6.547,-2.491 -1.847,-1.659 -3.344,-3.935 -4.47,-6.815 l -7.722,3.193 c 1.566,4.77 3.986,8.547 7.247,11.34 3.259,2.788 7.097,4.188 11.491,4.188 5.828,0 10.581,-2.354 14.252,-7.057 3.674,-4.704 5.517,-10.512 5.517,-17.413 0.001,-5.583 -1.26,-10.447 -3.766,-14.582 z"
+         id="path6" />
+      <g
+         id="g14">
+        <path
+           fill="#ffffff"
+           d="m 142.451,0.939 1.606,9.73 -5.677,10.841 c 0,0 -2.176,-4.603 -5.783,-7.148 -3.045,-2.145 -5.034,-2.611 -8.131,-1.969 -3.987,0.822 -8.507,5.582 -10.477,11.454 -2.363,7.028 -2.383,10.427 -2.462,13.552 -0.133,5.002 0.655,7.963 0.655,7.963 0,0 -3.438,-6.36 -3.407,-15.682 0.028,-6.652 1.069,-12.689 4.141,-18.643 2.713,-5.229 6.742,-8.372 10.316,-8.744 3.692,-0.384 6.616,1.398 8.875,3.325 2.366,2.021 4.756,6.446 4.756,6.446 z"
+           id="path8" />
+        <path
+           fill="#ffffff"
+           d="m 143.151,55.996 c 0,0 -2.511,4.474 -4.068,6.201 -1.563,1.722 -4.351,4.765 -7.799,6.281 -3.454,1.517 -5.258,1.806 -8.671,1.479 -3.404,-0.327 -6.571,-2.296 -7.681,-3.121 -1.106,-0.822 -3.936,-3.248 -5.537,-5.5 -1.604,-2.262 -4.109,-6.777 -4.109,-6.777 0,0 1.392,4.527 2.27,6.447 0.502,1.104 2.048,4.482 4.239,7.427 2.038,2.754 6.011,7.477 12.052,8.544 6.041,1.064 10.186,-1.644 11.211,-2.298 1.025,-0.656 3.19,-2.472 4.558,-3.936 1.431,-1.526 2.782,-3.477 3.536,-4.645 0.552,-0.856 1.439,-2.59 1.439,-2.59 z"
+           id="path10" />
+        <path
+           fill-rule="evenodd"
+           clip-rule="evenodd"
+           fill="#ffffff"
+           d="m 149.896,2.222 c 0.654,0 0.957,0.184 0.957,0.639 0,0.436 -0.303,0.593 -0.938,0.593 h -0.593 V 2.222 Z m 0.126,-0.454 h -1.401 v 3.72 h 0.7 V 3.901 h 0.691 l 0.758,1.586 h 0.781 L 150.723,3.79 c 0.537,-0.108 0.848,-0.473 0.848,-1.002 0,-0.675 -0.51,-1.02 -1.549,-1.02 z m 2.759,1.95 c 0,0.758 -0.291,1.46 -0.828,1.978 -0.563,0.548 -1.265,0.839 -2.039,0.839 -0.729,0 -1.447,-0.3 -1.986,-0.847 -0.537,-0.548 -0.836,-1.249 -0.836,-1.996 0,-0.749 0.311,-1.478 0.865,-2.042 0.52,-0.53 1.22,-0.813 1.983,-0.813 0.783,0 1.485,0.292 2.032,0.849 0.528,0.528 0.809,1.24 0.809,2.032 z m -2.849,-3.307 c -0.885,0 -1.676,0.316 -2.276,0.929 -0.636,0.649 -0.992,1.486 -0.992,2.352 0,0.867 0.337,1.667 0.956,2.295 0.628,0.639 1.44,0.983 2.312,0.983 0.856,0 1.684,-0.344 2.331,-0.973 0.62,-0.601 0.956,-1.403 0.956,-2.305 0,-0.876 -0.347,-1.697 -0.948,-2.307 -0.626,-0.639 -1.446,-0.974 -2.339,-0.974 z"
+           id="path12" />
+      </g>
+    </g>
+  </g>
+  <g
+     aria-label="Editor's Draft"
+     id="text20"
+     style="fill:#ffffff">
+    <path
+       d="M -3.5371094,91.536133 H 8.0644531 v 2.607422 h -8.67187497 v 6.240235 H 7.7714844 v 2.62207 h -8.37890627 v 6.35742 H 8.3427734 v 2.60742 H -3.5371094 Z"
+       style="fill:#ffffff"
+       id="path27" />
+    <path
+       d="m 20.09082,91.536133 h 2.680664 V 112 h -5.698242 q -2.988281,0 -4.77539,-1.88965 -1.772461,-1.88965 -1.772461,-5.06836 0,-2.97363 1.860351,-4.89258 1.875,-1.918941 4.775391,-1.918941 1.347656,0 2.929687,0.571289 z m 0,18.178707 v -8.54004 q -1.245117,-0.62988 -2.519531,-0.62988 -1.992187,0 -3.178711,1.30371 -1.171875,1.30371 -1.171875,3.51563 0,2.08008 1.025391,3.20801 0.615234,0.67382 1.303711,0.9082 0.688476,0.23437 2.475586,0.23437 z"
+       style="fill:#ffffff"
+       id="path29" />
+    <path
+       d="m 27.766602,92.854492 q 0.659179,0 1.127929,0.454102 0.46875,0.454101 0.46875,1.113281 0,0.644531 -0.46875,1.113281 -0.46875,0.46875 -1.127929,0.46875 -0.615235,0 -1.083985,-0.46875 -0.46875,-0.483398 -0.46875,-1.113281 0,-0.615234 0.46875,-1.083984 0.46875,-0.483399 1.083985,-0.483399 z m -1.31836,5.668945 h 2.666016 V 112 h -2.666016 z"
+       style="fill:#ffffff"
+       id="path31" />
+    <path
+       d="m 31.0625,100.66211 5.009766,-4.921876 v 2.783203 h 4.262695 v 2.402343 h -4.262695 v 6.60645 q 0,2.31445 1.918945,2.31445 1.435547,0 3.032226,-0.9668 v 2.49024 q -1.538085,0.86426 -3.354492,0.86426 -1.831054,0 -3.046875,-1.06934 -0.380859,-0.32227 -0.629883,-0.71777 -0.249023,-0.41016 -0.424804,-1.05469 -0.161133,-0.65918 -0.161133,-2.49024 v -5.97656 H 31.0625 Z"
+       style="fill:#ffffff"
+       id="path33" />
+    <path
+       d="m 49.416992,98.494141 q 3.076172,0 5.112305,1.992189 2.036133,1.97754 2.036133,4.98047 0,2.91504 -2.06543,4.84863 -2.06543,1.91895 -5.200195,1.91895 -3.032227,0 -5.06836,-1.94825 -2.036133,-1.96289 -2.036133,-4.89258 0,-2.95898 2.050782,-4.92187 2.065429,-1.977539 5.170898,-1.977539 z m -0.146484,2.402339 q -1.918946,0 -3.149414,1.25977 -1.230469,1.25977 -1.230469,3.20801 0,1.93359 1.259766,3.16406 1.259765,1.21582 3.237304,1.21582 1.962891,0 3.208008,-1.23047 1.259766,-1.24512 1.259766,-3.17871 0,-1.91894 -1.303711,-3.17871 -1.303711,-1.25977 -3.28125,-1.25977 z"
+       style="fill:#ffffff"
+       id="path35" />
+    <path
+       d="m 62.410156,98.523437 v 3.090823 l 0.146485,-0.23438 q 1.933593,-3.120114 3.867187,-3.120114 1.508789,0 3.149414,1.523437 l -1.40625,2.343747 q -1.391601,-1.31836 -2.578125,-1.31836 -1.289062,0 -2.241211,1.23047 -0.9375,1.23047 -0.9375,2.91504 V 112 H 59.729492 V 98.523437 Z"
+       style="fill:#ffffff"
+       id="path37" />
+    <path
+       d="m 73.191406,98.142578 h -1.655273 l -0.65918,-4.02832 v -3.588867 h 3.00293 v 3.588867 z"
+       style="fill:#ffffff"
+       id="path39" />
+    <path
+       d="m 76.414062,111.0332 v -2.87109 q 1.12793,0.79102 2.299805,1.28906 1.186524,0.4834 1.992188,0.4834 0.834961,0 1.435547,-0.41016 0.600585,-0.41015 0.600585,-0.98144 0,-0.58594 -0.395507,-0.9668 -0.38086,-0.39551 -1.669922,-1.12793 -2.578125,-1.43554 -3.383789,-2.44629 -0.791016,-1.02539 -0.791016,-2.22656 0,-1.55273 1.201172,-2.534179 1.21582,-0.981445 3.120117,-0.981445 1.977539,0 4.057617,1.113281 v 2.636723 q -2.373047,-1.43555 -3.881836,-1.43555 -0.776367,0 -1.259765,0.33691 -0.46875,0.32227 -0.46875,0.86426 0,0.46875 0.424804,0.89356 0.439454,0.4248 1.523438,1.02539 l 0.952148,0.54199 q 3.369141,1.9043 3.369141,4.21875 0,1.65527 -1.303711,2.72461 -1.289062,1.05469 -3.325195,1.05469 -1.201172,0 -2.138672,-0.24903 -0.9375,-0.26367 -2.358399,-0.95215 z"
+       style="fill:#ffffff"
+       id="path41" />
+    <path
+       d="M 97.332031,111.9707 V 91.536133 h 6.899419 q 4.1748,0 6.60644,1.259765 2.43164,1.245118 3.86719,3.676758 1.43555,2.431641 1.43555,5.302734 0,2.05078 -0.79102,3.92578 -0.79102,1.875 -2.25586,3.2959 -1.49414,1.46484 -3.47168,2.21191 -1.15723,0.45411 -2.12402,0.61524 -0.9668,0.14648 -3.69141,0.14648 z m 6.591799,-17.827145 h -3.66211 v 15.219725 h 3.75 q 2.19726,0 3.41308,-0.29297 1.21583,-0.30761 2.02149,-0.76172 0.82031,-0.46875 1.49414,-1.14257 2.16797,-2.19727 2.16797,-5.55176 0,-3.295901 -2.22656,-5.375979 -0.82032,-0.776367 -1.88965,-1.274414 -1.05469,-0.498047 -2.00684,-0.65918 -0.95215,-0.161132 -3.06152,-0.161132 z"
+       style="fill:#ffffff"
+       id="path43" />
+    <path
+       d="m 122.29297,98.523437 v 3.090823 l 0.14648,-0.23438 q 1.9336,-3.120114 3.86719,-3.120114 1.50879,0 3.14941,1.523437 l -1.40625,2.343747 q -1.3916,-1.31836 -2.57812,-1.31836 -1.28906,0 -2.24121,1.23047 -0.9375,1.23047 -0.9375,2.91504 V 112 H 119.6123 V 98.523437 Z"
+       style="fill:#ffffff"
+       id="path45" />
+    <path
+       d="m 139.79785,103.89941 v 5.72754 q 0,0.68848 0.46875,0.68848 0.4834,0 1.50879,-0.71777 v 1.62597 q -0.9082,0.58594 -1.46484,0.79102 -0.542,0.21973 -1.14258,0.21973 -1.71387,0 -2.02149,-1.34766 -1.69921,1.31836 -3.61816,1.31836 -1.40625,0 -2.34375,-0.92285 -0.9375,-0.9375 -0.9375,-2.34375 0,-1.27442 0.9082,-2.27051 0.92285,-1.01074 2.60743,-1.59668 l 3.41308,-1.17188 v -0.71777 q 0,-2.43164 -2.43164,-2.43164 -2.18262,0 -4.24805,2.25586 v -2.91504 q 1.55274,-1.831054 4.46778,-1.831054 2.18261,0 3.50097,1.142578 0.43946,0.366211 0.79102,0.981446 0.35156,0.60059 0.43945,1.21582 0.10254,0.60059 0.10254,2.2998 z m -2.62207,5.43457 v -3.99902 l -1.78711,0.68848 q -1.3623,0.54199 -1.93359,1.09863 -0.55664,0.54199 -0.55664,1.36231 0,0.83496 0.52734,1.3623 0.54199,0.52734 1.3916,0.52734 1.27442,0 2.3584,-1.04004 z"
+       style="fill:#ffffff"
+       id="path47" />
+    <path
+       d="m 144.4707,98.523437 v -0.805664 q 0,-3.251953 1.37696,-4.848632 1.3916,-1.59668 3.32519,-1.59668 0.83496,0 1.97754,0.263672 v 2.607422 q -0.64453,-0.234375 -1.23047,-0.234375 -1.56738,0 -2.18262,0.834961 -0.60058,0.834961 -0.60058,2.973632 v 0.805664 h 2.40234 v 2.402343 h -2.40234 V 112 h -2.66602 v -11.07422 h -1.93359 v -2.402343 z"
+       style="fill:#ffffff"
+       id="path49" />
+    <path
+       d="m 149.77344,100.66211 5.00976,-4.921876 v 2.783203 h 4.2627 v 2.402343 h -4.2627 v 6.60645 q 0,2.31445 1.91895,2.31445 1.43555,0 3.03222,-0.9668 v 2.49024 q -1.53808,0.86426 -3.35449,0.86426 -1.83105,0 -3.04687,-1.06934 -0.38086,-0.32227 -0.62989,-0.71777 -0.24902,-0.41016 -0.4248,-1.05469 -0.16113,-0.65918 -0.16113,-2.49024 v -5.97656 h -2.34375 z"
+       style="fill:#ffffff"
+       id="path51" />
+  </g>
+</svg>
diff --git a/static/images/W3C.png b/static/images/W3C.png
new file mode 100644
index 0000000000000000000000000000000000000000..7aaf3927a0b0645d6c95b02ec992bb3f003ff434
Binary files /dev/null and b/static/images/W3C.png differ
diff --git a/static/images/W3C.svg b/static/images/W3C.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7170dcb0f1f2b6bdf96b5f9be105bcf22bce0198
--- /dev/null
+++ b/static/images/W3C.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" viewBox="0 0 72 48.000001" width="72" height="48">
+  <metadata id="metadata1654">
+    <rdf:RDF>
+      <cc:Work rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs id="defs1652" />
+  <rect x="0" y="0" width="72" height="48" fill="#1a5e9a" id="rect993" style="stroke-width:0.467575;fill:#005a9c" />
+  <path fill="#005a9c" d="m 2.032453,8.005453 9.53125,32.169922 h 0.396485 l 5.957031,-19.935547 5.958984,19.935547 h 0.396485 l 7.142578,-24.105469 c 1.364136,-4.603602 0.687308,-4.09375 4.757812,-4.09375 H 39.5305 l -6.636719,11.519532 h 2.664063 c 1.721607,0 3.534281,0.621234 4.488281,1.865234 0.133648,0.172602 0.253747,0.360478 0.365234,0.55664 0.02583,0.04519 0.04955,0.09224 0.07422,0.138672 0.104919,0.198597 0.202906,0.404193 0.28711,0.625 0.334699,0.878194 0.503906,1.933265 0.503906,3.167969 0,1.748 -0.384344,3.243281 -1.152344,4.488281 -0.208483,0.337699 -0.430231,0.625068 -0.664062,0.871094 -0.149564,0.157361 -0.305105,0.293883 -0.464844,0.414063 -0.01343,0.01005 -0.02751,0.01951 -0.04102,0.0293 -0.16287,0.11871 -0.328479,0.220536 -0.501953,0.300781 -0.158112,0.07314 -0.323214,0.125 -0.490234,0.166015 -0.04266,0.01039 -0.08568,0.01904 -0.128907,0.02734 -0.171803,0.03328 -0.346243,0.05664 -0.527343,0.05664 -0.0081,0 -0.01537,-0.0019 -0.02344,-0.002 -0.0081,-4.1e-5 -0.01539,-0.0019 -0.02344,-0.002 -0.0041,-3.9e-5 -0.0078,-0.0015 -0.01172,-0.002 -0.0094,-1.18e-4 -0.01799,-0.0018 -0.02734,-0.002 -0.238184,-0.0043 -0.471291,-0.0224 -0.695312,-0.0625 -0.0013,-2.26e-4 -0.0027,2.27e-4 -0.0039,0 -0.06129,-0.01103 -0.117505,-0.03511 -0.177734,-0.04883 -0.01254,-0.0028 -0.02493,-0.0059 -0.03711,-0.0098 -0.01528,-0.0037 -0.02971,-0.0098 -0.04492,-0.01367 -0.152838,-0.03546 -0.306311,-0.06965 -0.451172,-0.125 -0.228292,-0.08723 -0.447099,-0.195603 -0.658203,-0.326172 C 34.94049,35.478399 34.737935,35.326101 34.544172,35.151938 34.12993,34.701856 33.817992,34.190231 33.487531,33.691 h -4.054687 c 0.274888,0.816985 0.616402,1.555996 1.009765,2.234375 l -0.01172,0.02148 c 0.04254,0.07684 0.09949,0.148778 0.146484,0.22461 0.280031,0.454876 0.581602,0.886262 0.917969,1.27539 0.299571,0.346562 0.620593,0.666438 0.964844,0.960938 0.171266,0.146622 0.346692,0.28372 0.52539,0.412109 0,0 0.002,0.002 0.002,0.002 0.177989,0.127783 0.35957,0.245774 0.544922,0.355469 0.115046,0.06809 0.233683,0.126384 0.351563,0.1875 0.01577,0.0082 0.03106,0.01734 0.04687,0.02539 0.05701,0.03134 0.113495,0.06405 0.171875,0.0918 0.0018,8.68e-4 0.004,0.0011 0.0059,0.002 0.191896,0.09099 0.386651,0.17313 0.585937,0.246093 0.0027,10e-4 0.0051,0.0029 0.0078,0.0039 0,0 0.002,0 0.002,0 0.19779,0.07217 0.398564,0.134947 0.603516,0.189453 0.004,0.0011 0.0077,0.0029 0.01172,0.0039 0,0 0.002,0 0.002,0 0.20397,0.05382 0.412003,0.09842 0.623046,0.134766 0.0051,8.82e-4 0.01049,0.0011 0.01563,0.002 0.188465,0.03187 0.380106,0.05416 0.574218,0.07227 0.0046,4.32e-4 0.009,0.0015 0.01367,0.002 0.0071,0.0014 0.01417,0.0032 0.02148,0.0039 0.01093,0.0019 0.02197,0.0029 0.0332,0.0039 0,0 0.002,0 0.002,0 0.0053,4.46e-4 0.01031,0.0015 0.01563,0.002 0,0 0.002,0 0.002,0 0.116936,0.0096 0.238074,0.0091 0.357422,0.01367 0.02479,9.55e-4 0.04934,0.0032 0.07422,0.0039 0.0156,8.44e-4 0.03113,0.0016 0.04687,0.002 0.06026,0.0036 0.120272,0.0077 0.181641,0.0078 0.0079,2.2e-5 0.0155,0 0.02344,0 0.178244,0 0.34802,-0.01694 0.521484,-0.02734 v -0.0098 c 0.186606,-0.01341 0.378263,-0.0155 0.560547,-0.03906 0.02559,-0.0035 0.05069,-0.0079 0.07617,-0.01172 0.342257,-0.04769 0.6738,-0.119812 0.996094,-0.210937 1.50249,-0.424817 2.793149,-1.310157 3.861328,-2.679688 1.549,-1.986 2.324218,-4.434656 2.324218,-7.347656 0,-2.356 -0.530843,-4.407297 -1.589843,-6.154297 -0.804245,-1.326738 -1.898881,-2.339405 -3.283203,-3.041015 -0.04289,-0.02175 -0.08941,-0.03939 -0.132813,-0.06055 -0.178828,-0.087 -0.358606,-0.17317 -0.546875,-0.25 -0.233487,-0.09575 -0.473854,-0.183791 -0.722656,-0.263672 2.324763,-4.025522 4.690291,-8.027757 6.978515,-12.074219 H 33.805891 c -3.624299,0 -4.352809,0.6176449 -5.611329,4.896485 L 23.876203,27.585531 18.116438,8.005453 h -4.167969 l 0.953125,3.199219 c 0.794004,2.664306 0.723496,3.97222 -0.02148,6.49414 L 11.960188,27.585531 6.2023749,8.005453 Z" id="path1599-5" style="opacity:0.991;fill:#ffffff" />
+  <path id="path6-9" d="m 66.92,8.0059999 c -0.819,0 -1.554,0.295 -2.111,0.861 -0.591,0.6 -0.92,1.3760001 -0.92,2.1780001 0,0.802 0.313,1.545 0.887,2.128 0.583,0.591 1.334,0.912 2.145,0.912 0.793,0 1.562,-0.321 2.161,-0.903 0.574,-0.557 0.886,-1.301 0.886,-2.137 0,-0.811 -0.321,-1.5700001 -0.878,-2.1360001 -0.583,-0.591 -1.343,-0.903 -2.17,-0.903 z M 69.563,11.071 c 0,0.701 -0.271,1.351 -0.769,1.832 -0.523,0.507 -1.173,0.777 -1.891,0.777 -0.675,0 -1.342,-0.278 -1.84,-0.785 -0.498,-0.506 -0.777,-1.157 -0.777,-1.849 0,-0.692 0.287,-1.3680001 0.802,-1.8910001 0.481,-0.49 1.131,-0.751 1.84,-0.751 0.726,0 1.376,0.271 1.883,0.785 0.49,0.489 0.752,1.1480001 0.752,1.8820001 z M 67.005,9.2639999 h -1.3 V 12.709 h 0.65 V 11.24 h 0.642 l 0.701,1.469 h 0.726 l -0.769,-1.571 c 0.498,-0.101 0.785,-0.439 0.785,-0.928 0,-0.6250001 -0.473,-0.9460001 -1.435,-0.9460001 z m -0.119,0.422 c 0.608,0 0.886,0.169 0.886,0.5910001 0,0.405 -0.278,0.549 -0.87,0.549 H 66.353 V 9.6859999 Z" style="opacity:0.991;fill:#ffffff" />
+  <path id="path8-7" d="m 61.807,7.8249999 0.338,2.0535 C 62.460497,11.795283 62.1396,12.589153 61.2875,14.2195 L 60.092,16.507 c 0,0 -0.918,-1.941 -2.443,-3.015 -1.285,-0.905 -2.122,-1.102 -3.431,-0.832 -1.681,0.347 -3.587,2.357 -4.419,4.835 -0.995,2.965 -1.005,4.4 -1.04,5.718 -0.056,2.113 0.277,3.362 0.277,3.362 0,0 -1.451,-2.686 -1.438,-6.62 0.009,-2.808 0.451,-5.354 1.75,-7.867 1.143,-2.2090001 2.842,-3.5350001 4.35,-3.6910001 1.559,-0.161 2.791,0.59 3.743,1.404 C 58.44,10.655 59.451,12.521 59.451,12.521 Z" style="opacity:0.991;fill:#ffffff" />
+  <path id="path10-5" d="m 62.102,31.063 c 0,0 -1.057,1.889 -1.715,2.617 -0.659,0.728 -1.837,2.01 -3.292,2.651 -1.456,0.641 -2.218,0.762 -3.656,0.624 -1.437,-0.138 -2.773,-0.97 -3.241,-1.317 -0.468,-0.347 -1.664,-1.369 -2.339,-2.322 -0.676,-0.954 -1.733,-2.859 -1.733,-2.859 0,0 0.589,1.911 0.958,2.721 0.212,0.466 0.864,1.894 1.79,3.136 0.862,1.159 2.539,3.154 5.086,3.604 2.547,0.451 4.297,-0.693 4.73,-0.971 0.433,-0.277 1.432309,-0.93042 2.010243,-1.548482 0.603066,-0.644938 0.923083,-1.107393 1.325111,-1.920775 0.292057,-0.590889 0.544763,-1.977304 0.381146,-2.829243 z" style="opacity:0.991;fill:#ffffff" />
+</svg>
diff --git a/static/images/WD.gif b/static/images/WD.gif
new file mode 100644
index 0000000000000000000000000000000000000000..982fa70048e7f20c72ae93de996c58b59413dbe8
Binary files /dev/null and b/static/images/WD.gif differ
diff --git a/static/images/WD.png b/static/images/WD.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1dd37c9588bd1c5a15a866e218754d0a42999ce
Binary files /dev/null and b/static/images/WD.png differ
diff --git a/static/images/WD.svg b/static/images/WD.svg
new file mode 100644
index 0000000000000000000000000000000000000000..8a13673a493f991ef68e64c0601c740f37a391db
--- /dev/null
+++ b/static/images/WD.svg
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   version="1.1"
+   width="25"
+   height="380"
+   viewBox="0 0 25 380"
+   enable-background="new 0 0 25 380"
+   id="svg14"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <defs
+     id="defs18" />
+  <g
+     id="g12">
+    <path
+       id="rect4"
+       style="clip-rule:evenodd;fill:#1a5e9a;fill-rule:evenodd"
+       d="M 0,0 H 25 V 380 H 0 Z" />
+    <g
+       transform="rotate(-90,19,37)"
+       id="g10">
+      <g
+         aria-label="W3C Working Draft"
+         id="text8"
+         style="fill:#ffffff">
+        <path
+           d="m -129.4668,23.357422 h 1.94336 l -5.51758,13.701172 h -0.41992 l -4.46289,-11.09375 -4.50195,11.09375 h -0.41992 l -5.49805,-13.701172 h 1.96289 l 3.75977,9.404297 3.77929,-9.404297 h 1.85547 l 3.79883,9.404297 z"
+           id="path21" />
+        <path
+           d="m -123.88086,29.060547 h 0.11719 q 1.27929,0 1.94336,-0.527344 0.67383,-0.527344 0.67383,-1.533203 0,-0.908203 -0.6543,-1.474609 -0.64453,-0.566407 -1.69922,-0.566407 -1.06445,0 -2.36328,0.664063 v -1.865235 q 1.1914,-0.595703 2.59765,-0.595703 1.88477,0 2.96875,0.986328 1.09375,0.986329 1.09375,2.695313 0,1.035156 -0.41992,1.748047 -0.41992,0.703125 -1.33789,1.210937 0.80078,0.3125 1.17188,0.771485 0.37109,0.449218 0.57617,1.09375 0.20508,0.644531 0.20508,1.367187 0,1.78711 -1.19141,2.958985 -1.19141,1.162109 -3.00781,1.162109 -1.55274,0 -2.99805,-0.751953 v -2.128906 q 1.54297,0.966796 2.99805,0.966796 0.98633,0 1.58203,-0.585937 0.60547,-0.585938 0.60547,-1.552734 0,-0.810547 -0.49805,-1.416016 -0.29297,-0.341797 -0.6543,-0.498047 -0.35156,-0.166016 -1.5332,-0.3125 l -0.17578,-0.01953 z"
+           id="path23" />
+        <path
+           d="m -104.22266,33.835937 v 2.148438 q -2.14843,1.171875 -4.96093,1.171875 -2.28516,0 -3.87696,-0.917969 -1.59179,-0.917969 -2.51953,-2.529297 -0.92773,-1.611328 -0.92773,-3.486328 0,-2.978515 2.11914,-5.009765 2.1289,-2.03125 5.24414,-2.03125 2.14844,0 4.77539,1.123046 v 2.09961 q -2.39258,-1.367188 -4.67774,-1.367188 -2.34375,0 -3.89648,1.484375 -1.54297,1.47461 -1.54297,3.701172 0,2.246094 1.52344,3.691406 1.52344,1.445313 3.89648,1.445313 2.48047,0 4.84375,-1.523438 z"
+           id="path25" />
+        <path
+           d="m -81.380859,23.357422 h 1.943359 l -5.517578,13.701172 H -85.375 l -4.462891,-11.09375 -4.501953,11.09375 h -0.419922 l -5.498044,-13.701172 h 1.962888 l 3.759766,9.404297 3.779297,-9.404297 h 1.855468 l 3.798829,9.404297 z"
+           id="path27" />
+        <path
+           d="m -75.638672,27.996094 q 2.050781,0 3.408203,1.328125 1.357422,1.318359 1.357422,3.320312 0,1.94336 -1.376953,3.232422 -1.376953,1.279297 -3.466797,1.279297 -2.021484,0 -3.378906,-1.298828 -1.357422,-1.308594 -1.357422,-3.261719 0,-1.972656 1.367188,-3.28125 1.376953,-1.318359 3.447265,-1.318359 z m -0.09766,1.601562 q -1.279297,0 -2.099609,0.839844 -0.820313,0.839844 -0.820313,2.138672 0,1.289062 0.839844,2.109375 0.839844,0.810547 2.158203,0.810547 1.308594,0 2.138672,-0.820313 0.839844,-0.830078 0.839844,-2.11914 0,-1.279297 -0.869141,-2.119141 -0.869141,-0.839844 -2.1875,-0.839844 z"
+           id="path29" />
+        <path
+           d="m -66.976562,28.015625 v 2.060547 l 0.09766,-0.15625 q 1.289062,-2.080078 2.578125,-2.080078 1.005859,0 2.099609,1.015625 l -0.9375,1.5625 q -0.927734,-0.878907 -1.71875,-0.878907 -0.859375,0 -1.49414,0.820313 -0.625,0.820312 -0.625,1.943359 V 37 h -1.78711 v -8.984375 z"
+           id="path31" />
+        <path
+           d="m -55.111328,28.015625 h 2.119141 L -56.830078,32.419922 -52.210937,37 h -2.382813 l -4.501953,-4.580078 z m -5.839844,-4.658203 h 1.777344 V 37 h -1.777344 z"
+           id="path33" />
+        <path
+           d="m -50.462891,24.236328 q 0.439454,0 0.751954,0.302734 0.3125,0.302735 0.3125,0.742188 0,0.429687 -0.3125,0.742187 -0.3125,0.3125 -0.751954,0.3125 -0.410156,0 -0.722656,-0.3125 -0.3125,-0.322265 -0.3125,-0.742187 0,-0.410156 0.3125,-0.722656 0.3125,-0.322266 0.722656,-0.322266 z m -0.878906,3.779297 h 1.777344 V 37 h -1.777344 z"
+           id="path35" />
+        <path
+           d="m -45.228516,28.015625 v 1.142578 q 1.191407,-1.318359 2.705079,-1.318359 0.839843,0 1.5625,0.439453 0.722656,0.429687 1.09375,1.191406 0.380859,0.751953 0.380859,2.392578 V 37 h -1.777344 v -5.117188 q 0,-1.376953 -0.419922,-1.96289 -0.419922,-0.595703 -1.40625,-0.595703 -1.259765,0 -2.138672,1.259765 V 37 h -1.816406 v -8.984375 z"
+           id="path37" />
+        <path
+           d="m -37.464844,31.121094 q 0,-1.435547 1.044922,-2.265625 1.054688,-0.839844 2.871094,-0.839844 h 3.701172 v 1.386719 h -1.816406 q 0.527343,0.537109 0.732421,0.976562 0.205079,0.439453 0.205079,1.00586 0,0.703125 -0.400391,1.386718 -0.400391,0.673828 -1.035156,1.035157 -0.625,0.361328 -2.060547,0.576171 -1.00586,0.146485 -1.00586,0.69336 0,0.3125 0.371094,0.517578 0.38086,0.195312 1.367188,0.410156 1.65039,0.361328 2.11914,0.566406 0.478516,0.205079 0.859375,0.585938 0.644532,0.644531 0.644532,1.621094 0,1.279297 -1.142579,2.041015 -1.132812,0.761719 -3.037109,0.761719 -1.923828,0 -3.076172,-0.771484 -1.142578,-0.761719 -1.142578,-2.050782 0,-1.826171 2.255859,-2.353515 -0.898437,-0.576172 -0.898437,-1.142578 0,-0.429688 0.380859,-0.78125 0.390625,-0.351563 1.044922,-0.517578 -1.982422,-0.878907 -1.982422,-2.841797 z m 3.339844,-1.5625 q -0.722656,0 -1.230469,0.488281 -0.507812,0.488281 -0.507812,1.171875 0,0.693359 0.498047,1.152344 0.498047,0.449218 1.259765,0.449218 0.751953,0 1.25,-0.458984 0.507813,-0.46875 0.507813,-1.162109 0,-0.703125 -0.507813,-1.171875 -0.507812,-0.46875 -1.269531,-0.46875 z m -0.419922,7.861328 q -0.898437,0 -1.474609,0.380859 -0.566406,0.38086 -0.566406,0.976563 0,1.386718 2.5,1.386718 1.18164,0 1.826171,-0.351562 0.654297,-0.341797 0.654297,-0.976563 0,-0.625 -0.820312,-1.02539 -0.820313,-0.390625 -2.119141,-0.390625 z"
+           id="path39" />
+        <path
+           d="M -22.640625,36.980469 V 23.357422 h 4.599609 q 2.783203,0 4.404297,0.839844 1.621094,0.830078 2.578125,2.451171 0.957031,1.621094 0.957031,3.535157 0,1.367187 -0.527343,2.617187 -0.527344,1.25 -1.503907,2.197266 -0.996093,0.976562 -2.314453,1.474609 -0.771484,0.302735 -1.416015,0.410156 -0.644531,0.09766 -2.460938,0.09766 z m 4.394531,-11.884766 H -20.6875 v 10.146484 h 2.5 q 1.464844,0 2.275391,-0.195312 0.810546,-0.205078 1.347656,-0.507813 0.546875,-0.3125 0.996094,-0.761718 1.445312,-1.464844 1.445312,-3.701172 0,-2.197266 -1.484375,-3.583985 -0.546875,-0.517578 -1.259766,-0.849609 -0.703125,-0.332031 -1.33789,-0.439453 -0.634766,-0.107422 -2.041016,-0.107422 z"
+           id="path41" />
+        <path
+           d="m -6,28.015625 v 2.060547 l 0.097656,-0.15625 q 1.2890625,-2.080078 2.5781249,-2.080078 1.0058594,0 2.0996094,1.015625 l -0.9375,1.5625 q -0.9277344,-0.878907 -1.71875,-0.878907 -0.859375,0 -1.4941406,0.820313 Q -6,31.179687 -6,32.302734 V 37 h -1.7871094 v -8.984375 z"
+           id="path43" />
+        <path
+           d="m 5.6699219,31.599609 v 3.81836 q 0,0.458984 0.3125,0.458984 0.3222656,0 1.0058593,-0.478516 v 1.083985 Q 6.3828125,36.873047 6.0117187,37.009766 5.6503906,37.15625 5.25,37.15625 q -1.1425781,0 -1.3476562,-0.898438 -1.1328125,0.878907 -2.4121094,0.878907 -0.93750003,0 -1.56250002,-0.615235 -0.625,-0.625 -0.625,-1.5625 0,-0.849609 0.60546875,-1.513672 Q 0.5234375,32.771484 1.6464844,32.380859 L 3.921875,31.599609 V 31.121094 Q 3.921875,29.5 2.3007813,29.5 0.84570313,29.5 -0.53125,31.003906 v -1.943359 q 1.03515625,-1.220703 2.9785156,-1.220703 1.4550782,0 2.3339844,0.761718 0.2929687,0.244141 0.5273437,0.654297 0.234375,0.400391 0.2929688,0.810547 0.068359,0.400391 0.068359,1.533203 z M 3.921875,35.222656 v -2.666015 l -1.1914062,0.458984 q -0.9082032,0.361328 -1.2890626,0.732422 -0.3710937,0.361328 -0.3710937,0.908203 0,0.556641 0.3515625,0.908203 0.3613281,0.351563 0.9277344,0.351563 0.8496094,0 1.5722656,-0.69336 z"
+           id="path45" />
+        <path
+           d="m 8.7851563,28.015625 v -0.537109 q 0,-2.167969 0.9179687,-3.232422 0.927734,-1.064453 2.216797,-1.064453 0.556641,0 1.318359,0.175781 v 1.738281 q -0.429687,-0.15625 -0.820312,-0.15625 -1.044922,0 -1.455078,0.556641 -0.400391,0.55664 -0.400391,1.982422 v 0.537109 h 1.601563 v 1.601562 H 10.5625 V 37 H 8.7851563 V 29.617187 H 7.4960937 v -1.601562 z"
+           id="path47" />
+        <path
+           d="m 12.320313,29.441406 3.339843,-3.28125 v 1.855469 h 2.841797 v 1.601562 h -2.841797 v 4.404297 q 0,1.542969 1.279297,1.542969 0.957031,0 2.021484,-0.644531 v 1.660156 q -1.02539,0.576172 -2.236328,0.576172 -1.220703,0 -2.03125,-0.712891 -0.253906,-0.214843 -0.419921,-0.478515 -0.166016,-0.273438 -0.283204,-0.703125 -0.107421,-0.439453 -0.107421,-1.660157 v -3.984375 h -1.5625 z"
+           id="path49" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/static/javascripts/gitlab-widgets/gitlab-widgets.js b/static/javascripts/gitlab-widgets/gitlab-widgets.js
new file mode 100644
index 0000000000000000000000000000000000000000..8fdcbb0fa1661a15987d1aab6d6a966438f248c0
--- /dev/null
+++ b/static/javascripts/gitlab-widgets/gitlab-widgets.js
@@ -0,0 +1,421 @@
+/*
+ *
+ * Examples of use of the gitlab overview widget 
+ * {{< gitlab-overview servers="158:https://git.cleverthis.com/,1876:https://git.qoto.org/" displayCount=2 stats=true v9.2.6="http://example.com" >}}
+ *
+ * {{< gitlab-overview servers="158:https://git.cleverthis.com/" displayCount=1 stats=true v9.2.6="http://example.com" >}}
+ *
+ * {{< gitlab-overview servers="166:https://git.cleverthis.com/" v1.0="http://example2.com/" >}}
+ */
+
+import * as gitlabWidgets from "./helpers.js"
+
+const progressBarTitle = '<span class="releaseTitle"></span>';
+const progressBar = '<progress class="releaseProgressBar"></progress>';
+
+const issuesSearchParams = { scope: "all" };
+const issuesBugSearchParams = { scope: "all", labels: "bug" };
+const issuesOpenSearchParams = { scope: "all", state: "opened" };
+const issuesClosedSearchParams = { scope: "all", state: "closed" };
+
+function initWidgets() {
+    for(var widget of $(".gitlab-overview-container")) {
+        initializeOverviewWidget(widget)
+    }
+    for(var widget of $(".gitlab-single-version-container")) {
+        initializeSingleVersionWidget(widget)
+    }
+}
+
+function initializeOverviewWidget(widget) {
+    var overviewWidget = $(widget)
+    var projectName = overviewWidget.find(".project-name")
+    var releaseList = overviewWidget.find(".gitlab-overview-release-list")
+    var progressList = overviewWidget.find(".gitlab-progress-list")
+    var proxy = overviewWidget.find("#proxy")
+    var border = overviewWidget.find("#border")
+    var projectId = gitlabWidgets.getGitlabServerProjectID(overviewWidget, 0)
+    var displayCount = gitlabWidgets.getDisplayCount(overviewWidget)
+
+    gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(overviewWidget, 0), proxy, (data) => {
+        projectName.text(data['path_with_namespace'])
+    });
+
+    if(border.val() == "true") {
+        console.log("truth check passed")
+        overviewWidget.addClass("borderedWidget")
+    }
+
+    gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(overviewWidget, 0) + gitlabWidgets.ENDPOINTS.P.MILESTONES, proxy, (data) => {
+
+        var displayedData = null
+
+        if(displayCount != null) {
+            displayedData = data.slice(0, displayCount)
+        } else {
+            displayedData = data
+        }
+
+        displayedData.forEach(release => {
+            let releaseAnchor = gitlabWidgets.generateMilestoneAnchor(widget, release)
+            releaseAnchor.appendTo(releaseList)
+        })
+
+        styleReleaseName(overviewWidget, releaseList.children())
+
+        populateProgressList(overviewWidget, progressList, data)
+
+        let displayStats = overviewWidget.find('#stats')
+        if(displayStats.length > 0 && displayStats[0].value == "true") {
+            populateFooter(overviewWidget)
+        } else {
+            removeFooter(overviewWidget)
+        }
+    })
+}
+
+async function initializeSingleVersionWidget(widget) {
+    var singleVersionWidget = $(widget)
+    var releaseName = singleVersionWidget.find(".release-name")
+    var proxy = singleVersionWidget.find("#proxy")
+    var percentageComplete = singleVersionWidget.find(".gitlab-single-version-entry .percentage-complete")
+
+    var releaseData = null
+    var releaseAnchor = null
+
+    var addBugsField = false
+
+    await gitlabWidgets.apiCall(gitlabWidgets.buildProjectMilestoneURL(widget, 0), proxy, (data) => {
+        releaseName.text(data['title'])
+        releaseAnchor = gitlabWidgets.generateMilestoneAnchor(widget, data)
+        let releaseNameDatum = $("<td></td>").append(releaseAnchor)
+
+        singleVersionWidget.find(".gitlab-single-version-entry .title").append(releaseAnchor)//text(data['title'])
+        singleVersionWidget.find(".gitlab-single-version-entry .due-date").text(data['due_date'])
+
+        releaseData = data
+    })
+
+    await gitlabWidgets.apiCall(gitlabWidgets.buildProjectMilestoneURL(widget, 0), proxy, (data) => {
+        if(data['state'] == "active") {
+            initializeSingleVersionInProgress(widget, data)
+        } else if(data['state'] == "closed") {
+            addBugsField = true
+            initializeSingleVersionReleased(widget, releaseData)
+        }
+    })
+
+    let displayStats = singleVersionWidget.find('#stats')
+    if(displayStats.length > 0 && displayStats[0].value == "true") {
+        populateSingleVersionFooter(widget, releaseData['title'], addBugsField)
+    } else {
+        removeFooter(singleVersionWidget)
+    }
+}
+
+async function initializeSingleVersionReleased(widget, data) {
+    var singleVersionWidget = $(widget)
+    var proxy = singleVersionWidget.find("#proxy")
+    var title = singleVersionWidget.find(".title")
+    // DOM manipulations to get rid of fields that make no sense to display
+    singleVersionWidget.find(".percentage-column").remove()
+    singleVersionWidget.find(".progress-bar").remove()
+    singleVersionWidget.find(".due-date-tableheader").text("Release Date")
+    singleVersionWidget.find(".percentage-complete").text("Released")
+    singleVersionWidget.find(".completion-tableheader").css("width", "100%")
+
+    var milestoneBugIssuesParams = new URLSearchParams({ ...issuesSearchParams, milestone: data['title'], labels: ["Type::Bug"] })
+
+    // Color title based on whether bug issues exist
+    await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, 0) + gitlabWidgets.ENDPOINTS.P.ISSUES + "?" + milestoneBugIssuesParams.toString(), proxy, (data) => {
+        if(data.length > 0) {
+            title.children("a").addClass("red")
+        } else {
+            title.children("a").addClass("green")
+        }
+    })
+
+
+}
+
+async function initializeSingleVersionInProgress(widget, data) {
+    var singleVersionWidget = $(widget)
+    var proxy = singleVersionWidget.find("#proxy")
+
+    // TODO: Calculate percentage complete
+    var allIssuesParams = new URLSearchParams({ ...issuesSearchParams, milestone: data['title'] })
+    var closedIssuesParams = new URLSearchParams({ ...issuesClosedSearchParams, milestone: data['title'] })
+
+    var percentageComplete = singleVersionWidget.find(".gitlab-single-version-entry .percentage-complete")
+
+    var allIssuesCount = 0
+    var closedIssuesCount = 0
+
+    for(let i = 0; i < gitlabWidgets.getGitlabServerCount(singleVersionWidget); i++) {
+        await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.ISSUES + "?" + allIssuesParams.toString(), proxy, (allIssuesData) => {
+            allIssuesCount += allIssuesData.length
+        })
+
+        await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.ISSUES + "?" + closedIssuesParams.toString(), proxy, (closedIssuesData) => {
+            closedIssuesCount += closedIssuesData.length
+        })
+    }
+
+    singleVersionWidget.find("progress").attr('max', allIssuesCount)
+    singleVersionWidget.find("progress").val(closedIssuesCount)
+
+    if(allIssuesCount == 0) {
+        percentageComplete.text("0%")
+    } else {
+        // TODO: Extract this to helper
+        let progressText = ((closedIssuesCount / allIssuesCount)*100).toFixed(1) + "%"
+        percentageComplete.text(progressText)
+    }
+
+    //populateSingleVersionFooter(widget, data['title'])
+}
+
+async function populateSingleVersionFooter(widget, milestoneTitle, addBugsField=false) {
+    //var milestoneId = $(widget).find("#milestone_id").val()
+
+    var commitCount = 0
+    var issueCount = 0
+    var issueTotal = 0
+    var mergeRequestCount = 0
+    var mergeRequestTotal = 0
+
+    var proxy = $(widget).find("#proxy")
+
+    var bugFooterElement = $('<span class="footer-element"></span>')
+
+    let issuesMilestoneSearchParams = new URLSearchParams({ ...issuesSearchParams, milestone: milestoneTitle })
+    let issuesOpenMilestoneSearchParams = new URLSearchParams({ ...issuesOpenSearchParams, milestone: milestoneTitle })
+
+    let openMRSearchParams = new URLSearchParams({ state: "opened", milestone: milestoneTitle })
+    let allMRSearchParams = new URLSearchParams({ state: "all", milestone: milestoneTitle })
+
+    for(let i = 0; i < gitlabWidgets.getGitlabServerCount(widget); i++) {
+        await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.ISSUES + "?" + issuesMilestoneSearchParams.toString(), proxy, (data) => {
+            issueTotal += data.length 
+        })
+
+        await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.ISSUES + "?" + issuesOpenMilestoneSearchParams.toString(), proxy, (data) => {
+            issueCount += data.length 
+        })
+
+        await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.MERGE_REQUESTS + "?" + openMRSearchParams.toString(), proxy, (data) => {
+            mergeRequestCount += data.length
+        })
+
+        await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.MERGE_REQUESTS + "?" + allMRSearchParams.toString(), proxy, (data) => {
+            mergeRequestTotal += data.length
+        })
+    }
+
+    $(widget).find("#issue-count").text(issueCount)
+    $(widget).find("#issue-total").text(issueTotal)
+    $(widget).find("#mr-count").text(mergeRequestCount)
+    $(widget).find("#mr-total").text(mergeRequestTotal)
+
+    if(addBugsField == true) {
+        $('<span class="label">Bugs:</span>').appendTo(bugFooterElement)
+        $('<span id="bugs"></span>').appendTo(bugFooterElement)
+        $(widget).find(".gitlab-overview-footer").prepend(bugFooterElement)
+    }
+
+    var milestoneBugIssuesParams = new URLSearchParams({ ...issuesSearchParams, milestone: milestoneTitle, labels: ["Type::Bug"] })
+
+    // Color title based on whether bug issues exist
+    await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, 0) + gitlabWidgets.ENDPOINTS.P.ISSUES + "?" + milestoneBugIssuesParams.toString(), proxy, (data) => {
+        getBugCountSinceRelease(widget, milestoneTitle).then((bugCount) => {
+            bugFooterElement.find("#bugs").text(bugCount)
+        })
+    })
+
+    let projectStatsSearchParams = new URLSearchParams({ statistics: "true" })
+    await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, 0) + "?" + projectStatsSearchParams.toString(), proxy, (data) => {
+        $(widget).find("#commits").text(data['statistics']['commit_count'])
+    })
+}
+
+async function getBugCountSinceRelease(widget, milestoneTitle) {
+    var milestones = new Array()
+    var indice = 0
+    var bugCount = 0
+
+    var proxy = $(widget).find("#proxy")
+
+    let serverCount = gitlabWidgets.getGitlabServerCount(widget)
+
+    await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, 0) + gitlabWidgets.ENDPOINTS.P.MILESTONES, (data) => {
+        for(var milestone of data) {
+            milestones.push(milestone['title'])
+        }
+    })
+
+    milestones.sort(gitlabWidgets.compareSemanticVersions)
+    indice = milestones.indexOf(milestoneTitle)
+    var subsequentMilestones = milestones.slice(indice, milestones.length)
+
+    for(var milestone of subsequentMilestones) {
+        let milestoneBugIssuesParams = new URLSearchParams({ ...issuesSearchParams, milestone: milestone, labels: ["Type::Bug"] })
+        for(let i = 0; i < serverCount; i++) {
+            await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, i) + gitlabWidgets.ENDPOINTS.P.ISSUES + "?" + milestoneBugIssuesParams.toString(), proxy, (data) => {
+                bugCount += data.length
+            })
+        }
+    }
+
+    return bugCount
+}
+
+/* Overview widget */
+async function populateFooter(widget) {
+    var starCount = 0
+    var issueCount = 0
+    var issueTotal = 0
+    var mergeRequestCount = 0
+    var mergeRequestTotal = 0
+    var commitCount = 0
+
+    var proxy = $(widget).find("#proxy")
+
+    for(let i = 0; i < gitlabWidgets.getGitlabServerCount(widget); i++) {
+        // Project info
+        await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, i), proxy, (data) => {
+            starCount += data['star_count']
+            issueCount += data['open_issues_count']
+        })
+
+        // Issue count
+        await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, i) + gitlabWidgets.ENDPOINTS.P.ISSUES, proxy, (data) => {
+            issueTotal += data.length
+        })
+
+        // Merge request count
+        let openMRSearchParams = new URLSearchParams({ state: "opened" })
+        await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, i) + gitlabWidgets.ENDPOINTS.P.MERGE_REQUESTS + "?" + openMRSearchParams.toString(), proxy, (data) => {
+            mergeRequestCount += data.length
+        })
+
+        // Merge request count, part 2
+        let allMRSearchParams = new URLSearchParams({ state: "all" })
+        await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, i) + gitlabWidgets.ENDPOINTS.P.MERGE_REQUESTS + "?" + allMRSearchParams.toString(), proxy, (data) => {
+            mergeRequestTotal += data.length
+        })
+
+        // Count the project commits
+        let projectStatsSearchParams = new URLSearchParams({ statistics: "true" })
+        await gitlabWidgets.apiCall(gitlabWidgets.buildProjectURL(widget, i) + "?" + projectStatsSearchParams.toString(), proxy, (data) => {
+            // We don't sum these values because we don't want to double-count commits
+            // We want the higher count, though
+            let singleProjectCommitCount = data['statistics']['commit_count']
+            if(commitCount < singleProjectCommitCount) {
+                commitCount = singleProjectCommitCount
+            }
+        })
+    }
+
+    widget.find(".gitlab-overview-footer #stars").text(starCount)
+    widget.find(".gitlab-overview-footer #issue-count").text(issueCount)
+    widget.find(".gitlab-overview-footer #issue-total").text(issueTotal)
+    widget.find(".gitlab-overview-footer #mr-count").text(mergeRequestCount)
+    widget.find(".gitlab-overview-footer #mr-total").text(mergeRequestTotal)
+    widget.find(".gitlab-overview-footer #commits").text(commitCount)
+}
+
+function removeFooter(widget) {
+    $(widget).find('.gitlab-overview-footer').remove()
+}
+
+function styleReleaseName(widget, releases) {
+    var proxy = $(widget).find("#proxy")
+
+    Array.from(releases).forEach(release => {
+        var allBugIssuesParams = new URLSearchParams({ ...issuesBugSearchParams, milestone: release.innerText })
+        gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, 0) + gitlabWidgets.ENDPOINTS.ISSUES + "?" + allBugIssuesParams.toString(), proxy, (data) => {
+            if(data.length == 0) {
+                $(release).addClass("green")
+            } else {
+                $(release).addClass("red")
+            }
+        });
+    })
+}
+
+async function populateProgressList(widget, progressList, releases) {
+    var displayCount = gitlabWidgets.getDisplayCount(widget)
+
+    var proxy = $(widget).find("#proxy")
+
+    var displayedReleases = null
+
+    if(displayCount != null) {
+        displayedReleases = releases.slice(0, displayCount)
+    } else {
+        displayedReleases = releases
+    }
+
+
+    for(const release of displayedReleases) {
+        let releaseAnchor = gitlabWidgets.generateMilestoneAnchor(widget, release)
+        let releaseNameDatum = $("<td></td>").append(releaseAnchor)
+
+        var entry = $('<tr class="gitlabOverviewEntry"></div>').appendTo(progressList);
+
+        releaseNameDatum.appendTo(entry)
+
+        var percentageComplete = $('<td></td>').appendTo(entry)
+        var dueDate = $('<td></td>').appendTo(entry)
+
+        var entryBar = entry.append('<td><progress></progress></td>');
+
+        var allIssuesParams = new URLSearchParams({ ...issuesSearchParams, milestone: release.title })
+        var closedIssuesParams = new URLSearchParams({ ...issuesClosedSearchParams, milestone: release.title })
+
+        var allIssuesCount = 0
+        var closedIssuesCount = 0
+
+        for(let i = 0; i < gitlabWidgets.getGitlabServerCount(widget); i++) {
+
+            // Get issues of milestone_title, open and closed
+            await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.ISSUES + "?" + allIssuesParams.toString(), proxy, (allIssuesData) => {
+                allIssuesCount += allIssuesData.length
+            });
+
+            await gitlabWidgets.apiCall(gitlabWidgets.getGitlabServerURL(widget, i) + gitlabWidgets.ENDPOINTS.ISSUES + "?" + closedIssuesParams.toString(), proxy, (closedIssuesData) => {
+                closedIssuesCount += closedIssuesData.length
+            });
+        }
+
+
+        // Initialize progress bar
+        if(allIssuesCount == 0) {
+            percentageComplete.text("0%")
+        } else {
+            let progressText = ((closedIssuesCount / allIssuesCount)*100).toFixed(1) + "%"
+            percentageComplete.text(progressText)
+        }
+
+        entry.find("progress").attr('max', allIssuesCount);
+        entry.find("progress").val(closedIssuesCount);
+
+        let progress = entryBar.find("progress")
+        let progressMax = progress[0].max
+        let progressCount = progress.val()
+
+        let progressText = (progressCount / progressMax)*100 + "%"
+
+        if(release['due_date'] == null) {
+            dueDate.text("No due date") 
+        } else { 
+            dueDate.text(release['due_date'])
+        }
+    }
+}
+
+
+// Only initialize widgets when page is done loading
+$(document).ready(() => {
+    initWidgets()
+})
diff --git a/static/javascripts/gitlab-widgets/helpers.js b/static/javascripts/gitlab-widgets/helpers.js
new file mode 100644
index 0000000000000000000000000000000000000000..812c970da461b3418902718548e8cb7ea8accb5a
--- /dev/null
+++ b/static/javascripts/gitlab-widgets/helpers.js
@@ -0,0 +1,107 @@
+export { getDisplayCount, getGitlabServerCount, getGitlabServerURLs, getGitlabServerURL,
+         getGitlabServerProjectID, generateMilestoneAnchor, buildProjectURL, buildProjectMilestoneURL, 
+         apiCall, compareSemanticVersions, ENDPOINTS, PUBLIC_PROJECT_ENDPOINT };
+
+const PUBLIC_PROJECT_ENDPOINT = "/projects/"
+
+const ENDPOINTS = {
+    PROJECT: "/api/v4/projects/",
+
+    P: {
+        MILESTONES: "/milestones/",
+        ISSUES: "/issues",
+        MERGE_REQUESTS: "/merge_requests",
+        COMMITS: "/repository/commits",
+    },
+    MERGE_REQUESTS: "/api/v4/merge_requests",
+    ISSUES: "/api/v4/issues",
+}
+
+/*
+ * Helper functions
+ *
+ */
+
+function getDisplayCount(widget) {
+    var overviewWidget = $(widget)
+    var displayCount = null
+
+    if(overviewWidget.find('.displayCount').length > 0) {
+        displayCount = overviewWidget.find('.displayCount')[0].value
+    }
+
+    return displayCount
+}
+
+function getGitlabServerCount(widget) {
+    return $(widget).find("#servers").val().split(",").length
+}
+
+function getGitlabServerURLs() {
+    return $("#servers")
+}
+
+function getGitlabServerURL(widget, index) {
+    var overviewWidget = $(widget)
+    return overviewWidget.find("#servers").val().split(",")[index].split(/:(.*)/s)[1]
+}
+
+function getGitlabServerProjectID(widget, index) {
+    var overviewWidget = $(widget)
+    return overviewWidget.find("#servers").val().split(",")[index].split(/:(.*)/s)[0]
+}
+
+function generateMilestoneAnchor(widget, release) {
+    let override = $(widget).find("#" + $.escapeSelector(release.title))
+    if (override.length > 0) {
+        return $("<a href='" + override.val() + "'>" + release.title + "</a>")
+    } else {
+        return $("<a href='" + release['web_url'] + "'>" + release.title + "</a>")
+    }
+}
+
+function buildProjectURL(widget, index) {
+    const endpoint = ENDPOINTS.PROJECT + getGitlabServerProjectID(widget, index)
+    var url = new URL(endpoint, getGitlabServerURL(widget, index))
+    return url
+}
+
+function buildProjectMilestoneURL(widget, index) {
+    const milestone_id = $(widget).find("#milestone_id").val()
+    const endpoint = ENDPOINTS.PROJECT + getGitlabServerProjectID(widget, index) + ENDPOINTS.P.MILESTONES + milestone_id
+    var url = new URL(endpoint, getGitlabServerURL(widget, index))
+    return url
+}
+
+function apiCall(endpoint, proxy, callback) {
+    let proxyURL = new URL(proxy.val())
+    let proxySearchParams = new URLSearchParams({ url: endpoint.toString() })
+    let fullProxyEndpointWithParams = proxyURL.toString() + "?" + proxySearchParams.toString()
+
+
+    return $.ajax({
+        url: fullProxyEndpointWithParams,
+        method: "GET",
+        timeout: 0,
+        error: function(error, status, errorThrown) { console.dir({error, status, errorThrown}) },
+    }).done(callback)
+}
+
+const compareSemanticVersions = (a, b) => {
+ 
+    // 1. Split the strings into their parts.
+    const a1 = a.split('.');
+    const b1 = b.split('.');    // 2. Contingency in case there's a 4th or 5th version
+    const len = Math.min(a1.length, b1.length);    // 3. Look through each version number and compare.
+    for (let i = 0; i < len; i++) {
+        const a2 = +a1[ i ] || 0;
+        const b2 = +b1[ i ] || 0;
+        
+        if (a2 !== b2) {
+            return a2 > b2 ? 1 : -1;        
+        }    }
+    
+    // 4. We hit this if the all checked versions so far are equal
+    //
+    return b1.length - a1.length;
+};
diff --git a/static/javascripts/head.js b/static/javascripts/head.js
index 55f824995ac7dc28ba0604cfb56b057f093f979a..ecef51325c1d5b66541ecac06dfcf9f513e9ec84 100644
--- a/static/javascripts/head.js
+++ b/static/javascripts/head.js
@@ -87,6 +87,10 @@ null !== a ? t(a) : n.matches && t("dark")
 
 $(document).ready(function () {
 
+    if(window.localStorage) {
+      window.localStorage.setItem("configLangPref", 1)
+    }
+
     $('.tab-content').find('.tab-pane').each(function (idx, item) {
         var navTabs = $(this).closest('.code-tabs').find('.nav-tabs'),
             title = $(this).attr('title');