diff --git a/app/components/color-scheme-menu.hbs b/app/components/color-scheme-menu.hbs new file mode 100644 index 00000000000..002de8ade75 --- /dev/null +++ b/app/components/color-scheme-menu.hbs @@ -0,0 +1,20 @@ + + + {{svg-jar this.icon local-class="icon"}} + Change color scheme + + + + {{#each this.colorSchemes as |colorScheme|}} + + + + {{/each}} + + \ No newline at end of file diff --git a/app/components/color-scheme-menu.js b/app/components/color-scheme-menu.js new file mode 100644 index 00000000000..f17c66b5fcc --- /dev/null +++ b/app/components/color-scheme-menu.js @@ -0,0 +1,17 @@ +import { inject as service } from '@ember/service'; +import Component from '@glimmer/component'; + +export default class Header extends Component { + /** @type {import("../services/dark-mode").default} */ + @service colorScheme; + + colorSchemes = [ + { mode: 'light', svg: 'sun' }, + { mode: 'dark', svg: 'moon' }, + { mode: 'system', svg: 'color-mode' }, + ]; + + get icon() { + return this.colorSchemes.find(({ mode }) => mode === this.colorScheme.scheme)?.svg; + } +} diff --git a/app/components/color-scheme-menu.module.css b/app/components/color-scheme-menu.module.css new file mode 100644 index 00000000000..17193debea1 --- /dev/null +++ b/app/components/color-scheme-menu.module.css @@ -0,0 +1,35 @@ +.dropdown { + line-height: 1rem; +} + +.icon { + width: 1.4em; + height: auto; +} + +.trigger { + background: none; + border: 0; + padding: 0; +} + +.trigger-label { + composes: sr-only from '../styles/shared/a11y.module.css' +} + +.menu { + right: 0; + min-width: max-content; +} + +.menu-button { + composes: button-reset from '../styles/shared/buttons.module.css'; + align-items: center; + gap: var(--space-2xs); + cursor: pointer; + text-transform: capitalize; +} + +.selected { + background: light-dark(#e6e6e6, #404040); +} diff --git a/app/components/crate-downloads-list.module.css b/app/components/crate-downloads-list.module.css index fc2fcfbabea..688262076ba 100644 --- a/app/components/crate-downloads-list.module.css +++ b/app/components/crate-downloads-list.module.css @@ -9,8 +9,8 @@ } .link { - color: #525252; - background-color: #edebdd; + color: light-dark(#525252, #999999); + background-color: light-dark(#edebdd, #141413); font-size: 90%; padding: var(--space-s) var(--space-xs); display: flex; diff --git a/app/components/crate-row.module.css b/app/components/crate-row.module.css index 6c12e24fe54..26973115cd2 100644 --- a/app/components/crate-row.module.css +++ b/app/components/crate-row.module.css @@ -1,10 +1,10 @@ .crate-row { - --shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + --shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); display: flex; flex-wrap: wrap; padding: var(--space-s-m) var(--space-m-l); - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); box-shadow: var(--shadow); } @@ -77,6 +77,10 @@ width: calc(1em + 20px); margin: -10px; margin-right: calc(var(--space-xs) - 10px); + + circle { + fill: none; + } } } } diff --git a/app/components/crate-sidebar.module.css b/app/components/crate-sidebar.module.css index d8e094591f7..3fc9311e8bc 100644 --- a/app/components/crate-sidebar.module.css +++ b/app/components/crate-sidebar.module.css @@ -81,7 +81,7 @@ cursor: pointer; &:hover { - background-color: white; + background-color: light-dark(white, #141413); } } diff --git a/app/components/dependency-list/row.module.css b/app/components/dependency-list/row.module.css index c7931c1a678..1ec9334eadf 100644 --- a/app/components/dependency-list/row.module.css +++ b/app/components/dependency-list/row.module.css @@ -1,17 +1,17 @@ .row { --bg-color: var(--grey200); - --hover-bg-color: hsl(217, 37%, 98%); - --range-color: var(--grey900); - --crate-color: var(--grey700); + --hover-bg-color: light-dark(hsl(217, 37%, 98%), hsl(204, 3%, 11%)); + --range-color: light-dark(var(--grey900), #d1cfc7); + --crate-color: light-dark(var(--grey700), #d1cfc7); --placeholder-opacity: 0.35; - --shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + --shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); display: flex; align-items: center; position: relative; font-size: 18px; padding: var(--space-s) var(--space-m); - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); box-shadow: var(--shadow); transition: all var(--transition-slow); @@ -26,8 +26,8 @@ } &.optional { - --range-color: var(--grey600); - --crate-color: var(--grey600); + --range-color: light-dark(var(--grey600), var(--grey600)); + --crate-color: light-dark(var(--grey600), var(--grey600)); --placeholder-opacity: 0.15; } diff --git a/app/components/dropdown/menu.module.css b/app/components/dropdown/menu.module.css index 2993241459a..8fd1824547d 100644 --- a/app/components/dropdown/menu.module.css +++ b/app/components/dropdown/menu.module.css @@ -2,7 +2,7 @@ margin: 0; text-align: left; padding: 0; - background: white; + background: light-dark(white, #141413); border: 1px solid var(--gray-border); list-style: none; overflow: hidden; diff --git a/app/components/dropdown/trigger.hbs b/app/components/dropdown/trigger.hbs index cfd4bc0dc56..7ef3ae43ea7 100644 --- a/app/components/dropdown/trigger.hbs +++ b/app/components/dropdown/trigger.hbs @@ -1,4 +1,6 @@ \ No newline at end of file diff --git a/app/components/front-page-list/item.module.css b/app/components/front-page-list/item.module.css index 3b6484318b4..39ad765d89d 100644 --- a/app/components/front-page-list/item.module.css +++ b/app/components/front-page-list/item.module.css @@ -1,13 +1,13 @@ .link { - --shadow: 0 2px 3px hsla(51, 50%, 44%, .35); + --shadow: 0 2px 3px light-dark(hsla(51, 50%, 44%, .35), #232321); display: flex; align-items: center; width: 100%; height: var(--space-2xl); padding: 0 var(--space-s); - background-color: white; - color: #525252; + background-color: light-dark(white, #141413); + color: light-dark(#525252, #f9f7ec); text-decoration: none; border-radius: var(--space-3xs); box-shadow: var(--shadow); @@ -19,8 +19,8 @@ } &:hover, &:focus-visible { - color: #525252; - background-color: hsl(58deg 72% 97%); + color: light-dark(#525252, #f9f7ec); + background-color: light-dark(hsl(58deg 72% 97%), hsl(204, 3%, 11%)); transition: background-color var(--transition-instant); } @@ -48,7 +48,7 @@ .subtitle { margin-top: var(--space-3xs); font-size: 13px; - color: rgb(118, 131, 138); + color: light-dark(rgb(118, 131, 138), #cccac2); } .right { @@ -56,5 +56,5 @@ height: var(--space-s); width: auto; margin-left: var(--space-xs); - color: rgb(118, 131, 138); + color: light-dark(rgb(118, 131, 138), #cccac2); } diff --git a/app/components/front-page-list/item/placeholder.module.css b/app/components/front-page-list/item/placeholder.module.css index 7be83a33b3c..68df7e14b7a 100644 --- a/app/components/front-page-list/item/placeholder.module.css +++ b/app/components/front-page-list/item/placeholder.module.css @@ -1,17 +1,17 @@ .link { - --shadow: 0 2px 3px hsla(51, 50%, 44%, .35); - --placeholder-bg: hsla(59, 19%, 50%, 1.0); - --placeholder-bg2: hsla(59, 19%, 50%, 0.7); + --shadow: 0 2px 3px light-dark(hsla(51, 50%, 44%, .35), #232321); + --placeholder-bg: light-dark(hsla(59, 19%, 50%, 1.0), hsl(60, 14%, 85%)); + --placeholder-bg2: light-dark(hsla(59, 19%, 50%, 0.7), hsla(59, 5%, 50%, 0.7)); display: flex; align-items: center; width: 100%; - height: 60px; + height: var(--space-2xl); margin: 8px 0; - padding: 0 15px; - background-color: white; - color: #525252; - border-radius: 5px; + padding: 0 var(--space-s); + background-color: light-dark(white, #141413); + color: light-dark(#525252, #f9f7ec); + border-radius: var(--space-3xs); box-shadow: var(--shadow); cursor: wait; } @@ -31,15 +31,15 @@ .subtitle { height: 13px; width: 90px; - margin-top: 4px; + margin-top: var(--space-3xs); border-radius: 6.5px; opacity: 0.2; } .right { flex-shrink: 0; - height: 16px; + height: var(--space-s); width: auto; - margin-left: 10px; - color: rgb(118, 131, 138); + margin-left: var(--space-xs); + color: light-dark(rgb(118, 131, 138), #cccac2); } diff --git a/app/components/header.hbs b/app/components/header.hbs index 1f0097bc72d..c2307c6acdf 100644 --- a/app/components/header.hbs +++ b/app/components/header.hbs @@ -14,6 +14,8 @@
+ + Menu diff --git a/app/components/header.module.css b/app/components/header.module.css index 505e04a0f25..c2cbaaba747 100644 --- a/app/components/header.module.css +++ b/app/components/header.module.css @@ -101,7 +101,7 @@ .nav { grid-area: nav; display: flex; - align-items: stretch; + align-items: center; justify-self: end; @media only screen and (max-width: 900px) { @@ -115,7 +115,8 @@ display: none; @media only screen and (max-width: 900px) { - display: block; + display: flex; + align-items: center; } } @@ -123,6 +124,10 @@ border-top: 1px solid var(--gray-border); } +.color-scheme-menu { + margin-right: var(--space-xs); +} + .login-button { composes: button-reset from '../styles/shared/buttons.module.css'; display: inline-flex; diff --git a/app/components/pagination.module.css b/app/components/pagination.module.css index 7777a0853ff..f71a1f1f4f8 100644 --- a/app/components/pagination.module.css +++ b/app/components/pagination.module.css @@ -23,6 +23,23 @@ img, svg { vertical-align: middle; } + + .prev, .next { + circle { + fill: none; + } + + path { + fill: currentColor; + } + + &:hover { + circle { + fill: var(--main-bg-dark); + } + } + } + .next:global(.active), .prev:global(.active), .next:hover, diff --git a/app/components/rev-dep-row.module.css b/app/components/rev-dep-row.module.css index 046a114adaf..9619fc516b1 100644 --- a/app/components/rev-dep-row.module.css +++ b/app/components/rev-dep-row.module.css @@ -1,13 +1,13 @@ .row { - --hover-bg-color: hsl(217, 37%, 98%); - --crate-color: var(--grey700); + --hover-bg-color: light-dark(hsl(217, 37%, 98%), hsl(204, 3%, 11%)); + --crate-color: light-dark(var(--grey700), var(--grey600)); --placeholder-opacity: 0.35; - --shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + --shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); position: relative; font-size: 18px; padding: var(--space-s) var(--space-m); - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); box-shadow: var(--shadow); transition: all var(--transition-slow); diff --git a/app/components/search-form.module.css b/app/components/search-form.module.css index 078e7bae6bc..c88dbb49ff8 100644 --- a/app/components/search-form.module.css +++ b/app/components/search-form.module.css @@ -25,11 +25,12 @@ --search-form-focus-shadow: 0 0 0 var(--space-3xs) var(--yellow500); border: none; - color: black; + color: light-dark(black, var(--main-color)); + background: light-dark(white, hsl(0, 1%, 19%)); width: 100%; padding: var(--input-padding) var(--input-padding-right) var(--input-padding) var(--input-padding-left); border-radius: var(--border-radius); - box-shadow: 1px 2px 4px 0 var(--green900); + box-shadow: 1px 2px 4px 0 light-dark(var(--green900), hsl(111, 10%, 8%)); transition: box-shadow var(--transition-fast); &:focus { diff --git a/app/components/settings/api-tokens.module.css b/app/components/settings/api-tokens.module.css index 19025919ff7..311ec4923d2 100644 --- a/app/components/settings/api-tokens.module.css +++ b/app/components/settings/api-tokens.module.css @@ -22,15 +22,15 @@ padding: 0; list-style: none; border-radius: var(--space-3xs); - background-color: white; - box-shadow: 0 2px 3px hsla(51, 50%, 44%, .35); + background-color: light-dark(white, #141413); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); > * { padding: var(--space-m); } > * + * { - border-top: 1px solid #f1f0ed; + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #424242); } } @@ -102,7 +102,7 @@ grid-template-columns: 1fr auto; align-items: center; background: var(--main-color); - color: white; + color: light-dark(white, #141413); font-family: var(--font-monospace); border-radius: var(--space-3xs); margin-top: var(--space-xs); @@ -120,7 +120,7 @@ cursor: pointer; &:hover { - color: #ddd8b2; + color: light-dark(#ddd8b2, #65655e); } } @@ -139,10 +139,10 @@ align-content: center; margin: var(--space-m) 0; padding: var(--space-xl-2xl); - border: 2px black dashed; + border: 2px light-dark(black, white) dashed; border-radius: var(--space-3xs); - background-color: white; - box-shadow: 0 2px 3px hsla(51, 50%, 44%, .35); + background-color: light-dark(white, #141413); + box-shadow: 0 2px 3px light-dark(hsla(51, 50%, 45%, .35), #232321); } .empty-state-label { diff --git a/app/components/side-menu/item.module.css b/app/components/side-menu/item.module.css index 8229b3db974..01f2b24b154 100644 --- a/app/components/side-menu/item.module.css +++ b/app/components/side-menu/item.module.css @@ -17,6 +17,6 @@ color: var(--main-color); &:hover { - background-color: #e5e1cd; + background-color: light-dark(#e5e1cd, #262522); } } diff --git a/app/components/text-content.module.css b/app/components/text-content.module.css index 4e272d61477..9ca75d08f3f 100644 --- a/app/components/text-content.module.css +++ b/app/components/text-content.module.css @@ -1,6 +1,6 @@ .boxed { padding: var(--space-m); - background-color: white; + background-color: light-dark(white, #141413); margin-bottom: var(--space-s); border-radius: 5px; } @@ -25,7 +25,7 @@ display: block; overflow-x: auto; padding: var(--space-xs); - background-color: #f6f8fa; + background-color: light-dark(#f6f8fa, #161b22); font-size: 85%; border-radius: var(--space-3xs); } @@ -40,7 +40,7 @@ p, li { code { - background-color: #f6f8fa; + background-color: light-dark(#f6f8fa, #383836); border-radius: var(--space-3xs); font-size: 85%; margin: 0; diff --git a/app/components/version-list/row.module.css b/app/components/version-list/row.module.css index fee370120d0..c088ffc29e2 100644 --- a/app/components/version-list/row.module.css +++ b/app/components/version-list/row.module.css @@ -1,15 +1,15 @@ .row { - --bg-color: var(--grey200); - --hover-bg-color: hsl(217, 37%, 98%); - --fg-color: var(--grey700); - --shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + --bg-color: light-dark(var(--grey200), #242422); + --hover-bg-color: light-dark(hsl(217, 37%, 98%), hsl(204, 3%, 11%)); + --fg-color: light-dark(var(--grey700), #ccc); + --shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); display: flex; align-items: center; position: relative; font-size: 18px; padding: var(--space-s) var(--space-m); - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); box-shadow: var(--shadow); transition: all var(--transition-slow); @@ -24,21 +24,21 @@ } &.latest { - --bg-color: hsl(109, 75%, 87%); - --hover-bg-color: hsl(109, 75%, 97%); - --fg-color: hsl(136, 67%, 38%); + --bg-color: light-dark(hsl(109, 75%, 87%), hsl(136, 67%, 11%)); + --hover-bg-color: light-dark(hsl(109, 75%, 97%), hsl(109, 10%, 11%)); + --fg-color: light-dark(hsl(136, 67%, 38%), hsl(109, 75%, 87%)); } &.prerelease { - --bg-color: hsl(39, 100%, 91%); - --hover-bg-color: hsl(39, 100%, 97%); - --fg-color: hsl(39, 71%, 45%); + --bg-color: light-dark(hsl(39, 100%, 91%), hsl(39, 71%, 15%)); + --hover-bg-color: light-dark(hsl(39, 100%, 97%), hsl(39, 10%, 11%)); + --fg-color: light-dark(hsl(39, 71%, 45%), hsl(39, 100%, 91%)); } &.yanked { - --bg-color: hsl(0, 92%, 90%); - --hover-bg-color: hsl(0, 92%, 98%); - --fg-color: hsl(0, 84%, 32%); + --bg-color: light-dark(hsl(0, 92%, 90%), hsl(0, 84%, 12%)); + --hover-bg-color: light-dark(hsl(0, 92%, 98%), hsl(0, 10%, 11%)); + --fg-color: light-dark(hsl(0, 84%, 32%), hsl(0, 92%, 90%)); } [title], :global(.ember-tooltip-target) { @@ -75,7 +75,7 @@ font-variant-numeric: tabular-nums; color: var(--fg-color); background-color: var(--bg-color); - border: 1px solid white; + border: 1px solid light-dark(white, #808080); border-radius: 50%; transition: all var(--transition-fast); @@ -85,8 +85,8 @@ } .row:hover &, .row.focused & { - border: var(--space-4xs) solid white; - box-shadow: 0 1px 3px var(--fg-color); + border: var(--space-4xs) solid light-dark(white, #bfbfbf); + box-shadow: 0 1px 3px light-dark(var(--fg-color), #232321); } @media only screen and (max-width: 550px) { @@ -132,17 +132,17 @@ .metadata { flex-grow: 1; margin-left: var(--space-m); - color: var(--grey600); + color: light-dark(var(--grey600), #d1cfc7); text-transform: uppercase; letter-spacing: .7px; font-size: 13px; a { position: relative; - color: var(--grey600); + color: inherit; &:hover { - color: var(--grey900); + color: light-dark(var(--grey900), #f5f3e9); } &:focus-visible { diff --git a/app/controllers/application.js b/app/controllers/application.js index bf6bc99be8c..5fe55b29330 100644 --- a/app/controllers/application.js +++ b/app/controllers/application.js @@ -2,6 +2,7 @@ import Controller from '@ember/controller'; import { inject as service } from '@ember/service'; export default class ApplicationController extends Controller { + @service colorScheme; @service design; @service progress; @service router; diff --git a/app/helpers/set-color-scheme.js b/app/helpers/set-color-scheme.js new file mode 100644 index 00000000000..a5580d258b7 --- /dev/null +++ b/app/helpers/set-color-scheme.js @@ -0,0 +1,9 @@ +import { helper } from '@ember/component/helper'; + +export default helper(function ([mode]) { + if (mode) { + window.document.documentElement.dataset.colorScheme = mode; + } else { + delete window.document.documentElement.dataset.colorScheme; + } +}); diff --git a/app/services/color-scheme.js b/app/services/color-scheme.js new file mode 100644 index 00000000000..4a7fbcf4419 --- /dev/null +++ b/app/services/color-scheme.js @@ -0,0 +1,22 @@ +import { action } from '@ember/object'; +import Service from '@ember/service'; +import { tracked } from '@glimmer/tracking'; + +import * as localStorage from '../utils/local-storage'; + +const DEFAULT_SCHEME = 'light'; +const VALID_SCHEMES = new Set(['light', 'dark', 'system']); +const LS_KEY = 'color-scheme'; + +export default class DesignService extends Service { + @tracked _scheme = localStorage.getItem(LS_KEY); + + get scheme() { + return VALID_SCHEMES.has(this._scheme) ? this._scheme : DEFAULT_SCHEME; + } + + @action set(scheme) { + this._scheme = scheme; + localStorage.setItem(LS_KEY, scheme); + } +} diff --git a/app/styles/application.module.css b/app/styles/application.module.css index 1fd2a66f7ad..156ebb949b9 100644 --- a/app/styles/application.module.css +++ b/app/styles/application.module.css @@ -21,7 +21,7 @@ --yellow500: hsl(44, 100%, 60%); --yellow700: hsl(44, 67%, 50%); - --header-bg-color: hsl(115, 31%, 20%); + --header-bg-color: light-dark(hsl(115, 31%, 20%), #141413); --transition-x-slow: 1000ms; --transition-slow: 500ms; @@ -35,12 +35,12 @@ --font-monospace: "Fira Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - --main-color: #383838; - --main-color-light: #858585; - --main-shadow-color: var(--green900); - --main-bg: #f9f7ec; - --main-bg-dark: #edebdd; - --gray-border: #d5d3cb; + --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: rgb(0, 172, 91); --link-hover-color: #007940; @@ -73,6 +73,16 @@ /* 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; } [data-theme="new-design"] { diff --git a/app/styles/categories.module.css b/app/styles/categories.module.css index b0fa67e4aca..0015886cd8b 100644 --- a/app/styles/categories.module.css +++ b/app/styles/categories.module.css @@ -16,9 +16,9 @@ } .list { - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); margin-bottom: var(--space-s); > * { @@ -26,7 +26,7 @@ } > * + * { - border-top: 1px solid hsla(51, 90%, 42%, .25); + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #424242); } } diff --git a/app/styles/category/index.module.css b/app/styles/category/index.module.css index 38005284293..4de585ec0c6 100644 --- a/app/styles/category/index.module.css +++ b/app/styles/category/index.module.css @@ -8,9 +8,9 @@ } .subcategories { - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); margin-bottom: var(--space-s); > * { @@ -18,7 +18,7 @@ } > * + * { - border-top: 1px solid hsla(51, 90%, 42%, .25); + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #424242); } } diff --git a/app/styles/crate/settings.module.css b/app/styles/crate/settings.module.css index 870400b5ce5..3d1d9917316 100644 --- a/app/styles/crate/settings.module.css +++ b/app/styles/crate/settings.module.css @@ -5,9 +5,9 @@ flex-wrap: wrap; gap: var(--space-s); padding: var(--space-s) var(--space-m); - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); } .email-input-label { @@ -23,9 +23,9 @@ } .list { - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); > * { padding: var(--space-s) var(--space-m); @@ -36,7 +36,7 @@ } > * + * { - border-top: 1px solid hsla(51, 90%, 42%, .25); + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #232321); } } diff --git a/app/styles/crate/version.module.css b/app/styles/crate/version.module.css index ba979a5f5e4..ad77dee357e 100644 --- a/app/styles/crate/version.module.css +++ b/app/styles/crate/version.module.css @@ -6,11 +6,11 @@ } .docs { - --shadow: 0 2px 3px hsla(51, 50%, 44%, .35); + --shadow: 0 2px 3px light-dark(hsla(51, 50%, 44%, .35), #232321); margin-bottom: var(--space-l); padding: var(--space-m) var(--space-l); - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); box-shadow: var(--shadow); diff --git a/app/styles/dashboard.module.css b/app/styles/dashboard.module.css index e3ac7371d87..ae6306159b8 100644 --- a/app/styles/dashboard.module.css +++ b/app/styles/dashboard.module.css @@ -89,9 +89,9 @@ } .feed { - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); margin: var(--space-s) 0; } @@ -107,7 +107,7 @@ } > * + * { - border-top: 1px solid hsla(51, 90%, 42%, .25); + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #232321); } } @@ -123,7 +123,7 @@ .load-more { padding: var(--space-s); - border-top: 1px solid hsla(51, 90%, 42%, .25); + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #232321); button { display: block; @@ -132,11 +132,11 @@ padding: var(--space-2xs); outline: 0; border: 0; - background-color: #dbd9cf; + background-color: light-dark(#dbd9cf, #202023); color: white; &:hover, &:focus { - background-color: #c5c2b2; + background-color: light-dark(#c5c2b2, #26262b); } } } diff --git a/app/styles/keywords.module.css b/app/styles/keywords.module.css index 00c5d9b70a4..9aac61330f8 100644 --- a/app/styles/keywords.module.css +++ b/app/styles/keywords.module.css @@ -14,9 +14,9 @@ } .list { - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); margin-bottom: var(--space-s); > * { @@ -24,7 +24,7 @@ } > * + * { - border-top: 1px solid hsla(51, 90%, 42%, .25); + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #424242); } } diff --git a/app/styles/me/pending-invites.module.css b/app/styles/me/pending-invites.module.css index 9e78660a3fe..678507eaee8 100644 --- a/app/styles/me/pending-invites.module.css +++ b/app/styles/me/pending-invites.module.css @@ -1,7 +1,7 @@ .list { - background-color: white; + background-color: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 1px 3px hsla(51, 90%, 42%, .35); + box-shadow: 0 1px 3px light-dark(hsla(51, 90%, 42%, .35), #232321); margin-bottom: var(--space-s); > * { @@ -9,6 +9,6 @@ } > * + * { - border-top: 1px solid hsla(51, 90%, 42%, .25); + border-top: 1px solid light-dark(hsla(51, 90%, 42%, .25), #232321); } } diff --git a/app/styles/settings/appearance.module.css b/app/styles/settings/appearance.module.css index 6edbb804e60..13c6304ec47 100644 --- a/app/styles/settings/appearance.module.css +++ b/app/styles/settings/appearance.module.css @@ -7,9 +7,9 @@ .theme-label { display: inline-block; padding: var(--space-s); - background: white; + background: light-dark(white, #141413); border-radius: var(--space-3xs); - box-shadow: 0 2px 3px hsla(51, 50%, 44%, .35); + box-shadow: 0 2px 3px light-dark(hsla(51, 50%, 44%, .35), #232321); } .theme-preview { diff --git a/app/styles/settings/tokens/new.module.css b/app/styles/settings/tokens/new.module.css index 0eaf64e2d76..c4f4bcc8ff4 100644 --- a/app/styles/settings/tokens/new.module.css +++ b/app/styles/settings/tokens/new.module.css @@ -12,12 +12,12 @@ .help-link { flex-shrink: 0; - color: var(--grey600); + color: light-dark(var(--grey600), var(--grey700)); padding: var(--space-3xs); margin: calc(-1 * var(--space-3xs)); &:hover { - color: var(--grey700); + color: light-dark(var(--grey700), var(--grey600)); } svg { @@ -45,12 +45,12 @@ .base-input { padding: var(--space-2xs); - background-color: white; + background-color: light-dark(white, #141413); border: 1px solid var(--gray-border); border-radius: var(--space-3xs); &[aria-invalid="true"] { - background: #fff2f2; + background: light-dark(#fff2f2, #170808); border-color: red; } } @@ -86,12 +86,12 @@ list-style: none; padding: 0; margin: 0; - background-color: white; + background-color: light-dark(white, #141413); border: 1px solid var(--gray-border); border-radius: var(--space-3xs); &.invalid { - background: #fff2f2; + background: light-dark(#fff2f2, #170808); border-color: red; } @@ -123,7 +123,7 @@ list-style: none; padding: 0; margin: 0; - background-color: white; + background-color: light-dark(white, #141413); border: 1px solid var(--gray-border); border-radius: var(--space-3xs); @@ -157,7 +157,7 @@ } &.invalid input { - background: #fff2f2; + background: light-dark(#fff2f2, #170808); border-color: red; } @@ -173,8 +173,8 @@ align-items: center; &:hover { - background: var(--grey200); - color: var(--grey900); + background: light-dark(var(--grey200), #333333); + color: light-dark(var(--grey900), white); } svg { @@ -213,7 +213,7 @@ font-weight: bold; &:hover { - background: var(--grey200); + background: light-dark(var(--grey200), #333333); } } diff --git a/app/templates/application.hbs b/app/templates/application.hbs index e31664b969b..edd06ee43c7 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -2,6 +2,7 @@ {{page-title "crates.io: Rust Package Registry" separator=' - ' prepend=true}} {{set-theme this.design.theme}} +{{set-color-scheme this.colorScheme.scheme}} diff --git a/public/assets/color-mode.svg b/public/assets/color-mode.svg new file mode 100644 index 00000000000..27ea96a99f6 --- /dev/null +++ b/public/assets/color-mode.svg @@ -0,0 +1 @@ + diff --git a/public/assets/moon.svg b/public/assets/moon.svg new file mode 100644 index 00000000000..e01a7f40265 --- /dev/null +++ b/public/assets/moon.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/sun.svg b/public/assets/sun.svg new file mode 100644 index 00000000000..6c72f4cfada --- /dev/null +++ b/public/assets/sun.svg @@ -0,0 +1,3 @@ + + +