tailwind: upgrade a17t, somewhat functional dark mode

instead of adding dark: variants to each element, a preprocessor script
adds them. still needs to be implemented to typescript.
This commit is contained in:
Harvey Tindall 2021-12-30 00:49:43 +00:00
parent 57e6469564
commit 18ae03554f
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
26 changed files with 2255 additions and 414 deletions

View File

@ -118,6 +118,7 @@ bundle-css:
-mkdir -p $(DATA)/web/css
$(info bundling css)
$(ESBUILD) --bundle css/base.css --outfile=$(DATA)/web/css/bundle.css --external:remixicon.css --minify
npx tailwindcss -i $(DATA)/web/css/bundle.css -o $(DATA)/web/css/bundle.css
inline:
cp html/crash.html $(DATA)/crash.html
@ -125,11 +126,16 @@ inline:
node scripts/inline.js root $(DATA) $(DATA)/crash.html $(DATA)/crash.html
rm $(DATA)/bundle.css
variants-html:
$(info copying html)
cp -r html $(DATA)/
$(info adding dark variants to html)
scripts/dark-variant.sh $(DATA)/html
copy:
$(info copying fonts)
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 $(DATA)/web/css/
$(info copying html)
cp -r html $(DATA)/
$(info copying crash page)
mv $(DATA)/crash.html $(DATA)/html/
$(info copying static data)
-mkdir -p $(DATA)/web
@ -159,4 +165,4 @@ clean:
-rm docs/docs.go docs/swagger.json docs/swagger.yaml
go clean
all: configuration npm email typescript bundle-css inline swagger copy compile
all: configuration npm email typescript variants-html bundle-css inline swagger copy compile

View File

