diff --git a/assets/sass/_vars.scss b/assets/sass/_vars.scss deleted file mode 100644 index 19e7e2f..0000000 --- a/assets/sass/_vars.scss +++ /dev/null @@ -1,33 +0,0 @@ -$primary: darken(#242b33, 2%); -$primaryForeground: #f0f0f0; -$secondary: lighten(#842cff, 10%); -$secondaryForeground: $primaryForeground; - -$backgroundColor: darken($primary, 4%); -$defaultTextColor: #ffffff; - -$headerBackground: transparent; -$headerContainer: true; -$footerBackground: transparent; -$panelBackground: darken($backgroundColor, 3.2%); -$inputBackground: darken($panelBackground, 4%); - -$info: #4499ff; -$infoText: darken($info, 42%); -$infoColor: desaturate($infoText, 50%); - -$success: #55ff55; -$successText: darken($success, 45%); -$successColor: desaturate($successText, 50%); - -$warning: #ffcc00; -$warningText: darken($warning, 30%); -$warningColor: desaturate($warningText, 50%); - -$error: #ff0000; -$errorText: darken($error, 30%); -$errorColor: desaturate($errorText, 50%); - -// Responsivity -$mobileThreshold: 850px; -$desktopThreshold: 940px; diff --git a/assets/sass/app.scss b/assets/sass/app.scss deleted file mode 100644 index 2721699..0000000 --- a/assets/sass/app.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import "layout"; -@import "fm"; - -.file-upload-table { - @media (max-width: 550px) { - > thead > tr > th:nth-child(3), - > tbody > tr > td:nth-child(3) { - display: none; - } - } - - @media (max-width: 785px) { - > thead > tr > th:nth-child(4), - > tbody > tr > td:nth-child(4) { - display: none; - } - } -} diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss deleted file mode 100644 index e489bdf..0000000 --- a/assets/sass/layout.scss +++ /dev/null @@ -1,977 +0,0 @@ -@import "vars"; -@import 'fonts'; -@import "responsivity_tools"; - -* { - box-sizing: border-box; -} - -html, body { - height: 100%; -} - -body { - display: flex; - flex-direction: column; - - margin: 0; - font-family: "Nunito Sans", sans-serif; - font-size: 16px; - - color: $defaultTextColor; - background-color: $backgroundColor; -} - -@mixin tip { - position: relative; - - .tip { - visibility: hidden; - position: absolute; - z-index: 10000; - pointer-events: none; - display: block; - width: max-content; - height: 30px; - padding: 4px 8px; - line-height: 22px; - top: calc(100% + 8px); - left: 50%; - transform: translateX(-50%); - - text-align: center; - font-size: 18px; - color: $defaultTextColor; - opacity: 0; - transition: opacity ease-out 100ms, visibility step-end 150ms; - transition-delay: 0ms; - background-color: #000; - border-radius: 5px; - - text-transform: initial; - font-weight: initial; - - &.top { - top: auto; - bottom: calc(100% + 8px); - } - } - - &:hover, &:active { - .tip { - visibility: visible; - opacity: 1; - transition: opacity ease-out 100ms; - transition-delay: 150ms; - } - } -} - -body > header { - z-index: 50; - display: flex; - flex-direction: row-reverse; - justify-content: space-between; - align-items: center; - - $headerHeight: 64px; - height: $headerHeight; - line-height: $headerHeight; - - background: $headerBackground; - - @if $headerContainer { - @include container; - } - - @media (max-width: $mobileThreshold) { - padding: 0; - } - - .logo { - display: flex; - flex-direction: row; - align-items: center; - - padding: 0 16px 0 8px; - font-size: 24px; - color: $defaultTextColor; - - &:hover { - color: lighten($defaultTextColor, 10%); - } - - img { - width: initial; - height: calc(#{$headerHeight} - 16px); - margin-right: 8px; - flex-shrink: 0; - } - } - - nav { - > ul { - position: fixed; - z-index: -1; - top: 0; - left: 0; - height: 100%; - transform: translateX(-100%); - transition: transform ease-out 150ms; - - display: flex; - flex-direction: column; - margin: 0; - padding: $headerHeight 8px 8px; - - font-size: 20px; - - background: $panelBackground; - - li { - position: relative; - list-style: none; - margin-top: 8px; - - a, button { - position: relative; - margin: 0; - - display: flex; - flex-direction: row; - align-items: center; - height: auto; - padding: 8px; - - border-radius: 3px; - - &:hover, &:active { - &:not(button) { - background-color: rgba(255, 255, 255, 0.07); - } - } - - .feather { - --icon-size: 16px; - } - - .tip { - position: static; - visibility: visible; - opacity: 1; - display: block; - height: auto; - margin-left: 8px; - padding: 0 0 0 4px; - transform: none; - - font-size: 16px; - line-height: 16px; - - color: inherit; - text-transform: uppercase; - font-weight: inherit; - background: transparent; - } - - &:hover { - .tip { - visibility: visible; - opacity: 1; - transition: opacity ease-out 100ms; - transition-delay: 150ms; - } - } - } - - button { - margin: 0; - height: 32px; - - .feather { - margin-right: 0; - } - } - - form { - display: flex; - justify-content: center; - align-items: center; - padding: 0; - } - - &.auth-user { - img { - width: 48px; - height: 48px; - border-radius: 3px; - margin-right: 8px; - } - } - - .dropdown { - position: initial; - display: block; - padding-left: 0; - } - } - - > li:not(:first-child) { - border-top: 1px solid transparentize($defaultTextColor, 0.8); - padding-top: 8px; - } - - &.open { - transform: translateX(0%); - box-shadow: 0 0 5px darken($panelBackground, 20%); - } - } - - #menu-button { - position: fixed; - top: 0; - left: 0; - display: block; - margin: 0; - padding: 0 16px; - line-height: $headerHeight; - - cursor: pointer; - background: transparent; - border-radius: 0; - - .feather { - --icon-size: 28px; - margin: 0 8px; - } - } - - hr { - border: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.2; - } - } - - @media (min-width: $mobileThreshold) { - flex-direction: row; - - nav { - #menu-button { - display: none; - } - - ul { - position: static; - flex-direction: row; - transform: none; - padding: 0; - background: transparent; - - li { - margin-top: 0; - margin-left: 8px; - - &:last-child { - a, button, .button { - .tip { - left: unset; - right: 4px; - transform: none; - } - } - } - - .dropdown { - position: absolute; - z-index: -1; - top: 100%; - right: 0; - display: none; - padding: 8px; - - white-space: nowrap; - background: $panelBackground; - border-radius: 0 0 3px 3px; - - box-shadow: 0 2px 2px transparentize(darken($panelBackground, 20%), 0.75); - border-top: 4px solid lighten($panelBackground, 5%); - - li { - margin-left: 0; - - &:not(:first-child) { - margin-top: 8px; - } - } - } - - &:hover .dropdown { - display: block; - } - } - - > li:not(:first-child) { - border-top: 0; - padding-top: 0; - } - } - } - } -} - -body > footer { - padding: 8px; - margin-top: 8px; - text-align: center; - background-color: $footerBackground; -} - -main { - flex: 1; - padding: 8px 0; - - button, .button { - @include tip; - } -} - -h1 { - text-align: center; - font-size: 32px; - - & + p { - text-align: center; - font-size: 20px; - } -} - -h1, h2 { - font-weight: 100; -} - -h3, h4 { - font-weight: 300; -} - -section > h2, .panel > h2 { - display: flex; - flex-direction: row; - align-items: center; - position: relative; - text-align: center; - margin-top: 4px; - - font-size: 24px; - line-height: 1; - - .feather { - margin: 0 16px 0 0; - opacity: 0.1; - } - - &::after { - content: ""; - flex: 1; - margin: 0 16px; - height: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.1; - } -} - -section > hr, .panel > hr { - border: 0; - border-bottom: 1px solid $defaultTextColor; - opacity: 0.2; - - margin: 8px 32px; -} - -a { - color: $secondary; - text-decoration: none; - - &:hover { - color: lighten($secondary, 30%); - } - - .feather.feather-external-link { - --icon-size: 16px; - margin-left: 4px; - margin-top: -3px; - } -} - -form { - padding: 8px 16px; - text-align: center; - - .form-field:not(.hidden) { - display: flex; - flex-direction: column; - margin: 16px auto; - - .control { - position: relative; - background: $inputBackground; - border-radius: 5px; - } - - .feather.icon { - position: absolute; - top: 50%; - right: 8px; - transform: translateY(-50%); - z-index: 0; - - --icon-size: 24px; - opacity: 0.75; - } - - label { - position: absolute; - left: 8px; - top: 20px; - user-select: none; - font-size: 16px; - opacity: 0.75; - - transition-property: top, font-size; - transition-duration: 150ms; - transition-timing-function: ease-out; - - cursor: text; - } - - [disabled] { - opacity: 0.5; - - & ~ label { - opacity: 0.5; - cursor: default; - } - } - - input, select, textarea, .input-group { - z-index: 1; - border: 0; - color: $defaultTextColor; - background: transparent; - font-size: 16px; - - &:focus, &:not([value=""]), &[type="file"] { - ~ label { - top: 8px; - font-size: 14px; - } - } - } - - input, select, textarea, .form-display { - display: block; - padding: 32px 8px 8px 8px; - width: 100%; - height: 60px; - } - - select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - - &::-ms-expand { - display: none; - } - - & + .feather { - position: absolute; - pointer-events: none; - right: 8px; - top: 30px; - - transition: transform 150ms ease-out; - } - - // Temporary - &:focus + .feather { - transform: rotateX(180deg); - } - } - - textarea { - resize: vertical; - min-height: 100px; - font-family: inherit; - } - - input[type=color] { - height: calc(32px + 8px + 32px); - } - - &.inline { - display: flex; - flex-direction: row; - - .control { - display: flex; - flex-direction: row; - align-items: center; - flex-grow: 1; - - input[type=checkbox] { - width: min-content; - height: min-content; - margin: 8px; - text-align: left; - - & ~ label { - position: static; - flex-grow: 1; - display: inline; - padding: 8px; - - font-size: 16px; - text-align: left; - } - } - } - } - - .input-group { - display: flex; - flex-grow: 1; - flex-direction: row; - - div { - position: relative; - flex: 1; - - input { - width: 100%; - border: 0; - background: transparent; - } - } - } - } - - .inline-fields { - display: flex; - flex-direction: row; - align-items: start; - margin: 16px auto; - - .form-field { - flex: 1; - margin: 0; - } - - > :not(.form-field) { - padding: 32px 8px 8px 8px; - } - - + { - .error, .hint { - margin-top: -16px; - margin-bottom: 16px; - } - } - } - - .form-field, .inline-fields + { - .error, .hint { - padding: 2px; - text-align: left; - font-size: 14px; - - .feather { - --icon-size: 14px; - } - } - - .error { - color: $error; - } - } -} - -button, .button { - display: inline-flex; - margin: 8px; - padding: 12px 16px; - border: 0; - border-radius: 5px; - cursor: pointer; - - text-transform: uppercase; - font-size: 16px; - font-weight: bolder; - - line-height: 16px; - - .feather { - --icon-size: 16px; - margin-right: 8px; - } - - .feather.last { - margin-right: 0; - margin-left: 8px; - } - - &, &.primary { - color: $primaryForeground; - background-color: darken($secondary, 10%); - - &:hover { - background-color: $secondary; - } - } - - &.info { - background-color: $infoColor; - } - - &.success { - background-color: $successColor; - } - - &.warning { - background-color: $warningColor; - - &:hover { - background-color: lighten($warningColor, 10%); - } - } - - &.error, &.danger { - background-color: $errorColor; - - &:hover { - background-color: lighten($errorColor, 10%); - } - } - - &.transparent { - background-color: transparent; - } - - &:hover { - color: $primaryForeground; - } -} - - -// --- -// --- Tables -// --- -td.actions { - > * { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - - form { - padding: 0; - display: inline; - } - - button, .button { - margin: 0; - padding: 8px; - - .feather { - margin-right: 0; - } - } - - > *:not(:first-child) { - margin-left: 8px; - } - } -} - -.data-table { - width: 100%; - text-align: left; - border-collapse: collapse; - - th, td { - padding: 8px; - } - - th { - border-bottom: 1px solid #39434a; - white-space: nowrap; - } - - tr:nth-child(even) { - background-color: rgba(255, 255, 255, 0.03); - } - - tr:hover { - background-color: rgba(255, 255, 255, 0.09); - } - - thead tr:hover { - background-color: transparent; - } - - th.shrink-col { - width: 0; - } -} - - -// --- -// --- Breadcrumb widget -// --- -.breadcrumb { - list-style: none; - display: flex; - flex-direction: row; - margin: 0; - padding: 8px; - - > *:not(:first-child)::before { - content: '›'; - padding: 0 8px; - } -} - - -// --- -// --- Layout helpers -// --- -.center { - text-align: center; -} - -.panel { - position: relative; - margin: 16px 0 48px; - padding: 8px; - background-color: $panelBackground; - border-radius: 5px; - - p { - margin: 16px 8px; - } - - > .feather:first-child { - position: absolute; - --icon-size: 24px; - opacity: 0.1; - top: 8px; - left: 8px; - } -} - -.sub-panel { - margin: 32px 0; - padding: 1px 16px; - border: 2px solid lighten($panelBackground, 4%); - border-radius: 5px; - - form > & { - margin: 32px -18px; - } -} - - -// --- -// --- Feather -// --- -.feather { - display: inline-flex; - justify-content: center; - align-items: center; - - flex-shrink: 0; - width: var(--icon-size); - height: var(--icon-size); - - --icon-size: 16px; - font-size: var(--icon-size); - stroke: currentColor; - stroke-width: 2; - stroke-linecap: square; - stroke-linejoin: miter; - fill: none; - vertical-align: middle; - - h1 > &, h2 > &, h3 > & { - --icon-size: 24px; - } -} - -// --- -// --- Helper classes -// --- -.message { - display: flex; - flex-direction: row; - align-items: center; - - padding: 8px 16px; - - border-radius: 5px; - - .feather { - --icon-size: 24px; - margin-right: 8px; - } - - &:not(&-discreet) { - background-color: rgba(255, 255, 255, 0.33); - - &[data-type=info], &[data-type=question] { - background-color: $infoColor; - } - - &[data-type=success] { - background-color: $successColor; - } - - &[data-type=warning] { - background-color: $warningColor; - } - - &[data-type=error] { - background-color: $errorColor; - } - } - - &-discreet { - color: mix($panelBackground, #fff, 35%); - - .feather { - --icon-size: 20px; - } - } -} - -.messages .message:not(:last-child) { - margin-bottom: 8px; -} - -.container > .messages:first-child { - margin-top: 16px; -} - -.copyable-text { - display: flex; - flex-direction: row; - margin: 8px; - - background-color: darken($backgroundColor, 2%); - border-radius: 5px; - overflow: hidden; - - .title { - padding: 8px; - } - - .content { - width: 0; - flex-grow: 1; - overflow: hidden; - white-space: nowrap; - padding: 8px; - } - - .copy-button { - margin: 0; - padding: 0; - border-radius: 0; - - .feather { - --icon-size: 20px; - margin: 8px; - } - } -} - -.hidden { - display: none; -} - -.progress-bar { - position: relative; - display: block; - margin: 8px; - padding: 4px; - background: #fff1; - border-radius: 5px; - overflow: hidden; - text-align: center; - - .content { - position: relative; - } - - &::before { - content: ""; - display: block; - position: absolute; - left: 0; - top: 0; - width: var(--progress); - height: 100%; - transition: width ease-out 150ms; - - background: $secondary; - } -} - -.table-col-grow { - width: 100%; -} - -.table-col-grow-cell { - > * { - display: flex; - flex-direction: row; - - > * { - width: 0; - flex-grow: 1; - white-space: nowrap; - text-overflow: ellipsis; - } - - * { - overflow: hidden; - text-overflow: ellipsis; - } - } -} - -.pagination { - ul { - display: flex; - flex-direction: row; - list-style: none; - padding: 8px; - - justify-content: center; - - li { - a, &.active, &.ellipsis { - display: block; - min-width: 40px; - height: 40px; - padding: 4px; - - line-height: 32px; - text-align:center; - - &:hover:not(.active):not(.ellipsis) { - background-color: #fff5; - } - } - } - } -} diff --git a/src/assets/scss/_vars.scss b/src/assets/scss/_vars.scss new file mode 100644 index 0000000..0e9546f --- /dev/null +++ b/src/assets/scss/_vars.scss @@ -0,0 +1,117 @@ +// +// --- Color palette --- +// +$onLight: #222; +$onDark: #eee; + + +// Primary +$primary: darken(#842cff, 17.5%); +$primaryLight: lighten($primary, 10%); +$onPrimary: $onDark; +$primaryOnBackground: $primary; +$primaryLightOnBackground: $primaryLight; +$primaryOnSurface: $primary; +$primaryLightOnSurface: $primaryLight; + +$primaryDarkMode: $primary; +$primaryLightDarkMode: lighten($primaryDarkMode, 23%); +$onPrimaryDarkMode: $onDark; +$primaryOnBackgroundDarkMode: lighten($primaryDarkMode, 20%); +$primaryLightOnBackgroundDarkMode: $primaryLightDarkMode; +$primaryOnSurfaceDarkMode: lighten($primaryDarkMode, 29%); +$primaryLightOnSurfaceDarkMode: lighten($primaryOnSurfaceDarkMode, 15%); + + +// Secondary +$secondary: #f21170; +$onSecondary: $onLight; +$secondaryDarkMode: $secondary; +$onSecondaryDarkMode: $onSecondary; + + +// Background +$backgroundBase: #eee; +$background: mix($backgroundBase, $primary, 98%); +$onBackground: $onLight; +$backgroundBaseDarkMode: #222; +$backgroundDarkMode: mix($backgroundBaseDarkMode, $primaryDarkMode, 98%); +$onBackgroundDarkMode: $onDark; + + +// Surface +$surface: lighten($background, 6%); +$onSurface: $onLight; +$surfaceDarkMode: darken($backgroundDarkMode, 4.5%); +$onSurfaceDarkMode: $onDark; + +// Subsurface +$subsurface: darken($surface, 3%); +$onSubsurface: $onLight; +$subsurfaceDarkMode: darken($surfaceDarkMode, 3%); +$onSubsurfaceDarkMode: $onDark; + + +// Input +$input: darken($surface, 5%); +$onInput: $onLight; +$inputDarkMode: darken($surfaceDarkMode, 5%); +$onInputDarkMode: $onDark; + + +// +// --- Layout --- +// +$header: $surface; +$headerDarkMode: $surfaceDarkMode; +$headerContainer: true; +$headerHeight: 72px; +$footer: transparent; + + +// +// --- State palette --- +// +$info: #4499ff; +$onInfo: darken($info, 50%); +$infoOnBackground: darken($info, 20%); +$infoOnSurface: darken($info, 20%); +$infoDarkMode: darken($info, 40%); +$onInfoDarkMode: lighten($info, 20%); +$infoOnBackgroundDarkMode: $info; +$infoOnSurfaceDarkMode: $info; + +$success: #55ff55; +$onSuccess: darken($success, 45%); +$successOnBackground: darken($success, 45%); +$successOnSurface: darken($success, 45%); +$successDarkMode: darken($success, 45%); +$onSuccessDarkMode: lighten($success, 20%); +$successOnBackgroundDarkMode: $success; +$successOnSurfaceDarkMode: $success; + +$warning: #ffcc00; +$onWarning: darken($warning, 30%); +$warningOnBackground: darken($warning, 25%); +$warningOnSurface: darken($warning, 25%); +$warningDarkMode: darken($warning, 30%); +$onWarningDarkMode: lighten($warning, 20%); +$warningOnBackgroundDarkMode: $warning; +$warningOnSurfaceDarkMode: $warning; + +$error: #ff0000; +$onError: darken($error, 40%); +$errorOnBackground: darken($error, 10%); +$errorOnSurface: darken($error, 10%); +$errorDarkMode: darken($error, 30%); +$onErrorDarkMode: lighten($error, 20%); +$errorOnBackgroundDarkMode: lighten($error, 15%); +$errorOnSurfaceDarkMode: lighten($error, 3%); + + +// +// --- Responsivity --- +// +$mobileThreshold: 850px; +$desktopThreshold: 940px; +