Compare commits
47 Commits
76 changed files with 4399 additions and 6971 deletions
@ -0,0 +1,135 @@
|
||||
module.exports = { |
||||
root: true, |
||||
parser: '@typescript-eslint/parser', |
||||
plugins: [ |
||||
'svelte3', |
||||
'@typescript-eslint', |
||||
'import', |
||||
'simple-import-sort', |
||||
], |
||||
parserOptions: { |
||||
tsconfigRootDir: __dirname, |
||||
project: [ |
||||
'./tsconfig.test.json', |
||||
'./src/tsconfig.json', |
||||
'./src/common/tsconfig.json', |
||||
'./src/assets/ts/tsconfig.eslint.json', |
||||
'./src/assets/views/tsconfig.json', |
||||
] |
||||
}, |
||||
extends: [ |
||||
'eslint:recommended', |
||||
'plugin:@typescript-eslint/recommended', |
||||
], |
||||
rules: { |
||||
indent: [ |
||||
'error', |
||||
4, |
||||
{ |
||||
SwitchCase: 1 |
||||
} |
||||
], |
||||
'no-trailing-spaces': 'error', |
||||
'max-len': [ |
||||
'error', |
||||
{ |
||||
code: 120, |
||||
ignoreTemplateLiterals: true, |
||||
ignoreRegExpLiterals: true |
||||
} |
||||
], |
||||
semi: 'off', |
||||
'@typescript-eslint/semi': [ |
||||
'error' |
||||
], |
||||
'no-extra-semi': 'error', |
||||
'eol-last': 'error', |
||||
'comma-dangle': 'off', |
||||
'simple-import-sort/imports': 'error', |
||||
'no-extra-parens': 'off', |
||||
'no-nested-ternary': 'error', |
||||
'no-return-await': 'off', |
||||
'no-useless-return': 'error', |
||||
'no-useless-constructor': 'off', |
||||
'import/extensions': ['error', 'ignorePackages'], |
||||
'@typescript-eslint/comma-dangle': [ |
||||
'error', |
||||
{ |
||||
arrays: 'always-multiline', |
||||
objects: 'always-multiline', |
||||
imports: 'always-multiline', |
||||
exports: 'always-multiline', |
||||
functions: 'always-multiline', |
||||
enums: 'always-multiline', |
||||
generics: 'always-multiline', |
||||
tuples: 'always-multiline' |
||||
} |
||||
], |
||||
'@typescript-eslint/no-extra-parens': [ |
||||
'error' |
||||
], |
||||
'@typescript-eslint/no-inferrable-types': 'off', |
||||
'@typescript-eslint/explicit-module-boundary-types': 'error', |
||||
'@typescript-eslint/no-unnecessary-condition': 'error', |
||||
'@typescript-eslint/no-unused-vars': [ |
||||
'error', |
||||
{ |
||||
argsIgnorePattern: '^_' |
||||
} |
||||
], |
||||
'@typescript-eslint/no-non-null-assertion': 'error', |
||||
'@typescript-eslint/no-useless-constructor': [ |
||||
'error' |
||||
], |
||||
'@typescript-eslint/return-await': [ |
||||
'error', |
||||
'always' |
||||
], |
||||
'@typescript-eslint/explicit-member-accessibility': [ |
||||
'error', |
||||
{ |
||||
accessibility: 'explicit' |
||||
} |
||||
], |
||||
'@typescript-eslint/no-floating-promises': 'error', |
||||
}, |
||||
ignorePatterns: [ |
||||
'.eslintrc.js', |
||||
'rollup.config.js', |
||||
'jest.config.js', |
||||
'dist/**/*', |
||||
'config/**/*', |
||||
'intermediates/**/*', |
||||
'public/**/*', |
||||
'scripts/**/*', |
||||
'src/frontend/register_svelte/register_svelte.js', |
||||
], |
||||
overrides: [ |
||||
{ |
||||
files: [ |
||||
'test/**/*' |
||||
], |
||||
rules: { |
||||
'max-len': [ |
||||
'error', |
||||
{ |
||||
code: 120, |
||||
ignoreTemplateLiterals: true, |
||||
ignoreRegExpLiterals: true, |
||||
ignoreStrings: true |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
{ |
||||
files: ['*.svelte'], |
||||
processor: 'svelte3/svelte3' |
||||
} |
||||
], |
||||
settings: { |
||||
'svelte3/typescript': require('typescript'), |
||||
'svelte3/ignore-styles': function (attributes) { |
||||
return !!(attributes['lang'] && attributes['lang'] !== 'css'); |
||||
} |
||||
}, |
||||
} |
@ -1,115 +0,0 @@
|
||||
{ |
||||
"root": true, |
||||
"parser": "@typescript-eslint/parser", |
||||
"plugins": [ |
||||
"@typescript-eslint" |
||||
], |
||||
"parserOptions": { |
||||
"project": [ |
||||
"./tsconfig.json", |
||||
"./tsconfig.test.json", |
||||
"./tsconfig.frontend.json" |
||||
] |
||||
}, |
||||
"extends": [ |
||||
"eslint:recommended", |
||||
"plugin:@typescript-eslint/recommended" |
||||
], |
||||
"rules": { |
||||
"indent": [ |
||||
"error", |
||||
4, |
||||
{ |
||||
"SwitchCase": 1 |
||||
} |
||||
], |
||||
"no-trailing-spaces": "error", |
||||
"max-len": [ |
||||
"error", |
||||
{ |
||||
"code": 120, |
||||
"ignoreStrings": true, |
||||
"ignoreTemplateLiterals": true, |
||||
"ignoreRegExpLiterals": true |
||||
} |
||||
], |
||||
"semi": "off", |
||||
"@typescript-eslint/semi": [ |
||||
"error" |
||||
], |
||||
"no-extra-semi": "error", |
||||
"eol-last": "error", |
||||
"comma-dangle": "off", |
||||
"@typescript-eslint/comma-dangle": [ |
||||
"error", |
||||
{ |
||||
"arrays": "always-multiline", |
||||
"objects": "always-multiline", |
||||
"imports": "always-multiline", |
||||
"exports": "always-multiline", |
||||
"functions": "always-multiline", |
||||
"enums": "always-multiline", |
||||
"generics": "always-multiline", |
||||
"tuples": "always-multiline" |
||||
} |
||||
], |
||||
"no-extra-parens": "off", |
||||
"@typescript-eslint/no-extra-parens": [ |
||||
"error" |
||||
], |
||||
"no-nested-ternary": "error", |
||||
"@typescript-eslint/no-inferrable-types": "off", |
||||
"@typescript-eslint/explicit-module-boundary-types": "error", |
||||
"@typescript-eslint/no-unnecessary-condition": "error", |
||||
"@typescript-eslint/no-unused-vars": [ |
||||
"error", |
||||
{ |
||||
"argsIgnorePattern": "^_" |
||||
} |
||||
], |
||||
"@typescript-eslint/no-non-null-assertion": "error", |
||||
"no-useless-return": "error", |
||||
"no-useless-constructor": "off", |
||||
"@typescript-eslint/no-useless-constructor": [ |
||||
"error" |
||||
], |
||||
"no-return-await": "off", |
||||
"@typescript-eslint/return-await": [ |
||||
"error", |
||||
"always" |
||||
], |
||||
"@typescript-eslint/explicit-member-accessibility": [ |
||||
"error", |
||||
{ |
||||
"accessibility": "explicit" |
||||
} |
||||
], |
||||
"@typescript-eslint/no-floating-promises": "error" |
||||
}, |
||||
"ignorePatterns": [ |
||||
"jest.config.js", |
||||
"scripts/**/*", |
||||
"webpack.config.js", |
||||
"dist/**/*", |
||||
"public/**/*", |
||||
"config/**/*" |
||||
], |
||||
"overrides": [ |
||||
{ |
||||
"files": [ |
||||
"test/**/*" |
||||
], |
||||
"rules": { |
||||
"max-len": [ |
||||
"error", |
||||
{ |
||||
"code": 120, |
||||
"ignoreTemplateLiterals": true, |
||||
"ignoreRegExpLiterals": true, |
||||
"ignoreStrings": true |
||||
} |
||||
] |
||||
} |
||||
} |
||||
] |
||||
} |
@ -1,12 +0,0 @@
|
||||
{ |
||||
"bundles": { |
||||
"app": "ts/app.ts", |
||||
"fm": "ts/fm.ts", |
||||
"url-shrinker": "ts/url-shrinker.ts", |
||||
"layout": "sass/layout.scss", |
||||
"error": "sass/error.scss", |
||||
"logo": "img/logo.svg", |
||||
"logo_png": "img/logox128.png", |
||||
"logo_png_xxl": "img/logox1024.png" |
||||
} |
||||
} |
@ -1,81 +0,0 @@
|
||||
/* vietnamese */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 300; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5iU1EQVg.woff2) format('woff2'); |
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; |
||||
} |
||||
/* latin-ext */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 300; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5jU1EQVg.woff2) format('woff2'); |
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; |
||||
} |
||||
/* latin */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 300; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Light'), local('NunitoSans-Light'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8WAc5tU1E.woff2) format('woff2'); |
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; |
||||
} |
||||
/* vietnamese */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 400; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8cceyI9tScg.woff2) format('woff2'); |
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; |
||||
} |
||||
/* latin-ext */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 400; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8ccezI9tScg.woff2) format('woff2'); |
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; |
||||
} |
||||
/* latin */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 400; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Regular'), local('NunitoSans-Regular'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe0qMImSLYBIv1o4X1M8cce9I9s.woff2) format('woff2'); |
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; |
||||
} |
||||
/* vietnamese */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 700; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5iU1EQVg.woff2) format('woff2'); |
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; |
||||
} |
||||
/* latin-ext */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 700; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5jU1EQVg.woff2) format('woff2'); |
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; |
||||
} |
||||
/* latin */ |
||||
@font-face { |
||||
font-family: 'Nunito Sans'; |
||||
font-style: normal; |
||||
font-weight: 700; |
||||
font-display: swap; |
||||
src: local('Nunito Sans Bold'), local('NunitoSans-Bold'), url(https://fonts.gstatic.com/s/nunitosans/v5/pe03MImSLYBIv1o4X1M8cc8GBs5tU1E.woff2) format('woff2'); |
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; |
||||
} |
@ -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; |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -1,90 +0,0 @@
|
||||
@import "layout"; |
||||
|
||||
header, footer { |
||||
margin: 0; |
||||
padding: 0; |
||||
height: 0; |
||||
} |
||||
|
||||
main { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
align-items: center; |
||||
|
||||
.messages { |
||||
margin-bottom: 32px; |
||||
} |
||||
|
||||
.error-code { |
||||
font-size: 36px; |
||||
} |
||||
|
||||
.error-message { |
||||
font-size: 32px; |
||||
} |
||||
|
||||
.error-instructions { |
||||
margin-top: 32px; |
||||
font-size: 20px; |
||||
} |
||||
|
||||
nav { |
||||
margin-top: 32px; |
||||
} |
||||
|
||||
&::before { |
||||
content: "Oops"; |
||||
position: absolute; |
||||
z-index: -1; |
||||
|
||||
font-size: #{'min(50vh, 40vw)'}; |
||||
opacity: 0.025; |
||||
} |
||||
} |
||||
|
||||
.contact { |
||||
text-align: center; |
||||
padding: 8px; |
||||
} |
||||
|
||||
.logo { |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
margin-top: 24px; |
||||
text-align: center; |
||||
|
||||
a { |
||||
position: relative; |
||||
padding: 16px; |
||||
|
||||
color: $defaultTextColor; |
||||
|
||||
&:hover { |
||||
color: #fff; |
||||
|
||||
&::before { |
||||
opacity: 0.2; |
||||
} |
||||
} |
||||
|
||||
&::before { |
||||
content: ""; |
||||
position: absolute; |
||||
width: 100%; |
||||
height: 100%; |
||||
top: 0; |
||||
left: 0; |
||||
|
||||
background-image: url(../img/logo.svg); |
||||
background-repeat: no-repeat; |
||||
background-position: center; |
||||
background-size: 64px; |
||||
|
||||
opacity: 0.075; |
||||
filter: contrast(0); |
||||
} |
||||
} |
||||
} |
@ -1,11 +0,0 @@
|
||||
@import "vars"; |
||||
|
||||
#file-upload { |
||||
padding: 8px; |
||||
background: $infoColor; |
||||
border-radius: 5px; |
||||
|
||||
.name, .status { |
||||
text-align: center; |
||||
} |
||||
} |
@ -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 { |
||||