@ -1,10 +1,13 @@
@import "../node_modules/a17t/dist/a17t.css";
@import "remixicon.css";
@import "./modal.css";
@import "./dark.css";
@import "./tooltip.css";
@import "./loader.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--border-width-default: 2px;
--border-width-2: 3px;
@ -16,7 +19,7 @@
--settings-section-button-filter: 90%;
}
.body {
.dark body {
background-color: #101010;
}
@ -543,10 +546,10 @@ div.card:contains(section.banner.footer) {
padding: var(--spacing-4, 1rem);
}
.button.discord.\!normal {
.button.discord.\@low {
background-color: rgba(88, 101, 242,60%);
}
.button.discord.\!normal:not(.lang-link) {
.button.discord.\@low:not(.lang-link) {
color: rgba(38, 51, 192, 90%);
}

View File

@ -1,4 +1,4 @@
.dark-theme {
.dark {
--settings-section-button-filter: 110%;
@ -86,6 +86,6 @@
display: initial;
}
.dark-theme select option {
.dark select option {
background: #202020;
}

351
css/dark.js Normal file
View File

@ -0,0 +1,351 @@
var c = {
inherit: 'inherit',
current: 'currentColor',
transparent: 'transparent',
black: '#000',
white: '#fff',
d_neutral: {
900: "rgba(255, 255, 255, 0.87)",
800: "rgba(255, 255, 255, 0.8)",
700: "rgba(255, 255, 255, 0.73)",
600: "rgba(255, 255, 255, 0.66)",
500: "rgb(153, 153, 153)",
400: "#383838",
300: "#303030",
200: "#292929",
100: "#242424",
50: "#202020",
000: "#101010"
},
d_critical: {
900: "#fef2f2",
800: "#fee2e2",
700: "#fecaca",
600: "#fca5a5",
500: "#f87171",
400: "#ef4444",
300: "#dc2626",
200: "#b91c1c",
100: "#991b1b",
50: "#7f1d1d",
000: "#441313"
},
d_warning: {
900: "#fffbeb",
800: "#fef3c7",
700: "#fde68a",
600: "#fcd34d",
500: "#fbbf24",
400: "#f59e0b",
300: "#d97706",
200: "#b45309",
100: "#92400e",
50: "#783900",
000: "#411e01"
},
d_positive: {
900: "#f0fdf4",
800: "#dcfce7",
700: "#bbf7d0",
600: "#86efac",
500: "#4ade80",
400: "#22c55e",
300: "#16a34a",
200: "#15803d",
100: "#166534",
50: "#14532d",
000: "#0f2e1b"
},
d_urge: {
900: "#e0ffff",
800: "#c0fbff",
700: "#a0f4ff",
600: "#80e9ff",
500: "#60dbfb",
400: "#40cbf3",
300: "#20b9e9",
200: "#00a4dc",
100: "#0054bc",
50: "#00169a",
000: "#050076"
},
d_info: {
900: "#f5f3ff",
800: "#ede9fe",
700: "#ddd6fe",
600: "#c4b5fd",
500: "#a78bfa",
400: "#8b5cf6",
300: "#7c3aed",
200: "#6d28d9",
100: "#5b21b6",
50: "#4c1d95",
000: "#240e44"
},
slate: {
50: '#f8fafc',
100: '#f1f5f9',
200: '#e2e8f0',
300: '#cbd5e1',
400: '#94a3b8',
500: '#64748b',
600: '#475569',
700: '#334155',
800: '#1e293b',
900: '#0f172a'
},
gray: {
50: '#f9fafb',
100: '#f3f4f6',
200: '#e5e7eb',
300: '#d1d5db',
400: '#9ca3af',
500: '#6b7280',
600: '#4b5563',
700: '#374151',
800: '#1f2937',
900: '#111827'
},
zinc: {
50: '#fafafa',
100: '#f4f4f5',
200: '#e4e4e7',
300: '#d4d4d8',
400: '#a1a1aa',
500: '#71717a',
600: '#52525b',
700: '#3f3f46',
800: '#27272a',
900: '#18181b'
},
neutral: {
50: '#fafafa',
100: '#f5f5f5',
200: '#e5e5e5',
300: '#d4d4d4',
400: '#a3a3a3',
500: '#737373',
600: '#525252',
700: '#404040',
800: '#262626',
900: '#171717'
},
stone: {
50: '#fafaf9',
100: '#f5f5f4',
200: '#e7e5e4',
300: '#d6d3d1',
400: '#a8a29e',
500: '#78716c',
600: '#57534e',
700: '#44403c',
800: '#292524',
900: '#1c1917'
},
red: {
50: '#fef2f2',
100: '#fee2e2',
200: '#fecaca',
300: '#fca5a5',
400: '#f87171',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c',
800: '#991b1b',
900: '#7f1d1d'
},
orange: {
50: '#fff7ed',
100: '#ffedd5',
200: '#fed7aa',
300: '#fdba74',
400: '#fb923c',
500: '#f97316',
600: '#ea580c',
700: '#c2410c',
800: '#9a3412',
900: '#7c2d12'
},
amber: {
50: '#fffbeb',
100: '#fef3c7',
200: '#fde68a',
300: '#fcd34d',
400: '#fbbf24',
500: '#f59e0b',
600: '#d97706',
700: '#b45309',
800: '#92400e',
900: '#78350f'
},
yellow: {
50: '#fefce8',
100: '#fef9c3',
200: '#fef08a',
300: '#fde047',
400: '#facc15',
500: '#eab308',
600: '#ca8a04',
700: '#a16207',
800: '#854d0e',
900: '#713f12'
},
lime: {
50: '#f7fee7',
100: '#ecfccb',
200: '#d9f99d',
300: '#bef264',
400: '#a3e635',
500: '#84cc16',
600: '#65a30d',
700: '#4d7c0f',
800: '#3f6212',
900: '#365314'
},
green: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d'
},
emerald: {
50: '#ecfdf5',
100: '#d1fae5',
200: '#a7f3d0',
300: '#6ee7b7',
400: '#34d399',
500: '#10b981',
600: '#059669',
700: '#047857',
800: '#065f46',
900: '#064e3b'
},
teal: {
50: '#f0fdfa',
100: '#ccfbf1',
200: '#99f6e4',
300: '#5eead4',
400: '#2dd4bf',
500: '#14b8a6',
600: '#0d9488',
700: '#0f766e',
800: '#115e59',
900: '#134e4a'
},
cyan: {
50: '#ecfeff',
100: '#cffafe',
200: '#a5f3fc',
300: '#67e8f9',
400: '#22d3ee',
500: '#06b6d4',
600: '#0891b2',
700: '#0e7490',
800: '#155e75',
900: '#164e63'
},
sky: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e'
},
blue: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a'
},
indigo: {
50: '#eef2ff',
100: '#e0e7ff',
200: '#c7d2fe',
300: '#a5b4fc',
400: '#818cf8',
500: '#6366f1',
600: '#4f46e5',
700: '#4338ca',
800: '#3730a3',
900: '#312e81'
},
violet: {
50: '#f5f3ff',
100: '#ede9fe',
200: '#ddd6fe',
300: '#c4b5fd',
400: '#a78bfa',
500: '#8b5cf6',
600: '#7c3aed',
700: '#6d28d9',
800: '#5b21b6',
900: '#4c1d95'
},
purple: {
50: '#faf5ff',
100: '#f3e8ff',
200: '#e9d5ff',
300: '#d8b4fe',
400: '#c084fc',
500: '#a855f7',
600: '#9333ea',
700: '#7e22ce',
800: '#6b21a8',
900: '#581c87'
},
fuchsia: {
50: '#fdf4ff',
100: '#fae8ff',
200: '#f5d0fe',
300: '#f0abfc',
400: '#e879f9',
500: '#d946ef',
600: '#c026d3',
700: '#a21caf',
800: '#86198f',
900: '#701a75'
},
pink: {
50: '#fdf2f8',
100: '#fce7f3',
200: '#fbcfe8',
300: '#f9a8d4',
400: '#f472b6',
500: '#ec4899',
600: '#db2777',
700: '#be185d',
800: '#9d174d',
900: '#831843'
},
rose: {
50: '#fff1f2',
100: '#ffe4e6',
200: '#fecdd3',
300: '#fda4af',
400: '#fb7185',
500: '#f43f5e',
600: '#e11d48',
700: '#be123c',
800: '#9f1239',
900: '#881337'
}
}
module.exports = c;

View File

@ -22,23 +22,23 @@
<div id="modal-login" class="modal">
<form class="modal-content card" id="form-login" href="">
<span class="heading">{{ .strings.login }}</span>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="login-user">
<input type="password" class="field input ~neutral !high mb-1" placeholder="{{ .strings.password }}" id="login-password">
<input type="text" class="field input ~neutral @high mt-half mb-1" placeholder="{{ .strings.username }}" id="login-user">
<input type="password" class="field input ~neutral @high mb-1" placeholder="{{ .strings.password }}" id="login-password">
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">{{ .strings.login }}</span>
<span class="button ~urge @low full-width center supra submit">{{ .strings.login }}</span>
</label>
</form>
</div>
<div id="modal-add-user" class="modal">
<form class="modal-content card" id="form-add-user" href="">
<span class="heading">{{ .strings.newUser }} <span class="modal-close">&times;</span></span>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="add-user-user">
<input type="email" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.emailAddress }}">
<input type="password" class="field input ~neutral !high mb-1" placeholder="{{ .strings.password }}" id="add-user-password">
<input type="text" class="field input ~neutral @high mt-half mb-1" placeholder="{{ .strings.username }}" id="add-user-user">
<input type="email" class="field input ~neutral @high mt-half mb-1" placeholder="{{ .strings.emailAddress }}">
<input type="password" class="field input ~neutral @high mb-1" placeholder="{{ .strings.password }}" id="add-user-password">
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">{{ .strings.create }}</span>
<span class="button ~urge @low full-width center supra submit">{{ .strings.create }}</span>
</label>
</form>
</div>
@ -59,13 +59,13 @@
<span class="ml-1 chev"></span>
</a>
<div class="dropdown-display">
<div class="card ~info !low">
<div class="card ~info @low">
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">GitHub</a>
<a href="https://ko-fi.com/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">Ko-fi</a>
</div>
</div>
</div>
<a class="button ~urge mt-1 mb-1 !normal discord lang-link" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-half"></i>discord</a>
<a class="button ~urge mt-1 mb-1 @low discord lang-link" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-half"></i>discord</a>
</div>
<p><a href="https://github.com/hrfee/jfa-go/blob/main/LICENSE">Available under the MIT License.</a></p>
<pre class="monospace">{{ .license }}</pre>
@ -78,17 +78,17 @@
<div class="flex-row mb-1">
<label class="flex-row-group mr-1">
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-profile" checked>
<span class="button ~neutral !high supra full-width center">{{ .strings.profile }}</span>
<span class="button ~neutral @high supra full-width center">{{ .strings.profile }}</span>
</label>
<label class="flex-row-group ml-1">
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-user">
<span class="button ~neutral !normal supra full-width center">{{ .strings.user }}</span>
<span class="button ~neutral @low supra full-width center">{{ .strings.user }}</span>
</label>
</div>
<div class="select ~neutral !normal mb-1">
<div class="select ~neutral @low mb-1">
<select id="modify-user-profiles"></select>
</div>
<div class="select ~neutral !normal mb-1 unfocused">
<div class="select ~neutral @low mb-1 unfocused">
<select id="modify-user-users"></select>
</div>
<label class="switch mb-1">
@ -97,7 +97,7 @@
</label>
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">{{ .strings.apply }}</span>
<span class="button ~urge @low full-width center supra submit">{{ .strings.apply }}</span>
</label>
</form>
</div>
@ -109,10 +109,10 @@
<input type="checkbox" id="delete-user-notify" checked>
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
</label>
<textarea id="textarea-delete-user" class="textarea full-width ~neutral !normal mb-1" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
<textarea id="textarea-delete-user" class="textarea full-width ~neutral @low mb-1" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
<label>
<input type="submit" class="unfocused">
<span class="button ~critical !normal full-width center supra submit">{{ .strings.delete }}</span>
<span class="button ~critical @low full-width center supra submit">{{ .strings.delete }}</span>
</label>
</div>
</form>
@ -124,7 +124,7 @@
<div class="row">
<div class="col">
<label class="label supra" for="extend-expiry-months">{{ .strings.inviteMonths }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="extend-expiry-months">
<option>0</option>
</select>
@ -132,7 +132,7 @@
</div>
<div class="col">
<label class="label supra" for="extend-expiry-days">{{ .strings.inviteDays }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="extend-expiry-days">
<option>0</option>
</select>
@ -142,7 +142,7 @@
<div class="row">
<div class="col">
<label class="label supra" for="extend-expiry-hours">{{ .strings.inviteHours }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="extend-expiry-hours">
<option>0</option>
</select>
@ -150,7 +150,7 @@
</div>
<div class="col">
<label class="label supra" for="extend-expiry-minutes">{{ .strings.inviteMinutes }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="extend-expiry-minutes">
<option>0</option>
</select>
@ -161,10 +161,10 @@
<input type="checkbox" id="expiry-extend-enable" checked>
<span>{{ .strings.sendDeleteNotificationEmail }}</span>
</label>
<textarea id="textarea-extend-enable" class="textarea full-width ~neutral !normal mb-1" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
<textarea id="textarea-extend-enable" class="textarea full-width ~neutral @low mb-1" placeholder="{{ .strings.sendDeleteNotificationExample }}"></textarea>
<label>
<input type="submit" class="unfocused">
<span class="button ~critical !normal full-width center supra submit">{{ .strings.submit }}</span>
<span class="button ~critical @low full-width center supra submit">{{ .strings.submit }}</span>
</label>
</div>
</form>
@ -177,27 +177,27 @@
<div id="announce-details">
<span class="label supra" for="editor-variables" id="label-editor-variables">{{ .strings.variables }}</span>
<div id="announce-variables">
<span class="button ~urge !normal mb-1 mt-half" id="announce-variables-username" style="margin-left: 0.25rem; margin-right: 0.25rem;"><span class="monospace">{username}</span></span>
<span class="button ~urge @low mb-1 mt-half" id="announce-variables-username" style="margin-left: 0.25rem; margin-right: 0.25rem;"><span class="monospace">{username}</span></span>
</div>
<label class="label supra" for="announce-subject"> {{ .strings.subject }}</label>
<input type="text" id="announce-subject" class="input ~neutral !normal mb-1 mt-half">
<input type="text" id="announce-subject" class="input ~neutral @low mb-1 mt-half">
<label class="label supra" for="textarea-announce">{{ .strings.message }}</label>
<textarea id="textarea-announce" class="textarea full-width ~neutral !normal mt-half monospace"></textarea>
<textarea id="textarea-announce" class="textarea full-width ~neutral @low mt-half monospace"></textarea>
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
</div>
<label class="label unfocused" id="announce-name"><p class="supra">{{ .strings.name }}</p>
<input type="text" class="input ~neutral !normal mb-1 mt-half">
<input type="text" class="input ~neutral @low mb-1 mt-half">
<p class="support">{{ .strings.templateEnterName }}</p>
</label>
<div class="row flex-expand">
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal center supra submit">{{ .strings.send }}</span>
<span class="button ~urge @low center supra submit">{{ .strings.send }}</span>
</label>
<span class="button ~info !normal center supra" id="save-announce">{{ .strings.saveAsTemplate }}</span>
<span class="button ~info @low center supra" id="save-announce">{{ .strings.saveAsTemplate }}</span>
</div>
</div>
<div class="col card ~neutral !low">
<div class="col card ~neutral @low">
<span class="subheading supra">{{ .strings.preview }}</span>
<div class="mt-half" id="announce-preview"></div>
</div>
@ -232,16 +232,16 @@
<span class="label supra" for="editor-conditionals" id="label-editor-conditionals">{{ .strings.conditionals }}</span>
<div id="editor-conditionals"></div>
<label class="label supra" for="textarea-editor">{{ .strings.message }}</label>
<textarea id="textarea-editor" class="textarea full-width flex-auto ~neutral !normal mt-half monospace"></textarea>
<textarea id="textarea-editor" class="textarea full-width flex-auto ~neutral @low mt-half monospace"></textarea>
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
<div class="flex-row">
<label class="full-width ml-half">
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
<span class="button ~urge @low full-width center supra submit">{{ .strings.submit }}</span>
</label>
</div>
</div>
<div class="col card ~neutral !low">
<div class="col card ~neutral @low">
<span class="subheading supra">{{ .strings.preview }}</span>
<div class="mt-half" id="editor-preview"></div>
</div>
@ -249,38 +249,38 @@
</form>
</div>
<div id="modal-restart" class="modal">
<div class="modal-content card ~critical !low">
<div class="modal-content card ~critical @low">
<span class="heading">{{ .strings.settingsRestartRequired }} <span class="modal-close">&times;</span></span>
<p class="content pb-1">{{ .strings.settingsRestartRequiredDescription }}</p>
<div class="fr">
<span class="button ~info !normal mb-half" id="settings-apply-no-restart">{{ .strings.settingsApplyRestartLater }}</span>
<span class="button ~critical !normal" id="settings-apply-restart">{{ .strings.settingsApplyRestartNow }}</span>
<span class="button ~info @low mb-half" id="settings-apply-no-restart">{{ .strings.settingsApplyRestartLater }}</span>
<span class="button ~critical @low" id="settings-apply-restart">{{ .strings.settingsApplyRestartNow }}</span>
</div>
</div>
</div>
<div id="modal-refresh" class="modal">
<div class="modal-content card ~neutral !normal">
<div class="modal-content card ~neutral @low">
<span class="heading">{{ .strings.settingsApplied }}</span>
<p class="content">{{ .strings.settingsRefreshPage }}</p>
</div>
</div>
<div id="modal-send-pwr" class="modal">
<div class="modal-content card ~neutral !normal">
<div class="modal-content card ~neutral @low">
<span class="heading">{{ .strings.sendPWR }}</span>
<p class="content" id="send-pwr-note"></p>
<span class="button ~urge !normal mt-half" id="send-pwr-link">{{ .strings.copy }}</span>
<span class="button ~urge @low mt-half" id="send-pwr-link">{{ .strings.copy }}</span>
</div>
</div>
<div id="modal-ombi-profile" class="modal">
<form class="modal-content card" id="form-ombi-defaults" href="">
<span class="heading">{{ .strings.ombiProfile }} <span class="modal-close">&times;</span></span>
<p class="content">{{ .strings.ombiUserDefaultsDescription }}</p>
<div class="select ~neutral !normal mb-1">
<div class="select ~neutral @low mb-1">
<select></select>
</div>
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
<span class="button ~urge @low full-width center supra submit">{{ .strings.submit }}</span>
</label>
</form>
</div>
@ -299,7 +299,7 @@
{{ end }}
<th>{{ .strings.from }}</th>
<th>{{ .strings.userProfilesLibraries }}</th>
<th><span class="button ~neutral !high" id="button-profile-create">{{ .strings.create }}</span></th>
<th><span class="button ~neutral @high" id="button-profile-create">{{ .strings.create }}</span></th>
</tr>
</thead>
<tbody id="table-profiles"></tbody>
@ -313,10 +313,10 @@
<p class="content">{{ .strings.addProfileDescription }}</p>
<label>
<span class="supra">{{ .strings.addProfileNameOf }} </span>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.name }}" id="add-profile-name">
<input type="text" class="field input ~neutral @high mt-half mb-1" placeholder="{{ .strings.name }}" id="add-profile-name">
<label>
<span class="supra">{{ .strings.user }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="add-profile-user"></select>
</div>
</label>
@ -326,7 +326,7 @@
</label>
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">{{ .strings.create }}</span>
<span class="button ~urge @low full-width center supra submit">{{ .strings.create }}</span>
</label>
</form>
</div>
@ -341,8 +341,8 @@
<p class="support" id="update-date"></p>
<div class="content markdown-box" id="update-changelog"></div>
</p>
<span class="button ~info !normal full-width center" id="update-download">{{ .strings.download }}</span>
<span class="button ~urge !normal full-width center" id="update-update">{{ .strings.update }}</span>
<span class="button ~info @low full-width center" id="update-download">{{ .strings.download }}</span>
<span class="button ~urge @low full-width center" id="update-update">{{ .strings.update }}</span>
</div>
</div>
{{ if .telegramEnabled }}
@ -359,7 +359,7 @@
</span>
&#64;<span id="telegram-username">
</a>
<span class="button ~info !normal full-width center mt-1" id="telegram-waiting">{{ .strings.success }}</span>
<span class="button ~info @low full-width center mt-1" id="telegram-waiting">{{ .strings.success }}</span>
</div>
</div>
{{ end }}
@ -369,7 +369,7 @@
<span class="heading mb-1"><span id="discord-header"></span><span class="modal-close">&times;</span></span>
<p class="content mb-1" id="discord-description"></p>
<div class="row">
<input type="search" class="col sm field ~neutral !normal input" id="discord-search" placeholder="user#1234">
<input type="search" class="col sm field ~neutral @low input" id="discord-search" placeholder="user#1234">
</div>
<table class="table"><tbody id="discord-list"></tbody></table>
</div>
@ -379,12 +379,12 @@
<form class="modal-content card" id="form-matrix" href="">
<span class="heading">{{ .strings.linkMatrix }}</span>
<p class="content">{{ .strings.linkMatrixDescription }}</p>
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.matrixHomeServer }}" id="matrix-homeserver">
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="matrix-user">
<input type="password" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="matrix-password">
<input type="text" class="field input ~neutral @high mt-half mb-1" placeholder="{{ .strings.matrixHomeServer }}" id="matrix-homeserver">
<input type="text" class="field input ~neutral @high mt-half mb-1" placeholder="{{ .strings.username }}" id="matrix-user">
<input type="password" class="field input ~neutral @high mt-half mb-1" placeholder="{{ .strings.password }}" id="matrix-password">
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
<span class="button ~urge @low full-width center supra submit">{{ .strings.submit }}</span>
</label>
</form>
</div>
@ -395,7 +395,7 @@
<span class="ml-1 chev"></span>
</span>
<div class="dropdown-display">
<div class="card ~neutral !low">
<div class="card ~neutral @low">
<label class="switch pb-1">
<input type="radio" name="lang-time" id="lang-12h">
<span>{{ .strings.time12h }}</span>
@ -421,33 +421,33 @@
</div>
<div class="mb-1">
<div class="text-neutral-700">
<span class="button ~critical !normal mb-1 unfocused" id="logout-button">{{ .strings.logout }}</span>
<span class="button ~critical @low mb-1 unfocused" id="logout-button">{{ .strings.logout }}</span>
</div>
</div>
<div id="tab-invites">
<div class="card ~neutral !low invites mb-1">
<div class="card ~neutral @low invites mb-1">
<span class="heading">{{ .strings.invites }}</span>
<div id="invites"></div>
</div>
<div class="card ~neutral !low">
<div class="card ~neutral @low">
<span class="heading">{{ .strings.create }}</span>
<div class="row" id="create-inv">
<div class="card ~neutral !normal col">
<div class="card ~neutral @low col">
<div class="row mb-1">
<label class="col mr-1">
<input type="radio" name="duration" class="unfocused" id="radio-inv-duration" checked>
<span class="button ~neutral !high supra full-width center">{{ .strings.inviteDuration }}</span>
<span class="button ~neutral @high supra full-width center">{{ .strings.inviteDuration }}</span>
</label>
<label class="col ml-1">
<input type="radio" name="duration" class="unfocused" id="radio-user-expiry">
<span class="button ~neutral !normal supra full-width center">{{ .strings.userExpiry }}</span>
<span class="button ~neutral @low supra full-width center">{{ .strings.userExpiry }}</span>
</label>
</div>
<div id="inv-duration">
<div class="row">
<div class="col">
<label class="label supra" for="create-months">{{ .strings.inviteMonths }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="create-months">
<option>0</option>
</select>
@ -455,7 +455,7 @@
</div>
<div class="col">
<label class="label supra" for="create-days">{{ .strings.inviteDays }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="create-days">
<option>0</option>
</select>
@ -465,7 +465,7 @@
<div class="row">
<div class="col">
<label class="label supra" for="create-hours">{{ .strings.inviteHours }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="create-hours">
<option>0</option>
</select>
@ -473,7 +473,7 @@
</div>
<div class="col">
<label class="label supra" for="create-minutes">{{ .strings.inviteMinutes }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="create-minutes">
<option>0</option>
</select>
@ -484,7 +484,7 @@
<div id="user-expiry" class="unfocused">
<p class="support">{{ .strings.userExpiryDescription }}</p>
<div class="mb-half">
<label for="create-user-expiry-enabled" class="button ~neutral !normal">
<label for="create-user-expiry-enabled" class="button ~neutral @low">
<input type="checkbox" id="create-user-expiry-enabled" aria-label="User duration enabled">
<span class="ml-half">{{ .strings.enabled }} </span>
</label>
@ -492,7 +492,7 @@
<div class="row">
<div class="col">
<label class="label supra" for="user-months">{{ .strings.inviteMonths }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="user-months">
<option>0</option>
</select>
@ -500,7 +500,7 @@
</div>
<div class="col">
<label class="label supra" for="user-days">{{ .strings.inviteDays }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="user-days">
<option>0</option>
</select>
@ -510,7 +510,7 @@
<div class="row">
<div class="col">
<label class="label supra" for="user-hours">{{ .strings.inviteHours }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="user-hours">
<option>0</option>
</select>
@ -518,7 +518,7 @@
</div>
<div class="col">
<label class="label supra" for="user-minutes">{{ .strings.inviteMinutes }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="user-minutes">
<option>0</option>
</select>
@ -528,21 +528,21 @@
</div>
<div class="col">
<label class="label supra" for="create-label"> {{ .strings.label }}</label>
<input type="text" id="create-label" class="input ~neutral !normal mb-1 mt-half">
<input type="text" id="create-label" class="input ~neutral @low mb-1 mt-half">
</div>
</div>
<div class="card ~neutral !normal col">
<div class="card ~neutral @low col">
<label class="label supra" for="create-uses">{{ .strings.inviteNumberOfUses }}</label>
<div class="flex-expand mb-1 mt-half">
<input type="number" min="0" id="create-uses" class="input ~neutral !normal mr-1" value=1>
<label for="create-inf-uses" class="button ~neutral !normal" title="Set uses to infinite">
<input type="number" min="0" id="create-uses" class="input ~neutral @low mr-1" value=1>
<label for="create-inf-uses" class="button ~neutral @low" title="Set uses to infinite">
<span></span>
<input type="checkbox" class="unfocused" id="create-inf-uses" aria-label="Set uses to infinite">
</label>
</div>
<p class="support unfocused" id="create-inf-uses-warning"><span class="badge ~critical">{{ .strings.warning }}</span> {{ .strings.inviteInfiniteUsesWarning }}</p>
<label class="label supra">{{ .strings.profile }}</label>
<div class="select ~neutral !normal mb-1 mt-half">
<div class="select ~neutral @low mb-1 mt-half">
<select id="create-profile">
</select>
</div>
@ -550,56 +550,56 @@
<label class="label supra">{{ .strings.inviteSendToEmail }}</label>
<div class="flex-expand mb-1 mt-half">
{{ if .discordEnabled }}
<input type="text" id="create-send-to" class="input ~neutral !normal mr-1" placeholder="example@example.com | user#1234">
<span id="create-send-to-search" class="button ~neutral !normal mr-1">
<input type="text" id="create-send-to" class="input ~neutral @low mr-1" placeholder="example@example.com | user#1234">
<span id="create-send-to-search" class="button ~neutral @low mr-1">
<i class="icon ri-search-2-line" title="{{ .strings.search }}"></i>
</span>
{{ else }}
<input type="email" id="create-send-to" class="input ~neutral !normal mr-1" placeholder="example@example.com">
<input type="email" id="create-send-to" class="input ~neutral @low mr-1" placeholder="example@example.com">
{{ end }}
<label for="create-send-to-enabled" class="button ~neutral !normal">
<label for="create-send-to-enabled" class="button ~neutral @low">
<input type="checkbox" id="create-send-to-enabled" aria-label="Send to address enabled">
</label>
</div>
</div>
<span class="button ~urge !normal supra full-width center lg" id="create-submit">{{ .strings.create }}</span>
<span class="button ~urge @low supra full-width center lg" id="create-submit">{{ .strings.create }}</span>
</div>
</div>
</div>
</div>
<div id="tab-accounts" class="unfocused">
<div class="card ~neutral !low accounts mb-1">
<div class="card ~neutral @low accounts mb-1">
<div class="flex-expand row">
<div class="row">
<span class="heading mr-1 col sm">{{ .strings.accounts }}</span>
<input type="search" class="col sm field ~neutral !normal input search ml-1 mr-1" id="accounts-search" placeholder="{{ .strings.search }}">
<input type="search" class="col sm field ~neutral @low input search ml-1 mr-1" id="accounts-search" placeholder="{{ .strings.search }}">
</div>
<div class="row">
<span class="col sm button ~neutral !normal center mb-half" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
<span class="col sm button ~neutral @low center mb-half" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
<div id="accounts-announce-dropdown" class="col sm dropdown" tabindex="0">
<span class="h-100 sm button ~info !normal center mb-half" id="accounts-announce">{{ .strings.announce }}</span>
<span class="h-100 sm button ~info @low center mb-half" id="accounts-announce">{{ .strings.announce }}</span>
<div class="dropdown-display">
<div class="card ~neutral !low">
<div class="card ~neutral @low">
<span class="supra sm">{{ .strings.templates }}</span>
<div id="accounts-announce-templates"></div>
</div>
</div>
</div>
<span class="col sm button ~urge !normal center mb-half" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
<span class="col sm button ~warning !normal center mb-half" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
<span class="col sm button ~urge @low center mb-half" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
<span class="col sm button ~warning @low center mb-half" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
<div id="accounts-disable-enable-dropdown" class="col sm dropdown manual" tabindex="0">
<span class="h-100 sm button ~positive !normal center mb-half" id="accounts-disable-enable">{{ .strings.disable }}</span>
<span class="h-100 sm button ~positive @low center mb-half" id="accounts-disable-enable">{{ .strings.disable }}</span>
<div class="dropdown-display">
<div class="card ~neutral !low">
<div class="card ~neutral @low">
<span class="button ~neutral sm full-width accounts-announce-template-button" id="accounts-enable-expiry">{{ .strings.setExpiry }}</span>
</div>
</div>
</div>
<span class="col sm button ~info !normal center mb-half unfocused" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
<span class="col sm button ~critical !normal center mb-half" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
<span class="col sm button ~info @low center mb-half unfocused" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
<span class="col sm button ~critical @low center mb-half" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
</div>
</div>
<div class="card ~neutral !normal accounts-header table-responsive mt-half">
<div class="card ~neutral @low accounts-header table-responsive mt-half">
<table class="table">
<thead>
<tr>
@ -625,27 +625,27 @@
</div>
</div>
<div id="tab-settings" class="unfocused">
<div class="card ~neutral !low settings overflow">
<div class="card ~neutral @low settings overflow">
<div class="flex-expand">
<div class="flex-row">
<span class="heading">{{ .strings.settings }}</span>
<label for="settings-advanced-enabled" class="button ~neutral !normal ml-1">
<label for="settings-advanced-enabled" class="button ~neutral @low ml-1">
<input type="checkbox" id="settings-advanced-enabled" aria-label="Advanced settings enabled">
<span class="ml-half">{{ .strings.advancedSettings }} </span>
</label>
</div>
<div>
<span class="button ~neutral !normal" id="settings-restart">{{ .strings.settingsRestart }}</span>
<span class="button ~urge !normal unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
<span class="button ~neutral @low" id="settings-restart">{{ .strings.settingsRestart }}</span>
<span class="button ~urge @low unfocused" id="settings-save">{{ .strings.settingsSave }}</span>
</div>
</div>
<div class="row">
<div class="card ~neutral !normal col" id="settings-sidebar">
<div class="card ~neutral @low col" id="settings-sidebar">
<aside class="aside sm ~info mb-half" id="settings-message">Note: <span class="badge ~critical">*</span> indicates a required field, <span class="badge ~info">R</span> indicates changes require a restart.</aside>
<span class="button ~neutral !low settings-section-button mb-half" id="setting-about"><span class="flex">{{ .strings.aboutProgram }} <i class="ri-information-line ml-half"></i></span></span>
<span class="button ~neutral !low settings-section-button mb-half" id="setting-profiles"><span class="flex">{{ .strings.userProfiles }} <i class="ri-user-line ml-half"></i></span></span>
<span class="button ~neutral @low settings-section-button mb-half" id="setting-about"><span class="flex">{{ .strings.aboutProgram }} <i class="ri-information-line ml-half"></i></span></span>
<span class="button ~neutral @low settings-section-button mb-half" id="setting-profiles"><span class="flex">{{ .strings.userProfiles }} <i class="ri-user-line ml-half"></i></span></span>
</div>
<div class="card ~neutral !normal col overflow" id="settings-panel"></div>
<div class="card ~neutral @low col overflow" id="settings-panel"></div>
</div>
</div>
</div>

View File

@ -19,17 +19,17 @@
{{ end }}
<a class="button ~critical mb-1" target="_blank" href="https://github.com/hrfee/jfa-go/issues/new/choose">Create an Issue</a>
</section>
<section class="section ~neutral !low">
<section class="section ~neutral @low">
<div class="flex-expand">
<span class="subheading">Full Log</span>
<span class="button ~urge ml-half" id="copy-log">Copy</span>
</div>
<div class="row mb-1">
<label class="col mr-1">
<span class="button ~neutral !high supra full-width center" id="button-log-normal">Normal</span>
<span class="button ~neutral @high supra full-width center" id="button-log-normal">Normal</span>
</label>
<label class="col mr-1">
<span class="button ~neutral !normal supra full-width center" id="button-log-sanitized">Sanitized</span>
<span class="button ~neutral @low supra full-width center" id="button-log-sanitized">Sanitized</span>
</label>
</div>
<div id="log-normal">

View File

@ -7,10 +7,10 @@
</head>
<body class="section">
<div class="page-container">
<div class="card ~neutral !normal mb-1">
<div class="card ~neutral @low mb-1">
<span class="heading mb-1">{{ .strings.successHeader }}</span>
<p class="content mb-1">{{ .successMessage }}</p>
<a class="button ~urge !normal full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.successContinueButton }}</a>
<a class="button ~urge @low full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.successContinueButton }}</a>
</div>
<i class="content">{{ .contactMessage }}</i>
</div>

View File

@ -16,7 +16,7 @@
<div class="modal-content card">
<span class="heading mb-1">{{ if .passwordReset }}{{ .strings.passwordReset }}{{ else }}{{ .strings.successHeader }}{{ end }}</span>
<p class="content mb-1">{{ if .passwordReset }}{{ .strings.youCanLoginPassword }}{{ else }}{{ .successMessage }}{{ end }}</p>
<a class="button ~urge !normal full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.continue }}</a>
<a class="button ~urge @low full-width center supra submit" href="{{ .jfLink }}" id="create-success-button">{{ .strings.continue }}</a>
</div>
</div>
<div id="modal-confirmation" class="modal">
@ -39,7 +39,7 @@
</span>
&#64;{{ .telegramUsername }}
</a>
<span class="button ~info !normal full-width center mt-1" id="telegram-waiting">{{ .strings.success }}</span>
<span class="button ~info @low full-width center mt-1" id="telegram-waiting">{{ .strings.success }}</span>
</div>
</div>
{{ end }}
@ -50,7 +50,7 @@
<p class="content mb-1"> {{ .discordSendPINMessage }}</p>
<h1 class="ac">{{ .discordPIN }}</h1>
<a id="discord-invite"></a>
<span class="button ~info !normal full-width center mt-1" id="discord-waiting">{{ .strings.success }}</span>
<span class="button ~info @low full-width center mt-1" id="discord-waiting">{{ .strings.success }}</span>
</div>
</div>
{{ end }}
@ -59,7 +59,7 @@
<div class="modal-content card">
<span class="heading mb-1">{{ .strings.linkMatrix }}</span>
<p class="content mb-1"> {{ .strings.matrixEnterUser }}</p>
<input type="text" class="input ~neutral !high" placeholder="@user:riot.im" id="matrix-userid">
<input type="text" class="input ~neutral @high" placeholder="@user:riot.im" id="matrix-userid">
<div class="subheading link-center mt-1">
<span class="shield ~info mr-1">
<span class="icon">
@ -68,7 +68,7 @@
</span>
{{ .matrixUser }}
</div>
<span class="button ~info !normal full-width center mt-1" id="matrix-send">{{ .strings.submit }}</span>
<span class="button ~info @low full-width center mt-1" id="matrix-send">{{ .strings.submit }}</span>
</div>
</div>
{{ end }}
@ -78,13 +78,13 @@
<span class="ml-1 chev"></span>
</span>
<div class="dropdown-display">
<div class="card ~neutral !low" id="lang-list">
<div class="card ~neutral @low" id="lang-list">
</div>
</div>
</span>
<div id="notification-box"></div>
<div class="page-container">
<div class="card ~neutral !low">
<div class="card ~neutral @low">
<div class="row baseline">
<span class="col heading">
{{ if .passwordReset }}
@ -106,23 +106,23 @@
{{ if .userExpiry }}
<aside class="col aside sm ~warning" id="user-expiry-message"></aside>
{{ end }}
<form class="card ~neutral !normal" id="form-create" href="">
<form class="card ~neutral @low" id="form-create" href="">
{{ if not .passwordReset }}
<label class="label supra">
{{ .strings.username }}
<input type="text" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="create-username" aria-label="{{ .strings.username }}">
<input type="text" class="input ~neutral @high mt-half mb-1" placeholder="{{ .strings.username }}" id="create-username" aria-label="{{ .strings.username }}">
</label>
<label class="label supra" for="create-email">{{ .strings.emailAddress }}</label>
<input type="email" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.emailAddress }}" id="create-email" aria-label="{{ .strings.emailAddress }}" value="{{ .email }}">
<input type="email" class="input ~neutral @high mt-half mb-1" placeholder="{{ .strings.emailAddress }}" id="create-email" aria-label="{{ .strings.emailAddress }}" value="{{ .email }}">
{{ if .telegramEnabled }}
<span class="button ~info !normal full-width center mb-1" id="link-telegram">{{ .strings.linkTelegram }}</span>
<span class="button ~info @low full-width center mb-1" id="link-telegram">{{ .strings.linkTelegram }}</span>
{{ end }}
{{ if .discordEnabled }}
<span class="button ~info !normal full-width center mb-1" id="link-discord">{{ .strings.linkDiscord }}</span>
<span class="button ~info @low full-width center mb-1" id="link-discord">{{ .strings.linkDiscord }}</span>
{{ end }}
{{ if .matrixEnabled }}
<span class="button ~info !normal full-width center mb-1" id="link-matrix">{{ .strings.linkMatrix }}</span>
<span class="button ~info @low full-width center mb-1" id="link-matrix">{{ .strings.linkMatrix }}</span>
{{ end }}
{{ if or (.telegramEnabled) (or .discordEnabled .matrixEnabled) }}
<div id="contact-via" class="unfocused">
@ -148,13 +148,13 @@
{{ end }}
{{ end }}
<label class="label supra" for="create-password">{{ .strings.password }}</label>
<input type="password" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-password" aria-label="{{ .strings.password }}">
<input type="password" class="input ~neutral @high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-password" aria-label="{{ .strings.password }}">
<label class="label supra" for="create-reenter-password">{{ .strings.reEnterPassword }}</label>
<input type="password" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-reenter-password" aria-label="{{ .strings.reEnterPassword }}">
<input type="password" class="input ~neutral @high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-reenter-password" aria-label="{{ .strings.reEnterPassword }}">
<label>
<input type="submit" class="unfocused">
<span class="button ~urge !normal full-width center supra submit">
<span class="button ~urge @low full-width center supra submit">
{{ if .passwordReset }}
{{ .strings.reset }}
{{ else }}
@ -165,7 +165,7 @@
</form>
</div>
<div class="col">
<div class="card ~neutral !normal">
<div class="card ~neutral @low">
<span class="label supra" for="inv-uses">{{ .strings.passwordRequirementsHeader }}</span>
<ul>
{{ range $key, $value := .requirements }}

View File

@ -12,7 +12,7 @@
</div>
{{ end }}
<div class="page-container">
<div class="card ~neutral !normal mb-1">
<div class="card ~neutral @low mb-1">
<span class="heading mb-1">
{{ if .success }}
{{ .strings.passwordReset }}
@ -35,7 +35,7 @@
<aside class="aside ~warning">
{{ .strings.changeYourPassword }}
</aside>
<span class="button ~urge !normal full-width center supra p-1 mt-1" id="pin" title="{{ .strings.copy }}">{{ .pin }}</span>
<span class="button ~urge @low full-width center supra p-1 mt-1" id="pin" title="{{ .strings.copy }}">{{ .pin }}</span>
{{ end }}
</div>
<i class="content">{{ .contactMessage }}</i>

View File

@ -13,12 +13,12 @@
<span class="ml-1 chev"></span>
</span>
<div class="dropdown-display">
<div class="card ~neutral !low" id="lang-list">
<div class="card ~neutral @low" id="lang-list">
</div>
</div>
</span>
<div class="page-container" id="page-container">
<div class="card ~neutral !low mb-1">
<div class="card ~neutral @low mb-1">
<div class="row">
<img class="banner header" src="banner.svg" alt="jfa-go" />
</div>
@ -30,45 +30,45 @@
</div>
<section class="section ~neutral banner footer flex-expand middle">
<span class="support">{{ .lang.StartPage.httpsNotice }}</span>
<span class="button ~urge !normal next">{{ .lang.StartPage.start }}</span>
<span class="button ~urge @low next">{{ .lang.StartPage.start }}</span>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.Language.title }}</span>
<p class="content" id="language-description"></p>
<label class="label">
<span class="mt-half">{{ .lang.Language.defaultAdminLang }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="ui-language-admin">
</select>
</div>
</label>
<label class="label">
<span class="mt-half">{{ .lang.Language.defaultFormLang }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="ui-language-form">
</select>
</div>
</label>
<label class="label">
<span class="mt-half">{{ .lang.Language.defaultEmailLang }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="email-language">
</select>
</div>
</label>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.General.title }}</span>
<div class="row">
<div class="col">
<label class="label">
<span class="mt-half">{{ .lang.General.listenAddress }}</span>
<input type="url" class="input ~neutral !normal mt-half mb-1" id="ui-host" value="0.0.0.0">
<input type="url" class="input ~neutral @low mt-half mb-1" id="ui-host" value="0.0.0.0">
</label>
<label class="row switch">
<input type="checkbox" id="advanced-tls"><span>{{ .lang.General.useHTTPS }}</span>
@ -76,11 +76,11 @@
<p class="support mb-1">{{ .lang.General.useHTTPSNotice }}</p>
<label class="label">
<span class="mt-half">{{ .lang.General.pathToCertificate }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="advanced-tls_cert">
<input type="text" class="input ~neutral @low mt-half mb-1" id="advanced-tls_cert">
</label>
<label class="label">
<span class="mt-half">{{ .lang.General.pathToKeyFile }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="advanced-tls_key">
<input type="text" class="input ~neutral @low mt-half mb-1" id="advanced-tls_key">
</label>
<span class="heading">{{ .lang.Updates.title }}</span>
<p class="content" id="updates-description"></p>
@ -89,7 +89,7 @@
</label>
<label class="label">
<span>{{ .lang.Updates.updateChannel }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="updates-channel">
<option value="stable">{{ .lang.Updates.stable }}</option>
<option value="unstable">{{ .lang.Updates.unstable }}</option>
@ -100,20 +100,20 @@
<div class="col">
<label class="label">
<span class="mt-half">{{ .lang.Strings.port }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="ui-port" value="8056">
<input type="number" class="input ~neutral @low mt-half mb-1" id="ui-port" value="8056">
</label>
<label class="label">
<span class="mt-half">{{ .lang.General.httpsPort }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="advanced-tls_port" value="8057">
<input type="number" class="input ~neutral @low mt-half mb-1" id="advanced-tls_port" value="8057">
</label>
<label class="label">
<span class="mt-half">{{ .lang.General.urlBase }} ({{ .lang.Strings.optional }})</span>
<input type="url" class="input ~neutral !normal mt-half" id="ui-url_base">
<input type="url" class="input ~neutral @low mt-half" id="ui-url_base">
<p class="support mb-1">{{ .lang.General.urlBaseNotice }}</p>
</label>
<label class="label">
<span>{{ .lang.Strings.theme }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="ui-theme">
<option value="Jellyfin (Dark)">{{ .lang.General.darkTheme }}</option>
<option value="Default (Light)">{{ .lang.General.lightTheme }}</option>
@ -123,11 +123,11 @@
</div>
</div>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.Login.title }}</span>
<p class="content">{{ .lang.Login.description }}</p>
<div class="pl-1">
@ -144,31 +144,31 @@
<div id="login-manual">
<label class="label">
<span class="mt-half">{{ .lang.Strings.username }}</span>
<input type="text" id="ui-username" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.username }}">
<input type="text" id="ui-username" class="input ~neutral @low mt-half mb-1" placeholder="{{ .lang.Strings.username }}">
</label>
<label class="label">
<span>{{ .lang.Strings.password }}</span>
<input type="password" id="ui-password" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
<input type="password" id="ui-password" class="input ~neutral @low mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
</label>
<label class="label">
<span>{{ .lang.Strings.emailAddress }} ({{ .lang.Strings.optional }})</span>
<input type="email" id="ui-email" class="input ~neutral !normal mt-half" placeholder="email@address">
<input type="email" id="ui-email" class="input ~neutral @low mt-half" placeholder="email@address">
<span class="support mb-1">{{ .lang.Login.emailNotice }}</span>
</label>
</div>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.JellyfinEmby.title }}</span>
<p class="content">{{ .lang.JellyfinEmby.description }}</p>
<div class="row">
<div class="col">
<label class="label">
<span>{{ .lang.Strings.serverType }}</span>
<div class="select ~neutral !normal mt-half">
<div class="select ~neutral @low mt-half">
<select id="jellyfin-type">
<option value="jellyfin">Jellyfin</option>
<option value="emby">Emby</option>
@ -178,39 +178,39 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.JellyfinEmby.replaceJellyfin }} ({{ .lang.Strings.optional }})</span>
<input type="text" class="input ~neutral !normal mt-half" id="jellyfin-substitute_jellyfin_strings">
<input type="text" class="input ~neutral @low mt-half" id="jellyfin-substitute_jellyfin_strings">
<p class="support mb-1">{{ .lang.JellyfinEmby.replaceJellyfinNotice }}</p>
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.username }}</span>
<input type="text" id="jellyfin-username" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.username }}">
<input type="text" id="jellyfin-username" class="input ~neutral @low mt-half mb-1" placeholder="{{ .lang.Strings.username }}">
</label>
<label class="label">
<span>{{ .lang.Strings.password }}</span>
<input type="password" id="jellyfin-password" class="input ~neutral !normal mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
<input type="password" id="jellyfin-password" class="input ~neutral @low mt-half mb-1" placeholder="{{ .lang.Strings.password }}">
</label>
</div>
<div class="col">
<label class="label">
<span class="mt-half">{{ .lang.Strings.serverAddress }} ({{ .lang.JellyfinEmby.internal }})</span>
<input type="url" class="input ~neutral !normal mt-half mb-1" id="jellyfin-server" placeholder="http://jellyf.in:80">
<input type="url" class="input ~neutral @low mt-half mb-1" id="jellyfin-server" placeholder="http://jellyf.in:80">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.serverAddress }} ({{ .lang.JellyfinEmby.external }})</span>
<input type="url" class="input ~neutral !normal mt-half" id="jellyfin-public_server" placeholder="https://jellyf.in">
<input type="url" class="input ~neutral @low mt-half" id="jellyfin-public_server" placeholder="https://jellyf.in">
<p class="support mb-1">{{ .lang.JellyfinEmby.addressExternalNotice }}</p>
</label>
</div>
</div>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal" id="jellyfin-test-connection">{{ .lang.JellyfinEmby.testConnection }}</span>
<span class="button ~urge !normal next" disabled>{{ .lang.Strings.next }}</span>
<span class="button ~urge @low" id="jellyfin-test-connection">{{ .lang.JellyfinEmby.testConnection }}</span>
<span class="button ~urge @low next" disabled>{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.Ombi.title }}</span>
<p class="content">{{ .lang.Ombi.description }}</p>
<label class="row switch pb-1">
@ -218,21 +218,21 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.serverAddress }}</span>
<input type="url" class="input ~neutral !normal mt-half mb-1" id="ombi-server" placeholder="ombi.jellyf.in">
<input type="url" class="input ~neutral @low mt-half mb-1" id="ombi-server" placeholder="ombi.jellyf.in">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.apiKey }}</span>
<input type="text" class="input ~neutral !normal mt-half" id="ombi-api_key">
<input type="text" class="input ~neutral @low mt-half" id="ombi-api_key">
<p class="support mb-1">{{ .lang.Ombi.apiKeyNotice }}</p>
</label>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.Messages.title }}</span>
<p class="content" id="messages-description"></p>
<label class="row switch pb-1">
@ -240,7 +240,7 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.Email.dateFormat }}</span>
<input type="text" class="input ~neutral !normal mt-half" id="email-date_format" value="%d/%m/%y">
<input type="text" class="input ~neutral @low mt-half" id="email-date_format" value="%d/%m/%y">
<p class="support mb-1" id="email-dateformat-notice"></p>
</label>
<div>
@ -258,7 +258,7 @@
<div class="col">
<label class="label">
<span>{{ .lang.Email.method }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="email-method">
<option value="">{{ .lang.Strings.disabled }}</option>
<option value="smtp">SMTP</option>
@ -272,11 +272,11 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.Email.fromAddress }}</span>
<input type="email" class="input ~neutral !normal mt-half mb-1" id="email-address" placeholder="mail@jellyf.in">
<input type="email" class="input ~neutral @low mt-half mb-1" id="email-address" placeholder="mail@jellyf.in">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Email.senderName }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="email-from" value="Jellyfin">
<input type="text" class="input ~neutral @low mt-half mb-1" id="email-from" value="Jellyfin">
</label>
</div>
<div class="col">
@ -284,7 +284,7 @@
<p class="subheading">SMTP</p>
<label class="label">
<span>{{ .lang.Email.encryption }}</span>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="smtp-encryption">
<option value="starttls">STARTTLS ({{ .lang.Strings.port }} 587)</option>
<option value="ssl_tls">SSL/TLS ({{ .lang.Strings.port }} 465)</option>
@ -293,43 +293,43 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.serverAddress }}</span>
<input type="url" class="input ~neutral !normal mt-half mb-1" id="smtp-server" placeholder="smtp.jellyf.in">
<input type="url" class="input ~neutral @low mt-half mb-1" id="smtp-server" placeholder="smtp.jellyf.in">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.port }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="smtp-port" placeholder="587">
<input type="number" class="input ~neutral @low mt-half mb-1" id="smtp-port" placeholder="587">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.username }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="smtp-username">
<input type="text" class="input ~neutral @low mt-half mb-1" id="smtp-username">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.password }}</span>
<input type="password" class="input ~neutral !normal mt-half mb-1" id="smtp-password">
<input type="password" class="input ~neutral @low mt-half mb-1" id="smtp-password">
</label>
</div>
<div id="email-mailgun">
<p class="subheading">Mailgun</p>
<label class="label">
<span class="mt-half">{{ .lang.Email.mailgunApiURL }}</span>
<input type="url" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_url" placeholder="https://api.eu.mailgun.net/v3/mail.jellyf.in/messages">
<input type="url" class="input ~neutral @low mt-half mb-1" id="mailgun-api_url" placeholder="https://api.eu.mailgun.net/v3/mail.jellyf.in/messages">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.apiKey }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_key">
<input type="text" class="input ~neutral @low mt-half mb-1" id="mailgun-api_key">
</label>
</div>
</div>
</div>
</div>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused related-to-email">
<div class="card ~neutral @low mb-1 unfocused related-to-email">
<span class="heading">{{ .lang.Notifications.title }}</span>
<p class="content">{{ .lang.Notifications.description }}</p>
<label class="row switch pb-1">
@ -342,16 +342,16 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.emailSubject }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="welcome_email-subject" placeholder="{{ .emailLang.WelcomeEmail.title }}">
<input type="text" class="input ~neutral @low mt-half mb-1" id="welcome_email-subject" placeholder="{{ .emailLang.WelcomeEmail.title }}">
</label>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused related-to-email">
<div class="card ~neutral @low mb-1 unfocused related-to-email">
<span class="heading">{{ .lang.InviteEmails.title }}</span>
<p class="content">{{ .lang.InviteEmails.description }}</p>
<label class="row switch pb-1">
@ -359,20 +359,20 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.URL }}</span>
<input type="url" class="input ~neutral !normal mt-half mb-1" id="invite_emails-url_base" placeholder="https://accounts.jellyf.in/invite">
<input type="url" class="input ~neutral @low mt-half mb-1" id="invite_emails-url_base" placeholder="https://accounts.jellyf.in/invite">
</label>
<label class="label">
<span class="mt-half">{{ .lang.Strings.emailSubject }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="invite_emails-subject" placeholder="{{ .emailLang.InviteEmail.title }}">
<input type="text" class="input ~neutral @low mt-half mb-1" id="invite_emails-subject" placeholder="{{ .emailLang.InviteEmail.title }}">
</label>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div id="password-resets" class="card ~neutral !low mb-1 unfocused related-to-email">
<div id="password-resets" class="card ~neutral @low mb-1 unfocused related-to-email">
<span class="heading">{{ .lang.PasswordResets.title }}</span>
<p class="content">{{ .lang.PasswordResets.description }}</p>
<label class="row switch pb-1">
@ -380,7 +380,7 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.PasswordResets.pathToJellyfin }}</span>
<input type="text" class="input ~neutral !normal mt-half" id="password_resets-watch_directory" placeholder="/config/jellyfin">
<input type="text" class="input ~neutral @low mt-half" id="password_resets-watch_directory" placeholder="/config/jellyfin">
<p class="support mb-1">{{ .lang.PasswordResets.pathToJellyfinNotice }}</p>
</label>
<label class="switch">
@ -393,23 +393,23 @@
</label>
<label class="label">
<p class="mt-half">{{ .lang.PasswordResets.resetLinksLanguage }}</p>
<div class="select ~neutral !normal mt-half mb-1">
<div class="select ~neutral @low mt-half mb-1">
<select id="password_resets-language">
</select>
</div>
</label>
<label class="row label">
<span class="mt-half">{{ .lang.Strings.emailSubject }}</span>
<input type="text" class="input ~neutral !normal mt-half mb-1" id="password_resets-subject" placeholder="{{ .emailLang.PasswordReset.title }}">
<input type="text" class="input ~neutral @low mt-half mb-1" id="password_resets-subject" placeholder="{{ .emailLang.PasswordReset.title }}">
</label>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.PasswordValidation.title }}</span>
<p class="content">{{ .lang.PasswordValidation.description }}</p>
<label class="row switch pb-1">
@ -417,62 +417,62 @@
</label>
<label class="label">
<span class="mt-half">{{ .lang.PasswordValidation.length }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-min_length" value="8">
<input type="number" class="input ~neutral @low mt-half mb-1" id="password_validation-min_length" value="8">
</label>
<label class="label">
<span class="mt-half">{{ .lang.PasswordValidation.uppercase }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-upper" value="1">
<input type="number" class="input ~neutral @low mt-half mb-1" id="password_validation-upper" value="1">
</label>
<label class="label">
<span class="mt-half">{{ .lang.PasswordValidation.lowercase }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-lower" value="0">
<input type="number" class="input ~neutral @low mt-half mb-1" id="password_validation-lower" value="0">
</label>
<label class="label">
<span class="mt-half">{{ .lang.PasswordValidation.numbers }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-number" value="0">
<input type="number" class="input ~neutral @low mt-half mb-1" id="password_validation-number" value="0">
</label>
<label class="label">
<span class="mt-half">{{ .lang.PasswordValidation.special }}</span>
<input type="number" class="input ~neutral !normal mt-half mb-1" id="password_validation-special" value="0">
<input type="number" class="input ~neutral @low mt-half mb-1" id="password_validation-special" value="0">
</label>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<span class="heading">{{ .lang.HelpMessages.title }}</span>
<p class="content">{{ .lang.HelpMessages.description }}</p>
<label class="label">
<span class="mt-half">{{ .lang.HelpMessages.contactMessage }}</span>
<input type="text" class="input ~neutral !normal mt-half" id="ui-contact_message">
<input type="text" class="input ~neutral @low mt-half" id="ui-contact_message">
<p class="support mb-1">{{ .lang.HelpMessages.contactMessageNotice }}</p>
</label>
<label class="label">
<span class="mt-half">{{ .lang.HelpMessages.helpMessage }}</span>
<input type="text" class="input ~neutral !normal mt-half" id="ui-help_message">
<input type="text" class="input ~neutral @low mt-half" id="ui-help_message">
<p class="support mb-1">{{ .lang.HelpMessages.helpMessageNotice }}</p>
</label>
<label class="label">
<span class="mt-half">{{ .lang.HelpMessages.successMessage }}</span>
<input type="text" class="input ~neutral !normal mt-half" id="ui-success_message">
<input type="text" class="input ~neutral @low mt-half" id="ui-success_message">
<p class="support mb-1">{{ .lang.HelpMessages.successMessageNotice }}</p>
</label>
<label class="label related-to-email">
<span class="mt-half">{{ .lang.HelpMessages.emailMessage }}</span>
<input type="text" class="input ~neutral !normal mt-half" id="email-message">
<input type="text" class="input ~neutral @low mt-half" id="email-message">
<p class="support mb-1">{{ .lang.HelpMessages.emailMessageNotice }}</p>
</label>
<section class="section ~neutral banner footer flex-expand middle">
<span class="button ~neutral !normal back">{{ .lang.Strings.back }}</span>
<span class="button ~neutral @low back">{{ .lang.Strings.back }}</span>
<div>
<span class="button ~urge !normal next">{{ .lang.Strings.next }}</span>
<span class="button ~urge @low next">{{ .lang.Strings.next }}</span>
</div>
</section>
</div>
<div class="card ~neutral !low mb-1 unfocused">
<div class="card ~neutral @low mb-1 unfocused">
<div class="row col flex center">
<span class="heading">{{ .lang.EndPage.finished }}</span>
</div>
@ -480,9 +480,9 @@
<p class="content">{{ .lang.EndPage.restartMessage }}</p>
</div>
<div class="row col flex center">
<span class="button ~neutral !normal back mr-1">{{ .lang.Strings.back }}</span>
<span class="button ~urge !normal" id="restart">{{ .lang.Strings.submit }}</span>
<span class="button ~urge !normal unfocused" id="refresh">{{ .lang.EndPage.refreshPage }}</span>
<span class="button ~neutral @low back mr-1">{{ .lang.Strings.back }}</span>
<span class="button ~urge @low" id="restart">{{ .lang.Strings.submit }}</span>
<span class="button ~urge @low unfocused" id="refresh">{{ .lang.EndPage.refreshPage }}</span>
</div>
</div>
</div>

1680
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@
"dependencies": {
"@ts-stack/markdown": "^1.3.0",
"@types/node": "^15.0.1",
"a17t": "^0.4.0",
"a17t": "^0.10.1",
"browserslist": "^4.16.6",
"esbuild": "^0.8.57",
"inline-source": "^7.2.0",

7
scripts/dark-variant.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
for f in $1/*.html; do
for color in neutral positive urge warning info critical; do
sed -i "s/~${color}/~${color} dark:~d_${color}/g" $f
done
done

View File

@ -53,7 +53,7 @@ sudo apt-get install jfa-go-tray
</div>
</div>
<div class="page-container" id="page-container">
<div class="card ~neutral !low mb-1">
<div class="card ~neutral @low mb-1">
<div class="row col flex center">
<span class="heading welcome">jellyfin-accounts (go)</span>
</div>
@ -84,19 +84,19 @@ sudo apt-get install jfa-go-tray
<span class="ml-1 chev"></span>
</a>
<div class="dropdown-display">
<div class="card ~info !low">
<div class="card ~info @low">
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">GitHub</a>
<a href="https://ko-fi.com/hrfee" target="_blank" class="button input ~neutral field mb-half lang-link">Ko-fi</a>
</div>
</div>
</div>
<a class="button ~urge mt-1 mb-1 !normal discord" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-half"></i>discord</a>
<a class="button ~urge mt-1 mb-1 @low discord" href="https://discord.com/invite/MrtvuQmyhP" target="_blank"><i class="ri-discord-line mr-half"></i>discord</a>
</div>
<p class="row col flex center supra">downloads</p>
<p class="row col flex center support">instructions can be found&nbsp<a target="_blank" href="https://github.com/hrfee/jfa-go#install">here</a></p>
<p class="row col flex center text-center support">note: tray icon builds should only be used on systems with a Desktop Interface, and require extra dependencies on linux, see the github README for more info.</p>
<div class="row col flex center">
<span class="button ~neutral !high mr-1 mt-1" id="download-stable">Stable</span>
<span class="button ~neutral @high mr-1 mt-1" id="download-stable">Stable</span>
<span class="button ~neutral mt-1 mr-1" id="download-unstable">Unstable</span>
</div>
<div class="mt-1" id="sect-stable">

View File

@ -29,8 +29,8 @@ const dockerUnstable = document.getElementById("docker-unstable");
stableButton.onclick = () => {
debUnstable.classList.add("unfocused");
dockerUnstable.classList.add("unfocused");
stableButton.classList.add("!high");
unstableButton.classList.remove("!high");
stableButton.classList.add("@high");
unstableButton.classList.remove("@high");
stableSect.classList.remove("unfocused");
unstableSect.classList.add("unfocused");
@ -39,8 +39,8 @@ stableButton.onclick = () => {
unstableButton.onclick = () => {
debUnstable.classList.remove("unfocused");
dockerUnstable.classList.remove("unfocused");
unstableButton.classList.add("!high");
stableButton.classList.remove("!high");
unstableButton.classList.add("@high");
stableButton.classList.remove("@high");
stableSect.classList.add("unfocused");
unstableSect.classList.remove("unfocused");
}

View File

@ -39,7 +39,7 @@ export const loadBuilds = () => {
<span class="ml-half chev"></span>
</span>
<div class="dropdown-display above">
<div class="card ~info !low">
<div class="card ~info @low">
`;
for (let arch in categories[buildName]) {
innerHTML += `

26
tailwind.config.js Normal file
View File

@ -0,0 +1,26 @@
let colors = require("tailwindcss/colors")
let dark = require("./css/dark");
module.exports = {
content: ["./data/html/*.html", "./build/data/html/*.html", "./ts/*.ts", "./ts/modules/*.ts"],
darkMode: 'class',
theme: {
extend: {
colors: {
neutral: colors.slate,
positive: colors.green,
urge: colors.violet,
warning: colors.yellow,
info: colors.blue,
critical: colors.red,
d_neutral: dark.d_neutral,
d_positive: dark.d_positive,
d_urge: dark.d_urge,
d_warning: dark.d_warning,
d_info: dark.d_info,
d_critical: dark.d_critical
}
},
},
plugins: [require("a17t")],
}

View File

@ -13,16 +13,16 @@ loadTheme();
const themeButton = document.getElementById('button-theme') as HTMLSpanElement;
const switchThemeIcon = () => {
const icon = themeButton.childNodes[0] as HTMLElement;
if (document.documentElement.classList.contains("dark-theme")) {
if (document.documentElement.classList.contains("dark")) {
icon.classList.add("ri-sun-line");
icon.classList.remove("ri-moon-line");
themeButton.classList.add("~warning");
themeButton.classList.remove("~neutral");
themeButton.classList.remove("!high");
themeButton.classList.remove("@high");
} else {
icon.classList.add("ri-moon-line");
icon.classList.remove("ri-sun-line");
themeButton.classList.add("!high");
themeButton.classList.add("@high");
themeButton.classList.add("~neutral");
themeButton.classList.remove("~warning");
}
@ -117,10 +117,10 @@ window.notifications = new notificationBox(document.getElementById('notification
const user = document.getElementById('radio-use-user') as HTMLInputElement;
const profileSelect = document.getElementById('modify-user-profiles') as HTMLDivElement;
const userSelect = document.getElementById('modify-user-users') as HTMLDivElement;
(user.nextElementSibling as HTMLSpanElement).classList.toggle('!normal');
(user.nextElementSibling as HTMLSpanElement).classList.toggle('!high');
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('!normal');
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('!high');
(user.nextElementSibling as HTMLSpanElement).classList.toggle('@low');
(user.nextElementSibling as HTMLSpanElement).classList.toggle('@high');
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('@low');
(profile.nextElementSibling as HTMLSpanElement).classList.toggle('@high');
profileSelect.classList.toggle('unfocused');
userSelect.classList.toggle('unfocused');
}*/

View File

@ -11,17 +11,17 @@ const buttonChange = (type: string) => {
if (type == "normal") {
logSanitized.classList.add("unfocused");
logNormal.classList.remove("unfocused");
buttonNormal.classList.add("!high");
buttonNormal.classList.remove("!normal");
buttonSanitized.classList.add("!normal");
buttonSanitized.classList.remove("!high");
buttonNormal.classList.add("@high");
buttonNormal.classList.remove("@low");
buttonSanitized.classList.add("@low");
buttonSanitized.classList.remove("@high");
} else {
logNormal.classList.add("unfocused");
logSanitized.classList.remove("unfocused");
buttonSanitized.classList.add("!high");
buttonSanitized.classList.remove("!normal");
buttonNormal.classList.add("!normal");
buttonNormal.classList.remove("!high");
buttonSanitized.classList.add("@high");
buttonSanitized.classList.remove("@low");
buttonNormal.classList.add("@low");
buttonNormal.classList.remove("@high");
}
}
buttonNormal.onclick = () => buttonChange("normal");

View File

@ -133,7 +133,7 @@ class user implements User {
<i class="icon ri-settings-2-line ml-half dropdown-button"></i>
<div class="dropdown manual">
<div class="dropdown-display lg">
<div class="card ~neutral !low">
<div class="card ~neutral @low">
<span class="supra sm">${window.lang.strings("contactThrough")}</span>
<label class="row switch pb-1 mt-half">
<input type="checkbox" name="accounts-contact-${this.id}" class="accounts-contact-email">
@ -193,8 +193,8 @@ class user implements User {
if (!u) {
this._notifyDropdown.querySelector(".accounts-area-matrix").classList.add("unfocused");
this._matrix.innerHTML = `
<span class="chip btn !low">${window.lang.strings("add")}</span>
<input type="text" class="input ~neutral !normal stealth-input unfocused" placeholder="@user:riot.im">
<span class="chip btn @low">${window.lang.strings("add")}</span>
<input type="text" class="input ~neutral @low stealth-input unfocused" placeholder="@user:riot.im">
`;
(this._matrix.querySelector("span") as HTMLSpanElement).onclick = this._addMatrix;
} else {
@ -257,7 +257,7 @@ class user implements User {
this._telegramUsername = u;
if (!u) {
this._notifyDropdown.querySelector(".accounts-area-telegram").classList.add("unfocused");
this._telegram.innerHTML = `<span class="chip btn !low">${window.lang.strings("add")}</span>`;
this._telegram.innerHTML = `<span class="chip btn @low">${window.lang.strings("add")}</span>`;
(this._telegram.querySelector("span") as HTMLSpanElement).onclick = this._addTelegram;
} else {
this._notifyDropdown.querySelector(".accounts-area-telegram").classList.remove("unfocused");
@ -322,7 +322,7 @@ class user implements User {
const lastNotifyMethod = this.lastNotifyMethod() == "discord";
this._discordUsername = u;
if (!u) {
this._discord.innerHTML = `<span class="chip btn !low">Add</span>`;
this._discord.innerHTML = `<span class="chip btn @low">Add</span>`;
(this._discord.querySelector("span") as HTMLSpanElement).onclick = () => addDiscord(this.id);
this._notifyDropdown.querySelector(".accounts-area-discord").classList.add("unfocused");
} else {
@ -403,7 +403,7 @@ class user implements User {
<td class="accounts-last-active"></td>
`;
this._row.innerHTML = innerHTML;
const emailEditor = `<input type="email" class="input ~neutral !normal stealth-input">`;
const emailEditor = `<input type="email" class="input ~neutral @low stealth-input">`;
this._check = this._row.querySelector("input[type=checkbox]") as HTMLInputElement;
this._username = this._row.querySelector(".accounts-username") as HTMLSpanElement;
this._admin = this._row.querySelector(".accounts-admin") as HTMLSpanElement;
@ -1281,17 +1281,17 @@ export class accountsList {
if (this._modifySettingsProfile.checked) {
this._userSelect.parentElement.classList.add("unfocused");
this._profileSelect.parentElement.classList.remove("unfocused")
profileSpan.classList.add("!high");
profileSpan.classList.remove("!normal");
userSpan.classList.remove("!high");
userSpan.classList.add("!normal");
profileSpan.classList.add("@high");
profileSpan.classList.remove("@low");
userSpan.classList.remove("@high");
userSpan.classList.add("@low");
} else {
this._userSelect.parentElement.classList.remove("unfocused");
this._profileSelect.parentElement.classList.add("unfocused");
userSpan.classList.add("!high");
userSpan.classList.remove("!normal");
profileSpan.classList.remove("!high");
profileSpan.classList.add("!normal");
userSpan.classList.add("@high");
userSpan.classList.remove("@low");
profileSpan.classList.remove("@high");
profileSpan.classList.add("@low");
}
};
this._modifySettingsProfile.onchange = checkSource;

View File

@ -104,14 +104,14 @@ export class notificationBox implements NotificationBox {
private _error = (message: string): HTMLElement => {
const noti = document.createElement('aside');
noti.classList.add("aside", "~critical", "!normal", "mt-half", "notification-error");
noti.classList.add("aside", "~critical", "@low", "mt-half", "notification-error");
let error = "";
if (window.lang) {
error = window.lang.strings("error") + ":"
}
noti.innerHTML = `<strong>${error}</strong> ${message}`;
const closeButton = document.createElement('span') as HTMLSpanElement;
closeButton.classList.add("button", "~critical", "!low", "ml-1");
closeButton.classList.add("button", "~critical", "@low", "ml-1");
closeButton.innerHTML = `<i class="icon ri-close-line"></i>`;
closeButton.onclick = () => { this._box.removeChild(noti); };
noti.appendChild(closeButton);
@ -120,10 +120,10 @@ export class notificationBox implements NotificationBox {
private _positive = (bold: string, message: string): HTMLElement => {
const noti = document.createElement('aside');
noti.classList.add("aside", "~positive", "!normal", "mt-half", "notification-positive");
noti.classList.add("aside", "~positive", "@low", "mt-half", "notification-positive");
noti.innerHTML = `<strong>${bold}</strong> ${message}`;
const closeButton = document.createElement('span') as HTMLSpanElement;
closeButton.classList.add("button", "~positive", "!low", "ml-1");
closeButton.classList.add("button", "~positive", "@low", "ml-1");
closeButton.innerHTML = `<i class="icon ri-close-line"></i>`;
closeButton.onclick = () => { this._box.removeChild(noti); };
noti.appendChild(closeButton);

View File

@ -43,7 +43,7 @@ export function newDiscordSearch(title: string, description: string, buttonText:
<p class="content">${users[i].name}</p>
</td>
<td class="sm">
<span id="discord-user-${users[i].id}" class="button ~info !high">${buttonText}</span>
<span id="discord-user-${users[i].id}" class="button ~info @high">${buttonText}</span>
</td>
</tr>
`;

View File

@ -251,14 +251,14 @@ class DOMInvite implements Invite {
this._header = document.createElement('div') as HTMLDivElement;
this._container.appendChild(this._header);
this._header.classList.add("card", "~neutral", "!normal", "inv-header", "elem-pad", "no-pad", "flex-expand", "row", "mt-half", "overflow-y");
this._header.classList.add("card", "~neutral", "@low", "inv-header", "elem-pad", "no-pad", "flex-expand", "row", "mt-half", "overflow-y");
this._codeArea = document.createElement('div') as HTMLDivElement;
this._header.appendChild(this._codeArea);
this._codeArea.classList.add("inv-codearea");
this._codeArea.innerHTML = `
<a class="invite-link code monospace mr-1" href=""></a>
<span class="button ~info !normal" title="${window.lang.strings("copy")}"><i class="ri-file-copy-line"></i></span>
<span class="button ~info @low" title="${window.lang.strings("copy")}"><i class="ri-file-copy-line"></i></span>
`;
const copyButton = this._codeArea.querySelector("span.button") as HTMLSpanElement;
copyButton.onclick = () => {
@ -285,7 +285,7 @@ class DOMInvite implements Invite {
<span class="content sm"></span>
</div>
<span class="inv-duration mr-1"></span>
<span class="button ~critical !normal inv-delete">${window.lang.strings("delete")}</span>
<span class="button ~critical @low inv-delete">${window.lang.strings("delete")}</span>
<label>
<i class="icon clickable ri-arrow-down-s-line not-rotated"></i>
<input class="inv-toggle-details unfocused" type="checkbox">
@ -304,7 +304,7 @@ class DOMInvite implements Invite {
this._details = document.createElement('div') as HTMLDivElement;
this._container.appendChild(this._details);
this._details.classList.add("card", "~neutral", "!normal", "mt-half", "no-pad", "inv-details");
this._details.classList.add("card", "~neutral", "@low", "mt-half", "no-pad", "inv-details");
const detailsInner = document.createElement('div') as HTMLDivElement;
this._details.appendChild(detailsInner);
detailsInner.classList.add("inv-row", "flex-expand", "row", "elem-pad", "align-top");
@ -314,7 +314,7 @@ class DOMInvite implements Invite {
this._left.classList.add("inv-profilearea");
let innerHTML = `
<p class="supra mb-1 top">${window.lang.strings("profile")}</p>
<div class="select ~neutral !normal inv-profileselect inline-block">
<div class="select ~neutral @low inv-profileselect inline-block">
<select>
<option value="noProfile" selected>${window.lang.strings("inviteNoProfile")}</option>
</select>
@ -355,7 +355,7 @@ class DOMInvite implements Invite {
this._right = document.createElement('div') as HTMLDivElement;
detailsInner.appendChild(this._right);
this._right.classList.add("card", "~neutral", "!low", "inv-created-users");
this._right.classList.add("card", "~neutral", "@low", "inv-created-users");
this._right.innerHTML = `<strong class="supra table-header">${window.lang.strings("inviteUsersCreated")}</strong>`;
this._userTable = document.createElement('div') as HTMLDivElement;
this._right.appendChild(this._userTable);
@ -425,7 +425,7 @@ export class inviteList implements inviteList {
this._list.classList.add("empty");
this._list.innerHTML = `
<div class="inv inv-empty">
<div class="card ~neutral !normal inv-header flex-expand mt-half">
<div class="card ~neutral @low inv-header flex-expand mt-half">
<div class="inv-codearea">
<span class="code monospace">${window.lang.strings("inviteNoInvites")}</span>
</div>
@ -787,17 +787,17 @@ export class createInvite {
if (this._invDurationButton.checked) {
this._invDuration.classList.remove("unfocused");
this._userExpiry.classList.add("unfocused");
invSpan.classList.add("!high");
invSpan.classList.remove("!normal");
userSpan.classList.add("!normal");
userSpan.classList.remove("!high");
invSpan.classList.add("@high");
invSpan.classList.remove("@low");
userSpan.classList.add("@low");
userSpan.classList.remove("@high");
} else if (this._userExpiryButton.checked) {
this._userExpiry.classList.remove("unfocused");
this._invDuration.classList.add("unfocused");
invSpan.classList.add("!normal");
invSpan.classList.remove("!high");
userSpan.classList.add("!high");
userSpan.classList.remove("!normal");
invSpan.classList.add("@low");
invSpan.classList.remove("@high");
userSpan.classList.add("@high");
userSpan.classList.remove("@low");
}
};

View File

@ -62,12 +62,12 @@ class profile implements Profile {
<td><input type="radio" name="profile-default"></td>
`;
if (window.ombiEnabled) innerHTML += `
<td><span class="button !normal profile-ombi"></span></td>
<td><span class="button @low profile-ombi"></span></td>
`;
innerHTML += `
<td class="profile-from ellipsis"></td>
<td class="profile-libraries"></td>
<td><span class="button ~critical !normal">${window.lang.strings("delete")}</span></td>
<td><span class="button ~critical @low">${window.lang.strings("delete")}</span></td>
`;
this._row.innerHTML = innerHTML;
this._name = this._row.querySelector("b.profile-name");

View File

@ -109,7 +109,7 @@ class DOMInput {
<i class="icon ri-information-line"></i>
<span class="content sm"></span>
</div>
<input type="${inputType}" class="input ~neutral !normal mt-half mb-half">
<input type="${inputType}" class="input ~neutral @low mt-half mb-half">
</label>
`;
this._tooltip = this._container.querySelector("div.setting-tooltip") as HTMLDivElement;
@ -403,7 +403,7 @@ class DOMSelect implements SSelect {
<i class="icon ri-information-line"></i>
<span class="content sm"></span>
</div>
<div class="select ~neutral !normal mt-half mb-half">
<div class="select ~neutral @low mt-half mb-half">
<select class="settings-select"></select>
</div>
</label>
@ -549,7 +549,7 @@ export class settingsList {
this._sections[name] = section;
this._panel.appendChild(this._sections[name].asElement());
const button = document.createElement("span") as HTMLSpanElement;
button.classList.add("button", "~neutral", "!low", "settings-section-button", "mb-half");
button.classList.add("button", "~neutral", "@low", "settings-section-button", "mb-half");
button.textContent = s.meta.name;
if (subButton) { button.appendChild(subButton); }
button.onclick = () => { this._showPanel(name); };
@ -710,7 +710,7 @@ export class settingsList {
const editButton = document.createElement("div");
editButton.classList.add("tooltip", "left");
editButton.innerHTML = `
<span class="button ~neutral !normal">
<span class="button ~neutral @low">
<i class="icon ri-edit-line"></i>
</span>
<span class="content sm">
@ -731,7 +731,7 @@ export class settingsList {
const addButton = document.createElement("div");
addButton.classList.add("tooltip", "left");
addButton.innerHTML = `
<span class="button ~neutral !normal">+</span>
<span class="button ~neutral @low">+</span>
<span class="content sm">
${window.lang.strings("linkMatrix")}
</span>
@ -808,7 +808,7 @@ class EmailEditor {
let innerHTML = '';
for (let i = 0; i < this._templ.variables.length; i++) {
let ci = i % colors.length;
innerHTML += '<span class="button ~' + colors[ci] +' !normal mb-1" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
innerHTML += '<span class="button ~' + colors[ci] +' @low mb-1" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
}
if (this._templ.variables.length == 0) {
this._variablesLabel.classList.add("unfocused");
@ -832,7 +832,7 @@ class EmailEditor {
} else {
for (let i = this._templ.conditionals.length-1; i >= 0; i--) {
let ci = i % colors.length;
innerHTML += '<span class="button ~' + colors[ci] +' !normal mb-1" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
innerHTML += '<span class="button ~' + colors[ci] +' @low mb-1" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
}
this._conditionalsLabel.classList.remove("unfocused");
this._conditionals.innerHTML = innerHTML
@ -896,7 +896,7 @@ class EmailEditor {
tr.innerHTML = `
<td>${this._names[id].name}</td>
<td>${resetButton}</td>
<td><span class="button ~info !normal" title="${window.lang.get("strings", "edit")}"><i class="icon ri-edit-line"></i></span></td>
<td><span class="button ~info @low" title="${window.lang.get("strings", "edit")}"><i class="icon ri-edit-line"></i></span></td>
`;
(tr.querySelector("span.button") as HTMLSpanElement).onclick = () => {
window.modals.customizeEmails.close()

View File

@ -1,19 +1,19 @@
export function toggleTheme() {
document.documentElement.classList.toggle('dark-theme');
document.documentElement.classList.toggle('light-theme');
localStorage.setItem('theme', document.documentElement.classList.contains('dark-theme') ? "dark" : "light");
document.documentElement.classList.toggle('dark');
document.documentElement.classList.toggle('light');
localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? "dark" : "light");
}
export function loadTheme() {
const theme = localStorage.getItem("theme");
if (theme == "dark") {
document.documentElement.classList.add('dark-theme');
document.documentElement.classList.remove('light-theme');
document.documentElement.classList.add('dark');
document.documentElement.classList.remove('light');
} else if (theme == "light") {
document.documentElement.classList.add('light-theme');
document.documentElement.classList.remove('dark-theme');
document.documentElement.classList.add('light');
document.documentElement.classList.remove('dark');
} else if (window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all') {
document.documentElement.classList.add('dark-theme');
document.documentElement.classList.remove('light-theme');
document.documentElement.classList.add('dark');
document.documentElement.classList.remove('light');
}
}