diff --git a/svelte/src/lib/assets/cargo.png b/svelte/src/lib/assets/cargo.png
new file mode 100644
index 00000000000..eaa250e634c
Binary files /dev/null and b/svelte/src/lib/assets/cargo.png differ
diff --git a/svelte/src/lib/components/Header.svelte b/svelte/src/lib/components/Header.svelte
new file mode 100644
index 00000000000..cc82d648955
--- /dev/null
+++ b/svelte/src/lib/components/Header.svelte
@@ -0,0 +1,311 @@
+
+
+
+
+
diff --git a/svelte/src/lib/css/global.css b/svelte/src/lib/css/global.css
new file mode 100644
index 00000000000..44d6ae47605
--- /dev/null
+++ b/svelte/src/lib/css/global.css
@@ -0,0 +1,205 @@
+@import './shared/a11y.css';
+@import './shared/buttons.css';
+@import './shared/forms.css';
+@import './shared/sort-by.css';
+@import './shared/typography.css';
+
+/*
+ * The `normalize.css` file does not use CSS layers, so we need to vendor it
+ * with a layer to ensure it is applied before our global styles.
+ */
+@import './normalize.css';
+
+@layer global {
+ :root {
+ --violet800: hsl(252, 44%, 24%);
+ --grey900: hsl(200, 15%, 19%);
+ --grey700: hsl(200, 11%, 43%);
+ --grey600: hsl(200, 13%, 60%);
+ --grey200: hsl(200, 17%, 96%);
+ --green800: hsl(115, 31%, 31%);
+ --green900: hsl(115, 31%, 21%);
+
+ --orange-50: #fff7ed;
+ --orange-100: #ffedd5;
+ --orange-200: #fed7aa;
+ --orange-300: #fdba74;
+ --orange-400: #fb923c;
+ --orange-500: #f97316;
+ --orange-600: #ea580c;
+ --orange-700: #c2410c;
+ --orange-800: #9a3412;
+ --orange-900: #7c2d12;
+
+ --yellow100: hsl(44, 100%, 90%);
+ --yellow500: hsl(44, 100%, 60%);
+ --yellow700: hsl(44, 67%, 50%);
+ --yellow800: hsl(44, 67%, 20%);
+ --yellow900: hsl(44, 30%, 23%);
+
+ --header-bg-color: light-dark(hsl(115, 31%, 20%), #141413);
+
+ --transition-x-slow: 1000ms;
+ --transition-slow: 500ms;
+ --transition-medium: 250ms;
+ --transition-fast: 150ms;
+ --transition-x-fast: 50ms;
+ --transition-instant: 0ms;
+
+ --font-heading: 'Fira Sans', sans-serif;
+ --font-body: var(--font-heading);
+ --font-monospace:
+ 'Fira Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
+
+ --main-color: light-dark(#383838, #f9f7ec);
+ --main-color-light: light-dark(#858585, #a6a6a6);
+ --main-shadow-color: light-dark(var(--green900), hsl(111, 10%, 8%));
+ --main-bg: light-dark(#f9f7ec, hsl(0, 1%, 19%));
+ --main-bg-dark: light-dark(#edebdd, #141413);
+ --gray-border: light-dark(#d5d3cb, #666561);
+ --link-color: light-dark(#00ac5b, #04da75);
+ --link-hover-color: light-dark(#007940, #00f27f);
+
+ --placeholder-bg: hsl(212, 7%, 57%);
+ --placeholder-bg2: hsl(213, 16%, 75%);
+
+ /* see https://utopia.fyi/space/calculator?c=320,14,1.2,1140,18,1.25,5,2,&s=0.75|0.5|0.25|0.125,1.5|2|3|4|6,s-l */
+
+ --space-4xs: clamp(0.13rem, calc(0.13rem + 0vw), 0.13rem);
+ --space-3xs: clamp(0.25rem, calc(0.23rem + 0.12vw), 0.31rem);
+ --space-2xs: clamp(0.44rem, calc(0.39rem + 0.24vw), 0.56rem);
+ --space-xs: clamp(0.69rem, calc(0.61rem + 0.37vw), 0.88rem);
+ --space-s: clamp(0.88rem, calc(0.78rem + 0.49vw), 1.13rem);
+ --space-m: clamp(1.31rem, calc(1.17rem + 0.73vw), 1.69rem);
+ --space-l: clamp(1.75rem, calc(1.55rem + 0.98vw), 2.25rem);
+ --space-xl: clamp(2.63rem, calc(2.33rem + 1.46vw), 3.38rem);
+ --space-2xl: clamp(3.5rem, calc(3.11rem + 1.95vw), 4.5rem);
+ --space-3xl: clamp(5.25rem, calc(4.66rem + 2.93vw), 6.75rem);
+
+ /* One-up pairs */
+ --space-4xs-3xs: clamp(0.13rem, calc(0.05rem + 0.37vw), 0.31rem);
+ --space-3xs-2xs: clamp(0.25rem, calc(0.13rem + 0.61vw), 0.56rem);
+ --space-2xs-xs: clamp(0.44rem, calc(0.27rem + 0.85vw), 0.88rem);
+ --space-xs-s: clamp(0.69rem, calc(0.52rem + 0.85vw), 1.13rem);
+ --space-s-m: clamp(0.88rem, calc(0.56rem + 1.59vw), 1.69rem);
+ --space-m-l: clamp(1.31rem, calc(0.95rem + 1.83vw), 2.25rem);
+ --space-l-xl: clamp(1.75rem, calc(1.12rem + 3.17vw), 3.38rem);
+ --space-xl-2xl: clamp(2.63rem, calc(1.89rem + 3.66vw), 4.5rem);
+ --space-2xl-3xl: clamp(3.5rem, calc(2.23rem + 6.34vw), 6.75rem);
+
+ /* Custom pairs */
+ --space-s-l: clamp(0.88rem, calc(0.34rem + 2.68vw), 2.25rem);
+
+ color-scheme: light dark;
+ }
+
+ [data-color-scheme='light'] {
+ color-scheme: light;
+ }
+
+ [data-color-scheme='dark'] {
+ color-scheme: dark;
+ }
+
+ * {
+ box-sizing: border-box;
+ }
+
+ html,
+ body {
+ margin: 0;
+ scroll-behavior: smooth;
+ }
+
+ body {
+ background-color: var(--header-bg-color);
+ font-family: var(--font-body);
+ font-size: 16px;
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ }
+
+ h1,
+ h2,
+ h3,
+ h4 {
+ font-family: var(--font-heading);
+ }
+
+ h1 {
+ @media only screen and (max-width: 400px) {
+ font-size: 1.5em;
+ }
+ }
+
+ a,
+ .link,
+ .text--link {
+ color: var(--link-color);
+ text-decoration: none;
+ cursor: pointer;
+
+ &:hover {
+ color: var(--link-hover-color);
+ }
+ }
+
+ /* Using `:not(...)` here for specificity reasons */
+ a:not([href]) {
+ color: unset;
+ cursor: initial;
+ }
+
+ pre.terminal {
+ background: var(--main-color);
+ color: white;
+ padding: var(--space-s);
+ font-family: var(--font-monospace);
+ }
+
+ abbr[title] {
+ text-decoration: none;
+ border-bottom: 1px dotted;
+ }
+
+ noscript {
+ display: grid;
+ justify-items: center;
+ padding: var(--space-m);
+ color: white;
+ }
+
+ /* see https://github.com/twbs/bootstrap/pull/30269 */
+ ::-webkit-datetime-edit,
+ ::-webkit-datetime-edit-fields-wrapper,
+ ::-webkit-datetime-edit-text,
+ ::-webkit-datetime-edit-minute,
+ ::-webkit-datetime-edit-hour-field,
+ ::-webkit-datetime-edit-day-field,
+ ::-webkit-datetime-edit-month-field,
+ ::-webkit-datetime-edit-year-field {
+ padding: 0;
+ }
+
+ ::-webkit-calendar-picker-indicator {
+ font-size: 0.9em;
+ }
+
+ .c-notification__icon {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .c-notification__content {
+ line-height: 1.5;
+ }
+
+ .width-limit {
+ width: 960px;
+ @media only screen and (max-width: 960px) {
+ width: 100%;
+ }
+ }
+}
diff --git a/svelte/src/lib/css/normalize.css b/svelte/src/lib/css/normalize.css
new file mode 100644
index 00000000000..75f0e188c7f
--- /dev/null
+++ b/svelte/src/lib/css/normalize.css
@@ -0,0 +1,353 @@
+@layer global.normalize {
+ /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
+
+ /* Document
+ ========================================================================== */
+
+ /**
+ * 1. Correct the line height in all browsers.
+ * 2. Prevent adjustments of font size after orientation changes in iOS.
+ */
+
+ html {
+ line-height: 1.15; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+ }
+
+ /* Sections
+ ========================================================================== */
+
+ /**
+ * Remove the margin in all browsers.
+ */
+
+ body {
+ margin: 0;
+ }
+
+ /**
+ * Render the `main` element consistently in IE.
+ */
+
+ main {
+ display: block;
+ }
+
+ /**
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
+ */
+
+ h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+ }
+
+ /* Grouping content
+ ========================================================================== */
+
+ /**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+ hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+ }
+
+ /**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+ pre {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+ }
+
+ /* Text-level semantics
+ ========================================================================== */
+
+ /**
+ * Remove the gray background on active links in IE 10.
+ */
+
+ a {
+ background-color: transparent;
+ }
+
+ /**
+ * 1. Remove the bottom border in Chrome 57-
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+ */
+
+ abbr[title] {
+ border-bottom: none; /* 1 */
+ text-decoration: underline; /* 2 */
+ text-decoration: underline dotted; /* 2 */
+ }
+
+ /**
+ * Add the correct font weight in Chrome, Edge, and Safari.
+ */
+
+ b,
+ strong {
+ font-weight: bolder;
+ }
+
+ /**
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+ code,
+ kbd,
+ samp {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+ }
+
+ /**
+ * Add the correct font size in all browsers.
+ */
+
+ small {
+ font-size: 80%;
+ }
+
+ /**
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
+ */
+
+ sub,
+ sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+ }
+
+ sub {
+ bottom: -0.25em;
+ }
+
+ sup {
+ top: -0.5em;
+ }
+
+ /* Embedded content
+ ========================================================================== */
+
+ /**
+ * Remove the border on images inside links in IE 10.
+ */
+
+ img {
+ border-style: none;
+ }
+
+ /* Forms
+ ========================================================================== */
+
+ /**
+ * 1. Change the font styles in all browsers.
+ * 2. Remove the margin in Firefox and Safari.
+ */
+
+ button,
+ input,
+ optgroup,
+ select,
+ textarea {
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
+ }
+
+ /**
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
+ */
+
+ button,
+ input {
+ /* 1 */
+ overflow: visible;
+ }
+
+ /**
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
+ */
+
+ button,
+ select {
+ /* 1 */
+ text-transform: none;
+ }
+
+ /**
+ * Correct the inability to style clickable types in iOS and Safari.
+ */
+
+ button,
+ [type='button'],
+ [type='reset'],
+ [type='submit'] {
+ -webkit-appearance: button;
+ }
+
+ /**
+ * Remove the inner border and padding in Firefox.
+ */
+
+ button::-moz-focus-inner,
+ [type='button']::-moz-focus-inner,
+ [type='reset']::-moz-focus-inner,
+ [type='submit']::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+ }
+
+ /**
+ * Restore the focus styles unset by the previous rule.
+ */
+
+ button:-moz-focusring,
+ [type='button']:-moz-focusring,
+ [type='reset']:-moz-focusring,
+ [type='submit']:-moz-focusring {
+ outline: 1px dotted ButtonText;
+ }
+
+ /**
+ * Correct the padding in Firefox.
+ */
+
+ fieldset {
+ padding: 0.35em 0.75em 0.625em;
+ }
+
+ /**
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
+ */
+
+ legend {
+ box-sizing: border-box; /* 1 */
+ color: inherit; /* 2 */
+ display: table; /* 1 */
+ max-width: 100%; /* 1 */
+ padding: 0; /* 3 */
+ white-space: normal; /* 1 */
+ }
+
+ /**
+ * Add the correct vertical alignment in Chrome, Firefox, and Opera.
+ */
+
+ progress {
+ vertical-align: baseline;
+ }
+
+ /**
+ * Remove the default vertical scrollbar in IE 10+.
+ */
+
+ textarea {
+ overflow: auto;
+ }
+
+ /**
+ * 1. Add the correct box sizing in IE 10.
+ * 2. Remove the padding in IE 10.
+ */
+
+ [type='checkbox'],
+ [type='radio'] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+ }
+
+ /**
+ * Correct the cursor style of increment and decrement buttons in Chrome.
+ */
+
+ [type='number']::-webkit-inner-spin-button,
+ [type='number']::-webkit-outer-spin-button {
+ height: auto;
+ }
+
+ /**
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
+ */
+
+ [type='search'] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+ }
+
+ /**
+ * Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+ [type='search']::-webkit-search-decoration {
+ -webkit-appearance: none;
+ }
+
+ /**
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
+ */
+
+ ::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
+ }
+
+ /* Interactive
+ ========================================================================== */
+
+ /*
+ * Add the correct display in Edge, IE 10+, and Firefox.
+ */
+
+ details {
+ display: block;
+ }
+
+ /*
+ * Add the correct display in all browsers.
+ */
+
+ summary {
+ display: list-item;
+ }
+
+ /* Misc
+ ========================================================================== */
+
+ /**
+ * Add the correct display in IE 10+.
+ */
+
+ template {
+ display: none;
+ }
+
+ /**
+ * Add the correct display in IE 10.
+ */
+
+ [hidden] {
+ display: none;
+ }
+}
diff --git a/svelte/src/lib/css/shared/a11y.css b/svelte/src/lib/css/shared/a11y.css
new file mode 100644
index 00000000000..45142091f82
--- /dev/null
+++ b/svelte/src/lib/css/shared/a11y.css
@@ -0,0 +1,12 @@
+@layer global {
+ .sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border: 0;
+ }
+}
diff --git a/svelte/src/lib/css/shared/buttons.css b/svelte/src/lib/css/shared/buttons.css
new file mode 100644
index 00000000000..e91c8fb8d04
--- /dev/null
+++ b/svelte/src/lib/css/shared/buttons.css
@@ -0,0 +1,109 @@
+@layer global {
+ .button-reset {
+ padding: 0;
+ border: none;
+ outline: none;
+ font: inherit;
+ color: inherit;
+ background: none;
+ }
+
+ .button {
+ --text-color: #383838;
+ --disabled-text-color: #858585;
+
+ --bg-color-top: #fede9e;
+ --bg-color-bottom: #fdc452;
+
+ --bg-color-top-light: #fee7b7;
+ --bg-color-bottom-light: #fdcd6b;
+
+ --bg-color-top-dark: #fed585;
+ --bg-color-bottom-dark: #fdbb39;
+
+ padding: var(--space-xs) var(--space-m-l);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--text-color);
+ text-decoration: none;
+ font-weight: bold;
+ border: none;
+ outline: 0;
+ border-radius: 5000px;
+ background: linear-gradient(to bottom, var(--bg-color-top) 0%, var(--bg-color-bottom) 100%);
+ cursor: pointer;
+
+ &:hover,
+ &:active,
+ &:visited {
+ /*
+ * This is using `important` to override the `a:hover` declaration which
+ * appears to have higher specificity than the `button:hover` declaration.
+ */
+ color: var(--text-color) !important;
+ }
+
+ img,
+ svg {
+ float: left;
+ display: inline-block;
+ margin-right: var(--space-2xs);
+ }
+
+ &:hover,
+ &:focus,
+ &.active {
+ background: linear-gradient(to bottom, var(--bg-color-top-dark) 0%, var(--bg-color-bottom-dark) 100%);
+ outline: 0;
+ }
+
+ &[disabled] {
+ background: linear-gradient(to bottom, var(--bg-color-top-light) 0%, var(--bg-color-bottom-light) 100%);
+ color: var(--disabled-text-color) !important;
+ cursor: not-allowed;
+ }
+ }
+
+ .button--tan {
+ --bg-color-top: #e8e3c7;
+ --bg-color-bottom: #d6cd99;
+
+ --bg-color-top-light: #efecd9;
+ --bg-color-bottom-light: #ddd6ab;
+
+ --bg-color-top-dark: #e1dab5;
+ --bg-color-bottom-dark: #cfc487;
+ }
+
+ .button--red {
+ --bg-color-top: #ffb8b8;
+ --bg-color-bottom: #f78888;
+
+ --bg-color-top-light: #ffcccc;
+ --bg-color-bottom-light: #f7adad;
+
+ --bg-color-top-dark: #fab4b4;
+ --bg-color-bottom-dark: #ed6b6b;
+ }
+
+ .button--small {
+ padding: var(--space-2xs) var(--space-s);
+ }
+
+ .load-more-button {
+ display: block;
+ text-align: center;
+ width: 100%;
+ padding: var(--space-2xs);
+ outline: 0;
+ border: 0;
+ background-color: light-dark(#dbd9cf, #202023);
+ color: light-dark(#525252, #f9f7ec);
+
+ &:hover,
+ &:focus {
+ background-color: light-dark(#c5c2b2, #26262b);
+ }
+ }
+}
diff --git a/svelte/src/lib/css/shared/forms.css b/svelte/src/lib/css/shared/forms.css
new file mode 100644
index 00000000000..e3ffe21be01
--- /dev/null
+++ b/svelte/src/lib/css/shared/forms.css
@@ -0,0 +1,27 @@
+@layer global {
+ .form-group-name {
+ display: flex;
+ gap: var(--space-2xs);
+ margin-bottom: var(--space-2xs);
+ font-weight: 600;
+ }
+
+ .form-group-error {
+ display: block;
+ color: red;
+ font-size: 0.9em;
+ margin-top: var(--space-2xs);
+ }
+
+ .base-input {
+ padding: var(--space-2xs);
+ background-color: light-dark(white, #141413);
+ border: 1px solid var(--gray-border);
+ border-radius: var(--space-3xs);
+
+ &[aria-invalid='true'] {
+ background: light-dark(#fff2f2, #170808);
+ border-color: red;
+ }
+ }
+}
diff --git a/svelte/src/lib/css/shared/sort-by.css b/svelte/src/lib/css/shared/sort-by.css
new file mode 100644
index 00000000000..71a1bb0f4a3
--- /dev/null
+++ b/svelte/src/lib/css/shared/sort-by.css
@@ -0,0 +1,9 @@
+@layer global {
+ .sort-by-v-center {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+
+ gap: 5px;
+ }
+}
diff --git a/svelte/src/lib/css/shared/typography.css b/svelte/src/lib/css/shared/typography.css
new file mode 100644
index 00000000000..0203d97e80d
--- /dev/null
+++ b/svelte/src/lib/css/shared/typography.css
@@ -0,0 +1,24 @@
+@layer global {
+ .small,
+ .text--small {
+ color: var(--main-color-light);
+ font-size: 80%;
+
+ strong {
+ color: var(--main-color);
+ }
+ }
+
+ .small a,
+ .text--small a,
+ a.small,
+ a.text--small {
+ color: var(--main-color-light);
+ text-decoration: underline;
+ font-weight: normal;
+
+ &:hover {
+ color: #6b6b6b;
+ }
+ }
+}
diff --git a/svelte/src/routes/+layout.svelte b/svelte/src/routes/+layout.svelte
index cba194029ea..422b46f4990 100644
--- a/svelte/src/routes/+layout.svelte
+++ b/svelte/src/routes/+layout.svelte
@@ -1,11 +1,55 @@
+ crates.io: Rust Package Registry
-{@render children()}
+
+
+
+
+
+
+
+
+
+ {@render children()}
+
+
+
+
+
+