From f78a5158e160fce03b333ad0aea6b2e136d42f67 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 2 Oct 2018 21:43:58 +0300
Subject: [PATCH 01/96] something works without exploding and i'm tired already

---
 package.json                                  |   1 +
 src/App.scss                                  |  10 +-
 src/components/settings/settings.vue          |   2 +
 .../style_switcher/style_switcher.js          | 141 +++++++++-----
 .../style_switcher/style_switcher.vue         | 174 ++++++++----------
 src/lib/persisted_state.js                    |   1 +
 src/services/color_convert/color_convert.js   |  12 ++
 src/services/style_setter/style_setter.js     | 134 +++++++++-----
 yarn.lock                                     |   4 +
 9 files changed, 297 insertions(+), 182 deletions(-)

diff --git a/package.json b/package.json
index b716e7c6..1149d200 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
   "dependencies": {
     "babel-plugin-add-module-exports": "^0.2.1",
     "babel-plugin-lodash": "^3.2.11",
+    "chromatism": "^3.0.0",
     "diff": "^3.0.1",
     "karma-mocha-reporter": "^2.2.1",
     "localforage": "^1.5.0",
diff --git a/src/App.scss b/src/App.scss
index 056a235e..1119caf2 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -51,7 +51,7 @@ a {
 button {
   user-select: none;
   color: $fallback--fg;
-  color: var(--fg, $fallback--fg);
+  color: var(--btnText, $fallback--fg);
   background-color: $fallback--btn;
   background-color: var(--btn, $fallback--btn);
   border: none;
@@ -254,7 +254,7 @@ nav {
       mask-position: center;
       mask-size: contain;
       background-color: $fallback--fg;
-      background-color: var(--fg, $fallback--fg);
+      background-color: var(--topBarText, $fallback--fg);
       position: absolute;
       top: 0;
       bottom: 0;
@@ -330,8 +330,9 @@ main-router {
   padding: .6em .6em;
   text-align: left;
   line-height: 28px;
+  color: var(--panelText);
   background-color: $fallback--btn;
-  background-color: var(--btn, $fallback--btn);
+  background-color: var(--panel, $fallback--btn);
   align-items: baseline;
 
   .title {
@@ -387,8 +388,9 @@ main-router {
 
 nav {
   z-index: 1000;
+  color: var(--topBarText);
   background-color: $fallback--btn;
-  background-color: var(--btn, $fallback--btn);
+  background-color: var(--topBar, $fallback--btn);
   color: $fallback--faint;
   color: var(--faint, $fallback--faint);
   box-shadow: 0px 0px 4px rgba(0,0,0,.6);
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index 42c660a3..eebb2cb7 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -18,6 +18,7 @@
     </transition>
   </div>
   <div class="panel-body">
+<keep-alive>
     <tab-switcher>
       <div :label="$t('settings.general')" >
         <div class="setting-item">
@@ -146,6 +147,7 @@
       </div>
 
     </tab-switcher>
+</keep-alive>
   </div>
 </div>
 </template>
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 95c15b49..5f76c038 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,4 +1,7 @@
-import { rgbstr2hex } from '../../services/color_convert/color_convert.js'
+import { rgb2hex } from '../../services/color_convert/color_convert.js'
+import ColorInput from '../color_input/color_input.vue'
+import OpacityInput from '../opacity_input/opacity_input.vue'
+import StyleSetter from '../../services/style_setter/style_setter.js'
 
 export default {
   data () {
@@ -7,13 +10,23 @@ export default {
       selected: this.$store.state.config.theme,
       invalidThemeImported: false,
       bgColorLocal: '',
+      bgOpacityLocal: 0,
       btnColorLocal: '',
+      btnOpacityLocal: '',
+
       textColorLocal: '',
       linkColorLocal: '',
+
+      panelColorLocal: undefined,
+      panelOpacityLocal: undefined,
+      topBarColorLocal: undefined,
+      topBarOpacityLocal: undefined,
+
       redColorLocal: '',
       blueColorLocal: '',
       greenColorLocal: '',
       orangeColorLocal: '',
+
       btnRadiusLocal: '',
       inputRadiusLocal: '',
       panelRadiusLocal: '',
@@ -33,7 +46,48 @@ export default {
       })
   },
   mounted () {
-    this.normalizeLocalState(this.$store.state.config.colors, this.$store.state.config.radii)
+    this.normalizeLocalState(this.$store.state.config.customTheme)
+  },
+  computed: {
+    currentTheme () {
+      return {
+        colors: {
+          bg: this.bgColorLocal,
+          fg: this.textColorLocal,
+          panel: this.panelColorLocal,
+          topBar: this.topBarColorLocal,
+          btn: this.btnColorLocal,
+          link: this.linkColorLocal,
+          cRed: this.redColorLocal,
+          cBlue: this.blueColorLocal,
+          cGreen: this.greenColorLocal,
+          cOrange: this.orangeColorLocal
+        },
+        radii: {
+          btnRadius: this.btnRadiusLocal,
+          inputRadius: this.inputRadiusLocal,
+          panelRadius: this.panelRadiusLocal,
+          avatarRadius: this.avatarRadiusLocal,
+          avatarAltRadius: this.avatarAltRadiusLocal,
+          tooltipRadius: this.tooltipRadiusLocal,
+          attachmentRadius: this.attachmentRadiusLocal
+        }
+      }
+    },
+    previewRules () {
+      try {
+        const generated = StyleSetter.generatePreset(this.currentTheme.colors)
+        return [generated.colorRules, generated.radiiRules].join(';')
+      } catch (e) {
+        console.error('CATCH')
+        console.error(e)
+        return ''
+      }
+    }
+  },
+  components: {
+    ColorInput,
+    OpacityInput
   },
   methods: {
     exportCurrentTheme () {
@@ -101,57 +155,62 @@ export default {
           b: parseInt(result[3], 16)
         } : null
       }
-      const bgRgb = rgb(this.bgColorLocal)
-      const btnRgb = rgb(this.btnColorLocal)
-      const textRgb = rgb(this.textColorLocal)
-      const linkRgb = rgb(this.linkColorLocal)
 
-      const redRgb = rgb(this.redColorLocal)
-      const blueRgb = rgb(this.blueColorLocal)
-      const greenRgb = rgb(this.greenColorLocal)
-      const orangeRgb = rgb(this.orangeColorLocal)
-
-      if (bgRgb && btnRgb && linkRgb) {
-        this.$store.dispatch('setOption', {
-          name: 'customTheme',
-          value: {
-            fg: btnRgb,
-            bg: bgRgb,
-            text: textRgb,
-            link: linkRgb,
-            cRed: redRgb,
-            cBlue: blueRgb,
-            cGreen: greenRgb,
-            cOrange: orangeRgb,
-            btnRadius: this.btnRadiusLocal,
-            inputRadius: this.inputRadiusLocal,
-            panelRadius: this.panelRadiusLocal,
-            avatarRadius: this.avatarRadiusLocal,
-            avatarAltRadius: this.avatarAltRadiusLocal,
-            tooltipRadius: this.tooltipRadiusLocal,
-            attachmentRadius: this.attachmentRadiusLocal
-          }})
-      }
+      this.$store.dispatch('setOption', {
+        name: 'customTheme',
+        value: this.currentTheme
+      })
     },
 
-    normalizeLocalState (colors, radii) {
-      this.bgColorLocal = rgbstr2hex(colors.bg)
-      this.btnColorLocal = rgbstr2hex(colors.btn)
-      this.textColorLocal = rgbstr2hex(colors.fg)
-      this.linkColorLocal = rgbstr2hex(colors.link)
+    normalizeLocalState (input) {
+      const colors = input.colors || input
+      const radii = input.radii || input
+      let i = 0
+      console.log('BENIS')
+      console.log(colors)
 
-      this.redColorLocal = rgbstr2hex(colors.cRed)
-      this.blueColorLocal = rgbstr2hex(colors.cBlue)
-      this.greenColorLocal = rgbstr2hex(colors.cGreen)
-      this.orangeColorLocal = rgbstr2hex(colors.cOrange)
+      console.log(i++)
+      this.bgColorLocal = rgb2hex(colors.bg)
+      console.log(i++)
+      this.btnColorLocal = rgb2hex(colors.btn)
+      console.log(i++)
+      this.textColorLocal = rgb2hex(colors.text || colors.fg)
+      console.log(i++)
+      this.linkColorLocal = rgb2hex(colors.link)
+      console.log(i++)
+
+      this.panelColorLocal = colors.panel ? rgb2hex(colors.panel) : undefined
+      console.log(i++)
+      this.topBarColorLocal = colors.topBad ? rgb2hex(colors.topBar) : undefined
+      console.log(i++)
+
+      this.redColorLocal = rgb2hex(colors.cRed)
+      console.log(i++)
+      console.log('red')
+      console.log(colors.cRed)
+      console.log(this.redColorLocal)
+      this.blueColorLocal = rgb2hex(colors.cBlue)
+      console.log(i++)
+      console.log('blue', this.blueColorLocal, colors.cBlue)
+      this.greenColorLocal = rgb2hex(colors.cGreen)
+      console.log(i++)
+      this.orangeColorLocal = rgb2hex(colors.cOrange)
+      console.log(i++)
 
       this.btnRadiusLocal = radii.btnRadius || 4
+      console.log(i++)
       this.inputRadiusLocal = radii.inputRadius || 4
+      console.log(i++)
       this.panelRadiusLocal = radii.panelRadius || 10
+      console.log(i++)
       this.avatarRadiusLocal = radii.avatarRadius || 5
+      console.log(i++)
       this.avatarAltRadiusLocal = radii.avatarAltRadius || 50
+      console.log(i++)
       this.tooltipRadiusLocal = radii.tooltipRadius || 2
+      console.log(i++)
       this.attachmentRadiusLocal = radii.attachmentRadius || 5
+      console.log(i++)
     }
   },
   watch: {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 72a338bd..339d7c3d 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -24,80 +24,73 @@
     </div>
   </div>
 
-  <div class="preview-container">
-    <div :style="{
-                 '--btnRadius': btnRadiusLocal + 'px',
-                 '--inputRadius': inputRadiusLocal + 'px',
-                 '--panelRadius': panelRadiusLocal + 'px',
-                 '--avatarRadius': avatarRadiusLocal + 'px',
-                 '--avatarAltRadius': avatarAltRadiusLocal + 'px',
-                 '--tooltipRadius': tooltipRadiusLocal + 'px',
-                 '--attachmentRadius': attachmentRadiusLocal + 'px'
-                 }">
-      <div class="panel dummy">
-        <div class="panel-heading" :style="{ 'background-color': btnColorLocal, 'color': textColorLocal }">Preview</div>
-        <div class="panel-body theme-preview-content" :style="{ 'background-color': bgColorLocal, 'color': textColorLocal }">
-          <div class="avatar" :style="{
-                                      'border-radius': avatarRadiusLocal + 'px'
-                                      }">
-            ( ͡° ͜ʖ ͡°)
-          </div>
-          <h4>Content</h4>
-          <br>
-          A bunch of more content and
-          <a :style="{ color: linkColorLocal }">a nice lil' link</a>
-          <i :style="{ color: blueColorLocal }" class="icon-reply"/>
-          <i :style="{ color: greenColorLocal }" class="icon-retweet"/>
-          <i :style="{ color: redColorLocal }" class="icon-cancel"/>
-          <i :style="{ color: orangeColorLocal }" class="icon-star"/>
-          <br>
-          <button class="btn" :style="{ 'background-color': btnColorLocal, 'color': textColorLocal }">Button</button>
+  <div class="preview-container" :style="previewRules">
+    <div class="panel dummy">
+      <div class="panel-heading">Preview</div>
+      <div class="panel-body theme-preview-content">
+        <div class="avatar">
+          ( ͡° ͜ʖ ͡°)
         </div>
+        <h4>Content</h4>
+        <br>
+        A bunch of more content and
+        <a style="color: var(--link)">a nice lil' link</a>
+        <i style="color: var(--cBlue)" class="icon-reply"/>
+        <i style="color: var(--cGreen)" class="icon-retweet"/>
+        <i style="color: var(--cRed)" class="icon-cancel"/>
+        <i style="color: var(--cOrange)" class="icon-star"/>
+        <br>
+        <button class="btn">Button</button>
       </div>
     </div>
   </div>
 
   <div class="color-container">
     <p>{{$t('settings.theme_help')}}</p>
-    <div class="color-item">
-      <label for="bgcolor" class="theme-color-lb">{{$t('settings.background')}}</label>
-      <input id="bgcolor" class="theme-color-cl" type="color" v-model="bgColorLocal">
-      <input id="bgcolor-t" class="theme-color-in" type="text" v-model="bgColorLocal">
+    <h3>Basic colors!!</h3>
+    <div>
+      <div class="color-item">
+        <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
+        <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" fallback="1"/>
+      </div>
+      <div class="color-item">
+        <ColorInput name="fgColor" v-model="btnColorLocal" :label="$t('settings.foreground')"/>
+        <OpacityInput name="fgOpacity" v-model="btnOpacityLocal" fallback="1"/>
+      </div>
+      <div class="color-item">
+        <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
+      </div>
+      <div class="color-item">
+        <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
+      </div>
     </div>
-    <div class="color-item">
-      <label for="fgcolor" class="theme-color-lb">{{$t('settings.foreground')}}</label>
-      <input id="fgcolor" class="theme-color-cl" type="color" v-model="btnColorLocal">
-      <input id="fgcolor-t" class="theme-color-in" type="text" v-model="btnColorLocal">
+
+    <h3>More customs!</h3>
+    <div>
+      <div class="color-item">
+        <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="btnColorLocal" label="Panel header"/>
+        <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" fallback="1"/>
+      </div>
+      <div class="color-item">
+        <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="btnColorLocal" label="Top bar"/>
+        <OpacityInput name="topBarOpacity" v-model="topBarOpacityLocal" fallback="1"/>
+      </div>
     </div>
-    <div class="color-item">
-      <label for="textcolor" class="theme-color-lb">{{$t('settings.text')}}</label>
-      <input id="textcolor" class="theme-color-cl" type="color" v-model="textColorLocal">
-      <input id="textcolor-t" class="theme-color-in" type="text" v-model="textColorLocal">
-    </div>
-    <div class="color-item">
-      <label for="linkcolor" class="theme-color-lb">{{$t('settings.links')}}</label>
-      <input id="linkcolor" class="theme-color-cl" type="color" v-model="linkColorLocal">
-      <input id="linkcolor-t" class="theme-color-in" type="text" v-model="linkColorLocal">
-    </div>
-    <div class="color-item">
-      <label for="redcolor" class="theme-color-lb">{{$t('settings.cRed')}}</label>
-      <input id="redcolor" class="theme-color-cl" type="color" v-model="redColorLocal">
-      <input id="redcolor-t" class="theme-color-in" type="text" v-model="redColorLocal">
-    </div>
-    <div class="color-item">
-      <label for="bluecolor" class="theme-color-lb">{{$t('settings.cBlue')}}</label>
-      <input id="bluecolor" class="theme-color-cl" type="color" v-model="blueColorLocal">
-      <input id="bluecolor-t" class="theme-color-in" type="text" v-model="blueColorLocal">
-    </div>
-    <div class="color-item">
-      <label for="greencolor" class="theme-color-lb">{{$t('settings.cGreen')}}</label>
-      <input id="greencolor" class="theme-color-cl" type="color" v-model="greenColorLocal">
-      <input id="greencolor-t" class="theme-color-in" type="green" v-model="greenColorLocal">
-    </div>
-    <div class="color-item">
-      <label for="orangecolor" class="theme-color-lb">{{$t('settings.cOrange')}}</label>
-      <input id="orangecolor" class="theme-color-cl" type="color" v-model="orangeColorLocal">
-      <input id="orangecolor-t" class="theme-color-in" type="text" v-model="orangeColorLocal">
+
+    <h3>Rainbows!!!</h3>
+    <div>
+      <div class="color-item">
+        <ColorInput name="cRedColor" v-model="redColorLocal" :label="$t('settings.cRed')"/>
+      </div>
+      <div class="color-item">
+        <ColorInput name="cBlueColor" v-model="blueColorLocal" :label="$t('settings.cBlue')"/>
+      </div>
+      <div class="color-item">
+        <ColorInput name="cGreenColor" v-model="greenColorLocal" :label="$t('settings.cGreen')"/>
+      </div>
+      <div class="color-item">
+        <ColorInput name="cOrangeColor" v-model="orangeColorLocal" :label="$t('settings.cOrange')"/>
+      </div>
     </div>
   </div>
 
@@ -161,7 +154,7 @@
 
 .apply-container,
 .radius-container,
-.color-container,
+.color-container > div,
 .presets-container {
   display: flex;
 
@@ -176,7 +169,7 @@
   flex-direction: column;
 }
 
-.color-container {
+.color-container > div{
   flex-wrap: wrap;
   justify-content: space-between;
 }
@@ -214,14 +207,30 @@
 .radius-item,
 .color-item {
   min-width: 20em;
+  margin: 5px 6px 0 0;
   display:flex;
+  flex-direction: column;
   flex: 1 1 0;
-  align-items: baseline;
-  margin: 5px 6px 5px 0;
+
+  &:nth-child(2n+1) {
+    margin-right: 7px;
+
+  }
+
+  .color, .opacity {
+    display:flex;
+    align-items: baseline;
+  }
 
   label {
     color: var(--faint, $fallback--faint);
   }
+  .opacity-control {
+    margin-top: 5px;
+    height: 12px;
+    line-height: 12px;
+    font-size: 12px;
+  }
 }
 
 .radius-item {
@@ -243,44 +252,19 @@
   margin-left: 4px;
 }
 
-.theme-color-in {
-  min-width: 4em;
-}
-
 .theme-radius-in {
   min-width: 1em;
 }
 
-.theme-radius-in,
-.theme-color-in {
+.theme-radius-in {
   max-width: 7em;
   flex: 1;
 }
 
-.theme-radius-lb,
-.theme-color-lb {
-  flex: 2;
-  min-width: 7em;
-}
-
 .theme-radius-lb{
   max-width: 50em;
 }
 
-.theme-color-lb {
-  max-width: 10em;
-}
-
-.theme-color-cl {
-  padding: 1px;
-  max-width: 8em;
-  height: 100%;
-  flex: 0;
-  min-width: 2em;
-  cursor: pointer;
-  max-height: 29px;
-}
-
 .theme-preview-content {
   padding: 20px;
 }
diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js
index 006107e2..e55b3b79 100644
--- a/src/lib/persisted_state.js
+++ b/src/lib/persisted_state.js
@@ -73,6 +73,7 @@ export default function createPersistedState ({
         loaded = true
       } catch (e) {
         console.log("Couldn't load state")
+        console.error(e)
         loaded = true
       }
     })
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 13dd8979..efb43327 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -1,6 +1,10 @@
 import { map } from 'lodash'
 
 const rgb2hex = (r, g, b) => {
+  console.log(r)
+  if (typeof r === 'object') {
+    ({ r, g, b } = r)
+  }
   [r, g, b] = map([r, g, b], (val) => {
     val = Math.ceil(val)
     val = val < 0 ? 0 : val
@@ -27,8 +31,16 @@ const rgbstr2hex = (rgb) => {
   return `#${((Number(rgb[0]) << 16) + (Number(rgb[1]) << 8) + Number(rgb[2])).toString(16)}`
 }
 
+const mixrgb = (a, b) => {
+  return Object.keys(a).reduce((acc, k) => {
+    acc[k] = (a[k] + b[k]) / 2
+    return acc
+  }, {})
+}
+
 export {
   rgb2hex,
   hex2rgb,
+  mixrgb,
   rgbstr2hex
 }
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 493d444e..72782594 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -1,5 +1,6 @@
 import { times } from 'lodash'
-import { rgb2hex, hex2rgb } from '../color_convert/color_convert.js'
+import { brightness, invertLightness, convert } from 'chromatism'
+import { rgb2hex, hex2rgb, mixrgb } from '../color_convert/color_convert.js'
 
 // While this is not used anymore right now, I left it in if we want to do custom
 // styles that aren't just colors, so user can pick from a few different distinct
@@ -53,7 +54,23 @@ const setStyle = (href, commit) => {
   cssEl.addEventListener('load', setDynamic)
 }
 
-const setColors = (col, commit) => {
+const rgb2rgba = function (rgba) {
+  return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`
+}
+
+const getTextColor = function (bg, text) {
+  const bgIsLight = convert(bg).hsl.l > 50
+  const textIsLight = convert(text).hsl.l > 50
+
+  if ((bgIsLight && textIsLight) || (!bgIsLight && !textIsLight)) {
+    const base = typeof text.a !== 'undefined' ? { a: text.a } : {}
+    return Object.assign(base, invertLightness(text).rgb)
+  }
+  return text
+}
+
+const setColors = (input, commit) => {
+  const { colorRules, radiiRules, col } = generatePreset(input)
   const head = document.head
   const body = document.body
   body.style.display = 'none'
@@ -62,51 +79,83 @@ const setColors = (col, commit) => {
   head.appendChild(styleEl)
   const styleSheet = styleEl.sheet
 
-  const isDark = (col.text.r + col.text.g + col.text.b) > (col.bg.r + col.bg.g + col.bg.b)
-  let colors = {}
-  let radii = {}
-
-  const mod = isDark ? -10 : 10
-
-  colors.bg = rgb2hex(col.bg.r, col.bg.g, col.bg.b)                         // background
-  colors.lightBg = rgb2hex((col.bg.r + col.fg.r) / 2, (col.bg.g + col.fg.g) / 2, (col.bg.b + col.fg.b) / 2) // hilighted bg
-  colors.btn = rgb2hex(col.fg.r, col.fg.g, col.fg.b)                         // panels & buttons
-  colors.input = `rgba(${col.fg.r}, ${col.fg.g}, ${col.fg.b}, .5)`
-  colors.border = rgb2hex(col.fg.r - mod, col.fg.g - mod, col.fg.b - mod)       // borders
-  colors.faint = `rgba(${col.text.r}, ${col.text.g}, ${col.text.b}, .5)`
-  colors.fg = rgb2hex(col.text.r, col.text.g, col.text.b)                   // text
-  colors.lightFg = rgb2hex(col.text.r - mod * 5, col.text.g - mod * 5, col.text.b - mod * 5) // strong text
-
-  colors['base07'] = rgb2hex(col.text.r - mod * 2, col.text.g - mod * 2, col.text.b - mod * 2)
-
-  colors.link = rgb2hex(col.link.r, col.link.g, col.link.b)                   // links
-  colors.icon = rgb2hex((col.bg.r + col.text.r) / 2, (col.bg.g + col.text.g) / 2, (col.bg.b + col.text.b) / 2) // icons
-
-  colors.cBlue = col.cBlue && rgb2hex(col.cBlue.r, col.cBlue.g, col.cBlue.b)
-  colors.cRed = col.cRed && rgb2hex(col.cRed.r, col.cRed.g, col.cRed.b)
-  colors.cGreen = col.cGreen && rgb2hex(col.cGreen.r, col.cGreen.g, col.cGreen.b)
-  colors.cOrange = col.cOrange && rgb2hex(col.cOrange.r, col.cOrange.g, col.cOrange.b)
-
-  colors.cAlertRed = col.cRed && `rgba(${col.cRed.r}, ${col.cRed.g}, ${col.cRed.b}, .5)`
-
-  radii.btnRadius = col.btnRadius
-  radii.inputRadius = col.inputRadius
-  radii.panelRadius = col.panelRadius
-  radii.avatarRadius = col.avatarRadius
-  radii.avatarAltRadius = col.avatarAltRadius
-  radii.tooltipRadius = col.tooltipRadius
-  radii.attachmentRadius = col.attachmentRadius
-
   styleSheet.toString()
-  styleSheet.insertRule(`body { ${Object.entries(colors).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';')} }`, 'index-max')
-  styleSheet.insertRule(`body { ${Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';')} }`, 'index-max')
+  styleSheet.insertRule(`body { ${colorRules} }`, 'index-max')
+  styleSheet.insertRule(`body { ${radiiRules} }`, 'index-max')
   body.style.display = 'initial'
 
-  commit('setOption', { name: 'colors', value: colors })
-  commit('setOption', { name: 'radii', value: radii })
+  // commit('setOption', { name: 'colors', value: htmlColors })
+  // commit('setOption', { name: 'radii', value: radii })
   commit('setOption', { name: 'customTheme', value: col })
 }
 
+const generatePreset = (input) => {
+  const radii = input.radii || {
+    btnRadius: input.btnRadius,
+    inputRadius: input.inputRadius,
+    panelRadius: input.panelRadius,
+    avatarRadius: input.avatarRadius,
+    avatarAltRadius: input.avatarAltRadius,
+    tooltipRadius: input.tooltipRadius,
+    attachmentRadius: input.attachmentRadius
+  }
+  const colors = {}
+
+  const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
+    if (typeof v === 'object') {
+      acc[k] = v
+    } else {
+      acc[k] = hex2rgb(v)
+    }
+    return acc
+  }, {})
+
+  colors.fg = col.fg || col.text                   // text
+  colors.text = col.fg || col.text                   // text
+  colors.lightFg = col.fg || col.text                   // text
+
+  colors.bg = col.bg                         // background
+  colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb // hilighted bg
+  console.log(colors.bg)
+  console.log(colors.lightBg)
+
+  colors.btn = col.btn || { r: 0, g: 0, b: 0 }
+  colors.btnText = getTextColor(colors.btn, colors.text)
+
+  colors.panel = col.panel || col.btn
+  colors.panelText = getTextColor(colors.panel, colors.text)
+
+  colors.topBar = col.topBar || col.btn
+  colors.topBarText = getTextColor(colors.topBar, colors.text)
+
+  colors.input = col.input || Object.assign({ a: 0.5 }, col.btn)
+  colors.border = col.btn       // borders
+  colors.faint = col.faint || Object.assign({ a: 0.5 }, col.text)
+
+  colors.link = col.link                   // links
+  colors.icon = mixrgb(colors.bg, colors.text) // icons
+
+  colors.cBlue = col.cBlue
+  colors.cRed = col.cRed
+  colors.cGreen = col.cGreen
+  colors.cOrange = col.cOrange
+
+  colors.cAlertRed = col.cAlertRed || Object.assign({ a: 0.5 }, col.cRed)
+
+  const htmlColors = Object.entries(colors)
+        .reduce((acc, [k, v]) => {
+          if (!v) return acc
+          acc[k] = typeof v.a === 'undefined' ? rgb2hex(v) : rgb2rgba(v)
+          return acc
+        }, {})
+
+  return {
+    colorRules: Object.entries(htmlColors).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
+    radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';'),
+    col
+  }
+}
+
 const setPreset = (val, commit) => {
   window.fetch('/static/styles.json')
     .then((data) => data.json())
@@ -148,7 +197,8 @@ const setPreset = (val, commit) => {
 const StyleSetter = {
   setStyle,
   setPreset,
-  setColors
+  setColors,
+  generatePreset
 }
 
 export default StyleSetter
diff --git a/yarn.lock b/yarn.lock
index fdad8b49..0139c714 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1205,6 +1205,10 @@ chokidar@^1.0.0, chokidar@^1.4.1:
   optionalDependencies:
     fsevents "^1.0.0"
 
+chromatism@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/chromatism/-/chromatism-3.0.0.tgz#a7249d353c1e4f3577e444ac41171c4e2e624b12"
+
 chromedriver@^2.21.2:
   version "2.35.0"
   resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.35.0.tgz#c103ba2fb3d1671f666058159f5cbaa816902e4d"

From fb29e7c73da9520d2d08bae0757bb4ff7803ca11 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 3 Oct 2018 21:21:48 +0300
Subject: [PATCH 02/96] more workings and even less explosions.

---
 .../style_switcher/style_switcher.js          | 110 ++++++++++--------
 .../style_switcher/style_switcher.vue         |  64 +++++++---
 src/i18n/en.json                              |   1 +
 src/services/color_convert/color_convert.js   |   7 +-
 src/services/style_setter/style_setter.js     |  18 ++-
 5 files changed, 124 insertions(+), 76 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 5f76c038..f74337fd 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -9,17 +9,27 @@ export default {
       availableStyles: [],
       selected: this.$store.state.config.theme,
       invalidThemeImported: false,
-      bgColorLocal: '',
-      bgOpacityLocal: 0,
-      btnColorLocal: '',
-      btnOpacityLocal: '',
 
       textColorLocal: '',
       linkColorLocal: '',
 
+      bgColorLocal: '',
+      bgOpacityLocal: undefined,
+
+      btnColorLocal: '',
+      btnTextColorLocal: undefined,
+      btnOpacityLocal: undefined,
+
+      inputColorLocal: undefined,
+      inputTextColorLocal: undefined,
+      inputOpacityLocal: undefined,
+
       panelColorLocal: undefined,
+      panelTextColorLocal: undefined,
       panelOpacityLocal: undefined,
+
       topBarColorLocal: undefined,
+      topBarTextColorLocal: undefined,
       topBarOpacityLocal: undefined,
 
       redColorLocal: '',
@@ -49,6 +59,9 @@ export default {
     this.normalizeLocalState(this.$store.state.config.customTheme)
   },
   computed: {
+    selectedVersion () {
+      return Array.isArray(this.selected) ? 1 : 2
+    },
     currentTheme () {
       return {
         colors: {
@@ -76,8 +89,11 @@ export default {
     },
     previewRules () {
       try {
-        const generated = StyleSetter.generatePreset(this.currentTheme.colors)
-        return [generated.colorRules, generated.radiiRules].join(';')
+        if (!this.currentTheme.colors.bg) {
+          return ''
+        }
+        const generated = StyleSetter.generatePreset(this.currentTheme)
+        return [generated.colorRules, generated.radiiRules, 'color: var(--text)'].join(';')
       } catch (e) {
         console.error('CATCH')
         console.error(e)
@@ -93,9 +109,8 @@ export default {
     exportCurrentTheme () {
       const stringified = JSON.stringify({
         // To separate from other random JSON files and possible future theme formats
-        _pleroma_theme_version: 1,
-        colors: this.$store.state.config.colors,
-        radii: this.$store.state.config.radii
+        _pleroma_theme_version: 2,
+        theme: this.currentTheme
       }, null, 2) // Pretty-print and indent with 2 spaces
 
       // Create an invisible link with a data url and simulate a click
@@ -123,7 +138,9 @@ export default {
             try {
               const parsed = JSON.parse(target.result)
               if (parsed._pleroma_theme_version === 1) {
-                this.normalizeLocalState(parsed.colors, parsed.radii)
+                this.normalizeLocalState(parsed, 1)
+              } else if (parsed._pleroma_theme_version === 2) {
+                this.normalizeLocalState(parsed.theme)
               } else {
                 // A theme from the future, spooky
                 this.invalidThemeImported = true
@@ -162,67 +179,68 @@ export default {
       })
     },
 
-    normalizeLocalState (input) {
+    clearV1 () {
+      this.panelColorLocal = undefined
+      this.topBarColorLocal = undefined
+      this.btnTextColorLocal = undefined
+      this.btnOpacityLocal = undefined
+
+      this.inputColorLocal = undefined
+      this.inputTextColorLocal = undefined
+      this.inputOpacityLocal = undefined
+
+      this.panelColorLocal = undefined
+      this.panelTextColorLocal = undefined
+      this.panelOpacityLocal = undefined
+
+      this.topBarColorLocal = undefined
+      this.topBarTextColorLocal = undefined
+      this.topBarOpacityLocal = undefined
+    },
+
+    normalizeLocalState (input, version = 2) {
       const colors = input.colors || input
       const radii = input.radii || input
-      let i = 0
-      console.log('BENIS')
-      console.log(colors)
 
-      console.log(i++)
       this.bgColorLocal = rgb2hex(colors.bg)
-      console.log(i++)
       this.btnColorLocal = rgb2hex(colors.btn)
-      console.log(i++)
       this.textColorLocal = rgb2hex(colors.text || colors.fg)
-      console.log(i++)
       this.linkColorLocal = rgb2hex(colors.link)
-      console.log(i++)
 
-      this.panelColorLocal = colors.panel ? rgb2hex(colors.panel) : undefined
-      console.log(i++)
-      this.topBarColorLocal = colors.topBad ? rgb2hex(colors.topBar) : undefined
-      console.log(i++)
+      if (version === 1) {
+        this.clearV1()
+      }
+
+      this.panelColorLocal = rgb2hex(colors.panel)
+      this.topBarColorLocal = rgb2hex(colors.topBar)
 
       this.redColorLocal = rgb2hex(colors.cRed)
-      console.log(i++)
-      console.log('red')
-      console.log(colors.cRed)
-      console.log(this.redColorLocal)
       this.blueColorLocal = rgb2hex(colors.cBlue)
-      console.log(i++)
-      console.log('blue', this.blueColorLocal, colors.cBlue)
       this.greenColorLocal = rgb2hex(colors.cGreen)
-      console.log(i++)
       this.orangeColorLocal = rgb2hex(colors.cOrange)
-      console.log(i++)
 
       this.btnRadiusLocal = radii.btnRadius || 4
-      console.log(i++)
       this.inputRadiusLocal = radii.inputRadius || 4
-      console.log(i++)
       this.panelRadiusLocal = radii.panelRadius || 10
-      console.log(i++)
       this.avatarRadiusLocal = radii.avatarRadius || 5
-      console.log(i++)
       this.avatarAltRadiusLocal = radii.avatarAltRadius || 50
-      console.log(i++)
       this.tooltipRadiusLocal = radii.tooltipRadius || 2
-      console.log(i++)
       this.attachmentRadiusLocal = radii.attachmentRadius || 5
-      console.log(i++)
     }
   },
   watch: {
     selected () {
-      this.bgColorLocal = this.selected[1]
-      this.btnColorLocal = this.selected[2]
-      this.textColorLocal = this.selected[3]
-      this.linkColorLocal = this.selected[4]
-      this.redColorLocal = this.selected[5]
-      this.greenColorLocal = this.selected[6]
-      this.blueColorLocal = this.selected[7]
-      this.orangeColorLocal = this.selected[8]
+      if (this.selectedVersion === 1) {
+        this.clearV1();
+        this.bgColorLocal = this.selected[1]
+        this.btnColorLocal = this.selected[2]
+        this.textColorLocal = this.selected[3]
+        this.linkColorLocal = this.selected[4]
+        this.redColorLocal = this.selected[5]
+        this.greenColorLocal = this.selected[6]
+        this.blueColorLocal = this.selected[7]
+        this.orangeColorLocal = this.selected[8]
+      }
     }
   }
 }
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 339d7c3d..521683be 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -52,44 +52,65 @@
       <div class="color-item">
         <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" fallback="1"/>
+        <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
+        <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
       </div>
       <div class="color-item">
         <ColorInput name="fgColor" v-model="btnColorLocal" :label="$t('settings.foreground')"/>
-        <OpacityInput name="fgOpacity" v-model="btnOpacityLocal" fallback="1"/>
+        <OpacityInput name="fgOpacity" v-model="fgOpacityLocal" :fallback="bgOpacityLocal || 1"/>
+        <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="textColorLocal"/>
+        <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="linkColorLocal"/>
       </div>
       <div class="color-item">
-        <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
+        <ColorInput name="cRedColor" v-model="redColorLocal" :label="$t('settings.cRed')"/>
+        <ColorInput name="cBlueColor" v-model="blueColorLocal" :label="$t('settings.cBlue')"/>
       </div>
       <div class="color-item">
-        <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
+        <ColorInput name="cGreenColor" v-model="greenColorLocal" :label="$t('settings.cGreen')"/>
+        <ColorInput name="cOrangeColor" v-model="orangeColorLocal" :label="$t('settings.cOrange')"/>
+      </div>
+      <div class="color-item wide">
+        <h4>Alert opacity</h4>
+        <OpacityInput name="alertOpacity" v-model="alertOpacityLocal" fallback="1"/>
       </div>
     </div>
 
     <h3>More customs!</h3>
     <div>
       <div class="color-item">
-        <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="btnColorLocal" label="Panel header"/>
+        <h4>Panel header</h4>
+        <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" fallback="1"/>
+        <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="textColorLocal" :label="$t('settings.links')"/>
       </div>
       <div class="color-item">
-        <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="btnColorLocal" label="Top bar"/>
+        <h4>Top bar</h4>
+        <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="topBarOpacity" v-model="topBarOpacityLocal" fallback="1"/>
-      </div>
-    </div>
-
-    <h3>Rainbows!!!</h3>
-    <div>
-      <div class="color-item">
-        <ColorInput name="cRedColor" v-model="redColorLocal" :label="$t('settings.cRed')"/>
+        <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
+        <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="linkColorLocal" :label="$t('settings.links')"/>
       </div>
       <div class="color-item">
-        <ColorInput name="cBlueColor" v-model="blueColorLocal" :label="$t('settings.cBlue')"/>
+        <h4>Inputs</h4>
+        <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
+        <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" fallback="0.5"/>
+        <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
       </div>
       <div class="color-item">
-        <ColorInput name="cGreenColor" v-model="greenColorLocal" :label="$t('settings.cGreen')"/>
+        <h4>Buttons</h4>
+        <ColorInput name="buttonColor" v-model="buttonColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
+        <OpacityInput name="buttonOpacity" v-model="buttonOpacityLocal" fallback="0.5"/>
+        <ColorInput name="buttonTextColor" v-model="buttonTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
       </div>
       <div class="color-item">
-        <ColorInput name="cOrangeColor" v-model="orangeColorLocal" :label="$t('settings.cOrange')"/>
+        <h4>Borders</h4>
+        <ColorInput name="buttonColor" v-model="buttonColorLocal" :fallback="btnColorLocal" label="Color"/>
+        <OpacityInput name="buttonOpacity" v-model="buttonOpacityLocal" fallback="0.5"/>
+      </div>
+      <div class="color-item">
+        <h4>Faint text</h4>
+        <ColorInput name="buttonColor" v-model="buttonColorLocal" :fallback="btnColorLocal" :label="$t('settings.text')"/>
+        <OpacityInput name="buttonOpacity" v-model="buttonOpacityLocal" fallback="0.5"/>
       </div>
     </div>
   </div>
@@ -212,7 +233,10 @@
   flex-direction: column;
   flex: 1 1 0;
 
-  &:nth-child(2n+1) {
+  &.wide {
+    min-width: 60%
+  }
+  &:not(.wide):nth-child(2n+1) {
     margin-right: 7px;
 
   }
@@ -222,14 +246,16 @@
     align-items: baseline;
   }
 
+  h4 {
+    margin-top: 1em;
+  }
+
   label {
     color: var(--faint, $fallback--faint);
   }
   .opacity-control {
     margin-top: 5px;
-    height: 12px;
-    line-height: 12px;
-    font-size: 12px;
+    margin-bottom: 5px;
   }
 }
 
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 8c7360e9..d825dcc1 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -108,6 +108,7 @@
     "follow_import_error": "Error importing followers",
     "follows_imported": "Follows imported! Processing them will take a while.",
     "foreground": "Foreground",
+    "opacity": "Opacity",
     "general": "General",
     "hide_attachments_in_convo": "Hide attachments in conversations",
     "hide_attachments_in_tl": "Hide attachments in timeline",
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index efb43327..ae5d5a31 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -1,7 +1,12 @@
 import { map } from 'lodash'
 
 const rgb2hex = (r, g, b) => {
-  console.log(r)
+  if (r === null || typeof r === 'undefined') {
+    return undefined
+  }
+  if (r[0] === '#') {
+    return r
+  }
   if (typeof r === 'object') {
     ({ r, g, b } = r)
   }
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 72782594..2a803a4f 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -70,7 +70,7 @@ const getTextColor = function (bg, text) {
 }
 
 const setColors = (input, commit) => {
-  const { colorRules, radiiRules, col } = generatePreset(input)
+  const { colorRules, radiiRules } = generatePreset(input)
   const head = document.head
   const body = document.body
   body.style.display = 'none'
@@ -86,10 +86,11 @@ const setColors = (input, commit) => {
 
   // commit('setOption', { name: 'colors', value: htmlColors })
   // commit('setOption', { name: 'radii', value: radii })
-  commit('setOption', { name: 'customTheme', value: col })
+  commit('setOption', { name: 'customTheme', value: input })
 }
 
 const generatePreset = (input) => {
+  console.log(input)
   const radii = input.radii || {
     btnRadius: input.btnRadius,
     inputRadius: input.inputRadius,
@@ -116,8 +117,6 @@ const generatePreset = (input) => {
 
   colors.bg = col.bg                         // background
   colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb // hilighted bg
-  console.log(colors.bg)
-  console.log(colors.lightBg)
 
   colors.btn = col.btn || { r: 0, g: 0, b: 0 }
   colors.btnText = getTextColor(colors.btn, colors.text)
@@ -151,8 +150,7 @@ const generatePreset = (input) => {
 
   return {
     colorRules: Object.entries(htmlColors).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
-    radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';'),
-    col
+    radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';')
   }
 }
 
@@ -162,7 +160,7 @@ const setPreset = (val, commit) => {
     .then((themes) => {
       const theme = themes[val] ? themes[val] : themes['pleroma-dark']
       const bgRgb = hex2rgb(theme[1])
-      const fgRgb = hex2rgb(theme[2])
+      const btnRgb = hex2rgb(theme[2])
       const textRgb = hex2rgb(theme[3])
       const linkRgb = hex2rgb(theme[4])
 
@@ -171,9 +169,9 @@ const setPreset = (val, commit) => {
       const cBlueRgb = hex2rgb(theme[7] || '#0000FF')
       const cOrangeRgb = hex2rgb(theme[8] || '#E3FF00')
 
-      const col = {
+      const colors = {
         bg: bgRgb,
-        fg: fgRgb,
+        btn: btnRgb,
         text: textRgb,
         link: linkRgb,
         cRed: cRedRgb,
@@ -189,7 +187,7 @@ const setPreset = (val, commit) => {
       // load config -> set preset -> wait for styles.json to load ->
       // load persisted state -> set colors -> styles.json loaded -> set colors
       if (!window.themeLoaded) {
-        setColors(col, commit)
+        setColors({ colors }, commit)
       }
     })
 }

From 0a4b07652aa24ea5fcda8f62838ea37f8e8168ef Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 4 Oct 2018 18:16:14 +0300
Subject: [PATCH 03/96] trying to fix transition

---
 .../style_switcher/style_switcher.js          | 67 +++++++++++++++----
 .../style_switcher/style_switcher.vue         | 18 ++---
 src/services/style_setter/style_setter.js     | 44 +++++++++---
 3 files changed, 98 insertions(+), 31 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index f74337fd..7c204bdb 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -16,7 +16,12 @@ export default {
       bgColorLocal: '',
       bgOpacityLocal: undefined,
 
-      btnColorLocal: '',
+      fgColorLocal: '',
+      fgOpacityLocal: undefined,
+      fgTextColorLocal: undefined,
+      fgLinkColorLocal: undefined,
+
+      btnColorLocal: undefined,
       btnTextColorLocal: undefined,
       btnOpacityLocal: undefined,
 
@@ -30,8 +35,11 @@ export default {
 
       topBarColorLocal: undefined,
       topBarTextColorLocal: undefined,
+      topBarLinkColorLocal: undefined,
       topBarOpacityLocal: undefined,
 
+      alertOpacityLocal: undefined,
+
       redColorLocal: '',
       blueColorLocal: '',
       greenColorLocal: '',
@@ -66,7 +74,8 @@ export default {
       return {
         colors: {
           bg: this.bgColorLocal,
-          fg: this.textColorLocal,
+          fg: this.fgColorLocal,
+          text: this.textColorLocal,
           panel: this.panelColorLocal,
           topBar: this.topBarColorLocal,
           btn: this.btnColorLocal,
@@ -87,18 +96,26 @@ export default {
         }
       }
     },
-    previewRules () {
+    preview () {
       try {
         if (!this.currentTheme.colors.bg) {
-          return ''
+          return {}
         }
-        const generated = StyleSetter.generatePreset(this.currentTheme)
-        return [generated.colorRules, generated.radiiRules, 'color: var(--text)'].join(';')
+        return StyleSetter.generatePreset(this.currentTheme)
       } catch (e) {
         console.error('CATCH')
         console.error(e)
-        return ''
+        return {}
       }
+    },
+    previewTheme () {
+      if (!this.preview.theme) return { colors: {}, radii: {} }
+      console.log(this.preview.theme)
+      return this.preview.theme
+    },
+    previewRules () {
+      if (!this.preview.colorRules) return ''
+      return [this.preview.colorRules, this.preview.radiiRules, 'color: var(--text)'].join(';')
     }
   },
   components: {
@@ -140,7 +157,7 @@ export default {
               if (parsed._pleroma_theme_version === 1) {
                 this.normalizeLocalState(parsed, 1)
               } else if (parsed._pleroma_theme_version === 2) {
-                this.normalizeLocalState(parsed.theme)
+                this.normalizeLocalState(parsed.theme, 2)
               } else {
                 // A theme from the future, spooky
                 this.invalidThemeImported = true
@@ -180,6 +197,10 @@ export default {
     },
 
     clearV1 () {
+      this.fgOpacityLocal = undefined
+      this.fgTextColorLocal = undefined
+      this.fgLinkColorLocal = undefined
+
       this.panelColorLocal = undefined
       this.topBarColorLocal = undefined
       this.btnTextColorLocal = undefined
@@ -198,13 +219,35 @@ export default {
       this.topBarOpacityLocal = undefined
     },
 
-    normalizeLocalState (input, version = 2) {
+    /**
+     * This applies stored theme data onto form.
+     * @param {Object} input - input data
+     * @param {Number} version - version of data. 0 means try to guess based on data.
+     */
+    normalizeLocalState (input, version = 0) {
       const colors = input.colors || input
       const radii = input.radii || input
 
+      if (version === 0) {
+        if (input.version) version = input.version
+        // Old v1 naming: fg is text, btn is foreground
+        if (typeof input.text === 'undefined' && typeof input.fg !== 'undefined') {
+          version = 1
+        }
+        // New v2 naming: text is text, fg is foreground
+        if (typeof input.text !== 'undefined' && typeof input.fg !== 'undefined') {
+          version = 2
+        }
+      }
+
       this.bgColorLocal = rgb2hex(colors.bg)
-      this.btnColorLocal = rgb2hex(colors.btn)
-      this.textColorLocal = rgb2hex(colors.text || colors.fg)
+      if (version === 1) {
+        this.fgColorLocal = rgb2hex(colors.btn)
+        this.textColorLocal = rgb2hex(colors.fg)
+      } else {
+        this.fgColorLocal = rgb2hex(colors.fg)
+        this.textColorLocal = rgb2hex(colors.text)
+      }
       this.linkColorLocal = rgb2hex(colors.link)
 
       if (version === 1) {
@@ -231,7 +274,7 @@ export default {
   watch: {
     selected () {
       if (this.selectedVersion === 1) {
-        this.clearV1();
+        this.clearV1()
         this.bgColorLocal = this.selected[1]
         this.btnColorLocal = this.selected[2]
         this.textColorLocal = this.selected[3]
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 521683be..cf1fac92 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -56,9 +56,9 @@
         <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
       </div>
       <div class="color-item">
-        <ColorInput name="fgColor" v-model="btnColorLocal" :label="$t('settings.foreground')"/>
+        <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
         <OpacityInput name="fgOpacity" v-model="fgOpacityLocal" :fallback="bgOpacityLocal || 1"/>
-        <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="textColorLocal"/>
+        <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.btnText"/>
         <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="linkColorLocal"/>
       </div>
       <div class="color-item">
@@ -98,19 +98,19 @@
       </div>
       <div class="color-item">
         <h4>Buttons</h4>
-        <ColorInput name="buttonColor" v-model="buttonColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="buttonOpacity" v-model="buttonOpacityLocal" fallback="0.5"/>
-        <ColorInput name="buttonTextColor" v-model="buttonTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
+        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
+        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" fallback="0.5"/>
+        <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
       </div>
       <div class="color-item">
         <h4>Borders</h4>
-        <ColorInput name="buttonColor" v-model="buttonColorLocal" :fallback="btnColorLocal" label="Color"/>
-        <OpacityInput name="buttonOpacity" v-model="buttonOpacityLocal" fallback="0.5"/>
+        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="btnColorLocal" label="Color"/>
+        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" fallback="0.5"/>
       </div>
       <div class="color-item">
         <h4>Faint text</h4>
-        <ColorInput name="buttonColor" v-model="buttonColorLocal" :fallback="btnColorLocal" :label="$t('settings.text')"/>
-        <OpacityInput name="buttonOpacity" v-model="buttonOpacityLocal" fallback="0.5"/>
+        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="btnColorLocal" :label="$t('settings.text')"/>
+        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" fallback="0.5"/>
       </div>
     </div>
   </div>
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 2a803a4f..54f54b4e 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -101,7 +101,6 @@ const generatePreset = (input) => {
     attachmentRadius: input.attachmentRadius
   }
   const colors = {}
-
   const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
     if (typeof v === 'object') {
       acc[k] = v
@@ -111,12 +110,32 @@ const generatePreset = (input) => {
     return acc
   }, {})
 
-  colors.fg = col.fg || col.text                   // text
-  colors.text = col.fg || col.text                   // text
-  colors.lightFg = col.fg || col.text                   // text
+  let version = 0
 
-  colors.bg = col.bg                         // background
-  colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb // hilighted bg
+  if (input.version) {
+    version = input.version
+  }
+  // Old v1 naming: fg is text, btn is foreground
+  if (typeof col.text === 'undefined' && typeof col.fg !== 'undefined') {
+    version = 1
+  }
+  // New v2 naming: text is text, fg is foreground
+  if (typeof col.text !== 'undefined' && typeof col.fg !== 'undefined') {
+    version = 2
+  }
+
+  colors.text = version === 1 ? col.fg : col.text
+  colors.lightText = colors.text
+
+  colors.bg = col.bg
+  colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb
+
+  colors.fg = version === 1 ? col.btn : col.fg
+  console.log('BENIN')
+  console.log(version)
+  console.log(col)
+  console.log(colors.text)
+  colors.fgText = getTextColor(colors.fg, colors.text)
 
   colors.btn = col.btn || { r: 0, g: 0, b: 0 }
   colors.btnText = getTextColor(colors.btn, colors.text)
@@ -128,11 +147,11 @@ const generatePreset = (input) => {
   colors.topBarText = getTextColor(colors.topBar, colors.text)
 
   colors.input = col.input || Object.assign({ a: 0.5 }, col.btn)
-  colors.border = col.btn       // borders
+  colors.border = col.btn
   colors.faint = col.faint || Object.assign({ a: 0.5 }, col.text)
 
-  colors.link = col.link                   // links
-  colors.icon = mixrgb(colors.bg, colors.text) // icons
+  colors.link = col.link
+  colors.icon = mixrgb(colors.bg, colors.text)
 
   colors.cBlue = col.cBlue
   colors.cRed = col.cRed
@@ -150,7 +169,11 @@ const generatePreset = (input) => {
 
   return {
     colorRules: Object.entries(htmlColors).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
-    radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';')
+    radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';'),
+    theme: {
+      colors,
+      radii
+    }
   }
 }
 
@@ -196,6 +219,7 @@ const StyleSetter = {
   setStyle,
   setPreset,
   setColors,
+  getTextColor,
   generatePreset
 }
 

From 5441766c3cba46682227202e91e08c4fbb3e3ac3 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 4 Oct 2018 18:27:27 +0300
Subject: [PATCH 04/96] fix

---
 .../style_switcher/style_switcher.js          | 21 ++------------
 src/services/style_setter/style_setter.js     | 28 ++++---------------
 2 files changed, 7 insertions(+), 42 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 7c204bdb..a1c44be3 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -228,26 +228,9 @@ export default {
       const colors = input.colors || input
       const radii = input.radii || input
 
-      if (version === 0) {
-        if (input.version) version = input.version
-        // Old v1 naming: fg is text, btn is foreground
-        if (typeof input.text === 'undefined' && typeof input.fg !== 'undefined') {
-          version = 1
-        }
-        // New v2 naming: text is text, fg is foreground
-        if (typeof input.text !== 'undefined' && typeof input.fg !== 'undefined') {
-          version = 2
-        }
-      }
-
       this.bgColorLocal = rgb2hex(colors.bg)
-      if (version === 1) {
-        this.fgColorLocal = rgb2hex(colors.btn)
-        this.textColorLocal = rgb2hex(colors.fg)
-      } else {
-        this.fgColorLocal = rgb2hex(colors.fg)
-        this.textColorLocal = rgb2hex(colors.text)
-      }
+      this.fgColorLocal = rgb2hex(colors.fg)
+      this.textColorLocal = rgb2hex(colors.text)
       this.linkColorLocal = rgb2hex(colors.link)
 
       if (version === 1) {
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 54f54b4e..cfa41b11 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -110,40 +110,22 @@ const generatePreset = (input) => {
     return acc
   }, {})
 
-  let version = 0
-
-  if (input.version) {
-    version = input.version
-  }
-  // Old v1 naming: fg is text, btn is foreground
-  if (typeof col.text === 'undefined' && typeof col.fg !== 'undefined') {
-    version = 1
-  }
-  // New v2 naming: text is text, fg is foreground
-  if (typeof col.text !== 'undefined' && typeof col.fg !== 'undefined') {
-    version = 2
-  }
-
-  colors.text = version === 1 ? col.fg : col.text
+  colors.text = col.text
   colors.lightText = colors.text
 
   colors.bg = col.bg
   colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb
 
-  colors.fg = version === 1 ? col.btn : col.fg
-  console.log('BENIN')
-  console.log(version)
-  console.log(col)
-  console.log(colors.text)
+  colors.fg = col.fg
   colors.fgText = getTextColor(colors.fg, colors.text)
 
-  colors.btn = col.btn || { r: 0, g: 0, b: 0 }
+  colors.btn = col.btn || col.fg
   colors.btnText = getTextColor(colors.btn, colors.text)
 
-  colors.panel = col.panel || col.btn
+  colors.panel = col.panel || col.fg
   colors.panelText = getTextColor(colors.panel, colors.text)
 
-  colors.topBar = col.topBar || col.btn
+  colors.topBar = col.topBar || col.fg
   colors.topBarText = getTextColor(colors.topBar, colors.text)
 
   colors.input = col.input || Object.assign({ a: 0.5 }, col.btn)

From 96804d42f0f6aa6af85295933af6fd267b19e473 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 7 Oct 2018 19:59:22 +0300
Subject: [PATCH 05/96] Some themeing is working!!

---
 src/App.scss                                  |  56 ++++-----
 src/_variables.scss                           |   7 +-
 src/components/chat_panel/chat_panel.vue      |   4 +-
 src/components/color_input/color_input.vue    |  84 +++++++++++++
 .../notifications/notifications.scss          |   7 +-
 .../opacity_input/opacity_input.vue           |  75 ++++++++++++
 .../post_status_form/post_status_form.vue     |  12 +-
 src/components/settings/settings.vue          |   2 +-
 src/components/status/status.vue              |   4 +-
 .../style_switcher/style_switcher.js          | 113 +++++++++++++-----
 .../style_switcher/style_switcher.vue         |  40 ++++---
 src/components/tab_switcher/tab_switcher.scss |   8 +-
 src/components/timeline/timeline.vue          |  10 +-
 .../user_card_content/user_card_content.vue   |  16 +--
 src/services/style_setter/style_setter.js     |  28 +++--
 15 files changed, 346 insertions(+), 120 deletions(-)
 create mode 100644 src/components/color_input/color_input.vue
 create mode 100644 src/components/opacity_input/opacity_input.vue

diff --git a/src/App.scss b/src/App.scss
index 1119caf2..c91b6a61 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -36,8 +36,8 @@ body {
   font-family: sans-serif;
   font-size: 14px;
   margin: 0;
-  color: $fallback--fg;
-  color: var(--fg, $fallback--fg);
+  color: $fallback--text;
+  color: var(--text, $fallback--text);
   max-width: 100vw;
   overflow-x: hidden;
 }
@@ -50,10 +50,10 @@ a {
 
 button {
   user-select: none;
-  color: $fallback--fg;
-  color: var(--btnText, $fallback--fg);
-  background-color: $fallback--btn;
-  background-color: var(--btn, $fallback--btn);
+  color: $fallback--text;
+  color: var(--btnText, $fallback--text);
+  background-color: $fallback--fg;
+  background-color: var(--btn, $fallback--fg);
   border: none;
   border-radius: $fallback--btnRadius;
   border-radius: var(--btnRadius, $fallback--btnRadius);
@@ -102,10 +102,10 @@ input, textarea, .select {
   border-bottom: 1px solid rgba(255, 255, 255, 0.2);
   border-top: 1px solid rgba(0, 0, 0, 0.2);
   box-shadow: 0px 0px 2px black inset;
-  background-color: $fallback--input;
-  background-color: var(--input, $fallback--input);
-  color: $fallback--lightFg;
-  color: var(--lightFg, $fallback--lightFg);
+  background-color: $fallback--fg;
+  background-color: var(--input, $fallback--fg);
+  color: $fallback--lightText;
+  color: var(--inputText, $fallback--lightText);
   font-family: sans-serif;
   font-size: 14px;
   padding: 8px 7px;
@@ -122,8 +122,8 @@ input, textarea, .select {
     bottom: 0;
     right: 5px;
     height: 100%;
-    color: $fallback--fg;
-    color: var(--fg, $fallback--fg);
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
     line-height: 29px;
     z-index: 0;
     pointer-events: none;
@@ -136,8 +136,8 @@ input, textarea, .select {
     background: transparent;
     border: none;
     margin: 0;
-    color: $fallback--fg;
-    color: var(--fg, $fallback--fg);
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
     padding: 4px 2em 3px 3px;
     width: 100%;
     z-index: 1;
@@ -149,8 +149,8 @@ input, textarea, .select {
   &[type=checkbox] {
     display: none;
     &:checked + label::before {
-      color: $fallback--fg;
-      color: var(--fg, $fallback--fg);
+      color: $fallback--text;
+      color: var(--text, $fallback--text);
     }
     &:disabled,
     {
@@ -172,8 +172,8 @@ input, textarea, .select {
       border-top: 1px solid rgba(0, 0, 0, 0.2);
       box-shadow: 0px 0px 2px black inset;
       margin-right: .5em;
-      background-color: $fallback--input;
-      background-color: var(--input, $fallback--input);
+      background-color: $fallback--fg;
+      background-color: var(--input, $fallback--fg);
       vertical-align: top;
       text-align: center;
       line-height: 1.1em;
@@ -187,8 +187,8 @@ input, textarea, .select {
 }
 
 option {
-  color: $fallback--fg;
-  color: var(--fg, $fallback--fg);
+  color: $fallback--text;
+  color: var(--text, $fallback--text);
   background-color: $fallback--bg;
   background-color: var(--bg, $fallback--bg);
 }
@@ -279,9 +279,9 @@ nav {
     margin: auto;
     height: 50px;
 
-    a i {
+    a, a i {
       color: $fallback--link;
-      color: var(--link, $fallback--link);
+      color: var(--topBarLink, $fallback--link);
     }
   }
 }
@@ -331,8 +331,8 @@ main-router {
   text-align: left;
   line-height: 28px;
   color: var(--panelText);
-  background-color: $fallback--btn;
-  background-color: var(--panel, $fallback--btn);
+  background-color: $fallback--fg;
+  background-color: var(--panel, $fallback--fg);
   align-items: baseline;
 
   .title {
@@ -389,8 +389,8 @@ main-router {
 nav {
   z-index: 1000;
   color: var(--topBarText);
-  background-color: $fallback--btn;
-  background-color: var(--topBar, $fallback--btn);
+  background-color: $fallback--fg;
+  background-color: var(--topBar, $fallback--fg);
   color: $fallback--faint;
   color: var(--faint, $fallback--faint);
   box-shadow: 0px 0px 4px rgba(0,0,0,.6);
@@ -518,8 +518,8 @@ nav {
   cursor: pointer;
 
   .selected {
-    color: $fallback--lightFg;
-    color: var(--lightFg, $fallback--lightFg);
+    color: $fallback--lightText;
+    color: var(--lightText, $fallback--lightText);
   }
 
   .text-format {
diff --git a/src/_variables.scss b/src/_variables.scss
index b5222a6a..0f73e929 100644
--- a/src/_variables.scss
+++ b/src/_variables.scss
@@ -3,14 +3,13 @@ $main-background: white;
 $darkened-background: whitesmoke;
 
 $fallback--bg: #121a24;
-$fallback--btn: #182230;
-$fallback--input: #182230;
+$fallback--fg: #182230;
 $fallback--faint: rgba(185, 185, 186, .5);
-$fallback--fg: #b9b9ba;
+$fallback--text: #b9b9ba;
 $fallback--link: #d8a070;
 $fallback--icon: #666;
 $fallback--lightBg: rgb(21, 30, 42);
-$fallback--lightFg: #b9b9ba;
+$fallback--lightText: #b9b9ba;
 $fallback--border: #222;
 $fallback--cRed: #ff0000;
 $fallback--cBlue: #0095ff;
diff --git a/src/components/chat_panel/chat_panel.vue b/src/components/chat_panel/chat_panel.vue
index 30070d3e..f174319a 100644
--- a/src/components/chat_panel/chat_panel.vue
+++ b/src/components/chat_panel/chat_panel.vue
@@ -55,8 +55,8 @@
 .chat-heading {
   cursor: pointer;
   .icon-comment-empty {
-    color: $fallback--fg;
-    color: var(--fg, $fallback--fg);
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
   }
 }
 
diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
new file mode 100644
index 00000000..49d9bed7
--- /dev/null
+++ b/src/components/color_input/color_input.vue
@@ -0,0 +1,84 @@
+<template>
+<div class="color-control" :class="{ disabled: !present }">
+  <label :for="name" class="label">
+    {{label}}
+  </label>
+  <input
+  v-if="typeof fallback !== 'undefined'"
+  class="opt"
+  :id="name + '-o'"
+      type="checkbox"
+  :checked="present"
+           @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
+           >
+           <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
+  <input
+    :id="name"
+    class="color-input"
+    type="color"
+    :value="value || fallback"
+    :disabled="!present"
+    @input="$emit('input', $event.target.value)"
+    >
+  <input
+    :id="name + '-t'"
+    class="text-input"
+    type="text"
+    :value="value || fallback"
+    :disabled="!present"
+    @input="$emit('input', $event.target.value)"
+    >
+</div>
+</template>
+
+<script>
+export default {
+  props: [
+    'name', 'label', 'value', 'fallback'
+  ],
+  computed: {
+    present () {
+      return typeof this.value !== 'undefined'
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.color-control {
+  display: flex;
+
+  &.disabled *:not(.opt-l){
+    opacity: .5
+  }
+
+  .label {
+    flex: 2;
+    min-width: 7em;
+  }
+
+  .opt-l {
+    align-self: center;
+    flex: 0;
+    &::before {
+      width: 14px;
+      height: 14px;
+    }
+  }
+
+  .text-input {
+    max-width: 7em;
+    flex: 1;
+  }
+
+  .color-input {
+    flex: 0;
+    padding: 1px;
+    cursor: pointer;
+    height: 100%;
+    max-height: 29px;
+    min-width: 2em;
+    border: none;
+  }
+}
+</style>
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index a137ccd5..a98c2549 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -22,8 +22,8 @@
   }
 
   .loadmore-error {
-    color: $fallback--fg;
-    color: var(--fg, $fallback--fg);
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
   }
 
   .unseen {
@@ -90,6 +90,9 @@
         padding: 0.25em 0;
         color: $fallback--faint;
         color: var(--faint, $fallback--faint);
+        a {
+          color: var(--faintLink);
+        }
       }
       padding: 0;
       .media-body {
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
new file mode 100644
index 00000000..cfe6de21
--- /dev/null
+++ b/src/components/opacity_input/opacity_input.vue
@@ -0,0 +1,75 @@
+<template>
+<div class="opacity-control" :class="{ disabled: !present }">
+  <label :for="name" class="label">
+    {{$t('settings.opacity')}}
+  </label>
+  <input
+  v-if="typeof fallback !== 'undefined'"
+  class="opt"
+  :id="name + '-o'"
+      type="checkbox"
+  :checked="present"
+           @input="$emit('input', !present ? fallback : undefined)"
+           >
+  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
+  <input
+    :id="name"
+    class="input-range"
+    type="range"
+    :value="value || fallback"
+    :disabled="!present"
+    @input="$emit('input', $event.target.value)"
+    max="1"
+    min="0"
+    step=".05">
+</div>
+</template>
+
+<script>
+export default {
+  props: [
+    'name', 'value', 'fallback'
+  ],
+  computed: {
+    present () {
+      return typeof this.value !== 'undefined'
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.opacity-control {
+  display: flex;
+
+  &.disabled *:not(.opt-l) {
+    opacity: .5
+  }
+
+  .opt-l {
+    align-self: center;
+    line-height: 0;
+    &::before {
+      width: 14px;
+      height: 14px;
+    }
+  }
+
+  .label {
+    flex: 2;
+    min-width: 7em;
+  }
+
+  .input-range {
+    align-self: center;
+    background: none;
+    border: none;
+    padding: 0;
+    margin: 0;
+    height: auto;
+    box-shadow: none;
+    min-width: 9em;
+    flex: 1;
+  }
+}
+</style>
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 42e9c65c..4514e79f 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -153,8 +153,8 @@
       padding-bottom: 0;
       margin-left: $fallback--attachmentRadius;
       margin-left: var(--attachmentRadius, $fallback--attachmentRadius);
-      background-color: $fallback--btn;
-      background-color: var(--btn, $fallback--btn);
+      background-color: $fallback--fg;
+      background-color: var(--fg, $fallback--fg);
       border-bottom-left-radius: 0;
       border-bottom-right-radius: 0;
     }
@@ -261,8 +261,8 @@
     min-width: 75%;
     background: $fallback--bg;
     background: var(--bg, $fallback--bg);
-    color: $fallback--lightFg;
-    color: var(--lightFg, $fallback--lightFg);
+    color: $fallback--lightText;
+    color: var(--lightText, $fallback--lightText);
   }
 
   .autocomplete {
@@ -291,8 +291,8 @@
     }
 
     &.highlighted {
-      background-color: $fallback--btn;
-      background-color: var(--btn, $fallback--btn);
+      background-color: $fallback--fg;
+      background-color: var(--fg, $fallback--fg);
     }
   }
 }
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index eebb2cb7..990d1f0d 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -159,7 +159,7 @@
 @import '../../_variables.scss';
 
 .setting-item {
-  border-bottom: 2px solid var(--btn, $fallback--btn);
+  border-bottom: 2px solid var(--fg, $fallback--fg);
   margin: 1em 1em 1.4em;
   padding-bottom: 1.4em;
 
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index eb521280..57a007d9 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -284,8 +284,8 @@
       margin-left: 0.2em;
     }
     a:hover i {
-      color: $fallback--fg;
-      color: var(--fg, $fallback--fg);
+      color: $fallback--text;
+      color: var(--text, $fallback--text);
     }
   }
 
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index a1c44be3..203ca18a 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -31,6 +31,7 @@ export default {
 
       panelColorLocal: undefined,
       panelTextColorLocal: undefined,
+      panelFaintColorLocal: undefined,
       panelOpacityLocal: undefined,
 
       topBarColorLocal: undefined,
@@ -40,10 +41,17 @@ export default {
 
       alertOpacityLocal: undefined,
 
-      redColorLocal: '',
-      blueColorLocal: '',
-      greenColorLocal: '',
-      orangeColorLocal: '',
+      borderColorLocal: undefined,
+      borderOpacityLocal: undefined,
+
+      faintColorLocal: undefined,
+      faintOpacityLocal: undefined,
+      faintLinkColorLocal: undefined,
+
+      cRedColorLocal: '',
+      cBlueColorLocal: '',
+      cGreenColorLocal: '',
+      cOrangeColorLocal: '',
 
       btnRadiusLocal: '',
       inputRadiusLocal: '',
@@ -74,16 +82,35 @@ export default {
       return {
         colors: {
           bg: this.bgColorLocal,
-          fg: this.fgColorLocal,
           text: this.textColorLocal,
-          panel: this.panelColorLocal,
-          topBar: this.topBarColorLocal,
-          btn: this.btnColorLocal,
           link: this.linkColorLocal,
-          cRed: this.redColorLocal,
-          cBlue: this.blueColorLocal,
-          cGreen: this.greenColorLocal,
-          cOrange: this.orangeColorLocal
+
+          fg: this.fgColorLocal,
+          fgText: this.fgTextColorLocal,
+          fgLink: this.fgLinkColorLocal,
+
+          panel: this.panelColorLocal,
+          panelText: this.panelTextColorLocal,
+          panelFaint: this.panelFaintColorLocal,
+
+          input: this.inputColorLocal,
+          inputText: this.inputTextColorLocal,
+
+          topBar: this.topBarColorLocal,
+          topBarText: this.topBarTextColorLocal,
+          topBarLink: this.topBarLinkColorLocal,
+
+          btn: this.btnColorLocal,
+          btnText: this.btnTextColorLocal,
+
+          faint: this.faintColorLocal,
+          faintLink: this.faintLinkColorLocal,
+          border: this.borderColorLocal,
+
+          cRed: this.cRedColorLocal,
+          cBlue: this.cBlueColorLocal,
+          cGreen: this.cGreenColorLocal,
+          cOrange: this.cOrangeColorLocal
         },
         radii: {
           btnRadius: this.btnRadiusLocal,
@@ -197,12 +224,12 @@ export default {
     },
 
     clearV1 () {
+      this.bgOpacityLocal = undefined
       this.fgOpacityLocal = undefined
       this.fgTextColorLocal = undefined
       this.fgLinkColorLocal = undefined
 
-      this.panelColorLocal = undefined
-      this.topBarColorLocal = undefined
+      this.btnColorLocal = undefined
       this.btnTextColorLocal = undefined
       this.btnOpacityLocal = undefined
 
@@ -216,7 +243,17 @@ export default {
 
       this.topBarColorLocal = undefined
       this.topBarTextColorLocal = undefined
+      this.topBarLinkColorLocal = undefined
       this.topBarOpacityLocal = undefined
+
+      this.alertOpacityLocal = undefined
+
+      this.borderColorLocal = undefined
+      this.borderOpacityLocal = undefined
+
+      this.faintColorLocal = undefined
+      this.faintOpacityLocal = undefined
+      this.faintLinkColorLocal = undefined
     },
 
     /**
@@ -228,22 +265,42 @@ export default {
       const colors = input.colors || input
       const radii = input.radii || input
 
-      this.bgColorLocal = rgb2hex(colors.bg)
-      this.fgColorLocal = rgb2hex(colors.fg)
-      this.textColorLocal = rgb2hex(colors.text)
-      this.linkColorLocal = rgb2hex(colors.link)
-
-      if (version === 1) {
-        this.clearV1()
+      if (version === 0) {
+        if (input.version) version = input.version
+        // Old v1 naming: fg is text, btn is foreground
+        if (typeof colors.text === 'undefined' && typeof colors.fg !== 'undefined') {
+          version = 1
+        }
+        // New v2 naming: text is text, fg is foreground
+        if (typeof colors.text !== 'undefined' && typeof colors.fg !== 'undefined') {
+          version = 2
+        }
       }
 
-      this.panelColorLocal = rgb2hex(colors.panel)
-      this.topBarColorLocal = rgb2hex(colors.topBar)
+      console.log('BENIS')
+      console.log(version)
+      // Stuff that differs between V1 and V2
+      if (version === 1) {
+        console.log(colors)
+        this.fgColorLocal = rgb2hex(colors.btn)
+        this.textColorLocal = rgb2hex(colors.fg)
+      }
 
-      this.redColorLocal = rgb2hex(colors.cRed)
-      this.blueColorLocal = rgb2hex(colors.cBlue)
-      this.greenColorLocal = rgb2hex(colors.cGreen)
-      this.orangeColorLocal = rgb2hex(colors.cOrange)
+      const keys = new Set(version !== 1 ? Object.keys(colors) : [])
+      if (version === 1) {
+        // V1 ignores the rest
+        this.clearV1()
+        keys
+          .add('bg')
+          .add('link')
+          .add('cRed')
+          .add('cBlue')
+          .add('cGreen')
+          .add('cOrange')
+      }
+      keys.forEach(key => {
+        this[key + 'ColorLocal'] = rgb2hex(colors[key])
+      })
 
       this.btnRadiusLocal = radii.btnRadius || 4
       this.inputRadiusLocal = radii.inputRadius || 4
@@ -259,7 +316,7 @@ export default {
       if (this.selectedVersion === 1) {
         this.clearV1()
         this.bgColorLocal = this.selected[1]
-        this.btnColorLocal = this.selected[2]
+        this.fgColorLocal = this.selected[2]
         this.textColorLocal = this.selected[3]
         this.linkColorLocal = this.selected[4]
         this.redColorLocal = this.selected[5]
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index cf1fac92..7ddc2d1c 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -58,16 +58,16 @@
       <div class="color-item">
         <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
         <OpacityInput name="fgOpacity" v-model="fgOpacityLocal" :fallback="bgOpacityLocal || 1"/>
-        <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.btnText"/>
-        <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="linkColorLocal"/>
+        <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
+        <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
       </div>
       <div class="color-item">
-        <ColorInput name="cRedColor" v-model="redColorLocal" :label="$t('settings.cRed')"/>
-        <ColorInput name="cBlueColor" v-model="blueColorLocal" :label="$t('settings.cBlue')"/>
+        <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
+        <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
       </div>
       <div class="color-item">
-        <ColorInput name="cGreenColor" v-model="greenColorLocal" :label="$t('settings.cGreen')"/>
-        <ColorInput name="cOrangeColor" v-model="orangeColorLocal" :label="$t('settings.cOrange')"/>
+        <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
+        <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
       </div>
       <div class="color-item wide">
         <h4>Alert opacity</h4>
@@ -79,38 +79,40 @@
     <div>
       <div class="color-item">
         <h4>Panel header</h4>
-        <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
+        <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" fallback="1"/>
-        <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="textColorLocal" :label="$t('settings.links')"/>
+        <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
+        <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.faint')"/>
       </div>
       <div class="color-item">
         <h4>Top bar</h4>
-        <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
+        <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="topBarOpacity" v-model="topBarOpacityLocal" fallback="1"/>
-        <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
-        <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="linkColorLocal" :label="$t('settings.links')"/>
+        <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
+        <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
       </div>
       <div class="color-item">
         <h4>Inputs</h4>
-        <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
+        <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" fallback="0.5"/>
-        <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
+        <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
       </div>
       <div class="color-item">
         <h4>Buttons</h4>
-        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="btnColorLocal" :label="$t('settings.background')"/>
+        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" fallback="0.5"/>
-        <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="textColorLocal" :label="$t('settings.text')"/>
+        <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
       </div>
       <div class="color-item">
         <h4>Borders</h4>
-        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="btnColorLocal" label="Color"/>
-        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" fallback="0.5"/>
+        <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
+        <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" fallback="0.5"/>
       </div>
       <div class="color-item">
         <h4>Faint text</h4>
-        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="btnColorLocal" :label="$t('settings.text')"/>
-        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" fallback="0.5"/>
+        <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint" :label="$t('settings.text')"/>
+        <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" fallback="0.5"/>
+        <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.link')"/>
       </div>
     </div>
   </div>
diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index 374a19c5..578caec2 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -17,8 +17,8 @@
 
     .tab, &::after, &::before {
       border-bottom: 1px solid;
-      border-bottom-color: $fallback--btn;
-      border-bottom-color: var(--btn, $fallback--btn);
+      border-bottom-color: $fallback--fg;
+      border-bottom-color: var(--fg, $fallback--fg);
     }
 
     .tab {
@@ -28,8 +28,8 @@
 
       &:not(.active) {
         border-bottom: 1px solid;
-        border-bottom-color: $fallback--btn;
-        border-bottom-color: var(--btn, $fallback--btn);
+        border-bottom-color: $fallback--fg;
+        border-bottom-color: var(--fg, $fallback--fg);
         z-index: 4;
       }
 
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 2dd4376a..77a9a2af 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -61,12 +61,12 @@
     opacity: 0.8;
     background-color: transparent;
     color: $fallback--faint;
-    color: var(--faint, $fallback--faint);
+    color: var(--panelFaint, $fallback--faint);
   }
 
   .loadmore-error {
-    color: $fallback--fg;
-    color: var(--fg, $fallback--fg);
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
   }
 }
 
@@ -79,7 +79,7 @@
   border-color: var(--border, $fallback--border);
   padding: 10px;
   z-index: 1;
-  background-color: $fallback--btn;
-  background-color: var(--btn, $fallback--btn);
+  background-color: $fallback--fg;
+  background-color: var(--fg, $fallback--fg);
 }
 </style>
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index 59358040..f1b54fad 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -138,8 +138,8 @@
 }
 
 .user-info {
-  color: $fallback--lightFg;
-  color: var(--lightFg, $fallback--lightFg);
+  color: $fallback--lightText;
+  color: var(--lightText, $fallback--lightText);
   padding: 0 16px;
 
   .container {
@@ -173,8 +173,8 @@
   }
 
   .usersettings {
-    color: $fallback--lightFg;
-    color: var(--lightFg, $fallback--lightFg);
+    color: $fallback--lightText;
+    color: var(--lightText, $fallback--lightText);
     opacity: .8;
   }
 
@@ -193,8 +193,8 @@
   }
 
   .user-screen-name {
-    color: $fallback--lightFg;
-    color: var(--lightFg, $fallback--lightFg);
+    color: $fallback--lightText;
+    color: var(--lightText, $fallback--lightText);
     display: inline-block;
     font-weight: light;
     font-size: 15px;
@@ -269,8 +269,8 @@
   padding: .5em 1.5em 0em 1.5em;
   text-align: center;
   justify-content: space-between;
-  color: $fallback--lightFg;
-  color: var(--lightFg, $fallback--lightFg);
+  color: $fallback--lightText;
+  color: var(--lightText, $fallback--lightText);
 
   &.clickable {
     .user-count {
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index cfa41b11..cc408933 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -112,27 +112,33 @@ const generatePreset = (input) => {
 
   colors.text = col.text
   colors.lightText = colors.text
+  colors.link = col.link
+  colors.border = col.border || col.fg
+  colors.faint = col.faint || col.text
 
   colors.bg = col.bg
   colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb
 
   colors.fg = col.fg
-  colors.fgText = getTextColor(colors.fg, colors.text)
+  colors.fgText = col.fgText || getTextColor(colors.fg, colors.text)
+  colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link)
 
   colors.btn = col.btn || col.fg
-  colors.btnText = getTextColor(colors.btn, colors.text)
+  colors.btnText = col.btnText || getTextColor(colors.btn, colors.fgText)
+
+  colors.input = col.input || col.fg
+  colors.inputText = col.inputText || getTextColor(colors.input, colors.fgText)
 
   colors.panel = col.panel || col.fg
-  colors.panelText = getTextColor(colors.panel, colors.text)
+  colors.panelText = col.panelText || getTextColor(colors.panel, colors.fgText)
+  colors.panelFaint = col.panelFaint || getTextColor(colors.panel, colors.faint)
 
   colors.topBar = col.topBar || col.fg
-  colors.topBarText = getTextColor(colors.topBar, colors.text)
+  colors.topBarText = col.topBarText || getTextColor(colors.topBar, colors.fgText)
+  colors.topBarLink = col.topBarLink || getTextColor(colors.topBar, colors.fgLink)
 
-  colors.input = col.input || Object.assign({ a: 0.5 }, col.btn)
-  colors.border = col.btn
-  colors.faint = col.faint || Object.assign({ a: 0.5 }, col.text)
+  colors.faintLink = col.faintLink || col.link
 
-  colors.link = col.link
   colors.icon = mixrgb(colors.bg, colors.text)
 
   colors.cBlue = col.cBlue
@@ -153,7 +159,7 @@ const generatePreset = (input) => {
     colorRules: Object.entries(htmlColors).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
     radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';'),
     theme: {
-      colors,
+      colors: htmlColors,
       radii
     }
   }
@@ -165,7 +171,7 @@ const setPreset = (val, commit) => {
     .then((themes) => {
       const theme = themes[val] ? themes[val] : themes['pleroma-dark']
       const bgRgb = hex2rgb(theme[1])
-      const btnRgb = hex2rgb(theme[2])
+      const fgRgb = hex2rgb(theme[2])
       const textRgb = hex2rgb(theme[3])
       const linkRgb = hex2rgb(theme[4])
 
@@ -176,7 +182,7 @@ const setPreset = (val, commit) => {
 
       const colors = {
         bg: bgRgb,
-        btn: btnRgb,
+        fg: fgRgb,
         text: textRgb,
         link: linkRgb,
         cRed: cRedRgb,

From 4d77b0c86bbd711e76e8ed23b6b227332bbea3cf Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 7 Oct 2018 22:03:34 +0300
Subject: [PATCH 06/96] Transparency works without exploding now. All nice.

---
 .../opacity_input/opacity_input.vue           | 19 ++++++-
 .../style_switcher/style_switcher.js          | 28 ++++++----
 .../style_switcher/style_switcher.vue         | 24 ++++-----
 src/components/tab_switcher/tab_switcher.scss |  8 +--
 src/services/style_setter/style_setter.js     | 54 +++++++++++++------
 5 files changed, 87 insertions(+), 46 deletions(-)

diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index cfe6de21..09972868 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -22,6 +22,16 @@
     max="1"
     min="0"
     step=".05">
+  <input
+    :id="name"
+    class="input-number"
+    type="number"
+    :value="value || fallback"
+    :disabled="!present"
+    @input="$emit('input', $event.target.value)"
+    max="1"
+    min="0"
+    step=".05">
 </div>
 </template>
 
@@ -64,12 +74,17 @@ export default {
     align-self: center;
     background: none;
     border: none;
-    padding: 0;
     margin: 0;
     height: auto;
     box-shadow: none;
-    min-width: 9em;
+    min-width: 7em;
     flex: 1;
   }
+  .input-number {
+    align-self: center;
+    margin: 0;
+    min-width: 4em;
+    flex: 0;
+  }
 }
 </style>
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 203ca18a..c419a9ce 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -17,7 +17,6 @@ export default {
       bgOpacityLocal: undefined,
 
       fgColorLocal: '',
-      fgOpacityLocal: undefined,
       fgTextColorLocal: undefined,
       fgLinkColorLocal: undefined,
 
@@ -37,7 +36,6 @@ export default {
       topBarColorLocal: undefined,
       topBarTextColorLocal: undefined,
       topBarLinkColorLocal: undefined,
-      topBarOpacityLocal: undefined,
 
       alertOpacityLocal: undefined,
 
@@ -112,6 +110,15 @@ export default {
           cGreen: this.cGreenColorLocal,
           cOrange: this.cOrangeColorLocal
         },
+        opacity: {
+          bg: this.bgOpacityLocal,
+          btn: this.btnOpacityLocal,
+          input: this.inputOpacityLocal,
+          panel: this.panelOpacityLocal,
+          topBar: this.topBarOpacityLocal,
+          border: this.borderOpacityLocal,
+          faint: this.faintOpacityLocal
+        },
         radii: {
           btnRadius: this.btnRadiusLocal,
           inputRadius: this.inputRadiusLocal,
@@ -136,8 +143,7 @@ export default {
       }
     },
     previewTheme () {
-      if (!this.preview.theme) return { colors: {}, radii: {} }
-      console.log(this.preview.theme)
+      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {} }
       return this.preview.theme
     },
     previewRules () {
@@ -226,7 +232,6 @@ export default {
     clearV1 () {
       this.bgOpacityLocal = undefined
       this.fgOpacityLocal = undefined
-      this.fgTextColorLocal = undefined
       this.fgLinkColorLocal = undefined
 
       this.btnColorLocal = undefined
@@ -239,6 +244,7 @@ export default {
 
       this.panelColorLocal = undefined
       this.panelTextColorLocal = undefined
+      this.panelFaintColorLocal = undefined
       this.panelOpacityLocal = undefined
 
       this.topBarColorLocal = undefined
@@ -246,8 +252,6 @@ export default {
       this.topBarLinkColorLocal = undefined
       this.topBarOpacityLocal = undefined
 
-      this.alertOpacityLocal = undefined
-
       this.borderColorLocal = undefined
       this.borderOpacityLocal = undefined
 
@@ -264,6 +268,7 @@ export default {
     normalizeLocalState (input, version = 0) {
       const colors = input.colors || input
       const radii = input.radii || input
+      const opacity = input.opacity || input
 
       if (version === 0) {
         if (input.version) version = input.version
@@ -277,11 +282,8 @@ export default {
         }
       }
 
-      console.log('BENIS')
-      console.log(version)
       // Stuff that differs between V1 and V2
       if (version === 1) {
-        console.log(colors)
         this.fgColorLocal = rgb2hex(colors.btn)
         this.textColorLocal = rgb2hex(colors.fg)
       }
@@ -302,6 +304,7 @@ export default {
         this[key + 'ColorLocal'] = rgb2hex(colors[key])
       })
 
+      // TODO optimize this
       this.btnRadiusLocal = radii.btnRadius || 4
       this.inputRadiusLocal = radii.inputRadius || 4
       this.panelRadiusLocal = radii.panelRadius || 10
@@ -309,6 +312,11 @@ export default {
       this.avatarAltRadiusLocal = radii.avatarAltRadius || 50
       this.tooltipRadiusLocal = radii.tooltipRadius || 2
       this.attachmentRadiusLocal = radii.attachmentRadius || 5
+
+      Object.entries(opacity).forEach(([k, v]) => {
+        if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
+        this[k + 'OpacityLocal'] = v
+      })
     }
   },
   watch: {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 7ddc2d1c..1b00603c 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -51,13 +51,12 @@
     <div>
       <div class="color-item">
         <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" fallback="1"/>
+        <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
         <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
         <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
       </div>
       <div class="color-item">
         <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
-        <OpacityInput name="fgOpacity" v-model="fgOpacityLocal" :fallback="bgOpacityLocal || 1"/>
         <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
         <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
       </div>
@@ -71,7 +70,7 @@
       </div>
       <div class="color-item wide">
         <h4>Alert opacity</h4>
-        <OpacityInput name="alertOpacity" v-model="alertOpacityLocal" fallback="1"/>
+        <OpacityInput name="alertOpacity" v-model="alertOpacityLocal" fallback="previewTheme.opacity.alert || 1"/>
       </div>
     </div>
 
@@ -80,39 +79,38 @@
       <div class="color-item">
         <h4>Panel header</h4>
         <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" fallback="1"/>
+        <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
         <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
         <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.faint')"/>
       </div>
       <div class="color-item">
         <h4>Top bar</h4>
         <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="topBarOpacity" v-model="topBarOpacityLocal" fallback="1"/>
         <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
         <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
       </div>
       <div class="color-item">
         <h4>Inputs</h4>
         <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" fallback="0.5"/>
+        <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
         <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
       </div>
       <div class="color-item">
         <h4>Buttons</h4>
         <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" fallback="0.5"/>
+        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
         <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
       </div>
       <div class="color-item">
         <h4>Borders</h4>
         <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
-        <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" fallback="0.5"/>
+        <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
       </div>
       <div class="color-item">
         <h4>Faint text</h4>
-        <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint" :label="$t('settings.text')"/>
-        <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" fallback="0.5"/>
-        <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.link')"/>
+        <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
+        <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
+        <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" fallback="previewTheme.opacity.faint"/>
       </div>
     </div>
   </div>
@@ -255,10 +253,6 @@
   label {
     color: var(--faint, $fallback--faint);
   }
-  .opacity-control {
-    margin-top: 5px;
-    margin-bottom: 5px;
-  }
 }
 
 .radius-item {
diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index 578caec2..6f3f9f27 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -17,8 +17,8 @@
 
     .tab, &::after, &::before {
       border-bottom: 1px solid;
-      border-bottom-color: $fallback--fg;
-      border-bottom-color: var(--fg, $fallback--fg);
+      border-bottom-color: $fallback--border;
+      border-bottom-color: var(--border, $fallback--border);
     }
 
     .tab {
@@ -28,8 +28,8 @@
 
       &:not(.active) {
         border-bottom: 1px solid;
-        border-bottom-color: $fallback--fg;
-        border-bottom-color: var(--fg, $fallback--fg);
+        border-bottom-color: $fallback--border;
+        border-bottom-color: var(--border, $fallback--border);
         z-index: 4;
       }
 
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index cc408933..4de39f79 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -90,7 +90,6 @@ const setColors = (input, commit) => {
 }
 
 const generatePreset = (input) => {
-  console.log(input)
   const radii = input.radii || {
     btnRadius: input.btnRadius,
     inputRadius: input.inputRadius,
@@ -101,6 +100,12 @@ const generatePreset = (input) => {
     attachmentRadius: input.attachmentRadius
   }
   const colors = {}
+  const opacity = Object.assign({
+    alert: 0.5,
+    input: 0.5,
+    faint: 0.5
+  }, input.opacity)
+
   const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
     if (typeof v === 'object') {
       acc[k] = v
@@ -110,11 +115,13 @@ const generatePreset = (input) => {
     return acc
   }, {})
 
+  const isLightOnDark = convert(col.bg).hsl.l < convert(col.text).hsl.l
+  const mod = isLightOnDark ? 1 : -1
+
   colors.text = col.text
-  colors.lightText = colors.text
+  colors.lightText = brightness(20 * mod, colors.text).rgb
   colors.link = col.link
-  colors.border = col.border || col.fg
-  colors.faint = col.faint || col.text
+  colors.faint = col.faint || Object.assign({}, col.text)
 
   colors.bg = col.bg
   colors.lightBg = col.lightBg || brightness(5, colors.bg).rgb
@@ -123,21 +130,23 @@ const generatePreset = (input) => {
   colors.fgText = col.fgText || getTextColor(colors.fg, colors.text)
   colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link)
 
-  colors.btn = col.btn || col.fg
+  colors.border = col.border || brightness(20 * mod, colors.fg).rgb
+
+  colors.btn = col.btn || Object.assign({}, col.fg)
   colors.btnText = col.btnText || getTextColor(colors.btn, colors.fgText)
 
-  colors.input = col.input || col.fg
-  colors.inputText = col.inputText || getTextColor(colors.input, colors.fgText)
+  colors.input = col.input || Object.assign({}, col.fg)
+  colors.inputText = col.inputText || getTextColor(colors.input, colors.lightText)
 
-  colors.panel = col.panel || col.fg
+  colors.panel = col.panel || Object.assign({}, col.fg)
   colors.panelText = col.panelText || getTextColor(colors.panel, colors.fgText)
   colors.panelFaint = col.panelFaint || getTextColor(colors.panel, colors.faint)
 
-  colors.topBar = col.topBar || col.fg
+  colors.topBar = col.topBar || Object.assign({}, col.fg)
   colors.topBarText = col.topBarText || getTextColor(colors.topBar, colors.fgText)
   colors.topBarLink = col.topBarLink || getTextColor(colors.topBar, colors.fgLink)
 
-  colors.faintLink = col.faintLink || col.link
+  colors.faintLink = col.faintLink || Object.assign({}, col.link)
 
   colors.icon = mixrgb(colors.bg, colors.text)
 
@@ -146,20 +155,35 @@ const generatePreset = (input) => {
   colors.cGreen = col.cGreen
   colors.cOrange = col.cOrange
 
-  colors.cAlertRed = col.cAlertRed || Object.assign({ a: 0.5 }, col.cRed)
+  colors.cAlertRed = col.cAlertRed || Object.assign({}, col.cRed)
+
+  Object.entries(opacity).forEach(([ k, v ]) => {
+    if (typeof v === 'undefined') return
+    if (k === 'alert') {
+      colors.cAlertRed.a = v
+      return
+    }
+    if (k === 'faint') {
+      colors[k + 'Link'].a = v
+      colors['panelFaint'].a = v
+    }
+    colors[k].a = v
+  })
 
   const htmlColors = Object.entries(colors)
         .reduce((acc, [k, v]) => {
           if (!v) return acc
-          acc[k] = typeof v.a === 'undefined' ? rgb2hex(v) : rgb2rgba(v)
+          acc.solid[k] = rgb2hex(v)
+          acc.complete[k] = typeof v.a === 'undefined' ? rgb2hex(v) : rgb2rgba(v)
           return acc
-        }, {})
+        }, { complete: {}, solid: {} })
 
   return {
-    colorRules: Object.entries(htmlColors).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
+    colorRules: Object.entries(htmlColors.complete).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
     radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';'),
     theme: {
-      colors: htmlColors,
+      colors: htmlColors.solid,
+      opacity,
       radii
     }
   }

From 87e98772b09b9b317dee020d22115517635a29c8 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 10 Oct 2018 00:07:28 +0300
Subject: [PATCH 07/96] initial contrast display support

---
 .../contrast_ratio/contrast_ratio.vue         | 64 +++++++++++++++++++
 .../style_switcher/style_switcher.js          | 37 +++++++++--
 .../style_switcher/style_switcher.vue         |  6 ++
 src/services/color_convert/color_convert.js   | 39 ++++++++++-
 4 files changed, 141 insertions(+), 5 deletions(-)
 create mode 100644 src/components/contrast_ratio/contrast_ratio.vue

diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
new file mode 100644
index 00000000..6c4a59b6
--- /dev/null
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -0,0 +1,64 @@
+<template>
+<div class="contrast-ratio">
+  <span class="label">
+    Contrast:
+  </span>
+  <span>
+    <span>
+      {{contrast.text}}
+    </span>
+    <span class="rating">
+      <span v-if="contrast.aaa">
+        AAA
+      </span>
+      <span v-if="!contrast.aaa && contrast.aa">
+        AA
+      </span>
+      <span v-if="!contrast.aaa && !contrast.aa">
+        bad
+      </span>
+    </span>
+  </span>
+  <span v-if="large">
+    <span>
+      18pt+:
+    </span>
+    <span class="rating">
+      <span v-if="contrast.aaa">
+        AAA
+      </span>
+      <span v-if="!contrast.aaa && contrast.aa">
+        AA
+      </span>
+      <span v-if="!contrast.aaa && !contrast.aa">
+        bad
+      </span>
+    </span>
+  </span>
+</div>
+</template>
+
+<script>
+export default {
+  props: [
+    'large', 'contrast'
+  ]
+}
+</script>
+
+<style lang="scss">
+.contrast-ratio {
+  display: flex;
+  justify-content: end;
+
+  .label {
+    margin-right: 1em;
+  }
+
+  .rating {
+    display: inline-block;
+    min-width: 3em;
+    text-align: center;
+  }
+}
+</style>
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index c419a9ce..27efa230 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,5 +1,6 @@
-import { rgb2hex } from '../../services/color_convert/color_convert.js'
+import { rgb2hex, hex2rgb, getContrastRatio } from '../../services/color_convert/color_convert.js'
 import ColorInput from '../color_input/color_input.vue'
+import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
 import StyleSetter from '../../services/style_setter/style_setter.js'
 
@@ -127,7 +128,7 @@ export default {
           avatarAltRadius: this.avatarAltRadiusLocal,
           tooltipRadius: this.tooltipRadiusLocal,
           attachmentRadius: this.attachmentRadiusLocal
-        }
+        },
       }
     },
     preview () {
@@ -143,9 +144,36 @@ export default {
       }
     },
     previewTheme () {
-      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {} }
+      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {}, contrast: {} }
       return this.preview.theme
     },
+    previewContrast () {
+      if (!this.previewTheme.colors) return {}
+      const colors = this.previewTheme.colors
+      const hints = (ratio) => ({
+        text: ratio.toPrecision(3) + ':1',
+        // AA level, AAA level
+        aa: ratio >= 4.5,
+        aaa: ratio >= 7,
+        // same but for 18pt+ texts
+        laa: ratio >= 3,
+        laaa: ratio >= 4.5
+      })
+
+      const ratios = {
+        bgText: getContrastRatio(hex2rgb(colors.bg), hex2rgb(colors.text)),
+        bgLink: getContrastRatio(hex2rgb(colors.bg), hex2rgb(colors.link)),
+
+        panelText: getContrastRatio(hex2rgb(colors.panel), hex2rgb(colors.panelText)),
+
+        btnText: getContrastRatio(hex2rgb(colors.btn), hex2rgb(colors.btnText)),
+
+        topBarText: getContrastRatio(hex2rgb(colors.topBar), hex2rgb(colors.topBarText)),
+        topBarLink: getContrastRatio(hex2rgb(colors.topBar), hex2rgb(colors.topBarLink)),
+      }
+
+      return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
+    },
     previewRules () {
       if (!this.preview.colorRules) return ''
       return [this.preview.colorRules, this.preview.radiiRules, 'color: var(--text)'].join(';')
@@ -153,7 +181,8 @@ export default {
   },
   components: {
     ColorInput,
-    OpacityInput
+    OpacityInput,
+    ContrastRatio
   },
   methods: {
     exportCurrentTheme () {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 1b00603c..4235d65c 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -53,7 +53,9 @@
         <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
         <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
+        <ContrastRatio :contrast="previewContrast.bgText"/>
         <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
+        <ContrastRatio :contrast="previewContrast.bgLink"/>
       </div>
       <div class="color-item">
         <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
@@ -81,13 +83,16 @@
         <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
         <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
+        <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
         <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.faint')"/>
       </div>
       <div class="color-item">
         <h4>Top bar</h4>
         <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
+        <ContrastRatio :contrast="previewContrast.topBarText"/>
         <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
+        <ContrastRatio :contrast="previewContrast.topBarLink"/>
       </div>
       <div class="color-item">
         <h4>Inputs</h4>
@@ -100,6 +105,7 @@
         <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
         <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
+        <ContrastRatio :contrast="previewContrast.btnText"/>
       </div>
       <div class="color-item">
         <h4>Borders</h4>
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index ae5d5a31..31ee3a6b 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -19,6 +19,42 @@ const rgb2hex = (r, g, b) => {
   return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`
 }
 
+// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+// https://www.w3.org/TR/2008/REC-WCAG20-20081211/relative-luminance.xml
+// https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation
+const c2linear = (b) => {
+  // W3C gives 0.03928 while wikipedia states 0.04045
+  // what those magical numbers mean - I don't know.
+  // something about gamma-correction, i suppose.
+  // Sticking with W3C example.
+  const c = b / 255
+  if (c < 0.03928) {
+    return c / 12.92
+  } else {
+    return Math.pow((c + 0.055) / 1.055, 2.4)
+  }
+}
+
+const srgbToLinear = (srgb) => {
+  return 'rgb'.split('').reduce((acc, c) => { acc[c] = c2linear(srgb[c]); return acc }, {})
+}
+
+// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+// https://www.w3.org/TR/2008/REC-WCAG20-20081211/relative-luminance.xml
+const relativeLuminance = (srgb) => {
+  const {r, g, b} = srgbToLinear(srgb)
+  return 0.2126 * r + 0.7152 * g + 0.0722 * b
+}
+
+// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
+const getContrastRatio = (a, b) => {
+  const la = relativeLuminance(a)
+  const lb = relativeLuminance(b)
+  const [l1, l2] = la > lb ? [la, lb] : [lb, la]
+
+  return (l1 + 0.05) / (l2 + 0.05)
+}
+
 const hex2rgb = (hex) => {
   const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
   return result ? {
@@ -47,5 +83,6 @@ export {
   rgb2hex,
   hex2rgb,
   mixrgb,
-  rgbstr2hex
+  rgbstr2hex,
+  getContrastRatio
 }

From 4b7b7d9905b965c225fd42fb68682b9602254c82 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 10 Oct 2018 05:39:02 +0300
Subject: [PATCH 08/96] cleanup, documentation, contrast taking alpha into
 account.

---
 .../style_switcher/style_switcher.js          | 38 +++++++---
 src/services/color_convert/color_convert.js   | 70 ++++++++++++++++---
 2 files changed, 91 insertions(+), 17 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 27efa230..d4381202 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,4 +1,4 @@
-import { rgb2hex, hex2rgb, getContrastRatio } from '../../services/color_convert/color_convert.js'
+import { rgb2hex, hex2rgb, getContrastRatio, worstCase } from '../../services/color_convert/color_convert.js'
 import ColorInput from '../color_input/color_input.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
@@ -144,12 +144,13 @@ export default {
       }
     },
     previewTheme () {
-      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {}, contrast: {} }
+      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {} }
       return this.preview.theme
     },
     previewContrast () {
       if (!this.previewTheme.colors) return {}
       const colors = this.previewTheme.colors
+      const opacity = this.previewTheme.opacity
       const hints = (ratio) => ({
         text: ratio.toPrecision(3) + ':1',
         // AA level, AAA level
@@ -160,16 +161,37 @@ export default {
         laaa: ratio >= 4.5
       })
 
+      // fgsfds :DDDD
+      const fgs = {
+        text: hex2rgb(colors.text),
+        panelText: hex2rgb(colors.panelText),
+        btnText: hex2rgb(colors.btnText),
+        topBarText: hex2rgb(colors.topBarText),
+
+        link: hex2rgb(colors.link),
+        topBarLink: hex2rgb(colors.topBarLink),
+      }
+
+      const bgs = {
+        bg: hex2rgb(colors.bg),
+        btn: hex2rgb(colors.btn),
+        panel: hex2rgb(colors.panel),
+        topBar: hex2rgb(colors.topBar)
+      }
+
       const ratios = {
-        bgText: getContrastRatio(hex2rgb(colors.bg), hex2rgb(colors.text)),
-        bgLink: getContrastRatio(hex2rgb(colors.bg), hex2rgb(colors.link)),
+        bgText: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.text), fgs.text),
+        bgLink: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.link), fgs.link),
 
-        panelText: getContrastRatio(hex2rgb(colors.panel), hex2rgb(colors.panelText)),
+        // User Profile
+        tintText: getContrastRatio(worstCase(bgs.bg, 0.5, fgs.panelText), fgs.text),
 
-        btnText: getContrastRatio(hex2rgb(colors.btn), hex2rgb(colors.btnText)),
+        panelText: getContrastRatio(worstCase(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
 
-        topBarText: getContrastRatio(hex2rgb(colors.topBar), hex2rgb(colors.topBarText)),
-        topBarLink: getContrastRatio(hex2rgb(colors.topBar), hex2rgb(colors.topBarLink)),
+        btnText: getContrastRatio(worstCase(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
+
+        topBarText: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarText), fgs.topBarText),
+        topBarLink: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarLink), fgs.topBarLink)
       }
 
       return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 31ee3a6b..0acc7e7c 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -19,15 +19,21 @@ const rgb2hex = (r, g, b) => {
   return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`
 }
 
-// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
-// https://www.w3.org/TR/2008/REC-WCAG20-20081211/relative-luminance.xml
-// https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation
-const c2linear = (b) => {
+/**
+ * Converts 8-bit RGB component into linear component
+ * https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+ * https://www.w3.org/TR/2008/REC-WCAG20-20081211/relative-luminance.xml
+ * https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation
+ *
+ * @param {Number} bit - color component [0..255]
+ * @returns {Number} linear component [0..1]
+ */
+const c2linear = (bit) => {
   // W3C gives 0.03928 while wikipedia states 0.04045
   // what those magical numbers mean - I don't know.
   // something about gamma-correction, i suppose.
   // Sticking with W3C example.
-  const c = b / 255
+  const c = bit / 255
   if (c < 0.03928) {
     return c / 12.92
   } else {
@@ -35,18 +41,36 @@ const c2linear = (b) => {
   }
 }
 
+/**
+ * Converts sRGB into linear RGB
+ * @param {Object} srgb - sRGB color
+ * @returns {Object} linear rgb color
+ */
 const srgbToLinear = (srgb) => {
   return 'rgb'.split('').reduce((acc, c) => { acc[c] = c2linear(srgb[c]); return acc }, {})
 }
 
-// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
-// https://www.w3.org/TR/2008/REC-WCAG20-20081211/relative-luminance.xml
+/**
+ * Calculates relative luminance for given color
+ * https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+ * https://www.w3.org/TR/2008/REC-WCAG20-20081211/relative-luminance.xml
+ *
+ * @param {Object} srgb - sRGB color
+ * @returns {Number} relative luminance
+ */
 const relativeLuminance = (srgb) => {
   const {r, g, b} = srgbToLinear(srgb)
   return 0.2126 * r + 0.7152 * g + 0.0722 * b
 }
 
-// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
+/**
+ * Generates color ratio between two colors. Order is unimporant
+ * https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
+ *
+ * @param {Object} a - sRGB color
+ * @param {Object} b - sRGB color
+ * @returns {Number} color ratio
+ */
 const getContrastRatio = (a, b) => {
   const la = relativeLuminance(a)
   const lb = relativeLuminance(b)
@@ -55,6 +79,33 @@ const getContrastRatio = (a, b) => {
   return (l1 + 0.05) / (l2 + 0.05)
 }
 
+/**
+ * This generates what "worst case" color would look like for transparent
+ * segments. I.e. black with .2 alpha and pure-white background image
+ * could make white text unreadable
+ *
+ * @param {Object} srgb - transparent color
+ * @param {Number} alpha - color's opacity/alpha channel
+ * @param {Boolean} white - use white "background" if true, black otherwise
+ * @returns {Object} sRGB of resulting color
+ */
+const transparentWorstCase = (srgb, alpha, white = false) => {
+  const bg = 'rgb'.split('').reduce((acc, c) => { acc[c] = Number(white) * 255; return acc }, {})
+  return 'rgb'.split('').reduce((acc, c) => {
+    // Simplified https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
+    // for opaque bg and transparent fg
+    acc[c] = (srgb[c] * alpha + bg[c] * (1 - alpha))
+    return acc
+  }, {})
+}
+
+const worstCase = (bg, bga, text) => {
+  if (bga === 1 || typeof bga === 'undefined') return bg
+  // taken from https://github.com/toish/chromatism/blob/master/src/operations/contrastRatio.js
+  const blackWorse = ((text.r * 299) + (text.g * 587) + (text.b * 114)) / 1000 <= 128
+  return transparentWorstCase(bg, bga, !blackWorse)
+}
+
 const hex2rgb = (hex) => {
   const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
   return result ? {
@@ -84,5 +135,6 @@ export {
   hex2rgb,
   mixrgb,
   rgbstr2hex,
-  getContrastRatio
+  getContrastRatio,
+  worstCase
 }

From 7b657fcccd3524aba552cab4ee1005057fd83d41 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 21 Oct 2018 15:25:21 +0300
Subject: [PATCH 09/96] added contrasts for rgbo

---
 .../style_switcher/style_switcher.js          | 20 +++++++++++++------
 .../style_switcher/style_switcher.vue         |  4 ++++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index d4381202..7f794608 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -128,7 +128,7 @@ export default {
           avatarAltRadius: this.avatarAltRadiusLocal,
           tooltipRadius: this.tooltipRadiusLocal,
           attachmentRadius: this.attachmentRadiusLocal
-        },
+        }
       }
     },
     preview () {
@@ -170,6 +170,11 @@ export default {
 
         link: hex2rgb(colors.link),
         topBarLink: hex2rgb(colors.topBarLink),
+
+        red: hex2rgb(colors.cRed),
+        green: hex2rgb(colors.cGreen),
+        blue: hex2rgb(colors.cBlue),
+        orange: hex2rgb(colors.cOrange)
       }
 
       const bgs = {
@@ -182,8 +187,11 @@ export default {
       const ratios = {
         bgText: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.text), fgs.text),
         bgLink: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.link), fgs.link),
+        bgRed: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.red), fgs.red),
+        bgGreen: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.green), fgs.green),
+        bgBlue: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.blue), fgs.blue),
+        bgOrange: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.orange), fgs.orange),
 
-        // User Profile
         tintText: getContrastRatio(worstCase(bgs.bg, 0.5, fgs.panelText), fgs.text),
 
         panelText: getContrastRatio(worstCase(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
@@ -378,10 +386,10 @@ export default {
         this.fgColorLocal = this.selected[2]
         this.textColorLocal = this.selected[3]
         this.linkColorLocal = this.selected[4]
-        this.redColorLocal = this.selected[5]
-        this.greenColorLocal = this.selected[6]
-        this.blueColorLocal = this.selected[7]
-        this.orangeColorLocal = this.selected[8]
+        this.cRedColorLocal = this.selected[5]
+        this.cGreenColorLocal = this.selected[6]
+        this.cBlueColorLocal = this.selected[7]
+        this.cOrangeColorLocal = this.selected[8]
       }
     }
   }
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 4235d65c..cecd6bc0 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -64,11 +64,15 @@
       </div>
       <div class="color-item">
         <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
+        <ContrastRatio :contrast="previewContrast.bgRed"/>
         <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
+        <ContrastRatio :contrast="previewContrast.bgBlue"/>
       </div>
       <div class="color-item">
         <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
+        <ContrastRatio :contrast="previewContrast.bgGreen"/>
         <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
+        <ContrastRatio :contrast="previewContrast.bgOrange"/>
       </div>
       <div class="color-item wide">
         <h4>Alert opacity</h4>

From 1723f427f59bb6bf62bb35de93c7226aef2e8727 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 13 Nov 2018 16:30:01 +0300
Subject: [PATCH 10/96] updates

---
 src/App.scss                                  |   4 +-
 src/_variables.scss                           |   2 +-
 .../contrast_ratio/contrast_ratio.vue         |  50 +++++++-----------
 .../notifications/notifications.scss          |   8 +--
 .../opacity_input/opacity_input.vue           |  10 ----
 .../style_switcher/style_switcher.js          |  24 ++++++++-
 .../style_switcher/style_switcher.vue         |  26 +++++----
 src/services/color_convert/color_convert.js   |  16 +++---
 src/services/style_setter/style_setter.js     |   6 ++-
 static/font/config.json                       |  26 ++++++---
 static/font/css/fontello-codes.css            |   6 ++-
 static/font/css/fontello-embedded.css         |  18 ++++---
 static/font/css/fontello-ie7-codes.css        |   6 ++-
 static/font/css/fontello-ie7.css              |   6 ++-
 static/font/css/fontello.css                  |  20 +++----
 static/font/demo.html                         |  22 ++++----
 static/font/font/fontello.eot                 | Bin 15552 -> 16124 bytes
 static/font/font/fontello.svg                 |   8 ++-
 static/font/font/fontello.ttf                 | Bin 15384 -> 15956 bytes
 static/font/font/fontello.woff                | Bin 9432 -> 9848 bytes
 static/font/font/fontello.woff2               | Bin 8020 -> 8372 bytes
 21 files changed, 145 insertions(+), 113 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index c91b6a61..0a2ff5cc 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -479,8 +479,8 @@ nav {
   line-height: 28px;
 
   &.error {
-    background-color: $fallback--cAlertRed;
-    background-color: var(--cAlertRed, $fallback--cAlertRed);
+    background-color: $fallback--alertError;
+    background-color: var(--alertError, $fallback--alertError);
   }
 }
 
diff --git a/src/_variables.scss b/src/_variables.scss
index 0f73e929..d0d91efe 100644
--- a/src/_variables.scss
+++ b/src/_variables.scss
@@ -16,7 +16,7 @@ $fallback--cBlue: #0095ff;
 $fallback--cGreen: #0fa00f;
 $fallback--cOrange: orange;
 
-$fallback--cAlertRed: rgba(211,16,20,.5);
+$fallback--alertError: rgba(211,16,20,.5);
 
 $fallback--panelRadius: 10px;
 $fallback--checkBoxRadius: 2px;
diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
index 6c4a59b6..a428e75f 100644
--- a/src/components/contrast_ratio/contrast_ratio.vue
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -1,41 +1,28 @@
 <template>
-<div class="contrast-ratio">
-  <span class="label">
-    Contrast:
-  </span>
-  <span>
-    <span>
-      {{contrast.text}}
+<span class="contrast-ratio">
+  <span :title="`Contrast is ${contrast.text}`" class="rating">
+    <span v-if="contrast.aaa">
+      <i class="icon-thumbs-up-alt"/>
     </span>
-    <span class="rating">
-      <span v-if="contrast.aaa">
-        AAA
-      </span>
-      <span v-if="!contrast.aaa && contrast.aa">
-        AA
-      </span>
-      <span v-if="!contrast.aaa && !contrast.aa">
-        bad
-      </span>
+    <span v-if="!contrast.aaa && contrast.aa">
+      <i class="icon-adjust"/>
+    </span>
+    <span v-if="!contrast.aaa && !contrast.aa">
+      <i class="icon-attention"/>
     </span>
   </span>
-  <span v-if="large">
-    <span>
-      18pt+:
+  <span class="rating" v-if="large" :title="`Contrast is ${contrast.text} (18pt+)`">
+    <span v-if="contrast.aaa">
+      <i class="icon-thumbs-up-alt"/>
     </span>
-    <span class="rating">
-      <span v-if="contrast.aaa">
-        AAA
-      </span>
-      <span v-if="!contrast.aaa && contrast.aa">
-        AA
-      </span>
-      <span v-if="!contrast.aaa && !contrast.aa">
-        bad
-      </span>
+    <span v-if="!contrast.aaa && contrast.aa">
+      <i class="icon-adjust"/>
+    </span>
+    <span v-if="!contrast.aaa && !contrast.aa">
+      <i class="icon-attention"/>
     </span>
   </span>
-</div>
+</span>
 </template>
 
 <script>
@@ -57,7 +44,6 @@ export default {
 
   .rating {
     display: inline-block;
-    min-width: 3em;
     text-align: center;
   }
 }
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index a98c2549..98fdd3f5 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -7,7 +7,7 @@
   .unseen-count {
     display: inline-block;
     background-color: $fallback--cRed;
-    background-color: var(--cRed, $fallback--cRed);
+    background-color: var(--badgeNotification, $fallback--cRed);
     text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.5);
     border-radius: 99px;
     min-width: 22px;
@@ -27,7 +27,7 @@
   }
 
   .unseen {
-    box-shadow: inset 4px 0 0 var(--cRed, $fallback--cRed);
+    box-shadow: inset 4px 0 0 var(--badgeNotification, $fallback--cRed);
     padding-left: 0;
   }
 }
@@ -44,8 +44,8 @@
     border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
     color: $fallback--faint;
     color: var(--faint, $fallback--faint);
-    background-color: $fallback--cAlertRed;
-    background-color: var(--cAlertRed, $fallback--cAlertRed);
+    background-color: $fallback--alertError;
+    background-color: var(--alertError, $fallback--alertError);
     padding: 2px .5em
   }
 
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index 09972868..efa6c449 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -12,16 +12,6 @@
            @input="$emit('input', !present ? fallback : undefined)"
            >
   <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
-  <input
-    :id="name"
-    class="input-range"
-    type="range"
-    :value="value || fallback"
-    :disabled="!present"
-    @input="$emit('input', $event.target.value)"
-    max="1"
-    min="0"
-    step=".05">
   <input
     :id="name"
     class="input-number"
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 7f794608..8953dc49 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -39,6 +39,10 @@ export default {
       topBarLinkColorLocal: undefined,
 
       alertOpacityLocal: undefined,
+      alertErrorColorLocal: undefined,
+
+      badgeOpacityLocal: undefined,
+      badgeNotificationColorLocal: undefined,
 
       borderColorLocal: undefined,
       borderOpacityLocal: undefined,
@@ -102,6 +106,9 @@ export default {
           btn: this.btnColorLocal,
           btnText: this.btnTextColorLocal,
 
+          alertError: this.alertErrorColorLocal,
+          badgeNotification: this.badgeNotificationColorLocal,
+
           faint: this.faintColorLocal,
           faintLink: this.faintLinkColorLocal,
           border: this.borderColorLocal,
@@ -116,6 +123,8 @@ export default {
           btn: this.btnOpacityLocal,
           input: this.inputOpacityLocal,
           panel: this.panelOpacityLocal,
+          alert: this.alertOpacityLocal,
+          badge: this.badgeOpacityLocal,
           topBar: this.topBarOpacityLocal,
           border: this.borderOpacityLocal,
           faint: this.faintOpacityLocal
@@ -167,6 +176,7 @@ export default {
         panelText: hex2rgb(colors.panelText),
         btnText: hex2rgb(colors.btnText),
         topBarText: hex2rgb(colors.topBarText),
+        inputText: hex2rgb(colors.inputText),
 
         link: hex2rgb(colors.link),
         topBarLink: hex2rgb(colors.topBarLink),
@@ -181,7 +191,10 @@ export default {
         bg: hex2rgb(colors.bg),
         btn: hex2rgb(colors.btn),
         panel: hex2rgb(colors.panel),
-        topBar: hex2rgb(colors.topBar)
+        topBar: hex2rgb(colors.topBar),
+        input: hex2rgb(colors.input),
+        alertError: hex2rgb(colors.alertError),
+        badgeNotification: hex2rgb(colors.badgeNotification)
       }
 
       const ratios = {
@@ -198,6 +211,10 @@ export default {
 
         btnText: getContrastRatio(worstCase(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
 
+        inputText: getContrastRatio(worstCase(bgs.input, opacity.input, fgs.inputText), fgs.inputText),
+
+        badgeNotification: getContrastRatio(worstCase(bgs.badgeNotification, opacity.badge, fgs.text), fgs.text),
+
         topBarText: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarText), fgs.topBarText),
         topBarLink: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarLink), fgs.topBarLink)
       }
@@ -317,6 +334,10 @@ export default {
       this.faintColorLocal = undefined
       this.faintOpacityLocal = undefined
       this.faintLinkColorLocal = undefined
+
+      this.alertErrorColorLocal = undefined
+
+      this.badgeNotificationColorLocal = undefined
     },
 
     /**
@@ -348,6 +369,7 @@ export default {
       }
 
       const keys = new Set(version !== 1 ? Object.keys(colors) : [])
+      console.log(keys)
       if (version === 1) {
         // V1 ignores the rest
         this.clearV1()
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index cecd6bc0..f4b4e88f 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -74,21 +74,27 @@
         <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
         <ContrastRatio :contrast="previewContrast.bgOrange"/>
       </div>
-      <div class="color-item wide">
-        <h4>Alert opacity</h4>
-        <OpacityInput name="alertOpacity" v-model="alertOpacityLocal" fallback="previewTheme.opacity.alert || 1"/>
-      </div>
     </div>
 
     <h3>More customs!</h3>
     <div>
+      <div class="color-item">
+        <h4>Alerts</h4>
+        <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.error')" :fallback="previewTheme.colors.alertError"/>
+        <OpacityInput name="alertOpacity" v-model="alertOpacityLocal" :fallback="previewTheme.opacity.alert || 1"/>
+      </div>
+      <div class="color-item">
+        <h4>Alerts</h4>
+        <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.notification')" :fallback="previewTheme.colors.badgeNotification"/>
+        <ContrastRatio :contrast="previewContrast.badgeNotification"/>
+        <OpacityInput name="badgeOpacity" v-model="badgeOpacityLocal" :fallback="previewTheme.opacity.badge || 1"/>
+      </div>
       <div class="color-item">
         <h4>Panel header</h4>
         <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
         <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
         <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
-        <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.faint')"/>
       </div>
       <div class="color-item">
         <h4>Top bar</h4>
@@ -99,10 +105,11 @@
         <ContrastRatio :contrast="previewContrast.topBarLink"/>
       </div>
       <div class="color-item">
-        <h4>Inputs</h4>
+        <h4>Text fields</h4>
         <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
         <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
         <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
+        <ContrastRatio :contrast="previewContrast.inputText"/>
       </div>
       <div class="color-item">
         <h4>Buttons</h4>
@@ -120,7 +127,8 @@
         <h4>Faint text</h4>
         <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
         <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
-        <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" fallback="previewTheme.opacity.faint"/>
+        <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.panel')"/>
+        <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
       </div>
     </div>
   </div>
@@ -259,10 +267,6 @@
   h4 {
     margin-top: 1em;
   }
-
-  label {
-    color: var(--faint, $fallback--faint);
-  }
 }
 
 .radius-item {
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 0acc7e7c..7a5254b9 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -81,29 +81,27 @@ const getContrastRatio = (a, b) => {
 
 /**
  * This generates what "worst case" color would look like for transparent
- * segments. I.e. black with .2 alpha and pure-white background image
- * could make white text unreadable
+ * segments. I.e. transparent black with yellow text over yellow background.
  *
  * @param {Object} srgb - transparent color
  * @param {Number} alpha - color's opacity/alpha channel
- * @param {Boolean} white - use white "background" if true, black otherwise
+ * @param {Object} textSrgb - text color (considered as worst case scenario for transparent background)
  * @returns {Object} sRGB of resulting color
  */
-const transparentWorstCase = (srgb, alpha, white = false) => {
-  const bg = 'rgb'.split('').reduce((acc, c) => { acc[c] = Number(white) * 255; return acc }, {})
+const transparentWorstCase = (srgb, alpha, textSrgb) => {
   return 'rgb'.split('').reduce((acc, c) => {
     // Simplified https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
     // for opaque bg and transparent fg
-    acc[c] = (srgb[c] * alpha + bg[c] * (1 - alpha))
+    acc[c] = (srgb[c] * alpha + textSrgb[c] * (1 - alpha))
     return acc
   }, {})
 }
 
 const worstCase = (bg, bga, text) => {
+  console.log(bg)
+  console.log(text)
   if (bga === 1 || typeof bga === 'undefined') return bg
-  // taken from https://github.com/toish/chromatism/blob/master/src/operations/contrastRatio.js
-  const blackWorse = ((text.r * 299) + (text.g * 587) + (text.b * 114)) / 1000 <= 128
-  return transparentWorstCase(bg, bga, !blackWorse)
+  return transparentWorstCase(bg, bga, text)
 }
 
 const hex2rgb = (hex) => {
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 4de39f79..666e74c1 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -155,12 +155,14 @@ const generatePreset = (input) => {
   colors.cGreen = col.cGreen
   colors.cOrange = col.cOrange
 
-  colors.cAlertRed = col.cAlertRed || Object.assign({}, col.cRed)
+  colors.alertError = col.alertError || Object.assign({}, col.cRed)
+  colors.badgeNotification = col.badgeNotification || Object.assign({}, col.cRed)
+  colors.badgeNotificationText = col.badgeNotification || Object.assign({}, col.cRed)
 
   Object.entries(opacity).forEach(([ k, v ]) => {
     if (typeof v === 'undefined') return
     if (k === 'alert') {
-      colors.cAlertRed.a = v
+      colors.alertError.a = v
       return
     }
     if (k === 'faint') {
diff --git a/static/font/config.json b/static/font/config.json
index 20cb3254..be809269 100644
--- a/static/font/config.json
+++ b/static/font/config.json
@@ -51,7 +51,7 @@
     {
       "uid": "09feb4465d9bd1364f4e301c9ddbaa92",
       "css": "retweet",
-      "code": 59396,
+      "code": 59398,
       "src": "fontawesome"
     },
     {
@@ -66,12 +66,6 @@
       "code": 61925,
       "src": "fontawesome"
     },
-    {
-      "uid": "1a5cfa186647e8c929c2b17b9fc4dac1",
-      "css": "plus-squared",
-      "code": 59398,
-      "src": "font-awesome"
-    },
     {
       "uid": "e99461abfef3923546da8d745372c995",
       "css": "cog",
@@ -191,6 +185,24 @@
       "css": "brush",
       "code": 59411,
       "src": "iconic"
+    },
+    {
+      "uid": "ca90da02d2c6a3183f2458e4dc416285",
+      "css": "adjust",
+      "code": 59396,
+      "src": "fontawesome"
+    },
+    {
+      "uid": "5e2ab018e3044337bcef5f7e94098ea1",
+      "css": "thumbs-up-alt",
+      "code": 61796,
+      "src": "fontawesome"
+    },
+    {
+      "uid": "c76b7947c957c9b78b11741173c8349b",
+      "css": "attention",
+      "code": 59412,
+      "src": "fontawesome"
     }
   ]
 }
\ No newline at end of file
diff --git a/static/font/css/fontello-codes.css b/static/font/css/fontello-codes.css
index b1c76c3f..21cf6f06 100644
--- a/static/font/css/fontello-codes.css
+++ b/static/font/css/fontello-codes.css
@@ -3,9 +3,9 @@
 .icon-upload:before { content: '\e801'; } /* '' */
 .icon-star:before { content: '\e802'; } /* '' */
 .icon-star-empty:before { content: '\e803'; } /* '' */
-.icon-retweet:before { content: '\e804'; } /* '' */
+.icon-adjust:before { content: '\e804'; } /* '' */
 .icon-eye-off:before { content: '\e805'; } /* '' */
-.icon-plus-squared:before { content: '\e806'; } /* '' */
+.icon-retweet:before { content: '\e806'; } /* '' */
 .icon-cog:before { content: '\e807'; } /* '' */
 .icon-logout:before { content: '\e808'; } /* '' */
 .icon-down-open:before { content: '\e809'; } /* '' */
@@ -19,6 +19,7 @@
 .icon-lock:before { content: '\e811'; } /* '' */
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
+.icon-attention:before { content: '\e814'; } /* '' */
 .icon-spin3:before { content: '\e832'; } /* '' */
 .icon-spin4:before { content: '\e834'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
@@ -28,5 +29,6 @@
 .icon-comment-empty:before { content: '\f0e5'; } /* '' */
 .icon-reply:before { content: '\f112'; } /* '' */
 .icon-lock-open-alt:before { content: '\f13e'; } /* '' */
+.icon-thumbs-up-alt:before { content: '\f164'; } /* '' */
 .icon-binoculars:before { content: '\f1e5'; } /* '' */
 .icon-user-plus:before { content: '\f234'; } /* '' */
\ No newline at end of file
diff --git a/static/font/css/fontello-embedded.css b/static/font/css/fontello-embedded.css
index bea63f38..a1b3e3d6 100644
--- a/static/font/css/fontello-embedded.css
+++ b/static/font/css/fontello-embedded.css
@@ -1,15 +1,15 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?99189355');
-  src: url('../font/fontello.eot?99189355#iefix') format('embedded-opentype'),
-       url('../font/fontello.svg?99189355#fontello') format('svg');
+  src: url('../font/fontello.eot?61520746');
+  src: url('../font/fontello.eot?61520746#iefix') format('embedded-opentype'),
+       url('../font/fontello.svg?61520746#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
 @font-face {
   font-family: 'fontello';
-  src: url('data:application/octet-stream;base64,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') format('woff'),
-       url('data:application/octet-stream;base64,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') format('truetype');
+  src: url('data:application/octet-stream;base64,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') format('woff'),
+       url('data:application/octet-stream;base64,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RCywABUgR7AAI0KyAAEBFRQTLrAxKi2wRSywABUgR7AAI0KyAAEBFRQTLrAxKi2wRiyxAAEUE7AyKi2wRyywNCotsEgssAAWRSMgLiBGiiNhOLErARQrLbBJLLAII0KwSCstsEossgAAQSstsEsssgABQSstsEwssgEAQSstsE0ssgEBQSstsE4ssgAAQistsE8ssgABQistsFAssgEAQistsFEssgEBQistsFIssgAAPistsFMssgABPistsFQssgEAPistsFUssgEBPistsFYssgAAQCstsFcssgABQCstsFgssgEAQCstsFkssgEBQCstsFossgAAQystsFsssgABQystsFwssgEAQystsF0ssgEBQystsF4ssgAAPystsF8ssgABPystsGAssgEAPystsGEssgEBPystsGIssDcrLrErARQrLbBjLLA3K7A7Ky2wZCywNyuwPCstsGUssAAWsDcrsD0rLbBmLLA4Ky6xKwEUKy2wZyywOCuwOystsGgssDgrsDwrLbBpLLA4K7A9Ky2waiywOSsusSsBFCstsGsssDkrsDsrLbBsLLA5K7A8Ky2wbSywOSuwPSstsG4ssDorLrErARQrLbBvLLA6K7A7Ky2wcCywOiuwPCstsHEssDorsD0rLbByLLMJBAIDRVghGyMhWUIrsAhlsAMkUHiwARUwLQBLuADIUlixAQGOWbABuQgACABjcLEABUKyAAEAKrEABUKzCgIBCCqxAAVCsw4AAQgqsQAGQroCwAABAAkqsQAHQroAQAABAAkqsQMARLEkAYhRWLBAiFixA2REsSYBiFFYugiAAAEEQIhjVFixAwBEWVlZWbMMAgEMKrgB/4WwBI2xAgBEAAA=') format('truetype');
 }
 /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
 /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
@@ -17,7 +17,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?99189355#fontello') format('svg');
+    src: url('../font/fontello.svg?61520746#fontello') format('svg');
   }
 }
 */
@@ -56,9 +56,9 @@
 .icon-upload:before { content: '\e801'; } /* '' */
 .icon-star:before { content: '\e802'; } /* '' */
 .icon-star-empty:before { content: '\e803'; } /* '' */
-.icon-retweet:before { content: '\e804'; } /* '' */
+.icon-adjust:before { content: '\e804'; } /* '' */
 .icon-eye-off:before { content: '\e805'; } /* '' */
-.icon-plus-squared:before { content: '\e806'; } /* '' */
+.icon-retweet:before { content: '\e806'; } /* '' */
 .icon-cog:before { content: '\e807'; } /* '' */
 .icon-logout:before { content: '\e808'; } /* '' */
 .icon-down-open:before { content: '\e809'; } /* '' */
@@ -72,6 +72,7 @@
 .icon-lock:before { content: '\e811'; } /* '' */
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
+.icon-attention:before { content: '\e814'; } /* '' */
 .icon-spin3:before { content: '\e832'; } /* '' */
 .icon-spin4:before { content: '\e834'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
@@ -81,5 +82,6 @@
 .icon-comment-empty:before { content: '\f0e5'; } /* '' */
 .icon-reply:before { content: '\f112'; } /* '' */
 .icon-lock-open-alt:before { content: '\f13e'; } /* '' */
+.icon-thumbs-up-alt:before { content: '\f164'; } /* '' */
 .icon-binoculars:before { content: '\f1e5'; } /* '' */
 .icon-user-plus:before { content: '\f234'; } /* '' */
\ No newline at end of file
diff --git a/static/font/css/fontello-ie7-codes.css b/static/font/css/fontello-ie7-codes.css
index 5ba45f75..5e732ec9 100644
--- a/static/font/css/fontello-ie7-codes.css
+++ b/static/font/css/fontello-ie7-codes.css
@@ -3,9 +3,9 @@
 .icon-upload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
 .icon-star { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
 .icon-star-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
-.icon-retweet { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
+.icon-adjust { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
 .icon-eye-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
-.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
+.icon-retweet { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
 .icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }
 .icon-logout { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe808;&nbsp;'); }
 .icon-down-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe809;&nbsp;'); }
@@ -19,6 +19,7 @@
 .icon-lock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe811;&nbsp;'); }
 .icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
 .icon-brush { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
+.icon-attention { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe814;&nbsp;'); }
 .icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe832;&nbsp;'); }
 .icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe834;&nbsp;'); }
 .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
@@ -28,5 +29,6 @@
 .icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e5;&nbsp;'); }
 .icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf112;&nbsp;'); }
 .icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13e;&nbsp;'); }
+.icon-thumbs-up-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf164;&nbsp;'); }
 .icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf1e5;&nbsp;'); }
 .icon-user-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf234;&nbsp;'); }
\ No newline at end of file
diff --git a/static/font/css/fontello-ie7.css b/static/font/css/fontello-ie7.css
index 6ab5e0ca..b4be6e9b 100644
--- a/static/font/css/fontello-ie7.css
+++ b/static/font/css/fontello-ie7.css
@@ -14,9 +14,9 @@
 .icon-upload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
 .icon-star { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
 .icon-star-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
-.icon-retweet { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
+.icon-adjust { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
 .icon-eye-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
-.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
+.icon-retweet { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
 .icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }
 .icon-logout { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe808;&nbsp;'); }
 .icon-down-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe809;&nbsp;'); }
@@ -30,6 +30,7 @@
 .icon-lock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe811;&nbsp;'); }
 .icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
 .icon-brush { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
+.icon-attention { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe814;&nbsp;'); }
 .icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe832;&nbsp;'); }
 .icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe834;&nbsp;'); }
 .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
@@ -39,5 +40,6 @@
 .icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e5;&nbsp;'); }
 .icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf112;&nbsp;'); }
 .icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13e;&nbsp;'); }
+.icon-thumbs-up-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf164;&nbsp;'); }
 .icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf1e5;&nbsp;'); }
 .icon-user-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf234;&nbsp;'); }
\ No newline at end of file
diff --git a/static/font/css/fontello.css b/static/font/css/fontello.css
index 2a3d708d..d8419862 100644
--- a/static/font/css/fontello.css
+++ b/static/font/css/fontello.css
@@ -1,11 +1,11 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?60305294');
-  src: url('../font/fontello.eot?60305294#iefix') format('embedded-opentype'),
-       url('../font/fontello.woff2?60305294') format('woff2'),
-       url('../font/fontello.woff?60305294') format('woff'),
-       url('../font/fontello.ttf?60305294') format('truetype'),
-       url('../font/fontello.svg?60305294#fontello') format('svg');
+  src: url('../font/fontello.eot?91338570');
+  src: url('../font/fontello.eot?91338570#iefix') format('embedded-opentype'),
+       url('../font/fontello.woff2?91338570') format('woff2'),
+       url('../font/fontello.woff?91338570') format('woff'),
+       url('../font/fontello.ttf?91338570') format('truetype'),
+       url('../font/fontello.svg?91338570#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
@@ -15,7 +15,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?60305294#fontello') format('svg');
+    src: url('../font/fontello.svg?91338570#fontello') format('svg');
   }
 }
 */
@@ -59,9 +59,9 @@
 .icon-upload:before { content: '\e801'; } /* '' */
 .icon-star:before { content: '\e802'; } /* '' */
 .icon-star-empty:before { content: '\e803'; } /* '' */
-.icon-retweet:before { content: '\e804'; } /* '' */
+.icon-adjust:before { content: '\e804'; } /* '' */
 .icon-eye-off:before { content: '\e805'; } /* '' */
-.icon-plus-squared:before { content: '\e806'; } /* '' */
+.icon-retweet:before { content: '\e806'; } /* '' */
 .icon-cog:before { content: '\e807'; } /* '' */
 .icon-logout:before { content: '\e808'; } /* '' */
 .icon-down-open:before { content: '\e809'; } /* '' */
@@ -75,6 +75,7 @@
 .icon-lock:before { content: '\e811'; } /* '' */
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
+.icon-attention:before { content: '\e814'; } /* '' */
 .icon-spin3:before { content: '\e832'; } /* '' */
 .icon-spin4:before { content: '\e834'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
@@ -84,5 +85,6 @@
 .icon-comment-empty:before { content: '\f0e5'; } /* '' */
 .icon-reply:before { content: '\f112'; } /* '' */
 .icon-lock-open-alt:before { content: '\f13e'; } /* '' */
+.icon-thumbs-up-alt:before { content: '\f164'; } /* '' */
 .icon-binoculars:before { content: '\f1e5'; } /* '' */
 .icon-user-plus:before { content: '\f234'; } /* '' */
\ No newline at end of file
diff --git a/static/font/demo.html b/static/font/demo.html
index 26a1875e..22bc0e92 100644
--- a/static/font/demo.html
+++ b/static/font/demo.html
@@ -229,11 +229,11 @@ body {
 }
 @font-face {
       font-family: 'fontello';
-      src: url('./font/fontello.eot?32487936');
-      src: url('./font/fontello.eot?32487936#iefix') format('embedded-opentype'),
-           url('./font/fontello.woff?32487936') format('woff'),
-           url('./font/fontello.ttf?32487936') format('truetype'),
-           url('./font/fontello.svg?32487936#fontello') format('svg');
+      src: url('./font/fontello.eot?93659852');
+      src: url('./font/fontello.eot?93659852#iefix') format('embedded-opentype'),
+           url('./font/fontello.woff?93659852') format('woff'),
+           url('./font/fontello.ttf?93659852') format('truetype'),
+           url('./font/fontello.svg?93659852#fontello') format('svg');
       font-weight: normal;
       font-style: normal;
     }
@@ -304,9 +304,9 @@ body {
         <div class="the-icons span3" title="Code: 0xe803"><i class="demo-icon icon-star-empty">&#xe803;</i> <span class="i-name">icon-star-empty</span><span class="i-code">0xe803</span></div>
       </div>
       <div class="row">
-        <div class="the-icons span3" title="Code: 0xe804"><i class="demo-icon icon-retweet">&#xe804;</i> <span class="i-name">icon-retweet</span><span class="i-code">0xe804</span></div>
+        <div class="the-icons span3" title="Code: 0xe804"><i class="demo-icon icon-adjust">&#xe804;</i> <span class="i-name">icon-adjust</span><span class="i-code">0xe804</span></div>
         <div class="the-icons span3" title="Code: 0xe805"><i class="demo-icon icon-eye-off">&#xe805;</i> <span class="i-name">icon-eye-off</span><span class="i-code">0xe805</span></div>
-        <div class="the-icons span3" title="Code: 0xe806"><i class="demo-icon icon-plus-squared">&#xe806;</i> <span class="i-name">icon-plus-squared</span><span class="i-code">0xe806</span></div>
+        <div class="the-icons span3" title="Code: 0xe806"><i class="demo-icon icon-retweet">&#xe806;</i> <span class="i-name">icon-retweet</span><span class="i-code">0xe806</span></div>
         <div class="the-icons span3" title="Code: 0xe807"><i class="demo-icon icon-cog">&#xe807;</i> <span class="i-name">icon-cog</span><span class="i-code">0xe807</span></div>
       </div>
       <div class="row">
@@ -328,20 +328,24 @@ body {
         <div class="the-icons span3" title="Code: 0xe813"><i class="demo-icon icon-brush">&#xe813;</i> <span class="i-name">icon-brush</span><span class="i-code">0xe813</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xe814"><i class="demo-icon icon-attention">&#xe814;</i> <span class="i-name">icon-attention</span><span class="i-code">0xe814</span></div>
         <div class="the-icons span3" title="Code: 0xe832"><i class="demo-icon icon-spin3 animate-spin">&#xe832;</i> <span class="i-name">icon-spin3</span><span class="i-code">0xe832</span></div>
         <div class="the-icons span3" title="Code: 0xe834"><i class="demo-icon icon-spin4 animate-spin">&#xe834;</i> <span class="i-name">icon-spin4</span><span class="i-code">0xe834</span></div>
         <div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-link-ext">&#xf08e;</i> <span class="i-name">icon-link-ext</span><span class="i-code">0xf08e</span></div>
-        <div class="the-icons span3" title="Code: 0xf08f"><i class="demo-icon icon-link-ext-alt">&#xf08f;</i> <span class="i-name">icon-link-ext-alt</span><span class="i-code">0xf08f</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf08f"><i class="demo-icon icon-link-ext-alt">&#xf08f;</i> <span class="i-name">icon-link-ext-alt</span><span class="i-code">0xf08f</span></div>
         <div class="the-icons span3" title="Code: 0xf0c9"><i class="demo-icon icon-menu">&#xf0c9;</i> <span class="i-name">icon-menu</span><span class="i-code">0xf0c9</span></div>
         <div class="the-icons span3" title="Code: 0xf0e0"><i class="demo-icon icon-mail-alt">&#xf0e0;</i> <span class="i-name">icon-mail-alt</span><span class="i-code">0xf0e0</span></div>
         <div class="the-icons span3" title="Code: 0xf0e5"><i class="demo-icon icon-comment-empty">&#xf0e5;</i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xf0e5</span></div>
-        <div class="the-icons span3" title="Code: 0xf112"><i class="demo-icon icon-reply">&#xf112;</i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf112"><i class="demo-icon icon-reply">&#xf112;</i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
         <div class="the-icons span3" title="Code: 0xf13e"><i class="demo-icon icon-lock-open-alt">&#xf13e;</i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xf13e</span></div>
+        <div class="the-icons span3" title="Code: 0xf164"><i class="demo-icon icon-thumbs-up-alt">&#xf164;</i> <span class="i-name">icon-thumbs-up-alt</span><span class="i-code">0xf164</span></div>
         <div class="the-icons span3" title="Code: 0xf1e5"><i class="demo-icon icon-binoculars">&#xf1e5;</i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
+      </div>
+      <div class="row">
         <div class="the-icons span3" title="Code: 0xf234"><i class="demo-icon icon-user-plus">&#xf234;</i> <span class="i-name">icon-user-plus</span><span class="i-code">0xf234</span></div>
       </div>
     </div>
diff --git a/static/font/font/fontello.eot b/static/font/font/fontello.eot
index 0533282b937801677597e6f61c7f0f2e66845d04..993381629cbd44410df7caee5dfa646e5ed19525 100644
GIT binary patch
delta 1615
zcmY*ZZERCj7=GV#zq_s<x3{<ZU~6}~wS;bLD`hi+wV;T?VwO3{Hc=>Bw}I<gw-yEl
zYy3r&085E~_{bCmG?JK96GBMz$3j5ypGHGS;Lk`yi0Sx9j2YDTb`s^>Jm)#@bKY~#
z`=0mY{<weXptuwT=#S2dUHrMZ`CGHGPjVjtU@rh{8&1a4v7djqOZIsH?$Gewj87~-
zc?b|*PxHRf^jPxa*<*ubZwIJKkHx3cq&vut5X)l|`$uni_Z9$z4uIgE@kD&Y_4Ngs
zYCTC^*Ek8%HSRIlzmnZNp3Ka=|K+yw9TNT`;m|~CIDV%7QyRB@NcJnq_)Hr2Ri7pM
zD%rltcrtPQRHKjVA^`g(otn;+PGvU%bX=sM52U9O>4goU%K$H2&(GmocqYGuW9#k#
z(rSP^z*R=A#1`_u2RvLNy^c~KrKlCd#YpLB>00S_X<<=aj4qDkPqKPxWO3nsq+HH-
za<#Qc-Wx05%ka#XzsojAK4_wS#WS58s<g4yJQdB{&DNBU@egtuK#>4$;_xy+C#D-T
z0Um(Tk!3&)@zG^KE%CKwPzX@Ey$q-)URVaK09d4RO+W)NmD&U}5|1pS4!ks=1t!1;
zaGwq}0ZoPPgc~eZeq6rD?ch|9K!Z?hCEW}l2RnI0#;~6V*#IzPJpiiHT19@6QxM#t
z7N=ojjfk2JjnyoQVH#g}<8UwQKg4kAO7ZHXc;NEGOCPLdJNpiQakvjVvh$hD{9Uu7
z7XwiKi7T?gXUa}2%*rwreyiH<%5mjK6wd>05bSifYhWa1t#>kxDaa7m=B?j0_YTAw
zfC-$yxa8Adsmwg`+d&Yl!fW+00|X|dfR?5H^Wb^x2Sk3rbnO|8DW2zo!GK>B>Ow7R
zBY_YaVgu$h-Lod#6?8>{rXq=MkEVB%!l5qNP--#)!9X`swmMs9ktQTdr9+D#Ne4t(
zP^{9JY?bjF&8-;f(pl9|+!|g`jDRt;N48jG>d^W-qR5LPFP8-wMdn!g)9-hxs5$(y
zpHrQh22g1C>Pn7kLAP;`sw30mcoSZaZQX*h<gI6v7b0{zsYd)}kYp(ZGAE}*Djk=i
z3PK8a#;2iDL~>;V0^K0%X>WBmzZh8SQWc>g)E!xkHf+Q$ms1lZKjr3(bW#4gph>!0
zmvXu!N+$fqY77Q~6^AJ6?&_v4%B=}E@}h_8FWHzxtB&do8WM&y$DEx;wmG}bj(ZiX
zRTM=Re9c>4ZP^xHwaG=3TK)4Y0;<I(3cToW+iO?VXtKzdRkotcb0<Qvcgd-zvLUuU
zIZ@dT6E+<+dxyVPU1fOvUUxJYLe*xkp`$8uF@L9OF|-=J#?Y;5U5!tzcDL#pZ?%ar
zD7>_Ck>zg9&z;+0U;hZIIQpdk{9%uL^_1!9?c!&+F|uV~rb>-|CEQ^7Jpg_$%|GC0
zOy!wom^*P!!rcEbSbl8ke7m{+U%d$VLZ}rV<!^>sa4!EO<k@hZ4YAwY=X^6i#Lo*+
z@tAl;{9EdfdAY~hYdun}Ru^qEcHN$_-*9Yk+;oPWC)JHEi|cy|!3@MG^tD!TXyo5%
zkMU@rKYzO2>k;E4d$Q9RDX~A%mKq(ErV^Qbi9{xUqy24*63=83lbPMA$$WQ5UrTjn
qJe%A#-Ih(a#V0bBUAre!!`X@W)U=YFPE56>C$iJ@8c%l^)_(vKZCslG

delta 961
zcmYjQUuaWT82_DnZ|;pvnxyINO}A=u({v8orLJj`B6eM48T#OZh=@guy|lM2+St1`
z?ONDq5s}eBwL4DmVZ(up!C(yUgZm@WO;HpDx0elNBQKSdJuIzG1~$vS<ZiHY?(h80
z@B6;<efJ#B*?ezhPG0E&8he)Il=OHpvbNm!!TbWi4gfejlr^lkzKxbie-4PlLo+#D
zF8}=uc%9tPN37B8;_~?c(mLR=MvW<p>;YisU&QXw@wt)NkEVYITwdUnnK9EC4&J%8
z6=*v{{?r&5lpn<xq_2~19n0osb4`cKRG=+ShK2EoA>+d@&JF_Y1nkKgvlg4K{fzV#
z()uYQYu^93Stor95FS_)Q@JO`R|e2=fqr_}nl!D|bUP*AeV$)tN7<)*la21mgVAc>
z5ya~3HR2kI&qKnOWN)M`h;SF`3-Lmtc&>Q2m@lrb2iJS~Cqk2Jbt6$O^Y4XFh*4y3
zwfEtFoo@(fN-XoVxXB+1ik~)5*(+PFv@qW<J)MsO1p*p~6AqvO#U%#_5ubBFRZzU^
z051{e9pGi+RR?GS)`Jc}2fW_v0NaQurUEnr8&s<T0b%<W*CWARs_`&;$CfcR|Ft+E
z1`$OU(tW+P3@pqfQP?ZcOk@zVE+$I!orFS%rm#UsvMe2fB*{l0OY;6?GTNm@Tcd8*
z)^?UmY*(T*yc%thm4@n|YTaE8s<xZOQ{Bm~c&ffmm6b@#_GDcm)g6f+)P#Gg-`0G4
z{VKak(0o@NVf(bDOn+&uKa=SfLj4(*-sjVpT@A5Se^vN2&1b9Z%~D}ch7G2L#tPXN
zJ;&?qQdr$$A8Y$VXkLpfK0fa6`4b+oK*xcfFMV_EKQ5Q}iC8#PDnFHG|Ggd+m(z59
zIi}V~JLwV7LUDlKi0$GpVl6z<p}w&pToD7}PtqZ2QF`V&C9lZOl{RJ2op8VFUGUzh
zz2Iy0{ovRAXZ_Cu?+1RX+ZPN3zoWdBJE+?;9UhVC{B&m@zug($rc9c-cT6*<m~&=q
jVr0Z?jZaU-rrw@5Ce2~K*?Ei)#SikE@kaaCc-Z?79H96`

diff --git a/static/font/font/fontello.svg b/static/font/font/fontello.svg
index ec7c464d..c706fcad 100644
--- a/static/font/font/fontello.svg
+++ b/static/font/font/fontello.svg
@@ -14,11 +14,11 @@
 
 <glyph glyph-name="star-empty" unicode="&#xe803;" d="M635 297l170 166-235 34-106 213-105-213-236-34 171-166-41-235 211 111 211-111z m294 199q0-12-15-27l-202-197 48-279q0-4 0-12 0-28-23-28-10 0-22 7l-251 132-250-132q-12-7-23-7-11 0-17 9t-6 19q0 4 1 12l48 279-203 197q-14 15-14 27 0 21 31 26l280 40 126 254q11 23 27 23t28-23l125-254 280-40q32-5 32-26z" horiz-adv-x="928.6" />
 
-<glyph glyph-name="retweet" unicode="&#xe804;" d="M714 18q0-7-5-13t-13-5h-535q-5 0-8 1t-5 4-3 4-2 7 0 6v335h-107q-15 0-25 11t-11 25q0 13 8 23l179 214q11 12 27 12t28-12l178-214q9-10 9-23 0-15-11-25t-25-11h-107v-214h321q9 0 14-6l89-108q4-5 4-11z m357 232q0-13-8-23l-178-214q-12-13-28-13t-27 13l-179 214q-8 10-8 23 0 14 11 25t25 11h107v214h-322q-9 0-14 7l-89 107q-4 5-4 11 0 7 5 12t13 6h536q4 0 7-1t5-4 3-5 2-6 1-7v-334h107q14 0 25-11t10-25z" horiz-adv-x="1071.4" />
+<glyph glyph-name="adjust" unicode="&#xe804;" d="M429 53v608q-83 0-153-41t-110-111-41-152 41-152 110-111 153-41z m428 304q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
 
 <glyph glyph-name="eye-off" unicode="&#xe805;" d="M310 112l43 79q-48 35-76 88t-27 114q0 67 34 125-128-65-213-197 94-144 239-209z m217 424q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m202 106q0-4 0-5-59-105-176-316t-176-316l-28-50q-5-9-15-9-7 0-75 39-9 6-9 16 0 7 25 49-80 36-147 96t-117 137q-11 17-11 38t11 39q86 131 212 207t277 76q50 0 100-10l31 54q5 9 15 9 3 0 10-3t18-9 18-10 18-10 10-7q9-5 9-15z m21-249q0-78-44-142t-117-91l157 280q4-25 4-47z m250-72q0-19-11-38-22-36-61-81-84-96-194-149t-234-53l41 74q119 10 219 76t169 171q-65 100-158 164l35 63q53-36 102-85t81-103q11-19 11-39z" horiz-adv-x="1000" />
 
-<glyph glyph-name="plus-squared" unicode="&#xe806;" d="M714 321v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
+<glyph glyph-name="retweet" unicode="&#xe806;" d="M714 18q0-7-5-13t-13-5h-535q-5 0-8 1t-5 4-3 4-2 7 0 6v335h-107q-15 0-25 11t-11 25q0 13 8 23l179 214q11 12 27 12t28-12l178-214q9-10 9-23 0-15-11-25t-25-11h-107v-214h321q9 0 14-6l89-108q4-5 4-11z m357 232q0-13-8-23l-178-214q-12-13-28-13t-27 13l-179 214q-8 10-8 23 0 14 11 25t25 11h107v214h-322q-9 0-14 7l-89 107q-4 5-4 11 0 7 5 12t13 6h536q4 0 7-1t5-4 3-5 2-6 1-7v-334h107q14 0 25-11t10-25z" horiz-adv-x="1071.4" />
 
 <glyph glyph-name="cog" unicode="&#xe807;" d="M571 357q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 16 20 16h124q7 0 13-5t7-12l15-103q28-9 51-20l79 59q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-12 0-7-4-13-9-12-29-37t-30-40q15-28 23-54l102-16q7-1 12-7t4-13z" horiz-adv-x="857.1" />
 
@@ -46,6 +46,8 @@
 
 <glyph glyph-name="brush" unicode="&#xe813;" d="M464 209q0-124-87-212t-210-87q-81 0-149 40 68 39 109 108t40 151q0 61 44 105t105 44 105-44 43-105z m415 562q32-32 32-79t-33-79l-318-318q-20 55-61 97t-97 62l318 318q32 32 79 32t80-33z" horiz-adv-x="928" />
 
+<glyph glyph-name="attention" unicode="&#xe814;" d="M571 90v106q0 8-5 13t-12 5h-108q-7 0-12-5t-5-13v-106q0-8 5-13t12-6h108q7 0 12 6t5 13z m-1 208l10 257q0 6-5 10-7 6-14 6h-122q-6 0-14-6-5-4-5-12l9-255q0-5 6-9t13-3h103q8 0 14 3t5 9z m-7 522l428-786q20-35-1-70-9-17-26-26t-35-10h-858q-18 0-35 10t-26 26q-21 35-1 70l429 786q9 17 26 27t36 10 36-10 27-27z" horiz-adv-x="1000" />
+
 <glyph glyph-name="spin3" unicode="&#xe832;" d="M494 857c-266 0-483-210-494-472-1-19 13-20 13-20l84 0c16 0 19 10 19 18 10 199 176 358 378 358 107 0 205-45 273-118l-58-57c-11-12-11-27 5-31l247-50c21-5 46 11 37 44l-58 227c-2 9-16 22-29 13l-65-60c-89 91-214 148-352 148z m409-508c-16 0-19-10-19-18-10-199-176-358-377-358-108 0-205 45-274 118l59 57c10 12 10 27-5 31l-248 50c-21 5-46-11-37-44l58-227c2-9 16-22 30-13l64 60c89-91 214-148 353-148 265 0 482 210 493 473 1 18-13 19-13 19l-84 0z" horiz-adv-x="1000" />
 
 <glyph glyph-name="spin4" unicode="&#xe834;" d="M498 857c-114 0-228-39-320-116l0 0c173 140 428 130 588-31 134-134 164-332 89-495-10-29-5-50 12-68 21-20 61-23 84 0 3 3 12 15 15 24 71 180 33 393-112 539-99 98-228 147-356 147z m-409-274c-14 0-29-5-39-16-3-3-13-15-15-24-71-180-34-393 112-539 185-185 479-195 676-31l0 0c-173-140-428-130-589 31-134 134-163 333-89 495 11 29 6 50-12 68-11 11-27 17-44 16z" horiz-adv-x="1001" />
@@ -64,6 +66,8 @@
 
 <glyph glyph-name="lock-open-alt" unicode="&#xf13e;" d="M589 428q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v179q0 103 74 177t176 73 177-73 73-177q0-14-10-25t-25-11h-36q-14 0-25 11t-11 25q0 59-42 101t-101 42-101-42-41-101v-179h410z" horiz-adv-x="642.9" />
 
+<glyph glyph-name="thumbs-up-alt" unicode="&#xf164;" d="M143 107q0 15-11 25t-25 11q-15 0-25-11t-11-25q0-15 11-25t25-11q15 0 25 11t11 25z m89 286v-357q0-15-10-25t-26-11h-160q-15 0-25 11t-11 25v357q0 14 11 25t25 10h160q15 0 26-10t10-25z m661 0q0-48-31-83 9-25 9-43 1-42-24-76 9-31 0-66-9-31-31-52 5-62-27-101-36-43-110-44h-72q-37 0-80 9t-68 16-67 22q-69 24-88 25-15 0-25 11t-11 25v357q0 14 10 25t24 11q13 1 42 33t57 67q38 49 56 67 10 10 17 27t10 27 8 34q4 22 7 34t11 29 19 28q10 11 25 11 25 0 46-6t33-15 22-22 14-25 7-28 2-25 1-22q0-21-6-43t-10-33-16-31q-1-4-5-10t-6-13-5-13h155q43 0 75-32t32-75z" horiz-adv-x="928.6" />
+
 <glyph glyph-name="binoculars" unicode="&#xf1e5;" d="M393 678v-428q0-15-11-25t-25-11v-321q0-15-10-25t-26-11h-285q-15 0-25 11t-11 25v285l139 488q4 12 17 12h237z m178 0v-392h-142v392h142z m429-500v-285q0-15-11-25t-25-11h-285q-15 0-25 11t-11 25v321q-15 0-25 11t-11 25v428h237q13 0 17-12z m-589 661v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z m375 0v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z" horiz-adv-x="1000" />
 
 <glyph glyph-name="user-plus" unicode="&#xf234;" d="M393 357q-89 0-152 63t-62 151 62 152 152 63 151-63 63-152-63-151-151-63z m536-71h196q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-196v-197q0-7-6-12t-12-6h-107q-8 0-13 6t-5 12v197h-197q-7 0-12 5t-6 13v107q0 7 6 12t12 6h197v196q0 7 5 13t13 5h107q7 0 12-5t6-13v-196z m-411-125q0-29 21-51t50-21h143v-133q-38-28-95-28h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q11 0 22-10 44-34 86-51t92-17 92 17 86 51q11 10 22 10 73 0 121-54h-125q-29 0-50-21t-21-50v-107z" horiz-adv-x="1142.9" />
diff --git a/static/font/font/fontello.ttf b/static/font/font/fontello.ttf
index 3f91b6432ea9d6cad18c263b6370859b2802b07b..d2d2963e7db8232c1a10317db768f4c3fe1b0b33 100644
GIT binary patch
delta 1558
zcmY*Zdu&r>6hG&?&vtix+}_^q!Pf3}Yt6bBrEEU179yf!F$+%ICI%|&HgR1W*1^C>
zjsHjt*&x>#5+GSb5s4%wjfM~s|5*qq`WK0YXxKj^l@QYbQ#3$5Z6(UR`JMBf=Xbty
zzI;b!uDpH7pM4(y`vG9<&SX3t`~KS-B%cD{4(!~M@rlI;cL2ic$nG0Wk0n1md}xT|
zZ2(p2vG`P)^bV3E#O1MxeWTaBdvX9m7eH{=cp^UHI(>#rZO4dokCQ^W#N8+P3dzmm
z$;`}KpKUE(C&gV-9GFP$jGw6gnAYv@k^EdTK9k11)h9{5NV0D-o=jXm-smGa55Rs%
zr=~K6<I@`fy3SJ3`_sD<>816d^8im@K7998JYf#t*ef>yDHz~7aOG7SaVxps1Rl<j
zzK%{nn!J_|=Ocx=!llAuVQE=ijxLWZFWrh1ivW2j+h+f7Gi|J)p3+eKhVuU`Jo1|x
z*m}taP2?h)huK|oo>keEQXyFCM(JxZk8roM8s#T|n|Qba(1}w|O8^f*VYULOAwE|D
z)Dpi`0o4G7#R`CmDlAn1s{oeO3ZQ{_v;t@(K2kv)cxgcaC4dj$7HwJrH02cGD$5q{
z7teCrITa+(AQXFyngz(g4jz#)93X~l5E!yP0M)5fk)Pxg1b3*#Y1mjJqGm&*gGDh+
z>oYGM>}LZ981BB1zc?xGKY!=kyKC8wEeAh6xCOhW7c!ZJ8zn+_2%z{KmuI=Z<Q<s%
zO_DL!UbW4Y<%%m*&uwl9?9|*fFcMShos44^WC(22=C7Lj2V)Ju1WsUF@?o(wCm#82
zAP9=^LVe5tfe9&~u+)DZJdXo_$PboW`-Wl`&*Q;hz%L4Qp_a9gKnM-70kfL!SrhIK
zx+1}nMiSi~P46KMhq`1#smTZg13gHm)!9>4X+pA=30eh7+Aqq2MUlp2MaC~Rx5ZHJ
zom35rTf;LJBVY{glC4&m2r54zio7WDa#4^`WR82k`~6N8HHTmJbE;F*0CFER>Xt0c
zg1YezO-H87@iM#^+uVz?<gI6PE<{-Eq#5y>K$4{t$ef%KX>?qwbZ=9@Gd>OFA(AT_
z6sUu&ud~hF{7hi2OSK3Mp`J(w+OQG3T~1Au{B$;Fq?^vK3!0?6bt$V$qEv$4=)hng
zSayiAp6(tZQEpARkrzEQf62xqikj0KG$agbj(Iz+Z1Z-VedM)Zt;J%|1z&UT^DSG$
zts7lr)asvH6;Q1<QQ$>~+g{sRqsby;imaf_b4Nq5H_555oDka{94)8AgiS}y-sP`V
zTMe(@>y8FPsM_o`v{l&_^RHH|hE}837`md?)%etEcbl&9icO3`?r3nCHC|ho|9rcB
z-3nB3^vD4GY>#~LkQZ0X)2&|5O7S*7LmhndGt9+S&B_fG@0SAkPV+(Q6S!hVLM=n{
z^qiJ-d;X2+g&$GH2|UGy*&_D|-^>s53qn*pBwi5zmbzqK?o;}e*=n^qZ=12}_Kf|i
zqu23^GweL3Zg5#$UsIma_D1e>sER|w{H7zuqk(?&j}EU#jF0S^p2|pxeTnwe=%}<i
wk=dI_WXy2qYgS7<lSxcw-bhWFbDdkP)tT|><m*%I(`ob9&Q-ZTJDZe$041hYjQ{`u

delta 1041
zcmZ8gZ)h839Dd$=FL!C1CTW^pr`wuquTE?i*QQDPVN#nF*%*G%tqzNr_10cfF==o4
zQ!^N}f(+@0w(}<F2f;xRK@iy?Qzs%rkjXYs1fhcDOGk#FNjJwpYW!WUqImB;@AE#t
z=Y4<gy+7Xj@%%fbb!}-GV9x<KHJ#PXXTH$tq(21s%=BVGmFj=p2L{N7I%}r0D;L)%
zNvlAMnbz|r#e=}1hs54==G<)Q?c%S1#|J#NIA`cHp>MD51Nz<|e|U}p^7s5t(qEG9
zoy!(Vg}tZhv_W5)0?V0&Y5lE_E=&Ra1RTlgC6g6fKOnt9TAkOk#?AM-RMOu7!Yy+l
zU$~=xq61G}qK}?2bB4K<?5E_1*DpSNiCwlPSbDMyMvH+>@W$vMaWhRXL&V1v-$N(h
z@K)L@u}ZwUR=rUzSGQ`R+GuTSJ6@-1RM2o%|L<6rh0ab!>qi@H4F74?aUp512|m{3
z9Nl>$)&{?~6r*$mbP&f~Kmn?&F3?H5=7JKVdcy@CAuhYXqr_V-uotL>T!0E)8+C#G
z#5BhNx`1uk%YlH1J>c0C>^n^@%zoWF$Cf_hlRN|sLr9K|wlc5?6S;6ypb=-_Sr6kP
zy{|&1>d9;hq9lnE5Jl-lNTT#?BB2c_TCe8y?CWQV_yJj??s2V0k~<n*SQ#1W2rGwK
zY<MIw6dP`D3rli$&w)f+e0Zcgc0v)p3kPh)e>4zgR|ty#iYsitvYHy-xjUXpjSHRQ
zDV99uSD4+HVuu3_;a3#D9cEAORF0(BR8rXEko{Zp>2~{tNVv)V^oievrMulLKc5af
z^#@vbh01}S-u?XQKV09bpAkzuP1;M<aUZ%be6oHP5Ese6Czf_^(5_9SI+=JI;r)Lh
z9-^@mr$3|t$E(27q6e*$(VpkY5*K%K9LH@IVi~qAZ15oeL7Wg*#QUCk>1*kM+$T?Y
z<KFYWW#3n=m;Al{>j5=zA@CshX7HD`W1(Q^8s%`Vv})guws59en*(E3*I;D7oHGiq
z8Ad@i&Kc2#*;${NDdwa3vqe2;%vckHFI(3JPjob&d1ZcKx|q>(`KDst$VHu5b}ZK8
F`x`(Z4-fzV

diff --git a/static/font/font/fontello.woff b/static/font/font/fontello.woff
index ec5cf4aa8b365ad6d24e0d3ac4e564cf4c873dd4..c1aa83bb3aeb19fbeb0626a27133e218ad0d0444 100644
GIT binary patch
delta 7787
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

delta 7378
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
AJpcdz

diff --git a/static/font/font/fontello.woff2 b/static/font/font/fontello.woff2
index 8eed845a60243dfe59560f1ee38e4350d2026dbe..cbd9b09f706d5320154cd4fb11140fac7e7c35ed 100644
GIT binary patch
literal 8372
zcmV;lAWPqOPew8T0RR9103fsg4*&oF06tUz03cid0RR9100000000000000000000
z0000SR0dW6hX@ED36^jX2nx<@!W#=l00A}vBm;p61Rw>4O$UN{41oq4vo^C45o{a)
z1aWJT{T~jv0YjvQ*gs$dvm@P#V@CJ2hwjv@sM=;R!BU;@znRHo!Z@w++M56U1B0hO
z@g{xPZw*+m!3VdA1G|)dI*pKI7XH7lnRV`a|NqPs6tGJsfbNz-%@q!5u)tha$ql%g
zm=(~jS3`s=q7_gM!cPCEGy8uuLX*gnWt3S)TpF(z00ICG6m_b5R~5nTxT<b4RV6$=
zK(YZaa}AMf#+Iv&oos!8K7q>*L$cZ}*_M>Cmuryh=hw%t^Pro35(0^fFw{6eWvSf?
z#Kofuh@(S@F;yHBC-zRnvFP^BPC6FSwY2TOqPILd*79bTce`uYZ{;6s_x>(kIwKRA
ztY~=jc=_=E%+_l~`QtQ~yok+2>`Rojs6Z6fiaJG2R~;q}kF{SW2UzAz_8`x=Osj$2
z?r%>B(FBB0_`jtl{WGU|9{UzZY1Mvt*O&v?HFz|L&(3PsGqciZc5S_<)isqXvV3K2
zUvWuuNmFV8s8t?&?HB7xQ%dWo!qNdr2rCW102oLr3#4H<+j1^w?SPslLE7hj_S^f~
zTYDFM1L0tT92?m_AH1l?gMbRVEh2Z_vvUFix94WBU>YT(V#NFQx_$HUUC7fif#9Qj
zc_Qr5->Q{FuxIUaz^k4=di{bu85q&Y?$-m?Rv*CW(m$2n>05c8U*`?gSw4+WC$(Li
zto}^w`5lguLpdsmz-RK))T75(j@7Qq;erQ-$NR_Bf0#FXWq%Ax$V*x=uB=B)TaFiV
zm$QyK`t<+fkyB8iN{u=L3^GKcGnm3Gwg^X5Ok6@ziYpD2@SAHKrq`j?3{moyB2rR}
zloTf=C6JO5Nl8hhq-3O|<fNn&q@+|xNvV>OQX?g$PD;uEDJg@bqzsXgGE7R!2q`I}
zq@;|Ik}__Tdnpq}xt}s={Cx#w%J{p3vdsAV1<JJX_Xm`Q@%LfMa^oL7$_nEjQz<Kr
zf0!w&jDHMMRvZ6RUMFh=sj0X$uJ;|lE;tIP>H~KgCrNtx4}ynJ5#ByUx|euAd98Z-
z4e|0{5((}vZ0@`VE`h0y2SAwS(1GCAbq7I9@!u<G`80T{Oec%Uo6pgkclF|qgXidB
zKTZr^Hx7T28bh%x@t*b`OW~$!g5bZ9)~a910gB8>xn!lh;y(0sPNCqya5)38ShaOK
zI5ZK|%Tn;!GFPyGpc-`EC$M%<%$wJ;@m&xxSu=k$Q_L6P)}G6yYJYIwH={L&d1!eZ
z^D9^0q-ZG-u(wz#Cz0LgbR9g1d2s-u77&C81ruN^1=6jx{H=5F>pCx@7KVMf_($bl
zEkWg3P5GU99L^*$h;x`u!UeBrkVh&$rBo1L7*~LLzHO@6rX@-~#E{guONL>?%v!fH
zF8_k~cs+6-5R4gtpG!0G;G1!)(L3|$f>#3qG}2q;K|!%2NUbI9=M!FYt6E3|_RtXu
zu#BD%LRH5A{iAZfX4{w6%&K=pFbX!2%F}nT(Z6vzl^@^O522y8ujA9V=brQREMtD1
z2BGPD5t@g9Ef9(%O_g|P{tFZs0G^oOyi-ka8v0yOzo^b&?d^^8o^muG=4f4o6aJhL
z0FxP|pT^UByKMl5jll#K2UNVQZ?Msj)pwDQ1x@hH?NJP@LHXgg-|F5b1YtSUJOBEq
z!n<%MQ-?_d<6=kHVgw5lurUV_Ou@lCM6m!dEJ7Shkic>-$%eS7qZKHHlE~!&q%naE
z<{*nH<S-9;EI<K^P{a~=ST2{)ov8%nJ{h%YRKFVGZAup7BT83jMATxv-z`<7nN(e}
zvTJ&3{M4NDsm;{zAC4zf*WmFL$=o_3W1lWJ&`l9#GkrNdmVDh{)aZ~(VEuyZ>$7st
zc3VTk7dl$#j%Fg}fT{fib+qY^-s$MDX^=H@2X<*htkddE9>|W_%H#TFW_`6N&YiwH
z7z;y3F?{GkM-RY)dTZrRjGPx&wQka#I*cvU?^0j91hoKQo4PZT2eOy=liY2)&Q;5H
zG=<fzM@rQ!P}{V*OqxqX<rOBW#U~({mj;(*Y0ZmQoKksp85Mp|#UyC4Y1ws#lv9W=
zRs)xt6)E$ju`1&p@LtAI8S>E58P{7tJtx<%Gc_ZUg8>DL=`3HmpR+r=)U06<$pSB?
zz-!_IrA8#H^){L_!Ab0O$Gn4_xQ5`>?FoK6&*N=1*-K+iT6<8Gja@aq<w!eMDx2L=
z<#YN`&#|i>vE1}cMB&u8ikcUxruju))mQ+IO~2_y=tYU)CFn<W5g#d+SBGIQX!ca{
zGHh~@!bg^{EOyJ<Zdrv1O-f$WVI2M@W)qLMo$HkA-?3fihdS$%cxqV@PS^1?>n&#a
zqsWU^QsJ5D53mHq4o6$-rCF`4(Eu+VZB<-{?gAV42G+#XYg)4nBY%^z$Rg&^Yl{J3
zV$e25*l9sQyI5f_0kDkrF~UI$3Od9JM+tyMbc_*BT2Rm_Rya!lFm#R)E?Q8~C04jf
z08G&}M!3;}f^K4kTM2+AbQ>ewX+c4Ev2M5r0~M?LA3Wx&Sr5=WJoLfx(E>cm41w@C
zHiRd!p?VrvH}I@!1kYn5co7@H%h(8BHI3nQYz%K=V|W`IZ}*O$@_>9PiU=2xHo)Md
z4}3Ny5j8;6A7hZLWi5Ia(>x6MU!d|QviTl>+F=3_>NdlO$Xp$-sG^;8a6&NW)h0vy
z1~wGM)TFDd&g+%o^}^`dj6A>D3Ag2JD1&fgfq~8WRK5T8xLzF^(Y=zJ@gk0Y-=nEW
zp_-G2PH1$vQYqH2dwl{hoKb>?562qrN5@)80;xTN8NTPWaz~+BsYfpd<mrIDL~Q`z
z_0g#K9wGU0VAEaQU4W3L7-|Y+=Y@$Cc-6e_+2v8?T68N=u%`~-V~<27**`c`IU0o|
z6KgY3um`j(P!x_d3m4kO@locSNOEZ^FD&wGJV-|Jl`a$KxWU4Cw6uVyNZN>b?%&Kb
z1w|QRYIb+n$_J+G>$G~NMN*Ub8tYxmW%d*U*6-XR=U|kkQ4+3vA5SlS&lK$;45h}P
zMks2nzCyTkzE^)uA5mR@!|MovZvN9?{hm@2qP5q6Wc4UdgmbY>k9ZW$6#7+{>lZ=6
zQ5{_#<@zZIg#lsPm@0HKL5F<%)NdUCfuW%8j!FY-O9)*`+aV-qADa%eNaTD_87+p6
z$LkPQk8rU+m=ImWSSbue0vdS=$$LZ}0$t$Kpa#}Cn?b};hO<i40Duoi^SY0^E2Kr|
zsVx1x_l=g^fd?W?k|>u3*W<x)CVS6KsHIDD_0Dleo$=alpP1`P*1Xu3b#V}pg!fN}
z`<i`n2~XqBAH6{o<c{<b3O6zB_m-A6a}zX0#Vj}9KSP^&*W82X3;?fTC^|e(6(Ly<
z?*tN`P(<jDjTCmHq=BODwN4aGpY{oE-rZ<J5kWy3(vY8yswTKrRP_2$6Z-^3%^uCp
zluQn%s%9s%ExxTh8#gz<-@%#$Ju`<m6c2`S;jzxS@^H_jkze^I5$@9^@8@sXJqVc-
z35XX!{b?F>#BCh|c>U&ikKs5DSPYFk-qRiM#JS;z8d%4u9-=m&aSkpBcq-$Jr}HwS
zV|MJkMJX(;1-5-`J2BSxhe?zH40EG^F?@6j?kiX^A!L*i*ir+nq3E<{+NuyCT4}v$
zj14;iri5U$X``?iV@AnVY%MI+r<IC_S*elcROb4MFd`~M0T{L^QGwRdYAiI{H8vv9
zW8gWM8lMwd9wmLTo%rOXz%k}{9PKh%YvyY#M{9C|bpo{!{S+ap=&SK$sfpsrt5X0}
z(Y_sELI99Vnhy`@cV?W`W?o^mmVT;QBo$v2kshHfD2PTDlm}45jV01{Td2AZQy#Qj
zE=FoBgc(HJ?zSG8f6Hg0;AN3ew-fDC<7;16E;P+%D6(c4puiaGb7Z89E5XH#)H7}O
z8LzEpJg6Ctc3c9R`z(!e6y5j7m^w|ZvA4GhW0Vqx<3o_M%DV~gS@Cs|6kBGa2~+wA
zbD;>+G@Jwno~yEX*(=G0TwQ(-xPee8&!Y*dOW__)1A#RJ$Un&ar_WC++#1zO+@Tky
z=1X_w?Yzji-pn?20MbaXwb6L{HdQ2nZZFZ$wBbw=CN08qAPvP?+_BTPl3uwG4^{k~
zaS-RLh_B2IrKRyw7{hn$ob;FR`uRj_{WJ*^>1TxuE3u1d<_7`N!f|}Z<TRz<Xf5w?
zu$yLUj=HluDEo#%xeEZU8O0tbb(Cqi<nRt_ZDy&7sz)1njdl~~MhA2&BiprXG|));
z?R%P-%k&TlXy$3uQ^tAog?q7A)bA~K-w7pTVVKP~XtSrcu{u5us<-2@NTzourcpg&
zZl2q;N!=<_DB8wMFn4H}jJcBx;ZKn`h|aHta~T!~^N0O0DUBwMzOGovB}q%u&OtH9
zWy-Vq7z&Iviz+nH)=LA2#&pOt9>du<&a;dvD6E75yyX85c=F`Kn<UwOJ9N;1D)!LX
zAU?X)?5`;xW{5(lzy{TCxEJwS+t!}l(_p^MB2Cbz`}r-KRP=tGR2)<o_vfU087Pt$
zbCNN%htu9Q_31?Wdud>)^m`r2>(y$pSRm||LO&G*e)yeVm&ET?H|8_!v8a0kZ2U3g
z!8S;e!(IcIIrJLJi6l+q;JHIy;hvUoS^z^~0I)Vki9iu!*gwnek44_6rpD92|4y%7
zefV~^B==*PF11K5hvJ^sb%Or4apV7d+F9<+g`GuHe~kXlV2V+KL!M54`iP%~T#&Gd
z8_}WGHLc6M*u)ENDB0ht@9Os-^FM(9#%!Ms<I|(r5{EeZ>Qn#GZ^+I7#|Wl);J^r<
z5eGg2`0&9Q;;deNPD%pzx%blxr>FRPdmT&qc4Xm)h2Q$SJz->u|Hae4diy=WBkZGl
z!oKYo#Uow|+ah~*|1GM%U3L2(QSa`^zi)olXGh&dPl*8ceAy!oD2u73q+uzzlUn*E
z2~26Uo;qXu^PFw=Ddu0Trv`1W2W<9J6Nt~pXS|H9_SOZ?P0CtW;Ha+f8vEm^tW3Xz
zY2T}<(?!_<uV*lrQ1#bt_fOQF=85RSJ3W!b21#dg^o(uex6=zgZrC6X98U9O+}W+z
z4J<ODjO@8-L7VWn4+Z=kR4rBXQ*}pVdXvYwg~?S(W%-GdbtNTlc4S}RBCa}|N%AB>
zFlew~glB8to&8~h?mLSG)OE{UjfXzRqBKABX?5Q@9Co1ZPHQmDw%pZvq~z2neVlax
zFv*jGI3vTtrnL!X6-l*_6xc{p4Kx+p+<~+gS7MuYjknTl{S$-XIAWfmTDAe5Zb{^H
zpaTe2vCopB%Hq)a!~!K--)`OVPg^;=xSiF3xRNTdmZ8sQ%<@ioY%usB4Kq|78_?<P
zQ@9<-0E=DmeN9F}GG<QIs+4SE>8r+C%dujY-mHYUun@J@_vs1>bX}KEZy)MJJyE8B
z)m+ynQ!u+^RMgijK8Z6YuzM#@=@C%a_7OJCzKc=UN487Py^k2EO>nQ@ys0~+TXgq^
z^yKI5G9pxZ1wZ8Fi31LNwWvaunyP0UqYIurGZ+d22le{Fz#{SC85(LX@)%3`vVrL{
zTNN9oPakak&TXTIhPa`P#|p^*{?klnbe5HLGSU;D{nxB^K6^%zp=Ny2FD6i}nWfg4
z7(*)N2+!i~Gvx>b!fkfMiR?iJjdo-J*@HTb+&wZyl3hwOl7TXUz9UIv6Awm8Va+t#
z10Fw|5Ar(M2N+(*6c2(#Dn=FQge@UL90boNq^NQbBNA4!R&j%qnvdo+a++Ua><V%F
z2O;)g<qJ@l5K}zJ-aSuD`+$64xNLr4KWpGISi~+Y6*OIH#Z#F=W|va%)0Xe*boJ+(
zxAX{l^7DHIy%CYB6}=}{czAQS0AGG65*H$!Ax>qc%`7jZhhq_TWjKT<9IDUDGoCXd
z%?tZ^y%Y|41vd8z0{@?bdWgmVnddRiS?6KfcX#dHaROH?DXJw!u`a>5-Ft;j;fRW&
znkY&&az2ya-Izj23b<c_GqM)0s>0H}@KN^*Kd<y^Z2l^M%JAzH6-^;u{nfW$So@(~
zBS;y%uWi%%j~a3OH+cOPjTyPM6>HX9UbhA;ujS#tj1RiSYdB-Gp89*C|4YpibDBk<
z9|1}bt+X2$RO?BRSFs6!<Z$#FP(!QWMu-Q(VPSGP48stM!Q#{}(7+_FV1SMNfVMwM
z0{i(x&8#67-`pux$pJ_KiGWg9fLeP>8XkLF4A+s65X6(0@&IvH4#C&5)-meX3M8E$
zMlOmbLH%MyN_aSj83*4(_WU8|h{7SO0tFjIpbeG=^2BPclFMYcy<tf>#2NVVe+*Kq
z4cCee%1`WI5PVu;i}HvvPK?e_B;jzTP6p0#f_`Pm3aJ`~QNAY#gq<bD{>rjWxzr}-
z{RV?vkbln?Rd9m-=#Z))1|-rkR2w#f3VRfDpoSmb9JZ)5pJXLj>t4v?*MR&uUm6k*
ziK7{?i)rN`t9U$^?*}sZ@vO}psapc_Ar$2J&XIyrUWr!%i1TgHBHIQwDum-W5<LfG
zKoBGXqio{Na3%~+zQDN^#T5h5;#A*RwrCt@z-()Lycx7=%YKN1eYso~s3Amw4E=zD
z&xfM;fx0{37hGs%lYSAO%tV;rqW)D?FYA2`S)ey~nn8#%fG`b5#DRciXrP`!lVlc?
zCASl+05iqi0CHm?&<(=Dc+|fC(BS#-R@Nu`wd)-RziI<WU4$;2Tnv!v?CiGe?9H#o
zZeeP53`yD4YCk}nV5&i#NG(WILh-MO3%Dx-g038CV>Rkf^b_;D;!5-z1PeOFlWXU3
zIk`N(Ln{xu#hb?u=bJ+wn-<n3)~dBN$+O{kXj*hs7M}-~C^O~8%*nH&$_&fZu^YR1
zeQ%?8#H~w=e}o5hCaH9KlPoVn{t*Q9OvcpEWMS&Q7T%6`slV=HG&Db=VnJQvY_+EP
z_<S_=opC5sV#+oOD4{M6ppz}W)%*%!b!bM0MiWMdWitDu#{1o4LcGOKYywW^a%A}q
zM}aI?I>HTjrXaGJ5)*h*!t5tCH8;0S(j;oZI|7Q0<&c_0XeK<Y!T1X|Jz7Mq>F)Ih
z&`zWU7K=_)iaL?Sz8SvGnld5nLyr&O&X5qJ-1|#PEEYY77|UYQ8@oKbUIEP(Vubxd
zrZ=W|;2khA)L<Alt~aEot4GiSQy2~17^^;gg)*S*>*2bBBF$SxPOP+~zR5o4u5oPb
zMFUtGn|N63qzOk+fKO_QL$&-5L+sS~R|aK@q!=m97+f-Zp=)}~JCiPW8zj&Kw*OwJ
z`?mcJesm&XSaxHTJmq`tPsbteA&(p9f-_f}i!{P;70H+|G$BSxO?tJU{>)6<LSXt-
zgEcMk<CBw{vn0u?hL>4l(sK-MXkK_?=3HS(=g#4xu81|Wi&x9`Dj4Wb0U$S)FFvZg
zLR6|gmj0C;UA79K0D@Dq<ryrUI`7Ydlr4-^iMnd83uW>lS!f*J6gu}8noBcd?G82(
zwnQN83F$FkSYQir*jJby2&avku^<11wF1)q%IPnG>l|Peo4}-On!UbG;@MxZq6VXm
z6W-%QrU~Vk;`ug=@F|aq>+55o*07@<b@4pruUN1mYv$X8bRbPebA?-y@vz%xnAo<p
z&&YM&pi+tK7kVtvWsPqx;tKo*8~YjUYME=oSVq_G0~mE(gDIX1^CuN9`9tNiwQEIJ
z!Yd)g52Xh7f8akK)rkZ4Gj`O8ZbzL>$lJmH)MYl=?ci6fbH4$b+nN0fTTiB)Mh2Od
zSmpE?WWd<PU92;K6R}*x89H#)S>WMyCkb809i4gcf9lAYx{z2ejo&@e33~OoDUo^D
zgS*Eo{f%Ad6gDSGE&)le{#&~ZEnnN7_5=907Io4&Yw$~WqX!(C*=F^xd2a9BoWrI4
z(R<-fZtBYq-n{?OO{ZfSM->C6rpvIN1lPvmrb*+}Ha6{HmI}<UCPgZGxl)#TWS;d1
zSeS`&33Fx%!P;1`)`|ISC!1;KM-g3#E4Hzy9;yV7HDriFD@>b<lj=*z#T_$PFY+u!
zSB)Opkh3jatzoPo4>*uB8zeK$1W9#)>cGhISINkRV;ukeYM*ptgz#`O<Dqjz_Q2Uv
zQBq0@O=5^W3}Nb`gwi6(Nxq2t5&^;tA<%|EtF>*^ot&8v<McMRl);eHbSX=jQnyeF
zSqh7}j7*lz7WAXysm?MhosXoguxDU!|CS$K?o24*SjEKtJEl^Xi{mA6@gA@#E?3;m
zUq!QPFStHF+}x;?Gp?bFabg==GSQ?a$)cs$CAvjlBsd=EA}q;fKU94N_fCL^C$dhy
zoG&V9v|0fnuoCLg*PXWB5541npqWU5woO4xY<-~B9`!eRlrV{WP-viDD}u57Ai=^=
z@o`Y>k}|uy<g*A&%o1W$h9BD!?z%Os)+>dqW2-4GWf;2D+|L=E-%dkC{<4=8htU|G
zK1|#m*bSTr%}d|Y4_vSTgg3wC#dtnDip7vZEW+$?z~VqM^Jue!@`{i%Tg^-wYs1(c
z7`qT-i-k6fjp0n;hu>K1k`=zbchAl(uJvnIEc;^7oQ{w0Up;^H;MVoo$=-G^$b!!I
zI@XYOnzAyN6Ll}wNt~b-gR>`XYVji{c-N$<dhmli8_mrz;=1S3_n@)ODx#uLyb2~3
za1>qh4DvnZdF?!AsZC1tbfKZF^H$lflr6?6w^XGajAZErd?L8ZWDVGSIl=SL5kgAO
zR9~>v>V!z<U$s{EEG=v3GFGBkaxz0EtlP6hkj4n;k4ZtTbw<8#s6w3Hw*6f;wkPxO
zx6k^NH+s&?Bpi4xVK_hM2XyK1AZIzL!{t!OFug$=wO-4#RBd`fSG6GLm;8bniA)dc
zUTuaWC+Xk)q#L@V<2tH1?L$K3B$|!w?~1WKnKsN!A`sE%fA3Cg9<u+UJV!*tJq;yv
zb}k2@4(kE&%q{DZB_CQBNx8Q!lFRS^BGOVJ+?go^-j2Z>Z>g{j8&i3-=vT2U!p23i
z6pP2=LeYrv9uY4Si5DA<zI!^C69*9VQ{B~ozEid?^G&|a$9>F)eZVt3Nk#%{h#D0l
zV=qgYC>xH3tcl5b%XekN$}H1<jbY+ejNnvr2Aw_uBziRO8mUGQLE#0&Sc?}LECal4
zJlAmRQ6X?$>xVX5M61K($-~8BAv^N-#)9i71edkWcDdlD3!hK{(A?zROdia`B4)Ic
zpmtu%u8#FMt7~V0Drn(zy?{el-es~9AeC0{+7>t7xny?9Lz;KD8s0(az|{Q}Hnk}?
z4V_BRU2FHC?rQj4hLO!{$s0m=A;(#InC?>7IxHa8T&4l3R)ta?h~c5quuO+`l3;5T
zL%{d;azHIw*z(H4!d3@-EqMVc)zXCqtAe1^gN@u4r|2-{Xd~b2=R4=6hAx{79b$Wd
zFMOD0yMy09m$wcKOsB)gW!qTS!w_>OijIIAHR1J5ZnMTz5qTSXz1!(qRsKpvUCgB%
ziBTEbAL<rz;|`4z?fv_66C0;Flc2v1Gzzs#09L2^dfhKHShBox-^t^jmNG;QbeM)5
z`*WE@Ojp5fGAX=VC}0o-g+x$TVd@zuiK?!%jRjlQWG{d_eIy3DmJCIfU!E9|aeb;^
zfPB7mjb`{{Lf!~7kkw}_Vj60&NUUpJ)|Sfl7UmiC#0ZYWo<&TdNtS0la?g87j(=6U
zUa)Y7?)g#iw!5m~+)|-uZ0@(+DUmE+qi8F}1GPZ(W>C~UC`Q$UnpcA|%VdliikZbl
zB3WdyP?qKGicIEqK~QI2UBD^_XFB&%A(53|8P;YsrP<;cFT4DW&41n(JD1GWG=M{2
zyH%@r#at$pj5(UAnT8Ik(4l%9-^OOuJgH=>R|VZ|?<fhmH&Lb@StaWYh)TUey-T%j
z^{RDis!*?1>a$4}<+=GRc?kIoc^=w@LLOS;-b-5>t1FYGey7zadAUqHW`}iEDPka3
zJ{ZTg0Rn>WeC3$ED0KWksF#-jKOI!QJKbadO}{ie?bm@E1F&U-5D=bBz$=PIW@>E}
zo)7z`H*vTcB{hd#q=U-bd;6cT-yaK)u{U6NnYEV|v0z^RjbNwvOE9pD<Bq-WKrI*-
z%(jncTigGk1Xz6D`(t^}tlI)3{udn%*za>h&Ve~b#tG>hxl0BhtvQh@Gco~r@tg|V
zJl=biQNME(3g8xR_veVA2Im+9S|uIG4jF))m=l@kUYUR_%&Bl$k6o|I#=iYuY{^ec
z?mv6e;fQ5BBrEnKz_?Qych+%y`<HY(=gzZjp}V?OZyt{Lfh&FAe|+4Y%^um=rq`&>
z?_ptEH;!oP8H025xWh9%%1y3wgU4CTGi3``TT{!B>mICH?KPnHO_rGBHUxKhqS(Db
zl#hXAWAKPxDtMf$R^C2?o$ia;U6OoA2G@B)UgsQ-Qbyljaha>tyEjR9ezlgmCIB_v
zC6GHu$XpRSc+ZnY>=mYUuL<ZrD$sSUwwA6~?G0JpLUMs~cOoJm?}DQm{kXc;Wn{}x
z;k#mOCRb2YQl?ymDypicx&}0;Aq{IpqZ-q=CN!xjEz`6bTCNpZsa0C7HCn562>&&f
zl;CWo=%0|oAKaQtm=K=aimHxy^_hpY*N+~Fk6xX9de~ICh2CSqYAgR?COcNCnx$1O
z;itK#MJF$p|D9{B$!gJ*?1W{#t`MKNlPGF!r>LEp=C2!e*^!@r^uzlnvRzj{{;@kx
zUv+%HD><5Nu08xb^Pg91cVEn?wV0CZ-uPZR;G&ik+vP0`RiJFEA&Y8R$CcjKKD^n}
z%DiL=z9jtjvXz;tIiBqi;L@kyTMxw_2)?Fs2*1TN;?56<XFmdB>&wQEDv<Jcb`Thx
z&VGg*M-&z^15Quuz+E5C>17Y*d}m!37R<O1`a_zB!ZUwA>mpxv!mfY$A=S2iN@Jbh
K;pHEOfV%+u3jlop

literal 8020
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
W^{O=oUnmQUMIYeMXb+49djOt)yc@Cr


From e7fe2dc9f9e52771c2ffe8d0ee1c4e8b2e38ab2f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 14 Nov 2018 19:39:17 +0300
Subject: [PATCH 11/96] collateral fixes, removed alpha control for alerts,
 added contrast text generation for alerts, updated getTextColor to also have
 fallback to black/white if resulting contrast isn't passable (only when
 inverting lightness!), updated UI to use tabs.

---
 src/App.js                                    |   7 +-
 src/App.scss                                  |   9 +-
 .../contrast_ratio/contrast_ratio.vue         |   4 +-
 .../delete_button/delete_button.vue           |   2 +-
 .../notifications/notifications.scss          |  10 +-
 .../style_switcher/style_switcher.js          |  40 +--
 .../style_switcher/style_switcher.vue         | 257 +++++++++---------
 src/components/timeline/timeline.vue          |   5 -
 src/services/color_convert/color_convert.js   |  23 +-
 src/services/style_setter/style_setter.js     |  28 +-
 .../user_highlighter/user_highlighter.js      |   2 +-
 11 files changed, 200 insertions(+), 187 deletions(-)

diff --git a/src/App.js b/src/App.js
index 05e3eda3..b06e8b5d 100644
--- a/src/App.js
+++ b/src/App.js
@@ -59,7 +59,12 @@ export default {
       })
     },
     logo () { return this.$store.state.instance.logo },
-    style () { return { 'background-image': `url(${this.background})` } },
+    style () {
+      return {
+        '--body-background-image': `url(${this.background})`,
+        'background-image': `url(${this.background})`
+      }
+    },
     sitename () { return this.$store.state.instance.name },
     chat () { return this.$store.state.chat.channel.state === 'joined' },
     suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
diff --git a/src/App.scss b/src/App.scss
index 0a2ff5cc..8fb3c488 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -473,14 +473,19 @@ nav {
   padding: 0.25em;
   border-radius: $fallback--tooltipRadius;
   border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
-  color: $fallback--faint;
-  color: var(--faint, $fallback--faint);
   min-height: 28px;
   line-height: 28px;
 
   &.error {
     background-color: $fallback--alertError;
     background-color: var(--alertError, $fallback--alertError);
+    color: $fallback--text;
+    color: var(--alertErrorText, $fallback--text);
+
+    .panel-heading & {
+      color: $fallback--text;
+      color: var(--alertErrorPanelText, $fallback--text);
+    }
   }
 }
 
diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
index a428e75f..cb65c371 100644
--- a/src/components/contrast_ratio/contrast_ratio.vue
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -1,5 +1,5 @@
 <template>
-<span class="contrast-ratio">
+<span  v-if="contrast" class="contrast-ratio">
   <span :title="`Contrast is ${contrast.text}`" class="rating">
     <span v-if="contrast.aaa">
       <i class="icon-thumbs-up-alt"/>
@@ -11,7 +11,7 @@
       <i class="icon-attention"/>
     </span>
   </span>
-  <span class="rating" v-if="large" :title="`Contrast is ${contrast.text} (18pt+)`">
+  <span class="rating" v-if="contrast && large" :title="`Contrast is ${contrast.text} (18pt+)`">
     <span v-if="contrast.aaa">
       <i class="icon-thumbs-up-alt"/>
     </span>
diff --git a/src/components/delete_button/delete_button.vue b/src/components/delete_button/delete_button.vue
index d13547e2..b458b0dc 100644
--- a/src/components/delete_button/delete_button.vue
+++ b/src/components/delete_button/delete_button.vue
@@ -14,8 +14,8 @@
 .icon-cancel,.delete-status {
   cursor: pointer;
   &:hover {
-    color: var(--cRed, $fallback--cRed);
     color: $fallback--cRed;
+    color: var(--cRed, $fallback--cRed);
   }
 }
 </style>
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 98fdd3f5..fcc0c3d4 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -8,13 +8,13 @@
     display: inline-block;
     background-color: $fallback--cRed;
     background-color: var(--badgeNotification, $fallback--cRed);
-    text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.5);
     border-radius: 99px;
     min-width: 22px;
     max-width: 22px;
     min-height: 22px;
     max-height: 22px;
     color: white;
+    color: var(--badgeNotificationText, white);
     font-size: 15px;
     line-height: 22px;
     text-align: center;
@@ -27,8 +27,8 @@
   }
 
   .unseen {
-    box-shadow: inset 4px 0 0 var(--badgeNotification, $fallback--cRed);
-    padding-left: 0;
+
+    background-image: linear-gradient(135deg, var(--badgeNotification, $fallback--cRed) 4px, transparent 10px)
   }
 }
 
@@ -42,8 +42,8 @@
   .broken-favorite {
     border-radius: $fallback--tooltipRadius;
     border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
-    color: $fallback--faint;
-    color: var(--faint, $fallback--faint);
+    color: $fallback--text;
+    color: var(--alertErrorText, $fallback--text);
     background-color: $fallback--alertError;
     background-color: var(--alertError, $fallback--alertError);
     padding: 2px .5em
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 8953dc49..9e236488 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,8 +1,9 @@
-import { rgb2hex, hex2rgb, getContrastRatio, worstCase } from '../../services/color_convert/color_convert.js'
+import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
 import ColorInput from '../color_input/color_input.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
 import StyleSetter from '../../services/style_setter/style_setter.js'
+import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
 
 export default {
   data () {
@@ -38,7 +39,6 @@ export default {
       topBarTextColorLocal: undefined,
       topBarLinkColorLocal: undefined,
 
-      alertOpacityLocal: undefined,
       alertErrorColorLocal: undefined,
 
       badgeOpacityLocal: undefined,
@@ -123,8 +123,6 @@ export default {
           btn: this.btnOpacityLocal,
           input: this.inputOpacityLocal,
           panel: this.panelOpacityLocal,
-          alert: this.alertOpacityLocal,
-          badge: this.badgeOpacityLocal,
           topBar: this.topBarOpacityLocal,
           border: this.borderOpacityLocal,
           faint: this.faintOpacityLocal
@@ -160,6 +158,7 @@ export default {
       if (!this.previewTheme.colors) return {}
       const colors = this.previewTheme.colors
       const opacity = this.previewTheme.opacity
+      if (!colors.bg) return {}
       const hints = (ratio) => ({
         text: ratio.toPrecision(3) + ':1',
         // AA level, AAA level
@@ -197,26 +196,28 @@ export default {
         badgeNotification: hex2rgb(colors.badgeNotification)
       }
 
+      /* This is a bit confusing because "bottom layer" used is text color
+       * This is done to get worst case scenario when background below transparent
+       * layer matches text color, making it harder to read the lower alpha is.
+       */
       const ratios = {
-        bgText: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.text), fgs.text),
-        bgLink: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.link), fgs.link),
-        bgRed: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.red), fgs.red),
-        bgGreen: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.green), fgs.green),
-        bgBlue: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.blue), fgs.blue),
-        bgOrange: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.orange), fgs.orange),
+        bgText: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.text), fgs.text),
+        bgLink: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.link), fgs.link),
+        bgRed: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.red), fgs.red),
+        bgGreen: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.green), fgs.green),
+        bgBlue: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.blue), fgs.blue),
+        bgOrange: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.orange), fgs.orange),
 
-        tintText: getContrastRatio(worstCase(bgs.bg, 0.5, fgs.panelText), fgs.text),
+        tintText: getContrastRatio(alphaBlend(bgs.bg, 0.5, fgs.panelText), fgs.text),
 
-        panelText: getContrastRatio(worstCase(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
+        panelText: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
 
-        btnText: getContrastRatio(worstCase(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
+        btnText: getContrastRatio(alphaBlend(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
 
-        inputText: getContrastRatio(worstCase(bgs.input, opacity.input, fgs.inputText), fgs.inputText),
+        inputText: getContrastRatio(alphaBlend(bgs.input, opacity.input, fgs.inputText), fgs.inputText),
 
-        badgeNotification: getContrastRatio(worstCase(bgs.badgeNotification, opacity.badge, fgs.text), fgs.text),
-
-        topBarText: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarText), fgs.topBarText),
-        topBarLink: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarLink), fgs.topBarLink)
+        topBarText: getContrastRatio(alphaBlend(bgs.topBar, opacity.topBar, fgs.topBarText), fgs.topBarText),
+        topBarLink: getContrastRatio(alphaBlend(bgs.topBar, opacity.topBar, fgs.topBarLink), fgs.topBarLink)
       }
 
       return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
@@ -229,7 +230,8 @@ export default {
   components: {
     ColorInput,
     OpacityInput,
-    ContrastRatio
+    ContrastRatio,
+    TabSwitcher
   },
   methods: {
     exportCurrentTheme () {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index f4b4e88f..5bc38318 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -24,8 +24,8 @@
     </div>
   </div>
 
-  <div class="preview-container" :style="previewRules">
-    <div class="panel dummy">
+  <div class="preview-container">
+    <div class="panel dummy" :style="previewRules">
       <div class="panel-heading">Preview</div>
       <div class="panel-body theme-preview-content">
         <div class="avatar">
@@ -45,132 +45,132 @@
     </div>
   </div>
 
-  <div class="color-container">
     <p>{{$t('settings.theme_help')}}</p>
-    <h3>Basic colors!!</h3>
-    <div>
-      <div class="color-item">
-        <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
-        <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.bgText"/>
-        <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
-        <ContrastRatio :contrast="previewContrast.bgLink"/>
+    <tab-switcher>
+      <div label="Basic" class="color-container">
+        <div class="color-item">
+          <h4>Main colors</h4>
+          <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
+          <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.bgText"/>
+          <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
+          <ContrastRatio :contrast="previewContrast.bgLink"/>
+        </div>
+        <div class="color-item">
+          <h4>Panel header, top bar, buttons, text fields</h4>
+          <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
+          <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
+          <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
+          <p>See "Advanced" tab for more detailed control</p>
+        </div>
+        <div class="color-item">
+          <h4>Icons, alerts, etc.</h4>
+          <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
+          <ContrastRatio :contrast="previewContrast.bgRed"/>
+          <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
+          <ContrastRatio :contrast="previewContrast.bgBlue"/>
+        </div>
+        <div class="color-item">
+          <h4>.</h4>
+          <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
+          <ContrastRatio :contrast="previewContrast.bgGreen"/>
+          <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
+          <ContrastRatio :contrast="previewContrast.bgOrange"/>
+        </div>
       </div>
-      <div class="color-item">
-        <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
-        <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
-        <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
-      </div>
-      <div class="color-item">
-        <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
-        <ContrastRatio :contrast="previewContrast.bgRed"/>
-        <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
-        <ContrastRatio :contrast="previewContrast.bgBlue"/>
-      </div>
-      <div class="color-item">
-        <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
-        <ContrastRatio :contrast="previewContrast.bgGreen"/>
-        <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
-        <ContrastRatio :contrast="previewContrast.bgOrange"/>
-      </div>
-    </div>
 
-    <h3>More customs!</h3>
-    <div>
-      <div class="color-item">
-        <h4>Alerts</h4>
-        <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.error')" :fallback="previewTheme.colors.alertError"/>
-        <OpacityInput name="alertOpacity" v-model="alertOpacityLocal" :fallback="previewTheme.opacity.alert || 1"/>
+      <div label="Advanced" class="color-container">
+        <div class="color-item">
+          <h4>Alerts</h4>
+          <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.error')" :fallback="previewTheme.colors.alertError"/>
+          <ContrastRatio :contrast="previewContrast.alertError"/>
+        </div>
+        <div class="color-item">
+          <h4>Badges</h4>
+          <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.notification')" :fallback="previewTheme.colors.badgeNotification"/>
+        </div>
+        <div class="color-item">
+          <h4>Panel header</h4>
+          <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
+          <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
+          <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
+        </div>
+        <div class="color-item">
+          <h4>Top bar</h4>
+          <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.topBarText"/>
+          <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
+          <ContrastRatio :contrast="previewContrast.topBarLink"/>
+        </div>
+        <div class="color-item">
+          <h4>Text fields</h4>
+          <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
+          <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.inputText"/>
+        </div>
+        <div class="color-item">
+          <h4>Buttons</h4>
+          <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
+          <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.btnText"/>
+        </div>
+        <div class="color-item">
+          <h4>Borders</h4>
+          <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
+          <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
+        </div>
+        <div class="color-item">
+          <h4>Faint text</h4>
+          <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
+          <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
+          <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.panel')"/>
+          <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
+        </div>
       </div>
-      <div class="color-item">
-        <h4>Alerts</h4>
-        <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.notification')" :fallback="previewTheme.colors.badgeNotification"/>
-        <ContrastRatio :contrast="previewContrast.badgeNotification"/>
-        <OpacityInput name="badgeOpacity" v-model="badgeOpacityLocal" :fallback="previewTheme.opacity.badge || 1"/>
+      <div label="Roundness" class="radius-container">
+        <p>{{$t('settings.radii_help')}}</p>
+        <div class="radius-item">
+          <label for="btnradius" class="theme-radius-lb">{{$t('settings.btnRadius')}}</label>
+          <input id="btnradius" class="theme-radius-rn" type="range" v-model="btnRadiusLocal" max="16">
+          <input id="btnradius-t" class="theme-radius-in" type="text" v-model="btnRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="inputradius" class="theme-radius-lb">{{$t('settings.inputRadius')}}</label>
+          <input id="inputradius" class="theme-radius-rn" type="range" v-model="inputRadiusLocal" max="16">
+          <input id="inputradius-t" class="theme-radius-in" type="text" v-model="inputRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="panelradius" class="theme-radius-lb">{{$t('settings.panelRadius')}}</label>
+          <input id="panelradius" class="theme-radius-rn" type="range" v-model="panelRadiusLocal" max="50">
+          <input id="panelradius-t" class="theme-radius-in" type="text" v-model="panelRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="avatarradius" class="theme-radius-lb">{{$t('settings.avatarRadius')}}</label>
+          <input id="avatarradius" class="theme-radius-rn" type="range" v-model="avatarRadiusLocal" max="28">
+          <input id="avatarradius-t" class="theme-radius-in" type="green" v-model="avatarRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="avataraltradius" class="theme-radius-lb">{{$t('settings.avatarAltRadius')}}</label>
+          <input id="avataraltradius" class="theme-radius-rn" type="range" v-model="avatarAltRadiusLocal" max="28">
+          <input id="avataraltradius-t" class="theme-radius-in" type="text" v-model="avatarAltRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="attachmentradius" class="theme-radius-lb">{{$t('settings.attachmentRadius')}}</label>
+          <input id="attachmentrradius" class="theme-radius-rn" type="range" v-model="attachmentRadiusLocal" max="50">
+          <input id="attachmentradius-t" class="theme-radius-in" type="text" v-model="attachmentRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="tooltipradius" class="theme-radius-lb">{{$t('settings.tooltipRadius')}}</label>
+          <input id="tooltipradius" class="theme-radius-rn" type="range" v-model="tooltipRadiusLocal" max="20">
+          <input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
+        </div>
       </div>
-      <div class="color-item">
-        <h4>Panel header</h4>
-        <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
-        <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
-        <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
-      </div>
-      <div class="color-item">
-        <h4>Top bar</h4>
-        <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.topBarText"/>
-        <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
-        <ContrastRatio :contrast="previewContrast.topBarLink"/>
-      </div>
-      <div class="color-item">
-        <h4>Text fields</h4>
-        <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
-        <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.inputText"/>
-      </div>
-      <div class="color-item">
-        <h4>Buttons</h4>
-        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
-        <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.btnText"/>
-      </div>
-      <div class="color-item">
-        <h4>Borders</h4>
-        <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
-        <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
-      </div>
-      <div class="color-item">
-        <h4>Faint text</h4>
-        <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
-        <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
-        <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.panel')"/>
-        <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
-      </div>
-    </div>
-  </div>
-
-  <div class="radius-container">
-    <p>{{$t('settings.radii_help')}}</p>
-    <div class="radius-item">
-      <label for="btnradius" class="theme-radius-lb">{{$t('settings.btnRadius')}}</label>
-      <input id="btnradius" class="theme-radius-rn" type="range" v-model="btnRadiusLocal" max="16">
-      <input id="btnradius-t" class="theme-radius-in" type="text" v-model="btnRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="inputradius" class="theme-radius-lb">{{$t('settings.inputRadius')}}</label>
-      <input id="inputradius" class="theme-radius-rn" type="range" v-model="inputRadiusLocal" max="16">
-      <input id="inputradius-t" class="theme-radius-in" type="text" v-model="inputRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="panelradius" class="theme-radius-lb">{{$t('settings.panelRadius')}}</label>
-      <input id="panelradius" class="theme-radius-rn" type="range" v-model="panelRadiusLocal" max="50">
-      <input id="panelradius-t" class="theme-radius-in" type="text" v-model="panelRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="avatarradius" class="theme-radius-lb">{{$t('settings.avatarRadius')}}</label>
-      <input id="avatarradius" class="theme-radius-rn" type="range" v-model="avatarRadiusLocal" max="28">
-      <input id="avatarradius-t" class="theme-radius-in" type="green" v-model="avatarRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="avataraltradius" class="theme-radius-lb">{{$t('settings.avatarAltRadius')}}</label>
-      <input id="avataraltradius" class="theme-radius-rn" type="range" v-model="avatarAltRadiusLocal" max="28">
-      <input id="avataraltradius-t" class="theme-radius-in" type="text" v-model="avatarAltRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="attachmentradius" class="theme-radius-lb">{{$t('settings.attachmentRadius')}}</label>
-      <input id="attachmentrradius" class="theme-radius-rn" type="range" v-model="attachmentRadiusLocal" max="50">
-      <input id="attachmentradius-t" class="theme-radius-in" type="text" v-model="attachmentRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="tooltipradius" class="theme-radius-lb">{{$t('settings.tooltipRadius')}}</label>
-      <input id="tooltipradius" class="theme-radius-rn" type="range" v-model="tooltipRadiusLocal" max="20">
-      <input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
-    </div>
-  </div>
+    </tab-switcher>
 
   <div class="apply-container">
     <button class="btn submit" @click="setCustomTheme">{{$t('general.apply')}}</button>
@@ -193,14 +193,12 @@
 
 .apply-container,
 .radius-container,
-.color-container > div,
+.color-container,
 .presets-container {
   display: flex;
 
   p {
-    flex: 2 0 100%;
-    margin-top: 2em;
-    margin-bottom: .5em;
+    margin-left: 1em
   }
 }
 
@@ -208,7 +206,7 @@
   flex-direction: column;
 }
 
-.color-container > div{
+.color-container{
   flex-wrap: wrap;
   justify-content: space-between;
 }
@@ -231,6 +229,9 @@
   border-color: var(--border, $fallback--border);
   margin: 1em -1em 0;
   padding: 1em;
+  background: var(--body-background-image);
+  background-size: cover;
+  background-position: 50% 50%;
 
   .btn {
     margin-top: 1em;
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 77a9a2af..c2d5b9e6 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -63,11 +63,6 @@
     color: $fallback--faint;
     color: var(--panelFaint, $fallback--faint);
   }
-
-  .loadmore-error {
-    color: $fallback--text;
-    color: var(--text, $fallback--text);
-  }
 }
 
 .new-status-notification {
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 7a5254b9..6f046a1d 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -80,30 +80,23 @@ const getContrastRatio = (a, b) => {
 }
 
 /**
- * This generates what "worst case" color would look like for transparent
- * segments. I.e. transparent black with yellow text over yellow background.
+ * This performs alpha blending between solid background and semi-transparent foreground
  *
- * @param {Object} srgb - transparent color
- * @param {Number} alpha - color's opacity/alpha channel
- * @param {Object} textSrgb - text color (considered as worst case scenario for transparent background)
+ * @param {Object} fg - top layer color
+ * @param {Number} fga - top layer's alpha
+ * @param {Object} bg - bottom layer color
  * @returns {Object} sRGB of resulting color
  */
-const transparentWorstCase = (srgb, alpha, textSrgb) => {
+const alphaBlend = (fg, fga, bg) => {
+  if (fga === 1 || typeof fga === 'undefined') return fg
   return 'rgb'.split('').reduce((acc, c) => {
     // Simplified https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
     // for opaque bg and transparent fg
-    acc[c] = (srgb[c] * alpha + textSrgb[c] * (1 - alpha))
+    acc[c] = (fg[c] * fga + bg[c] * (1 - fga))
     return acc
   }, {})
 }
 
-const worstCase = (bg, bga, text) => {
-  console.log(bg)
-  console.log(text)
-  if (bga === 1 || typeof bga === 'undefined') return bg
-  return transparentWorstCase(bg, bga, text)
-}
-
 const hex2rgb = (hex) => {
   const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
   return result ? {
@@ -134,5 +127,5 @@ export {
   mixrgb,
   rgbstr2hex,
   getContrastRatio,
-  worstCase
+  alphaBlend
 }
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 666e74c1..9388e6f9 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -1,6 +1,6 @@
 import { times } from 'lodash'
-import { brightness, invertLightness, convert } from 'chromatism'
-import { rgb2hex, hex2rgb, mixrgb } from '../color_convert/color_convert.js'
+import { brightness, invertLightness, convert, contrastRatio } from 'chromatism'
+import { rgb2hex, hex2rgb, mixrgb, getContrastRatio, alphaBlend } from '../color_convert/color_convert.js'
 
 // While this is not used anymore right now, I left it in if we want to do custom
 // styles that aren't just colors, so user can pick from a few different distinct
@@ -58,13 +58,17 @@ const rgb2rgba = function (rgba) {
   return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`
 }
 
-const getTextColor = function (bg, text) {
+const getTextColor = function (bg, text, preserve) {
   const bgIsLight = convert(bg).hsl.l > 50
   const textIsLight = convert(text).hsl.l > 50
 
   if ((bgIsLight && textIsLight) || (!bgIsLight && !textIsLight)) {
     const base = typeof text.a !== 'undefined' ? { a: text.a } : {}
-    return Object.assign(base, invertLightness(text).rgb)
+    const result = Object.assign(base, invertLightness(text).rgb)
+    if (!preserve && getContrastRatio(bg, result) < 4.5) {
+      return contrastRatio(bg, text).rgb
+    }
+    return result
   }
   return text
 }
@@ -104,7 +108,12 @@ const generatePreset = (input) => {
     alert: 0.5,
     input: 0.5,
     faint: 0.5
-  }, input.opacity)
+  }, Object.entries(input.opacity || {}).reduce((acc, [k, v]) => {
+    if (typeof v !== 'undefined') {
+      acc[k] = v
+    }
+    return acc
+  }, {}))
 
   const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
     if (typeof v === 'object') {
@@ -128,9 +137,9 @@ const generatePreset = (input) => {
 
   colors.fg = col.fg
   colors.fgText = col.fgText || getTextColor(colors.fg, colors.text)
-  colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link)
+  colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link, true)
 
-  colors.border = col.border || brightness(20 * mod, colors.fg).rgb
+  colors.border = col.border || brightness(2 * mod, colors.fg).rgb
 
   colors.btn = col.btn || Object.assign({}, col.fg)
   colors.btnText = col.btnText || getTextColor(colors.btn, colors.fgText)
@@ -156,8 +165,11 @@ const generatePreset = (input) => {
   colors.cOrange = col.cOrange
 
   colors.alertError = col.alertError || Object.assign({}, col.cRed)
+  colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)
+  colors.alertErrorPanelText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.panel), colors.panelText)
+
   colors.badgeNotification = col.badgeNotification || Object.assign({}, col.cRed)
-  colors.badgeNotificationText = col.badgeNotification || Object.assign({}, col.cRed)
+  colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
 
   Object.entries(opacity).forEach(([ k, v ]) => {
     if (typeof v === 'undefined') return
diff --git a/src/services/user_highlighter/user_highlighter.js b/src/services/user_highlighter/user_highlighter.js
index ebb25eca..f6ddfb9c 100644
--- a/src/services/user_highlighter/user_highlighter.js
+++ b/src/services/user_highlighter/user_highlighter.js
@@ -11,7 +11,7 @@ const highlightStyle = (prefs) => {
   if (type === 'striped') {
     return {
       backgroundImage: [
-        'repeating-linear-gradient(-45deg,',
+        'repeating-linear-gradient(135deg,',
         `${tintColor} ,`,
         `${tintColor} 20px,`,
         `${tintColor2} 20px,`,

From 75f0c191dd8ad029561901ce0dab8e10226b95f7 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 14 Nov 2018 21:53:51 +0300
Subject: [PATCH 12/96] some initial work for user highlight v2

---
 src/components/user_card_content/user_card_content.js |  2 +-
 src/services/color_convert/color_convert.js           | 10 ++++++++++
 src/services/style_setter/style_setter.js             |  5 ++---
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index 76a5577e..eae436a9 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -5,7 +5,7 @@ export default {
   props: [ 'user', 'switcher', 'selected', 'hideBio' ],
   computed: {
     headingStyle () {
-      const color = this.$store.state.config.colors.bg
+      const color = this.$store.state.config.customTheme.colors.bg
       if (color) {
         const rgb = hex2rgb(color)
         const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)`
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 6f046a1d..00b6c552 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -97,6 +97,15 @@ const alphaBlend = (fg, fga, bg) => {
   }, {})
 }
 
+const invert = (rgb) => {
+  return 'rgb'.split('').reduce((acc, c) => {
+    console.log(rgb[c])
+    acc[c] = 255 - rgb[c]
+    console.log(acc[c])
+    return acc
+  }, {})
+}
+
 const hex2rgb = (hex) => {
   const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
   return result ? {
@@ -125,6 +134,7 @@ export {
   rgb2hex,
   hex2rgb,
   mixrgb,
+  invert,
   rgbstr2hex,
   getContrastRatio,
   alphaBlend
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 9388e6f9..907de586 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -40,8 +40,6 @@ const setStyle = (href, commit) => {
       colors[name] = color
     })
 
-    commit('setOption', { name: 'colors', value: colors })
-
     body.removeChild(baseEl)
 
     const styleEl = document.createElement('style')
@@ -74,7 +72,7 @@ const getTextColor = function (bg, text, preserve) {
 }
 
 const setColors = (input, commit) => {
-  const { colorRules, radiiRules } = generatePreset(input)
+  const { colorRules, radiiRules, theme } = generatePreset(input)
   const head = document.head
   const body = document.body
   body.style.display = 'none'
@@ -91,6 +89,7 @@ const setColors = (input, commit) => {
   // commit('setOption', { name: 'colors', value: htmlColors })
   // commit('setOption', { name: 'radii', value: radii })
   commit('setOption', { name: 'customTheme', value: input })
+  commit('setOption', { name: 'colors', value: theme.colors })
 }
 
 const generatePreset = (input) => {

From 2369f2e4cba2df8bb1dda431f193130bbf290d2c Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 14 Nov 2018 22:20:42 +0300
Subject: [PATCH 13/96] fixed webkit appearance of the UI

---
 src/components/color_input/color_input.vue       | 5 +++--
 src/components/contrast_ratio/contrast_ratio.vue | 2 +-
 src/components/opacity_input/opacity_input.vue   | 5 ++---
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index 49d9bed7..60a62fa8 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -47,6 +47,7 @@ export default {
 <style lang="scss">
 .color-control {
   display: flex;
+  align-items: baseline;
 
   &.disabled *:not(.opt-l){
     opacity: .5
@@ -75,10 +76,10 @@ export default {
     flex: 0;
     padding: 1px;
     cursor: pointer;
-    height: 100%;
-    max-height: 29px;
+    height: 29px;
     min-width: 2em;
     border: none;
+    align-self: stretch;
   }
 }
 </style>
diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
index cb65c371..9a93dcd0 100644
--- a/src/components/contrast_ratio/contrast_ratio.vue
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -36,7 +36,7 @@ export default {
 <style lang="scss">
 .contrast-ratio {
   display: flex;
-  justify-content: end;
+  justify-content: flex-end;
 
   .label {
     margin-right: 1em;
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index efa6c449..4057dcca 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -41,6 +41,7 @@ export default {
 <style lang="scss">
 .opacity-control {
   display: flex;
+  align-items: baseline;
 
   &.disabled *:not(.opt-l) {
     opacity: .5
@@ -48,7 +49,6 @@ export default {
 
   .opt-l {
     align-self: center;
-    line-height: 0;
     &::before {
       width: 14px;
       height: 14px;
@@ -61,7 +61,6 @@ export default {
   }
 
   .input-range {
-    align-self: center;
     background: none;
     border: none;
     margin: 0;
@@ -70,8 +69,8 @@ export default {
     min-width: 7em;
     flex: 1;
   }
+
   .input-number {
-    align-self: center;
     margin: 0;
     min-width: 4em;
     flex: 0;

From 75cdcc40db45463c1612950c1263b3e3dc2a2725 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 15 Nov 2018 17:09:25 +0300
Subject: [PATCH 14/96] fix accidentally removed icon

---
 static/font/config.json                |   6 ++++++
 static/font/css/fontello-codes.css     |   1 +
 static/font/css/fontello-embedded.css  |  13 +++++++------
 static/font/css/fontello-ie7-codes.css |   1 +
 static/font/css/fontello-ie7.css       |   1 +
 static/font/css/fontello.css           |  15 ++++++++-------
 static/font/demo.html                  |  13 +++++++------
 static/font/font/fontello.eot          | Bin 16124 -> 16384 bytes
 static/font/font/fontello.svg          |   2 ++
 static/font/font/fontello.ttf          | Bin 15956 -> 16216 bytes
 static/font/font/fontello.woff         | Bin 9848 -> 9972 bytes
 static/font/font/fontello.woff2        | Bin 8372 -> 8456 bytes
 12 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/static/font/config.json b/static/font/config.json
index be809269..1d1317d7 100644
--- a/static/font/config.json
+++ b/static/font/config.json
@@ -203,6 +203,12 @@
       "css": "attention",
       "code": 59412,
       "src": "fontawesome"
+    },
+    {
+      "uid": "1a5cfa186647e8c929c2b17b9fc4dac1",
+      "css": "plus-squared",
+      "code": 61694,
+      "src": "fontawesome"
     }
   ]
 }
\ No newline at end of file
diff --git a/static/font/css/fontello-codes.css b/static/font/css/fontello-codes.css
index 21cf6f06..66a240cd 100644
--- a/static/font/css/fontello-codes.css
+++ b/static/font/css/fontello-codes.css
@@ -27,6 +27,7 @@
 .icon-menu:before { content: '\f0c9'; } /* '' */
 .icon-mail-alt:before { content: '\f0e0'; } /* '' */
 .icon-comment-empty:before { content: '\f0e5'; } /* '' */
+.icon-plus-squared:before { content: '\f0fe'; } /* '' */
 .icon-reply:before { content: '\f112'; } /* '' */
 .icon-lock-open-alt:before { content: '\f13e'; } /* '' */
 .icon-thumbs-up-alt:before { content: '\f164'; } /* '' */
diff --git a/static/font/css/fontello-embedded.css b/static/font/css/fontello-embedded.css
index a1b3e3d6..65875bde 100644
--- a/static/font/css/fontello-embedded.css
+++ b/static/font/css/fontello-embedded.css
@@ -1,15 +1,15 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?61520746');
-  src: url('../font/fontello.eot?61520746#iefix') format('embedded-opentype'),
-       url('../font/fontello.svg?61520746#fontello') format('svg');
+  src: url('../font/fontello.eot?92539127');
+  src: url('../font/fontello.eot?92539127#iefix') format('embedded-opentype'),
+       url('../font/fontello.svg?92539127#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
 @font-face {
   font-family: 'fontello';
-  src: url('data:application/octet-stream;base64,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') format('woff'),
-       url('data:application/octet-stream;base64,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RCywABUgR7AAI0KyAAEBFRQTLrAxKi2wRSywABUgR7AAI0KyAAEBFRQTLrAxKi2wRiyxAAEUE7AyKi2wRyywNCotsEgssAAWRSMgLiBGiiNhOLErARQrLbBJLLAII0KwSCstsEossgAAQSstsEsssgABQSstsEwssgEAQSstsE0ssgEBQSstsE4ssgAAQistsE8ssgABQistsFAssgEAQistsFEssgEBQistsFIssgAAPistsFMssgABPistsFQssgEAPistsFUssgEBPistsFYssgAAQCstsFcssgABQCstsFgssgEAQCstsFkssgEBQCstsFossgAAQystsFsssgABQystsFwssgEAQystsF0ssgEBQystsF4ssgAAPystsF8ssgABPystsGAssgEAPystsGEssgEBPystsGIssDcrLrErARQrLbBjLLA3K7A7Ky2wZCywNyuwPCstsGUssAAWsDcrsD0rLbBmLLA4Ky6xKwEUKy2wZyywOCuwOystsGgssDgrsDwrLbBpLLA4K7A9Ky2waiywOSsusSsBFCstsGsssDkrsDsrLbBsLLA5K7A8Ky2wbSywOSuwPSstsG4ssDorLrErARQrLbBvLLA6K7A7Ky2wcCywOiuwPCstsHEssDorsD0rLbByLLMJBAIDRVghGyMhWUIrsAhlsAMkUHiwARUwLQBLuADIUlixAQGOWbABuQgACABjcLEABUKyAAEAKrEABUKzCgIBCCqxAAVCsw4AAQgqsQAGQroCwAABAAkqsQAHQroAQAABAAkqsQMARLEkAYhRWLBAiFixA2REsSYBiFFYugiAAAEEQIhjVFixAwBEWVlZWbMMAgEMKrgB/4WwBI2xAgBEAAA=') format('truetype');
+  src: url('data:application/octet-stream;base64,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') format('woff'),
+       url('data:application/octet-stream;base64,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') format('truetype');
 }
 /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
 /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
@@ -17,7 +17,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?61520746#fontello') format('svg');
+    src: url('../font/fontello.svg?92539127#fontello') format('svg');
   }
 }
 */
@@ -80,6 +80,7 @@
 .icon-menu:before { content: '\f0c9'; } /* '' */
 .icon-mail-alt:before { content: '\f0e0'; } /* '' */
 .icon-comment-empty:before { content: '\f0e5'; } /* '' */
+.icon-plus-squared:before { content: '\f0fe'; } /* '' */
 .icon-reply:before { content: '\f112'; } /* '' */
 .icon-lock-open-alt:before { content: '\f13e'; } /* '' */
 .icon-thumbs-up-alt:before { content: '\f164'; } /* '' */
diff --git a/static/font/css/fontello-ie7-codes.css b/static/font/css/fontello-ie7-codes.css
index 5e732ec9..689c8e43 100644
--- a/static/font/css/fontello-ie7-codes.css
+++ b/static/font/css/fontello-ie7-codes.css
@@ -27,6 +27,7 @@
 .icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c9;&nbsp;'); }
 .icon-mail-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e0;&nbsp;'); }
 .icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e5;&nbsp;'); }
+.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0fe;&nbsp;'); }
 .icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf112;&nbsp;'); }
 .icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13e;&nbsp;'); }
 .icon-thumbs-up-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf164;&nbsp;'); }
diff --git a/static/font/css/fontello-ie7.css b/static/font/css/fontello-ie7.css
index b4be6e9b..23ecfa3c 100644
--- a/static/font/css/fontello-ie7.css
+++ b/static/font/css/fontello-ie7.css
@@ -38,6 +38,7 @@
 .icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0c9;&nbsp;'); }
 .icon-mail-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e0;&nbsp;'); }
 .icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0e5;&nbsp;'); }
+.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf0fe;&nbsp;'); }
 .icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf112;&nbsp;'); }
 .icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf13e;&nbsp;'); }
 .icon-thumbs-up-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf164;&nbsp;'); }
diff --git a/static/font/css/fontello.css b/static/font/css/fontello.css
index d8419862..0181fa62 100644
--- a/static/font/css/fontello.css
+++ b/static/font/css/fontello.css
@@ -1,11 +1,11 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?91338570');
-  src: url('../font/fontello.eot?91338570#iefix') format('embedded-opentype'),
-       url('../font/fontello.woff2?91338570') format('woff2'),
-       url('../font/fontello.woff?91338570') format('woff'),
-       url('../font/fontello.ttf?91338570') format('truetype'),
-       url('../font/fontello.svg?91338570#fontello') format('svg');
+  src: url('../font/fontello.eot?13201279');
+  src: url('../font/fontello.eot?13201279#iefix') format('embedded-opentype'),
+       url('../font/fontello.woff2?13201279') format('woff2'),
+       url('../font/fontello.woff?13201279') format('woff'),
+       url('../font/fontello.ttf?13201279') format('truetype'),
+       url('../font/fontello.svg?13201279#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
@@ -15,7 +15,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?91338570#fontello') format('svg');
+    src: url('../font/fontello.svg?13201279#fontello') format('svg');
   }
 }
 */
@@ -83,6 +83,7 @@
 .icon-menu:before { content: '\f0c9'; } /* '' */
 .icon-mail-alt:before { content: '\f0e0'; } /* '' */
 .icon-comment-empty:before { content: '\f0e5'; } /* '' */
+.icon-plus-squared:before { content: '\f0fe'; } /* '' */
 .icon-reply:before { content: '\f112'; } /* '' */
 .icon-lock-open-alt:before { content: '\f13e'; } /* '' */
 .icon-thumbs-up-alt:before { content: '\f164'; } /* '' */
diff --git a/static/font/demo.html b/static/font/demo.html
index 22bc0e92..6e4d3eb0 100644
--- a/static/font/demo.html
+++ b/static/font/demo.html
@@ -229,11 +229,11 @@ body {
 }
 @font-face {
       font-family: 'fontello';
-      src: url('./font/fontello.eot?93659852');
-      src: url('./font/fontello.eot?93659852#iefix') format('embedded-opentype'),
-           url('./font/fontello.woff?93659852') format('woff'),
-           url('./font/fontello.ttf?93659852') format('truetype'),
-           url('./font/fontello.svg?93659852#fontello') format('svg');
+      src: url('./font/fontello.eot?97354950');
+      src: url('./font/fontello.eot?97354950#iefix') format('embedded-opentype'),
+           url('./font/fontello.woff?97354950') format('woff'),
+           url('./font/fontello.ttf?97354950') format('truetype'),
+           url('./font/fontello.svg?97354950#fontello') format('svg');
       font-weight: normal;
       font-style: normal;
     }
@@ -340,12 +340,13 @@ body {
         <div class="the-icons span3" title="Code: 0xf0e5"><i class="demo-icon icon-comment-empty">&#xf0e5;</i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xf0e5</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf0fe"><i class="demo-icon icon-plus-squared">&#xf0fe;</i> <span class="i-name">icon-plus-squared</span><span class="i-code">0xf0fe</span></div>
         <div class="the-icons span3" title="Code: 0xf112"><i class="demo-icon icon-reply">&#xf112;</i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
         <div class="the-icons span3" title="Code: 0xf13e"><i class="demo-icon icon-lock-open-alt">&#xf13e;</i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xf13e</span></div>
         <div class="the-icons span3" title="Code: 0xf164"><i class="demo-icon icon-thumbs-up-alt">&#xf164;</i> <span class="i-name">icon-thumbs-up-alt</span><span class="i-code">0xf164</span></div>
-        <div class="the-icons span3" title="Code: 0xf1e5"><i class="demo-icon icon-binoculars">&#xf1e5;</i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf1e5"><i class="demo-icon icon-binoculars">&#xf1e5;</i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
         <div class="the-icons span3" title="Code: 0xf234"><i class="demo-icon icon-user-plus">&#xf234;</i> <span class="i-name">icon-user-plus</span><span class="i-code">0xf234</span></div>
       </div>
     </div>
diff --git a/static/font/font/fontello.eot b/static/font/font/fontello.eot
index 993381629cbd44410df7caee5dfa646e5ed19525..a7b690a7d7864f9799f11e78da248e8dea1a1fbc 100644
GIT binary patch
delta 797
zcmZ9KPfXKL9LImJ?K&c(b6crKCTuGK6WkK^*F-WHL)n3YQG*bZNyEmLNTsqt@SqTH
zDiKK&<3%z&7-NVg^a6>-i!s4Jks~SxFEcao&@IXdHh<gV#lC*u_kDi-y}tK;?f%V$
z1;Rofz)0^h8)WQqDYe{pZ+-!QoCAR2aamFxe(_|Gp8?P-<Fi=@TPgnr@ZltIOeiV&
z?(&0C<S~FoB_(APj2}imh2D^wyfHDc_A&=xhyk4FPbZ~>Z9R7kz`cmigJ}#Hx9BqR
zTjch%oSnN>9<KbrKmh}blT+i;la1$Z06babm@LgHWUlEc@+)M=HAzl>eBA0l-UXmO
zDN~v3hhJYm19Y$9rtc`zNhKfY!rbt-nj@FVs=7~7p*<it8$buTHadxZ2=n)Vf$B!=
zcmx_u1-{@d`1K`yOaHFt^|JbivU7U5Xf1||iDJIwuT<0s-O@sE!a%K^h5wpbqRtpx
z_-Yn2_tkC6Xf{<>uGX`5xwIkXJc;R8gR0;-K+#$kw4#UWf;RL-UEn~^*9A_1lD{s%
zb+jGBrgNSGsBF-qv=v0~L8LF-M1ZsrhNcE79MJ@5*+6Ip@2g<M5*W!CFf7Yl1cqTp
zfMwXBKtS{fV!PO2uy>Jwzr!eE*D1PKV{@(Jg^;hA7fuszFck24gEkA#8lA3=fW?0)
z7;<_A>OF7P1a8pGlXaB9t=B>0g!}R6!Ov(s9;J>%<0KN}1ftbaG~QeTP7pYaC%p%S
z{x}(nP)Dl<+EV9hgFRJ}?N`h_f1r`B{v)ts^9297ns$eXsOH==WK^|!E?8og6>Ed_
wg>9C1*1oi;&3YPXOu5}XK#_L!UH7*plQKDzac8d2NYlxLy6WxGcD)YMU(p`QkN^Mx

delta 514
zcmZo@VEj|d_Q#HaA;fMXn;FaU1xM~rbm*>cVqjnlU|?VfOU_L!a5%mH6_CGzfq}Ur
zxvWHi?f<_o3=Bp#KzW6<g7n<3i4!7${1^rX?t=8h;sT(!0FZA2q&d=aD%0-Emu+TX
zU^QT1P|wOpO-vD9wH7F)GY3eRWdH@(Pcr`n@~;5-DjB&Y71c|_{yzf>`~V7c<m4wO
zE|#7KWa~Bn`EI$16$Omtyvu<66F|N~USe+QnYnTbK>iB`2BxzG`Nbt4=9aoLFc|Cr
zI=ZT$D7E0JqxK#K2HP`}7cfRME}r~{G2QeH10zs31H&^0W-v<!NOJ+zzhPiu*aZ}q
z0(t=`@<QZ=(F>Cg{U1(#c<|xr<XKEIlXozwN-_fFoxsqA0R>L}#pJr#k(q~)6XZJ(
zP~05G62xfrQHX&7gc)RkG%&b9m_ZImr$8`+Jdl10!3+uv44;6Z2f{%8A6R!PZf?}r
z%_?*M$b#kZ{5D@1xS4@|Wnj3$Z?Y0bPma(tXH=RzL9cW&r+$E-k>DI5Ct)t(tw4E@
ePn9-j>2os!6_gpdOx|O3d-4)vo6Qf6<#_<4Q;_fg

diff --git a/static/font/font/fontello.svg b/static/font/font/fontello.svg
index c706fcad..fed9129e 100644
--- a/static/font/font/fontello.svg
+++ b/static/font/font/fontello.svg
@@ -62,6 +62,8 @@
 
 <glyph glyph-name="comment-empty" unicode="&#xf0e5;" d="M500 643q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-53q-13-51-39-97 85 36 154 96l24 21 32-3q38-5 72-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-8-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 6t1 6 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
 
+<glyph glyph-name="plus-squared" unicode="&#xf0fe;" d="M714 321v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
+
 <glyph glyph-name="reply" unicode="&#xf112;" d="M1000 232q0-93-71-252-1-4-6-13t-7-17-7-12q-7-10-16-10-8 0-13 6t-5 14q0 5 1 15t2 13q3 38 3 69 0 56-10 101t-27 77-45 56-59 39-74 24-86 12-98 3h-125v-143q0-14-10-25t-26-11-25 11l-285 286q-11 10-11 25t11 25l285 286q11 10 25 10t26-10 10-25v-143h125q398 0 488-225 30-75 30-186z" horiz-adv-x="1000" />
 
 <glyph glyph-name="lock-open-alt" unicode="&#xf13e;" d="M589 428q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v179q0 103 74 177t176 73 177-73 73-177q0-14-10-25t-25-11h-36q-14 0-25 11t-11 25q0 59-42 101t-101 42-101-42-41-101v-179h410z" horiz-adv-x="642.9" />
diff --git a/static/font/font/fontello.ttf b/static/font/font/fontello.ttf
index d2d2963e7db8232c1a10317db768f4c3fe1b0b33..5fb1466a2af114268066dcb77a0963f9449eaf3e 100644
GIT binary patch
delta 756
zcmZ9KO-vI(9L3-4Zd;Uo*mhZssnB*2O`rt&X(B;NQ5xgHC_#xyrGZkSR90FDCI-A}
z2tqdTCP8D2F-8;if{8{CUhw<i0nvjOv?d-_q67~V|83*NoqhA>_n)_$nc4ktd3j<+
zp1cCE;{dw*GD+pe$Hpx2J%FF<8_T(kTZLahppE9;14=q`ZFZ)IxEH8Y(#fns^&P|q
z$ScxAmj(tNJemg#abSP@U@F<~T$tYt_@-z+JV*u85?>&GL0mhS$&F7Gy0^YkAy0*=
zq2a#d?Zx}gfW{ngJd+$(*tq2`@e^YAg=8l6`ewD8_%p!0QHHa*S3g$X0nHC+(N~p`
zl(HJFr)=x{*^M*omfFSAk##V77|_9&Mh)cKDZUN?#dWx72RzJqG4Ia@_3QeQ{zYHa
z3#!gs9GRKhyNA*g>nOD&_^+u)xx>t>O>-8ujn1ufd9^$I2^QCBuSJ30@Y7Kis>xf+
zLJfI;S#XoDmIV*67Ay;1Kx;BQ_DpiX)*|1-J0K%~Xj`j=fz>d9=Q=qW@eF*%z<7b~
z^DxnpO{^D!(I|955R9i`6pY70Avqw)wQ_~QRnJ1fI+IM@KG|zDRh2qXiUg`e=^*om
zBcXsl?6iwUlgC>ZvIkFvBObrRy%cSlWbL$xY=I<M7s{YnrRhX$^Ls3jh;ch(2^Ni8
zC8m`knrJJ5Rg$cl$PR7h+Y_ue%Izu|v~P7!4X*TB#&y=#@*9<W@n68QvoZY7)#nWn
zCaW6_qpU|g=R0YS+vgk=j)%@M(Np@Qvi8<j$x~#dse@y+YIXA`i&+^O&HAzzN0TF|
Oe)Ugtix%{|&3^%@w!7Q_

delta 531
zcmcancco^6a(xp617iRK14CGHZeoGM>HV*O{1prg%pJ*PB?@f+|9xR#FtP#4E2I^q
z=XOn;5DDbRFfeczq$d^^0L2A>d=ntek)BhTc3-}1GXn#w0Rw}2Rz_-KitwtnKq;L$
zK*B5oD8PP_`7e-v1;|&)$StX;UK;lQ8BpK{P@p3xKRI!+^fVw_w*km^%T25(U@Yfd
z2IQXr@)hzDb5qaEl~VxnUobE*oh`^OF8MIG)Rlq3U<c6ARRu+<1y3Ed_b@Qno|*U~
znsM>u5XSVtHw=tG%?u3B7?{B<9U#pGRQ`s6g<%&^Tngv|pvVi67e+5kKJ<S$`QgEb
zryqqr+I>v<`1F&>|NjgOFBrgbeGs|H0!*rsj6i)(VCcet0w)JCxdJU>o4k<e-(&+O
z*2(jk**HP|2LZ*+>zIQWtv(7dFn}<FEReQ?U<NrLodUrO@<9421T!cwFnj`rF9-wm
zd$8_Q+<a4gH>=G3BMX+t^V@u7;ARGf1_Q$lev_3jdh!Ncb4I1fFLX;MC+Y<V8VSx3
nauVhe-U^fl1%}e*LwelIKn3RvT_%ed-Jbl%$Y!&pu{;j|Qh%O~

diff --git a/static/font/font/fontello.woff b/static/font/font/fontello.woff
index c1aa83bb3aeb19fbeb0626a27133e218ad0d0444..ca463697bc2307d76991a4af2a2cb0f5ba86a0f6 100644
GIT binary patch
delta 7744
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
G{3U$6^%k4}

delta 7641
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

diff --git a/static/font/font/fontello.woff2 b/static/font/font/fontello.woff2
index cbd9b09f706d5320154cd4fb11140fac7e7c35ed..09fafb310e4891a3337176a229ae0fdb5fb56f55 100644
GIT binary patch
literal 8456
zcmV+jA@|;QPew8T0RR9103iqf4*&oF06$m&03fgc0RR9100000000000000000000
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

literal 8372
zcmV;lAWPqOPew8T0RR9103fsg4*&oF06tUz03cid0RR9100000000000000000000
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
K;pHEOfV%+u3jlop


From edb429e30796c9312de9a28c262008c7d44757e6 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 15 Nov 2018 17:17:20 +0300
Subject: [PATCH 15/96] cleanup and fixes

---
 src/components/style_switcher/style_switcher.js | 16 ++--------------
 src/services/color_convert/color_convert.js     |  2 --
 2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 9e236488..f4f9331f 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -288,19 +288,6 @@ export default {
     },
 
     setCustomTheme () {
-      if (!this.bgColorLocal && !this.btnColorLocal && !this.linkColorLocal) {
-        // reset to picked themes
-      }
-
-      const rgb = (hex) => {
-        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
-        return result ? {
-          r: parseInt(result[1], 16),
-          g: parseInt(result[2], 16),
-          b: parseInt(result[3], 16)
-        } : null
-      }
-
       this.$store.dispatch('setOption', {
         name: 'customTheme',
         value: this.currentTheme
@@ -310,6 +297,8 @@ export default {
     clearV1 () {
       this.bgOpacityLocal = undefined
       this.fgOpacityLocal = undefined
+
+      this.fgTextColorLocal = undefined
       this.fgLinkColorLocal = undefined
 
       this.btnColorLocal = undefined
@@ -371,7 +360,6 @@ export default {
       }
 
       const keys = new Set(version !== 1 ? Object.keys(colors) : [])
-      console.log(keys)
       if (version === 1) {
         // V1 ignores the rest
         this.clearV1()
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 00b6c552..58c434fa 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -99,9 +99,7 @@ const alphaBlend = (fg, fga, bg) => {
 
 const invert = (rgb) => {
   return 'rgb'.split('').reduce((acc, c) => {
-    console.log(rgb[c])
     acc[c] = 255 - rgb[c]
-    console.log(acc[c])
     return acc
   }, {})
 }

From a5b4f31c12706b7226915864c01e5508caf262f9 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 19 Nov 2018 04:40:25 +0300
Subject: [PATCH 16/96] shadow control initial stuff. not done yet tho

---
 src/components/color_input/color_input.vue    |   8 +-
 .../opacity_input/opacity_input.vue           |   6 +-
 .../shadow_control/shadow_control.js          |  76 ++++++
 .../shadow_control/shadow_control.vue         | 249 ++++++++++++++++++
 .../style_switcher/style_switcher.js          |  18 ++
 .../style_switcher/style_switcher.vue         |  11 +
 src/services/style_setter/style_setter.js     |  29 +-
 static/font/config.json                       |   7 +-
 static/font/css/fontello-codes.css            |   1 +
 static/font/css/fontello-embedded.css         |  13 +-
 static/font/css/fontello-ie7-codes.css        |   1 +
 static/font/css/fontello-ie7.css              |   1 +
 static/font/css/fontello.css                  |  15 +-
 static/font/demo.html                         |  17 +-
 static/font/font/fontello.eot                 | Bin 16384 -> 16552 bytes
 static/font/font/fontello.svg                 |   2 +
 static/font/font/fontello.ttf                 | Bin 16216 -> 16384 bytes
 static/font/font/fontello.woff                | Bin 9972 -> 10072 bytes
 static/font/font/fontello.woff2               | Bin 8456 -> 8564 bytes
 19 files changed, 424 insertions(+), 30 deletions(-)
 create mode 100644 src/components/shadow_control/shadow_control.js
 create mode 100644 src/components/shadow_control/shadow_control.vue

diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index 60a62fa8..ea9fb3c4 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="color-control" :class="{ disabled: !present }">
+<div class="color-control" :class="{ disabled: !present || disabled }">
   <label :for="name" class="label">
     {{label}}
   </label>
@@ -17,7 +17,7 @@
     class="color-input"
     type="color"
     :value="value || fallback"
-    :disabled="!present"
+    :disabled="!present || disabled"
     @input="$emit('input', $event.target.value)"
     >
   <input
@@ -25,7 +25,7 @@
     class="text-input"
     type="text"
     :value="value || fallback"
-    :disabled="!present"
+    :disabled="!present || disabled"
     @input="$emit('input', $event.target.value)"
     >
 </div>
@@ -34,7 +34,7 @@
 <script>
 export default {
   props: [
-    'name', 'label', 'value', 'fallback'
+    'name', 'label', 'value', 'fallback', 'disabled'
   ],
   computed: {
     present () {
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index 4057dcca..91c4f5e9 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="opacity-control" :class="{ disabled: !present }">
+<div class="opacity-control" :class="{ disabled: !present || disabled }">
   <label :for="name" class="label">
     {{$t('settings.opacity')}}
   </label>
@@ -17,7 +17,7 @@
     class="input-number"
     type="number"
     :value="value || fallback"
-    :disabled="!present"
+    :disabled="!present || disabled"
     @input="$emit('input', $event.target.value)"
     max="1"
     min="0"
@@ -28,7 +28,7 @@
 <script>
 export default {
   props: [
-    'name', 'value', 'fallback'
+    'name', 'value', 'fallback', 'disabled'
   ],
   computed: {
     present () {
diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
new file mode 100644
index 00000000..c357581d
--- /dev/null
+++ b/src/components/shadow_control/shadow_control.js
@@ -0,0 +1,76 @@
+import ColorInput from '../color_input/color_input.vue'
+import OpacityInput from '../opacity_input/opacity_input.vue'
+import StyleSetter from '../../services/style_setter/style_setter.js'
+import { hex2rgb } from '../../services/color_convert/color_convert.js'
+import { set } from 'vue'
+
+export default {
+  props: [
+    'value', 'fallback'
+  ],
+  data () {
+    return {
+      selectedId: 0,
+      cValue: this.value || this.fallback
+    }
+  },
+  components: {
+    ColorInput,
+    OpacityInput
+  },
+  methods: {
+    add () {
+      this.cValue.push(Object.assign({}, this.selected))
+      this.selectedId = this.cValue.length - 1
+    },
+    del () {
+      this.cValue.splice(this.selectedId, 1)
+      this.selectedId = this.cValue.length === 0 ? undefined : this.selectedId - 1
+    },
+    moveUp () {
+      const movable = this.cValue.splice(this.selectedId, 1)[0]
+      this.cValue.splice(this.selectedId - 1, 0, movable)
+      this.selectedId -= 1
+    },
+    moveDn () {
+      const movable = this.cValue.splice(this.selectedId, 1)[0]
+      this.cValue.splice(this.selectedId + 1, 0, movable)
+      this.selectedId += 1
+    }
+  },
+  computed: {
+    selected () {
+      return this.cValue[this.selectedId] || {
+        x: 0,
+        y: 0,
+        blur: 0,
+        spread: 0,
+        inset: false,
+        color: '#000000',
+        alpha: 1
+      }
+    },
+    moveUpValid () {
+      return this.selectedId > 0
+    },
+    moveDnValid () {
+      return this.selectedId < this.cValue.length - 1
+    },
+    present () {
+      return typeof this.cValue[this.selectedId] !== 'undefined' &&
+        !this.usingFallback
+    },
+    usingFallback () {
+      return typeof this.value === 'undefined'
+    },
+    rgb () {
+      return hex2rgb(this.selected.color)
+    },
+    style () {
+      console.log(StyleSetter.generateShadow(this.cValue))
+      return {
+        boxShadow: StyleSetter.generateShadow(this.cValue)
+      }
+    }
+  }
+}
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
new file mode 100644
index 00000000..24439449
--- /dev/null
+++ b/src/components/shadow_control/shadow_control.vue
@@ -0,0 +1,249 @@
+<template>
+<div class="shadow-control" :class="{ disabled: !present }">
+  <div class="shadow-preview-container">
+    <div :disabled="!present" class="y-shift-control">
+      <input
+        v-model="selected.y"
+        :disabled="!present"
+        class="input-number"
+        type="number">
+      <div class="wrap">
+        <input
+          v-model="selected.y"
+          :disabled="!present"
+          class="input-range"
+          type="range"
+          max="20"
+          min="-20">
+      </div>
+    </div>
+    <div class="preview-window">
+      <div class="preview-block" :style="style"></div>
+    </div>
+    <div :disabled="!present" class="x-shift-control">
+      <input
+        v-model="selected.x"
+        :disabled="!present"
+        class="input-number"
+        type="number">
+      <div class="wrap">
+        <input
+          v-model="selected.x"
+          :disabled="!present"
+          class="input-range"
+          type="range"
+          max="20"
+          min="-20">
+      </div>
+    </div>
+  </div>
+
+  <div class="shadow-tweak">
+    <div :disabled="usingFallback" class="id-control">
+      <label for="id" class="label">
+        Shadow id
+      </label>
+      <input
+        v-model="selectedId"
+        :disabled="usingFallback"
+        class="input-number"
+        type="number"
+        min="0"
+        :max="cValue.length - 1">
+      <button class="btn btn-default" :disabled="!present" @click="del">
+        <i class="icon-cancel"/>
+      </button>
+      <button class="btn btn-default" :disabled="!moveUpValid" @click="moveUp">
+        <i class="icon-up-open"/>
+      </button>
+      <button class="btn btn-default" :disabled="!moveDnValid" @click="moveDn">
+        <i class="icon-down-open"/>
+      </button>
+      <button class="btn btn-default" @click="add">
+        <i class="icon-plus"/>
+      </button>
+    </div>
+    <div :disabled="!present" class="inset-control">
+      <label for="inset" class="label">
+        Inset
+      </label>
+      <input
+        v-model="selected.inset"
+        :disabled="!present"
+        name="inset"
+        id="inset"
+        class="input-inset"
+        type="checkbox">
+      <label class="checkbox-label" for="inset"></label>
+    </div>
+    <div :disabled="!present" class="blur-control">
+      <label for="spread" class="label">
+        Blur
+      </label>
+      <input
+        v-model="selected.blur"
+        :disabled="!present"
+        name="blur"
+        id="blur"
+        class="input-range"
+        type="range"
+        max="20"
+        min="0">
+      <input
+        v-model="selected.blur"
+        :disabled="!present"
+        class="input-number"
+        type="number"
+        min="0">
+    </div>
+    <div :disabled="!present" class="spread-control">
+      <label for="spread" class="label">
+        Spread
+      </label>
+      <input
+        v-model="selected.spread"
+        :disabled="!present"
+        name="spread"
+        id="spread"
+        class="input-range"
+        type="range"
+        max="20"
+        min="-20">
+      <input
+        v-model="selected.spread"
+        :disabled="!present"
+        class="input-number"
+        type="number">
+    </div>
+    <ColorInput
+      v-model="selected.color"
+      :disabled="!present"
+      label="Color"
+      name="shadow"/>
+    <OpacityInput
+      v-model="selected.alpha"
+      :disabled="!present"/>
+  </div>
+</div>
+</template>
+
+<script src="./shadow_control.js" ></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+.shadow-control {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: center;
+
+  .shadow-preview-container {
+    flex: 0;
+    display: flex;
+    flex-wrap: wrap;
+
+    $side: 15em;
+
+    input[type=number] {
+      width: 5em;
+      min-width: 2em;
+    }
+    .x-shift-control,
+    .y-shift-control {
+      display: flex;
+      flex: 0;
+
+      &[disabled=disabled] *{
+        opacity: .5
+      }
+
+    }
+
+    .x-shift-control {
+      align-items: flex-start;
+    }
+
+    .x-shift-control .wrap,
+    input[type=range] {
+      margin: 0;
+      width: $side;
+      height: 2em;
+    }
+    .y-shift-control {
+      flex-direction: column;
+      align-items: flex-end;
+      .wrap {
+        width: 2em;
+        height: $side;
+      }
+      input[type=range] {
+        transform-origin: 1em 1em;
+        transform: rotate(90deg);
+      }
+    }
+    .preview-window {
+      flex: 1;
+      background-color: white;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background-image:
+      linear-gradient(45deg, #808080 25%, transparent 25%),
+      linear-gradient(-45deg, #808080 25%, transparent 25%),
+      linear-gradient(45deg, transparent 75%, #808080 75%),
+      linear-gradient(-45deg, transparent 75%, #808080 75%);
+      background-size: 20px 20px;
+      background-position:0 0, 0 10px, 10px -10px, -10px 0;
+
+      border-radius: $fallback--inputRadius;
+      border-radius: var(--inputRadius, $fallback--inputRadius);
+
+      .preview-block {
+        width: 33%;
+        height: 33%;
+        background-color: $fallback--bg;
+        background-color: var(--bg, $fallback--bg);
+        border-radius: $fallback--panelRadius;
+        border-radius: var(--panelRadius, $fallback--panelRadius);
+      }
+    }
+  }
+
+  .shadow-tweak {
+    .label {
+      flex: 1;
+      min-width: 3em;
+    }
+
+    .inset-control {
+      justify-content: flex-end;
+      label {
+        flex: 0
+      }
+    }
+
+    .blur-control,
+    .id-control,
+    .inset-control,
+    .spread-control {
+      display: flex;
+      align-items: baseline;
+      max-width: 100%;
+
+      &[disabled=disabled] *{
+        opacity: .5
+      }
+
+      .input-range {
+        flex: 1;
+        align-self: center;
+      }
+
+      .input-number {
+        width: 4em;
+        min-width: 4em;
+        flex: 0;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index f4f9331f..8e344eb1 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,5 +1,6 @@
 import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
 import ColorInput from '../color_input/color_input.vue'
+import ShadowControl from '../shadow_control/shadow_control.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
 import StyleSetter from '../../services/style_setter/style_setter.js'
@@ -51,6 +52,9 @@ export default {
       faintOpacityLocal: undefined,
       faintLinkColorLocal: undefined,
 
+      shadowSelected: undefined,
+      shadowsLocal: {},
+
       cRedColorLocal: '',
       cBlueColorLocal: '',
       cGreenColorLocal: '',
@@ -225,12 +229,23 @@ export default {
     previewRules () {
       if (!this.preview.colorRules) return ''
       return [this.preview.colorRules, this.preview.radiiRules, 'color: var(--text)'].join(';')
+    },
+    shadowsAvailable () {
+      return Object.keys(this.preview.theme.shadows)
+    },
+    currentShadow () {
+      const fallback = this.preview.theme.shadows[this.shadowSelected];
+      return fallback ? {
+        fallback,
+        value: this.shadowsLocal[this.shadowSelected]
+      } : undefined
     }
   },
   components: {
     ColorInput,
     OpacityInput,
     ContrastRatio,
+    ShadowControl,
     TabSwitcher
   },
   methods: {
@@ -340,6 +355,7 @@ export default {
       const colors = input.colors || input
       const radii = input.radii || input
       const opacity = input.opacity || input
+      const shadows = input.shadows || {}
 
       if (version === 0) {
         if (input.version) version = input.version
@@ -384,6 +400,8 @@ export default {
       this.tooltipRadiusLocal = radii.tooltipRadius || 2
       this.attachmentRadiusLocal = radii.attachmentRadius || 5
 
+      this.shadowsLocal = shadows
+
       Object.entries(opacity).forEach(([k, v]) => {
         if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
         this[k + 'OpacityLocal'] = v
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 5bc38318..0352f546 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -170,6 +170,17 @@
           <input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
         </div>
       </div>
+      <div label="Shadow Realm" class="shadow-container">
+        <div class="shadow-selector">
+          <select id="style-switcher" v-model="shadowSelected" class="style-switcher">
+            <option v-for="shadow in shadowsAvailable"
+                    :value="shadow">
+              {{shadow}}
+            </option>
+          </select>
+        </div>
+        <shadow-control v-if="currentShadow" :value="currentShadow.value" :fallback="currentShadow.fallback"/>
+      </div>
     </tab-switcher>
 
   <div class="apply-container">
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 907de586..3840e215 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -92,6 +92,19 @@ const setColors = (input, commit) => {
   commit('setOption', { name: 'colors', value: theme.colors })
 }
 
+const generateShadow = (input) => {
+  // >shad
+  return input.map((shad) => [
+    shad.x,
+    shad.y,
+    shad.blur,
+    shad.spread
+  ].map(_ => _ + 'px').concat([
+    rgb2rgba({...(hex2rgb(shad.color)), a: shad.alpha}),
+    shad.inset ? 'inset' : ''
+  ]).join(' ')).join(', ')
+}
+
 const generatePreset = (input) => {
   const radii = input.radii || {
     btnRadius: input.btnRadius,
@@ -102,6 +115,17 @@ const generatePreset = (input) => {
     tooltipRadius: input.tooltipRadius,
     attachmentRadius: input.attachmentRadius
   }
+  const shadows = {
+    panel: [{
+      x: 1,
+      y: 1,
+      blur: 4,
+      spread: 0,
+      color: '#000000',
+      alpha: 0.6
+    }],
+    ...(input.shadows || {})
+  }
   const colors = {}
   const opacity = Object.assign({
     alert: 0.5,
@@ -194,8 +218,10 @@ const generatePreset = (input) => {
   return {
     colorRules: Object.entries(htmlColors.complete).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
     radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';'),
+    shadowRules: Object.entries(shadows).filter(([k, v]) => v).map(([k, v]) => `--${k}-shadow: ${generateShadow(v)}`).join(';'),
     theme: {
       colors: htmlColors.solid,
+      shadows,
       opacity,
       radii
     }
@@ -245,7 +271,8 @@ const StyleSetter = {
   setPreset,
   setColors,
   getTextColor,
-  generatePreset
+  generatePreset,
+  generateShadow
 }
 
 export default StyleSetter
diff --git a/static/font/config.json b/static/font/config.json
index 1d1317d7..3abeffe9 100644
--- a/static/font/config.json
+++ b/static/font/config.json
@@ -1,5 +1,4 @@
 {
-  "name": "",
   "css_prefix_text": "icon-",
   "css_use_suffix": false,
   "hinting": true,
@@ -209,6 +208,12 @@
       "css": "plus-squared",
       "code": 61694,
       "src": "fontawesome"
+    },
+    {
+      "uid": "44e04715aecbca7f266a17d5a7863c68",
+      "css": "plus",
+      "code": 59413,
+      "src": "fontawesome"
     }
   ]
 }
\ No newline at end of file
diff --git a/static/font/css/fontello-codes.css b/static/font/css/fontello-codes.css
index 66a240cd..5cfcbf6a 100644
--- a/static/font/css/fontello-codes.css
+++ b/static/font/css/fontello-codes.css
@@ -20,6 +20,7 @@
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
 .icon-attention:before { content: '\e814'; } /* '' */
+.icon-plus:before { content: '\e815'; } /* '' */
 .icon-spin3:before { content: '\e832'; } /* '' */
 .icon-spin4:before { content: '\e834'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
diff --git a/static/font/css/fontello-embedded.css b/static/font/css/fontello-embedded.css
index 65875bde..58a57456 100644
--- a/static/font/css/fontello-embedded.css
+++ b/static/font/css/fontello-embedded.css
@@ -1,15 +1,15 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?92539127');
-  src: url('../font/fontello.eot?92539127#iefix') format('embedded-opentype'),
-       url('../font/fontello.svg?92539127#fontello') format('svg');
+  src: url('../font/fontello.eot?4112743');
+  src: url('../font/fontello.eot?4112743#iefix') format('embedded-opentype'),
+       url('../font/fontello.svg?4112743#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
 @font-face {
   font-family: 'fontello';
-  src: url('data:application/octet-stream;base64,d09GRgABAAAAACb0AA8AAAAAP1gAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABWAAAADsAAABUIIslek9TLzIAAAGUAAAAQwAAAFY+L1OAY21hcAAAAdgAAAEtAAADnpbZLnNjdnQgAAADCAAAABMAAAAgBv/+9GZwZ20AAAMcAAAFkAAAC3CKkZBZZ2FzcAAACKwAAAAIAAAACAAAABBnbHlmAAAItAAAGikAAChCZqyvoGhlYWQAACLgAAAAMgAAADYTsqAaaGhlYQAAIxQAAAAgAAAAJAfJA/5obXR4AAAjNAAAAFEAAACMfv7/5mxvY2EAACOIAAAASAAAAEiiuKq/bWF4cAAAI9AAAAAgAAAAIAF4DaZuYW1lAAAj8AAAAXcAAALNzJ0eIHBvc3QAACVoAAABEAAAAYnL7NrPcHJlcAAAJngAAAB6AAAAhuVBK7x4nGNgZGBg4GIwYLBjYHJx8wlh4MtJLMljkGJgYYAAkDwymzEnMz2RgQPGA8qxgGkOIGaDiAIAJjsFSAB4nGNgZF7IOIGBlYGBqYppDwMDQw+EZnzAYMjIBBRlYGVmwAoC0lxTGBxeMHwyYY78X8gQxZzOMA8ozAiSAwD6DAw3AHic5ZI5TgNBEEXfYGM2sxmzLwbHRGhiR4iT+Dz2NTgIiW/hZKQKux0Q2vyeqozlAnTrjdTVUnVp/gO2gY54Fl2oPqkoK6latfUO+229y4fOd5yo0rehvVid5mmRlqlJ6zzIkzzNzarebMBob2c/3/66KnV/bffbt11ut/RyVxP32GGXPc11QJ9DjjjWVKcMOGPIORdccsU1N9yq4z0PjHjkibGa9P54/7+sfvlU73Eal7yckrgF+ttYUAyxoFhiQbHHAqWCBcoHC5QUFigzLChWWaAcsaBMZ4GyxQKljAXKGwuUPBbIASyQDVggL7BAhmCBXJGpjqzBakf+kGaOTCLNHTlFWjiyi7R05BmpcWQcae3IPfLAkYXkiSMfyVNHZpIbR46yqh3GX+4Qg9oAAAB4nGNgQAMSEMic/j8JhAETDgP3AHicrVZpd9NGFB15SZyELCULLWphxMRpsEYmbMGACUGyYyBdnK2VoIsUO+m+8Ynf4F/zZNpz6Dd+Wu8bLySQtOdwmpOjd+fN1czbZRJaktgL65GUmy/F1NYmjew8CemGTctRfCg7eyFlisnfBVEQrZbatx2HREQiULWusEQQ+x5ZmmR86FFGy7akV03KLT3pLlvjQb1V334aOsqxO6GkZjN0aD2yJVUYVaJIpj1S0qZlqPorSSu8v8LMV81QwohOImm8GcbQSN4bZ7TKaDW24yiKbLLcKFIkmuFBFHmU1RLn5IoJDMoHzZDyyqcR5cP8iKzYo5xWsEu20/y+L3mndzk/sV9vUbbkQB/Ijuzg7HQlX4RbW2HctJPtKFQRdtd3QmzZ7FT/Zo/ymkYDtysyvdCMYKl8hRArP6HM/iFZLZxP+ZJHo1qykRNB62VO7Es+gdbjiClxzRhZ0N3RCRHU/ZIzDPaYPh788d4plgsTAngcy3pHJZwIEylhczRJ2jByYCVliyqp9a6YOOV1WsRbwn7t2tGXzmjjUHdiPFsPHVs5UcnxaFKnmUyd2knNoykNopR0JnjMrwMoP6JJXm1jNYmVR9M4ZsaERCICLdxLU0EsO7GkKQTNoxm9uRumuXYtWqTJA/Xco/f05la4udNT2g70s0Z/VqdiOtgL0+lp5C/xadrlIkXp+ukZfkziQdYCMpEtNsOUgwdv/Q7Sy9eWHIXXBtju7fMrqH3WRPCkAfsb0B5P1SkJTIWYVYhWQGKta1mWydWsFqnI1HdDmla+rNMEinIcF8e+jHH9XzMzlpgSvt+J07MjLj1z7UsI0xx8m3U9mtepxXIBcWZ5TqdZlu/rNMfyA53mWZ7X6QhLW6ejLD/UaYHlRzodY3lBC5p038GQizDkAg6QMISlA0NYXoIhLBUMYbkIQ1gWYQjLJRjC8mMYwnIZhrC8rGXV1FNJ49qZWAZsQmBijh65zEXlaiq5VEK7aFRqQ54SbpVUFM+qf2WgXjzyhjmwFkiXyJpfMc6Vj0bl+NYVLW8aO1fAsepvH472OfFS1ouFPwX/1dZUJb1izcOTq/Abhp5sJ6o2qXh0TZfPVT26/l9UVFgL9BtIhVgoyrJscGcihI86nYZqoJVDzGzMPLTrdcuan8P9NzFCFlD9+DcUGgvcg05ZSVnt4KzV19uy3DuDcjgTLEkxN/P6VvgiI7PSfpFZyp6PfB5wBYxKZdhqA60VvNknMQ+Z3iTPBHFbUTZI2tjOBIkNHPOAefOdBCZh6qoN5E7hhg34BWFuwXknXKJ6oyyH7kXs8yik/Fun4kT2qGiMwLPZG2Gv70LKb3EMJDT5pX4MVBWhqRg1FdA0Um6oBl/G2bptQsYO9CMqdsOyrOLDxxb3lZJtGYR8pIjVo6Of1l6iTqrcfmYUl++dvgXBIDUxf3vfdHGQyrtayTJHbQNTtxqVU9eaQ+NVh+rmUfW94+wTOWuabronHnpf06rbwcVcLLD2bQ7SUiYX1PVhhQ2iy8WlUOplNEnvuAcYFhjQ71CKjf+r+th8nitVhdFxJN9O1LfR52AM/A/Yf0f1A9D3Y+hyDS7P95oTn2704WyZrqIX66foNzBrrblZugbc0HQD4iFHrY64yg18pwZxeqS5HOkh4GPdFeIBwCaAxeAT3bWM5lMAo/mMOT7A58xh0GQOgy3mMNhmzhrADnMY7DKHwR5zGHzBnHWAL5nDIGQOg4g5DJ4wJwB4yhwGXzGHwdfMYfANc+4DfMscBjFzGCTMYbCv6dYwzC1e0F2gtkFVoANTT1jcw+JQU2XI/o4Xhv29Qcz+wSCm/qjp9pD6Ey8M9WeDmPqLQUz9VdOdIfU3Xhjq7wYx9Q+DmPpMvxjLZQa/jHyXCgeUXWw+5++J9w/bxUC5AAEAAf//AA94nMV6C3Bc13ne+c+573v37uvuvQtgsVjsYnfxEggu9kGRFLgEH6BEiARJiAIoioYokooIkbAU2WJkUVEtRiPViqg4iuoZT+RoKmvS2nIV0nWYuLYzjmSndDsj1zGlcdqZxs54KLtlPa3SdFhy2e/cBUDq1Uwy0ymwuHvvPe///P/3/99/wIixa/+T/yX/bdbHss2ufEdMVxinSUGc8UVC8REv43mKmh4qelHS8qtIl5dSdQOV5aVe6aGGvPgoDnz+l9Gp2HDslVdwmYrJ79j152j0lVeij/jy5stfjn64YnREVmAK5nROvCxqzGBxNsCabGtzUw3jmoxjVpPM1MxFgzRdW2S60BfRgCszKglMlws2zxSFz+IVn7plfWGskK8Ub04nLLV7qFgtuTxL9cbyd8rTCr35UrlWrQdjWVpHlXpjrOILbYhQpBdkES7tVfr8vJf1eLoz/dteLsH9THprzr/ygyBLOf+SUy+cztcjl/zcN8z0aS96OurR6SAZv2xlrcuJPtfniVxC6XSWb5456+dyPi7U09/fk6Xd/mW08N3Lw2hiXY4z/Mi9+SHkMMl6WHezMxG1FKHKzWEre9PtBUINhgiyT6Y8l8LdKdWqjWRZXovhzqi+eDl6ftRJOf/7suM7NPoDt4fSj9s55ySlc/QrJ/pm613HjpF+6pSesBSDgjejTkrtbwVBqx8jrszDxG6Um32ZDs+NmIauqYKc90+o2Bf4iZhQvSFqrCJohN4Iku3ZFfIfMzv+mX/5y6P3/5evDPzoRy3MM7A+ep4Dr+Z//OP8q79cXKQz7SlnPmbC+OHXrkKHPiESTGceG2r2MwGBQjkUIs5pBl8klYT4FGOJuGOjnh5X1dRQMZ6XykGQZn6Ej1MF96/teXaazzzN6aHvXfyL49qj/+a9P328xud3P/vKs7tp9FNvPPzwG7+QF8Yw+LXz4iI/B1l1snG2md3J7mzOVLs4U/ZoUN/dmzDm9MRAGQqskTLJVEVdhPygunSMkYbPAtMEPgtMiOPSGJQZaDSbxQ2bmtqeHOno87p1tXOo2BihRrWh6T5VS3peS3l+pQ5VHoMWeymNw1wL+VDSI9JWG+M0VgkaKPahzLqfhIYn/cDTNd2lAkobpXIjCxum+tDoGso/cccBOhqztx6K+bHNo3bs/LpfrMuolr7Z7Jh+qmLbe6/8s0qlR7WEa/fZZKZmb/195bLtl2f+42MDj/zFlo13F2oHc/YndxaO3rJp7cZTz9N9ULFDW+xYzB7dHPuUQve39t1fMcuapQ/2nbg9Pph48gtW3dQ0TyO1dXXHE12U7jiQTPbdNH/0NuvU/YeaG/oO1pMs1Mdryih/kvWyTWyiuSFPiiYhC+qlk3bMJE3RNWXBAIbpxPX5G4SokpTiRNPvLaZ7/VR/MsQFTysDBlbRCI3FC/kRWjJ4CQGpXnm3jH2lan0d1Xrbd41eKckspeIQKT9vGVffVTUO5KQF2LJxFop7xvTdBdpoqnMKHTbOODn7rIE3rW/LN5bB00rYYMH1E7pDXCjk0E6/y7rgOBesjEcXtAfUn0asC5HIBavLv6AvqBEL1VRuiNYZn7VlcU7sg54b7Cjb0pw4PDe1UWHKOosTq/Z3xRRBoq1k0DamLEpYWYQl0CITXEDz+JH9d+3Zdeu2ocF8LpnQVX8I2pR3CbpUBAhi3bof+B50pIxlA3R1oCOsuFwqw5pxDTWrEUpPAilk1ygtq1sPHvALYJU6B+WrBEud6aHo+LrdJ3bzvQ/vpYyh/5plJ/s1NTod0fXbOzpNXYk9ZjixrmCnFtO2+opq9FtR44hukKX+muEGxXZd4/Z0p2mI+GOQYDQT7FSj+jZPUcx2ZYsOr5uZ+fTMzAlZHsumuiqaq6WmSV0fMaYyMUu/z3TWq1ozq7qaU4lmuqLk6GHdjs7cTbqje9M3VLXXqeqmzFLVzhjgL9wDxsQCP8/K8FXQRw8qAFDUuMo19RhTBVdhzYpgQmHHpKVrxOflg5iBjUvLFmzKL3QUB4tlXe2CPvpRgojgemrxaii9VBC+Khfymh73/GCskuXkQdvzpVuoIC/QxzGI3w/Ip8PAGDKMM5sOHNh0xrAk1snHYpXqfV/XOHBIs1s/tDP+ZdeHz/EzNq2yazyhuiYXBzbR05sOWIZtahAulKF1Ag0VbtCwa7fesrzoy757ARr+MpyZiRfLvuqS+AYfBdp2NP0IMUgAUmDQMxlDBAnpp2CZ+TK1w4bAXDIy8ZXWQXjJ1kHbvhvf1E/9dsbZb9OLrXttm37fzlr7bbv1Dl7b++0MxrrWuvYZcU7cx1aznmZGjk0zGI/NQueJTREbHGCrabX0QkG+DJCkeiCBTZcSLNXxiFst8BvyFrqKhyxfevvekc3blL30q+kDw1udzulWqX8+l9WGaSpd7Wx9fTjtOGmfflLJra/XW4kJ5dBTt9GvZFFs929t2/pnB9Cw09k6PC8bWrn0oUHa0VlNo2GnwRXZ8NMxt9JKTD11UGnSpfSIbCjlp1y7du2csiq04yj8/Sp2R3N3t8dJRLEmN+KYCmeZFIIaRXpbGfEcY0A7QZqYlxLA0oFzqhrinDorLX4qHhsZKhU6glhPvCeZTBhhpOBK6IJPS/XWGgEVe9sKBSyrl+PVUhAH6AELG/E2vtHh8X3j+PD1Vy6d2UfdlL3yJGzK0cRJmIi1q1q88mRfnapFcbJY5embxvnE3gllbevy5YWzc9T9MkBxn6xo8FcNK3F1X6iC/FX5xWys+cFwze0Vb2A72ScATr/JTrMvsX/F3mh2PN/kpvH0E/M5RVVOrOGCT48yAQif3P567/Rss8FSCYcbZsqYT5IZI0U1lfl4hMM+uUTJ+SgJi0K/b+vQRm+WeV7Eu7WrOf4Pa+l5NLPSA3lTc83S177y6j9/6YsvvvDcs0+devyxT//68YUjhw7ctXdmx/ZarVbCb23Mh28JavDNsNpu8nwZXwIiS8DP8BmxZvhcXiqHVdcJm4CYVMNG+GPYFPpA++VnPdV+FqivL9UPUD9Y6l+Wy/4bS/3L52Dp+cb2jXg7Bl7e8AtedJsEBVzoI2/5Ot9t7Qlf0WtR7+qb14tE3HcnwzAW1x+/r9rbN5R83HXb+5Sp7/qwf3N9Gj+/oU3rHsrKgtZPceW/MxlFeWwS91c/d70tfZO6w4LWz2Sbf/vRXf3N9cb3XU0Uq9UivxTqqMS17/OHxXbgWtD0zBDX2DKsZRIc/tJcCg0a5jK0AdX4UQBaxr4bCNbfemcJ2l6y6JOteyzrbpTQgMQ5WUFWXMbQ7/MvLI9F7x8rCMKxuB+GIhJFG0sAyp9rvU0D7V4limKYrHW3xf+o9U7r7fDWoi+Fw4fTkOPA43yD397GapXeH8IHXojVRendV5a2tCrxlf2AY/T7ztLaXpIrecl+aD/GGMBolizHBKylRSHqvvageEPsYw7i4Qn2btNhCMtosr8Lgc/W7a+7MOMhnTAJUg+HMHYvGhGYheRxxiwzDGcbohRtlmlaRLu1q235w+9rwhf+vjZ9aDPwcW04XLW2f6WpAnxY9cG6Bvy3ocxfb6NpfGZpDK5Nzc3NNZ2efKLfjxeSCROGr1bhlhvVvLTDSrG3FK+OcDCLVEz1EEB5kghJ/z6uNGB4CNLHyU95OtyUlxV01ewdpcTafrP1LL/we53V3Q/srnbyVwe7LyOUudw9mBkZ7UvwU/erueGcevSz5OdHR+eM0V7THFhL/+IPaSCzfk0+v2Z9pvX2H3YPIgBaN9idrswcePr2mc/HLDvI8nzKtmKfn9nx1Pzu6nIMw58M+VIPG2yWEbRgo7D0Y1gkaAhR6FlolpFCU4VksZ6MaSAhyV4AikuBuuQ44ETApRGIVHw9hbj4LHVjykRv5fyr74ZcOf7Cv3uRJ3D71QfWzfDpW15ufdvH+xRNgA0/cOSFF448kGUi5G9zmI9D36K/449sf92cnt24nn2LfZOdg3t4kT3NNKlecBaYJe5+wn6E6GqO7YKajbMxlmMdzMJyOL1EX6AX6Vn6HD1Kn6LDdC9g/a/Zf4ZKaiAIe+h2kvTQYBq9R39FP6Qf0J/Rt2kNjeEdyfdsEipkYfxNS6M/DQ8seea3UC5w9/9+DjqbxJoJYxHb2vX/TxBzc+FONGuMC11w/RjTNaFLzmoIzYCdkDBoAch1HFiJ4HYGX0zMqgpH+DvVFmNzrULwsao4zLiucn0BfajtPtR2H+r1PlS13Ye6F2tXb+v6R448N7exI4wU36EL9Cf0x3Qn7WXfZ2+yf82+zv6IfY39Bvs0ZKRBjkAo/FkYzhuS9H85EyBD8so41cB26kFJEp0NpJVqnl4tabURReKkzHB4g+TltbxeL5cKiC7HRjhCULwGVGtZ3AC+JQfS8rgpSf6ky79KSR+nguy07EsKBfsZ86vlSlhBC2RlDFBGt+i1XJLPWQKbAu/Pa74O7uVLNw9C1qgGZU2vyK6CRoDGuq9jBmiq6VnuNXw9JGF6uaT5Y7KfHkyoofWILA802V8NtRAbl0d4TTI4xMZjmHclq/QIv4Je0biRD4kv0KpeQy+4yNWX6kGljuViWZ6WKtSlM8R7Pa+7ooQpyOeynBcCjyrW4dfREybsN7Ic0qk3fKDCOIFb1kZkli6URgU18pgN6KQvrw2/XhqnVKNekHOUAq7UIBABEIWrqoOHyk+UsLIU5DWCXYtSqV6Scq9rKZdSIAQhGwCTDTzNp9ce/t5Dy4kdSoJaE1dEPJVEmMsNTWDLFMVSNYUMAKIQCn400hA8qmDv4NeGQ2pGERwcC4Nx3UQV8CU0tLiiRoTw3KRigPMRV01OSVNTuKpZcCdQfqGZ6A3RpypAExVydTuqxAR6VQwy5Bc6Fgj7E6pwHAzPnY4uoalqUhW2ErExkKYYiqnsqiiSbgpKW5iDqsh5Sh5K3NL1hKKb0n9xV6a/XNAIHjUEuhYqKXDd6EF1dC4MYeq+pqmGEVM89IPOhSsUEG4jbnH8kMrxxIUjwAelqGCINsbhhidANLlctwop4UNKWpgCExAR7kpxKCjRMAfISVF0Q9UdBQ8gw2o4EUfhCTTnkoRyy4CoNE1XTce6/9enyaEI2qckbEhBqw5sHj8kZ25hhzhEjUqYiGJHiZsWicRSUg6X1n8ig8t0myFUG9XQBTiJHsqVuOaoGuQKFyfCF7jnhhQrYeXYa10YuqUrqqY6UjWwNMeEUFQsQcS5cA35XpjYVqGRq1joUsWyLEXXdTJVQzcgJCFlCXWwhHBlsaqATlhGlAsJZi4EoGj4xSRu2qnIXVe0qIU5gMe5pmdz0jo5vKyigdUKEYOMFUM1FLLTEdXBqhXHcBWXLNsDZ1chcuxFQliKYsqclBUKmMeMhNRfzMPS3XArIe+YGpVYzG0sGo9K2jVd1ZQpNYgaQoeZqDwKHSGZqhJgkQo3IEiXW5Yqc1a2qUrVwB5gzQoMAiLQCMtDQ7nvuLQiqTvkmmVSUtoBRM0tAaqlQrqgXLKO1CfZj5ox4qZrOlyJ6WF+68vitOgDIgcs3+xBWMzjqoxNJmX2dnElPu7y82HY6mnlPGCiLCMQRKy6TEsheqW3vvaZXZs376bZR2fppVxv67ve7jU0njvww8dep/7yP919y+ws/W3uQK713caMhwL4jmt/ixjkf4g58NNe+NFDTacL+83NMC6abAeV3Qyyg1IeW04wY0IQ6374LUdFIJlnEO4iXBamulID2ywTFsqsrAoyaQZryvAWMp4q3sAPJV8rJ6tl+ULXUkGb0QnyZf5MxlqlBuCyAkpm6Q/oVniBqer6o3CkpqPfZzgGfdVLmfnElVcTeTPl0WtmvpTfd9SwLAMXct4mgtoBQa7B5Wo8duVSoRBPgAoVCiIR97zlXPqD4peQQ5lNs9ebbp8PVORTE1WJIEtUvMRCdRHHdFgNlGJBntXMavC4CMXbGQk1oi6H4oUP1VZkxmL/9UYcshv4YC2tnejgH8p0IPoOBvqJTW5Zvap/emDaSzgWK1PZkAcR0vFpuuf3kHQVMh+JuDTQNZmSHCeZt4SDKJconwqzmzJnXm6EjsQl6eY2EDzeWEU2bFTxmi49+eCxTVswA2UmqdbG9tx5787nqmtN7vyd7VnKWp4wN27et5/GwsK9905v21JbZ3D7fy2VWs3N++4+8tkHj0+EfYi55vjC8X9iwDUkDu7ZtWr1+JqbzaSoCNOP/cywtfVbS/0tpV2Uy364TLb+rGFwau/VtWsHxS+wVz1sI7u1KcEIbGs10ea25JPXzxrouJCSZpB0VMjQcXHJoujIXDNCrDfnJVkP9SjLQlwNCcjQIfCl68ySzPvWpWOXwguFrPntckhqNZ7KYXxTl5VK9N/v3DWzee8DR+87unOit1crup2xsbiweIGKpecP3NVS01HpWPt4X2nbXZ955DdO3iMrL6ByTi0ampsQc93Zm7ekvGxu58TePWd3DXTFKC6i2r4/n7v7+VKxdSmmaEb4tO2uvny6Y9cNdVO9boKt5Govhrq8gZ1sJvthAHEYdGMEAN0LHFKWDLuPwUsDsFfyt5CQEuZtJavdD2bpgFk2hxEsa4v/t7o35HjnmtbarmKtXhyTaV5aOn6sLaVeYPLyuZ3g7a3UZU5X5n6T8fBkb4WKl0vV+hjqi8SBTa1RmeOlZ6T1tx4Js2v0VrFqGX2GdcHP2AdbL6gxpQnf98BB23epO+rRnjAvTG9NHKCwXrXYGg1bngEs0E9kooQ7aKhpTdUNG2b862cNkpOlWT+rNFcl4KhZmDpoa5SCOorEN4QvEt/ELINjnKo1vI4xVe0YkrmtMhbYg7XIcLjSoLZhJZfI47Ik+Hkv2novnUxMty7Y9s0yxzC4y4pqRur0gU1X35XT58GmA2AsDtZzU0xWy1o3Y/aD07awqHb1IhY3v5Gn5Rdr5yFw2cd/sJRrbDSr/aSoBmt7EhXsXg3ZvYxd5m9IKcu0zJRM55XGQnhOLdHcWnumItU+OwqPkJeeCzc+z3mxK/8tTDSJeJhj+tinhRvyURRbyWCRR67MS7lhimrZxs+Jd/l58Lo17KbmoDwXF9iH9oFO2ym+b/6Arb61Y4o821nJ70o7zXI4FGnE+MV7hMguB4sIz3Ik2xiRbjRUtYvV4pXzfXXq6Dk/lStt7uKZif6eT/xxLl0f+A/VmpPPRriTjWcjee135xOF9TQyJOqo/u9bW9o6+c0u/5lGujNDnZlg82P+d4anuz9fKJsJhGFWwsiIwxNusLtvaO1SLgL+5iLWF7Bb2MGmU5XgVrJl5LfkbQI4ADj+UNmYDEuwdSIiYI9ZKYVP3lAsT3vZymHvXDNObN3avnx3VyLGAgq0ENzgT6V/AIKBc0idHOcj4REwnIHEtfA/AUAiQs43zjfIoKI6Trks0XsPfe9hmr51NBrpvGNLOlfK45mf+C498dTPny4PHv/drj5huAirEDMrEU/3Ynp09hA99XOK/fwp/uSOU1PjDw1kamMjfetTQt1x6gundrR+es8r88o9JUNxEGogFIyqrm9kMsnByudnUDT/yo22WEBksrE5Lk9cekj6Y3kIAjgXx1QZv0rfqkNIusyNwdFLpylzVoo2VasVxvxCX8FQM0PttPJKrriwnEBezhKDCX6klZ5tK+yZUHXPtB/Ouv5z7zPTjVKNz4ZVzrZ1+qxU6LMebfigoVK4rouixobYQLNUwoqkYitQbIRKizIltRimKmXIVwiStwQSWIqe7vL2/xZAlWvVETUE15UsqUxF5QJo8SRZiNtBZUh4+TXje/c2Tno5s/Uz26ZuO5PmJ+m5fdmLd39JScQUy0H0IEo9a/Y1R7MJ7bTr25SVadSs5UVP//X2dh6VPyn2YQ+OtJ1GDoqHgIQdQzTMSGXtfARCHwmFIgwIix9dRaCO9BQyoBEIaJpJYrmerrSXjLmmxgpU0KWmInD5YKIN3NxrH8lWS3ktSPHbwzTbjdk2L9rn+mEa7qvZ4MZ029n7XuDP3y83Q+YIz7bztefEyfAcKs3uYDua228jQ+/pkokl4MnqOOxJmWS6oS8yQxiLGiJasXSqDPL0yRsMTpWR/tSq4VTfhlKtnRRtVCUfz1JblwrLq6j4qqf7KV/3w2yFLJFBRTksH+dAJ1zGxVglq4Cyw1ix22h02u+GTnV7+7zYH4Ta9QdRn7/QY1KHaZq+muu7bVtxb2VwSxKFXtfaTClhuaAkWiwV7RhMewb4hwPyDgv74lBTntmH/dFw64thb3Q4xODRQkdiMN9T6EmNl4co4UbTy2XNwuqElffSfjrvO4nOdC4RSQ37nuK4WpO1/xfkwTDWiDGPFeF1bmZ/1QzGBrhuINLg3amIg7BXTCqkylS4BLabNAe0HuRJJ5l5VXWuLqAjXWULJum6MWuRTG4r0L0IW46mhz++kax4/IaWOjSw8vdUR0XUn5H19b1oa+i3Ib7OxeOMNWqV1TcN9Zf78j3Zro64F/eSCawu2oioqbZvWdHOJBxHvBCnlRfyb6wSFFOAmTCuUVfu6BnfXTqh+ZwSoS89Fx4yyUd8/mtEaY2/aRkvg6880v7mr7ZmUNL6Tnufuumi0zpBT7ec9iGPSxvx91XntZMnJdEJr0tnEeeUEyIJ3R5mO9kjzYeHi9zScz0uKH8lyRVDTDLSgTDg+4suMStiscgxZkd4xObH4KtYxLYi82DGwFaDi3kGymzMMMNQZk2Zipgidvv227Zt2bxxQ31s9aqB/r58pitIJWKWCZM3yIiG7qY0TlmuqWMSmLzr/2wWnuSHkcVYrW0WQXhKmGqHidVxNajAqCshgwmA0Sl6Zu5x/ug3Tmin6M/fCM9Z33C0BcN6MzyjhbAWcNM6PNh9unRzK71pt+IksqW1vbY9PHNoZti2bx092T1Ihx9//Qn+2NcfvfXDbdudtr7TPUy/ldmxKbtmor4m38mtPH6s+mA3+z+xaNdOAAAAeJxjYGRgYADi9E99a+L5bb4ycDO/AIow3BDWM4PR/7/+T2KpYE4HcjkYmECiAFpcDA4AAHicY2BkYGCO/F/IwMBS9v/r/88sFQxAERSgDACjOwbOeJxjfsHAwCwIxAuQcOT/v8xAcRZ9EBsqBlK3+v8/Fv3//0GY6RQDAwiDxYGYqQmqD6z2/1cg/sv88v9/sHwkFL9A4sP0QM1mKWNgAADDsCg9AAAAAAAAAABKAM4BEgFsAagCWgLgA6IEJARaBMQFPgaQBsYG+gcwCAQITAxQDI4NEg3oDngPFg90D9oQShDcEUgRnhIIEq4TdhQhAAEAAAAjAfgACwAAAAAAAgAsADwAcwAAAKoLcAAAAAB4nHWQ3WrCMBiG38yfbQrb2GCny9FQxuoPDEQQBIeebCcyPB211rZSG0mj4G3sHnYxu4ldy17bOIayljTP9+TLl68BcI1vCOTPE0fOAmeMcj7BKXqWC/TPlovkF8slVPFmuUz/brmCBwSWq7jBByuI4jmjBT4tC1yJS8snuBB3lgv0j5aL5J7lEm7Fq+UyvWe5golILVdxL74GarXVURAaWRvUZbvZ6sjpViqqKHFj6a5NqHQq+3KuEuPHsXI8tdzz2A/Wsav34X6e+DqNVCJbTnOvRn7ia9f4s131dBO0jZnLuVZLObQZcqXVwveMExqz6jYaf8/DAAorbKER8apCGEjUaOuc22iihQ5pygzJzDwrQgIXMY2LNXeE2UrKuM8xZ5TQ+syIyQ48fpdHfkwKuD9mFX20ehhPSLszosxL9uWwu8OsESnJMt3Mzn57T7HhaW1aw127LnXWlcTwoIbkfezWFjQevZPdiqHtosH3n//7AelzhFMAeJxtTsdWwzAQ9CQusUnovUO46gQ/JMsbW0SWhAohf0/sPG7MYXdn20wySfaokv+xxARTpMiQo8AMJSocYI4FDnGEY5zgFGc4xwUucYVr3OAWd7jHAx7xhGe84BVLvCW54FqQyqNVhjepD9xVQ2DU27DNefMZfShoS8ysVoWjsCEKU2HaXJnWxFA2ZqOZsaRzHgIXXWGlCNFR9i0bMpWTbRfGealota+KaMec1qRUqoxYZ60yNWW1i74rd39IB2l05q3U72P8mCmp14x+wvyvYFyFtCcdZz2XamALYfpdI+y9z62KnvmvyB01mSOrtotBa5Qe10MX+9qznZsdq2qpjYiKO19GT44N50nyC7iuahR4nGPw3sFwIihiIyNjX+QGxp0cDBwMyQUbGVidNjEwMmiBGJu5mBg5ICw+BjCLzWkX0wGgNCeQze60i8EBwmZmcNmowtgRGLHBoSNiI3OKy0Y1EG8XRwMDI4tDR3JIBEhJJBBs5mFi5NHawfi/dQNL70YmBhcADHYj9AAA') format('woff'),
-       url('data:application/octet-stream;base64,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') format('truetype');
+  src: url('data:application/octet-stream;base64,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') format('woff'),
+       url('data:application/octet-stream;base64,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') format('truetype');
 }
 /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
 /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
@@ -17,7 +17,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?92539127#fontello') format('svg');
+    src: url('../font/fontello.svg?4112743#fontello') format('svg');
   }
 }
 */
@@ -73,6 +73,7 @@
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
 .icon-attention:before { content: '\e814'; } /* '' */
+.icon-plus:before { content: '\e815'; } /* '' */
 .icon-spin3:before { content: '\e832'; } /* '' */
 .icon-spin4:before { content: '\e834'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
diff --git a/static/font/css/fontello-ie7-codes.css b/static/font/css/fontello-ie7-codes.css
index 689c8e43..fa7c1002 100644
--- a/static/font/css/fontello-ie7-codes.css
+++ b/static/font/css/fontello-ie7-codes.css
@@ -20,6 +20,7 @@
 .icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
 .icon-brush { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
 .icon-attention { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe814;&nbsp;'); }
+.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe815;&nbsp;'); }
 .icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe832;&nbsp;'); }
 .icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe834;&nbsp;'); }
 .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
diff --git a/static/font/css/fontello-ie7.css b/static/font/css/fontello-ie7.css
index 23ecfa3c..b37a63cd 100644
--- a/static/font/css/fontello-ie7.css
+++ b/static/font/css/fontello-ie7.css
@@ -31,6 +31,7 @@
 .icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
 .icon-brush { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
 .icon-attention { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe814;&nbsp;'); }
+.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe815;&nbsp;'); }
 .icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe832;&nbsp;'); }
 .icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe834;&nbsp;'); }
 .icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
diff --git a/static/font/css/fontello.css b/static/font/css/fontello.css
index 0181fa62..38caec46 100644
--- a/static/font/css/fontello.css
+++ b/static/font/css/fontello.css
@@ -1,11 +1,11 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?13201279');
-  src: url('../font/fontello.eot?13201279#iefix') format('embedded-opentype'),
-       url('../font/fontello.woff2?13201279') format('woff2'),
-       url('../font/fontello.woff?13201279') format('woff'),
-       url('../font/fontello.ttf?13201279') format('truetype'),
-       url('../font/fontello.svg?13201279#fontello') format('svg');
+  src: url('../font/fontello.eot?3996201');
+  src: url('../font/fontello.eot?3996201#iefix') format('embedded-opentype'),
+       url('../font/fontello.woff2?3996201') format('woff2'),
+       url('../font/fontello.woff?3996201') format('woff'),
+       url('../font/fontello.ttf?3996201') format('truetype'),
+       url('../font/fontello.svg?3996201#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
@@ -15,7 +15,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?13201279#fontello') format('svg');
+    src: url('../font/fontello.svg?3996201#fontello') format('svg');
   }
 }
 */
@@ -76,6 +76,7 @@
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
 .icon-attention:before { content: '\e814'; } /* '' */
+.icon-plus:before { content: '\e815'; } /* '' */
 .icon-spin3:before { content: '\e832'; } /* '' */
 .icon-spin4:before { content: '\e834'; } /* '' */
 .icon-link-ext:before { content: '\f08e'; } /* '' */
diff --git a/static/font/demo.html b/static/font/demo.html
index 6e4d3eb0..cb1aa970 100644
--- a/static/font/demo.html
+++ b/static/font/demo.html
@@ -229,11 +229,11 @@ body {
 }
 @font-face {
       font-family: 'fontello';
-      src: url('./font/fontello.eot?97354950');
-      src: url('./font/fontello.eot?97354950#iefix') format('embedded-opentype'),
-           url('./font/fontello.woff?97354950') format('woff'),
-           url('./font/fontello.ttf?97354950') format('truetype'),
-           url('./font/fontello.svg?97354950#fontello') format('svg');
+      src: url('./font/fontello.eot?15755415');
+      src: url('./font/fontello.eot?15755415#iefix') format('embedded-opentype'),
+           url('./font/fontello.woff?15755415') format('woff'),
+           url('./font/fontello.ttf?15755415') format('truetype'),
+           url('./font/fontello.svg?15755415#fontello') format('svg');
       font-weight: normal;
       font-style: normal;
     }
@@ -329,23 +329,24 @@ body {
       </div>
       <div class="row">
         <div class="the-icons span3" title="Code: 0xe814"><i class="demo-icon icon-attention">&#xe814;</i> <span class="i-name">icon-attention</span><span class="i-code">0xe814</span></div>
+        <div class="the-icons span3" title="Code: 0xe815"><i class="demo-icon icon-plus">&#xe815;</i> <span class="i-name">icon-plus</span><span class="i-code">0xe815</span></div>
         <div class="the-icons span3" title="Code: 0xe832"><i class="demo-icon icon-spin3 animate-spin">&#xe832;</i> <span class="i-name">icon-spin3</span><span class="i-code">0xe832</span></div>
         <div class="the-icons span3" title="Code: 0xe834"><i class="demo-icon icon-spin4 animate-spin">&#xe834;</i> <span class="i-name">icon-spin4</span><span class="i-code">0xe834</span></div>
-        <div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-link-ext">&#xf08e;</i> <span class="i-name">icon-link-ext</span><span class="i-code">0xf08e</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-link-ext">&#xf08e;</i> <span class="i-name">icon-link-ext</span><span class="i-code">0xf08e</span></div>
         <div class="the-icons span3" title="Code: 0xf08f"><i class="demo-icon icon-link-ext-alt">&#xf08f;</i> <span class="i-name">icon-link-ext-alt</span><span class="i-code">0xf08f</span></div>
         <div class="the-icons span3" title="Code: 0xf0c9"><i class="demo-icon icon-menu">&#xf0c9;</i> <span class="i-name">icon-menu</span><span class="i-code">0xf0c9</span></div>
         <div class="the-icons span3" title="Code: 0xf0e0"><i class="demo-icon icon-mail-alt">&#xf0e0;</i> <span class="i-name">icon-mail-alt</span><span class="i-code">0xf0e0</span></div>
-        <div class="the-icons span3" title="Code: 0xf0e5"><i class="demo-icon icon-comment-empty">&#xf0e5;</i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xf0e5</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf0e5"><i class="demo-icon icon-comment-empty">&#xf0e5;</i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xf0e5</span></div>
         <div class="the-icons span3" title="Code: 0xf0fe"><i class="demo-icon icon-plus-squared">&#xf0fe;</i> <span class="i-name">icon-plus-squared</span><span class="i-code">0xf0fe</span></div>
         <div class="the-icons span3" title="Code: 0xf112"><i class="demo-icon icon-reply">&#xf112;</i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
         <div class="the-icons span3" title="Code: 0xf13e"><i class="demo-icon icon-lock-open-alt">&#xf13e;</i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xf13e</span></div>
-        <div class="the-icons span3" title="Code: 0xf164"><i class="demo-icon icon-thumbs-up-alt">&#xf164;</i> <span class="i-name">icon-thumbs-up-alt</span><span class="i-code">0xf164</span></div>
       </div>
       <div class="row">
+        <div class="the-icons span3" title="Code: 0xf164"><i class="demo-icon icon-thumbs-up-alt">&#xf164;</i> <span class="i-name">icon-thumbs-up-alt</span><span class="i-code">0xf164</span></div>
         <div class="the-icons span3" title="Code: 0xf1e5"><i class="demo-icon icon-binoculars">&#xf1e5;</i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
         <div class="the-icons span3" title="Code: 0xf234"><i class="demo-icon icon-user-plus">&#xf234;</i> <span class="i-name">icon-user-plus</span><span class="i-code">0xf234</span></div>
       </div>
diff --git a/static/font/font/fontello.eot b/static/font/font/fontello.eot
index a7b690a7d7864f9799f11e78da248e8dea1a1fbc..7dfef262db9c104276310ad6c8aeeb45ad3f33a5 100644
GIT binary patch
delta 782
zcmZ9KPfQa*7{%Xo+JYA7AKI-Vwkz9~5==2&C<l$!3nF;nK#*#pZb~T%wHu41BqpHI
ziyAF%IFe{$Ob^CO^#mcFG$e8{F?fUnq<AoB#1Lbs-?Dl!o8P>7Z|2*~e7n=rtazJQ
zi*W$)8Eee!?_HUli9eXS1+YE}2a*{@4X<U+k}m@MWpZL%v{rV10CJhu#bGs_xj$1#
z0PWR)O-(B~m2wBIuaZ`$$0mn+)GzCRr5^}?97!od_4CiVfk>FvV<Qw)E%6HZE93(s
zneqG``#@!bg1ZzH#<EG}&8OmXpv_IbC!^$5Hd*_Eyj~z)S2C#&b3T#$G+<g*v$^r&
z_Sg47lrF#u>W!4Te!6u5IF;9)vWsj^`_0lVJ781|d<Wl~9VOjQ`*&c*JIWjB3LG_M
zkM_`X-rEKJ>Hh!GewofNsTAk6Y~Sm>*8!3?V6IGgfHDDrG-?1ZX}bXq09%g?aFFz|
z0UAh`3~-2a)qswJE$X2T4wLR0zz2MD8Ng3^(jWwpCPM}|LP~`?Xre3AA#@;>wk*Mh
zsl7&U7k5EIOFRTKH)p9QOtmmhpS+)hW6;E?ALk@FD9Mu5($LC0ZfmndLzUDN>g=GQ
zxuZSSDbsMAMFp=%jtbl*3T06k6+~9{`WP9Xca$c&S=7@_!N(k;XY+3?i2DALTMXAV
z&aU+OFWXOS!^ZU=4WGTQmj9_X80lmItq@6YC!m!hN$En}vAVbROZEjvljDgq;4C;d
tTz#&e^^5MSRHa`rP`cJ;<5V^g?J}{Twh*1OnANeHIV~aIE3L`?nm@V`zIOls

delta 621
zcmZ9IF=!J}7{~vYOJgxHNt4oQJlkuks8~}qAv#E{A~iVGrM5WOYnoh!o;^$`aj|hw
zs0KAWaBGPUQlu!F#X)d!DJnW@>EKey;1EMCA|>&EIb6KQkN^9B@B7~S?pwYk6$+9I
z!@&5Nk}K|1jJjSLzBgY0q)`B4NkcOqeT`)4mjQVxIhRvi&Bi7WWf9c0sT+4o4=3m+
z0k^4ZS(9-;{V8g@K64|TUU^Xl+7iH_bD5Mj9eh;|0Y{5Gk7pRzu_`y{-_h^S7`gn-
z##r+^162l!GqXwU$?Iotfk=)%VQ6_%%I|tg|At<@rWvUZi#;m+I^g(d&SrD(f2@51
zj<2xk1@n5!+&FuLxkH~tS-K)U7Tc13cncD%fg0r2Zh*Rz`CD+pYDD2L$naD<MbUA&
z`#h{Q^8XTl92Z#b5|`xPVp4YdJl2)gpjuy8j60k2Cx9wJ7d2*sZa#e92D_;bY_NyA
zY6Fg__RR)+sT(%z3^k6+0{eiU0UPvChiuSGowiY+a>HT^^Z|7?VSzAE*={=!s=QPW
zdKJBHC|7-_f59zVbH|rpB>qpuX5^&QF9rrD#KPcIZ`GUkb@_6>HUCBbdPkyTDbOBx
g9-Qm!YfZAh;yvb;nI4Lch^gqJaK>&|?!>~Lzh+jVrT_o{

diff --git a/static/font/font/fontello.svg b/static/font/font/fontello.svg
index fed9129e..6e5616a1 100644
--- a/static/font/font/fontello.svg
+++ b/static/font/font/fontello.svg
@@ -48,6 +48,8 @@
 
 <glyph glyph-name="attention" unicode="&#xe814;" d="M571 90v106q0 8-5 13t-12 5h-108q-7 0-12-5t-5-13v-106q0-8 5-13t12-6h108q7 0 12 6t5 13z m-1 208l10 257q0 6-5 10-7 6-14 6h-122q-6 0-14-6-5-4-5-12l9-255q0-5 6-9t13-3h103q8 0 14 3t5 9z m-7 522l428-786q20-35-1-70-9-17-26-26t-35-10h-858q-18 0-35 10t-26 26q-21 35-1 70l429 786q9 17 26 27t36 10 36-10 27-27z" horiz-adv-x="1000" />
 
+<glyph glyph-name="plus" unicode="&#xe815;" d="M786 446v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" />
+
 <glyph glyph-name="spin3" unicode="&#xe832;" d="M494 857c-266 0-483-210-494-472-1-19 13-20 13-20l84 0c16 0 19 10 19 18 10 199 176 358 378 358 107 0 205-45 273-118l-58-57c-11-12-11-27 5-31l247-50c21-5 46 11 37 44l-58 227c-2 9-16 22-29 13l-65-60c-89 91-214 148-352 148z m409-508c-16 0-19-10-19-18-10-199-176-358-377-358-108 0-205 45-274 118l59 57c10 12 10 27-5 31l-248 50c-21 5-46-11-37-44l58-227c2-9 16-22 30-13l64 60c89-91 214-148 353-148 265 0 482 210 493 473 1 18-13 19-13 19l-84 0z" horiz-adv-x="1000" />
 
 <glyph glyph-name="spin4" unicode="&#xe834;" d="M498 857c-114 0-228-39-320-116l0 0c173 140 428 130 588-31 134-134 164-332 89-495-10-29-5-50 12-68 21-20 61-23 84 0 3 3 12 15 15 24 71 180 33 393-112 539-99 98-228 147-356 147z m-409-274c-14 0-29-5-39-16-3-3-13-15-15-24-71-180-34-393 112-539 185-185 479-195 676-31l0 0c-173-140-428-130-589 31-134 134-163 333-89 495 11 29 6 50-12 68-11 11-27 17-44 16z" horiz-adv-x="1001" />
diff --git a/static/font/font/fontello.ttf b/static/font/font/fontello.ttf
index 5fb1466a2af114268066dcb77a0963f9449eaf3e..1fe7c631348c3a8f9d12ba8b15e70de95907627a 100644
GIT binary patch
delta 775
zcmZ9KUr19?9LK+BXLnkf`{Q<3X4`Fdn-g={HXTuvz1XrIB!*={HRjyHtzFVWA#y~$
z^iZ=)j}k(J4<W_sDUs-*5VD6L^3fn=_7D~sKDmB(w_f7#Ip6dBo%6e#-|wEKn}q@^
z$`dyL)(4<JnM){vFS!%sX8`^*d3{teRknTs;WF(@LrOY#cd|GDL~4OLC7l>iC~l$s
zWzyPoc6_K;`L+TGaUk$9lS&LWzM75!!2s=dWhhXyz$@f0k@seDqhq(s{gqV;+@?S=
zn@=WQewuj<?6;He%_YVZHooHtc`ZS@lE|grPq`%W1;DVV<VQwlHom_DLR0`NDpym=
z%CWXN;ON-o=6N=y##y>`6O599pWxNiKGN-Ud=o~zrFb({z)@dzs9)I`XAiUy`+umX
z4aWtUvP|l<VN2~W2<jtl+V-OQWk6PEd1b-@lnIEWAsskLBRbd#tl!hYF4FrtXd+$E
z!EVxJ9l9CTshb+uL%O8{7x2TT12^dr9X}*m4C-JnDJ5#aL)FtIG$5B^g0E?!+7oW$
zHppo0_QS}Hd1?<+1jgy-$4NNO8W^?alpOZSVc8@!wK0d?)FRVVBYXVOPMTUeBVExj
zO@~-WbUMNzk=rD(EQ!OS#L7+=Bja)o(?T=zT69fxF^l9_`x_P|?R+Wg4m31B{Cv`V
z(R_FVbzFOLSaQxT{!{f?dz5+Aa{B<c0%~_KDW7ZTXn1YDV4kyhEDx++Ytg!D>$ClC
poVQ=5EUiRu=}oYXQ`(0EJqG4e?V%~bsAR8=sLw-pN(aO4`ah*^yn+A#

delta 602
zcmZ9IL1+^}6o&uF+FDI)(xkLnW4lch6?Mf#ss|}5QiFI9DV3t2Ynp5hUAr_(iI+A9
zJt#$62E4Vj3L;We%tb`-;-#qQv6dnVR&wwVixy9b|77vv4j=#gZ{C}E`-(-eG(Hud
zC<5XffPu7aI`=*qdHP3yHk%%E^~PHD7mz&8b3N-=_U-AZLHa9z-?7ZR!+41PD7DEN
zzMjo4Je>m?Qox>*xr{j!c|O+x9GK*JPmY0&i&~Zb4gJoX?H0zX1GVoAlo^;D9!Z<`
zUp#&d7%qLvHVcj@Y<WokieA5F+L?DVojUyr;Ct_k<lVPFmOlW87TEMHXEfuip4i9S
z-jCCNE{b{CFRZ=m5G)2N(CWMW)Xhv^#|EfAqWl95fpV+-CN8v}f?9q5FL~Z~n&piT
z=6xc}qJX+ljj8^{<TI@{kpRjBZPddaXy?0kJg}8|*8|(Aiyq*BDqlRXox1A5#!%s~
z6xad$<hu%VQhPnnMIG{pLg$9X3UmW&Y(jw;Q0i~k)lu4{?{1D-Yj*T<@YrwoH8piC
zMU0+*D$g26L|oo52IW`dYFD|r5Nr#&!R64I&`L|HWj5Rtei9jL?XC|pUdkTyYfK+a
S^vRcr8F?vrv-CL`3;YFN#+@Gk

diff --git a/static/font/font/fontello.woff b/static/font/font/fontello.woff
index ca463697bc2307d76991a4af2a2cb0f5ba86a0f6..fc65e32512172f75ddafe16b924f90a2f98c3d26 100644
GIT binary patch
delta 7822
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

delta 7738
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
AZU6uP

diff --git a/static/font/font/fontello.woff2 b/static/font/font/fontello.woff2
index 09fafb310e4891a3337176a229ae0fdb5fb56f55..8513d894effdd5926975a2c9987741e1a01fcf3a 100644
GIT binary patch
literal 8564
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

literal 8456
zcmV+jA@|;QPew8T0RR9103iqf4*&oF06$m&03fgc0RR9100000000000000000000
z0000SR0dW6haLzZ36^jX2nx_d!%+)J00A}vBm;pA1Rw>4O$UPs41oq4k~c+1XxKOa
z^M=$BMOhLJW&d9exFJJosDD|6iF$g)P@^36aCf!Zozx)a8Mkbmavi4E^W-=bN5yo$
zqxGq&RQ#xw*V=4jHgWJgxDVTyOH=k}^#2JI-Vd*hkYv{Xe}8Jf_knxw6Buw3IRvPH
z!WxhCQRXCy{2ah))~^sNBB~KO#Li&Ra`{pVD2;Jq<R0^&n|%@j38;jC8V4xL(XC)y
zJgR^=I)oTg#W8VWe_e}i@9ff!Md@1F_FvIko?XkEw%eOs-tErCyzexn!jE*vf<pqs
z4me!~d<2vBDZTv(;%4Jgk^xg!*`|lFz4s6-rf=4$SY26(3nlGHXEwW90os;i$-n~3
zfPw=WpF;?~Bt?Bys*1a>Qg?6R+P@?ulwxMPA1GI#55*i6At@%0gs#wWYLc>7U0Bz4
z=a}FG`Q=*Q%&B(ATsk>JPf-5~P*Iq(5)eY+|7@D=pE=F*7z!zb_RBMMPSG8e*QV-c
zX9Y8}(rI_?eQ#Gsf&*DTSW9;oL&y+P5L)Cuvg{Y@j->!`g*8yoBuxiYlqt%T4R$Hp
zbak2n2pG|(-|x3??@-1&2v#zLe(wF=Wr??*t@sLoA!0LeNc(pWPVC8m01DXZFgbbp
z%oXUmHMV*O3mFnhOnBd(w{ARt2r16NU@l6_17o-PcD@=8$P@VzfR{fH<8QGo!8OAb
z$%DE)ee?+&{k?y_+MKV$b94r8DNc8(gDT=1o8$1m%%Q&v!013lAr#_U-iRJN@zU=H
z{+$1rc(Ps_vD-FoA6)-<`eUmb|3|sq2slgbnPxKNIsL-L4$<{As#gC`o>V4RC{=2W
zR;M=@O=gSLW_LJUZjaZ;7v9KiE;-)chc8IK?Zks9J`p7#qJ%`0h=>vsQ4%6bN<_(s
zC^-?OAfl8+l!}N_6Hyu>N=roPh$uY~Wgw!AM3gDfJZ4H_VLh?3-q_ek?Cf?NY&=f(
zAudiBH#a>V&KfT_9v}ax%a^w`^zQ6Xg{1$LcNk%akK9$?2jIzHFfKl!@c-zUTp1N{
zfqd1IYWgR+5!6$i7!krv!cw~m1Q?wq0b6llNr4&o?<HCISR=12`)U9BlNS|}Z-5tG
zdLae_uD@<vF9M1{Ce0Y#BYP}`r)mm<e?Bab57Q2cj1SdfE9DhukeM;Kv>`F;D&Z;S
zZB0uK=s~7w2J&o~O^c%-8#E$;Bw8}4s9;w3%7Ga!nLlbN)@8`$!ns8D_5E75GVKRs
z;gydsO?n-?hJ=T2e5Fi_B9+c%$%7&fDo|WN5F*kFg2^Y+YN2FZyX5maB?2|{tDOF2
zuBs)-6vmL=A3J|O300f|d$%u0gFF%WxKe;eOu00f#>=Mcm6(xaLzPIAtvQL*Fuhha
zb@`tgRo0^a0l}03XuLI*t2*J1dNC?tU*rfKg?5heNkPWaKy3ob=3`lHEr<)$_s}Jz
zvy7n}z&su!@Rzwdd*zpQM&t*=h=Nwi<H=iJSkr~g{9vo!Md7jbm4EW)+%i%xuzH#(
zkXybJxoHeZ>6o+7ngUf<v<IY*AUP<==}#5pOtSlme26l=T=Y%!J#KhFwL!n~2WlLt
zLt`fCr|I<GE(^e*9SI4$m3VSl+rm;okG}QHi9=6y>PtmPqC<RM%3t}_GA!Wh@`GXy
z2K;njE(S{*1*`+hA_|GY!4zD~K?yS`V;(A4fGQTDh9#(D*==Bn&Tp#)YN7^eaSz&<
zLI-o;VFo_tA;1EJScEQ?Ai{F42i%@Y&@YP2N3`XumTpb37#~sQ0FAI(<lDV61TX^Y
ztfnJXQ`6_VMnan$(LbIXILt}*ms@6x37PtIZUWqBqMW8Lp<m8dOJXI)SXpp>Lh|+b
z-PNNq@x^`18E_k86J5g6e1a_JXwKfYjKxe6R?8ikpip<%LZedzZ_MT&<-<{ZA;C|K
zx~oTAjXf!@?^~uIIAq%D>6Iz-V4lYU+|KK<g|Y!O*|TKg0BltcX7WgU<$uuEYRlL{
zSgi!Nx(!K0_JF1i&BZb<5fxXMuoAC88D~n4X=b#Om5fwzb(s`iS5km1=#Y+#QsO|W
zvtGd^Mg&S-sjP~$d%UJ$Qh^j%=!~H?pc=#L*J-K|!NM8^hbe~--FNl&QE0(>hLSj5
z4B#d4fl?bRz4j3@=YuQ0!EF^odg4kTkGCc0<!q1iYPgrCoV1ZaQ8ISb<}D{WdZpsF
zJ8Ao({pfB%OE_Wf@Y+B8p(z7zAB38=7kOD`2RJqVmUqF_a`f+kndR1lkCaQw>;5n@
zHXP(7adJV3jX$AT?BeKAUg^bQk&@@P8;8G%apLj1bCq)A+j?YVs2vH-Q~O9nyN;KR
zXvp#>X)ihwFV0N6!V(l~9G&G$b2NYKumCw(oXgDdLnbqvxIb`uMS~%GB}Mkh!?DOB
z+CJ>mVQmm_Od}r?f))e{F(C>8j-wb8k`@F?F(C^94x=0siWUSaF`)_pj-nb9nid3V
zF`)|qPM{tWh86@GF<}Y;j-VM6mKFqBF*j_Je+d|?{e$&OsTLfN3P&4;T%^G%DFWdf
z5aALK)z#B);MOF;Js`m&Ai*;r!K+DzcR+?uK!$HX-tIT~FK_atNbLWLxv7tFD=&ZB
zN~(;2;Jh0Rl9m<dY0U97kSzm>YmxN043r+jBdqQa2poyQ;}u14CloOsN$fSk0sjV`
z3AkK8Lduh(UOZgM5y|D;l5l??6&DdC;M15FKOFV*a(^m&c?g8U@Cj0RxSzlKL;`~S
zLY0EaO0GbQ!#Iz}RVwBozaWuOEO|K6NuD0*HI1ch8RmIfHhTtYjow!J@>qZYG)grm
zK-rp&v%fLc|4ziZak_?3m=a_%Nd50DEWm2qRYRu$(^HDs4JDkZ0p;8)X<d(xFZEtc
zlOUtDQ5v5CEelfVE1fF1K6!psgrEwyEcJ;+o{w*enQ~`{@~U)11;A<#Wr?*<1qeTl
zmKmh-5KFTMlWsY&WZ$ISD?QehuD8UV5+OR1#bVrBn?gWoS*As@^Y46l_Ovi;gmR2I
zhue{Ac5_5{>ugYdO<cjQ)X5gcaG3incs^2FO05NLSU0Z9LWPj)@(N%`R2$dWZeMt{
zz*O~~Sz(+(NI97F%_+hx7APP0Kl1Jg@En8nU|OHp+!8SBWjlt({d3ES9yd7^_s(vH
zna@`~V!k8Ucxb4e5n>EMs(|gXgroqqhroLMH>phwu4brmRgj8NO$gD$;j+c?U@z^m
zcS8<)xcA$-s{0?Sq$tvA8GoEl&ZEj#VL`LpT5S!^+iT3XynkVJsMzz%u}a9DNCo`;
zY=p<ff1!|NKKLvcrg8PkC}l{8uza-ktW&zUBPv$e9{*46ltXLl7>uE85~KzI(7;%?
zk}E-k6NV^#ww<D3l(tbkyxfhfiQ6tA&8OQVP()FjKs>|~Y0-p~OS9fM?GXQ=raD(E
zGbLH2sbIy;N|zf!FG8DfcRwZ?20b^IBvRi@l?sT#wfgeNqFsLQf1$#E?|~Pd6kj1E
zf+}D<4O>5!&P=7L;h=1N`Zf?G&ts9Jk?+q8hq4G^`lU88Fl&TrPH3Nly`e019s%>N
z&WO#99d{W+wD-{W&+VtqbKcKj927)41D)ohTgWa?j8IBcGm3cTkarB9wp?H3qtqH}
zSCbIUc25{ZmSeseadX@(-A%klxmv8ZV^pdwwvy>o+fYHogem~XR;3Cstu`i6iftxw
z<k>ms7|k4)l=aNgU8bLM`cjY>vpjS|WSuGaIjd(|dcrjpt19CRr6%KMK3!@eJ9u#l
zg7TL83C?*C>!fzGuzjb+S*_)zXIsrvg^c!cl|_Pp>0v>2>|xIY=A`pf`)&(U7YPH9
zm+fLflPJ=h=-Z6$BkkYvnJ8pgRb>0A<;-!*ZQ;U(*#sGD#z6+1^IQ@mbzCVarlp-|
zKWDt@fwqukIN3oBz57s^<|wvr&v9jH$|PWGSI!wD9LI;i^#)u7xaYaeXx1`QoeE>G
zh>)nHER#vF|J8<ASNWhgP;Kd_p>zl-0{}~LolVY2<_V%8M!e4Rx8Gh=`)t-I^#yxp
z>D~I5`t!Rg3SP_Bln2X{*wScz{FupTZ2RjhaeX8zlA=q205Xv}GAB;@?x59Ei~D-{
z$vn>URVtU0j<MW$E{x$jcFg$FeEai4?|E4yg|I8C4J%2=dD;g7(;{$u$HW}<S6K5d
z5YRBi)|?J!S1^$qhTIT@QZb4%$PV<dWXa(Z`r6D=l^R#uWs?n4Z_SRw?SdY+y3yET
z&HK-Eh!BlX1?-e%I#TC%w=X=3y`p@yJbfjM(1nq6w@sNnyX}qndEEFspNn<*<-#&;
zr6Q~ghYp#~dKglDa~8NSSW?XSqL?Co#8k)N<0^zm<nj7xuPrLmg|k1F%(+F;)$|ES
ztqD=jsv^gr^KMc37W!6w;?$U#$c)^Jd46@3iYczxdKOVx7Kh{H?W!RnQ!~UU2W6eV
zijv}ofBq;6ogGtKBN_zY7vucuT6Vm0ft)=kLJDfNlIb9o&A!hA&Y89?Un?>x{^Wa7
zEXu&k!)_+k=Doh?s|cy$mo>#4-lORsTKeNc|7v|=z5Z$o>yI0aEUQuRQf-{Eg52!E
z$8+NMYMAh;&Uie$4Yfb(b8j20>1EJhCojGFs;Vf<+*#pLr^x7#XzWFhauDhoRbnW*
zftFUp*K;xW+;n;t<eTM(AAbAiYE8e+b-C4Jy&b8qz|aFW1@Lg@%ny@4?AhzJnH?E7
z+<TlxlXwR_nEK!`KL{F8@X5=O!FB7}R(kNs$9OO`*k<e=^mY4^#Bc2O*)Tsik)`OB
zXMO*`_x)#7mtXH2Onti-BfZ}A5|e<}uN^^->eUw{$K#JYAB>!v=IiNkGV${_OI|Pe
z+}Fi}k!ikPpZnF*=ROf;f4^V)dFOi~?3tuJyl>y%vZ`y9*Zz_9?+gF?%KyCc-j(%)
zhzVY$u)|SB^a{$f0^BqI^Z%FvrZv@_J>T%>#fG_O*?+a29d39w)L=h5iJUhv{Ygxf
zr@?<gV&;<k-l}pB_fD&{)ac>%b$d(=h6oS$$O;DIEC1RTU+GHaA%@T{9<t1&=xT|a
zwR7SwX7Srin^gYesXW&8ed>L{(h*9}T96vBm56<vFWODl(1kx$b%v)kb1yDQs!S}+
zOPFdXE`Gi{YXnD}wFH|IDu6)HWWz{a+rafh(qY&2Wny~Nc0<QCX4|5ycf8tM*N;gL
z4_t2xWcaoldTw%db(EK*)(@tHN|0cs+xUz=-m0PKR*D9j7`l<616w+gj-m=|+un(F
z4BvR)WIBadXK7Y$LTB0%1fA#*f|Vb%rE4+;j4>fUif`<w+x|~`8NaB5(}_3}E3nqF
zd9&ttCf_reypYCOn$B1Cc1*)Nks%Jh{LAX}_$17lqSr+6$rXQ%wUuE-PNOvn!eI$o
zS3h9L&o^{GJi7y^1LdJ?F{h<=AVkgX4xuAH<%lSPJ&E5xby}a8#&*5oGyEGEJ^JSL
z)p8vSjMT@wHg4OxC1?u`_6POl<!&;}<@?27<>u0U`#)V;Zb(TnvQ9Gj4<DLL`ToO3
z<FJ1reSF5oS_--Dn|$fe%-L<~O*3Z>w|(JiV8+Jq;HH!L)PMi!X0p0Ui@R892@n5k
z(K;SJq^MvkG36HvsMXEU>MX1=4f~DI<{GeMi^Y<icEo|~M~2OIWC+=hI?VX~5Otzm
z$*`i4AtZBMk;*4;50u858NLPFyG1|9(O?lUo`R`wd!ZDJ&M@)YgGd~K<rP$vKZ23*
zt64pJn;<0>DQuF|z6AJr^4eDt?8eG_(U=5N-*#?XVkW#mHZYzyKZrb=z&+^90W1YH
zS4#PV5Os)MNy86nzO!>x^R{j86Zhri^^5z%!m$<o2S?n$ZHt&#bu|2$4tE4Oq?XpQ
zte`%QMcA1=eMJ1x`rKS?Il|IBvz^<|;gHv0Tff-<T{g;<xq-~&PH@z68xG!Be_(>x
z8AHixC|QhCJYnAfi9_;6L(|PPt$A}imtS0-Ml161kHJ})OV(6kX&%IT*JB@#v?^@T
z8h}ps>5>&rqn`dXa7a?~p;i+}n>>HmsrP+vCWznQ<y+)7<2B{$)_uES9avT)Bz~C~
za8=lNzM<~y-wXX;YN1@vA_IL$P=V-`TY%xVo|1VKSrAACN3H{Pj0SFkgdi-Hs#Gux
zLmU=IP`_9QQ-qoYHVp#$!3YKH;|sNL#yBEtmr|nwpcs+?B~CxB{;V=I=9(O?r637N
zB&`qv^6qR>q~~m4)$-Lynn+45jif;1GIerjsDK>{-$eHRp%TbKp*l4RHp##SSm`g6
zYw;+Y&2o9dicm-}^zr{$lwKdImmN`^-pwLKjJhF$8)2RtnXXPG;0!|uINt&KlqRW_
zS{Oz}JP;^4ii>=sO1o6b29@wP7{o!*O>a~!2>7E@sexFK%)ruY+6Joa5$vIAQD}>F
zX-OW%Nvx}VtcqI)iekMPNIoWyWWi2$od8)Q6v84OkS&ViY!fJ53Qz>0pul^+5>yI{
zJ>o$^)DS6a*u+OAaI8RK6o4!Uf@EMsgS;!04TDoh1Xm+)IS?sN@t)HVNf0cUUl$i=
z1?%*sU&X@SIL-leq|BdX98!x!P=v_ea2@;zhgLTmmx`zigbgkoTvPd^-rJN3dV=Rz
zq%0kf>I5<Y1nfgY^(=;>GT9uJom>N0X?zoi$3UP9gae6)ga4s{i{Krc5B48MJCA(Q
z4p4?LLnyTjptM<8?O9pdp1IFsT5U8%H)yrp2zk7v8g(Ewkf?y7UlS*Ag9`}DGNhf;
zWI)jm>@SKc(9aMo;H*%kUx*8GgrZ)(D&VScp(s>j4Z3GpQkzht)mJCYg%_f!krA09
zAzU1lp)zMoofA=NTBVKI+$|h<5xF~dLqgnLBA_c#V=!7ma>G<_LBPysP6<wuq#SG&
z?tU5D8{P(E^TNs(*Cx!>>WU98LQ~!wM}rlXEVG!F7-9h?$>v=pDwk9Rr>E<5QbwA=
z9#EQZZE*vTZ}*W~fHTVMki6dB{E!^w8{F@qn#^J=EZ`XhvyYUNoSb$=v#gcq^eZyw
zL#ji;8SuD9^DlT>q>NtEjnN0tSJDH^5(lb89muk-86IU#j#Lhy$NO=8OoGv_L&e25
zn^8czGx^NQPLHl%%<v@`X&=e(#MHMv{U!&SOcN&b2laLLiTf~%*|Y`Y)Ti}C`Q?2h
z!jNC6d&{fH)wYy3&Lez{W6LlGz)tYVo4!tJIE)6oj>iRD-TgSkOkecfaELlFTFJ16
zmyeHh&y0R)F$C^}#5(_u-wO<%cRVLfOeRe$FRxK0e~JHe3i2G|UcMNZvDR9slZ0w0
z)}*mX(Mo#C)5Z1YXE!VXW==QNrG~$~e`Z^zB1zNuBva0Mfx%5JOHR*TASv$JGhWyo
zwr+0G+K>Zk7W$JPh{uTJC!)S1D>QFQ{>q9hT?5bnA*k7$Dj7-KKAgcp)$I%pw8R-0
zT;Eyvn)&pq>0~^Iy6Fr5%un9VT9aU?!ks8v1ce00iY&nkeqnHi9b@n1lhWm4NncRk
z_=Uv{LA~}K%WcVw39}9nzi^Z%9juu98*oD}Sji_bC7<D|<{5Z{<vrCHeTwuPDp@9#
zVd_UaG199nDn^$lLa*aT-0c=}7xgUe$(;QnJ`G3>VQ|UzBtm-o9FseD4484pWjck-
zdThk}opo_7g}B&fxM`5pp$&0Pa;JCiJB-nzI!ygYl0Tzl`5zju9o;?M@lPcoekgU=
z_u>D%G^Y>S&)ZQ4x(jtQBX9Np)NQrc?cgVE3qAu|I@p6t+Rmh&Lx$P5SpM93WXQY*
zot*QY1F@ZYoj->-Yi*BiOQOVis<$gQ?oR_X+Yl7vq4T*(IY5s-7cH~)yK(h-q&>Gw
z9Fmqq#Wz4S%>9D62CZ5;9%K&mbJ=>_MQPOYc(Vm?=t4)GeoJ$P?^}J9uAF~=P5((P
z^Wvj7u76a^(Q2oh7Y)LyQXn}AOb^s-oB2~4aG8=AGKfH`$U>GUh8S{0jX4Zrb*GXL
zMGI!qfSA+{ZF{lTnFkvsQ}IO`uwv#4rd~o4fp3xRay~4-1ix0cjdGS^aAk?_Tjjfs
znXh4>p$HV9qGhBA>qfFH;0T~^){2Ne-RnMxU+pVNmBOwC5nMe%DVLA;x)MX6RpI72
z1ca~y1~9Y{6hYfiorM8bhZ!1xp;kL>jmy4W7k%Ld-0KhvtST8pWawlJ7K61D1(6b4
z8Et1c+i`T-L8<K&Ba4CuxBv9!nFWI#C<w9hs^*zen_~rX!5m;?kjkKnzK$Z(&%1s3
z;>i<(ey3%bq7QArJ(~zwMG%+Z9k_~X8>Uc02ZRJl>q9~7Q0)Y$f5<Bb{h%wM((dR4
zL9$?uzV3I;e(=?R06$Q27eWv<V*L%<+J^rVxKy_(wVPm9xs;h;WTz%pg^Ytt2O*kW
z1#N+V5G|NH8n!oDxbs?Xemn@hvYT%fnwDis)%~2Y{N04I^x|iWq|EKnUaE3=D=1;r
z^S|1cZ{QjXE}EolFtz$g)<g5mTD`h>R}fK`RyVakP|+$zAqN^Tu;~M5tGJtK!@vNk
zXMXez)NW$<<G+8;cIU?RJu5$2I=}PF=XbB4J-K)L+Ld#sQzt`}N@Hh8`)wJ`<p>5x
zOzK0S#gNuvmpc5!2|h4vV-Fh01FWvCQswFMzl_Tb9Efy+K85D!2`K2wmVva}luBnH
z5*i4h9L`qII{Q%kGD$l`{!;Z$BnT3oCnwBaEKXoO5=@iDd<cnp@o5RQrmKqDlI3RP
z6g<n6sS@3i;|VB)bcSYO<QM_|G0|9CVFj6$7kuG{)4$})jm0*6*%y7zTfNbX1t@@5
zAq0w_`+*LcxPs$2Y=@;5C?G=k7QUHp<jeUoKH+^%ae|89`K=NHBCqiR*FupH`0sw=
zWq!j`Ji)!(fdnEUpjtWoOS#-wEGuR@WN`H5-@C%AhxlI<Z$vnV(-jo@n>Poc2Bshy
zRbmG*Xy4vONZQ^;qCWUG$k~igMLi>+4L4C}4Z|9^$*3-_Q;_J`*hUPVJ>Uy@oBMsj
zN8#{ul}g_~&6|rd5a3UFgG2l*pW!IJ>)Sr<Q$Fq^9^(Nb0)P^T5(;n(JlM1erPl?N
zDuj|R-<1`ovrJ1Wy;LO|!SU)0I%OTi)kQm-R3jja_B^<k{A>j~;G%i1q>^*NxT>|S
zAy%c<M0t2`w;OsRe@|$v91@gLJDzZ+q6(i<2ox1+CsIw++7Lk_5Gb8dva7x9v%0(o
zRHlT_@;nJ4c^8X4Ks>D8<t1#qc@y1UL{L37n?x6S7i?22U`=b%*3hq*>RP*v@MOhj
zu{PNhXSE^(E2mEfIi)-0bQ5)A*=bv_q$QTiL$M;l&`aT-&D3NW-HhHl^TEW$bY6}S
z({+HaC7y>6O5tn;hY%QY*hIZJOB0p-l_1T6_&hr?WobjK*_Po8AEs7S&<Cf~+O9Rb
z9P_?l111qMPnamC1BNTY8w*uho2f!ztxmlW_pR!GrJ_n^<4VM&f_?WSp}!e3AL^^^
zOhT-lBsvL7T`(tDF9GPCD%P@|tzaX+v(BaQPfJMz4K%SpaNz5A>Qyrj!wm<-i+6Q`
zOE}4PA_SGtj#G^jX0`|-vIPraEO50Bw(DJ~7dxKsNj|ax!;n~8kcEu4LYV6~30YX-
zT01UP;X#Df+zvN%Bnar3!6~?7Yv^n_7eTsIh3b4fA~n&fcDD4WmTW6;WC1H$5u^O+
zQzXUEQ=?Fj*fvw4RS{Fnku>Fj3jMToBNLkgLbfy9cFVBn?}e$pYS4{)G^S;ASv07Z
z46aq9>uA)jHWEr&G)9TkXAOB2Z^IEC?Tj&|MuA#)J0noWvOJeV2`+Tj*-RpqUlyE;
zYC>yq-HM~%*!1Upu6Yw%g#uvDXFeMZqORX*Hmc=<U9c?^dUWq8```v#4Fg(;OP3g`
zvb~>L(kd94BNk%bMHI>flshPvrCgLwi3OC4g>oxUoSH;iNM@;yl&q1_lGTU{=TDtD
zdStPe#j{B-@;kMvTQu`Z=7z-7?E@Qt00=zu&z`@9*unoK5B)s={B)g~#k>9gxx2(3
z=?s7b0l>OBg$H|(fTvdjB2g=fu(Y>pdK-tU_pD~yLYnCJ?g!^TJneb6e}w!2wCV31
zc~KS}X3ak*c8I@-A(9<8qx&&<tXRh$n0s`r=>LikAi;y~9*GZ3b6bEuzivM4ioACc
z3A;K45r?F5<fJr^TBoCkx(pyM>?~k|nLQWL@3j=P48Tpi+wCNJ>h2VDafwurP0~OP
zbvlN+AOpxmX91(Ud!r&&_x=CMOKRC`{qs68%d&`twZb21#;xqQ^-<J~{L=C0dGtAA
zaJ+gpo*qv40W!s(zdWC>R?p0a6UVsG-zy_xtT~~o=L}9D#~dEx4sKuu*KrR^t#tzH
zEVbQM+w8T}I94r{1BTzgEXHsP-Wcu|8`qigF67a{n?|1U?qSNvTZgyV1eNcw<W=F#
z;J&!pG2G!yzQ1A=Q^gxMSa*M^Z8qBqKviQFWQ;MAlg;+-;(-?1Ni)WD1C2Wky1J!K
z$19eaW6PTlIl&p536b}H-hNyBw7NDRNS2|1?~WA-l}2Y^WMakwi!8CsE_Snrz3gK@
z2RO(f4)ZB4;6he7!bM!nC0xp7T+S6-iSU1Li3|2)iv3YM{J|Jmxe4LU&BAJkQ;(mH
z-amUL-kDl`ecBYbiTt@>hL$>5$+lu@WI9$(`1!O6(QeJ)e~TP_y6QY7+m-3BE5!SA
zkz(e9iW%OS{ETL&6Z7MD4nDt-4b@8cyK^t!#jc%5wsV_DPrt3S^TO!in-w#EQ<5Pc
z-%IFLcj0C$%`z@NGM4Lq!rM<Oy&An-T~xRIV{!Z7!(Lh$zws`?=ZO7TwxLra+1&zg
z{&VoXpZ`tx%H~n>&9YVIeuE$X1Q6?AHhxkOrm)q(=y3cC^lKn81F;Q`Rwi-s<33+}
qCHoh4-!L$VL*IYWv!LBmk27zi%ck4;UrktA|2drRBK(SvLpTZb8WLdu


From a8180d03be3488aeb7cfc811a1b49f6519836ab5 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 19 Nov 2018 18:15:27 +0300
Subject: [PATCH 17/96] it works, now to clean it up

---
 src/App.scss                                  |   1 +
 .../shadow_control/shadow_control.js          |   6 +-
 .../shadow_control/shadow_control.vue         |  11 +-
 .../style_switcher/style_switcher.js          |  38 ++++--
 .../style_switcher/style_switcher.vue         | 116 ++++++++++--------
 src/services/style_setter/style_setter.js     |   3 +-
 6 files changed, 108 insertions(+), 67 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 8fb3c488..19c069ed 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -313,6 +313,7 @@ main-router {
   border-radius: $fallback--panelRadius;
   border-radius: var(--panelRadius, $fallback--panelRadius);
   box-shadow: 1px 1px 4px rgba(0,0,0,.6);
+  box-shadow: var(--panel-shadow);
 }
 
 .panel-body:empty::before {
diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
index c357581d..a6992999 100644
--- a/src/components/shadow_control/shadow_control.js
+++ b/src/components/shadow_control/shadow_control.js
@@ -9,6 +9,8 @@ export default {
     'value', 'fallback'
   ],
   data () {
+    console.log('sdsa')
+    console.log(this.value, this.fallback)
     return {
       selectedId: 0,
       cValue: this.value || this.fallback
@@ -36,6 +38,9 @@ export default {
       const movable = this.cValue.splice(this.selectedId, 1)[0]
       this.cValue.splice(this.selectedId + 1, 0, movable)
       this.selectedId += 1
+    },
+    update () {
+      this.$emit('input', this.cValue)
     }
   },
   computed: {
@@ -67,7 +72,6 @@ export default {
       return hex2rgb(this.selected.color)
     },
     style () {
-      console.log(StyleSetter.generateShadow(this.cValue))
       return {
         boxShadow: StyleSetter.generateShadow(this.cValue)
       }
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index 24439449..614de76a 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -5,6 +5,7 @@
       <input
         v-model="selected.y"
         :disabled="!present"
+        @input="update"
         class="input-number"
         type="number">
       <div class="wrap">
@@ -182,15 +183,15 @@
     }
     .preview-window {
       flex: 1;
-      background-color: white;
+      background-color: #999999;
       display: flex;
       align-items: center;
       justify-content: center;
       background-image:
-      linear-gradient(45deg, #808080 25%, transparent 25%),
-      linear-gradient(-45deg, #808080 25%, transparent 25%),
-      linear-gradient(45deg, transparent 75%, #808080 75%),
-      linear-gradient(-45deg, transparent 75%, #808080 75%);
+      linear-gradient(45deg, #666666 25%, transparent 25%),
+      linear-gradient(-45deg, #666666 25%, transparent 25%),
+      linear-gradient(45deg, transparent 75%, #666666 75%),
+      linear-gradient(-45deg, transparent 75%, #666666 75%);
       background-size: 20px 20px;
       background-position:0 0, 0 10px, 10px -10px, -10px 0;
 
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 8e344eb1..b40511df 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,4 +1,5 @@
 import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
+import { set, delete as del } from 'vue'
 import ColorInput from '../color_input/color_input.vue'
 import ShadowControl from '../shadow_control/shadow_control.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
@@ -155,7 +156,7 @@ export default {
       }
     },
     previewTheme () {
-      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {} }
+      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
       return this.preview.theme
     },
     previewContrast () {
@@ -231,14 +232,30 @@ export default {
       return [this.preview.colorRules, this.preview.radiiRules, 'color: var(--text)'].join(';')
     },
     shadowsAvailable () {
-      return Object.keys(this.preview.theme.shadows)
+      return Object.keys(this.previewTheme.shadows)
     },
-    currentShadow () {
-      const fallback = this.preview.theme.shadows[this.shadowSelected];
-      return fallback ? {
-        fallback,
-        value: this.shadowsLocal[this.shadowSelected]
-      } : undefined
+    currentShadowOverriden: {
+      get () {
+        return this.currentShadow
+      },
+      set (val) {
+        if (val) {
+          set(this.shadowsLocal, this.shadowSelected, Object.assign({}, this.currentShadowFallback))
+        } else {
+          del(this.shadowsLocal, this.shadowSelected)
+        }
+      }
+    },
+    currentShadowFallback () {
+      return this.previewTheme.shadows[this.shadowSelected]
+    },
+    currentShadow: {
+      get () {
+        return this.shadowsLocal[this.shadowSelected]
+      },
+      set (v) {
+        set(this.shadowsLocal, this.shadowSelected, v)
+      }
     }
   },
   components: {
@@ -305,7 +322,10 @@ export default {
     setCustomTheme () {
       this.$store.dispatch('setOption', {
         name: 'customTheme',
-        value: this.currentTheme
+        value: {
+          ...this.currentTheme,
+          shadows: this.shadowsLocal
+        }
       })
     },
 
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 0352f546..af816a23 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -1,49 +1,49 @@
 <template>
-<div>
-  <div class="presets-container">
-    <div>
-      {{$t('settings.presets')}}
-      <label for="style-switcher" class='select'>
-        <select id="style-switcher" v-model="selected" class="style-switcher">
-          <option v-for="style in availableStyles"
-                  :value="style"
-                  :style="{
-                          backgroundColor: style[1],
-                          color: style[3]
-                          }">
-            {{style[0]}}
-          </option>
-        </select>
-        <i class="icon-down-open"/>
-      </label>
-    </div>
-    <div class="import-export">
-      <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
-      <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
-      <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
-    </div>
-  </div>
-
-  <div class="preview-container">
-    <div class="panel dummy" :style="previewRules">
-      <div class="panel-heading">Preview</div>
-      <div class="panel-body theme-preview-content">
-        <div class="avatar">
-          ( ͡° ͜ʖ ͡°)
-        </div>
-        <h4>Content</h4>
-        <br>
-        A bunch of more content and
-        <a style="color: var(--link)">a nice lil' link</a>
-        <i style="color: var(--cBlue)" class="icon-reply"/>
-        <i style="color: var(--cGreen)" class="icon-retweet"/>
-        <i style="color: var(--cRed)" class="icon-cancel"/>
-        <i style="color: var(--cOrange)" class="icon-star"/>
-        <br>
-        <button class="btn">Button</button>
+  <div>
+    <div class="presets-container">
+      <div>
+        {{$t('settings.presets')}}
+        <label for="style-switcher" class='select'>
+          <select id="style-switcher" v-model="selected" class="style-switcher">
+            <option v-for="style in availableStyles"
+                    :value="style"
+                    :style="{
+                            backgroundColor: style[1],
+                            color: style[3]
+                            }">
+              {{style[0]}}
+            </option>
+          </select>
+          <i class="icon-down-open"/>
+        </label>
+      </div>
+      <div class="import-export">
+        <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
+        <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
+        <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
+      </div>
+    </div>
+
+    <div class="preview-container">
+      <div class="panel dummy" :style="previewRules">
+        <div class="panel-heading">Preview</div>
+        <div class="panel-body theme-preview-content">
+          <div class="avatar">
+            ( ͡° ͜ʖ ͡°)
+          </div>
+          <h4>Content</h4>
+          <br>
+          A bunch of more content and
+          <a style="color: var(--link)">a nice lil' link</a>
+          <i style="color: var(--cBlue)" class="icon-reply"/>
+          <i style="color: var(--cGreen)" class="icon-retweet"/>
+          <i style="color: var(--cRed)" class="icon-cancel"/>
+          <i style="color: var(--cOrange)" class="icon-star"/>
+          <br>
+          <button class="btn">Button</button>
+        </div>
       </div>
     </div>
-  </div>
 
     <p>{{$t('settings.theme_help')}}</p>
     <tab-switcher>
@@ -171,15 +171,29 @@
         </div>
       </div>
       <div label="Shadow Realm" class="shadow-container">
-        <div class="shadow-selector">
-          <select id="style-switcher" v-model="shadowSelected" class="style-switcher">
-            <option v-for="shadow in shadowsAvailable"
-                    :value="shadow">
-              {{shadow}}
-            </option>
-          </select>
+        <div>
+          Shadow
+          <label for="shadow-switcher" class="shadow-selector select">
+            <select id="shadow-switcher" v-model="shadowSelected" class="shadow-switcher">
+              <option v-for="shadow in shadowsAvailable"
+                      :value="shadow">
+                {{shadow}}
+              </option>
+            </select>
+            <i class="icon-down-open"/>
+          </label>
+          <label for="override" class="label">
+            Override
+          </label>
+          <input
+            v-model="currentShadowOverriden"
+            name="override"
+            id="override"
+            class="input-override"
+            type="checkbox">
+          <label class="checkbox-label" for="override"></label>
         </div>
-        <shadow-control v-if="currentShadow" :value="currentShadow.value" :fallback="currentShadow.fallback"/>
+        <shadow-control v-if="currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
       </div>
     </tab-switcher>
 
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 3840e215..aac04055 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -72,7 +72,7 @@ const getTextColor = function (bg, text, preserve) {
 }
 
 const setColors = (input, commit) => {
-  const { colorRules, radiiRules, theme } = generatePreset(input)
+  const { colorRules, radiiRules, shadowRules, theme } = generatePreset(input)
   const head = document.head
   const body = document.body
   body.style.display = 'none'
@@ -84,6 +84,7 @@ const setColors = (input, commit) => {
   styleSheet.toString()
   styleSheet.insertRule(`body { ${colorRules} }`, 'index-max')
   styleSheet.insertRule(`body { ${radiiRules} }`, 'index-max')
+  styleSheet.insertRule(`body { ${shadowRules} }`, 'index-max')
   body.style.display = 'initial'
 
   // commit('setOption', { name: 'colors', value: htmlColors })

From 56fec664a9bb5c1539423e396c127c4a45e8f4e9 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 19 Nov 2018 20:22:46 +0300
Subject: [PATCH 18/96] cleanup and optimization

---
 src/App.scss                                  |   2 +-
 .../shadow_control/shadow_control.js          |  10 +-
 .../shadow_control/shadow_control.vue         |   1 -
 .../style_switcher/style_switcher.js          | 204 +++++++++---------
 src/modules/config.js                         |   6 +-
 src/modules/instance.js                       |   4 +-
 src/services/style_setter/style_setter.js     | 144 +++++++++----
 7 files changed, 216 insertions(+), 155 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 19c069ed..1021b64b 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -313,7 +313,7 @@ main-router {
   border-radius: $fallback--panelRadius;
   border-radius: var(--panelRadius, $fallback--panelRadius);
   box-shadow: 1px 1px 4px rgba(0,0,0,.6);
-  box-shadow: var(--panel-shadow);
+  box-shadow: var(--panelShadow);
 }
 
 .panel-body:empty::before {
diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
index a6992999..54813685 100644
--- a/src/components/shadow_control/shadow_control.js
+++ b/src/components/shadow_control/shadow_control.js
@@ -1,16 +1,13 @@
 import ColorInput from '../color_input/color_input.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
-import StyleSetter from '../../services/style_setter/style_setter.js'
+import { getCssShadow } from '../../services/style_setter/style_setter.js'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
-import { set } from 'vue'
 
 export default {
   props: [
     'value', 'fallback'
   ],
   data () {
-    console.log('sdsa')
-    console.log(this.value, this.fallback)
     return {
       selectedId: 0,
       cValue: this.value || this.fallback
@@ -38,9 +35,6 @@ export default {
       const movable = this.cValue.splice(this.selectedId, 1)[0]
       this.cValue.splice(this.selectedId + 1, 0, movable)
       this.selectedId += 1
-    },
-    update () {
-      this.$emit('input', this.cValue)
     }
   },
   computed: {
@@ -73,7 +67,7 @@ export default {
     },
     style () {
       return {
-        boxShadow: StyleSetter.generateShadow(this.cValue)
+        boxShadow: getCssShadow(this.cValue)
       }
     }
   }
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index 614de76a..6847278c 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -5,7 +5,6 @@
       <input
         v-model="selected.y"
         :disabled="!present"
-        @input="update"
         class="input-number"
         type="number">
       <div class="wrap">
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index b40511df..e523cd7b 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,12 +1,23 @@
 import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
 import { set, delete as del } from 'vue'
+import { generateColors, generateShadows, generateRadii, composePreset } from '../../services/style_setter/style_setter.js'
 import ColorInput from '../color_input/color_input.vue'
 import ShadowControl from '../shadow_control/shadow_control.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
-import StyleSetter from '../../services/style_setter/style_setter.js'
 import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
 
+const v1OnlyNames = [
+  'bg',
+  'fg',
+  'text',
+  'link',
+  'cRed',
+  'cGreen',
+  'cBlue',
+  'cOrange'
+].map(_ => _ + 'ColorLocal')
+
 export default {
   data () {
     return {
@@ -53,14 +64,14 @@ export default {
       faintOpacityLocal: undefined,
       faintLinkColorLocal: undefined,
 
-      shadowSelected: undefined,
-      shadowsLocal: {},
-
       cRedColorLocal: '',
       cBlueColorLocal: '',
       cGreenColorLocal: '',
       cOrangeColorLocal: '',
 
+      shadowSelected: undefined,
+      shadowsLocal: {},
+
       btnRadiusLocal: '',
       inputRadiusLocal: '',
       panelRadiusLocal: '',
@@ -86,81 +97,90 @@ export default {
     selectedVersion () {
       return Array.isArray(this.selected) ? 1 : 2
     },
-    currentTheme () {
+    currentColors () {
       return {
-        colors: {
-          bg: this.bgColorLocal,
-          text: this.textColorLocal,
-          link: this.linkColorLocal,
+        bg: this.bgColorLocal,
+        text: this.textColorLocal,
+        link: this.linkColorLocal,
 
-          fg: this.fgColorLocal,
-          fgText: this.fgTextColorLocal,
-          fgLink: this.fgLinkColorLocal,
+        fg: this.fgColorLocal,
+        fgText: this.fgTextColorLocal,
+        fgLink: this.fgLinkColorLocal,
 
-          panel: this.panelColorLocal,
-          panelText: this.panelTextColorLocal,
-          panelFaint: this.panelFaintColorLocal,
+        panel: this.panelColorLocal,
+        panelText: this.panelTextColorLocal,
+        panelFaint: this.panelFaintColorLocal,
 
-          input: this.inputColorLocal,
-          inputText: this.inputTextColorLocal,
+        input: this.inputColorLocal,
+        inputText: this.inputTextColorLocal,
 
-          topBar: this.topBarColorLocal,
-          topBarText: this.topBarTextColorLocal,
-          topBarLink: this.topBarLinkColorLocal,
+        topBar: this.topBarColorLocal,
+        topBarText: this.topBarTextColorLocal,
+        topBarLink: this.topBarLinkColorLocal,
 
-          btn: this.btnColorLocal,
-          btnText: this.btnTextColorLocal,
+        btn: this.btnColorLocal,
+        btnText: this.btnTextColorLocal,
 
-          alertError: this.alertErrorColorLocal,
-          badgeNotification: this.badgeNotificationColorLocal,
+        alertError: this.alertErrorColorLocal,
+        badgeNotification: this.badgeNotificationColorLocal,
 
-          faint: this.faintColorLocal,
-          faintLink: this.faintLinkColorLocal,
-          border: this.borderColorLocal,
+        faint: this.faintColorLocal,
+        faintLink: this.faintLinkColorLocal,
+        border: this.borderColorLocal,
 
-          cRed: this.cRedColorLocal,
-          cBlue: this.cBlueColorLocal,
-          cGreen: this.cGreenColorLocal,
-          cOrange: this.cOrangeColorLocal
-        },
-        opacity: {
-          bg: this.bgOpacityLocal,
-          btn: this.btnOpacityLocal,
-          input: this.inputOpacityLocal,
-          panel: this.panelOpacityLocal,
-          topBar: this.topBarOpacityLocal,
-          border: this.borderOpacityLocal,
-          faint: this.faintOpacityLocal
-        },
-        radii: {
-          btnRadius: this.btnRadiusLocal,
-          inputRadius: this.inputRadiusLocal,
-          panelRadius: this.panelRadiusLocal,
-          avatarRadius: this.avatarRadiusLocal,
-          avatarAltRadius: this.avatarAltRadiusLocal,
-          tooltipRadius: this.tooltipRadiusLocal,
-          attachmentRadius: this.attachmentRadiusLocal
-        }
+        cRed: this.cRedColorLocal,
+        cBlue: this.cBlueColorLocal,
+        cGreen: this.cGreenColorLocal,
+        cOrange: this.cOrangeColorLocal
       }
     },
-    preview () {
-      try {
-        if (!this.currentTheme.colors.bg) {
-          return {}
-        }
-        return StyleSetter.generatePreset(this.currentTheme)
-      } catch (e) {
-        console.error('CATCH')
-        console.error(e)
+    currentOpacity () {
+      return {
+        bg: this.bgOpacityLocal,
+        btn: this.btnOpacityLocal,
+        input: this.inputOpacityLocal,
+        panel: this.panelOpacityLocal,
+        topBar: this.topBarOpacityLocal,
+        border: this.borderOpacityLocal,
+        faint: this.faintOpacityLocal
+      }
+    },
+    currentRadii () {
+      return {
+        btn: this.btnRadiusLocal,
+        input: this.inputRadiusLocal,
+        panel: this.panelRadiusLocal,
+        avatar: this.avatarRadiusLocal,
+        avatarAlt: this.avatarAltRadiusLocal,
+        tooltip: this.tooltipRadiusLocal,
+        attachment: this.attachmentRadiusLocal
+      }
+    },
+    previewColors () {
+      if (this.currentColors.bg) {
+        return generateColors({
+          opacity: this.currentOpacity,
+          colors: this.currentColors
+        })
+      } else {
         return {}
       }
     },
+    previewRadii () {
+      return generateRadii(this.currentRadii)
+    },
+    previewShadows () {
+      return generateShadows({ shadows: this.shadowsLocal })
+    },
+    preview () {
+      return composePreset(this.previewColors, this.previewRadii, this.previewShadows)
+    },
     previewTheme () {
-      if (!this.preview.theme) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
+      if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
       return this.preview.theme
     },
     previewContrast () {
-      if (!this.previewTheme.colors) return {}
+      if (!this.previewTheme.colors.bg) return {}
       const colors = this.previewTheme.colors
       const opacity = this.previewTheme.opacity
       if (!colors.bg) return {}
@@ -228,19 +248,19 @@ export default {
       return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
     },
     previewRules () {
-      if (!this.preview.colorRules) return ''
-      return [this.preview.colorRules, this.preview.radiiRules, 'color: var(--text)'].join(';')
+      if (!this.preview.rules) return ''
+      return [...Object.values(this.preview.rules), 'color: var(--text)'].join(';')
     },
     shadowsAvailable () {
       return Object.keys(this.previewTheme.shadows)
     },
     currentShadowOverriden: {
       get () {
-        return this.currentShadow
+        return !!this.currentShadow
       },
       set (val) {
         if (val) {
-          set(this.shadowsLocal, this.shadowSelected, Object.assign({}, this.currentShadowFallback))
+          set(this.shadowsLocal, this.shadowSelected, this.currentShadowFallback.map(_ => Object.assign({}, _)))
         } else {
           del(this.shadowsLocal, this.shadowSelected)
         }
@@ -270,7 +290,12 @@ export default {
       const stringified = JSON.stringify({
         // To separate from other random JSON files and possible future theme formats
         _pleroma_theme_version: 2,
-        theme: this.currentTheme
+        theme: {
+          shadows: this.shadowsLocal,
+          opacity: this.currentOpacity,
+          colors: this.currentColors,
+          radii: this.currentRadii
+        }
       }, null, 2) // Pretty-print and indent with 2 spaces
 
       // Create an invisible link with a data url and simulate a click
@@ -323,47 +348,22 @@ export default {
       this.$store.dispatch('setOption', {
         name: 'customTheme',
         value: {
-          ...this.currentTheme,
-          shadows: this.shadowsLocal
+          shadows: this.shadowsLocal,
+          opacity: this.currentOpacity,
+          colors: this.currentColors,
+          radii: this.currentRadii
         }
       })
     },
 
+    // Clears all the extra stuff when loading V1 theme
     clearV1 () {
-      this.bgOpacityLocal = undefined
-      this.fgOpacityLocal = undefined
-
-      this.fgTextColorLocal = undefined
-      this.fgLinkColorLocal = undefined
-
-      this.btnColorLocal = undefined
-      this.btnTextColorLocal = undefined
-      this.btnOpacityLocal = undefined
-
-      this.inputColorLocal = undefined
-      this.inputTextColorLocal = undefined
-      this.inputOpacityLocal = undefined
-
-      this.panelColorLocal = undefined
-      this.panelTextColorLocal = undefined
-      this.panelFaintColorLocal = undefined
-      this.panelOpacityLocal = undefined
-
-      this.topBarColorLocal = undefined
-      this.topBarTextColorLocal = undefined
-      this.topBarLinkColorLocal = undefined
-      this.topBarOpacityLocal = undefined
-
-      this.borderColorLocal = undefined
-      this.borderOpacityLocal = undefined
-
-      this.faintColorLocal = undefined
-      this.faintOpacityLocal = undefined
-      this.faintLinkColorLocal = undefined
-
-      this.alertErrorColorLocal = undefined
-
-      this.badgeNotificationColorLocal = undefined
+      Object.keys(this.$data)
+        .filter(_ => _.endsWith('ColorLocal') || _.endsWith('OpacityLocal'))
+        .filter(_ => !v1OnlyNames.includes(_))
+        .forEach(key => {
+          set(this.$data, key, undefined)
+        })
     },
 
     /**
diff --git a/src/modules/config.js b/src/modules/config.js
index 375d0167..96f2fd5e 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -1,5 +1,5 @@
 import { set, delete as del } from 'vue'
-import StyleSetter from '../services/style_setter/style_setter.js'
+import { setPreset, setColors } from '../services/style_setter/style_setter.js'
 
 const browserLocale = (window.navigator.language || 'en').split('-')[0]
 
@@ -51,10 +51,10 @@ const config = {
       commit('setOption', {name, value})
       switch (name) {
         case 'theme':
-          StyleSetter.setPreset(value, commit)
+          setPreset(value, commit)
           break
         case 'customTheme':
-          StyleSetter.setColors(value, commit)
+          setColors(value, commit)
       }
     }
   }
diff --git a/src/modules/instance.js b/src/modules/instance.js
index cb724821..611212c3 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -1,5 +1,5 @@
 import { set } from 'vue'
-import StyleSetter from '../services/style_setter/style_setter.js'
+import { setPreset } from '../services/style_setter/style_setter.js'
 
 const defaultState = {
   // Stuff from static/config.json and apiConfig
@@ -54,7 +54,7 @@ const instance = {
           dispatch('setPageTitle')
           break
         case 'theme':
-          StyleSetter.setPreset(value, commit)
+          setPreset(value, commit)
       }
     }
   }
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index aac04055..cfff51ea 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -72,7 +72,7 @@ const getTextColor = function (bg, text, preserve) {
 }
 
 const setColors = (input, commit) => {
-  const { colorRules, radiiRules, shadowRules, theme } = generatePreset(input)
+  const { rules, theme } = generatePreset(input)
   const head = document.head
   const body = document.body
   body.style.display = 'none'
@@ -81,10 +81,11 @@ const setColors = (input, commit) => {
   head.appendChild(styleEl)
   const styleSheet = styleEl.sheet
 
+  console.log(rules)
   styleSheet.toString()
-  styleSheet.insertRule(`body { ${colorRules} }`, 'index-max')
-  styleSheet.insertRule(`body { ${radiiRules} }`, 'index-max')
-  styleSheet.insertRule(`body { ${shadowRules} }`, 'index-max')
+  styleSheet.insertRule(`body { ${rules.radii} }`, 'index-max')
+  styleSheet.insertRule(`body { ${rules.colors} }`, 'index-max')
+  styleSheet.insertRule(`body { ${rules.shadows} }`, 'index-max')
   body.style.display = 'initial'
 
   // commit('setOption', { name: 'colors', value: htmlColors })
@@ -93,7 +94,8 @@ const setColors = (input, commit) => {
   commit('setOption', { name: 'colors', value: theme.colors })
 }
 
-const generateShadow = (input) => {
+const getCssShadow = (input) => {
+  console.log(input)
   // >shad
   return input.map((shad) => [
     shad.x,
@@ -106,27 +108,8 @@ const generateShadow = (input) => {
   ]).join(' ')).join(', ')
 }
 
-const generatePreset = (input) => {
-  const radii = input.radii || {
-    btnRadius: input.btnRadius,
-    inputRadius: input.inputRadius,
-    panelRadius: input.panelRadius,
-    avatarRadius: input.avatarRadius,
-    avatarAltRadius: input.avatarAltRadius,
-    tooltipRadius: input.tooltipRadius,
-    attachmentRadius: input.attachmentRadius
-  }
-  const shadows = {
-    panel: [{
-      x: 1,
-      y: 1,
-      blur: 4,
-      spread: 0,
-      color: '#000000',
-      alpha: 0.6
-    }],
-    ...(input.shadows || {})
-  }
+const generateColors = (input) => {
+  console.log(input.opacity)
   const colors = {}
   const opacity = Object.assign({
     alert: 0.5,
@@ -138,7 +121,7 @@ const generatePreset = (input) => {
     }
     return acc
   }, {}))
-
+  console.log(colors, opacity)
   const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
     if (typeof v === 'object') {
       acc[k] = v
@@ -205,7 +188,11 @@ const generatePreset = (input) => {
       colors[k + 'Link'].a = v
       colors['panelFaint'].a = v
     }
-    colors[k].a = v
+    if (colors[k]) {
+      colors[k].a = v
+    } else {
+      console.error('Wrong key ' + k)
+    }
   })
 
   const htmlColors = Object.entries(colors)
@@ -215,20 +202,99 @@ const generatePreset = (input) => {
           acc.complete[k] = typeof v.a === 'undefined' ? rgb2hex(v) : rgb2rgba(v)
           return acc
         }, { complete: {}, solid: {} })
-
   return {
-    colorRules: Object.entries(htmlColors.complete).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';'),
-    radiiRules: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';'),
-    shadowRules: Object.entries(shadows).filter(([k, v]) => v).map(([k, v]) => `--${k}-shadow: ${generateShadow(v)}`).join(';'),
+    rules: {
+      colors: Object.entries(htmlColors.complete)
+        .filter(([k, v]) => v)
+        .map(([k, v]) => `--${k}: ${v}`)
+        .join(';')
+    },
     theme: {
       colors: htmlColors.solid,
-      shadows,
-      opacity,
+      opacity
+    }
+  }
+}
+
+const generateRadii = (input) => {
+  const inputRadii = input.radii || {
+    btn: input.btnRadius,
+    input: input.inputRadius,
+    panel: input.panelRadius,
+    avatar: input.avatarRadius,
+    avatarAlt: input.avatarAltRadius,
+    tooltip: input.tooltipRadius,
+    attachment: input.attachmentRadius
+  }
+
+  const radii = {
+    btn: 4,
+    input: 4,
+    panel: 10,
+    avatar: 5,
+    avatarAlt: 50,
+    tooltip: 2,
+    attachment: 5,
+    ...inputRadii
+  }
+
+  return {
+    rules: {
+      radii: Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}Radius: ${v}px`).join(';')
+    },
+    theme: {
       radii
     }
   }
 }
 
+const generateShadows = (input) => {
+  const shadows = {
+    panel: [{
+      x: 1,
+      y: 1,
+      blur: 4,
+      spread: 0,
+      color: '#000000',
+      alpha: 0.6
+    }],
+    ...(input.shadows || {})
+  }
+  console.log('benis')
+
+  return {
+    rules: {
+      shadows: Object.entries(shadows).filter(([k, v]) => v).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';')
+    },
+    theme: {
+      shadows
+    }
+  }
+}
+
+const composePreset = (colors, radii, shadows) => {
+  return {
+    rules: {
+      ...shadows.rules,
+      ...colors.rules,
+      ...radii.rules
+    },
+    theme: {
+      ...shadows.theme,
+      ...colors.theme,
+      ...radii.theme
+    }
+  }
+}
+
+const generatePreset = (input) => {
+  const shadows = generateShadows(input)
+  const colors = generateColors(input)
+  const radii = generateRadii(input)
+
+  return composePreset(colors, radii, shadows)
+}
+
 const setPreset = (val, commit) => {
   window.fetch('/static/styles.json')
     .then((data) => data.json())
@@ -267,13 +333,15 @@ const setPreset = (val, commit) => {
     })
 }
 
-const StyleSetter = {
+export {
   setStyle,
   setPreset,
   setColors,
   getTextColor,
+  generateColors,
+  generateRadii,
+  generateShadows,
   generatePreset,
-  generateShadow
+  composePreset,
+  getCssShadow
 }
-
-export default StyleSetter

From cb8218c3c1b567d6e2eac570a5a12cf37951239f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 19 Nov 2018 21:01:46 +0300
Subject: [PATCH 19/96] consolelog

---
 src/services/style_setter/style_setter.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index cfff51ea..e7d8252c 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -95,7 +95,6 @@ const setColors = (input, commit) => {
 }
 
 const getCssShadow = (input) => {
-  console.log(input)
   // >shad
   return input.map((shad) => [
     shad.x,

From 32132e225c749e506285370a2a065bb71920ce59 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 20 Nov 2018 20:58:20 +0300
Subject: [PATCH 20/96] localization and small fixes

---
 src/components/color_input/color_input.vue    | 17 ++++---
 .../opacity_input/opacity_input.vue           | 17 ++++---
 .../shadow_control/shadow_control.vue         | 27 ++++++-----
 .../style_switcher/style_switcher.js          |  1 +
 .../style_switcher/style_switcher.vue         | 44 ++++++++---------
 src/i18n/en.json                              | 47 ++++++++++++++++++-
 6 files changed, 99 insertions(+), 54 deletions(-)

diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index ea9fb3c4..b756d265 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -1,17 +1,16 @@
 <template>
-<div class="color-control" :class="{ disabled: !present || disabled }">
+<div class="color-control style-control" :class="{ disabled: !present || disabled }">
   <label :for="name" class="label">
     {{label}}
   </label>
   <input
-  v-if="typeof fallback !== 'undefined'"
-  class="opt"
-  :id="name + '-o'"
-      type="checkbox"
-  :checked="present"
-           @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
-           >
-           <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
+    v-if="typeof fallback !== 'undefined'"
+    class="opt"
+    :id="name + '-o'"
+    type="checkbox"
+    :checked="present"
+    @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)">
+  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
   <input
     :id="name"
     class="color-input"
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index 91c4f5e9..e0567ec7 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -1,16 +1,15 @@
 <template>
-<div class="opacity-control" :class="{ disabled: !present || disabled }">
+<div class="opacity-control style-control" :class="{ disabled: !present || disabled }">
   <label :for="name" class="label">
-    {{$t('settings.opacity')}}
+    {{$t('settings.style.common.opacity')}}
   </label>
   <input
-  v-if="typeof fallback !== 'undefined'"
-  class="opt"
-  :id="name + '-o'"
-      type="checkbox"
-  :checked="present"
-           @input="$emit('input', !present ? fallback : undefined)"
-           >
+    v-if="typeof fallback !== 'undefined'"
+    class="opt"
+    :id="name + '-o'"
+    type="checkbox"
+    :checked="present"
+    @input="$emit('input', !present ? fallback : undefined)">
   <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
   <input
     :id="name"
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index 6847278c..b99df35a 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -40,16 +40,17 @@
 
   <div class="shadow-tweak">
     <div :disabled="usingFallback" class="id-control">
-      <label for="id" class="label">
-        Shadow id
+      <label for="shadow-switcher" class="select">
+        <select
+          v-model="selectedId" class="shadow-switcher"
+          :disabled="usingFallback"
+          id="shadow-switcher">
+          <option v-for="(shadow, index) in cValue" :value="index">
+            {{$t('settings.style.shadows.shadow_id', { value: index })}}
+          </option>
+        </select>
+        <i class="icon-down-open"/>
       </label>
-      <input
-        v-model="selectedId"
-        :disabled="usingFallback"
-        class="input-number"
-        type="number"
-        min="0"
-        :max="cValue.length - 1">
       <button class="btn btn-default" :disabled="!present" @click="del">
         <i class="icon-cancel"/>
       </button>
@@ -65,7 +66,7 @@
     </div>
     <div :disabled="!present" class="inset-control">
       <label for="inset" class="label">
-        Inset
+        {{$t('settings.style.shadows.inset')}}
       </label>
       <input
         v-model="selected.inset"
@@ -78,7 +79,7 @@
     </div>
     <div :disabled="!present" class="blur-control">
       <label for="spread" class="label">
-        Blur
+        {{$t('settings.style.shadows.blur')}}
       </label>
       <input
         v-model="selected.blur"
@@ -98,7 +99,7 @@
     </div>
     <div :disabled="!present" class="spread-control">
       <label for="spread" class="label">
-        Spread
+        {{$t('settings.style.shadows.spread')}}
       </label>
       <input
         v-model="selected.spread"
@@ -118,7 +119,7 @@
     <ColorInput
       v-model="selected.color"
       :disabled="!present"
-      label="Color"
+      :label="$t('settings.style.common.color')"
       name="shadow"/>
     <OpacityInput
       v-model="selected.alpha"
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index e523cd7b..7cb6197c 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -7,6 +7,7 @@ import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
 import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
 
+// List of color values used in v1
 const v1OnlyNames = [
   'bg',
   'fg',
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index af816a23..fd5d830a 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -47,9 +47,9 @@
 
     <p>{{$t('settings.theme_help')}}</p>
     <tab-switcher>
-      <div label="Basic" class="color-container">
+      <div :label="$t('settings.style.basic_colors._tab_label')" class="color-container">
         <div class="color-item">
-          <h4>Main colors</h4>
+          <h4>{{ $t('settings.style.basic_colors.main') }}</h4>
           <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
           <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
           <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
@@ -58,14 +58,14 @@
           <ContrastRatio :contrast="previewContrast.bgLink"/>
         </div>
         <div class="color-item">
-          <h4>Panel header, top bar, buttons, text fields</h4>
+          <h4>{{ $t('settings.style.basic_colors.foreground') }}</h4>
           <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
           <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
           <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
-          <p>See "Advanced" tab for more detailed control</p>
+          <p>{{ $t('settings.style.basic_colors.foreground_hint') }}</p>
         </div>
         <div class="color-item">
-          <h4>Icons, alerts, etc.</h4>
+          <h4>{{ $t('settings.style.basic_colors.rgbo') }}</h4>
           <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
           <ContrastRatio :contrast="previewContrast.bgRed"/>
           <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
@@ -80,25 +80,25 @@
         </div>
       </div>
 
-      <div label="Advanced" class="color-container">
+      <div :label="$t('settings.style.advanced_colors._tab_label')" class="color-container">
         <div class="color-item">
-          <h4>Alerts</h4>
-          <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.error')" :fallback="previewTheme.colors.alertError"/>
+          <h4>{{ $t('settings.style.advanced_colors.alert') }}</h4>
+          <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.style.advanced_colors.alert_error')" :fallback="previewTheme.colors.alertError"/>
           <ContrastRatio :contrast="previewContrast.alertError"/>
         </div>
         <div class="color-item">
-          <h4>Badges</h4>
-          <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.notification')" :fallback="previewTheme.colors.badgeNotification"/>
+          <h4>{{ $t('settings.style.advanced_colors.badge') }}</h4>
+          <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.style.advanced_colors.badge_notification')" :fallback="previewTheme.colors.badgeNotification"/>
         </div>
         <div class="color-item">
-          <h4>Panel header</h4>
+          <h4>{{ $t('settings.style.advanced_colors.panel_header') }}</h4>
           <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
           <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
           <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
           <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
         </div>
         <div class="color-item">
-          <h4>Top bar</h4>
+          <h4>{{ $t('settings.style.advanced_colors.top_bar') }}</h4>
           <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
           <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
           <ContrastRatio :contrast="previewContrast.topBarText"/>
@@ -106,33 +106,33 @@
           <ContrastRatio :contrast="previewContrast.topBarLink"/>
         </div>
         <div class="color-item">
-          <h4>Text fields</h4>
+          <h4>{{ $t('settings.style.advanced_colors.inputs') }}</h4>
           <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
           <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
           <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
           <ContrastRatio :contrast="previewContrast.inputText"/>
         </div>
         <div class="color-item">
-          <h4>Buttons</h4>
+          <h4>{{ $t('settings.style.advanced_colors.buttons') }}</h4>
           <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
           <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
           <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
           <ContrastRatio :contrast="previewContrast.btnText"/>
         </div>
         <div class="color-item">
-          <h4>Borders</h4>
+          <h4>{{ $t('settings.style.advanced_colors.borders') }}</h4>
           <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
           <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
         </div>
         <div class="color-item">
-          <h4>Faint text</h4>
+          <h4>{{ $t('settings.style.advanced_colors.faint_text') }}</h4>
           <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
           <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
-          <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.panel')"/>
+          <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.style.advanced_colors.panel_header')"/>
           <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
         </div>
       </div>
-      <div label="Roundness" class="radius-container">
+      <div :label="$t('settings.style.radii._tab_label')" class="radius-container">
         <p>{{$t('settings.radii_help')}}</p>
         <div class="radius-item">
           <label for="btnradius" class="theme-radius-lb">{{$t('settings.btnRadius')}}</label>
@@ -170,20 +170,20 @@
           <input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
         </div>
       </div>
-      <div label="Shadow Realm" class="shadow-container">
+      <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
         <div>
-          Shadow
+          {{$t('settings.style.shadows.component')}}
           <label for="shadow-switcher" class="shadow-selector select">
             <select id="shadow-switcher" v-model="shadowSelected" class="shadow-switcher">
               <option v-for="shadow in shadowsAvailable"
                       :value="shadow">
-                {{shadow}}
+                {{$t('settings.style.shadows.components.' + shadow)}}
               </option>
             </select>
             <i class="icon-down-open"/>
           </label>
           <label for="override" class="label">
-            Override
+            {{$t('settings.style.shadows.override')}}
           </label>
           <input
             v-model="currentShadowOverriden"
diff --git a/src/i18n/en.json b/src/i18n/en.json
index d825dcc1..04e9977b 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -108,7 +108,6 @@
     "follow_import_error": "Error importing followers",
     "follows_imported": "Follows imported! Processing them will take a while.",
     "foreground": "Foreground",
-    "opacity": "Opacity",
     "general": "General",
     "hide_attachments_in_convo": "Hide attachments in conversations",
     "hide_attachments_in_tl": "Hide attachments in timeline",
@@ -162,6 +161,52 @@
     "values": {
       "false": "no",
       "true": "yes"
+    },
+    "style": {
+      "common": {
+        "color": "Color",
+        "opacity": "Opacity"
+      },
+      "basic_colors": {
+        "_tab_label": "Basic",
+        "main": "Basic colors",
+        "foreground": "Panel header, top bar, buttons, text fields",
+        "foreground_hint": "See \"Advanced\" tab for more detailed control",
+        "rgbo": "Icons, accents, badges"
+      },
+      "advanced_colors": {
+        "_tab_label": "Advanced",
+        "alert": "Alert background",
+        "alert_error": "Error",
+        "badge": "Badge background",
+        "badge_notification": "Notification",
+        "panel_header": "Panel header",
+        "top_bar": "Top bar",
+        "borders": "Borders",
+        "buttons": "Buttons",
+        "inputs": "Input fields",
+        "faint_text": "Faded text"
+      },
+      "radii": {
+        "_tab_label": "Roundness"
+      },
+      "shadows": {
+        "_tab_label": "Shadow and lighting",
+        "component": "Component",
+        "override": "Override",
+        "shadow_id": "Shadow #{value}",
+        "blur": "Blur",
+        "spread": "Spread",
+        "inset": "Inset",
+        "components": {
+          "panel": "Panel",
+          "button": "Button",
+          "button_hover": "Button (hover)",
+          "button_pressed": "Button (pressed)",
+          "button_pressed_hover": "Button (pressed+hover)",
+          "input_box": "Input field"
+        }
+      }
     }
   },
   "timeline": {

From 2609c0d0d279031cba579d60bf94cca81544ec4f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 20 Nov 2018 22:14:49 +0300
Subject: [PATCH 21/96] unification of stylings

---
 src/App.scss                                  |  13 +
 src/components/color_input/color_input.vue    |  35 +--
 .../opacity_input/opacity_input.vue           |  42 +--
 .../shadow_control/shadow_control.vue         |  52 ++--
 .../style_switcher/style_switcher.vue         | 272 +++++-------------
 5 files changed, 104 insertions(+), 310 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 1021b64b..970a5f74 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -64,6 +64,11 @@ button {
   font-size: 14px;
   font-family: sans-serif;
 
+  i[class*=icon-] {
+    color: $fallback--text;
+    color: var(--btnText, $fallback--text);
+  }
+
   &::-moz-focus-inner {
     border: none;
   }
@@ -145,6 +150,14 @@ input, textarea, .select {
     line-height: 16px;
   }
 
+  &[type=range] {
+    background: none;
+    border: none;
+    margin: 0;
+    box-shadow: none;
+    flex: 1;
+  }
+
   &[type=radio],
   &[type=checkbox] {
     display: none;
diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index b756d265..34eec248 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -5,7 +5,7 @@
   </label>
   <input
     v-if="typeof fallback !== 'undefined'"
-    class="opt"
+    class="opt exlcude-disabled"
     :id="name + '-o'"
     type="checkbox"
     :checked="present"
@@ -45,40 +45,9 @@ export default {
 
 <style lang="scss">
 .color-control {
-  display: flex;
-  align-items: baseline;
-
-  &.disabled *:not(.opt-l){
-    opacity: .5
-  }
-
-  .label {
-    flex: 2;
-    min-width: 7em;
-  }
-
-  .opt-l {
-    align-self: center;
-    flex: 0;
-    &::before {
-      width: 14px;
-      height: 14px;
-    }
-  }
-
-  .text-input {
+  input.text-input {
     max-width: 7em;
     flex: 1;
   }
-
-  .color-input {
-    flex: 0;
-    padding: 1px;
-    cursor: pointer;
-    height: 29px;
-    min-width: 2em;
-    border: none;
-    align-self: stretch;
-  }
 }
 </style>
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index e0567ec7..3926915b 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -5,7 +5,7 @@
   </label>
   <input
     v-if="typeof fallback !== 'undefined'"
-    class="opt"
+    class="opt exclude-disabled"
     :id="name + '-o'"
     type="checkbox"
     :checked="present"
@@ -36,43 +36,3 @@ export default {
   }
 }
 </script>
-
-<style lang="scss">
-.opacity-control {
-  display: flex;
-  align-items: baseline;
-
-  &.disabled *:not(.opt-l) {
-    opacity: .5
-  }
-
-  .opt-l {
-    align-self: center;
-    &::before {
-      width: 14px;
-      height: 14px;
-    }
-  }
-
-  .label {
-    flex: 2;
-    min-width: 7em;
-  }
-
-  .input-range {
-    background: none;
-    border: none;
-    margin: 0;
-    height: auto;
-    box-shadow: none;
-    min-width: 7em;
-    flex: 1;
-  }
-
-  .input-number {
-    margin: 0;
-    min-width: 4em;
-    flex: 0;
-  }
-}
-</style>
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index b99df35a..cd774d32 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -39,7 +39,7 @@
   </div>
 
   <div class="shadow-tweak">
-    <div :disabled="usingFallback" class="id-control">
+    <div :disabled="usingFallback" class="id-control style-control">
       <label for="shadow-switcher" class="select">
         <select
           v-model="selectedId" class="shadow-switcher"
@@ -64,7 +64,7 @@
         <i class="icon-plus"/>
       </button>
     </div>
-    <div :disabled="!present" class="inset-control">
+    <div :disabled="!present" class="inset-control style-control">
       <label for="inset" class="label">
         {{$t('settings.style.shadows.inset')}}
       </label>
@@ -77,7 +77,7 @@
         type="checkbox">
       <label class="checkbox-label" for="inset"></label>
     </div>
-    <div :disabled="!present" class="blur-control">
+    <div :disabled="!present" class="blur-control style-control">
       <label for="spread" class="label">
         {{$t('settings.style.shadows.blur')}}
       </label>
@@ -97,7 +97,7 @@
         type="number"
         min="0">
     </div>
-    <div :disabled="!present" class="spread-control">
+    <div :disabled="!present" class="spread-control style-control">
       <label for="spread" class="label">
         {{$t('settings.style.shadows.spread')}}
       </label>
@@ -137,6 +137,11 @@
   flex-wrap: wrap;
   justify-content: center;
 
+
+  .shadow-preview-container,
+  .shadow-tweak {
+    margin: 5px 6px 0 0;
+  }
   .shadow-preview-container {
     flex: 0;
     display: flex;
@@ -210,39 +215,18 @@
   }
 
   .shadow-tweak {
-    .label {
-      flex: 1;
-      min-width: 3em;
-    }
+    flex: 1;
 
-    .inset-control {
-      justify-content: flex-end;
-      label {
-        flex: 0
+    .id-control {
+      align-items: stretch;
+      .select, .btn {
+        margin-right: 5px;
       }
-    }
-
-    .blur-control,
-    .id-control,
-    .inset-control,
-    .spread-control {
-      display: flex;
-      align-items: baseline;
-      max-width: 100%;
-
-      &[disabled=disabled] *{
-        opacity: .5
-      }
-
-      .input-range {
+      .select {
         flex: 1;
-        align-self: center;
-      }
-
-      .input-number {
-        width: 4em;
-        min-width: 4em;
-        flex: 0;
+        select {
+          align-self: initial;
+        }
       }
     }
   }
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index fd5d830a..5f0c2566 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -1,52 +1,53 @@
 <template>
-  <div>
-    <div class="presets-container">
-      <div>
-        {{$t('settings.presets')}}
-        <label for="style-switcher" class='select'>
-          <select id="style-switcher" v-model="selected" class="style-switcher">
-            <option v-for="style in availableStyles"
-                    :value="style"
-                    :style="{
-                            backgroundColor: style[1],
-                            color: style[3]
-                            }">
-              {{style[0]}}
-            </option>
-          </select>
-          <i class="icon-down-open"/>
-        </label>
-      </div>
-      <div class="import-export">
-        <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
-        <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
-        <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
-      </div>
+<div class="style-switcher">
+  <div class="presets-container">
+    <div>
+      {{$t('settings.presets')}}
+      <label for="preset-switcher" class='select'>
+        <select id="preset-switcher" v-model="selected" class="preset-switcher">
+          <option v-for="style in availableStyles"
+                  :value="style"
+                  :style="{
+                          backgroundColor: style[1],
+                          color: style[3]
+                          }">
+            {{style[0]}}
+          </option>
+        </select>
+        <i class="icon-down-open"/>
+      </label>
     </div>
+    <div class="import-export">
+      <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
+      <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
+      <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
+    </div>
+  </div>
 
-    <div class="preview-container">
-      <div class="panel dummy" :style="previewRules">
-        <div class="panel-heading">Preview</div>
-        <div class="panel-body theme-preview-content">
-          <div class="avatar">
-            ( ͡° ͜ʖ ͡°)
-          </div>
-          <h4>Content</h4>
-          <br>
-          A bunch of more content and
-          <a style="color: var(--link)">a nice lil' link</a>
-          <i style="color: var(--cBlue)" class="icon-reply"/>
-          <i style="color: var(--cGreen)" class="icon-retweet"/>
-          <i style="color: var(--cRed)" class="icon-cancel"/>
-          <i style="color: var(--cOrange)" class="icon-star"/>
-          <br>
-          <button class="btn">Button</button>
+  <div class="preview-container">
+    <div class="panel dummy" :style="previewRules">
+      <div class="panel-heading">Preview</div>
+      <div class="panel-body theme-preview-content">
+        <div class="avatar">
+          ( ͡° ͜ʖ ͡°)
         </div>
+        <h4>Content</h4>
+        <br>
+        A bunch of more content and
+        <a style="color: var(--link)">a nice lil' link</a>
+        <i style="color: var(--cBlue)" class="icon-reply"/>
+        <i style="color: var(--cGreen)" class="icon-retweet"/>
+        <i style="color: var(--cRed)" class="icon-cancel"/>
+        <i style="color: var(--cOrange)" class="icon-star"/>
+        <br>
+        <button class="btn">Button</button>
       </div>
     </div>
+  </div>
 
-    <p>{{$t('settings.theme_help')}}</p>
-    <tab-switcher>
+  <p>{{$t('settings.theme_help')}}</p>
+  <keep-alive>
+    <tab-switcher key="style-tweak">
       <div :label="$t('settings.style.basic_colors._tab_label')" class="color-container">
         <div class="color-item">
           <h4>{{ $t('settings.style.basic_colors.main') }}</h4>
@@ -171,31 +172,36 @@
         </div>
       </div>
       <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
-        <div>
-          {{$t('settings.style.shadows.component')}}
-          <label for="shadow-switcher" class="shadow-selector select">
-            <select id="shadow-switcher" v-model="shadowSelected" class="shadow-switcher">
-              <option v-for="shadow in shadowsAvailable"
-                      :value="shadow">
-                {{$t('settings.style.shadows.components.' + shadow)}}
-              </option>
-            </select>
-            <i class="icon-down-open"/>
-          </label>
-          <label for="override" class="label">
-            {{$t('settings.style.shadows.override')}}
-          </label>
-          <input
-            v-model="currentShadowOverriden"
-            name="override"
-            id="override"
-            class="input-override"
-            type="checkbox">
-          <label class="checkbox-label" for="override"></label>
+        <div class="shadow-selector">
+          <div>
+            {{$t('settings.style.shadows.component')}}
+            <label for="shadow-switcher" class="select">
+              <select id="shadow-switcher" v-model="shadowSelected" class="shadow-switcher">
+                <option v-for="shadow in shadowsAvailable"
+                        :value="shadow">
+                  {{$t('settings.style.shadows.components.' + shadow)}}
+                </option>
+              </select>
+              <i class="icon-down-open"/>
+            </label>
+          </div>
+          <div class="override">
+            <label for="override" class="label">
+              {{$t('settings.style.shadows.override')}}
+            </label>
+            <input
+              v-model="currentShadowOverriden"
+              name="override"
+              id="override"
+              class="input-override"
+              type="checkbox">
+            <label class="checkbox-label" for="override"></label>
+          </div>
         </div>
         <shadow-control v-if="currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
       </div>
     </tab-switcher>
+  </keep-alive>
 
   <div class="apply-container">
     <button class="btn submit" @click="setCustomTheme">{{$t('general.apply')}}</button>
@@ -205,142 +211,4 @@
 
 <script src="./style_switcher.js"></script>
 
-<style lang="scss">
-@import '../../_variables.scss';
-.style-switcher {
-  margin-right: 1em;
-}
-
-.import-warning {
-  color: $fallback--cRed;
-  color: var(--cRed, $fallback--cRed);
-}
-
-.apply-container,
-.radius-container,
-.color-container,
-.presets-container {
-  display: flex;
-
-  p {
-    margin-left: 1em
-  }
-}
-
-.radius-container {
-  flex-direction: column;
-}
-
-.color-container{
-  flex-wrap: wrap;
-  justify-content: space-between;
-}
-
-.presets-container {
-  justify-content: center;
-  .import-export {
-    display: flex;
-
-    .btn {
-      margin-left: .5em;
-    }
-  }
-}
-
-.preview-container {
-  border-top: 1px dashed;
-  border-bottom: 1px dashed;
-  border-color: $fallback--border;
-  border-color: var(--border, $fallback--border);
-  margin: 1em -1em 0;
-  padding: 1em;
-  background: var(--body-background-image);
-  background-size: cover;
-  background-position: 50% 50%;
-
-  .btn {
-    margin-top: 1em;
-    min-height: 30px;
-    width: 10em;
-  }
-}
-
-.apply-container {
-  justify-content: center;
-}
-
-.radius-item,
-.color-item {
-  min-width: 20em;
-  margin: 5px 6px 0 0;
-  display:flex;
-  flex-direction: column;
-  flex: 1 1 0;
-
-  &.wide {
-    min-width: 60%
-  }
-  &:not(.wide):nth-child(2n+1) {
-    margin-right: 7px;
-
-  }
-
-  .color, .opacity {
-    display:flex;
-    align-items: baseline;
-  }
-
-  h4 {
-    margin-top: 1em;
-  }
-}
-
-.radius-item {
-  flex-basis: auto;
-}
-
-.theme-radius-rn,
-.theme-color-cl {
-  border: 0;
-  box-shadow: none;
-  background: transparent;
-  color: var(--faint, $fallback--faint);
-  align-self: stretch;
-}
-
-.theme-color-cl,
-.theme-radius-in,
-.theme-color-in {
-  margin-left: 4px;
-}
-
-.theme-radius-in {
-  min-width: 1em;
-}
-
-.theme-radius-in {
-  max-width: 7em;
-  flex: 1;
-}
-
-.theme-radius-lb{
-  max-width: 50em;
-}
-
-.theme-preview-content {
-  padding: 20px;
-}
-
-.dummy {
-  .avatar {
-    background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
-    color: black;
-    text-align: center;
-    height: 48px;
-    line-height: 48px;
-    width: 48px;
-    float: left;
-    margin-right: 1em;
-  }
-}
-</style>
+<style src="./style_switcher.scss" lang="scss"></style>

From d7af2c8419df59d8b897bc57e94f6cc67bd60eca Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 20 Nov 2018 23:25:38 +0300
Subject: [PATCH 22/96] mentioned bug in tab-switcher, made shadow-control work
 in zero-state

---
 .../shadow_control/shadow_control.js          | 19 +++++++++++++------
 .../shadow_control/shadow_control.vue         |  7 +++----
 .../style_switcher/style_switcher.js          |  4 ++++
 .../style_switcher/style_switcher.vue         |  2 +-
 src/components/tab_switcher/tab_switcher.jsx  |  2 ++
 5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
index 54813685..b4f48668 100644
--- a/src/components/shadow_control/shadow_control.js
+++ b/src/components/shadow_control/shadow_control.js
@@ -37,9 +37,12 @@ export default {
       this.selectedId += 1
     }
   },
+  beforeUpdate () {
+    this.cValue = this.value || this.fallback
+  },
   computed: {
     selected () {
-      return this.cValue[this.selectedId] || {
+      return this.isReady && this.cValue[this.selectedId] || {
         x: 0,
         y: 0,
         blur: 0,
@@ -50,13 +53,17 @@ export default {
       }
     },
     moveUpValid () {
-      return this.selectedId > 0
+      return this.isReady && this.selectedId > 0
     },
     moveDnValid () {
-      return this.selectedId < this.cValue.length - 1
+      return this.isReady && this.selectedId < this.cValue.length - 1
+    },
+    isReady () {
+      return typeof this.cValue !== 'undefined'
     },
     present () {
-      return typeof this.cValue[this.selectedId] !== 'undefined' &&
+      return this.isReady &&
+        typeof this.cValue[this.selectedId] !== 'undefined' &&
         !this.usingFallback
     },
     usingFallback () {
@@ -66,9 +73,9 @@ export default {
       return hex2rgb(this.selected.color)
     },
     style () {
-      return {
+      return this.isReady ? {
         boxShadow: getCssShadow(this.cValue)
-      }
+      } : {}
     }
   }
 }
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index cd774d32..f8066947 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -43,7 +43,7 @@
       <label for="shadow-switcher" class="select">
         <select
           v-model="selectedId" class="shadow-switcher"
-          :disabled="usingFallback"
+          :disabled="!isReady || usingFallback"
           id="shadow-switcher">
           <option v-for="(shadow, index) in cValue" :value="index">
             {{$t('settings.style.shadows.shadow_id', { value: index })}}
@@ -51,7 +51,7 @@
         </select>
         <i class="icon-down-open"/>
       </label>
-      <button class="btn btn-default" :disabled="!present" @click="del">
+      <button class="btn btn-default" :disabled="!isReady || !present" @click="del">
         <i class="icon-cancel"/>
       </button>
       <button class="btn btn-default" :disabled="!moveUpValid" @click="moveUp">
@@ -60,7 +60,7 @@
       <button class="btn btn-default" :disabled="!moveDnValid" @click="moveDn">
         <i class="icon-down-open"/>
       </button>
-      <button class="btn btn-default" @click="add">
+      <button class="btn btn-default" :disabled="!isReady" @click="add">
         <i class="icon-plus"/>
       </button>
     </div>
@@ -137,7 +137,6 @@
   flex-wrap: wrap;
   justify-content: center;
 
-
   .shadow-preview-container,
   .shadow-tweak {
     margin: 5px 6px 0 0;
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 7cb6197c..acb1764d 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -93,6 +93,9 @@ export default {
   },
   mounted () {
     this.normalizeLocalState(this.$store.state.config.customTheme)
+    if (typeof this.shadowSelected === 'undefined') {
+      this.shadowSelected = this.shadowsAvailable[0]
+    }
   },
   computed: {
     selectedVersion () {
@@ -180,6 +183,7 @@ export default {
       if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
       return this.preview.theme
     },
+    // This needs optimization maybe
     previewContrast () {
       if (!this.previewTheme.colors.bg) return {}
       const colors = this.previewTheme.colors
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 5f0c2566..5cf75636 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -198,7 +198,7 @@
             <label class="checkbox-label" for="override"></label>
           </div>
         </div>
-        <shadow-control v-if="currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
+        <shadow-control :fallback="currentShadowFallback" v-model="currentShadow"/>
       </div>
     </tab-switcher>
   </keep-alive>
diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx
index 3fff38f6..ea582450 100644
--- a/src/components/tab_switcher/tab_switcher.jsx
+++ b/src/components/tab_switcher/tab_switcher.jsx
@@ -1,5 +1,7 @@
 import Vue from 'vue'
 
+// FIXME: This doesn't like v-if directly inside the tab's contents, breaks vue really bad
+
 import './tab_switcher.scss'
 
 export default Vue.component('tab-switcher', {

From 0184d5fff01f03d099de50773e59cb6363c5bede Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 20 Nov 2018 23:34:04 +0300
Subject: [PATCH 23/96] whoops

---
 .../style_switcher/style_switcher.scss        | 192 ++++++++++++++++++
 1 file changed, 192 insertions(+)
 create mode 100644 src/components/style_switcher/style_switcher.scss

diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
new file mode 100644
index 00000000..6e34a0f7
--- /dev/null
+++ b/src/components/style_switcher/style_switcher.scss
@@ -0,0 +1,192 @@
+@import '../../_variables.scss';
+.style-switcher {
+  .preset-switcher {
+    margin-right: 1em;
+  }
+
+  .style-control {
+    display: flex;
+    align-items: baseline;
+    margin-bottom: 5px;
+
+    .label {
+      flex: 1;
+    }
+
+    input, select {
+      min-width: 3em;
+      margin: 0;
+      flex: 0;
+
+      &[type=color] {
+        padding: 1px;
+        cursor: pointer;
+        height: 29px;
+        min-width: 2em;
+        border: none;
+        align-self: stretch;
+      }
+
+      &[type=number] {
+        min-width: 5em;
+      }
+
+      &[type=range] {
+        flex: 1;
+        min-width: 3em;
+      }
+
+      &[type=checkbox] + label {
+        margin: 6px 0;
+      }
+
+      &:not([type=number]):not([type=text]) {
+        align-self: center;
+      }
+
+      &.disabled *:not(.exlcude-disabled) {
+        opacity: .5
+      }
+    }
+  }
+
+  .import-warning {
+    color: $fallback--cRed;
+    color: var(--cRed, $fallback--cRed);
+  }
+
+  .apply-container,
+  .radius-container,
+  .color-container,
+  .presets-container {
+    display: flex;
+
+    p {
+      margin-left: 1em
+    }
+  }
+
+  .radius-container {
+    flex-direction: column;
+  }
+
+  .color-container{
+    flex-wrap: wrap;
+    justify-content: space-between;
+  }
+
+  .presets-container,
+  .shadow-selector {
+    display: flex;
+    justify-content: center;
+    align-items: baseline;
+
+    .import-export {
+      display: flex;
+
+      .btn {
+        margin-left: .5em;
+      }
+    }
+    .override {
+      margin-left: .5em;
+    }
+  }
+
+  .preview-container {
+    border-top: 1px dashed;
+    border-bottom: 1px dashed;
+    border-color: $fallback--border;
+    border-color: var(--border, $fallback--border);
+    margin: 1em -1em 0;
+    padding: 1em;
+    background: var(--body-background-image);
+    background-size: cover;
+    background-position: 50% 50%;
+
+    .btn {
+      margin-top: 1em;
+      min-height: 30px;
+      width: 10em;
+    }
+  }
+
+  .apply-container {
+    justify-content: center;
+  }
+
+  .radius-item,
+  .color-item {
+    min-width: 20em;
+    margin: 5px 6px 0 0;
+    display:flex;
+    flex-direction: column;
+    flex: 1 1 0;
+
+    &.wide {
+      min-width: 60%
+    }
+    &:not(.wide):nth-child(2n+1) {
+      margin-right: 7px;
+
+    }
+
+    .color, .opacity {
+      display:flex;
+      align-items: baseline;
+    }
+
+    h4 {
+      margin-top: 1em;
+    }
+  }
+
+  .radius-item {
+    flex-basis: auto;
+  }
+
+  .theme-radius-rn,
+  .theme-color-cl {
+    border: 0;
+    box-shadow: none;
+    background: transparent;
+    color: var(--faint, $fallback--faint);
+    align-self: stretch;
+  }
+
+  .theme-color-cl,
+  .theme-radius-in,
+  .theme-color-in {
+    margin-left: 4px;
+  }
+
+  .theme-radius-in {
+    min-width: 1em;
+  }
+
+  .theme-radius-in {
+    max-width: 7em;
+    flex: 1;
+  }
+
+  .theme-radius-lb{
+    max-width: 50em;
+  }
+
+  .theme-preview-content {
+    padding: 20px;
+  }
+
+  .dummy {
+    .avatar {
+      background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
+      color: black;
+      text-align: center;
+      height: 48px;
+      line-height: 48px;
+      width: 48px;
+      float: left;
+      margin-right: 1em;
+    }
+  }
+}

From 73a9370710f46c0594eda01ac8fe016e87c7e18c Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 03:14:59 +0300
Subject: [PATCH 24/96] fixed and updated roundness tab

---
 src/components/range_input/range_input.vue    | 48 +++++++++++++++++++
 .../style_switcher/style_switcher.js          | 23 +++++----
 .../style_switcher/style_switcher.scss        | 12 +++--
 .../style_switcher/style_switcher.vue         | 42 +++-------------
 src/services/style_setter/style_setter.js     | 25 +++-------
 5 files changed, 84 insertions(+), 66 deletions(-)
 create mode 100644 src/components/range_input/range_input.vue

diff --git a/src/components/range_input/range_input.vue b/src/components/range_input/range_input.vue
new file mode 100644
index 00000000..3e50664b
--- /dev/null
+++ b/src/components/range_input/range_input.vue
@@ -0,0 +1,48 @@
+<template>
+<div class="range-control style-control" :class="{ disabled: !present || disabled }">
+  <label :for="name" class="label">
+    {{label}}
+  </label>
+  <input
+    v-if="typeof fallback !== 'undefined'"
+    class="opt exclude-disabled"
+    :id="name + '-o'"
+    type="checkbox"
+    :checked="present"
+    @input="$emit('input', !present ? fallback : undefined)">
+  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
+  <input
+    :id="name"
+    class="input-number"
+    type="range"
+    :value="value || fallback"
+    :disabled="!present || disabled"
+    @input="$emit('input', $event.target.value)"
+    :max="max || hardMax || 100"
+    :min="min || hardMin || 0"
+    :step="step || 1">
+  <input
+    :id="name"
+    class="input-number"
+    type="number"
+    :value="value || fallback"
+    :disabled="!present || disabled"
+    @input="$emit('input', $event.target.value)"
+    :max="hardMax"
+    :min="hardMin"
+    :step="step || 1">
+</div>
+</template>
+
+<script>
+export default {
+  props: [
+    'name', 'value', 'fallback', 'disabled', 'label', 'max', 'min', 'step', 'hardMin', 'hardMax'
+  ],
+  computed: {
+    present () {
+      return typeof this.value !== 'undefined'
+    }
+  }
+}
+</script>
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index acb1764d..d0f72427 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -2,9 +2,10 @@ import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/c
 import { set, delete as del } from 'vue'
 import { generateColors, generateShadows, generateRadii, composePreset } from '../../services/style_setter/style_setter.js'
 import ColorInput from '../color_input/color_input.vue'
+import RangeInput from '../range_input/range_input.vue'
+import OpacityInput from '../opacity_input/opacity_input.vue'
 import ShadowControl from '../shadow_control/shadow_control.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
-import OpacityInput from '../opacity_input/opacity_input.vue'
 import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
 
 // List of color values used in v1
@@ -171,7 +172,7 @@ export default {
       }
     },
     previewRadii () {
-      return generateRadii(this.currentRadii)
+      return generateRadii({ radii: this.currentRadii })
     },
     previewShadows () {
       return generateShadows({ shadows: this.shadowsLocal })
@@ -181,6 +182,7 @@ export default {
     },
     previewTheme () {
       if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
+      console.log(this.preview.theme.radii)
       return this.preview.theme
     },
     // This needs optimization maybe
@@ -286,6 +288,7 @@ export default {
   components: {
     ColorInput,
     OpacityInput,
+    RangeInput,
     ContrastRatio,
     ShadowControl,
     TabSwitcher
@@ -379,6 +382,8 @@ export default {
     normalizeLocalState (input, version = 0) {
       const colors = input.colors || input
       const radii = input.radii || input
+      console.log('Benis')
+      console.log(JSON.stringify(radii, null, 2))
       const opacity = input.opacity || input
       const shadows = input.shadows || {}
 
@@ -417,13 +422,13 @@ export default {
       })
 
       // TODO optimize this
-      this.btnRadiusLocal = radii.btnRadius || 4
-      this.inputRadiusLocal = radii.inputRadius || 4
-      this.panelRadiusLocal = radii.panelRadius || 10
-      this.avatarRadiusLocal = radii.avatarRadius || 5
-      this.avatarAltRadiusLocal = radii.avatarAltRadius || 50
-      this.tooltipRadiusLocal = radii.tooltipRadius || 2
-      this.attachmentRadiusLocal = radii.attachmentRadius || 5
+      this.btnRadiusLocal = radii.btn
+      this.inputRadiusLocal = radii.input
+      this.panelRadiusLocal = radii.panel
+      this.avatarRadiusLocal = radii.avatar
+      this.avatarAltRadiusLocal = radii.avatarAlt
+      this.tooltipRadiusLocal = radii.tooltip
+      this.attachmentRadiusLocal = radii.attachment
 
       this.shadowsLocal = shadows
 
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 6e34a0f7..6c6e913a 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -13,6 +13,14 @@
       flex: 1;
     }
 
+    &.disabled {
+      input, select {
+        &:not(.exclude-disabled) {
+          opacity: .5
+        }
+      }
+    }
+
     input, select {
       min-width: 3em;
       margin: 0;
@@ -43,10 +51,6 @@
       &:not([type=number]):not([type=text]) {
         align-self: center;
       }
-
-      &.disabled *:not(.exlcude-disabled) {
-        opacity: .5
-      }
     }
   }
 
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 5cf75636..54ea072f 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -135,41 +135,13 @@
       </div>
       <div :label="$t('settings.style.radii._tab_label')" class="radius-container">
         <p>{{$t('settings.radii_help')}}</p>
-        <div class="radius-item">
-          <label for="btnradius" class="theme-radius-lb">{{$t('settings.btnRadius')}}</label>
-          <input id="btnradius" class="theme-radius-rn" type="range" v-model="btnRadiusLocal" max="16">
-          <input id="btnradius-t" class="theme-radius-in" type="text" v-model="btnRadiusLocal">
-        </div>
-        <div class="radius-item">
-          <label for="inputradius" class="theme-radius-lb">{{$t('settings.inputRadius')}}</label>
-          <input id="inputradius" class="theme-radius-rn" type="range" v-model="inputRadiusLocal" max="16">
-          <input id="inputradius-t" class="theme-radius-in" type="text" v-model="inputRadiusLocal">
-        </div>
-        <div class="radius-item">
-          <label for="panelradius" class="theme-radius-lb">{{$t('settings.panelRadius')}}</label>
-          <input id="panelradius" class="theme-radius-rn" type="range" v-model="panelRadiusLocal" max="50">
-          <input id="panelradius-t" class="theme-radius-in" type="text" v-model="panelRadiusLocal">
-        </div>
-        <div class="radius-item">
-          <label for="avatarradius" class="theme-radius-lb">{{$t('settings.avatarRadius')}}</label>
-          <input id="avatarradius" class="theme-radius-rn" type="range" v-model="avatarRadiusLocal" max="28">
-          <input id="avatarradius-t" class="theme-radius-in" type="green" v-model="avatarRadiusLocal">
-        </div>
-        <div class="radius-item">
-          <label for="avataraltradius" class="theme-radius-lb">{{$t('settings.avatarAltRadius')}}</label>
-          <input id="avataraltradius" class="theme-radius-rn" type="range" v-model="avatarAltRadiusLocal" max="28">
-          <input id="avataraltradius-t" class="theme-radius-in" type="text" v-model="avatarAltRadiusLocal">
-        </div>
-        <div class="radius-item">
-          <label for="attachmentradius" class="theme-radius-lb">{{$t('settings.attachmentRadius')}}</label>
-          <input id="attachmentrradius" class="theme-radius-rn" type="range" v-model="attachmentRadiusLocal" max="50">
-          <input id="attachmentradius-t" class="theme-radius-in" type="text" v-model="attachmentRadiusLocal">
-        </div>
-        <div class="radius-item">
-          <label for="tooltipradius" class="theme-radius-lb">{{$t('settings.tooltipRadius')}}</label>
-          <input id="tooltipradius" class="theme-radius-rn" type="range" v-model="tooltipRadiusLocal" max="20">
-          <input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
-        </div>
+        <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
+        <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="16" hardMin="0"/>
+        <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
+        <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
+        <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
+        <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
+        <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
       </div>
       <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
         <div class="shadow-selector">
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index e7d8252c..69a1b899 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -81,7 +81,6 @@ const setColors = (input, commit) => {
   head.appendChild(styleEl)
   const styleSheet = styleEl.sheet
 
-  console.log(rules)
   styleSheet.toString()
   styleSheet.insertRule(`body { ${rules.radii} }`, 'index-max')
   styleSheet.insertRule(`body { ${rules.colors} }`, 'index-max')
@@ -108,7 +107,6 @@ const getCssShadow = (input) => {
 }
 
 const generateColors = (input) => {
-  console.log(input.opacity)
   const colors = {}
   const opacity = Object.assign({
     alert: 0.5,
@@ -120,7 +118,6 @@ const generateColors = (input) => {
     }
     return acc
   }, {}))
-  console.log(colors, opacity)
   const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
     if (typeof v === 'object') {
       acc[k] = v
@@ -216,26 +213,19 @@ const generateColors = (input) => {
 }
 
 const generateRadii = (input) => {
-  const inputRadii = input.radii || {
-    btn: input.btnRadius,
-    input: input.inputRadius,
-    panel: input.panelRadius,
-    avatar: input.avatarRadius,
-    avatarAlt: input.avatarAltRadius,
-    tooltip: input.tooltipRadius,
-    attachment: input.attachmentRadius
-  }
-
-  const radii = {
+  console.log(input)
+  const radii = Object.entries(input.radii).filter(([k, v]) => v).reduce((acc, [k, v]) => {
+    acc[k] = v
+    return acc
+  }, {
     btn: 4,
     input: 4,
     panel: 10,
     avatar: 5,
     avatarAlt: 50,
     tooltip: 2,
-    attachment: 5,
-    ...inputRadii
-  }
+    attachment: 5
+  })
 
   return {
     rules: {
@@ -259,7 +249,6 @@ const generateShadows = (input) => {
     }],
     ...(input.shadows || {})
   }
-  console.log('benis')
 
   return {
     rules: {

From b7fb720c190385b887ee7d7c3c46936e9a603862 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 03:23:02 +0300
Subject: [PATCH 25/96] cleanup, cold-boot issue fixed

---
 src/services/style_setter/style_setter.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 69a1b899..45e950f0 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -213,8 +213,7 @@ const generateColors = (input) => {
 }
 
 const generateRadii = (input) => {
-  console.log(input)
-  const radii = Object.entries(input.radii).filter(([k, v]) => v).reduce((acc, [k, v]) => {
+  const radii = Object.entries(input.radii || {}).filter(([k, v]) => v).reduce((acc, [k, v]) => {
     acc[k] = v
     return acc
   }, {

From aa93664fd68e3fc27821fc1b03af25b6a6e6ae87 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 03:51:57 +0300
Subject: [PATCH 26/96] fix coldboot

---
 src/components/user_card_content/user_card_content.js | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index eae436a9..4c7b6a68 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -5,9 +5,8 @@ export default {
   props: [ 'user', 'switcher', 'selected', 'hideBio' ],
   computed: {
     headingStyle () {
-      const color = this.$store.state.config.customTheme.colors.bg
-      if (color) {
-        const rgb = hex2rgb(color)
+      const rgb = this.$store.state.config.customTheme.colors.bg
+      if (rgb) {
         const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)`
         return {
           backgroundColor: `rgb(${Math.floor(rgb.r * 0.53)}, ${Math.floor(rgb.g * 0.56)}, ${Math.floor(rgb.b * 0.59)})`,

From c3d8ff65bdcf02a014aafab93628e0508509d25a Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 03:52:12 +0300
Subject: [PATCH 27/96] fix notification unseen display rendering underneath
 the highlight

---
 src/components/notifications/notifications.scss | 17 +++++++++++++++--
 src/components/notifications/notifications.vue  |  1 +
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index fcc0c3d4..26455ffb 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -26,9 +26,22 @@
     color: var(--text, $fallback--text);
   }
 
-  .unseen {
+  .notification {
+    position: relative;
 
-    background-image: linear-gradient(135deg, var(--badgeNotification, $fallback--cRed) 4px, transparent 10px)
+    .notification-overlay {
+      position: absolute;
+      top: 0;
+      right: 0;
+      left: 0;
+      bottom: 0;
+    }
+
+    &.unseen {
+      .notification-overlay {
+        background-image: linear-gradient(135deg, var(--badgeNotification, $fallback--cRed) 4px, transparent 10px)
+      }
+    }
   }
 }
 
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index 7a4322f9..eb6c4dd0 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -13,6 +13,7 @@
       </div>
       <div class="panel-body">
         <div v-for="notification in visibleNotifications" :key="notification.action.id" class="notification" :class='{"unseen": !notification.seen}'>
+          <div class="notification-overlay"></div>
           <notification :notification="notification"></notification>
         </div>
       </div>

From a79d9d9774a5b8f9f86d1190371df8af42248a1e Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 04:14:10 +0300
Subject: [PATCH 28/96] attempted fix^W workaround for tab-switcher bug

---
 .../style_switcher/style_switcher.vue          | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 54ea072f..fbf9a20a 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -134,14 +134,16 @@
         </div>
       </div>
       <div :label="$t('settings.style.radii._tab_label')" class="radius-container">
-        <p>{{$t('settings.radii_help')}}</p>
-        <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
-        <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="16" hardMin="0"/>
-        <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
-        <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
-        <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
-        <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
-        <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
+        <div>
+          <p>{{$t('settings.radii_help')}}</p>
+          <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
+          <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="16" hardMin="0"/>
+          <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
+          <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
+          <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
+          <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
+          <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
+        </div>
       </div>
       <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
         <div class="shadow-selector">

From 3d6547001ecf9ae5e923d399dfe2c80b920beecf Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 04:14:32 +0300
Subject: [PATCH 29/96] panels now have shadow-overlay so that it's possible to
 have inset shadow all over the panel, without header overlapping it

---
 src/App.scss | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 970a5f74..30020722 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -317,16 +317,33 @@ main-router {
 
 .panel {
   display: flex;
+  position: relative;
+
   flex-direction: column;
   margin: 0.5em;
 
   background-color: $fallback--bg;
   background-color: var(--bg, $fallback--bg);
 
-  border-radius: $fallback--panelRadius;
-  border-radius: var(--panelRadius, $fallback--panelRadius);
-  box-shadow: 1px 1px 4px rgba(0,0,0,.6);
-  box-shadow: var(--panelShadow);
+  &::after, & {
+    border-radius: $fallback--panelRadius;
+    border-radius: var(--panelRadius, $fallback--panelRadius);
+  }
+
+  &::after {
+    content: '';
+    position: absolute;
+
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+
+    pointer-events: none;
+
+    box-shadow: 1px 1px 4px rgba(0,0,0,.6);
+    box-shadow: var(--panelShadow);
+  }
 }
 
 .panel-body:empty::before {

From 50562eb6b700cee84f70210fd1adc8df3b18b92b Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 04:26:45 +0300
Subject: [PATCH 30/96] fix lint, for shadows, it's now possible to refer css
 variables as colors

---
 .../user_card_content/user_card_content.js    |  1 -
 src/services/style_setter/style_setter.js     | 20 ++++++++++++++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index 4c7b6a68..e8073021 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -1,5 +1,4 @@
 import StillImage from '../still-image/still-image.vue'
-import { hex2rgb } from '../../services/color_convert/color_convert.js'
 
 export default {
   props: [ 'user', 'switcher', 'selected', 'hideBio' ],
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 45e950f0..1b7ec7f2 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -101,11 +101,29 @@ const getCssShadow = (input) => {
     shad.blur,
     shad.spread
   ].map(_ => _ + 'px').concat([
-    rgb2rgba({...(hex2rgb(shad.color)), a: shad.alpha}),
+    getCssColor(shad.color, shad.alpha),
     shad.inset ? 'inset' : ''
   ]).join(' ')).join(', ')
 }
 
+const getCssColor = (input, a) => {
+  console.log(input)
+  let rgb = {}
+  if (typeof input === 'object') {
+    rgb = input
+  } else if (typeof input === 'string') {
+    if (input.startsWith('#')) {
+      rgb = hex2rgb(input)
+    } else if (input.startsWith('--')) {
+      return `var(${input})`
+    } else {
+      return input
+    }
+  }
+  console.log(rgb2rgba({ ...rgb, a }))
+  return rgb2rgba({ ...rgb, a })
+}
+
 const generateColors = (input) => {
   const colors = {}
   const opacity = Object.assign({

From acf414e4517434d8847e842930c697b168d94cde Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 07:38:00 +0300
Subject: [PATCH 31/96] changed the way tab-switcher works to avoid
 removing/adding nodes since that seems to cause issues, instead hiding nodes
 with css.

---
 src/components/tab_switcher/tab_switcher.jsx  | 19 ++++++++++---------
 src/components/tab_switcher/tab_switcher.scss |  5 +++++
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx
index ea582450..a044b740 100644
--- a/src/components/tab_switcher/tab_switcher.jsx
+++ b/src/components/tab_switcher/tab_switcher.jsx
@@ -1,7 +1,5 @@
 import Vue from 'vue'
 
-// FIXME: This doesn't like v-if directly inside the tab's contents, breaks vue really bad
-
 import './tab_switcher.scss'
 
 export default Vue.component('tab-switcher', {
@@ -27,11 +25,14 @@ export default Vue.component('tab-switcher', {
             }
             return (<button onClick={this.activateTab(index)} class={ classes.join(' ') }>{slot.data.attrs.label}</button>)
           });
-    const contents = (
-      <div>
-        {this.$slots.default.filter(slot => slot.data)[this.active]}
-      </div>
-    );
+    const contents = this.$slots.default.filter(_=>_.data).map(( slot, index ) => {
+      const active = index === this.active
+      return (
+        <div class={active ? 'active' : 'hidden'}>
+          {slot}
+        </div>
+      )
+    });
     return (
       <div class="tab-switcher">
         <div class="tabs">
@@ -40,7 +41,7 @@ export default Vue.component('tab-switcher', {
         <div class="contents">
           {contents}
         </div>
-      </div>
-    )
+        </div>
+      )
   }
 })
diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index 6f3f9f27..4740fbde 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -1,6 +1,11 @@
 @import '../../_variables.scss';
 
 .tab-switcher {
+  .contents {
+    .hidden {
+      display: none;
+    }
+  }
   .tabs {
     display: flex;
     position: relative;

From dc3df7bc4e91abf4a911e4c5ecc0c627d00dcfb1 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 18:22:05 +0300
Subject: [PATCH 32/96] fixes

---
 src/components/notifications/notifications.scss       | 1 +
 src/components/post_status_form/post_status_form.vue  | 4 ++--
 src/components/timeline/timeline.vue                  | 2 +-
 src/components/user_card_content/user_card_content.js | 6 ++++--
 src/services/style_setter/style_setter.js             | 3 +++
 5 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 26455ffb..3f22b690 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -35,6 +35,7 @@
       right: 0;
       left: 0;
       bottom: 0;
+      pointer-events: none;
     }
 
     &.unseen {
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 4514e79f..751b048a 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -154,7 +154,7 @@
       margin-left: $fallback--attachmentRadius;
       margin-left: var(--attachmentRadius, $fallback--attachmentRadius);
       background-color: $fallback--fg;
-      background-color: var(--fg, $fallback--fg);
+      background-color: var(--btn, $fallback--fg);
       border-bottom-left-radius: 0;
       border-bottom-right-radius: 0;
     }
@@ -292,7 +292,7 @@
 
     &.highlighted {
       background-color: $fallback--fg;
-      background-color: var(--fg, $fallback--fg);
+      background-color: var(--lightBg, $fallback--fg);
     }
   }
 }
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index c2d5b9e6..39f1b5bc 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -75,6 +75,6 @@
   padding: 10px;
   z-index: 1;
   background-color: $fallback--fg;
-  background-color: var(--fg, $fallback--fg);
+  background-color: var(--panel, $fallback--fg);
 }
 </style>
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index e8073021..6f9ed9fe 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -1,11 +1,13 @@
 import StillImage from '../still-image/still-image.vue'
+import { hex2rgb } from '../../services/color_convert/color_convert.js'
 
 export default {
   props: [ 'user', 'switcher', 'selected', 'hideBio' ],
   computed: {
     headingStyle () {
-      const rgb = this.$store.state.config.customTheme.colors.bg
-      if (rgb) {
+      const color = this.$store.state.config.customTheme.colors.bg
+      if (color) {
+        const rgb = (typeof color === 'string') ? hex2rgb(color) : color
         const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)`
         return {
           backgroundColor: `rgb(${Math.floor(rgb.r * 0.53)}, ${Math.floor(rgb.g * 0.56)}, ${Math.floor(rgb.b * 0.59)})`,
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 1b7ec7f2..57bd2841 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -202,6 +202,9 @@ const generateColors = (input) => {
       colors[k + 'Link'].a = v
       colors['panelFaint'].a = v
     }
+    if (k === 'bg') {
+      colors['lightBg'].a = v
+    }
     if (colors[k]) {
       colors[k].a = v
     } else {

From 3bdcdefc9bd697413c5ef4b3e0b606e045b8e612 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 20:18:49 +0300
Subject: [PATCH 33/96] better tooltips, localized, too

---
 .../contrast_ratio/contrast_ratio.vue         | 28 +++++++++++++++----
 src/i18n/en.json                              | 14 +++++++++-
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
index 9a93dcd0..f4f9ea86 100644
--- a/src/components/contrast_ratio/contrast_ratio.vue
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -1,6 +1,6 @@
 <template>
 <span  v-if="contrast" class="contrast-ratio">
-  <span :title="`Contrast is ${contrast.text}`" class="rating">
+  <span :title="hint" class="rating">
     <span v-if="contrast.aaa">
       <i class="icon-thumbs-up-alt"/>
     </span>
@@ -11,14 +11,14 @@
       <i class="icon-attention"/>
     </span>
   </span>
-  <span class="rating" v-if="contrast && large" :title="`Contrast is ${contrast.text} (18pt+)`">
-    <span v-if="contrast.aaa">
+  <span class="rating" v-if="contrast && large" :title="hint_18pt">
+    <span v-if="contrast.laaa">
       <i class="icon-thumbs-up-alt"/>
     </span>
-    <span v-if="!contrast.aaa && contrast.aa">
+    <span v-if="!contrast.laaa && contrast.laa">
       <i class="icon-adjust"/>
     </span>
-    <span v-if="!contrast.aaa && !contrast.aa">
+    <span v-if="!contrast.laaa && !contrast.laa">
       <i class="icon-attention"/>
     </span>
   </span>
@@ -29,7 +29,23 @@
 export default {
   props: [
     'large', 'contrast'
-  ]
+  ],
+  computed: {
+    hint () {
+      const levelVal = this.contrast.aaa ? 'aaa' : (this.contrast.aa ? 'aa' : 'bad')
+      const level = this.$t(`settings.style.common.contrast.level.${levelVal}`)
+      const context = this.$t('settings.style.common.contrast.context.text')
+      const ratio = this.contrast.text
+      return this.$t('settings.style.common.contrast.hint', { level, context, ratio })
+    },
+    hint_18pt () {
+      const levelVal = this.contrast.laaa ? 'aaa' : (this.contrast.laa ? 'aa' : 'bad')
+      const level = this.$t(`settings.style.common.contrast.level.${levelVal}`)
+      const context = this.$t('settings.style.common.contrast.context.18pt')
+      const ratio = this.contrast.text
+      return this.$t('settings.style.common.contrast.hint', { level, context, ratio })
+    }
+  }
 }
 </script>
 
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 04e9977b..18b47ba7 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -165,7 +165,19 @@
     "style": {
       "common": {
         "color": "Color",
-        "opacity": "Opacity"
+        "opacity": "Opacity",
+        "contrast": {
+          "hint": "Contrast ratio is {ratio}, it {level} {context}",
+          "level": {
+            "aa": "meets Level AA guideline (minimal)",
+            "aaa": "meets Level AAA guideline (recommended)",
+            "bad": "doesn't meet any accessibility guidelines"
+          },
+          "context": {
+            "18pt": "for large (18pt+) text",
+            "text": "for text"
+          }
+        }
       },
       "basic_colors": {
         "_tab_label": "Basic",

From 621ab806e63e42e0495fa174fd64f8eaeeb46b91 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 21:23:07 +0300
Subject: [PATCH 34/96] more default shadows, replaced original shadows with
 generated ones. maybe gotta update fallbacks...

---
 src/App.scss                                  | 17 +++--
 src/components/status/status.vue              |  1 +
 .../user_card_content/user_card_content.vue   |  1 +
 src/i18n/en.json                              | 13 +++-
 src/services/style_setter/style_setter.js     | 76 +++++++++++++++++++
 5 files changed, 98 insertions(+), 10 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 30020722..a41140ef 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -58,9 +58,10 @@ button {
   border-radius: $fallback--btnRadius;
   border-radius: var(--btnRadius, $fallback--btnRadius);
   cursor: pointer;
-  border-top: 1px solid rgba(255, 255, 255, 0.2);
-  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
+  /* border-top: 1px solid rgba(255, 255, 255, 0.2); */
+  /* border-bottom: 1px solid rgba(0, 0, 0, 0.2); */
   box-shadow: 0px 0px 2px black;
+  box-shadow: var(--buttonShadow);
   font-size: 14px;
   font-family: sans-serif;
 
@@ -75,11 +76,12 @@ button {
 
   &:hover {
     box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3);
+    box-shadow: var(--buttonHoverShadow);
   }
 
   &:active {
-    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
-    border-top: 1px solid rgba(0, 0, 0, 0.2);
+    /* border-bottom: 1px solid rgba(255, 255, 255, 0.2); */
+    /* border-top: 1px solid rgba(0, 0, 0, 0.2); */
   }
 
   &:disabled {
@@ -104,9 +106,10 @@ input, textarea, .select {
   border: none;
   border-radius: $fallback--inputRadius;
   border-radius: var(--inputRadius, $fallback--inputRadius);
-  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
-  border-top: 1px solid rgba(0, 0, 0, 0.2);
+  /* border-bottom: 1px solid rgba(255, 255, 255, 0.2); */
+  /* border-top: 1px solid rgba(0, 0, 0, 0.2); */
   box-shadow: 0px 0px 2px black inset;
+  box-shadow: var(--inputShadow);
   background-color: $fallback--fg;
   background-color: var(--input, $fallback--fg);
   color: $fallback--lightText;
@@ -184,6 +187,7 @@ input, textarea, .select {
       border-bottom: 1px solid rgba(255, 255, 255, 0.2);
       border-top: 1px solid rgba(0, 0, 0, 0.2);
       box-shadow: 0px 0px 2px black inset;
+      box-shadow: var(--inputShadow);
       margin-right: .5em;
       background-color: $fallback--fg;
       background-color: var(--input, $fallback--fg);
@@ -365,6 +369,7 @@ main-router {
   background-color: $fallback--fg;
   background-color: var(--panel, $fallback--fg);
   align-items: baseline;
+  box-shadow: var(--panelHeaderShadow);
 
   .title {
     flex: 1 0 auto;
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 57a007d9..c4a268d0 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -146,6 +146,7 @@
   border-radius: $fallback--tooltipRadius;
   border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
   box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
+  box-shadow: var(--popupShadow);
   margin-top: 0.25em;
   margin-left: 0.5em;
   z-index: 50;
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index f1b54fad..a2bb99a1 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -155,6 +155,7 @@
       width: 56px;
       height: 56px;
       box-shadow: 0px 1px 8px rgba(0,0,0,0.75);
+      box-shadow: var(--avatarShadow);
       object-fit: cover;
 
       &.animated::before {
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 18b47ba7..3fcc6da2 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -212,11 +212,16 @@
         "inset": "Inset",
         "components": {
           "panel": "Panel",
+          "panelHeader": "Panel header",
+          "topBar": "Top bar",
+          "avatar": "User avatar (in post display)",
+          "avatarStatus": "User avatar (in profile view)",
+          "popup": "Popups and tooltips",
           "button": "Button",
-          "button_hover": "Button (hover)",
-          "button_pressed": "Button (pressed)",
-          "button_pressed_hover": "Button (pressed+hover)",
-          "input_box": "Input field"
+          "buttonHover": "Button (hover)",
+          "buttonPressed": "Button (pressed)",
+          "buttonPressedHover": "Button (pressed+hover)",
+          "input": "Input field"
         }
       }
     }
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 57bd2841..8142da8b 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -258,6 +258,40 @@ const generateRadii = (input) => {
 }
 
 const generateShadows = (input) => {
+  const buttonInsetFakeBorders = [{
+    x: 0,
+    y: 101,
+    blur: 0,
+    spread: -100,
+    color: '#FFFFFF',
+    alpha: 0.2,
+    inset: true
+  }, {
+    x: 0,
+    y: -101,
+    blur: 0,
+    spread: -100,
+    color: '#000000',
+    alpha: 0.2,
+    inset: true
+  }]
+  const inputInsetFakeBorders = [{
+    x: 0,
+    y: 101,
+    blur: 0,
+    spread: -100,
+    color: '#000000',
+    alpha: 0.2,
+    inset: true
+  }, {
+    x: 0,
+    y: -101,
+    blur: 0,
+    spread: -100,
+    color: '#FFFFFF',
+    alpha: 0.3,
+    inset: true
+  }]
   const shadows = {
     panel: [{
       x: 1,
@@ -267,6 +301,48 @@ const generateShadows = (input) => {
       color: '#000000',
       alpha: 0.6
     }],
+    popup: [{
+      x: 2,
+      y: 2,
+      blur: 3,
+      spread: 0,
+      color: '#000000',
+      alpha: 0.5
+    }],
+    avatar: [{
+      x: 0,
+      y: 1,
+      blur: 8,
+      spread: 0,
+      color: '#000000',
+      alpha: 0.7
+    }],
+    panelHeader: [],
+    button: [{
+      x: 0,
+      y: 0,
+      blur: 2,
+      spread: 0,
+      color: '#000000',
+      alpha: 1
+    }, ...buttonInsetFakeBorders],
+    buttonHover: [{
+      x: 0,
+      y: 0,
+      blur: 4,
+      spread: 0,
+      color: '--faint',
+      alpha: 1
+    }, ...buttonInsetFakeBorders],
+    input: [{
+      x: 0,
+      y: 0,
+      blur: 2,
+      inset: true,
+      spread: 0,
+      color: '#000000',
+      alpha: 1
+    }, ...inputInsetFakeBorders],
     ...(input.shadows || {})
   }
 

From de88cfb94d9df08ad8afa7df66d499a2fa249a98 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 21:28:22 +0300
Subject: [PATCH 35/96] compensate tab-switcher for fake borders

---
 src/components/tab_switcher/tab_switcher.scss | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index 4740fbde..fee30800 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -13,6 +13,8 @@
     width: 100%;
     overflow: hidden;
     padding-top: 5px;
+    height: 32px;
+    box-sizing: border-box;
 
     &::after, &::before {
       display: block;
@@ -29,7 +31,7 @@
     .tab {
       border-bottom-left-radius: 0;
       border-bottom-right-radius: 0;
-      padding: .3em 1em;
+      padding: .3em 1em 99px;
 
       &:not(.active) {
         border-bottom: 1px solid;

From 017fa60a82b4a7183dcbac0debf44de3b324ba07 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 21:32:51 +0300
Subject: [PATCH 36/96] better default pleroma shadows, matches original
 borders more closely

---
 src/services/style_setter/style_setter.js | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 8142da8b..b77b2d01 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -260,34 +260,34 @@ const generateRadii = (input) => {
 const generateShadows = (input) => {
   const buttonInsetFakeBorders = [{
     x: 0,
-    y: 101,
+    y: 1,
     blur: 0,
-    spread: -100,
+    spread: 0,
     color: '#FFFFFF',
     alpha: 0.2,
     inset: true
   }, {
     x: 0,
-    y: -101,
+    y: -1,
     blur: 0,
-    spread: -100,
+    spread: 0,
     color: '#000000',
     alpha: 0.2,
     inset: true
   }]
   const inputInsetFakeBorders = [{
     x: 0,
-    y: 101,
+    y: 1,
     blur: 0,
-    spread: -100,
+    spread: 0,
     color: '#000000',
     alpha: 0.2,
     inset: true
   }, {
     x: 0,
-    y: -101,
+    y: -1,
     blur: 0,
-    spread: -100,
+    spread: 0,
     color: '#FFFFFF',
     alpha: 0.3,
     inset: true
@@ -334,7 +334,7 @@ const generateShadows = (input) => {
       color: '--faint',
       alpha: 1
     }, ...buttonInsetFakeBorders],
-    input: [{
+    input: [...inputInsetFakeBorders, {
       x: 0,
       y: 0,
       blur: 2,
@@ -342,7 +342,7 @@ const generateShadows = (input) => {
       spread: 0,
       color: '#000000',
       alpha: 1
-    }, ...inputInsetFakeBorders],
+    }],
     ...(input.shadows || {})
   }
 

From b3ec3d450c8daf100ae7654c8db69551aa5b1a75 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 21:35:18 +0300
Subject: [PATCH 37/96] fixup! better default pleroma shadows, matches original
 borders more closely

---
 src/services/style_setter/style_setter.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index b77b2d01..60eec7ea 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -289,7 +289,7 @@ const generateShadows = (input) => {
     blur: 0,
     spread: 0,
     color: '#FFFFFF',
-    alpha: 0.3,
+    alpha: 0.2,
     inset: true
   }]
   const shadows = {

From 18e0828ee7bf4d90267db62bc079e1d8b3cf45ee Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 21:40:45 +0300
Subject: [PATCH 38/96] last shadow override i wanted to make for now. also
 small tweak

---
 src/App.scss                                         | 1 +
 src/components/post_status_form/post_status_form.vue | 2 ++
 src/components/style_switcher/style_switcher.js      | 2 +-
 src/services/style_setter/style_setter.js            | 8 ++++++++
 4 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/App.scss b/src/App.scss
index a41140ef..e8aa5846 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -430,6 +430,7 @@ nav {
   color: $fallback--faint;
   color: var(--faint, $fallback--faint);
   box-shadow: 0px 0px 4px rgba(0,0,0,.6);
+  box-shadow: var(--topBarShadow);
 }
 
 .fade-enter-active, .fade-leave-active {
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 751b048a..1c79cab3 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -258,6 +258,8 @@
     position: absolute;
     z-index: 1;
     box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5);
+    // this doesn't match original but i don't care, making it uniform.
+    box-shadow: var(--popupShadow);
     min-width: 75%;
     background: $fallback--bg;
     background: var(--bg, $fallback--bg);
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index d0f72427..c39aa95b 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -259,7 +259,7 @@ export default {
       return [...Object.values(this.preview.rules), 'color: var(--text)'].join(';')
     },
     shadowsAvailable () {
-      return Object.keys(this.previewTheme.shadows)
+      return Object.keys(this.previewTheme.shadows).sort()
     },
     currentShadowOverriden: {
       get () {
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 60eec7ea..20f54a84 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -301,6 +301,14 @@ const generateShadows = (input) => {
       color: '#000000',
       alpha: 0.6
     }],
+    topBar: [{
+      x: 0,
+      y: 0,
+      blur: 4,
+      spread: 0,
+      color: '#000000',
+      alpha: 0.6
+    }],
     popup: [{
       x: 2,
       y: 2,

From 92afd6af12abc0a11f721a8f4c181c55522743ac Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 22:01:34 +0300
Subject: [PATCH 39/96] layout fixes

---
 .../contrast_ratio/contrast_ratio.vue           |  3 +++
 .../style_switcher/style_switcher.scss          | 17 +++++++++++++----
 .../style_switcher/style_switcher.vue           | 10 ++++------
 src/i18n/en.json                                |  6 +++---
 4 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
index f4f9ea86..bd971d00 100644
--- a/src/components/contrast_ratio/contrast_ratio.vue
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -54,6 +54,9 @@ export default {
   display: flex;
   justify-content: flex-end;
 
+  margin-top: -4px;
+  margin-bottom: 5px;
+
   .label {
     margin-right: 1em;
   }
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 6c6e913a..f8529b4f 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -59,6 +59,10 @@
     color: var(--cRed, $fallback--cRed);
   }
 
+  .tab-switcher {
+    margin: 0 -1em;
+  }
+
   .apply-container,
   .radius-container,
   .color-container,
@@ -75,10 +79,19 @@
   }
 
   .color-container{
+    > h4 {
+      width: 99%;
+    }
     flex-wrap: wrap;
     justify-content: space-between;
   }
 
+  .color-container,
+  .shadow-container,
+  .radius-container {
+    margin: 1em 1em 0;
+  }
+
   .presets-container,
   .shadow-selector {
     display: flex;
@@ -139,10 +152,6 @@
       display:flex;
       align-items: baseline;
     }
-
-    h4 {
-      margin-top: 1em;
-    }
   }
 
   .radius-item {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index fbf9a20a..4ed62242 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -48,9 +48,9 @@
   <p>{{$t('settings.theme_help')}}</p>
   <keep-alive>
     <tab-switcher key="style-tweak">
-      <div :label="$t('settings.style.basic_colors._tab_label')" class="color-container">
+      <div :label="$t('settings.style.common_colors._tab_label')" class="color-container">
+        <h4>{{ $t('settings.style.common_colors.main') }}</h4>
         <div class="color-item">
-          <h4>{{ $t('settings.style.basic_colors.main') }}</h4>
           <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
           <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
           <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
@@ -59,21 +59,19 @@
           <ContrastRatio :contrast="previewContrast.bgLink"/>
         </div>
         <div class="color-item">
-          <h4>{{ $t('settings.style.basic_colors.foreground') }}</h4>
           <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
           <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
           <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
-          <p>{{ $t('settings.style.basic_colors.foreground_hint') }}</p>
+          <p>{{ $t('settings.style.common_colors.foreground_hint') }}</p>
         </div>
+        <h4>{{ $t('settings.style.common_colors.rgbo') }}</h4>
         <div class="color-item">
-          <h4>{{ $t('settings.style.basic_colors.rgbo') }}</h4>
           <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
           <ContrastRatio :contrast="previewContrast.bgRed"/>
           <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
           <ContrastRatio :contrast="previewContrast.bgBlue"/>
         </div>
         <div class="color-item">
-          <h4>.</h4>
           <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
           <ContrastRatio :contrast="previewContrast.bgGreen"/>
           <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 3fcc6da2..b039757e 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -179,9 +179,9 @@
           }
         }
       },
-      "basic_colors": {
-        "_tab_label": "Basic",
-        "main": "Basic colors",
+      "common_colors": {
+        "_tab_label": "Common",
+        "main": "Common colors",
         "foreground": "Panel header, top bar, buttons, text fields",
         "foreground_hint": "See \"Advanced\" tab for more detailed control",
         "rgbo": "Icons, accents, badges"

From b8b5dbf63e73e9ca7f5683cb6cca8d47e9cee49c Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 22:08:27 +0300
Subject: [PATCH 40/96] fix

---
 src/components/tab_switcher/tab_switcher.jsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx
index a044b740..9e3dee04 100644
--- a/src/components/tab_switcher/tab_switcher.jsx
+++ b/src/components/tab_switcher/tab_switcher.jsx
@@ -41,7 +41,7 @@ export default Vue.component('tab-switcher', {
         <div class="contents">
           {contents}
         </div>
-        </div>
-      )
+      </div>
+    )
   }
 })

From cd6c5b3e33fc71d68892f5d6985a3d27125468bc Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 23:30:47 +0300
Subject: [PATCH 41/96] fix for tab-switcher

---
 src/components/tab_switcher/tab_switcher.scss | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index fee30800..bd93e988 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -29,15 +29,24 @@
     }
 
     .tab {
+      position: relative;
       border-bottom-left-radius: 0;
       border-bottom-right-radius: 0;
-      padding: .3em 1em 99px;
+      padding: 5px 1em 99px;
 
       &:not(.active) {
-        border-bottom: 1px solid;
-        border-bottom-color: $fallback--border;
-        border-bottom-color: var(--border, $fallback--border);
         z-index: 4;
+
+        &::after {
+          content: '';
+          position: absolute;
+          left: 0;
+          right: 0;
+          top: 26px;
+          border-bottom: 1px solid;
+          border-bottom-color: $fallback--border;
+          border-bottom-color: var(--border, $fallback--border);
+        }
       }
 
       &.active {

From 379144f4abe7075d4a86b44d09d712fde5ebaae6 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 22 Nov 2018 03:55:45 +0300
Subject: [PATCH 42/96] fix for zero-state for shadow-control

---
 .../shadow_control/shadow_control.js          | 39 +++++++++++--------
 .../style_switcher/style_switcher.js          |  3 --
 .../style_switcher/style_switcher.vue         |  2 +-
 src/services/style_setter/style_setter.js     |  2 -
 4 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
index b4f48668..a1484d09 100644
--- a/src/components/shadow_control/shadow_control.js
+++ b/src/components/shadow_control/shadow_control.js
@@ -4,13 +4,17 @@ import { getCssShadow } from '../../services/style_setter/style_setter.js'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
 
 export default {
+  // 'Value' and 'Fallback' can be undefined, but if they are
+  // initially vue won't detect it when they become something else
+  // therefore i'm using "ready" which should be passed as true when
+  // data becomes available
   props: [
-    'value', 'fallback'
+    'value', 'fallback', 'ready'
   ],
   data () {
     return {
       selectedId: 0,
-      cValue: this.value || this.fallback
+      cValue: this.value || this.fallback || []
     }
   },
   components: {
@@ -42,27 +46,28 @@ export default {
   },
   computed: {
     selected () {
-      return this.isReady && this.cValue[this.selectedId] || {
-        x: 0,
-        y: 0,
-        blur: 0,
-        spread: 0,
-        inset: false,
-        color: '#000000',
-        alpha: 1
+      if (this.ready && this.cValue.length > 0) {
+        return this.cValue[this.selectedId]
+      } else {
+        return {
+          x: 0,
+          y: 0,
+          blur: 0,
+          spread: 0,
+          inset: false,
+          color: '#000000',
+          alpha: 1
+        }
       }
     },
     moveUpValid () {
-      return this.isReady && this.selectedId > 0
+      return this.ready && this.selectedId > 0
     },
     moveDnValid () {
-      return this.isReady && this.selectedId < this.cValue.length - 1
-    },
-    isReady () {
-      return typeof this.cValue !== 'undefined'
+      return this.ready && this.selectedId < this.cValue.length - 1
     },
     present () {
-      return this.isReady &&
+      return this.ready &&
         typeof this.cValue[this.selectedId] !== 'undefined' &&
         !this.usingFallback
     },
@@ -73,7 +78,7 @@ export default {
       return hex2rgb(this.selected.color)
     },
     style () {
-      return this.isReady ? {
+      return this.ready ? {
         boxShadow: getCssShadow(this.cValue)
       } : {}
     }
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index c39aa95b..2af77a85 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -182,7 +182,6 @@ export default {
     },
     previewTheme () {
       if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
-      console.log(this.preview.theme.radii)
       return this.preview.theme
     },
     // This needs optimization maybe
@@ -382,8 +381,6 @@ export default {
     normalizeLocalState (input, version = 0) {
       const colors = input.colors || input
       const radii = input.radii || input
-      console.log('Benis')
-      console.log(JSON.stringify(radii, null, 2))
       const opacity = input.opacity || input
       const shadows = input.shadows || {}
 
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 4ed62242..658bb288 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -170,7 +170,7 @@
             <label class="checkbox-label" for="override"></label>
           </div>
         </div>
-        <shadow-control :fallback="currentShadowFallback" v-model="currentShadow"/>
+        <shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
       </div>
     </tab-switcher>
   </keep-alive>
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 20f54a84..4a48f419 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -107,7 +107,6 @@ const getCssShadow = (input) => {
 }
 
 const getCssColor = (input, a) => {
-  console.log(input)
   let rgb = {}
   if (typeof input === 'object') {
     rgb = input
@@ -120,7 +119,6 @@ const getCssColor = (input, a) => {
       return input
     }
   }
-  console.log(rgb2rgba({ ...rgb, a }))
   return rgb2rgba({ ...rgb, a })
 }
 

From 324aadb7c180baf51e77d08058683c7e256bfcfb Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 22 Nov 2018 04:25:15 +0300
Subject: [PATCH 43/96] fix

---
 src/components/shadow_control/shadow_control.vue | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index f8066947..2bc05cb7 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -43,7 +43,7 @@
       <label for="shadow-switcher" class="select">
         <select
           v-model="selectedId" class="shadow-switcher"
-          :disabled="!isReady || usingFallback"
+          :disabled="!ready || usingFallback"
           id="shadow-switcher">
           <option v-for="(shadow, index) in cValue" :value="index">
             {{$t('settings.style.shadows.shadow_id', { value: index })}}
@@ -51,7 +51,7 @@
         </select>
         <i class="icon-down-open"/>
       </label>
-      <button class="btn btn-default" :disabled="!isReady || !present" @click="del">
+      <button class="btn btn-default" :disabled="!ready || !present" @click="del">
         <i class="icon-cancel"/>
       </button>
       <button class="btn btn-default" :disabled="!moveUpValid" @click="moveUp">
@@ -60,7 +60,7 @@
       <button class="btn btn-default" :disabled="!moveDnValid" @click="moveDn">
         <i class="icon-down-open"/>
       </button>
-      <button class="btn btn-default" :disabled="!isReady" @click="add">
+      <button class="btn btn-default" :disabled="!ready" @click="add">
         <i class="icon-plus"/>
       </button>
     </div>

From 631b8433c04799a04da5369273f5d1861a346739 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 22 Nov 2018 04:37:49 +0300
Subject: [PATCH 44/96] bundling v2 themes works

---
 .../style_switcher/style_switcher.js          |   2 +
 .../style_switcher/style_switcher.vue         |   6 +-
 static/styles.json                            | 228 +++++++++++++++++-
 3 files changed, 232 insertions(+), 4 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 2af77a85..710694d4 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -447,6 +447,8 @@ export default {
         this.cGreenColorLocal = this.selected[6]
         this.cBlueColorLocal = this.selected[7]
         this.cOrangeColorLocal = this.selected[8]
+      } else if (this.selectedVersion >= 2) {
+        this.normalizeLocalState(this.selected.theme, 2)
       }
     }
   }
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 658bb288..37709363 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -8,10 +8,10 @@
           <option v-for="style in availableStyles"
                   :value="style"
                   :style="{
-                          backgroundColor: style[1],
-                          color: style[3]
+                          backgroundColor: style[1] || style.theme.colors.bg,
+                          color: style[3] || style.theme.colors.text
                           }">
-            {{style[0]}}
+            {{style[0] || style.name}}
           </option>
         </select>
         <i class="icon-down-open"/>
diff --git a/static/styles.json b/static/styles.json
index 7116ef20..1155e73e 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -5,5 +5,231 @@
   "bird": [ "Bird", "#f8fafd", "#e6ecf0", "#14171a", "#0084b8", "#e0245e", "#17bf63", "#1b95e0", "#fab81e"],
   "ir-black": [ "Ir Black", "#000000", "#242422", "#b5b3aa", "#ff6c60", "#FF6C60", "#A8FF60", "#96CBFE", "#FFFFB6" ],
   "monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672", "#F92672", "#a6e22e", "#66d9ef", "#f4bf75" ],
-  "mammal": [ "Mammal", "#272c37", "#444b5d", "#f8f8f8", "#9bacc8", "#7f3142", "#2bd850", "#2b90d9", "#ca8f04" ]
+  "mammal": [ "Mammal", "#272c37", "#444b5d", "#f8f8f8", "#9bacc8", "#7f3142", "#2bd850", "#2b90d9", "#ca8f04" ],
+  "redmond-xx": {
+    "_pleroma_theme_version": 2,
+    "name": "Redmond XX",
+    "theme": {
+      "shadows": {
+        "panel": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "button": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "buttonHover": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "input": [
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--input",
+            "alpha": "1",
+            "inset": true
+          }
+        ]
+      },
+      "opacity": {
+        "input": "1"
+      },
+      "colors": {
+        "bg": "#c0c0c0",
+        "text": "#000000",
+        "link": "#0000ff",
+        "fg": "#c0c0c0",
+        "panel": "#000080",
+        "input": "#ffffff",
+        "topBar": "#000080",
+        "topBarLink": "#ffffff",
+        "btn": "#c0c0c0",
+        "faint": "#3f3f3f",
+        "faintLink": "#404080",
+        "border": "#808080",
+        "cRed": "#FF0000",
+        "cBlue": "#008080",
+        "cGreen": "#00FF00",
+        "cOrange": "#808000"
+      },
+      "radii": {
+        "btn": "0",
+        "input": "0",
+        "panel": "0",
+        "avatar": "0",
+        "avatarAlt": "0",
+        "tooltip": "0",
+        "attachment": "0"
+      }
+    }
+  }
 }

From d6f7cb469c95af95791984eabeb301028962e22b Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 22 Nov 2018 05:13:09 +0300
Subject: [PATCH 45/96] small tab-switcher tweak

---
 src/components/tab_switcher/tab_switcher.scss | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index bd93e988..9fd9d905 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -34,6 +34,10 @@
       border-bottom-right-radius: 0;
       padding: 5px 1em 99px;
 
+      &:hover {
+        z-index: 6;
+      }
+
       &:not(.active) {
         z-index: 4;
 

From 29082e9aee3dc50acfd5f1635f1a09017b83a893 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 00:24:16 +0300
Subject: [PATCH 46/96] fixed checkbox styles, optimized default shadows

---
 src/App.scss                                  |  9 +---
 src/components/tab_switcher/tab_switcher.scss |  8 +--
 src/services/style_setter/style_setter.js     | 50 ++++++-------------
 3 files changed, 20 insertions(+), 47 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index e8aa5846..3059d753 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -58,8 +58,6 @@ button {
   border-radius: $fallback--btnRadius;
   border-radius: var(--btnRadius, $fallback--btnRadius);
   cursor: pointer;
-  /* border-top: 1px solid rgba(255, 255, 255, 0.2); */
-  /* border-bottom: 1px solid rgba(0, 0, 0, 0.2); */
   box-shadow: 0px 0px 2px black;
   box-shadow: var(--buttonShadow);
   font-size: 14px;
@@ -80,8 +78,7 @@ button {
   }
 
   &:active {
-    /* border-bottom: 1px solid rgba(255, 255, 255, 0.2); */
-    /* border-top: 1px solid rgba(0, 0, 0, 0.2); */
+    box-shadow: var(--buttonPressedShadow);
   }
 
   &:disabled {
@@ -106,8 +103,6 @@ input, textarea, .select {
   border: none;
   border-radius: $fallback--inputRadius;
   border-radius: var(--inputRadius, $fallback--inputRadius);
-  /* border-bottom: 1px solid rgba(255, 255, 255, 0.2); */
-  /* border-top: 1px solid rgba(0, 0, 0, 0.2); */
   box-shadow: 0px 0px 2px black inset;
   box-shadow: var(--inputShadow);
   background-color: $fallback--fg;
@@ -184,8 +179,6 @@ input, textarea, .select {
       height: 1.1em;
       border-radius: $fallback--checkBoxRadius;
       border-radius: var(--checkBoxRadius, $fallback--checkBoxRadius);
-      border-bottom: 1px solid rgba(255, 255, 255, 0.2);
-      border-top: 1px solid rgba(0, 0, 0, 0.2);
       box-shadow: 0px 0px 2px black inset;
       box-shadow: var(--inputShadow);
       margin-right: .5em;
diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index 9fd9d905..d0e5ea87 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -34,13 +34,13 @@
       border-bottom-right-radius: 0;
       padding: 5px 1em 99px;
 
-      &:hover {
-        z-index: 6;
-      }
-
       &:not(.active) {
         z-index: 4;
 
+        &:hover {
+          z-index: 6;
+        }
+
         &::after {
           content: '';
           position: absolute;
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 4a48f419..10583722 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -256,40 +256,26 @@ const generateRadii = (input) => {
 }
 
 const generateShadows = (input) => {
-  const buttonInsetFakeBorders = [{
+  const border = (top, shadow) => ({
     x: 0,
-    y: 1,
+    y: top ? 1 : -1,
     blur: 0,
     spread: 0,
-    color: '#FFFFFF',
+    color: shadow ? '#000000' : '#FFFFFF',
     alpha: 0.2,
     inset: true
-  }, {
+  })
+  const buttonInsetFakeBorders = [border(true, false), border(false, true)]
+  const inputInsetFakeBorders = [border(true, true), border(false, false)]
+  const hoverGlow = {
     x: 0,
-    y: -1,
-    blur: 0,
+    y: 0,
+    blur: 4,
     spread: 0,
-    color: '#000000',
-    alpha: 0.2,
-    inset: true
-  }]
-  const inputInsetFakeBorders = [{
-    x: 0,
-    y: 1,
-    blur: 0,
-    spread: 0,
-    color: '#000000',
-    alpha: 0.2,
-    inset: true
-  }, {
-    x: 0,
-    y: -1,
-    blur: 0,
-    spread: 0,
-    color: '#FFFFFF',
-    alpha: 0.2,
-    inset: true
-  }]
+    color: '--faint',
+    alpha: 1
+  }
+
   const shadows = {
     panel: [{
       x: 1,
@@ -332,14 +318,8 @@ const generateShadows = (input) => {
       color: '#000000',
       alpha: 1
     }, ...buttonInsetFakeBorders],
-    buttonHover: [{
-      x: 0,
-      y: 0,
-      blur: 4,
-      spread: 0,
-      color: '--faint',
-      alpha: 1
-    }, ...buttonInsetFakeBorders],
+    buttonHover: [hoverGlow, ...buttonInsetFakeBorders],
+    buttonPressed: [hoverGlow, ...inputInsetFakeBorders],
     input: [...inputInsetFakeBorders, {
       x: 0,
       y: 0,

From 7af6be84bb8d019510b14dfe2e614156c92ff201 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 00:30:28 +0300
Subject: [PATCH 47/96] fake borders fallback

---
 src/App.scss | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 3059d753..8732d23c 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -58,7 +58,7 @@ button {
   border-radius: $fallback--btnRadius;
   border-radius: var(--btnRadius, $fallback--btnRadius);
   cursor: pointer;
-  box-shadow: 0px 0px 2px black;
+  box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 1), 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset;
   box-shadow: var(--buttonShadow);
   font-size: 14px;
   font-family: sans-serif;
@@ -78,6 +78,7 @@ button {
   }
 
   &:active {
+    box-shadow: 0px 0px 4px 0px rgba(255, 255, 255, 0.3), 0px 1px 0px 0px rgba(0, 0, 0, 0.2) inset, 0px -1px 0px 0px rgba(255, 255, 255, 0.2) inset;
     box-shadow: var(--buttonPressedShadow);
   }
 
@@ -103,7 +104,7 @@ input, textarea, .select {
   border: none;
   border-radius: $fallback--inputRadius;
   border-radius: var(--inputRadius, $fallback--inputRadius);
-  box-shadow: 0px 0px 2px black inset;
+  box-shadow: 0px 1px 0px 0px rgba(0, 0, 0, 0.2) inset, 0px -1px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 0px 2px 0px rgba(0, 0, 0, 1) inset;
   box-shadow: var(--inputShadow);
   background-color: $fallback--fg;
   background-color: var(--input, $fallback--fg);

From 8fd1b87e87e53c33de3976c3a87266a25a3905f7 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 01:13:57 +0300
Subject: [PATCH 48/96] more authentic redmond theme

---
 static/styles.json | 131 ++++++++++++++++++++++++++++++---------------
 1 file changed, 89 insertions(+), 42 deletions(-)

diff --git a/static/styles.json b/static/styles.json
index 1155e73e..4585dff0 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -26,16 +26,7 @@
             "y": "1",
             "blur": "0",
             "spread": 0,
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
+            "color": "#dfdfdf",
             "alpha": "1",
             "inset": true
           },
@@ -48,6 +39,15 @@
             "alpha": "1",
             "inset": true
           },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
           {
             "x": "0",
             "y": "0",
@@ -73,15 +73,6 @@
             "y": "1",
             "blur": "0",
             "spread": 0,
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
             "color": "#FFFFFF",
             "alpha": "1",
             "inset": true
@@ -95,6 +86,15 @@
             "alpha": "1",
             "inset": true
           },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
           {
             "x": "0",
             "y": "0",
@@ -120,15 +120,6 @@
             "y": "1",
             "blur": "0",
             "spread": 0,
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
             "color": "#FFFFFF",
             "alpha": "1",
             "inset": true
@@ -142,6 +133,62 @@
             "alpha": "1",
             "inset": true
           },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "buttonPressed": [
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
           {
             "x": "0",
             "y": "0",
@@ -153,21 +200,21 @@
           }
         ],
         "input": [
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
           {
             "x": "-1",
             "y": "-1",
             "blur": "0",
             "spread": 0,
-            "color": "--bg",
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
             "alpha": "1",
             "inset": true
           },
@@ -176,7 +223,7 @@
             "y": "-2",
             "blur": "0",
             "spread": 0,
-            "color": "#FFFFFF",
+            "color": "#dfdfdf",
             "alpha": "1",
             "inset": true
           },
@@ -185,7 +232,7 @@
             "y": "2",
             "blur": "0",
             "spread": 0,
-            "color": "#848484",
+            "color": "#000000",
             "alpha": "1",
             "inset": true
           },
@@ -197,8 +244,8 @@
             "color": "--input",
             "alpha": "1",
             "inset": true
-          }
-        ]
+        }
+      ]
       },
       "opacity": {
         "input": "1"

From d2f3b6d2442a04e6bcb244d0644c8c0dd6caa8fe Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 01:45:08 +0300
Subject: [PATCH 49/96] more styles, temporarily in one file, fix for panel
 header box-shadow affecting the user-card one

---
 .../user_card_content/user_card_content.vue   |   1 +
 static/styles.json                            | 572 +++++++++++++++++-
 2 files changed, 571 insertions(+), 2 deletions(-)

diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index a2bb99a1..14eb4023 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -124,6 +124,7 @@
   .panel-heading {
     padding: 0.6em 0em;
     text-align: center;
+    box-shadow: none;
   }
 }
 
diff --git a/static/styles.json b/static/styles.json
index 4585dff0..d9e1ea8c 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -244,8 +244,8 @@
             "color": "--input",
             "alpha": "1",
             "inset": true
-        }
-      ]
+          }
+        ]
       },
       "opacity": {
         "input": "1"
@@ -278,5 +278,573 @@
         "attachment": "0"
       }
     }
+  },
+  "redmond-xx-se": {
+    "_pleroma_theme_version": 2,
+    "name": "Redmond XX SE",
+    "theme": {
+      "shadows": {
+        "panel": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "button": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "buttonHover": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "buttonPressed": [
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "input": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--input",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "panelHeader": [
+          {
+            "x": "-2200",
+            "y": 0,
+            "blur": "200",
+            "spread": "-2000",
+            "inset": true,
+            "color": "#1084d0",
+            "alpha": 1
+          }
+        ]
+      },
+      "opacity": {
+        "input": "1"
+      },
+      "colors": {
+        "bg": "#c0c0c0",
+        "text": "#000000",
+        "link": "#0000ff",
+        "fg": "#c0c0c0",
+        "panel": "#000080",
+        "input": "#ffffff",
+        "topBar": "#000080",
+        "topBarLink": "#ffffff",
+        "btn": "#c0c0c0",
+        "faint": "#3f3f3f",
+        "faintLink": "#404080",
+        "border": "#808080",
+        "cRed": "#FF0000",
+        "cBlue": "#008080",
+        "cGreen": "#00FF00",
+        "cOrange": "#808000"
+      },
+      "radii": {
+        "btn": "0",
+        "input": "0",
+        "panel": "0",
+        "avatar": "0",
+        "avatarAlt": "0",
+        "tooltip": "0",
+        "attachment": "0"
+      }
+    }
+  },
+  "redmond-xxi": {
+    "_pleroma_theme_version": 2,
+    "name": "Redmond XXI",
+    "theme": {
+      "shadows": {
+        "panel": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "button": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "buttonHover": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "buttonPressed": [
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--bg",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "input": [
+          {
+            "x": "-1",
+            "y": "-1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#FFFFFF",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "1",
+            "y": "1",
+            "blur": "0",
+            "spread": 0,
+            "color": "#848484",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "-2",
+            "y": "-2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#dfdfdf",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "2",
+            "y": "2",
+            "blur": "0",
+            "spread": 0,
+            "color": "#000000",
+            "alpha": "1",
+            "inset": true
+          },
+          {
+            "x": "0",
+            "y": "0",
+            "blur": "0",
+            "spread": "3",
+            "color": "--input",
+            "alpha": "1",
+            "inset": true
+          }
+        ],
+        "panelHeader": [
+          {
+            "x": "-2200",
+            "y": 0,
+            "blur": "200",
+            "spread": "-2000",
+            "inset": true,
+            "color": "#a5cef7",
+            "alpha": 1
+          }
+        ]
+      },
+      "opacity": {
+        "input": "1"
+      },
+      "colors": {
+        "bg": "#d6d6ce",
+        "text": "#000000",
+        "link": "#0000ff",
+        "fg": "#d6d6ce",
+        "panel": "#042967",
+        "input": "#ffffff",
+        "topBar": "#042967",
+        "topBarLink": "#ffffff",
+        "btn": "#d6d6ce",
+        "faint": "#3f3f3f",
+        "faintLink": "#404080",
+        "border": "#808080",
+        "cRed": "#FF0000",
+        "cBlue": "#008080",
+        "cGreen": "#00FF00",
+        "cOrange": "#808000"
+      },
+      "radii": {
+        "btn": "0",
+        "input": "0",
+        "panel": "0",
+        "avatar": "0",
+        "avatarAlt": "0",
+        "tooltip": "0",
+        "attachment": "0"
+      }
+    }
   }
 }

From 91ea9b7b0e7b2ad818c0ac026951cd5a9c68bfdf Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 07:28:53 +0300
Subject: [PATCH 50/96] checkbox radius

---
 src/App.scss                                     | 4 ++--
 src/_variables.scss                              | 2 +-
 src/components/style_switcher/style_switcher.js  | 3 +++
 src/components/style_switcher/style_switcher.vue | 3 ++-
 src/i18n/en.json                                 | 1 +
 static/styles.json                               | 3 +++
 6 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 8732d23c..004c6fc3 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -178,8 +178,8 @@ input, textarea, .select {
       transition: color 200ms;
       width: 1.1em;
       height: 1.1em;
-      border-radius: $fallback--checkBoxRadius;
-      border-radius: var(--checkBoxRadius, $fallback--checkBoxRadius);
+      border-radius: $fallback--checkboxRadius;
+      border-radius: var(--checkboxRadius, $fallback--checkboxRadius);
       box-shadow: 0px 0px 2px black inset;
       box-shadow: var(--inputShadow);
       margin-right: .5em;
diff --git a/src/_variables.scss b/src/_variables.scss
index d0d91efe..150e4fb5 100644
--- a/src/_variables.scss
+++ b/src/_variables.scss
@@ -19,7 +19,7 @@ $fallback--cOrange: orange;
 $fallback--alertError: rgba(211,16,20,.5);
 
 $fallback--panelRadius: 10px;
-$fallback--checkBoxRadius: 2px;
+$fallback--checkboxRadius: 2px;
 $fallback--btnRadius: 4px;
 $fallback--inputRadius: 4px;
 $fallback--tooltipRadius: 5px;
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 710694d4..edc614c3 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -76,6 +76,7 @@ export default {
 
       btnRadiusLocal: '',
       inputRadiusLocal: '',
+      checkboxRadiusLocal: '',
       panelRadiusLocal: '',
       avatarRadiusLocal: '',
       avatarAltRadiusLocal: '',
@@ -154,6 +155,7 @@ export default {
       return {
         btn: this.btnRadiusLocal,
         input: this.inputRadiusLocal,
+        checkbox: this.checkboxRadiusLocal,
         panel: this.panelRadiusLocal,
         avatar: this.avatarRadiusLocal,
         avatarAlt: this.avatarAltRadiusLocal,
@@ -421,6 +423,7 @@ export default {
       // TODO optimize this
       this.btnRadiusLocal = radii.btn
       this.inputRadiusLocal = radii.input
+      this.checkboxRadiusLocal = radii.checkbox
       this.panelRadiusLocal = radii.panel
       this.avatarRadiusLocal = radii.avatar
       this.avatarAltRadiusLocal = radii.avatarAlt
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 37709363..6463a4ca 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -135,7 +135,8 @@
         <div>
           <p>{{$t('settings.radii_help')}}</p>
           <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
-          <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="16" hardMin="0"/>
+          <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="9" hardMin="0"/>
+          <RangeInput name="checkboxRadius" :label="$t('settings.checkboxRadius')" v-model="checkboxRadiusLocal" :fallback="previewTheme.radii.checkbox" max="16" hardMin="0"/>
           <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
           <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
           <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index b039757e..f990dd04 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -114,6 +114,7 @@
     "import_followers_from_a_csv_file": "Import follows from a csv file",
     "import_theme": "Load preset",
     "inputRadius": "Input fields",
+    "checkboxRadius": "Checkboxes",
     "instance_default": "(default: {value})",
     "interfaceLanguage": "Interface language",
     "invalid_theme_imported": "The selected file is not a supported Pleroma theme. No changes to your theme were made.",
diff --git a/static/styles.json b/static/styles.json
index d9e1ea8c..a53eeaa1 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -271,6 +271,7 @@
       "radii": {
         "btn": "0",
         "input": "0",
+        "checkbox": "0",
         "panel": "0",
         "avatar": "0",
         "avatarAlt": "0",
@@ -555,6 +556,7 @@
       "radii": {
         "btn": "0",
         "input": "0",
+        "checkbox": "0",
         "panel": "0",
         "avatar": "0",
         "avatarAlt": "0",
@@ -839,6 +841,7 @@
       "radii": {
         "btn": "0",
         "input": "0",
+        "checkbox": "0",
         "panel": "0",
         "avatar": "0",
         "avatarAlt": "0",

From 754d71ec1933d897f9206ddca080bb258256edbb Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 08:24:55 +0300
Subject: [PATCH 51/96] added checkboxes to keep current roundness and shadows,
 also cleaned up how shadows/roundness are reset when switching themes

---
 .../style_switcher/style_switcher.js          | 52 +++++++++++++----
 .../style_switcher/style_switcher.scss        | 18 ++++--
 .../style_switcher/style_switcher.vue         | 57 ++++++++++++-------
 src/i18n/en.json                              |  5 ++
 4 files changed, 99 insertions(+), 33 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index edc614c3..0c302e93 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -27,6 +27,9 @@ export default {
       selected: this.$store.state.config.theme,
       invalidThemeImported: false,
 
+      keepShadows: false,
+      keepRoundness: false,
+
       textColorLocal: '',
       linkColorLocal: '',
 
@@ -375,6 +378,19 @@ export default {
         })
     },
 
+    clearRoundness () {
+      Object.keys(this.$data)
+        .filter(_ => _.endsWith('RadiusLocal'))
+        .forEach(key => {
+          set(this.$data, key, undefined)
+        })
+    },
+
+    clearShadows () {
+      this.shadowsLocal = {}
+      console.log(this.shadowsLocal)
+    },
+
     /**
      * This applies stored theme data onto form.
      * @param {Object} input - input data
@@ -420,17 +436,24 @@ export default {
         this[key + 'ColorLocal'] = rgb2hex(colors[key])
       })
 
-      // TODO optimize this
-      this.btnRadiusLocal = radii.btn
-      this.inputRadiusLocal = radii.input
-      this.checkboxRadiusLocal = radii.checkbox
-      this.panelRadiusLocal = radii.panel
-      this.avatarRadiusLocal = radii.avatar
-      this.avatarAltRadiusLocal = radii.avatarAlt
-      this.tooltipRadiusLocal = radii.tooltip
-      this.attachmentRadiusLocal = radii.attachment
+      if (!this.keepRoundness) {
+        this.clearRoundness()
+        // TODO optimize this
+        this.btnRadiusLocal = radii.btn
+        this.inputRadiusLocal = radii.input
+        this.checkboxRadiusLocal = radii.checkbox
+        this.panelRadiusLocal = radii.panel
+        this.avatarRadiusLocal = radii.avatar
+        this.avatarAltRadiusLocal = radii.avatarAlt
+        this.tooltipRadiusLocal = radii.tooltip
+        this.attachmentRadiusLocal = radii.attachment
+      }
 
-      this.shadowsLocal = shadows
+      if (!this.keepShadows) {
+        this.clearShadows()
+        this.shadowsLocal = shadows
+        this.shadowSelected = this.shadowsAvailable[0]
+      }
 
       Object.entries(opacity).forEach(([k, v]) => {
         if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
@@ -441,7 +464,16 @@ export default {
   watch: {
     selected () {
       if (this.selectedVersion === 1) {
+        if (!this.keepRoundness) {
+          this.clearRoundness()
+        }
+
+        if (!this.keepShadows) {
+          this.clearShadows()
+        }
+
         this.clearV1()
+
         this.bgColorLocal = this.selected[1]
         this.fgColorLocal = this.selected[2]
         this.textColorLocal = this.selected[3]
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index f8529b4f..9cdc9f33 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -66,7 +66,7 @@
   .apply-container,
   .radius-container,
   .color-container,
-  .presets-container {
+  {
     display: flex;
 
     p {
@@ -88,12 +88,14 @@
 
   .color-container,
   .shadow-container,
-  .radius-container {
+  .radius-container,
+  .presets-container {
     margin: 1em 1em 0;
   }
 
-  .presets-container,
-  .shadow-selector {
+  .shadow-selector,
+  .save-load,
+  .save-load-options {
     display: flex;
     justify-content: center;
     align-items: baseline;
@@ -110,6 +112,14 @@
     }
   }
 
+  .save-load-options {
+    flex-wrap: wrap;
+    margin-top: .5em;
+    span {
+      margin: 0 .5em;
+    }
+  }
+
   .preview-container {
     border-top: 1px dashed;
     border-bottom: 1px dashed;
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 6463a4ca..0c6b811d 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -1,26 +1,45 @@
 <template>
 <div class="style-switcher">
   <div class="presets-container">
-    <div>
-      {{$t('settings.presets')}}
-      <label for="preset-switcher" class='select'>
-        <select id="preset-switcher" v-model="selected" class="preset-switcher">
-          <option v-for="style in availableStyles"
-                  :value="style"
-                  :style="{
-                          backgroundColor: style[1] || style.theme.colors.bg,
-                          color: style[3] || style.theme.colors.text
-                          }">
-            {{style[0] || style.name}}
-          </option>
-        </select>
-        <i class="icon-down-open"/>
-      </label>
+    <div class="save-load">
+      <div>
+        {{$t('settings.presets')}}
+        <label for="preset-switcher" class='select'>
+          <select id="preset-switcher" v-model="selected" class="preset-switcher">
+            <option v-for="style in availableStyles"
+                    :value="style"
+                    :style="{
+                            backgroundColor: style[1] || style.theme.colors.bg,
+                            color: style[3] || style.theme.colors.text
+                            }">
+              {{style[0] || style.name}}
+            </option>
+          </select>
+          <i class="icon-down-open"/>
+        </label>
+      </div>
+      <div class="import-export">
+        <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
+        <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
+        <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
+      </div>
     </div>
-    <div class="import-export">
-      <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
-      <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
-      <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
+    <div class="save-load-options">
+      <span>
+        <input
+          id="keep-shadows"
+          type="checkbox"
+          v-model="keepShadows">
+        <label for="keep-shadows">{{$t('settings.style.switcher.keep_shadows')}}</label>
+      </span>
+      <span>
+        <input
+          id="keep-roundness"
+          type="checkbox"
+          v-model="keepRoundness">
+        <label for="keep-roundness">{{$t('settings.style.switcher.keep_roundness')}}</label>
+      </span>
+      <p>{{$t('settings.style.switcher.save_load_hint')}}</p>
     </div>
   </div>
 
diff --git a/src/i18n/en.json b/src/i18n/en.json
index f990dd04..a9d50dbe 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -164,6 +164,11 @@
       "true": "yes"
     },
     "style": {
+      "switcher": {
+        "keep_shadows": "Keep shadows",
+        "keep_roundness": "Keep roundness",
+        "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme."
+      },
       "common": {
         "color": "Color",
         "opacity": "Opacity",

From 1059d9b602656355780f3bcd1ed3d7885de590c1 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 09:02:10 +0300
Subject: [PATCH 52/96] radii v1 fixes

---
 src/components/style_switcher/style_switcher.js | 14 +++++---------
 src/services/style_setter/style_setter.js       |  3 ++-
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 0c302e93..33be522b 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -438,15 +438,11 @@ export default {
 
       if (!this.keepRoundness) {
         this.clearRoundness()
-        // TODO optimize this
-        this.btnRadiusLocal = radii.btn
-        this.inputRadiusLocal = radii.input
-        this.checkboxRadiusLocal = radii.checkbox
-        this.panelRadiusLocal = radii.panel
-        this.avatarRadiusLocal = radii.avatar
-        this.avatarAltRadiusLocal = radii.avatarAlt
-        this.tooltipRadiusLocal = radii.tooltip
-        this.attachmentRadiusLocal = radii.attachment
+        Object.entries(radii).forEach(([k, v]) => {
+          // 'Radius' is kept mostly for v1->v2 localstorage transition
+          const key = k.endsWith('Radius') ? k.split('Radius')[0] : k
+          this[key + 'RadiusLocal'] = v
+        })
       }
 
       if (!this.keepShadows) {
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 10583722..2662fc42 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -233,7 +233,8 @@ const generateColors = (input) => {
 
 const generateRadii = (input) => {
   const radii = Object.entries(input.radii || {}).filter(([k, v]) => v).reduce((acc, [k, v]) => {
-    acc[k] = v
+    const key = k.endsWith('Radius') ? k.split('Radius')[0] : k
+    acc[key] = v
     return acc
   }, {
     btn: 4,

From 652b98b13c573f4c8d84f2e55251b2244b243afc Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 09:14:52 +0300
Subject: [PATCH 53/96] fix v1->v2 transition for localstorage

---
 src/services/style_setter/style_setter.js | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 2662fc42..d7487eed 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -232,9 +232,16 @@ const generateColors = (input) => {
 }
 
 const generateRadii = (input) => {
-  const radii = Object.entries(input.radii || {}).filter(([k, v]) => v).reduce((acc, [k, v]) => {
-    const key = k.endsWith('Radius') ? k.split('Radius')[0] : k
-    acc[key] = v
+  let inputRadii = input.radii || {}
+  // v1 -> v2
+  if (typeof input.btnRadius !== 'undefined') {
+    inputRadii = Object
+      .entries(input)
+      .filter(([k, v]) => k.endsWith('Radius'))
+      .reduce((acc, e) => { acc[e[0].split('Radius')[0]] = e[1]; return acc }, {})
+  }
+  const radii = Object.entries(inputRadii).filter(([k, v]) => v).reduce((acc, [k, v]) => {
+    acc[k] = v
     return acc
   }, {
     btn: 4,

From 26b9f787bb01551f991f9e79aa8c0fc59313b95e Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 10:17:01 +0300
Subject: [PATCH 54/96] added "keep opacity" option, fixed opacity loading,
 fixed missing shadows not affecting the preview (i.e. previewing pleroma-dark
 when redmond is applied)

---
 .../style_switcher/style_switcher.js          | 27 +++++++++++++++----
 .../style_switcher/style_switcher.vue         |  7 +++++
 src/i18n/en.json                              |  1 +
 src/services/style_setter/style_setter.js     |  8 ++++--
 4 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 33be522b..e1a17837 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -28,6 +28,7 @@ export default {
       invalidThemeImported: false,
 
       keepShadows: false,
+      keepOpacity: false,
       keepRoundness: false,
 
       textColorLocal: '',
@@ -386,6 +387,14 @@ export default {
         })
     },
 
+    clearOpacity () {
+      Object.keys(this.$data)
+        .filter(_ => _.endsWith('OpacityLocal'))
+        .forEach(key => {
+          set(this.$data, key, undefined)
+        })
+    },
+
     clearShadows () {
       this.shadowsLocal = {}
       console.log(this.shadowsLocal)
@@ -397,9 +406,10 @@ export default {
      * @param {Number} version - version of data. 0 means try to guess based on data.
      */
     normalizeLocalState (input, version = 0) {
+      console.log(input.opacity)
       const colors = input.colors || input
       const radii = input.radii || input
-      const opacity = input.opacity || input
+      const opacity = input.opacity
       const shadows = input.shadows || {}
 
       if (version === 0) {
@@ -451,10 +461,13 @@ export default {
         this.shadowSelected = this.shadowsAvailable[0]
       }
 
-      Object.entries(opacity).forEach(([k, v]) => {
-        if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
-        this[k + 'OpacityLocal'] = v
-      })
+      if (opacity && !this.keepOpacity) {
+        this.clearOpacity()
+        Object.entries(opacity).forEach(([k, v]) => {
+          if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
+          this[k + 'OpacityLocal'] = v
+        })
+      }
     }
   },
   watch: {
@@ -468,6 +481,10 @@ export default {
           this.clearShadows()
         }
 
+        if (!this.keepOpacity) {
+          this.clearOpacity()
+        }
+
         this.clearV1()
 
         this.bgColorLocal = this.selected[1]
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 0c6b811d..ed0dd733 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -32,6 +32,13 @@
           v-model="keepShadows">
         <label for="keep-shadows">{{$t('settings.style.switcher.keep_shadows')}}</label>
       </span>
+      <span>
+        <input
+          id="keep-opacity"
+          type="checkbox"
+          v-model="keepOpacity">
+        <label for="keep-opacity">{{$t('settings.style.switcher.keep_opacity')}}</label>
+      </span>
       <span>
         <input
           id="keep-roundness"
diff --git a/src/i18n/en.json b/src/i18n/en.json
index a9d50dbe..98a91013 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -166,6 +166,7 @@
     "style": {
       "switcher": {
         "keep_shadows": "Keep shadows",
+        "keep_opacity": "Keep opacity",
         "keep_roundness": "Keep roundness",
         "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme."
       },
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index d7487eed..60531f28 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -94,7 +94,10 @@ const setColors = (input, commit) => {
 }
 
 const getCssShadow = (input) => {
-  // >shad
+  if (input.length === 0) {
+    return 'none'
+  }
+
   return input.map((shad) => [
     shad.x,
     shad.y,
@@ -340,9 +343,10 @@ const generateShadows = (input) => {
     ...(input.shadows || {})
   }
 
+  console.log(Object.entries(shadows).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';'))
   return {
     rules: {
-      shadows: Object.entries(shadows).filter(([k, v]) => v).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';')
+      shadows: Object.entries(shadows).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';')
     },
     theme: {
       shadows

From b07d7d7229c376a0588d86ee8a28735bdcf99b7f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 23 Nov 2018 11:36:36 +0300
Subject: [PATCH 55/96] reset buttons, better disabled for shadows

---
 src/App.scss                                  |  5 ++
 src/components/settings/settings.vue          |  8 +--
 .../shadow_control/shadow_control.vue         |  9 +++-
 .../style_switcher/style_switcher.js          |  4 ++
 .../style_switcher/style_switcher.scss        | 54 +++++++++++++++----
 .../style_switcher/style_switcher.vue         | 21 ++++++--
 src/i18n/en.json                              |  5 +-
 src/services/style_setter/style_setter.js     |  1 +
 8 files changed, 85 insertions(+), 22 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 004c6fc3..ceb0bb87 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -120,6 +120,11 @@ input, textarea, .select {
   line-height: 16px;
   hyphens: none;
 
+  &:disabled, &[disabled=disabled] {
+    cursor: not-allowed;
+    opacity: 0.5;
+  }
+
   .icon-down-open {
     position: absolute;
     top: 0;
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index 990d1f0d..2097fd22 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -208,12 +208,8 @@
 
   .btn {
     min-height: 28px;
-  }
-
-  .submit {
-    margin-top: 1em;
-    min-height: 30px;
-    width: 10em;
+    min-width: 10em;
+    padding: 0 2em;
   }
 }
 .select-multiple {
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index 2bc05cb7..b608d0ff 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -40,7 +40,7 @@
 
   <div class="shadow-tweak">
     <div :disabled="usingFallback" class="id-control style-control">
-      <label for="shadow-switcher" class="select">
+      <label for="shadow-switcher" class="select" :disabled="!ready || usingFallback">
         <select
           v-model="selectedId" class="shadow-switcher"
           :disabled="!ready || usingFallback"
@@ -60,7 +60,7 @@
       <button class="btn btn-default" :disabled="!moveDnValid" @click="moveDn">
         <i class="icon-down-open"/>
       </button>
-      <button class="btn btn-default" :disabled="!ready" @click="add">
+      <button class="btn btn-default" :disabled="usingFallback" @click="add">
         <i class="icon-plus"/>
       </button>
     </div>
@@ -219,8 +219,13 @@
     .id-control {
       align-items: stretch;
       .select, .btn {
+        min-width: 1px;
         margin-right: 5px;
       }
+      .btn {
+        padding: 0 .4em;
+        margin: 0 .1em;
+      }
       .select {
         flex: 1;
         select {
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index e1a17837..d45ce455 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -369,6 +369,10 @@ export default {
       })
     },
 
+    clearAll () {
+      this.normalizeLocalState(this.$store.state.config.customTheme)
+    },
+
     // Clears all the extra stuff when loading V1 theme
     clearV1 () {
       Object.keys(this.$data)
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 9cdc9f33..ad203856 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -63,15 +63,16 @@
     margin: 0 -1em;
   }
 
+  .reset-container {
+    flex-wrap: wrap;
+  }
+
+  .reset-container,
   .apply-container,
   .radius-container,
   .color-container,
   {
     display: flex;
-
-    p {
-      margin-left: 1em
-    }
   }
 
   .radius-container {
@@ -93,7 +94,38 @@
     margin: 1em 1em 0;
   }
 
-  .shadow-selector,
+  .tab-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: baseline;
+    width: 100%;
+    min-height: 30px;
+
+    .btn {
+      min-width: 1px;
+      flex: 0 auto;
+      padding: 0 1em;
+    }
+
+    p {
+      flex: 1;
+      margin: 0;
+    }
+
+    margin-bottom: 1em;
+  }
+
+  .shadow-selector {
+    .override {
+      flex: 1;
+      margin-left: .5em;
+    }
+    .select-container {
+      margin-top: -4px;
+      margin-bottom: -3px;
+    }
+  }
+
   .save-load,
   .save-load-options {
     display: flex;
@@ -102,11 +134,8 @@
 
     .import-export {
       display: flex;
-
-      .btn {
-        margin-left: .5em;
-      }
     }
+
     .override {
       margin-left: .5em;
     }
@@ -132,6 +161,7 @@
     background-position: 50% 50%;
 
     .btn {
+      margin-left: 0;
       margin-top: 1em;
       min-height: 30px;
       width: 10em;
@@ -153,6 +183,7 @@
     &.wide {
       min-width: 60%
     }
+
     &:not(.wide):nth-child(2n+1) {
       margin-right: 7px;
 
@@ -200,6 +231,11 @@
     padding: 20px;
   }
 
+  .btn {
+    margin-left: .25em;
+    margin-right: .25em;
+  }
+
   .dummy {
     .avatar {
       background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index ed0dd733..9e5cffbe 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -71,10 +71,13 @@
     </div>
   </div>
 
-  <p>{{$t('settings.theme_help')}}</p>
   <keep-alive>
     <tab-switcher key="style-tweak">
       <div :label="$t('settings.style.common_colors._tab_label')" class="color-container">
+        <div class="tab-header">
+          <p>{{$t('settings.theme_help')}}</p>
+          <button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
+        </div>
         <h4>{{ $t('settings.style.common_colors.main') }}</h4>
         <div class="color-item">
           <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
@@ -106,6 +109,11 @@
       </div>
 
       <div :label="$t('settings.style.advanced_colors._tab_label')" class="color-container">
+        <div class="tab-header">
+          <p>{{$t('settings.theme_help')}}</p>
+          <button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
+          <button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
+        </div>
         <div class="color-item">
           <h4>{{ $t('settings.style.advanced_colors.alert') }}</h4>
           <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.style.advanced_colors.alert_error')" :fallback="previewTheme.colors.alertError"/>
@@ -159,7 +167,10 @@
       </div>
       <div :label="$t('settings.style.radii._tab_label')" class="radius-container">
         <div>
-          <p>{{$t('settings.radii_help')}}</p>
+          <div class="tab-header">
+            <p>{{$t('settings.radii_help')}}</p>
+            <button class="btn" @click="clearRoundness">{{$t('settings.style.switcher.clear_all')}}</button>
+          </div>
           <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
           <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="9" hardMin="0"/>
           <RangeInput name="checkboxRadius" :label="$t('settings.checkboxRadius')" v-model="checkboxRadiusLocal" :fallback="previewTheme.radii.checkbox" max="16" hardMin="0"/>
@@ -171,8 +182,8 @@
         </div>
       </div>
       <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
-        <div class="shadow-selector">
-          <div>
+        <div class="tab-header shadow-selector">
+          <div class="select-container">
             {{$t('settings.style.shadows.component')}}
             <label for="shadow-switcher" class="select">
               <select id="shadow-switcher" v-model="shadowSelected" class="shadow-switcher">
@@ -196,6 +207,7 @@
               type="checkbox">
             <label class="checkbox-label" for="override"></label>
           </div>
+          <button class="btn" @click="clearShadows">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
         <shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
       </div>
@@ -204,6 +216,7 @@
 
   <div class="apply-container">
     <button class="btn submit" @click="setCustomTheme">{{$t('general.apply')}}</button>
+    <button class="btn" @click="clearAll">{{$t('settings.style.switcher.reset')}}</button>
   </div>
 </div>
 </template>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 98a91013..15d57765 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -168,7 +168,10 @@
         "keep_shadows": "Keep shadows",
         "keep_opacity": "Keep opacity",
         "keep_roundness": "Keep roundness",
-        "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme."
+        "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme.",
+        "reset": "Reset",
+        "clear_all": "Clear all",
+        "clear_opacity": "Clear opacity"
       },
       "common": {
         "color": "Color",
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 60531f28..680aadb4 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -249,6 +249,7 @@ const generateRadii = (input) => {
   }, {
     btn: 4,
     input: 4,
+    checkbox: 2,
     panel: 10,
     avatar: 5,
     avatarAlt: 50,

From 1a8d24d649228a245e7f5b6ebf6883d8f1c6797b Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 17:21:53 +0300
Subject: [PATCH 56/96] some help strings

---
 src/components/shadow_control/shadow_control.vue | 4 ++++
 src/components/style_switcher/style_switcher.vue | 7 +++++--
 src/i18n/en.json                                 | 7 +++++--
 src/services/style_setter/style_setter.js        | 1 +
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index b608d0ff..85346e17 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -124,6 +124,9 @@
     <OpacityInput
       v-model="selected.alpha"
       :disabled="!present"/>
+    <div>
+      {{$t('settings.style.shadows.hint')}}
+    </div>
   </div>
 </div>
 </template>
@@ -215,6 +218,7 @@
 
   .shadow-tweak {
     flex: 1;
+    min-width: 280px;
 
     .id-control {
       align-items: stretch;
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 9e5cffbe..f5090321 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -75,9 +75,11 @@
     <tab-switcher key="style-tweak">
       <div :label="$t('settings.style.common_colors._tab_label')" class="color-container">
         <div class="tab-header">
-          <p>{{$t('settings.theme_help')}}</p>
+            <p>{{$t('settings.theme_help')}}</p>
           <button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
+          <button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
+        <p>{{$t('settings.theme_help_v2_1')}}</p>
         <h4>{{ $t('settings.style.common_colors.main') }}</h4>
         <div class="color-item">
           <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
@@ -106,13 +108,14 @@
           <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
           <ContrastRatio :contrast="previewContrast.bgOrange"/>
         </div>
+        <p>{{$t('settings.theme_help_v2_2')}}</p>
       </div>
 
       <div :label="$t('settings.style.advanced_colors._tab_label')" class="color-container">
         <div class="tab-header">
           <p>{{$t('settings.theme_help')}}</p>
-          <button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
           <button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
+          <button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
         <div class="color-item">
           <h4>{{ $t('settings.style.advanced_colors.alert') }}</h4>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 15d57765..5bd1ddbb 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -157,6 +157,8 @@
     "text": "Text",
     "theme": "Theme",
     "theme_help": "Use hex color codes (#rrggbb) to customize your color theme.",
+    "theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.",
+    "theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.",
     "tooltipRadius": "Tooltips/alerts",
     "user_settings": "User Settings",
     "values": {
@@ -220,12 +222,13 @@
         "blur": "Blur",
         "spread": "Spread",
         "inset": "Inset",
+        "hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
         "components": {
           "panel": "Panel",
           "panelHeader": "Panel header",
           "topBar": "Top bar",
-          "avatar": "User avatar (in post display)",
-          "avatarStatus": "User avatar (in profile view)",
+          "avatar": "User avatar (in profile view)",
+          "avatarStatus": "User avatar (in post display)",
           "popup": "Popups and tooltips",
           "button": "Button",
           "buttonHover": "Button (hover)",
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 680aadb4..5726cd61 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -321,6 +321,7 @@ const generateShadows = (input) => {
       color: '#000000',
       alpha: 0.7
     }],
+    avatarStatus: [],
     panelHeader: [],
     button: [{
       x: 0,

From 698ebf70037c3231b96f417ad1afeaad1da47d55 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 17:24:58 +0300
Subject: [PATCH 57/96] fixed indentation

---
 .../user_card_content/user_card_content.vue   | 128 +++++++++---------
 1 file changed, 64 insertions(+), 64 deletions(-)

diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index 14eb4023..22f77ffc 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -41,74 +41,74 @@
         </div>
       </div>
       <div v-if="isOtherUser" class="user-interactions">
-          <div class="follow" v-if="loggedIn">
-            <span v-if="user.following">
-              <!--Following them!-->
-              <button @click="unfollowUser" class="pressed">
-                {{ $t('user_card.following') }}
-              </button>
-            </span>
-            <span v-if="!user.following">
-              <button @click="followUser">
-                {{ $t('user_card.follow') }}
-              </button>
-            </span>
-          </div>
-          <div class='mute' v-if='isOtherUser'>
-            <span v-if='user.muted'>
-              <button @click="toggleMute" class="pressed">
-                {{ $t('user_card.muted') }}
-              </button>
-            </span>
-            <span v-if='!user.muted'>
-              <button @click="toggleMute">
-                {{ $t('user_card.mute') }}
-              </button>
-            </span>
-          </div>
-          <div class="remote-follow" v-if='!loggedIn && user.is_local'>
-            <form method="POST" :action='subscribeUrl'>
-              <input type="hidden" name="nickname" :value="user.screen_name">
-              <input type="hidden" name="profile" value="">
-              <button click="submit" class="remote-button">
-                {{ $t('user_card.remote_follow') }}
-              </button>
-            </form>
-          </div>
-          <div class='block' v-if='isOtherUser && loggedIn'>
-            <span v-if='user.statusnet_blocking'>
-              <button @click="unblockUser" class="pressed">
-                {{ $t('user_card.blocked') }}
-              </button>
-            </span>
-            <span v-if='!user.statusnet_blocking'>
-              <button @click="blockUser">
-                {{ $t('user_card.block') }}
-              </button>
-            </span>
-          </div>
+        <div class="follow" v-if="loggedIn">
+          <span v-if="user.following">
+            <!--Following them!-->
+            <button @click="unfollowUser" class="pressed">
+              {{ $t('user_card.following') }}
+            </button>
+          </span>
+          <span v-if="!user.following">
+            <button @click="followUser">
+              {{ $t('user_card.follow') }}
+            </button>
+          </span>
+        </div>
+        <div class='mute' v-if='isOtherUser'>
+          <span v-if='user.muted'>
+            <button @click="toggleMute" class="pressed">
+              {{ $t('user_card.muted') }}
+            </button>
+          </span>
+          <span v-if='!user.muted'>
+            <button @click="toggleMute">
+              {{ $t('user_card.mute') }}
+            </button>
+          </span>
+        </div>
+        <div class="remote-follow" v-if='!loggedIn && user.is_local'>
+          <form method="POST" :action='subscribeUrl'>
+            <input type="hidden" name="nickname" :value="user.screen_name">
+            <input type="hidden" name="profile" value="">
+            <button click="submit" class="remote-button">
+              {{ $t('user_card.remote_follow') }}
+            </button>
+          </form>
+        </div>
+        <div class='block' v-if='isOtherUser && loggedIn'>
+          <span v-if='user.statusnet_blocking'>
+            <button @click="unblockUser" class="pressed">
+              {{ $t('user_card.blocked') }}
+            </button>
+          </span>
+          <span v-if='!user.statusnet_blocking'>
+            <button @click="blockUser">
+              {{ $t('user_card.block') }}
+            </button>
+          </span>
         </div>
       </div>
     </div>
-    <div class="panel-body profile-panel-body">
-      <div class="user-counts" :class="{clickable: switcher}">
-        <div class="user-count" v-on:click.prevent="setProfileView('statuses')" :class="{selected: selected === 'statuses'}">
-          <h5>{{ $t('user_card.statuses') }}</h5>
-          <span>{{user.statuses_count}} <br></span>
-        </div>
-        <div class="user-count" v-on:click.prevent="setProfileView('friends')" :class="{selected: selected === 'friends'}">
-          <h5>{{ $t('user_card.followees') }}</h5>
-          <span>{{user.friends_count}}</span>
-        </div>
-        <div class="user-count" v-on:click.prevent="setProfileView('followers')" :class="{selected: selected === 'followers'}">
-          <h5>{{ $t('user_card.followers') }}</h5>
-          <span>{{user.followers_count}}</span>
-        </div>
-      </div>
-      <p v-if="!hideBio && user.description_html" class="profile-bio" v-html="user.description_html"></p>
-      <p v-else-if="!hideBio" class="profile-bio">{{ user.description }}</p>
-    </div>
   </div>
+  <div class="panel-body profile-panel-body">
+    <div class="user-counts" :class="{clickable: switcher}">
+      <div class="user-count" v-on:click.prevent="setProfileView('statuses')" :class="{selected: selected === 'statuses'}">
+        <h5>{{ $t('user_card.statuses') }}</h5>
+        <span>{{user.statuses_count}} <br></span>
+      </div>
+      <div class="user-count" v-on:click.prevent="setProfileView('friends')" :class="{selected: selected === 'friends'}">
+        <h5>{{ $t('user_card.followees') }}</h5>
+        <span>{{user.friends_count}}</span>
+      </div>
+      <div class="user-count" v-on:click.prevent="setProfileView('followers')" :class="{selected: selected === 'followers'}">
+        <h5>{{ $t('user_card.followers') }}</h5>
+        <span>{{user.followers_count}}</span>
+      </div>
+    </div>
+    <p v-if="!hideBio && user.description_html" class="profile-bio" v-html="user.description_html"></p>
+    <p v-else-if="!hideBio" class="profile-bio">{{ user.description }}</p>
+  </div>
+</div>
 </template>
 
 <script src="./user_card_content.js"></script>

From 2f1070deb63af7f351fb3e33e44394160c689be4 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 17:42:41 +0300
Subject: [PATCH 58/96] collateral fixes

---
 src/components/status/status.vue                     |  1 +
 .../user_card_content/user_card_content.vue          | 12 +++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index c4a268d0..710f2027 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -533,6 +533,7 @@ a.unmute {
   .status-el:last-child {
     border-bottom-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;;
     border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
+    border-bottom: none;
   }
 }
 
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index 22f77ffc..9830f283 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -120,6 +120,7 @@
   background-size: cover;
   border-radius: $fallback--panelRadius;
   border-radius: var(--panelRadius, $fallback--panelRadius);
+  overflow: hidden;
 
   .panel-heading {
     padding: 0.6em 0em;
@@ -147,7 +148,6 @@
     padding: 16px 10px 6px 10px;
     display: flex;
     max-height: 56px;
-    overflow: hidden;
 
     .avatar {
       border-radius: $fallback--avatarRadius;
@@ -187,6 +187,16 @@
     text-overflow: ellipsis;
     white-space: nowrap;
     flex: 1 1 0;
+    // This is so that text doesn't get overlapped by avatar's shadow if it has
+    // big one
+    z-index: 1;
+
+    img {
+      width: 26px;
+      height: 26px;
+      vertical-align: middle;
+      object-fit: contain
+    }
   }
 
   .user-name{

From 883a76147af6f9d60c6ac10e23b88e3148f076bb Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 19:12:38 +0300
Subject: [PATCH 59/96] validity checks, no longer exploding when something is
 invalid

---
 .../style_switcher/style_switcher.js          | 67 ++++++++++++++-----
 .../style_switcher/style_switcher.vue         |  2 +-
 2 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index d45ce455..286210b5 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -27,6 +27,14 @@ export default {
       selected: this.$store.state.config.theme,
       invalidThemeImported: false,
 
+      previewShadows: {},
+      previewColors: {},
+      previewRadii: {},
+
+      shadowsInvalid: true,
+      colorsInvalid: true,
+      radiiInvalid: true,
+
       keepShadows: false,
       keepOpacity: false,
       keepRoundness: false,
@@ -167,22 +175,6 @@ export default {
         attachment: this.attachmentRadiusLocal
       }
     },
-    previewColors () {
-      if (this.currentColors.bg) {
-        return generateColors({
-          opacity: this.currentOpacity,
-          colors: this.currentColors
-        })
-      } else {
-        return {}
-      }
-    },
-    previewRadii () {
-      return generateRadii({ radii: this.currentRadii })
-    },
-    previewShadows () {
-      return generateShadows({ shadows: this.shadowsLocal })
-    },
     preview () {
       return composePreset(this.previewColors, this.previewRadii, this.previewShadows)
     },
@@ -288,6 +280,9 @@ export default {
       set (v) {
         set(this.shadowsLocal, this.shadowSelected, v)
       }
+    },
+    themeValid () {
+      return !this.shadowsInvalid && !this.colorsInvalid && !this.radiiInvalid
     }
   },
   components: {
@@ -475,6 +470,46 @@ export default {
     }
   },
   watch: {
+    currentRadii () {
+      try {
+        this.previewRadii = generateRadii({ radii: this.currentRadii })
+        this.radiiInvalid = false
+      } catch (e) {
+        this.radiiInvalid = true
+        console.warn(e)
+      }
+    },
+    shadowsLocal () {
+      try {
+        this.previewShadows = generateShadows({ shadows: this.shadowsLocal })
+        this.shadowsInvalid = false
+      } catch (e) {
+        this.shadowsInvalid = true
+        console.warn(e)
+      }
+    },
+    currentColors () {
+      try {
+        this.previewColors = generateColors({
+          opacity: this.currentOpacity,
+          colors: this.currentColors
+        })
+        this.colorsInvalid = false
+      } catch (e) {
+        this.colorsInvalid = true
+        console.warn(e)
+      }
+    },
+    currentOpacity () {
+      try {
+        this.previewColors = generateColors({
+          opacity: this.currentOpacity,
+          colors: this.currentColors
+        })
+      } catch (e) {
+        console.warn(e)
+      }
+    },
     selected () {
       if (this.selectedVersion === 1) {
         if (!this.keepRoundness) {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index f5090321..5e9af19e 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -218,7 +218,7 @@
   </keep-alive>
 
   <div class="apply-container">
-    <button class="btn submit" @click="setCustomTheme">{{$t('general.apply')}}</button>
+    <button class="btn submit" :disabled="!themeValid" @click="setCustomTheme">{{$t('general.apply')}}</button>
     <button class="btn" @click="clearAll">{{$t('settings.style.switcher.reset')}}</button>
   </div>
 </div>

From e8536f3d95144945dcbd6bd96542f8401de3f1ed Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 19:15:54 +0300
Subject: [PATCH 60/96] clean up

---
 src/components/style_switcher/style_switcher.js | 2 --
 src/services/style_setter/style_setter.js       | 1 -
 2 files changed, 3 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 286210b5..57faa61b 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -396,7 +396,6 @@ export default {
 
     clearShadows () {
       this.shadowsLocal = {}
-      console.log(this.shadowsLocal)
     },
 
     /**
@@ -405,7 +404,6 @@ export default {
      * @param {Number} version - version of data. 0 means try to guess based on data.
      */
     normalizeLocalState (input, version = 0) {
-      console.log(input.opacity)
       const colors = input.colors || input
       const radii = input.radii || input
       const opacity = input.opacity
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 5726cd61..e11ee90c 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -345,7 +345,6 @@ const generateShadows = (input) => {
     ...(input.shadows || {})
   }
 
-  console.log(Object.entries(shadows).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';'))
   return {
     rules: {
       shadows: Object.entries(shadows).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';')

From 1a65895bfd441ea57163ee3e185785c82a81b736 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 21:48:16 +0300
Subject: [PATCH 61/96] initial font support

---
 src/App.scss                                  |  3 +
 src/components/font_control/font_control.vue  | 93 +++++++++++++++++++
 .../shadow_control/shadow_control.vue         |  5 +-
 .../style_switcher/style_switcher.js          | 63 ++++++++++---
 .../style_switcher/style_switcher.scss        |  3 +
 .../style_switcher/style_switcher.vue         | 55 ++++++++---
 src/i18n/en.json                              | 13 +++
 src/services/style_setter/style_setter.js     | 48 +++++++++-
 8 files changed, 251 insertions(+), 32 deletions(-)
 create mode 100644 src/components/font_control/font_control.vue

diff --git a/src/App.scss b/src/App.scss
index ceb0bb87..45491fd2 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -34,6 +34,7 @@ h4 {
 
 body {
   font-family: sans-serif;
+  font-family: var(--interfaceFont, sans-serif);
   font-size: 14px;
   margin: 0;
   color: $fallback--text;
@@ -62,6 +63,7 @@ button {
   box-shadow: var(--buttonShadow);
   font-size: 14px;
   font-family: sans-serif;
+  font-family: var(--interfaceFont, sans-serif);
 
   i[class*=icon-] {
     color: $fallback--text;
@@ -111,6 +113,7 @@ input, textarea, .select {
   color: $fallback--lightText;
   color: var(--inputText, $fallback--lightText);
   font-family: sans-serif;
+  font-family: var(--inputFont, sans-serif);
   font-size: 14px;
   padding: 8px 7px;
   box-sizing: border-box;
diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
new file mode 100644
index 00000000..424f6259
--- /dev/null
+++ b/src/components/font_control/font_control.vue
@@ -0,0 +1,93 @@
+<template>
+<div class="font-control style-control">
+  <label :for="preset === 'custom' ? name : name + '-font-switcher'" class="label">
+    {{label}}
+  </label>
+  <input
+    v-if="typeof fallback !== 'undefined'"
+    class="opt exlcude-disabled"
+    type="checkbox"
+    :id="name + '-o'"
+    :checked="present"
+    @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)">
+  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
+  <label :for="name + '-font-switcher'" class="select" :disabled="!present">
+    <select
+      :disabled="!present"
+      v-model="preset"
+      class="font-switcher"
+      id="name + '-font-switcher'">
+      <option v-for="option in options" :value="option">
+        {{ option }}
+      </option>
+    </select>
+    <i class="icon-down-open"/>
+  </label>
+  <input
+    v-if="preset === 'custom'"
+    class="custom-font"
+    type="text"
+    id="name"
+    v-model="family">
+</div>
+</template>
+
+<script>
+import { set } from 'vue'
+
+export default {
+  props: [
+    'name', 'label', 'value', 'fallback', 'options'
+  ],
+  data () {
+    return {
+      lValue: this.value
+    }
+  },
+  beforeUpdate () {
+    this.lValue = this.value
+  },
+  computed: {
+    present () {
+      return typeof this.lValue !== 'undefined'
+    },
+    dValue () {
+      return this.lValue || this.fallback || {}
+    },
+    family: {
+      get () {
+        return this.dValue.family
+      },
+      set (v) {
+        set(this.lValue, 'family', v)
+        this.$emit('input', this.lValue)
+      }
+    },
+    preset: {
+      get () {
+        console.log(this.family)
+        if (this.family === 'serif' ||
+            this.family === 'sans-serif' ||
+            this.family === 'monospace' ||
+            this.family === 'inherit') {
+          return this.family
+        } else {
+          return 'custom'
+        }
+      },
+      set (v) {
+        this.family = v === 'custom' ? '' : v
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+.font-control {
+  input.custom-font {
+    min-width: 10em;
+  }
+}
+</style>
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index 85346e17..744925d4 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -124,9 +124,9 @@
     <OpacityInput
       v-model="selected.alpha"
       :disabled="!present"/>
-    <div>
+    <p>
       {{$t('settings.style.shadows.hint')}}
-    </div>
+    </p>
   </div>
 </div>
 </template>
@@ -139,6 +139,7 @@
   display: flex;
   flex-wrap: wrap;
   justify-content: center;
+  margin-bottom: 1em;
 
   .shadow-preview-container,
   .shadow-tweak {
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 57faa61b..bbd28bdc 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,10 +1,11 @@
 import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
 import { set, delete as del } from 'vue'
-import { generateColors, generateShadows, generateRadii, composePreset } from '../../services/style_setter/style_setter.js'
+import { generateColors, generateShadows, generateRadii, generateFonts, composePreset } from '../../services/style_setter/style_setter.js'
 import ColorInput from '../color_input/color_input.vue'
 import RangeInput from '../range_input/range_input.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
 import ShadowControl from '../shadow_control/shadow_control.vue'
+import FontControl from '../font_control/font_control.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
 
@@ -30,6 +31,7 @@ export default {
       previewShadows: {},
       previewColors: {},
       previewRadii: {},
+      previewFonts: {},
 
       shadowsInvalid: true,
       colorsInvalid: true,
@@ -38,6 +40,7 @@ export default {
       keepShadows: false,
       keepOpacity: false,
       keepRoundness: false,
+      keepFonts: false,
 
       textColorLocal: '',
       linkColorLocal: '',
@@ -85,6 +88,7 @@ export default {
 
       shadowSelected: undefined,
       shadowsLocal: {},
+      fontsLocal: {},
 
       btnRadiusLocal: '',
       inputRadiusLocal: '',
@@ -176,10 +180,11 @@ export default {
       }
     },
     preview () {
-      return composePreset(this.previewColors, this.previewRadii, this.previewShadows)
+      return composePreset(this.previewColors, this.previewRadii, this.previewShadows, this.previewFonts)
     },
     previewTheme () {
-      if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
+      if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {}, fonts: {} }
+      console.log(this.preview.theme)
       return this.preview.theme
     },
     // This needs optimization maybe
@@ -253,7 +258,11 @@ export default {
     },
     previewRules () {
       if (!this.preview.rules) return ''
-      return [...Object.values(this.preview.rules), 'color: var(--text)'].join(';')
+      return [
+        ...Object.values(this.preview.rules),
+        'color: var(--text)',
+        'font-family: var(--interfaceFont, sans-serif)'
+      ].join(';')
     },
     shadowsAvailable () {
       return Object.keys(this.previewTheme.shadows).sort()
@@ -291,6 +300,7 @@ export default {
     RangeInput,
     ContrastRatio,
     ShadowControl,
+    FontControl,
     TabSwitcher
   },
   methods: {
@@ -300,6 +310,7 @@ export default {
         _pleroma_theme_version: 2,
         theme: {
           shadows: this.shadowsLocal,
+          fonts: this.fontsLocal,
           opacity: this.currentOpacity,
           colors: this.currentColors,
           radii: this.currentRadii
@@ -357,6 +368,7 @@ export default {
         name: 'customTheme',
         value: {
           shadows: this.shadowsLocal,
+          fonts: this.fontsLocal,
           opacity: this.currentOpacity,
           colors: this.currentColors,
           radii: this.currentRadii
@@ -398,6 +410,10 @@ export default {
       this.shadowsLocal = {}
     },
 
+    clearFonts () {
+      this.fontsLocal = {}
+    },
+
     /**
      * This applies stored theme data onto form.
      * @param {Object} input - input data
@@ -408,6 +424,7 @@ export default {
       const radii = input.radii || input
       const opacity = input.opacity
       const shadows = input.shadows || {}
+      const fonts = input.fonts || {}
 
       if (version === 0) {
         if (input.version) version = input.version
@@ -458,6 +475,11 @@ export default {
         this.shadowSelected = this.shadowsAvailable[0]
       }
 
+      if (!this.keepFonts) {
+        this.clearFonts()
+        this.fontsLocal = fonts
+      }
+
       if (opacity && !this.keepOpacity) {
         this.clearOpacity()
         Object.entries(opacity).forEach(([k, v]) => {
@@ -477,14 +499,31 @@ export default {
         console.warn(e)
       }
     },
-    shadowsLocal () {
-      try {
-        this.previewShadows = generateShadows({ shadows: this.shadowsLocal })
-        this.shadowsInvalid = false
-      } catch (e) {
-        this.shadowsInvalid = true
-        console.warn(e)
-      }
+    shadowsLocal: {
+      handler () {
+        try {
+          this.previewShadows = generateShadows({ shadows: this.shadowsLocal })
+          this.shadowsInvalid = false
+        } catch (e) {
+          this.shadowsInvalid = true
+          console.warn(e)
+        }
+      },
+      deep: true
+    },
+    fontsLocal: {
+      handler () {
+        try {
+          this.previewFonts = generateFonts({ fonts: this.fontsLocal })
+          console.log('BENIS')
+          console.log(this.previewFonts)
+          this.fontsInvalid = false
+        } catch (e) {
+          this.fontsInvalid = true
+          console.warn(e)
+        }
+      },
+      deep: true
     },
     currentColors () {
       try {
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index ad203856..9c4f4ecd 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -67,6 +67,7 @@
     flex-wrap: wrap;
   }
 
+  .fonts-container,
   .reset-container,
   .apply-container,
   .radius-container,
@@ -75,6 +76,7 @@
     display: flex;
   }
 
+  .fonts-container,
   .radius-container {
     flex-direction: column;
   }
@@ -87,6 +89,7 @@
     justify-content: space-between;
   }
 
+  .fonts-container,
   .color-container,
   .shadow-container,
   .radius-container,
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 5e9af19e..f64bda3f 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -75,7 +75,7 @@
     <tab-switcher key="style-tweak">
       <div :label="$t('settings.style.common_colors._tab_label')" class="color-container">
         <div class="tab-header">
-            <p>{{$t('settings.theme_help')}}</p>
+          <p>{{$t('settings.theme_help')}}</p>
           <button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
           <button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
@@ -169,20 +169,18 @@
         </div>
       </div>
       <div :label="$t('settings.style.radii._tab_label')" class="radius-container">
-        <div>
-          <div class="tab-header">
-            <p>{{$t('settings.radii_help')}}</p>
-            <button class="btn" @click="clearRoundness">{{$t('settings.style.switcher.clear_all')}}</button>
-          </div>
-          <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
-          <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="9" hardMin="0"/>
-          <RangeInput name="checkboxRadius" :label="$t('settings.checkboxRadius')" v-model="checkboxRadiusLocal" :fallback="previewTheme.radii.checkbox" max="16" hardMin="0"/>
-          <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
-          <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
-          <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
-          <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
-          <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
+        <div class="tab-header">
+          <p>{{$t('settings.radii_help')}}</p>
+          <button class="btn" @click="clearRoundness">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
+        <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
+        <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="9" hardMin="0"/>
+        <RangeInput name="checkboxRadius" :label="$t('settings.checkboxRadius')" v-model="checkboxRadiusLocal" :fallback="previewTheme.radii.checkbox" max="16" hardMin="0"/>
+        <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
+        <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
+        <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
+        <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
+        <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
       </div>
       <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
         <div class="tab-header shadow-selector">
@@ -214,6 +212,35 @@
         </div>
         <shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
       </div>
+      <div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
+        <div class="tab-header">
+          <p>{{$t('settings.style.fonts.help')}}</p>
+        </div>
+        <FontControl
+          name="ui"
+          v-model="fontsLocal.interface"
+          :label="$t('settings.style.fonts.components.interface')"
+          :fallback="previewTheme.fonts.interface"
+          :options="['serif', 'sans-serif', 'monospace', 'custom']" />
+        <FontControl
+          name="input"
+          v-model="fontsLocal.input"
+          :label="$t('settings.style.fonts.components.input')"
+          :fallback="previewTheme.fonts.input"
+          :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+        <FontControl
+          name="post"
+          v-model="fontsLocal.post"
+          :label="$t('settings.style.fonts.components.post')"
+          :fallback="previewTheme.fonts.post"
+          :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+        <FontControl
+          name="postCode"
+          v-model="fontsLocal.postCode"
+          :label="$t('settings.style.fonts.components.postCode')"
+          :fallback="previewTheme.fonts.postCode"
+          :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+      </div>
     </tab-switcher>
   </keep-alive>
 
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 5bd1ddbb..6f439f65 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -236,6 +236,19 @@
           "buttonPressedHover": "Button (pressed+hover)",
           "input": "Input field"
         }
+      },
+      "fonts": {
+        "_tab_label": "Fonts",
+        "help": "Select font to use for elements of UI. For \"custom\" you have to enter exact font name as it appears in system.",
+        "components": {
+          "interface": "Interface",
+          "input": "Input fields",
+          "post": "Post text",
+          "postCode": "Monospaced text in a post (rich text)"
+        },
+        "family": "Font name",
+        "size": "Size (in px)",
+        "weight": "Weight (boldness)"
       }
     }
   },
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index e11ee90c..f2c9c13e 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -85,6 +85,7 @@ const setColors = (input, commit) => {
   styleSheet.insertRule(`body { ${rules.radii} }`, 'index-max')
   styleSheet.insertRule(`body { ${rules.colors} }`, 'index-max')
   styleSheet.insertRule(`body { ${rules.shadows} }`, 'index-max')
+  styleSheet.insertRule(`body { ${rules.fonts} }`, 'index-max')
   body.style.display = 'initial'
 
   // commit('setOption', { name: 'colors', value: htmlColors })
@@ -267,6 +268,41 @@ const generateRadii = (input) => {
   }
 }
 
+const generateFonts = (input) => {
+  const fonts = Object.entries(input.fonts || {}).filter(([k, v]) => v).reduce((acc, [k, v]) => {
+    acc[k] = Object.entries(v).filter(([k, v]) => v).reduce((acc, [k, v]) => {
+      acc[k] = v
+      return acc
+    }, acc[k])
+    return acc
+  }, {
+    interface: {
+      family: 'sans-serif'
+    },
+    input: {
+      family: 'inherit'
+    },
+    post: {
+      family: 'inherit'
+    },
+    postCode: {
+      family: 'monospace'
+    }
+  })
+
+  return {
+    rules: {
+      fonts: Object
+        .entries(fonts)
+        .filter(([k, v]) => v)
+        .map(([k, v]) => `--${k}Font: ${v.family}`).join(';')
+    },
+    theme: {
+      fonts
+    }
+  }
+}
+
 const generateShadows = (input) => {
   const border = (top, shadow) => ({
     x: 0,
@@ -355,17 +391,19 @@ const generateShadows = (input) => {
   }
 }
 
-const composePreset = (colors, radii, shadows) => {
+const composePreset = (colors, radii, shadows, fonts) => {
   return {
     rules: {
       ...shadows.rules,
       ...colors.rules,
-      ...radii.rules
+      ...radii.rules,
+      ...fonts.rules
     },
     theme: {
       ...shadows.theme,
       ...colors.theme,
-      ...radii.theme
+      ...radii.theme,
+      ...fonts.theme
     }
   }
 }
@@ -374,8 +412,9 @@ const generatePreset = (input) => {
   const shadows = generateShadows(input)
   const colors = generateColors(input)
   const radii = generateRadii(input)
+  const fonts = generateFonts(input)
 
-  return composePreset(colors, radii, shadows)
+  return composePreset(colors, radii, shadows, fonts)
 }
 
 const setPreset = (val, commit) => {
@@ -424,6 +463,7 @@ export {
   generateColors,
   generateRadii,
   generateShadows,
+  generateFonts,
   generatePreset,
   composePreset,
   getCssShadow

From 707441ffe684f662a9b99c261d61fe2da5b5140f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 22:06:49 +0300
Subject: [PATCH 62/96] more fonts

---
 src/components/status/status.vue | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 710f2027..7d4ecbc7 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -324,6 +324,8 @@
 
   .status-content {
     margin-right: 0.5em;
+    font-family: var(--postFont, sans-serif);
+
     img, video {
       max-width: 100%;
       max-height: 400px;
@@ -338,6 +340,7 @@
 
     pre {
       overflow: auto;
+      font-family: var(--postCodeFont, sans-serif);
     }
 
     p {

From 1087741b0df00d42576c55f5869d331469bcbb6e Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 25 Nov 2018 22:39:06 +0300
Subject: [PATCH 63/96] font control args to allow passing an option list of
 fonts, for future use

---
 src/components/font_control/font_control.vue     | 14 +++++++++++---
 src/components/style_switcher/style_switcher.vue | 12 +++++-------
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
index 424f6259..004b5546 100644
--- a/src/components/font_control/font_control.vue
+++ b/src/components/font_control/font_control.vue
@@ -17,7 +17,7 @@
       v-model="preset"
       class="font-switcher"
       id="name + '-font-switcher'">
-      <option v-for="option in options" :value="option">
+      <option v-for="option in availableOptions" :value="option">
         {{ option }}
       </option>
     </select>
@@ -37,11 +37,19 @@ import { set } from 'vue'
 
 export default {
   props: [
-    'name', 'label', 'value', 'fallback', 'options'
+    'name', 'label', 'value', 'fallback', 'options', 'no-inherit'
   ],
   data () {
     return {
-      lValue: this.value
+      lValue: this.value,
+      availableOptions: [
+        this.noInherit ? '' : 'inherit',
+        'custom',
+        ...(this.options || []),
+        'serif',
+        'monospace',
+        'sans-serif'
+      ].filter(_ => _)
     }
   },
   beforeUpdate () {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index f64bda3f..a444c6a7 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -215,31 +215,29 @@
       <div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
         <div class="tab-header">
           <p>{{$t('settings.style.fonts.help')}}</p>
+          <button class="btn" @click="clearFonts">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
         <FontControl
           name="ui"
           v-model="fontsLocal.interface"
           :label="$t('settings.style.fonts.components.interface')"
           :fallback="previewTheme.fonts.interface"
-          :options="['serif', 'sans-serif', 'monospace', 'custom']" />
+          no-inherit="1"/>
         <FontControl
           name="input"
           v-model="fontsLocal.input"
           :label="$t('settings.style.fonts.components.input')"
-          :fallback="previewTheme.fonts.input"
-          :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+          :fallback="previewTheme.fonts.input"/>
         <FontControl
           name="post"
           v-model="fontsLocal.post"
           :label="$t('settings.style.fonts.components.post')"
-          :fallback="previewTheme.fonts.post"
-          :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+          :fallback="previewTheme.fonts.post"/>
         <FontControl
           name="postCode"
           v-model="fontsLocal.postCode"
           :label="$t('settings.style.fonts.components.postCode')"
-          :fallback="previewTheme.fonts.postCode"
-          :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+          :fallback="previewTheme.fonts.postCode"/>
       </div>
     </tab-switcher>
   </keep-alive>

From 94b481fa9c2bd5a9e135b589dcb78aa5fe802c87 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 00:19:28 +0300
Subject: [PATCH 64/96] cosmetic fixes

---
 src/App.scss                                 |  9 +++++---
 src/components/font_control/font_control.vue | 23 +++++++++++++++-----
 src/i18n/en.json                             |  3 ++-
 3 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 45491fd2..50645ec8 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -115,7 +115,7 @@ input, textarea, .select {
   font-family: sans-serif;
   font-family: var(--inputFont, sans-serif);
   font-size: 14px;
-  padding: 8px 7px;
+  padding: 8px .5em;
   box-sizing: border-box;
   display: inline-block;
   position: relative;
@@ -147,10 +147,13 @@ input, textarea, .select {
     appearance: none;
     background: transparent;
     border: none;
-    margin: 0;
     color: $fallback--text;
     color: var(--text, $fallback--text);
-    padding: 4px 2em 3px 3px;
+    margin: 0;
+    padding: 0 2em 0 .2em;
+    font-family: sans-serif;
+    font-family: var(--inputFont, sans-serif);
+    font-size: 14px;
     width: 100%;
     z-index: 1;
     height: 29px;
diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
index 004b5546..e97a2640 100644
--- a/src/components/font_control/font_control.vue
+++ b/src/components/font_control/font_control.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="font-control style-control">
+<div class="font-control style-control" :class="{ custom: isCustom }">
   <label :for="preset === 'custom' ? name : name + '-font-switcher'" class="label">
     {{label}}
   </label>
@@ -16,18 +16,18 @@
       :disabled="!present"
       v-model="preset"
       class="font-switcher"
-      id="name + '-font-switcher'">
+      :id="name + '-font-switcher'">
       <option v-for="option in availableOptions" :value="option">
-        {{ option }}
+        {{ option === 'custom' ? $t('settings.style.fonts.custom') : option }}
       </option>
     </select>
     <i class="icon-down-open"/>
   </label>
   <input
-    v-if="preset === 'custom'"
+    v-if="isCustom"
     class="custom-font"
     type="text"
-    id="name"
+    :id="name"
     v-model="family">
 </div>
 </template>
@@ -71,6 +71,9 @@ export default {
         this.$emit('input', this.lValue)
       }
     },
+    isCustom () {
+      return this.preset === 'custom'
+    },
     preset: {
       get () {
         console.log(this.family)
@@ -97,5 +100,15 @@ export default {
   input.custom-font {
     min-width: 10em;
   }
+  &.custom {
+    .select {
+      border-top-right-radius: 0;
+      border-bottom-right-radius: 0;
+    }
+    .custom-font {
+      border-top-left-radius: 0;
+      border-bottom-left-radius: 0;
+    }
+  }
 }
 </style>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 6f439f65..c70c488c 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -248,7 +248,8 @@
         },
         "family": "Font name",
         "size": "Size (in px)",
-        "weight": "Weight (boldness)"
+        "weight": "Weight (boldness)",
+        "custom": "Custom"
       }
     }
   },

From d7eec4c30d93b8a87fa912543889bd106398042d Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 00:23:07 +0300
Subject: [PATCH 65/96] more styles

---
 src/components/status/status.vue | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 7d4ecbc7..8682d996 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -340,7 +340,10 @@
 
     pre {
       overflow: auto;
-      font-family: var(--postCodeFont, sans-serif);
+    }
+
+    code, samp, kbd, var, pre {
+      font-family: var(--postCodeFont, monospace);
     }
 
     p {

From 572c874f5cd1e997de70c7771075ca1444f95549 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 02:29:08 +0300
Subject: [PATCH 66/96] theme separation

---
 src/components/font_control/font_control.vue  |   1 -
 .../style_switcher/style_switcher.js          |  29 +-
 static/styles.json                            | 848 +-----------------
 static/themes/redmond-xx-se.json              | 285 ++++++
 static/themes/redmond-xx.json                 | 274 ++++++
 static/themes/redmond-xxi.json                | 285 ++++++
 6 files changed, 873 insertions(+), 849 deletions(-)
 create mode 100644 static/themes/redmond-xx-se.json
 create mode 100644 static/themes/redmond-xx.json
 create mode 100644 static/themes/redmond-xxi.json

diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
index e97a2640..85f19eea 100644
--- a/src/components/font_control/font_control.vue
+++ b/src/components/font_control/font_control.vue
@@ -76,7 +76,6 @@ export default {
     },
     preset: {
       get () {
-        console.log(this.family)
         if (this.family === 'serif' ||
             this.family === 'sans-serif' ||
             this.family === 'monospace' ||
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index bbd28bdc..d833341f 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -106,7 +106,31 @@ export default {
     window.fetch('/static/styles.json')
       .then((data) => data.json())
       .then((themes) => {
-        self.availableStyles = themes
+        return Promise.all(Object.entries(themes).map(([k, v]) => {
+          if (typeof v === 'object') {
+            return Promise.resolve([k, v])
+          } else if (typeof v === 'string') {
+            return window.fetch(v)
+              .then((data) => data.json())
+              .then((theme) => {
+                return [k, theme]
+              })
+              .catch((e) => {
+                console.error(e)
+                return []
+              })
+          }
+        }))
+      })
+      .then((promises) => {
+        return promises
+          .filter(([k, v]) => v)
+          .reduce((acc, [k, v]) => {
+            acc[k] = v
+            return acc
+          }, {})
+      }).then((themesComplete) => {
+        self.availableStyles = themesComplete
       })
   },
   mounted () {
@@ -184,7 +208,6 @@ export default {
     },
     previewTheme () {
       if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {}, fonts: {} }
-      console.log(this.preview.theme)
       return this.preview.theme
     },
     // This needs optimization maybe
@@ -515,8 +538,6 @@ export default {
       handler () {
         try {
           this.previewFonts = generateFonts({ fonts: this.fontsLocal })
-          console.log('BENIS')
-          console.log(this.previewFonts)
           this.fontsInvalid = false
         } catch (e) {
           this.fontsInvalid = true
diff --git a/static/styles.json b/static/styles.json
index a53eeaa1..9204c717 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -6,848 +6,8 @@
   "ir-black": [ "Ir Black", "#000000", "#242422", "#b5b3aa", "#ff6c60", "#FF6C60", "#A8FF60", "#96CBFE", "#FFFFB6" ],
   "monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672", "#F92672", "#a6e22e", "#66d9ef", "#f4bf75" ],
   "mammal": [ "Mammal", "#272c37", "#444b5d", "#f8f8f8", "#9bacc8", "#7f3142", "#2bd850", "#2b90d9", "#ca8f04" ],
-  "redmond-xx": {
-    "_pleroma_theme_version": 2,
-    "name": "Redmond XX",
-    "theme": {
-      "shadows": {
-        "panel": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "button": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "buttonHover": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "buttonPressed": [
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "input": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--input",
-            "alpha": "1",
-            "inset": true
-          }
-        ]
-      },
-      "opacity": {
-        "input": "1"
-      },
-      "colors": {
-        "bg": "#c0c0c0",
-        "text": "#000000",
-        "link": "#0000ff",
-        "fg": "#c0c0c0",
-        "panel": "#000080",
-        "input": "#ffffff",
-        "topBar": "#000080",
-        "topBarLink": "#ffffff",
-        "btn": "#c0c0c0",
-        "faint": "#3f3f3f",
-        "faintLink": "#404080",
-        "border": "#808080",
-        "cRed": "#FF0000",
-        "cBlue": "#008080",
-        "cGreen": "#00FF00",
-        "cOrange": "#808000"
-      },
-      "radii": {
-        "btn": "0",
-        "input": "0",
-        "checkbox": "0",
-        "panel": "0",
-        "avatar": "0",
-        "avatarAlt": "0",
-        "tooltip": "0",
-        "attachment": "0"
-      }
-    }
-  },
-  "redmond-xx-se": {
-    "_pleroma_theme_version": 2,
-    "name": "Redmond XX SE",
-    "theme": {
-      "shadows": {
-        "panel": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "button": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "buttonHover": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "buttonPressed": [
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "input": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--input",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "panelHeader": [
-          {
-            "x": "-2200",
-            "y": 0,
-            "blur": "200",
-            "spread": "-2000",
-            "inset": true,
-            "color": "#1084d0",
-            "alpha": 1
-          }
-        ]
-      },
-      "opacity": {
-        "input": "1"
-      },
-      "colors": {
-        "bg": "#c0c0c0",
-        "text": "#000000",
-        "link": "#0000ff",
-        "fg": "#c0c0c0",
-        "panel": "#000080",
-        "input": "#ffffff",
-        "topBar": "#000080",
-        "topBarLink": "#ffffff",
-        "btn": "#c0c0c0",
-        "faint": "#3f3f3f",
-        "faintLink": "#404080",
-        "border": "#808080",
-        "cRed": "#FF0000",
-        "cBlue": "#008080",
-        "cGreen": "#00FF00",
-        "cOrange": "#808000"
-      },
-      "radii": {
-        "btn": "0",
-        "input": "0",
-        "checkbox": "0",
-        "panel": "0",
-        "avatar": "0",
-        "avatarAlt": "0",
-        "tooltip": "0",
-        "attachment": "0"
-      }
-    }
-  },
-  "redmond-xxi": {
-    "_pleroma_theme_version": 2,
-    "name": "Redmond XXI",
-    "theme": {
-      "shadows": {
-        "panel": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "button": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "buttonHover": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "buttonPressed": [
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--bg",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "input": [
-          {
-            "x": "-1",
-            "y": "-1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#FFFFFF",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "1",
-            "y": "1",
-            "blur": "0",
-            "spread": 0,
-            "color": "#848484",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "-2",
-            "y": "-2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#dfdfdf",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "2",
-            "y": "2",
-            "blur": "0",
-            "spread": 0,
-            "color": "#000000",
-            "alpha": "1",
-            "inset": true
-          },
-          {
-            "x": "0",
-            "y": "0",
-            "blur": "0",
-            "spread": "3",
-            "color": "--input",
-            "alpha": "1",
-            "inset": true
-          }
-        ],
-        "panelHeader": [
-          {
-            "x": "-2200",
-            "y": 0,
-            "blur": "200",
-            "spread": "-2000",
-            "inset": true,
-            "color": "#a5cef7",
-            "alpha": 1
-          }
-        ]
-      },
-      "opacity": {
-        "input": "1"
-      },
-      "colors": {
-        "bg": "#d6d6ce",
-        "text": "#000000",
-        "link": "#0000ff",
-        "fg": "#d6d6ce",
-        "panel": "#042967",
-        "input": "#ffffff",
-        "topBar": "#042967",
-        "topBarLink": "#ffffff",
-        "btn": "#d6d6ce",
-        "faint": "#3f3f3f",
-        "faintLink": "#404080",
-        "border": "#808080",
-        "cRed": "#FF0000",
-        "cBlue": "#008080",
-        "cGreen": "#00FF00",
-        "cOrange": "#808000"
-      },
-      "radii": {
-        "btn": "0",
-        "input": "0",
-        "checkbox": "0",
-        "panel": "0",
-        "avatar": "0",
-        "avatarAlt": "0",
-        "tooltip": "0",
-        "attachment": "0"
-      }
-    }
-  }
+
+  "redmond-xx": "./static/themes/redmond-xx.json",
+  "redmond-xx-se": "./static/themes/redmond-xx-se.json",
+  "redmond-xxi": "./static/themes/redmond-xxi.json"
 }
diff --git a/static/themes/redmond-xx-se.json b/static/themes/redmond-xx-se.json
new file mode 100644
index 00000000..e4cdbdee
--- /dev/null
+++ b/static/themes/redmond-xx-se.json
@@ -0,0 +1,285 @@
+{
+  "_pleroma_theme_version": 2,
+  "name": "Redmond XX SE",
+  "theme": {
+    "shadows": {
+      "panel": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "button": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "buttonHover": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "buttonPressed": [
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "input": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--input",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "panelHeader": [
+        {
+          "x": "-2200",
+          "y": 0,
+          "blur": "200",
+          "spread": "-2000",
+          "inset": true,
+          "color": "#1084d0",
+          "alpha": 1
+        }
+      ]
+    },
+    "opacity": {
+      "input": "1"
+    },
+    "colors": {
+      "bg": "#c0c0c0",
+      "text": "#000000",
+      "link": "#0000ff",
+      "fg": "#c0c0c0",
+      "panel": "#000080",
+      "input": "#ffffff",
+      "topBar": "#000080",
+      "topBarLink": "#ffffff",
+      "btn": "#c0c0c0",
+      "faint": "#3f3f3f",
+      "faintLink": "#404080",
+      "border": "#808080",
+      "cRed": "#FF0000",
+      "cBlue": "#008080",
+      "cGreen": "#00FF00",
+      "cOrange": "#808000"
+    },
+    "radii": {
+      "btn": "0",
+      "input": "0",
+      "checkbox": "0",
+      "panel": "0",
+      "avatar": "0",
+      "avatarAlt": "0",
+      "tooltip": "0",
+      "attachment": "0"
+    }
+  }
+}
diff --git a/static/themes/redmond-xx.json b/static/themes/redmond-xx.json
new file mode 100644
index 00000000..96dff499
--- /dev/null
+++ b/static/themes/redmond-xx.json
@@ -0,0 +1,274 @@
+{
+  "_pleroma_theme_version": 2,
+  "name": "Redmond XX",
+  "theme": {
+    "shadows": {
+      "panel": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "button": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "buttonHover": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "buttonPressed": [
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "input": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--input",
+          "alpha": "1",
+          "inset": true
+        }
+      ]
+    },
+    "opacity": {
+      "input": "1"
+    },
+    "colors": {
+      "bg": "#c0c0c0",
+      "text": "#000000",
+      "link": "#0000ff",
+      "fg": "#c0c0c0",
+      "panel": "#000080",
+      "input": "#ffffff",
+      "topBar": "#000080",
+      "topBarLink": "#ffffff",
+      "btn": "#c0c0c0",
+      "faint": "#3f3f3f",
+      "faintLink": "#404080",
+      "border": "#808080",
+      "cRed": "#FF0000",
+      "cBlue": "#008080",
+      "cGreen": "#00FF00",
+      "cOrange": "#808000"
+    },
+    "radii": {
+      "btn": "0",
+      "input": "0",
+      "checkbox": "0",
+      "panel": "0",
+      "avatar": "0",
+      "avatarAlt": "0",
+      "tooltip": "0",
+      "attachment": "0"
+    }
+  }
+}
diff --git a/static/themes/redmond-xxi.json b/static/themes/redmond-xxi.json
new file mode 100644
index 00000000..1469cc6b
--- /dev/null
+++ b/static/themes/redmond-xxi.json
@@ -0,0 +1,285 @@
+{
+  "_pleroma_theme_version": 2,
+  "name": "Redmond XXI",
+  "theme": {
+    "shadows": {
+      "panel": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "button": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "buttonHover": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "buttonPressed": [
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--bg",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "input": [
+        {
+          "x": "-1",
+          "y": "-1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#FFFFFF",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "0",
+          "spread": 0,
+          "color": "#848484",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "-2",
+          "y": "-2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#dfdfdf",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "2",
+          "y": "2",
+          "blur": "0",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "1",
+          "inset": true
+        },
+        {
+          "x": "0",
+          "y": "0",
+          "blur": "0",
+          "spread": "3",
+          "color": "--input",
+          "alpha": "1",
+          "inset": true
+        }
+      ],
+      "panelHeader": [
+        {
+          "x": "-2200",
+          "y": 0,
+          "blur": "200",
+          "spread": "-2000",
+          "inset": true,
+          "color": "#a5cef7",
+          "alpha": 1
+        }
+      ]
+    },
+    "opacity": {
+      "input": "1"
+    },
+    "colors": {
+      "bg": "#d6d6ce",
+      "text": "#000000",
+      "link": "#0000ff",
+      "fg": "#d6d6ce",
+      "panel": "#042967",
+      "input": "#ffffff",
+      "topBar": "#042967",
+      "topBarLink": "#ffffff",
+      "btn": "#d6d6ce",
+      "faint": "#3f3f3f",
+      "faintLink": "#404080",
+      "border": "#808080",
+      "cRed": "#FF0000",
+      "cBlue": "#008080",
+      "cGreen": "#00FF00",
+      "cOrange": "#808000"
+    },
+    "radii": {
+      "btn": "0",
+      "input": "0",
+      "checkbox": "0",
+      "panel": "0",
+      "avatar": "0",
+      "avatarAlt": "0",
+      "tooltip": "0",
+      "attachment": "0"
+    }
+  }
+}

From 9a9dc47fc573af28429a641bf5408ead1c0d33ec Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 03:19:04 +0300
Subject: [PATCH 67/96] better preview, collateral fixes

---
 src/App.scss                                  | 27 ++++++++
 .../notifications/notifications.scss          | 17 ------
 .../notifications/notifications.vue           |  2 +-
 src/components/status/status.vue              |  1 +
 .../style_switcher/style_switcher.scss        | 25 +++++++-
 .../style_switcher/style_switcher.vue         | 61 +++++++++++++++++--
 src/components/timeline/timeline.vue          |  5 +-
 src/i18n/en.json                              | 13 ++++
 8 files changed, 123 insertions(+), 28 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 50645ec8..8c9df0ba 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -381,6 +381,12 @@ main-router {
     font-size: 1.3em;
   }
 
+  .faint {
+    background-color: transparent;
+    color: $fallback--faint;
+    color: var(--panelFaint, $fallback--faint);
+  }
+
   .alert {
     white-space: nowrap;
     text-overflow: ellipsis;
@@ -509,6 +515,27 @@ nav {
     flex-grow: 0;
   }
 }
+.badge {
+  display: inline-block;
+  border-radius: 99px;
+  min-width: 22px;
+  max-width: 22px;
+  min-height: 22px;
+  max-height: 22px;
+  font-size: 15px;
+  line-height: 22px;
+  text-align: center;
+  vertical-align: middle;
+  white-space: nowrap;
+  padding: 0;
+
+  &.badge-notification {
+    background-color: $fallback--cRed;
+    background-color: var(--badgeNotification, $fallback--cRed);
+    color: white;
+    color: var(--badgeNotificationText, white);
+  }
+}
 
 .alert {
   margin: 0.35em;
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 3f22b690..87c89f6a 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -4,23 +4,6 @@
   // a bit of a hack to allow scrolling below notifications
   padding-bottom: 15em;
 
-  .unseen-count {
-    display: inline-block;
-    background-color: $fallback--cRed;
-    background-color: var(--badgeNotification, $fallback--cRed);
-    border-radius: 99px;
-    min-width: 22px;
-    max-width: 22px;
-    min-height: 22px;
-    max-height: 22px;
-    color: white;
-    color: var(--badgeNotificationText, white);
-    font-size: 15px;
-    line-height: 22px;
-    text-align: center;
-    vertical-align: middle
-  }
-
   .loadmore-error {
     color: $fallback--text;
     color: var(--text, $fallback--text);
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index eb6c4dd0..64f18720 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -4,7 +4,7 @@
       <div class="panel-heading">
         <div class="title">
           {{$t('notifications.notifications')}}
-          <span class="unseen-count" v-if="unseenCount">{{unseenCount}}</span>
+          <span class="badge badge-notification unseen-count" v-if="unseenCount">{{unseenCount}}</span>
         </div>
         <div @click.prevent class="loadmore-error alert error" v-if="error">
           {{$t('timeline.error_fetching')}}
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 8682d996..0edc7b71 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -471,6 +471,7 @@
 .avatar {
   width: 48px;
   height: 48px;
+  box-shadow: var(--avatarStatusShadow);
   border-radius: $fallback--avatarRadius;
   border-radius: var(--avatarRadius, $fallback--avatarRadius);
   overflow: hidden;
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 9c4f4ecd..2c33224b 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -163,11 +163,32 @@
     background-size: cover;
     background-position: 50% 50%;
 
+    .separator {
+      margin: 1em;
+      border-bottom: 1px solid;
+      border-color: $fallback--border;
+      border-color: var(--border, $fallback--border);
+    }
+
+    .panel-heading {
+      .badge, .alert, .btn, .faint {
+        margin-left: 1em;
+      }
+      .flex-spacer {
+        flex: 1;
+      }
+    }
+    .checkbox {
+      display: inline-flex;
+      align-items: baseline;
+      margin-right: 1em;
+    }
+
     .btn {
       margin-left: 0;
-      margin-top: 1em;
+      padding: 0 1em;
+      min-width: 3em;
       min-height: 30px;
-      width: 10em;
     }
   }
 
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index a444c6a7..2a7756ed 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -46,27 +46,80 @@
           v-model="keepRoundness">
         <label for="keep-roundness">{{$t('settings.style.switcher.keep_roundness')}}</label>
       </span>
+      <span>
+        <input
+          id="keep-fonts"
+          type="checkbox"
+          v-model="keepFonts">
+        <label for="keep-fonts">{{$t('settings.style.switcher.keep_fonts')}}</label>
+      </span>
       <p>{{$t('settings.style.switcher.save_load_hint')}}</p>
     </div>
   </div>
 
   <div class="preview-container">
     <div class="panel dummy" :style="previewRules">
-      <div class="panel-heading">Preview</div>
+      <div class="panel-heading">
+        {{$t('settings.style.preview.header')}}
+        <span class="badge badge-notification">
+          99
+        </span>
+        <span class="alert error">
+          {{$t('settings.style.preview.error')}}
+        </span>
+        <button class="btn">
+          {{$t('settings.style.preview.button')}}
+        </button>
+        <span class="flex-spacer"/>
+        <span class="faint">
+          {{$t('settings.style.preview.header_faint')}}
+        </span>
+      </div>
       <div class="panel-body theme-preview-content">
         <div class="avatar">
           ( ͡° ͜ʖ ͡°)
         </div>
         <h4>Content</h4>
+
         <br>
-        A bunch of more content and
-        <a style="color: var(--link)">a nice lil' link</a>
+
+        <i18n path="settings.style.preview.text">
+          <a style="color: var(--link)">
+            {{$t('settings.style.preview.link')}}
+          </a>
+        </i18n>
+
         <i style="color: var(--cBlue)" class="icon-reply"/>
         <i style="color: var(--cGreen)" class="icon-retweet"/>
         <i style="color: var(--cRed)" class="icon-cancel"/>
         <i style="color: var(--cOrange)" class="icon-star"/>
+
         <br>
-        <button class="btn">Button</button>
+        <br>
+
+        <input :value="$t('settings.style.preview.error')" type="text">
+        <span class="alert error">
+          {{$t('settings.style.preview.error')}}
+        </span>
+
+        <br>
+        <br>
+
+        <span class="checkbox">
+          <input checked="very yes" type="checkbox" id="preview_checkbox">
+          <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
+        </span>
+        <button class="btn">
+          {{$t('settings.style.preview.button')}}
+        </button>
+
+        <div class="separator"></div>
+
+        <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
+          <a style="color: var(--faintLink)">
+            {{$t('settings.style.preview.faint_link')}}
+          </a>
+        </i18n>
       </div>
     </div>
   </div>
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 39f1b5bc..b69a09fd 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -58,10 +58,7 @@
 
 .timeline {
   .loadmore-text {
-    opacity: 0.8;
-    background-color: transparent;
-    color: $fallback--faint;
-    color: var(--panelFaint, $fallback--faint);
+    opacity: 1;
   }
 }
 
diff --git a/src/i18n/en.json b/src/i18n/en.json
index c70c488c..0530b66d 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -170,6 +170,7 @@
         "keep_shadows": "Keep shadows",
         "keep_opacity": "Keep opacity",
         "keep_roundness": "Keep roundness",
+        "keep_fonts": "Keep fonts",
         "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme.",
         "reset": "Reset",
         "clear_all": "Clear all",
@@ -250,6 +251,18 @@
         "size": "Size (in px)",
         "weight": "Weight (boldness)",
         "custom": "Custom"
+      },
+      "preview": {
+        "header": "Preview of header",
+        "error": "Example error",
+        "button": "Button",
+        "text": "A bunch of more content and {0}",
+        "input": "Just landed in L.A.",
+        "faint_link": "helpful manual",
+        "fine_print": "Read our {0} to learn nothing useful!",
+        "header_faint": "This is fine",
+        "checkbox": "I have skimmed over terms and conditions",
+        "link": "a nice lil' link"
       }
     }
   },

From 08838774e41b9beba8f884da15ab1314eddf28f8 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 03:51:12 +0300
Subject: [PATCH 68/96] redmond update

---
 static/themes/redmond-xx-se.json | 38 ++++++++++-----
 static/themes/redmond-xx.json    | 18 ++++++-
 static/themes/redmond-xxi.json   | 83 +++++++++++++-------------------
 3 files changed, 75 insertions(+), 64 deletions(-)

diff --git a/static/themes/redmond-xx-se.json b/static/themes/redmond-xx-se.json
index e4cdbdee..70ee89d1 100644
--- a/static/themes/redmond-xx-se.json
+++ b/static/themes/redmond-xx-se.json
@@ -50,6 +50,26 @@
           "inset": true
         }
       ],
+      "panelHeader": [
+        {
+          "x": 0,
+          "y": 0,
+          "blur": 0,
+          "spread": "3",
+          "inset": true,
+          "color": "#c0c0c0",
+          "alpha": 1
+        },
+        {
+          "x": "-2200",
+          "y": 0,
+          "blur": "200",
+          "spread": "-2000",
+          "inset": true,
+          "color": "#1084d0",
+          "alpha": 1
+        }
+      ],
       "button": [
         {
           "x": "-1",
@@ -237,21 +257,12 @@
           "alpha": "1",
           "inset": true
         }
-      ],
-      "panelHeader": [
-        {
-          "x": "-2200",
-          "y": 0,
-          "blur": "200",
-          "spread": "-2000",
-          "inset": true,
-          "color": "#1084d0",
-          "alpha": 1
-        }
       ]
     },
+    "fonts": {},
     "opacity": {
-      "input": "1"
+      "input": "1",
+      "faint": "1"
     },
     "colors": {
       "bg": "#c0c0c0",
@@ -259,6 +270,7 @@
       "link": "#0000ff",
       "fg": "#c0c0c0",
       "panel": "#000080",
+      "panelFaint": "#c0c0c0",
       "input": "#ffffff",
       "topBar": "#000080",
       "topBarLink": "#ffffff",
@@ -268,7 +280,7 @@
       "border": "#808080",
       "cRed": "#FF0000",
       "cBlue": "#008080",
-      "cGreen": "#00FF00",
+      "cGreen": "#008000",
       "cOrange": "#808000"
     },
     "radii": {
diff --git a/static/themes/redmond-xx.json b/static/themes/redmond-xx.json
index 96dff499..4fd6a369 100644
--- a/static/themes/redmond-xx.json
+++ b/static/themes/redmond-xx.json
@@ -50,6 +50,17 @@
           "inset": true
         }
       ],
+      "panelHeader": [
+        {
+          "x": 0,
+          "y": 0,
+          "blur": 0,
+          "spread": "3",
+          "inset": true,
+          "color": "#c0c0c0",
+          "alpha": 1
+        }
+      ],
       "button": [
         {
           "x": "-1",
@@ -239,8 +250,10 @@
         }
       ]
     },
+    "fonts": {},
     "opacity": {
-      "input": "1"
+      "input": "1",
+      "faint": "1"
     },
     "colors": {
       "bg": "#c0c0c0",
@@ -248,6 +261,7 @@
       "link": "#0000ff",
       "fg": "#c0c0c0",
       "panel": "#000080",
+      "panelFaint": "#c0c0c0",
       "input": "#ffffff",
       "topBar": "#000080",
       "topBarLink": "#ffffff",
@@ -257,7 +271,7 @@
       "border": "#808080",
       "cRed": "#FF0000",
       "cBlue": "#008080",
-      "cGreen": "#00FF00",
+      "cGreen": "#008000",
       "cOrange": "#808000"
     },
     "radii": {
diff --git a/static/themes/redmond-xxi.json b/static/themes/redmond-xxi.json
index 1469cc6b..d10bf138 100644
--- a/static/themes/redmond-xxi.json
+++ b/static/themes/redmond-xxi.json
@@ -9,7 +9,7 @@
           "y": "-1",
           "blur": "0",
           "spread": 0,
-          "color": "#000000",
+          "color": "#404040",
           "alpha": "1",
           "inset": true
         },
@@ -50,13 +50,33 @@
           "inset": true
         }
       ],
+      "panelHeader": [
+        {
+          "x": 0,
+          "y": 0,
+          "blur": 0,
+          "spread": "3",
+          "inset": true,
+          "color": "#d6d6ce",
+          "alpha": 1
+        },
+        {
+          "x": "-2200",
+          "y": 0,
+          "blur": "200",
+          "spread": "-2000",
+          "inset": true,
+          "color": "#a5cef7",
+          "alpha": 1
+        }
+      ],
       "button": [
         {
           "x": "-1",
           "y": "-1",
           "blur": "0",
           "spread": 0,
-          "color": "#000000",
+          "color": "#404040",
           "alpha": "1",
           "inset": true
         },
@@ -78,15 +98,6 @@
           "alpha": "1",
           "inset": true
         },
-        {
-          "x": "2",
-          "y": "2",
-          "blur": "0",
-          "spread": 0,
-          "color": "#dfdfdf",
-          "alpha": "1",
-          "inset": true
-        },
         {
           "x": "0",
           "y": "0",
@@ -103,7 +114,7 @@
           "y": "-1",
           "blur": "0",
           "spread": 0,
-          "color": "#000000",
+          "color": "#404040",
           "alpha": "1",
           "inset": true
         },
@@ -125,15 +136,6 @@
           "alpha": "1",
           "inset": true
         },
-        {
-          "x": "2",
-          "y": "2",
-          "blur": "0",
-          "spread": 0,
-          "color": "#dfdfdf",
-          "alpha": "1",
-          "inset": true
-        },
         {
           "x": "0",
           "y": "0",
@@ -150,7 +152,7 @@
           "y": "1",
           "blur": "0",
           "spread": 0,
-          "color": "#000000",
+          "color": "#404040",
           "alpha": "1",
           "inset": true
         },
@@ -172,15 +174,6 @@
           "alpha": "1",
           "inset": true
         },
-        {
-          "x": "-2",
-          "y": "-2",
-          "blur": "0",
-          "spread": 0,
-          "color": "#dfdfdf",
-          "alpha": "1",
-          "inset": true
-        },
         {
           "x": "0",
           "y": "0",
@@ -215,7 +208,7 @@
           "y": "-2",
           "blur": "0",
           "spread": 0,
-          "color": "#dfdfdf",
+          "color": "#d4d0c8",
           "alpha": "1",
           "inset": true
         },
@@ -224,7 +217,7 @@
           "y": "2",
           "blur": "0",
           "spread": 0,
-          "color": "#000000",
+          "color": "#404040",
           "alpha": "1",
           "inset": true
         },
@@ -237,21 +230,12 @@
           "alpha": "1",
           "inset": true
         }
-      ],
-      "panelHeader": [
-        {
-          "x": "-2200",
-          "y": 0,
-          "blur": "200",
-          "spread": "-2000",
-          "inset": true,
-          "color": "#a5cef7",
-          "alpha": 1
-        }
       ]
     },
+    "fonts": {},
     "opacity": {
-      "input": "1"
+      "input": "1",
+      "faint": "1"
     },
     "colors": {
       "bg": "#d6d6ce",
@@ -259,6 +243,7 @@
       "link": "#0000ff",
       "fg": "#d6d6ce",
       "panel": "#042967",
+      "panelFaint": "#FFFFFF",
       "input": "#ffffff",
       "topBar": "#042967",
       "topBarLink": "#ffffff",
@@ -266,10 +251,10 @@
       "faint": "#3f3f3f",
       "faintLink": "#404080",
       "border": "#808080",
-      "cRed": "#FF0000",
-      "cBlue": "#008080",
-      "cGreen": "#00FF00",
-      "cOrange": "#808000"
+      "cRed": "#c42726",
+      "cBlue": "#6699cc",
+      "cGreen": "#669966",
+      "cOrange": "#cc6633"
     },
     "radii": {
       "btn": "0",

From bb39b99d65bf897e073bc809ccc924f1b0ecc58b Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 20:12:59 +0300
Subject: [PATCH 69/96] fix panel link color, fix broken user profiles

---
 src/App.scss                                           | 10 ++++++++++
 src/components/style_switcher/style_switcher.js        |  4 ++++
 src/components/style_switcher/style_switcher.vue       |  4 +++-
 src/components/user_card_content/user_card_content.vue |  5 ++---
 src/services/style_setter/style_setter.js              |  1 +
 5 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 8c9df0ba..15dec7ec 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -407,6 +407,11 @@ main-router {
     min-width: 1px;
     align-self: stretch;
   }
+
+  a {
+    color: $fallback--link;
+    color: var(--panelLink, $fallback--link)
+  }
 }
 
 .panel-heading.stub {
@@ -417,6 +422,11 @@ main-router {
 .panel-footer {
   border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
   border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
+
+  a {
+    color: $fallback--link;
+    color: var(--panelLink, $fallback--link)
+  }
 }
 
 .panel-body > p {
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index d833341f..0cceee4c 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -62,6 +62,7 @@ export default {
 
       panelColorLocal: undefined,
       panelTextColorLocal: undefined,
+      panelLinkColorLocal: undefined,
       panelFaintColorLocal: undefined,
       panelOpacityLocal: undefined,
 
@@ -155,6 +156,7 @@ export default {
 
         panel: this.panelColorLocal,
         panelText: this.panelTextColorLocal,
+        panelLink: this.panelLinkColorLocal,
         panelFaint: this.panelFaintColorLocal,
 
         input: this.inputColorLocal,
@@ -230,6 +232,7 @@ export default {
       const fgs = {
         text: hex2rgb(colors.text),
         panelText: hex2rgb(colors.panelText),
+        panelLink: hex2rgb(colors.panelLink),
         btnText: hex2rgb(colors.btnText),
         topBarText: hex2rgb(colors.topBarText),
         inputText: hex2rgb(colors.inputText),
@@ -268,6 +271,7 @@ export default {
         tintText: getContrastRatio(alphaBlend(bgs.bg, 0.5, fgs.panelText), fgs.text),
 
         panelText: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
+        panelLink: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelLink), fgs.panelLink),
 
         btnText: getContrastRatio(alphaBlend(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
 
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 2a7756ed..157a8534 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -183,8 +183,10 @@
           <h4>{{ $t('settings.style.advanced_colors.panel_header') }}</h4>
           <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
           <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
-          <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
+          <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.text')"/>
           <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
+          <ColorInput name="panelLinkColor" v-model="panelLinkColorLocal" :fallback="previewTheme.colors.panelLink" :label="$t('settings.links')"/>
+          <ContrastRatio :contrast="previewContrast.panelLink" large="1"/>
         </div>
         <div class="color-item">
           <h4>{{ $t('settings.style.advanced_colors.top_bar') }}</h4>
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index bb1e314f..5529948e 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -105,10 +105,9 @@
         <span v-if="!hideUserStatsLocal">{{user.followers_count}}</span>
       </div>
     </div>
+    <p v-if="!hideBio && user.description_html" class="profile-bio" v-html="user.description_html"></p>
+    <p v-else-if="!hideBio" class="profile-bio">{{ user.description }}</p>
   </div>
-  <p v-if="!hideBio && user.description_html" class="profile-bio" v-html="user.description_html"></p>
-  <p v-else-if="!hideBio" class="profile-bio">{{ user.description }}</p>
-</div>
 </div>
 </template>
 
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index f2c9c13e..7c375206 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -172,6 +172,7 @@ const generateColors = (input) => {
 
   colors.panel = col.panel || Object.assign({}, col.fg)
   colors.panelText = col.panelText || getTextColor(colors.panel, colors.fgText)
+  colors.panelLink = col.panelLink || getTextColor(colors.panel, colors.fgLink)
   colors.panelFaint = col.panelFaint || getTextColor(colors.panel, colors.faint)
 
   colors.topBar = col.topBar || Object.assign({}, col.fg)

From d64f4ab363b8fd8b6fe4542abe5f991178f4d3d4 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 20:14:53 +0300
Subject: [PATCH 70/96] fix preview input text using wrong string

---
 src/components/style_switcher/style_switcher.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 157a8534..655e0589 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -97,7 +97,7 @@
         <br>
         <br>
 
-        <input :value="$t('settings.style.preview.error')" type="text">
+        <input :value="$t('settings.style.preview.input')" type="text">
         <span class="alert error">
           {{$t('settings.style.preview.error')}}
         </span>

From f039b79e5ac7da33c3664241e0d20d3c6964872f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 20:25:14 +0300
Subject: [PATCH 71/96] unbreak user profiles

---
 src/components/user_card_content/user_card_content.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index 064c984d..e7ca21c7 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -12,7 +12,10 @@ export default {
   },
   computed: {
     headingStyle () {
-      const color = this.$store.state.config.customTheme.colors.bg
+      const color = this.$store.state.config.customTheme.colors ?
+            this.$store.state.config.customTheme.colors.bg : // v2
+            this.$store.state.config.colors.bg // v1
+
       if (color) {
         const rgb = (typeof color === 'string') ? hex2rgb(color) : color
         const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)`

From 2ebc06e30f009204eb289057730f9fa4a148d499 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 21:07:22 +0300
Subject: [PATCH 72/96] fixed keep checkboxes working when exporting

---
 .../style_switcher/style_switcher.js          | 51 ++++++++++++++-----
 src/i18n/en.json                              |  2 +-
 2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 0cceee4c..ccdb4c4f 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -332,16 +332,34 @@ export default {
   },
   methods: {
     exportCurrentTheme () {
+      const saveEverything = !this.keepFonts && !this.keepShadows && !this.keepColors && !this.keepOpacity && !this.keepRoundness
+      const theme = {
+        shadows: this.shadowsLocal,
+        fonts: this.fontsLocal,
+        opacity: this.currentOpacity,
+        colors: this.currentColors,
+        radii: this.currentRadii
+      }
+
+      if (!this.keepFonts && !saveEverything) {
+        delete theme.fonts
+      }
+      if (!this.keepShadows && !saveEverything) {
+        delete theme.shadows
+      }
+      if (!this.keepOpacity && !saveEverything) {
+        delete theme.opacity
+      }
+      if (!this.keepColors && !saveEverything) {
+        delete theme.colors
+      }
+      if (!this.keepRoundness && !saveEverything) {
+        delete theme.radii
+      }
+
       const stringified = JSON.stringify({
         // To separate from other random JSON files and possible future theme formats
-        _pleroma_theme_version: 2,
-        theme: {
-          shadows: this.shadowsLocal,
-          fonts: this.fontsLocal,
-          opacity: this.currentOpacity,
-          colors: this.currentColors,
-          radii: this.currentRadii
-        }
+        _pleroma_theme_version: 2, theme
       }, null, 2) // Pretty-print and indent with 2 spaces
 
       // Create an invisible link with a data url and simulate a click
@@ -404,7 +422,9 @@ export default {
     },
 
     clearAll () {
-      this.normalizeLocalState(this.$store.state.config.customTheme)
+      const state = this.$store.state.config.customTheme
+      const version = state.colors ? 2 : 'l1'
+      this.normalizeLocalState(this.$store.state.config.customTheme, version)
     },
 
     // Clears all the extra stuff when loading V1 theme
@@ -442,9 +462,13 @@ export default {
     },
 
     /**
-     * This applies stored theme data onto form.
+     * This applies stored theme data onto form. Supports three versions of data:
+     * v2 (version = 2) - newer version of themes.
+     * v1 (version = 1) - older version of themes (import from file)
+     * v1l (version = l1) - older version of theme (load from local storage)
+     * v1 and v1l differ because of way themes were stored/exported.
      * @param {Object} input - input data
-     * @param {Number} version - version of data. 0 means try to guess based on data.
+     * @param {Number} version - version of data. 0 means try to guess based on data. "l1" means v1, locastorage type
      */
     normalizeLocalState (input, version = 0) {
       const colors = input.colors || input
@@ -465,6 +489,8 @@ export default {
         }
       }
 
+      console.log(version)
+
       // Stuff that differs between V1 and V2
       if (version === 1) {
         this.fgColorLocal = rgb2hex(colors.btn)
@@ -472,7 +498,7 @@ export default {
       }
 
       const keys = new Set(version !== 1 ? Object.keys(colors) : [])
-      if (version === 1) {
+      if (version === 1 || version === 'l1') {
         // V1 ignores the rest
         this.clearV1()
         keys
@@ -483,6 +509,7 @@ export default {
           .add('cGreen')
           .add('cOrange')
       }
+
       keys.forEach(key => {
         this[key + 'ColorLocal'] = rgb2hex(colors[key])
       })
diff --git a/src/i18n/en.json b/src/i18n/en.json
index ab7b954a..74e7a556 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -183,7 +183,7 @@
         "keep_opacity": "Keep opacity",
         "keep_roundness": "Keep roundness",
         "keep_fonts": "Keep fonts",
-        "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme.",
+        "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme. When all checkboxes unset, exporting theme will save everything.",
         "reset": "Reset",
         "clear_all": "Clear all",
         "clear_opacity": "Clear opacity"

From f8e17cbdc58651b17a4f5639d3719a7e533b0d8b Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 21:22:44 +0300
Subject: [PATCH 73/96] lint fix

---
 src/components/user_card_content/user_card_content.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index e7ca21c7..254d1666 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -12,9 +12,9 @@ export default {
   },
   computed: {
     headingStyle () {
-      const color = this.$store.state.config.customTheme.colors ?
-            this.$store.state.config.customTheme.colors.bg : // v2
-            this.$store.state.config.colors.bg // v1
+      const color = this.$store.state.config.customTheme.colors
+            ? this.$store.state.config.customTheme.colors.bg  // v2
+            : this.$store.state.config.colors.bg // v1
 
       if (color) {
         const rgb = (typeof color === 'string') ? hex2rgb(color) : color

From b45fc6c6523b1332c6422a5dc6eff95c11a32690 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 27 Nov 2018 04:54:59 +0300
Subject: [PATCH 74/96] updated preview window

---
 .../style_switcher/style_switcher.scss        | 124 ++++++++++++------
 .../style_switcher/style_switcher.vue         | 108 ++++++++-------
 src/components/timeline/timeline.vue          |   2 +-
 src/i18n/en.json                              |   3 +-
 4 files changed, 150 insertions(+), 87 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 2c33224b..baf2b73a 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -163,32 +163,95 @@
     background-size: cover;
     background-position: 50% 50%;
 
-    .separator {
-      margin: 1em;
-      border-bottom: 1px solid;
-      border-color: $fallback--border;
-      border-color: var(--border, $fallback--border);
-    }
+    .dummy {
+      .post {
+        font-family: var(--postFont);
+        display: flex;
 
-    .panel-heading {
-      .badge, .alert, .btn, .faint {
-        margin-left: 1em;
-      }
-      .flex-spacer {
-        flex: 1;
-      }
-    }
-    .checkbox {
-      display: inline-flex;
-      align-items: baseline;
-      margin-right: 1em;
-    }
+        .content {
+          flex: 1;
 
-    .btn {
-      margin-left: 0;
-      padding: 0 1em;
-      min-width: 3em;
-      min-height: 30px;
+          h4 {
+            margin-bottom: .25em;
+          }
+
+          .icons {
+            margin-top: .5em;
+            display: flex;
+
+            i {
+              margin-right: 1em;
+            }
+          }
+        }
+      }
+
+      .after-post {
+        margin-top: 1em;
+        display: flex;
+        align-items: center;
+      }
+
+      .avatar, .avatar-alt{
+        background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
+        color: black;
+        font-family: sans-serif;
+        text-align: center;
+        margin-right: 1em;
+      }
+
+      .avatar-alt {
+        flex: 0 auto;
+        margin-left: 28px;
+        font-size: 12px;
+        width: 20px;
+        height: 20px;
+        line-height: 20px;
+        border-radius: $fallback--avatarAltRadius;
+        border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
+      }
+
+      .avatar {
+        flex: 0 auto;
+        width: 48px;
+        height: 48px;
+        font-size: 14px;
+        line-height: 48px;
+      }
+
+      .actions {
+        display: flex;
+        align-items: baseline;
+
+        .checkbox {
+          display: inline-flex;
+          align-items: baseline;
+          margin-right: 1em;
+          flex: 1;
+        }
+      }
+
+      .separator {
+        margin: 1em;
+        border-bottom: 1px solid;
+        border-color: $fallback--border;
+        border-color: var(--border, $fallback--border);
+      }
+
+      .panel-heading {
+        .badge, .alert, .btn, .faint {
+          margin-left: 1em;
+        }
+        .flex-spacer {
+          flex: 1;
+        }
+      }
+      .btn {
+        margin-left: 0;
+        padding: 0 1em;
+        min-width: 3em;
+        min-height: 30px;
+      }
     }
   }
 
@@ -259,17 +322,4 @@
     margin-left: .25em;
     margin-right: .25em;
   }
-
-  .dummy {
-    .avatar {
-      background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
-      color: black;
-      text-align: center;
-      height: 48px;
-      line-height: 48px;
-      width: 48px;
-      float: left;
-      margin-right: 1em;
-    }
-  }
 }
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 655e0589..fa173b98 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -60,66 +60,78 @@
   <div class="preview-container">
     <div class="panel dummy" :style="previewRules">
       <div class="panel-heading">
-        {{$t('settings.style.preview.header')}}
-        <span class="badge badge-notification">
-          99
-        </span>
-        <span class="alert error">
-          {{$t('settings.style.preview.error')}}
-        </span>
-        <button class="btn">
-          {{$t('settings.style.preview.button')}}
-        </button>
-        <span class="flex-spacer"/>
+        <div class="title">
+          {{$t('settings.style.preview.header')}}
+          <span class="badge badge-notification">
+            99
+          </span>
+        </div>
         <span class="faint">
           {{$t('settings.style.preview.header_faint')}}
         </span>
-      </div>
-      <div class="panel-body theme-preview-content">
-        <div class="avatar">
-          ( ͡° ͜ʖ ͡°)
-        </div>
-        <h4>Content</h4>
-
-        <br>
-
-        <i18n path="settings.style.preview.text">
-          <a style="color: var(--link)">
-            {{$t('settings.style.preview.link')}}
-          </a>
-        </i18n>
-
-        <i style="color: var(--cBlue)" class="icon-reply"/>
-        <i style="color: var(--cGreen)" class="icon-retweet"/>
-        <i style="color: var(--cRed)" class="icon-cancel"/>
-        <i style="color: var(--cOrange)" class="icon-star"/>
-
-        <br>
-        <br>
-
-        <input :value="$t('settings.style.preview.input')" type="text">
         <span class="alert error">
           {{$t('settings.style.preview.error')}}
         </span>
-
-        <br>
-        <br>
-
-        <span class="checkbox">
-          <input checked="very yes" type="checkbox" id="preview_checkbox">
-          <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
-        </span>
         <button class="btn">
           {{$t('settings.style.preview.button')}}
         </button>
+      </div>
+      <div class="panel-body theme-preview-content">
+        <div class="post">
+          <div class="avatar">
+            ( ͡° ͜ʖ ͡°)
+          </div>
+          <div class="content">
+            <h4>
+              Content
+            </h4>
 
+            <i18n path="settings.style.preview.text">
+              <code style="font-family: var(--postCodeFont)">
+                {{$t('settings.style.preview.mono')}}
+              </code>
+              <a style="color: var(--link)">
+                {{$t('settings.style.preview.link')}}
+              </a>
+            </i18n>
+
+            <div class="icons">
+              <i style="color: var(--cBlue)" class="icon-reply"/>
+              <i style="color: var(--cGreen)" class="icon-retweet"/>
+              <i style="color: var(--cOrange)" class="icon-star"/>
+              <i style="color: var(--cRed)" class="icon-cancel"/>
+            </div>
+          </div>
+        </div>
+
+        <div class="after-post">
+          <div class="avatar-alt">
+            :^)
+          </div>
+          <div class="content">
+            <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
+              <a style="color: var(--faintLink)">
+                {{$t('settings.style.preview.faint_link')}}
+              </a>
+            </i18n>
+          </div>
+        </div>
         <div class="separator"></div>
 
-        <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
-          <a style="color: var(--faintLink)">
-            {{$t('settings.style.preview.faint_link')}}
-          </a>
-        </i18n>
+        <span class="alert error">
+          {{$t('settings.style.preview.error')}}
+        </span>
+        <input :value="$t('settings.style.preview.input')" type="text">
+
+        <div class="actions">
+          <span class="checkbox">
+            <input checked="very yes" type="checkbox" id="preview_checkbox">
+            <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
+          </span>
+          <button class="btn">
+            {{$t('settings.style.preview.button')}}
+          </button>
+        </div>
       </div>
     </div>
   </div>
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index b69a09fd..bc7f74c2 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -10,7 +10,7 @@
       <button @click.prevent="showNewStatuses" class="loadmore-button" v-if="timeline.newStatusCount > 0 && !timelineError">
         {{$t('timeline.show_new')}}{{newStatusCountStr}}
       </button>
-      <div @click.prevent class="loadmore-text" v-if="!timeline.newStatusCount > 0 && !timelineError">
+      <div @click.prevent class="loadmore-text faint" v-if="!timeline.newStatusCount > 0 && !timelineError">
         {{$t('timeline.up_to_date')}}
       </div>
     </div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 74e7a556..8847b11e 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -268,7 +268,8 @@
         "header": "Preview of header",
         "error": "Example error",
         "button": "Button",
-        "text": "A bunch of more content and {0}",
+        "text": "A bunch of more {0} and {1}",
+        "mono": "content",
         "input": "Just landed in L.A.",
         "faint_link": "helpful manual",
         "fine_print": "Read our {0} to learn nothing useful!",

From 406df4399b630268c1028664f3b818571d6f8e4f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 30 Nov 2018 16:39:07 +0300
Subject: [PATCH 75/96] avatars shadows, also allows drop-shadow use

---
 src/components/notification/notification.js   |  3 +-
 src/components/notification/notification.vue  |  2 +-
 .../notifications/notifications.scss          |  6 ++++
 src/components/status/status.js               |  3 +-
 src/components/status/status.vue              | 13 ++++++++-
 .../style_switcher/style_switcher.vue         | 12 ++++++++
 .../user_card_content/user_card_content.js    |  3 +-
 .../user_card_content/user_card_content.vue   |  7 ++++-
 src/i18n/en.json                              |  7 +++++
 src/modules/interface.js                      |  6 ++++
 src/services/style_setter/style_setter.js     | 28 +++++++++++++++++--
 11 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index c786f2cc..4dea63bb 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -6,7 +6,8 @@ import { highlightClass, highlightStyle } from '../../services/user_highlighter/
 const Notification = {
   data () {
     return {
-      userExpanded: false
+      userExpanded: false,
+      betterShadow: this.$store.state.interface.browserSupport.cssFilter
     }
   },
   props: [
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 72c1ca69..f98afbe0 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -2,7 +2,7 @@
   <status v-if="notification.type === 'mention'" :compact="true" :statusoid="notification.status"></status>
   <div class="non-mention" :class="[userClass, { highlighted: userStyle }]" :style="[ userStyle ]"v-else>
     <a class='avatar-container' :href="notification.action.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
-      <StillImage class='avatar-compact' :src="notification.action.user.profile_image_url_original"/>
+      <StillImage class='avatar-compact' :class="{'better-shadow': betterShadow}" :src="notification.action.user.profile_image_url_original"/>
     </a>
     <div class='notification-right'>
       <div class="usercard notification-usercard" v-if="userExpanded">
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 87c89f6a..d17ae25d 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -49,11 +49,17 @@
   .avatar-compact {
     width: 32px;
     height: 32px;
+    box-shadow: var(--avatarStatusShadow);
     border-radius: $fallback--avatarAltRadius;
     border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
     overflow: hidden;
     line-height: 0;
 
+    &.better-shadow {
+      box-shadow: none;
+      filter: drop-shadow(var(--avatarStatusShadowFilter))
+    }
+
     &.animated::before {
       display: none;
     }
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 10716583..725bc3f8 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -33,7 +33,8 @@ const Status = {
       showingTall: false,
       expandingSubject: typeof this.$store.state.config.collapseMessageWithSubject === 'undefined'
         ? !this.$store.state.instance.collapseMessageWithSubject
-        : !this.$store.state.config.collapseMessageWithSubject
+        : !this.$store.state.config.collapseMessageWithSubject,
+      betterShadow: this.$store.state.interface.browserSupport.cssFilter
     }
   },
   computed: {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 4541c560..26be335c 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -21,7 +21,7 @@
       <div :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet }]" :style="[ userStyle ]" class="media status">
         <div v-if="!noHeading" class="media-left">
           <a :href="status.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
-            <StillImage class='avatar' :class="{'avatar-compact': compact}"  :src="status.user.profile_image_url_original"/>
+            <StillImage class='avatar' :class="{'avatar-compact': compact, 'better-shadow': betterShadow}"  :src="status.user.profile_image_url_original"/>
           </a>
         </div>
         <div class="status-body">
@@ -464,8 +464,14 @@
 .status .avatar-compact {
   width: 32px;
   height: 32px;
+  box-shadow: var(--avatarStatusShadow);
   border-radius: $fallback--avatarAltRadius;
   border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
+
+  &.better-shadow {
+    box-shadow: none;
+    filter: drop-shadow(var(--avatarStatusShadowFilter))
+  }
 }
 
 .avatar {
@@ -477,6 +483,11 @@
   overflow: hidden;
   position: relative;
 
+  &.better-shadow {
+    box-shadow: none;
+    filter: drop-shadow(var(--avatarStatusShadowFilter))
+  }
+
   img {
     width: 100%;
     height: 100%;
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index fa173b98..66fe0f6b 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -278,6 +278,18 @@
           <button class="btn" @click="clearShadows">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
         <shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
+        <div v-if="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'">
+          <i18n path="settings.style.shadows.filter_hint.always_drop_shadow" tag="p">
+            <code>filter: drop-shadow()</code>
+          </i18n>
+          <i18n path="settings.style.shadows.filter_hint.text" tag="p">
+            <code>drop-shadow</code>
+            <code>spread-radius</code>
+            <code>inset</code>
+          </i18n>
+          <p>{{$t('settings.style.shadows.filter_hint.inset_ignored')}}</p>
+          <p>{{$t('settings.style.shadows.filter_hint.spread_zero')}}</p>
+        </div>
       </div>
       <div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
         <div class="tab-header">
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index 254d1666..97cd4983 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -7,7 +7,8 @@ export default {
     return {
       hideUserStatsLocal: typeof this.$store.state.config.hideUserStats === 'undefined'
         ? this.$store.state.instance.hideUserStats
-        : this.$store.state.config.hideUserStats
+        : this.$store.state.config.hideUserStats,
+      betterShadow: this.$store.state.interface.browserSupport.cssFilter
     }
   },
   computed: {
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index 5529948e..cca418ff 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -10,7 +10,7 @@
       </a>
       <div class='container'>
         <router-link :to="{ name: 'user-profile', params: { id: user.id } }">
-          <StillImage class="avatar" :src="user.profile_image_url_original"/>
+          <StillImage class="avatar" :class='{ "better-shadow": betterShadow }' :src="user.profile_image_url_original"/>
         </router-link>
         <div class="name-and-screen-name">
           <div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
@@ -159,6 +159,11 @@
       box-shadow: var(--avatarShadow);
       object-fit: cover;
 
+      &.better-shadow {
+        box-shadow: none;
+        filter: drop-shadow(var(--avatarStatusShadowFilter))
+      }
+
       &.animated::before {
         display: none;
       }
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 8847b11e..7f5a2a4f 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -236,6 +236,13 @@
         "spread": "Spread",
         "inset": "Inset",
         "hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
+        "filter_hint": {
+          "always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",
+          "text": "Please note that {0} does not support {1} parameter and {2} keyword.",
+          "spread_zero": "Shadows with spread > 0 will appear as if it was set to zero",
+          "inset_ignored": "Inset shadows using will be ignored",
+          "inset_substituted": "Inset shadows will be substituted with {1} equivalent"
+        },
         "components": {
           "panel": "Panel",
           "panelHeader": "Panel header",
diff --git a/src/modules/interface.js b/src/modules/interface.js
index 07489685..132fb08d 100644
--- a/src/modules/interface.js
+++ b/src/modules/interface.js
@@ -4,6 +4,12 @@ const defaultState = {
   settings: {
     currentSaveStateNotice: null,
     noticeClearTimeout: null
+  },
+  browserSupport: {
+    cssFilter: window.CSS && window.CSS.supports && (
+      window.CSS.supports('filter', 'drop-shadow(0 0)') ||
+        window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
+    )
   }
 }
 
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 7c375206..cff81c40 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -110,6 +110,24 @@ const getCssShadow = (input) => {
   ]).join(' ')).join(', ')
 }
 
+const getCssShadowFilter = (input) => {
+  if (input.length === 0) {
+    return 'none'
+  }
+
+  return input
+  // drop-shadow doesn't support inset or spread
+    .filter((shad) => console.log(shad) || !shad.inset && Number(shad.spread) === 0)
+    .map((shad) => [
+      shad.x,
+      shad.y,
+      // drop-shadow's blur is twice as strong compared to box-shadow
+      shad.blur / 2
+    ].map(_ => _ + 'px').concat([
+      getCssColor(shad.color, shad.alpha)
+    ]).join(' ')).join(', ')
+}
+
 const getCssColor = (input, a) => {
   let rgb = {}
   if (typeof input === 'object') {
@@ -384,7 +402,12 @@ const generateShadows = (input) => {
 
   return {
     rules: {
-      shadows: Object.entries(shadows).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';')
+      shadows: Object
+        .entries(shadows)
+      // TODO for v2.1: if shadow doesn't have non-inset shadows with spread > 0 - optionally
+      // convert all non-inset shadows into filter: drop-shadow() to boost performance
+        .map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}; --${k}ShadowFilter: ${getCssShadowFilter(v)}`)
+        .join(';')
     },
     theme: {
       shadows
@@ -467,5 +490,6 @@ export {
   generateFonts,
   generatePreset,
   composePreset,
-  getCssShadow
+  getCssShadow,
+  getCssShadowFilter
 }

From 77ac42d9190934c8e4f1fa7dfef087c58ccd3990 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sat, 1 Dec 2018 14:47:42 +0300
Subject: [PATCH 76/96] fix retweeter avatar not getting proper shadow

---
 src/components/status/status.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 26be335c..6597d56b 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -9,7 +9,7 @@
     </template>
     <template v-else>
       <div v-if="retweet && !noHeading" :class="[repeaterClass, { highlighted: repeaterStyle }]" :style="[repeaterStyle]" class="media container retweet-info">
-        <StillImage v-if="retweet" class='avatar' :src="statusoid.user.profile_image_url_original"/>
+        <StillImage v-if="retweet" class='avatar' :class='{ "better-shadow": betterShadow }' :src="statusoid.user.profile_image_url_original"/>
         <div class="media-body faint">
           <a v-if="retweeterHtml" :href="statusoid.user.statusnet_profile_url" class="user-name" :title="'@'+statusoid.user.screen_name" v-html="retweeterHtml"></a>
           <a v-else :href="statusoid.user.statusnet_profile_url" class="user-name" :title="'@'+statusoid.user.screen_name">{{retweeter}}</a>

From bee738c815f287c4605eafd52c5565cdb07d5721 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 08:47:55 +0300
Subject: [PATCH 77/96] making inset shadows work on avatars again

---
 .../notifications/notifications.scss          |  4 +--
 src/components/status/status.vue              |  8 ++---
 .../style_switcher/style_switcher.vue         |  7 ++--
 .../user_card_content/user_card_content.vue   |  4 +--
 src/i18n/en.json                              |  6 ++--
 src/services/style_setter/style_setter.js     | 32 ++++++++++++-------
 6 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index d17ae25d..a6468e01 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -56,8 +56,8 @@
     line-height: 0;
 
     &.better-shadow {
-      box-shadow: none;
-      filter: drop-shadow(var(--avatarStatusShadowFilter))
+      box-shadow: var(--avatarStatusShadowInset);
+      filter: var(--avatarStatusShadowFilter)
     }
 
     &.animated::before {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 6597d56b..428383e3 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -469,8 +469,8 @@
   border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
 
   &.better-shadow {
-    box-shadow: none;
-    filter: drop-shadow(var(--avatarStatusShadowFilter))
+    box-shadow: var(--avatarStatusShadowInset);
+    filter: var(--avatarStatusShadowFilter)
   }
 }
 
@@ -484,8 +484,8 @@
   position: relative;
 
   &.better-shadow {
-    box-shadow: none;
-    filter: drop-shadow(var(--avatarStatusShadowFilter))
+    box-shadow: var(--avatarStatusShadowInset);
+    filter: var(--avatarStatusShadowFilter)
   }
 
   img {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 66fe0f6b..c0a7da69 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -282,12 +282,15 @@
           <i18n path="settings.style.shadows.filter_hint.always_drop_shadow" tag="p">
             <code>filter: drop-shadow()</code>
           </i18n>
-          <i18n path="settings.style.shadows.filter_hint.text" tag="p">
+          <p>{{$t('settings.style.shadows.filter_hint.avatar_inset')}}</p>
+          <i18n path="settings.style.shadows.filter_hint.drop_shadow_syntax" tag="p">
             <code>drop-shadow</code>
             <code>spread-radius</code>
             <code>inset</code>
           </i18n>
-          <p>{{$t('settings.style.shadows.filter_hint.inset_ignored')}}</p>
+          <i18n path="settings.style.shadows.filter_hint.inset_classic" tag="p">
+            <code>box-shadow</code>
+          </i18n>
           <p>{{$t('settings.style.shadows.filter_hint.spread_zero')}}</p>
         </div>
       </div>
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index cca418ff..e8b0ebf9 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -160,8 +160,8 @@
       object-fit: cover;
 
       &.better-shadow {
-        box-shadow: none;
-        filter: drop-shadow(var(--avatarStatusShadowFilter))
+        box-shadow: var(--avatarShadowInset);
+        filter: var(--avatarShadowFilter)
       }
 
       &.animated::before {
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 7f5a2a4f..39da04d8 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -238,10 +238,10 @@
         "hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
         "filter_hint": {
           "always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",
-          "text": "Please note that {0} does not support {1} parameter and {2} keyword.",
+          "drop_shadow_syntax": "{0} does not support {1} parameter and {2} keyword.",
+          "avatar_inset": "Please note that combining both inset and non-inset shadows on avatars might give unexpected results with transparent avatars.",
           "spread_zero": "Shadows with spread > 0 will appear as if it was set to zero",
-          "inset_ignored": "Inset shadows using will be ignored",
-          "inset_substituted": "Inset shadows will be substituted with {1} equivalent"
+          "inset_classic": "Inset shadows will be using {0}"
         },
         "components": {
           "panel": "Panel",
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index cff81c40..44a36c88 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -94,20 +94,22 @@ const setColors = (input, commit) => {
   commit('setOption', { name: 'colors', value: theme.colors })
 }
 
-const getCssShadow = (input) => {
+const getCssShadow = (input, usesDropShadow) => {
   if (input.length === 0) {
     return 'none'
   }
 
-  return input.map((shad) => [
-    shad.x,
-    shad.y,
-    shad.blur,
-    shad.spread
-  ].map(_ => _ + 'px').concat([
-    getCssColor(shad.color, shad.alpha),
-    shad.inset ? 'inset' : ''
-  ]).join(' ')).join(', ')
+  return input
+    .filter(_ => usesDropShadow ? _.inset : _)
+    .map((shad) => [
+      shad.x,
+      shad.y,
+      shad.blur,
+      shad.spread
+    ].map(_ => _ + 'px').concat([
+      getCssColor(shad.color, shad.alpha),
+      shad.inset ? 'inset' : ''
+    ]).join(' ')).join(', ')
 }
 
 const getCssShadowFilter = (input) => {
@@ -125,7 +127,9 @@ const getCssShadowFilter = (input) => {
       shad.blur / 2
     ].map(_ => _ + 'px').concat([
       getCssColor(shad.color, shad.alpha)
-    ]).join(' ')).join(', ')
+    ]).join(' '))
+    .map(_ => `drop-shadow(${_})`)
+    .join(' ')
 }
 
 const getCssColor = (input, a) => {
@@ -406,7 +410,11 @@ const generateShadows = (input) => {
         .entries(shadows)
       // TODO for v2.1: if shadow doesn't have non-inset shadows with spread > 0 - optionally
       // convert all non-inset shadows into filter: drop-shadow() to boost performance
-        .map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}; --${k}ShadowFilter: ${getCssShadowFilter(v)}`)
+        .map(([k, v]) => [
+          `--${k}Shadow: ${getCssShadow(v)}`,
+          `--${k}ShadowFilter: ${getCssShadowFilter(v)}`,
+          `--${k}ShadowInset: ${getCssShadow(v, true)}`
+        ].join(';'))
         .join(';')
     },
     theme: {

From 67ca21b2e6c5f76d1db3e7cfdd1c0ef019156172 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 09:38:40 +0300
Subject: [PATCH 78/96] localization strings, fixes

---
 .../style_switcher/style_switcher.scss        |   9 +-
 .../style_switcher/style_switcher.vue         |   4 +-
 src/i18n/en.json                              |   2 +-
 src/i18n/ru.json                              | 112 +++++++++++++++++-
 4 files changed, 119 insertions(+), 8 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index baf2b73a..4db1a295 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -49,7 +49,7 @@
       }
 
       &:not([type=number]):not([type=text]) {
-        align-self: center;
+        align-self: flex-start;
       }
     }
   }
@@ -113,6 +113,7 @@
     p {
       flex: 1;
       margin: 0;
+      margin-right: .5em;
     }
 
     margin-bottom: 1em;
@@ -148,7 +149,7 @@
     flex-wrap: wrap;
     margin-top: .5em;
     span {
-      margin: 0 .5em;
+      margin: 0 .5em .5em;
     }
   }
 
@@ -204,8 +205,8 @@
         flex: 0 auto;
         margin-left: 28px;
         font-size: 12px;
-        width: 20px;
-        height: 20px;
+        min-width: 20px;
+        min-height: 20px;
         line-height: 20px;
         border-radius: $fallback--avatarAltRadius;
         border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index c0a7da69..814a6f17 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -83,7 +83,7 @@
           </div>
           <div class="content">
             <h4>
-              Content
+              {{$t('settings.style.preview.content')}}
             </h4>
 
             <i18n path="settings.style.preview.text">
@@ -224,7 +224,7 @@
         </div>
         <div class="color-item">
           <h4>{{ $t('settings.style.advanced_colors.borders') }}</h4>
-          <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
+          <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" :label="$t('settings.style.common.color')"/>
           <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
         </div>
         <div class="color-item">
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 39da04d8..56179868 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -207,7 +207,6 @@
       "common_colors": {
         "_tab_label": "Common",
         "main": "Common colors",
-        "foreground": "Panel header, top bar, buttons, text fields",
         "foreground_hint": "See \"Advanced\" tab for more detailed control",
         "rgbo": "Icons, accents, badges"
       },
@@ -273,6 +272,7 @@
       },
       "preview": {
         "header": "Preview of header",
+        "content": "Content",
         "error": "Example error",
         "button": "Button",
         "text": "A bunch of more {0} and {1}",
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 921bf67e..63c0bd2a 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -138,8 +138,118 @@
     "text": "Текст",
     "theme": "Тема",
     "theme_help": "Используйте шестнадцатеричные коды цветов (#rrggbb) для настройки темы.",
+    "theme_help_v2_1": "Вы так же можете перепоределить цвета определенных компонентов нажав соотв. галочку. Используйте кнопку \"Очистить всё\" чтобы снять все переопределения",
+    "theme_help_v2_2": "Под некоторыми полями ввода это идикаторы контрастности, наведите на них мышью чтобы узнать больше. Приспользовании прозрачности контраст расчитывается для наихудшего варианта.",
     "tooltipRadius": "Всплывающие подсказки/уведомления",
-    "user_settings": "Настройки пользователя"
+    "user_settings": "Настройки пользователя",
+    "style": {
+      "switcher": {
+        "keep_shadows": "Оставить тени",
+        "keep_opacity": "Оставить прозрачность",
+        "keep_roundness": "Оставить скругление",
+        "keep_fonts": "Оставить шрифты",
+        "save_load_hint": "Опции \"оставить...\" позволяют сохранить текущие настройки при выборе другой темы или импорта её из файла. Так же они влияют на то какие компоненты будут сохранены при экспорте темы. Когда все галочки сняты все компоненты будут экспортированы.",
+        "reset": "Сбросить",
+        "clear_all": "Очистить всё",
+        "clear_opacity": "Очистить прозрачность"
+      },
+      "common": {
+        "color": "Цвет",
+        "opacity": "Прозрачность",
+        "contrast": {
+          "hint": "Уровень контраста: {ratio}, что {level} {context}",
+          "level": {
+            "aa": "соответствует гайдлайну Level AA (минимальный)",
+            "aaa": "соответствует гайдлайну Level AAA (рекомендуемый)",
+            "bad": "не соответствует каким либо гайдлайнам"
+          },
+          "context": {
+            "18pt": "для крупного (18pt+) текста",
+            "text": "для текста"
+          }
+        }
+      },
+      "common_colors": {
+        "_tab_label": "Общие",
+        "main": "Общие цвета",
+        "foreground_hint": "См. вкладку \"Дополнительно\" для более детального контроля",
+        "rgbo": "Иконки, акценты, ярылки"
+      },
+      "advanced_colors": {
+        "_tab_label": "Дополнительно",
+        "alert": "Фон уведомлений",
+        "alert_error": "Ошибки",
+        "badge": "Фон значков",
+        "badge_notification": "Уведомления",
+        "panel_header": "Заголовок панели",
+        "top_bar": "Верняя полоска",
+        "borders": "Границы",
+        "buttons": "Кнопки",
+        "inputs": "Поля ввода",
+        "faint_text": "Маловажный текст"
+      },
+      "radii": {
+        "_tab_label": "Скругление"
+      },
+      "shadows": {
+        "_tab_label": "Светотень",
+        "component": "Компонент",
+        "override": "Переопределить",
+        "shadow_id": "Тень №{value}",
+        "blur": "Размытие",
+        "spread": "Разброс",
+        "inset": "Внутренняя",
+        "hint": "Для теней вы так же можете использовать --variable в качестве цвета чтобы использовать CSS3-переменные. В таком случае прозрачность работать не будет.",
+        "filter_hint": {
+          "always_drop_shadow": "Внимание, эта тень всегда использует {0} когда браузер поддерживает это",
+          "drop_shadow_syntax": "{0} не поддерживает параметр {1} и ключевое слово {2}",
+          "avatar_inset": "Одновременное использование внутренних и внешних теней на (прозрачных) аватарках может дать не те результаты что вы ожидаете",
+          "spread_zero": "Тени с разбросом > 0 будут выглядеть как если бы разброс установлен в 0",
+          "inset_classic": "Внутренние тени будут использовать {0}"
+        },
+        "components": {
+          "panel": "Панель",
+          "panelHeader": "Заголовок панели",
+          "topBar": "Верхняя полоска",
+          "avatar": "Аватарка (профиль)",
+          "avatarStatus": "Аватарка (в ленте)",
+          "popup": "Всплывающие подсказки",
+          "button": "Кнопки",
+          "buttonHover": "Кнопки (наведен курсор)",
+          "buttonPressed": "Кнопки (нажата)",
+          "buttonPressedHover": "Кнопки (нажата+наведен курсор)",
+          "input": "Поля ввода"
+        }
+      },
+      "fonts": {
+        "_tab_label": "Шрифты",
+        "help": "Выберите тип шрифта для использования в интерфейсе. При выборе варианта \"другой\" надо ввести название шрифта в точности как он называется в системе.",
+        "components": {
+          "interface": "Интерфейс",
+          "input": "Поля ввода",
+          "post": "Текст постов",
+          "postCode": "Моноширинный текст в посте (форматирование)"
+        },
+        "family": "Шрифт",
+        "size": "Размер (в пикселях)",
+        "weight": "Ширина",
+        "custom": "Другой"
+      },
+      "preview": {
+        "header": "Пример",
+        "content": "Контент",
+        "error": "Ошибка стоп 000",
+        "button": "Кнопка",
+        "text": "Еще немного {0} и масенькая {1}",
+        "mono": "контента",
+        "input": "Что нового?",
+        "faint_link": "Его придется убрать",
+        "fine_print": "Если проблемы остались — ваш гуртовщик мыши плохо стоит. {0}.",
+        "header_faint": "Все идет по плану",
+        "checkbox": "Я подтверждаю что не было ни единого разрыва",
+        "link": "ссылка"
+      }
+    }
   },
   "timeline": {
     "collapse": "Свернуть",

From 80c0745558cd5dc69364bc19ee5dc1b8b3ddc3e2 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 10:22:25 +0300
Subject: [PATCH 79/96] some more themes, fixes

---
 .../style_switcher/style_switcher.js          |   3 +-
 .../style_switcher/style_switcher.scss        |   6 +
 .../style_switcher/style_switcher.vue         |   2 +-
 static/styles.json                            |   4 +-
 static/themes/breezy-dark.json                | 139 ++++++++++++++++++
 static/themes/breezy-light.json               | 139 ++++++++++++++++++
 6 files changed, 289 insertions(+), 4 deletions(-)
 create mode 100644 static/themes/breezy-dark.json
 create mode 100644 static/themes/breezy-light.json

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index ccdb4c4f..d09185fa 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -497,10 +497,9 @@ export default {
         this.textColorLocal = rgb2hex(colors.fg)
       }
 
+      this.clearV1()
       const keys = new Set(version !== 1 ? Object.keys(colors) : [])
       if (version === 1 || version === 'l1') {
-        // V1 ignores the rest
-        this.clearV1()
         keys
           .add('bg')
           .add('link')
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 4db1a295..c8c5d9dd 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -135,6 +135,12 @@
     display: flex;
     justify-content: center;
     align-items: baseline;
+    flex-wrap: wrap;
+
+    .presets,
+    .import-export {
+      margin-bottom: .5em;
+    }
 
     .import-export {
       display: flex;
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 814a6f17..9de60f7b 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -2,7 +2,7 @@
 <div class="style-switcher">
   <div class="presets-container">
     <div class="save-load">
-      <div>
+      <div class="presets">
         {{$t('settings.presets')}}
         <label for="preset-switcher" class='select'>
           <select id="preset-switcher" v-model="selected" class="preset-switcher">
diff --git a/static/styles.json b/static/styles.json
index 9204c717..b6bd6530 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -9,5 +9,7 @@
 
   "redmond-xx": "./static/themes/redmond-xx.json",
   "redmond-xx-se": "./static/themes/redmond-xx-se.json",
-  "redmond-xxi": "./static/themes/redmond-xxi.json"
+  "redmond-xxi": "./static/themes/redmond-xxi.json",
+  "breezy-dark": "./static/themes/breezy-dark.json",
+  "breezy-light": "./static/themes/breezy-light.json"
 }
diff --git a/static/themes/breezy-dark.json b/static/themes/breezy-dark.json
new file mode 100644
index 00000000..6119bf88
--- /dev/null
+++ b/static/themes/breezy-dark.json
@@ -0,0 +1,139 @@
+{
+  "_pleroma_theme_version": 2,
+  "name": "Breezy Dark (beta)",
+  "theme": {
+    "shadows": {
+      "panel": [
+        {
+          "x": "1",
+          "y": "2",
+          "blur": "6",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": 0.6
+        }
+      ],
+      "button": [
+        {
+          "x": 0,
+          "y": "0",
+          "blur": "0",
+          "spread": "1",
+          "color": "#ffffff",
+          "alpha": "0.15",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "1",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "0.3",
+          "inset": false
+        }
+      ],
+      "panelHeader": [
+        {
+          "x": 0,
+          "y": "40",
+          "blur": "40",
+          "spread": "-40",
+          "inset": true,
+          "color": "#ffffff",
+          "alpha": "0.1"
+        }
+      ],
+      "buttonHover": [
+        {
+          "x": 0,
+          "y": "0",
+          "blur": 0,
+          "spread": "1",
+          "color": "--link",
+          "alpha": "0.3",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "1",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "0.3",
+          "inset": false
+        }
+      ],
+      "buttonPressed": [
+        {
+          "x": 0,
+          "y": 0,
+          "blur": "0",
+          "spread": "50",
+          "color": "--faint",
+          "alpha": 1,
+          "inset": true
+        },
+        {
+          "x": 0,
+          "y": "0",
+          "blur": 0,
+          "spread": "1",
+          "color": "#ffffff",
+          "alpha": 0.2,
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": 0,
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "0.3",
+          "inset": false
+        }
+      ],
+      "input": [
+        {
+          "x": 0,
+          "y": "0",
+          "blur": 0,
+          "spread": "1",
+          "color": "#FFFFFF",
+          "alpha": "0.2",
+          "inset": true
+        }
+      ]
+    },
+    "fonts": {},
+    "opacity": {
+      "input": "1",
+      "panel": "0"
+    },
+    "colors": {
+      "bg": "#31363b",
+      "text": "#eff0f1",
+      "link": "#3daee9",
+      "fg": "#31363b",
+      "panel": "#31363b",
+      "input": "#232629",
+      "topBarLink": "#eff0f1",
+      "btn": "#31363b",
+      "border": "#4c545b",
+      "cRed": "#da4453",
+      "cBlue": "#3daee9",
+      "cGreen": "#27ae60",
+      "cOrange": "#f67400"
+    },
+    "radii": {
+      "btn": "2",
+      "input": "2",
+      "checkbox": "1",
+      "panel": "2",
+      "avatar": "2",
+      "avatarAlt": "2",
+      "tooltip": "2",
+      "attachment": "2"
+    }
+  }
+}
diff --git a/static/themes/breezy-light.json b/static/themes/breezy-light.json
new file mode 100644
index 00000000..becf704f
--- /dev/null
+++ b/static/themes/breezy-light.json
@@ -0,0 +1,139 @@
+{
+  "_pleroma_theme_version": 2,
+  "name": "Breezy Light (beta)",
+  "theme": {
+    "shadows": {
+      "panel": [
+        {
+          "x": "1",
+          "y": "2",
+          "blur": "6",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": 0.6
+        }
+      ],
+      "button": [
+        {
+          "x": 0,
+          "y": "0",
+          "blur": "0",
+          "spread": "1",
+          "color": "#000000",
+          "alpha": "0.3",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "1",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "0.3",
+          "inset": false
+        }
+      ],
+      "panelHeader": [
+        {
+          "x": 0,
+          "y": "40",
+          "blur": "40",
+          "spread": "-40",
+          "inset": true,
+          "color": "#ffffff",
+          "alpha": "0.1"
+        }
+      ],
+      "buttonHover": [
+        {
+          "x": 0,
+          "y": "0",
+          "blur": 0,
+          "spread": "1",
+          "color": "--link",
+          "alpha": "0.3",
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": "1",
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "0.3",
+          "inset": false
+        }
+      ],
+      "buttonPressed": [
+        {
+          "x": 0,
+          "y": 0,
+          "blur": "0",
+          "spread": "50",
+          "color": "--faint",
+          "alpha": 1,
+          "inset": true
+        },
+        {
+          "x": 0,
+          "y": "0",
+          "blur": 0,
+          "spread": "1",
+          "color": "#ffffff",
+          "alpha": 0.2,
+          "inset": true
+        },
+        {
+          "x": "1",
+          "y": "1",
+          "blur": 0,
+          "spread": 0,
+          "color": "#000000",
+          "alpha": "0.3",
+          "inset": false
+        }
+      ],
+      "input": [
+        {
+          "x": 0,
+          "y": "0",
+          "blur": 0,
+          "spread": "1",
+          "color": "#000000",
+          "alpha": "0.2",
+          "inset": true
+        }
+      ]
+    },
+    "fonts": {},
+    "opacity": {
+      "input": "1"
+    },
+    "colors": {
+      "bg": "#eff0f1",
+      "text": "#232627",
+      "link": "#2980b9",
+      "fg": "#bcc2c7",
+      "panel": "#475057",
+      "panelText": "#fcfcfc",
+      "input": "#fcfcfc",
+      "topBar": "#475057",
+      "topBarLink": "#eff0f1",
+      "btn": "#eff0f1",
+      "cRed": "#da4453",
+      "cBlue": "#2980b9",
+      "cGreen": "#27ae60",
+      "cOrange": "#f67400"
+    },
+    "radii": {
+      "btn": "2",
+      "input": "2",
+      "checkbox": "1",
+      "panel": "2",
+      "avatar": "2",
+      "avatarAlt": "2",
+      "tooltip": "2",
+      "attachment": "2"
+    }
+  }
+}

From 1e56cec2aaf8683a47d67ee657659b95c7a4d3b6 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 10:23:41 +0300
Subject: [PATCH 80/96] missing string

---
 src/i18n/ru.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 63c0bd2a..58a6eae5 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -100,6 +100,7 @@
     "import_followers_from_a_csv_file": "Импортировать читаемых из файла .csv",
     "import_theme": "Загрузить Тему",
     "inputRadius": "Поля ввода",
+    "checkboxRadius": "Чекбоксы",
     "interfaceLanguage": "Язык интерфейса",
     "limited_availability": "Не доступно в вашем браузере",
     "links": "Ссылки",

From d756455c3446f74df922f27d53081a5f307968f8 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 12:56:02 +0300
Subject: [PATCH 81/96] todo

---
 src/components/shadow_control/shadow_control.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/shadow_control/shadow_control.js b/src/components/shadow_control/shadow_control.js
index a1484d09..44e4a22f 100644
--- a/src/components/shadow_control/shadow_control.js
+++ b/src/components/shadow_control/shadow_control.js
@@ -14,6 +14,7 @@ export default {
   data () {
     return {
       selectedId: 0,
+      // TODO there are some bugs regarding display of array (it's not getting updated when deleting for some reason)
       cValue: this.value || this.fallback || []
     }
   },

From dd4deae66e5bb1b856898f9d1a4195b52427cdb0 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 15:03:51 +0300
Subject: [PATCH 82/96] fallback for some weird case on my phone

---
 src/services/style_setter/style_setter.js | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 44a36c88..33aba32c 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -205,10 +205,10 @@ const generateColors = (input) => {
 
   colors.icon = mixrgb(colors.bg, colors.text)
 
-  colors.cBlue = col.cBlue
-  colors.cRed = col.cRed
-  colors.cGreen = col.cGreen
-  colors.cOrange = col.cOrange
+  colors.cBlue = col.cBlue || hex2rgb('#0000FF')
+  colors.cRed = col.cRed || hex2rgb('#FF0000')
+  colors.cGreen = col.cGreen || hex2rgb('#00FF00')
+  colors.cOrange = col.cOrange || hex2rgb('#E3FF00')
 
   colors.alertError = col.alertError || Object.assign({}, col.cRed)
   colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)

From fad19c3c2faccefd51f0aa5905cfb6df38ae9744 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 15:10:18 +0300
Subject: [PATCH 83/96] fix

---
 src/services/style_setter/style_setter.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 33aba32c..5720d02d 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -119,7 +119,7 @@ const getCssShadowFilter = (input) => {
 
   return input
   // drop-shadow doesn't support inset or spread
-    .filter((shad) => console.log(shad) || !shad.inset && Number(shad.spread) === 0)
+    .filter((shad) => !shad.inset && Number(shad.spread) === 0)
     .map((shad) => [
       shad.x,
       shad.y,

From e95b6c7e538e5b65ee81fd5e5d3cb905609c6bab Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 2 Dec 2018 15:20:25 +0300
Subject: [PATCH 84/96] fix

---
 src/services/style_setter/style_setter.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 5720d02d..445d3c49 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -210,11 +210,11 @@ const generateColors = (input) => {
   colors.cGreen = col.cGreen || hex2rgb('#00FF00')
   colors.cOrange = col.cOrange || hex2rgb('#E3FF00')
 
-  colors.alertError = col.alertError || Object.assign({}, col.cRed)
+  colors.alertError = col.alertError || Object.assign({}, colors.cRed)
   colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)
   colors.alertErrorPanelText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.panel), colors.panelText)
 
-  colors.badgeNotification = col.badgeNotification || Object.assign({}, col.cRed)
+  colors.badgeNotification = col.badgeNotification || Object.assign({}, colors.cRed)
   colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
 
   Object.entries(opacity).forEach(([ k, v ]) => {

From 6636c0f551a146622a1db40582140c59d3eb650d Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 5 Dec 2018 12:01:24 +0300
Subject: [PATCH 85/96] mobile fixes

---
 src/components/style_switcher/style_switcher.scss | 6 ++++++
 src/components/tab_switcher/tab_switcher.scss     | 4 +++-
 src/i18n/en.json                                  | 2 +-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index c8c5d9dd..f53f00a0 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -248,6 +248,12 @@
       .panel-heading {
         .badge, .alert, .btn, .faint {
           margin-left: 1em;
+          white-space: nowrap;
+        }
+        .faint {
+          text-overflow: ellipsis;
+          min-width: 2em;
+          overflow-x: hidden;
         }
         .flex-spacer {
           flex: 1;
diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss
index d0e5ea87..fbd3321b 100644
--- a/src/components/tab_switcher/tab_switcher.scss
+++ b/src/components/tab_switcher/tab_switcher.scss
@@ -11,7 +11,8 @@
     position: relative;
     justify-content: center;
     width: 100%;
-    overflow: hidden;
+    overflow-y: hidden;
+    overflow-x: auto;
     padding-top: 5px;
     height: 32px;
     box-sizing: border-box;
@@ -33,6 +34,7 @@
       border-bottom-left-radius: 0;
       border-bottom-right-radius: 0;
       padding: 5px 1em 99px;
+      white-space: nowrap;
 
       &:not(.active) {
         z-index: 4;
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 890ed6c4..c0d30b59 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -273,7 +273,7 @@
         "custom": "Custom"
       },
       "preview": {
-        "header": "Preview of header",
+        "header": "Preview",
         "content": "Content",
         "error": "Example error",
         "button": "Button",

From aeecd2b09b7c31644a2c601fc1b8d123e2b263b0 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 00:56:15 +0300
Subject: [PATCH 86/96] separate font control js

---
 src/components/font_control/font_control.js  | 58 +++++++++++++++++++
 src/components/font_control/font_control.vue | 61 +-------------------
 2 files changed, 59 insertions(+), 60 deletions(-)
 create mode 100644 src/components/font_control/font_control.js

diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js
new file mode 100644
index 00000000..8e2b0e45
--- /dev/null
+++ b/src/components/font_control/font_control.js
@@ -0,0 +1,58 @@
+import { set } from 'vue'
+
+export default {
+  props: [
+    'name', 'label', 'value', 'fallback', 'options', 'no-inherit'
+  ],
+  data () {
+    return {
+      lValue: this.value,
+      availableOptions: [
+        this.noInherit ? '' : 'inherit',
+        'custom',
+        ...(this.options || []),
+        'serif',
+        'monospace',
+        'sans-serif'
+      ].filter(_ => _)
+    }
+  },
+  beforeUpdate () {
+    this.lValue = this.value
+  },
+  computed: {
+    present () {
+      return typeof this.lValue !== 'undefined'
+    },
+    dValue () {
+      return this.lValue || this.fallback || {}
+    },
+    family: {
+      get () {
+        return this.dValue.family
+      },
+      set (v) {
+        set(this.lValue, 'family', v)
+        this.$emit('input', this.lValue)
+      }
+    },
+    isCustom () {
+      return this.preset === 'custom'
+    },
+    preset: {
+      get () {
+        if (this.family === 'serif' ||
+            this.family === 'sans-serif' ||
+            this.family === 'monospace' ||
+            this.family === 'inherit') {
+          return this.family
+        } else {
+          return 'custom'
+        }
+      },
+      set (v) {
+        this.family = v === 'custom' ? '' : v
+      }
+    }
+  }
+}
diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
index 85f19eea..ed36b280 100644
--- a/src/components/font_control/font_control.vue
+++ b/src/components/font_control/font_control.vue
@@ -32,66 +32,7 @@
 </div>
 </template>
 
-<script>
-import { set } from 'vue'
-
-export default {
-  props: [
-    'name', 'label', 'value', 'fallback', 'options', 'no-inherit'
-  ],
-  data () {
-    return {
-      lValue: this.value,
-      availableOptions: [
-        this.noInherit ? '' : 'inherit',
-        'custom',
-        ...(this.options || []),
-        'serif',
-        'monospace',
-        'sans-serif'
-      ].filter(_ => _)
-    }
-  },
-  beforeUpdate () {
-    this.lValue = this.value
-  },
-  computed: {
-    present () {
-      return typeof this.lValue !== 'undefined'
-    },
-    dValue () {
-      return this.lValue || this.fallback || {}
-    },
-    family: {
-      get () {
-        return this.dValue.family
-      },
-      set (v) {
-        set(this.lValue, 'family', v)
-        this.$emit('input', this.lValue)
-      }
-    },
-    isCustom () {
-      return this.preset === 'custom'
-    },
-    preset: {
-      get () {
-        if (this.family === 'serif' ||
-            this.family === 'sans-serif' ||
-            this.family === 'monospace' ||
-            this.family === 'inherit') {
-          return this.family
-        } else {
-          return 'custom'
-        }
-      },
-      set (v) {
-        this.family = v === 'custom' ? '' : v
-      }
-    }
-  }
-}
-</script>
+<script src="./font_control.js" ></script>
 
 <style lang="scss">
 @import '../../_variables.scss';

From fe2fe092361b60c9d585f80b53d906b501c9722e Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 01:38:20 +0300
Subject: [PATCH 87/96] fixed v2 setting as default theme

---
 .../style_switcher/style_switcher.js          | 34 ++--------
 src/services/style_setter/style_setter.js     | 63 ++++++++++++++-----
 2 files changed, 53 insertions(+), 44 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index d09185fa..2bbf74db 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,6 +1,6 @@
 import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
 import { set, delete as del } from 'vue'
-import { generateColors, generateShadows, generateRadii, generateFonts, composePreset } from '../../services/style_setter/style_setter.js'
+import { generateColors, generateShadows, generateRadii, generateFonts, composePreset, getThemes } from '../../services/style_setter/style_setter.js'
 import ColorInput from '../color_input/color_input.vue'
 import RangeInput from '../range_input/range_input.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
@@ -104,35 +104,9 @@ export default {
   created () {
     const self = this
 
-    window.fetch('/static/styles.json')
-      .then((data) => data.json())
-      .then((themes) => {
-        return Promise.all(Object.entries(themes).map(([k, v]) => {
-          if (typeof v === 'object') {
-            return Promise.resolve([k, v])
-          } else if (typeof v === 'string') {
-            return window.fetch(v)
-              .then((data) => data.json())
-              .then((theme) => {
-                return [k, theme]
-              })
-              .catch((e) => {
-                console.error(e)
-                return []
-              })
-          }
-        }))
-      })
-      .then((promises) => {
-        return promises
-          .filter(([k, v]) => v)
-          .reduce((acc, [k, v]) => {
-            acc[k] = v
-            return acc
-          }, {})
-      }).then((themesComplete) => {
-        self.availableStyles = themesComplete
-      })
+    getThemes().then((themesComplete) => {
+      self.availableStyles = themesComplete
+    })
   },
   mounted () {
     this.normalizeLocalState(this.$store.state.config.customTheme)
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 445d3c49..783a693a 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -449,11 +449,43 @@ const generatePreset = (input) => {
   return composePreset(colors, radii, shadows, fonts)
 }
 
-const setPreset = (val, commit) => {
-  window.fetch('/static/styles.json')
+const getThemes = () => {
+  return window.fetch('/static/styles.json')
     .then((data) => data.json())
     .then((themes) => {
-      const theme = themes[val] ? themes[val] : themes['pleroma-dark']
+      return Promise.all(Object.entries(themes).map(([k, v]) => {
+        if (typeof v === 'object') {
+          return Promise.resolve([k, v])
+        } else if (typeof v === 'string') {
+          return window.fetch(v)
+            .then((data) => data.json())
+            .then((theme) => {
+              return [k, theme]
+            })
+            .catch((e) => {
+              console.error(e)
+              return []
+            })
+        }
+      }))
+    })
+    .then((promises) => {
+      return promises
+        .filter(([k, v]) => v)
+        .reduce((acc, [k, v]) => {
+          acc[k] = v
+          return acc
+        }, {})
+    })
+}
+
+const setPreset = (val, commit) => {
+  getThemes().then((themes) => {
+    const theme = themes[val] ? themes[val] : themes['pleroma-dark']
+    const isV1 = Array.isArray(theme)
+    const data = isV1 ? {} : theme.theme
+
+    if (isV1) {
       const bgRgb = hex2rgb(theme[1])
       const fgRgb = hex2rgb(theme[2])
       const textRgb = hex2rgb(theme[3])
@@ -464,7 +496,7 @@ const setPreset = (val, commit) => {
       const cBlueRgb = hex2rgb(theme[7] || '#0000FF')
       const cOrangeRgb = hex2rgb(theme[8] || '#E3FF00')
 
-      const colors = {
+      data.colors = {
         bg: bgRgb,
         fg: fgRgb,
         text: textRgb,
@@ -474,17 +506,19 @@ const setPreset = (val, commit) => {
         cGreen: cGreenRgb,
         cOrange: cOrangeRgb
       }
+    }
 
-      // This is a hack, this function is only called during initial load.
-      // We want to cancel loading the theme from config.json if we're already
-      // loading a theme from the persisted state.
-      // Needed some way of dealing with the async way of things.
-      // load config -> set preset -> wait for styles.json to load ->
-      // load persisted state -> set colors -> styles.json loaded -> set colors
-      if (!window.themeLoaded) {
-        setColors({ colors }, commit)
-      }
-    })
+    console.log(data)
+    // This is a hack, this function is only called during initial load.
+    // We want to cancel loading the theme from config.json if we're already
+    // loading a theme from the persisted state.
+    // Needed some way of dealing with the async way of things.
+    // load config -> set preset -> wait for styles.json to load ->
+    // load persisted state -> set colors -> styles.json loaded -> set colors
+    if (!window.themeLoaded) {
+      setColors(data, commit)
+    }
+  })
 }
 
 export {
@@ -497,6 +531,7 @@ export {
   generateShadows,
   generateFonts,
   generatePreset,
+  getThemes,
   composePreset,
   getCssShadow,
   getCssShadowFilter

From 4b25475b5766580d7645bb5e8fcb7f229ed6c620 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 01:39:18 +0300
Subject: [PATCH 88/96] setColors -> applyTheme. For sanity. Also disabled
 export because nobody uses it and should not use anyway.

---
 src/services/style_setter/style_setter.js | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 783a693a..5d988732 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -71,7 +71,7 @@ const getTextColor = function (bg, text, preserve) {
   return text
 }
 
-const setColors = (input, commit) => {
+const applyTheme = (input, commit) => {
   const { rules, theme } = generatePreset(input)
   const head = document.head
   const body = document.body
@@ -516,7 +516,7 @@ const setPreset = (val, commit) => {
     // load config -> set preset -> wait for styles.json to load ->
     // load persisted state -> set colors -> styles.json loaded -> set colors
     if (!window.themeLoaded) {
-      setColors(data, commit)
+      applyTheme(data, commit)
     }
   })
 }
@@ -524,7 +524,6 @@ const setPreset = (val, commit) => {
 export {
   setStyle,
   setPreset,
-  setColors,
   getTextColor,
   generateColors,
   generateRadii,

From 73aa9153d96ed50293dbbbeb8691a71d9f911bfc Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 01:40:19 +0300
Subject: [PATCH 89/96] cleanup

---
 src/components/style_switcher/style_switcher.js | 2 --
 src/services/style_setter/style_setter.js       | 1 -
 2 files changed, 3 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 2bbf74db..adcbee25 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -463,8 +463,6 @@ export default {
         }
       }
 
-      console.log(version)
-
       // Stuff that differs between V1 and V2
       if (version === 1) {
         this.fgColorLocal = rgb2hex(colors.btn)
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 5d988732..1e1b3fce 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -508,7 +508,6 @@ const setPreset = (val, commit) => {
       }
     }
 
-    console.log(data)
     // This is a hack, this function is only called during initial load.
     // We want to cancel loading the theme from config.json if we're already
     // loading a theme from the persisted state.

From 90a567066139377a3fd385151eed2e022555cb22 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 01:41:19 +0300
Subject: [PATCH 90/96] removed unused function from color_convert

---
 src/services/color_convert/color_convert.js | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 58c434fa..7576c518 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -113,14 +113,6 @@ const hex2rgb = (hex) => {
   } : null
 }
 
-const rgbstr2hex = (rgb) => {
-  if (rgb[0] === '#') {
-    return rgb
-  }
-  rgb = rgb.match(/\d+/g)
-  return `#${((Number(rgb[0]) << 16) + (Number(rgb[1]) << 8) + Number(rgb[2])).toString(16)}`
-}
-
 const mixrgb = (a, b) => {
   return Object.keys(a).reduce((acc, k) => {
     acc[k] = (a[k] + b[k]) / 2
@@ -133,7 +125,6 @@ export {
   hex2rgb,
   mixrgb,
   invert,
-  rgbstr2hex,
   getContrastRatio,
   alphaBlend
 }

From a17ac74df71a9de23a82825680d7154927b033ee Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 02:05:22 +0300
Subject: [PATCH 91/96] revert that, it's actually used, i'm an idiot

---
 src/services/style_setter/style_setter.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 1e1b3fce..10e7ed9b 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -523,6 +523,7 @@ const setPreset = (val, commit) => {
 export {
   setStyle,
   setPreset,
+  applyTheme,
   getTextColor,
   generateColors,
   generateRadii,

From 51dccb788798364bbb662d378f2aa2647f1845cf Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 02:46:17 +0300
Subject: [PATCH 92/96] separated preview and exported from style_switcher

---
 .../export_import/export_import.vue           | 75 ++++++++++++++
 src/components/style_switcher/preview.vue     | 78 +++++++++++++++
 .../style_switcher/style_switcher.js          | 97 +++++++------------
 .../style_switcher/style_switcher.vue         | 93 +++---------------
 src/modules/config.js                         |  4 +-
 5 files changed, 200 insertions(+), 147 deletions(-)
 create mode 100644 src/components/export_import/export_import.vue
 create mode 100644 src/components/style_switcher/preview.vue

diff --git a/src/components/export_import/export_import.vue b/src/components/export_import/export_import.vue
new file mode 100644
index 00000000..9914d54a
--- /dev/null
+++ b/src/components/export_import/export_import.vue
@@ -0,0 +1,75 @@
+<template>
+<div class="import-export">
+  <button class="btn" @click="exportData">{{ exportLabel }}</button>
+  <button class="btn" @click="importData">{{ importLabel }}</button>
+  <p v-if="importFailed" class="import-warning">{{ importFailedText }}</p>
+</div>
+</template>
+
+<script>
+export default {
+  props: [
+    'exportObject',
+    'importLabel',
+    'exportLabel',
+    'importFailedText',
+    'validator',
+    'onImport',
+    'onImportFailure'
+  ],
+  data () {
+    return {
+      importFailed: false
+    }
+  },
+  methods: {
+    exportData () {
+      const stringified = JSON.stringify(this.exportObject) // Pretty-print and indent with 2 spaces
+
+      // Create an invisible link with a data url and simulate a click
+      const e = document.createElement('a')
+      e.setAttribute('download', 'pleroma_theme.json')
+      e.setAttribute('href', 'data:application/json;base64,' + window.btoa(stringified))
+      e.style.display = 'none'
+
+      document.body.appendChild(e)
+      e.click()
+      document.body.removeChild(e)
+    },
+    importData () {
+      this.importFailed = false
+      const filePicker = document.createElement('input')
+      filePicker.setAttribute('type', 'file')
+      filePicker.setAttribute('accept', '.json')
+
+      filePicker.addEventListener('change', event => {
+        if (event.target.files[0]) {
+          // eslint-disable-next-line no-undef
+          const reader = new FileReader()
+          reader.onload = ({target}) => {
+            try {
+              const parsed = JSON.parse(target.result)
+              const valid = this.validator(parsed)
+              if (valid) {
+                this.onImport(parsed)
+              } else {
+                this.importFailed = true
+                // this.onImportFailure(valid)
+              }
+            } catch (e) {
+              // This will happen both if there is a JSON syntax error or the theme is missing components
+              this.importFailed = true
+              // this.onImportFailure(e)
+            }
+          }
+          reader.readAsText(event.target.files[0])
+        }
+      })
+
+      document.body.appendChild(filePicker)
+      filePicker.click()
+      document.body.removeChild(filePicker)
+    }
+  }
+}
+</script>
diff --git a/src/components/style_switcher/preview.vue b/src/components/style_switcher/preview.vue
new file mode 100644
index 00000000..09a136e9
--- /dev/null
+++ b/src/components/style_switcher/preview.vue
@@ -0,0 +1,78 @@
+<template>
+<div class="panel dummy">
+  <div class="panel-heading">
+    <div class="title">
+      {{$t('settings.style.preview.header')}}
+      <span class="badge badge-notification">
+        99
+      </span>
+    </div>
+    <span class="faint">
+      {{$t('settings.style.preview.header_faint')}}
+    </span>
+    <span class="alert error">
+      {{$t('settings.style.preview.error')}}
+    </span>
+    <button class="btn">
+      {{$t('settings.style.preview.button')}}
+    </button>
+  </div>
+  <div class="panel-body theme-preview-content">
+    <div class="post">
+      <div class="avatar">
+        ( ͡° ͜ʖ ͡°)
+      </div>
+      <div class="content">
+        <h4>
+          {{$t('settings.style.preview.content')}}
+        </h4>
+
+        <i18n path="settings.style.preview.text">
+          <code style="font-family: var(--postCodeFont)">
+            {{$t('settings.style.preview.mono')}}
+          </code>
+          <a style="color: var(--link)">
+            {{$t('settings.style.preview.link')}}
+          </a>
+        </i18n>
+
+        <div class="icons">
+          <i style="color: var(--cBlue)" class="icon-reply"/>
+          <i style="color: var(--cGreen)" class="icon-retweet"/>
+          <i style="color: var(--cOrange)" class="icon-star"/>
+          <i style="color: var(--cRed)" class="icon-cancel"/>
+        </div>
+      </div>
+    </div>
+
+    <div class="after-post">
+      <div class="avatar-alt">
+        :^)
+      </div>
+      <div class="content">
+        <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
+          <a style="color: var(--faintLink)">
+            {{$t('settings.style.preview.faint_link')}}
+          </a>
+        </i18n>
+      </div>
+    </div>
+    <div class="separator"></div>
+
+    <span class="alert error">
+      {{$t('settings.style.preview.error')}}
+    </span>
+    <input :value="$t('settings.style.preview.input')" type="text">
+
+    <div class="actions">
+      <span class="checkbox">
+        <input checked="very yes" type="checkbox" id="preview_checkbox">
+        <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
+      </span>
+      <button class="btn">
+        {{$t('settings.style.preview.button')}}
+      </button>
+    </div>
+  </div>
+</div>
+</template>
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index adcbee25..50cd1e6f 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -8,6 +8,8 @@ import ShadowControl from '../shadow_control/shadow_control.vue'
 import FontControl from '../font_control/font_control.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
+import Preview from './preview.vue'
+import ExportImport from '../export_import/export_import.vue'
 
 // List of color values used in v1
 const v1OnlyNames = [
@@ -26,7 +28,6 @@ export default {
     return {
       availableStyles: [],
       selected: this.$store.state.config.theme,
-      invalidThemeImported: false,
 
       previewShadows: {},
       previewColors: {},
@@ -293,20 +294,11 @@ export default {
     },
     themeValid () {
       return !this.shadowsInvalid && !this.colorsInvalid && !this.radiiInvalid
-    }
-  },
-  components: {
-    ColorInput,
-    OpacityInput,
-    RangeInput,
-    ContrastRatio,
-    ShadowControl,
-    FontControl,
-    TabSwitcher
-  },
-  methods: {
-    exportCurrentTheme () {
+    },
+    exportedTheme () {
       const saveEverything = !this.keepFonts && !this.keepShadows && !this.keepColors && !this.keepOpacity && !this.keepRoundness
+
+      // TODO change into delete-less version.
       const theme = {
         shadows: this.shadowsLocal,
         fonts: this.fontsLocal,
@@ -331,57 +323,24 @@ export default {
         delete theme.radii
       }
 
-      const stringified = JSON.stringify({
+      return {
         // To separate from other random JSON files and possible future theme formats
         _pleroma_theme_version: 2, theme
-      }, null, 2) // Pretty-print and indent with 2 spaces
-
-      // Create an invisible link with a data url and simulate a click
-      const e = document.createElement('a')
-      e.setAttribute('download', 'pleroma_theme.json')
-      e.setAttribute('href', 'data:application/json;base64,' + window.btoa(stringified))
-      e.style.display = 'none'
-
-      document.body.appendChild(e)
-      e.click()
-      document.body.removeChild(e)
-    },
-
-    importTheme () {
-      this.invalidThemeImported = false
-      const filePicker = document.createElement('input')
-      filePicker.setAttribute('type', 'file')
-      filePicker.setAttribute('accept', '.json')
-
-      filePicker.addEventListener('change', event => {
-        if (event.target.files[0]) {
-          // eslint-disable-next-line no-undef
-          const reader = new FileReader()
-          reader.onload = ({target}) => {
-            try {
-              const parsed = JSON.parse(target.result)
-              if (parsed._pleroma_theme_version === 1) {
-                this.normalizeLocalState(parsed, 1)
-              } else if (parsed._pleroma_theme_version === 2) {
-                this.normalizeLocalState(parsed.theme, 2)
-              } else {
-                // A theme from the future, spooky
-                this.invalidThemeImported = true
-              }
-            } catch (e) {
-              // This will happen both if there is a JSON syntax error or the theme is missing components
-              this.invalidThemeImported = true
-            }
-          }
-          reader.readAsText(event.target.files[0])
-        }
-      })
-
-      document.body.appendChild(filePicker)
-      filePicker.click()
-      document.body.removeChild(filePicker)
-    },
-
+      }
+    }
+  },
+  components: {
+    ColorInput,
+    OpacityInput,
+    RangeInput,
+    ContrastRatio,
+    ShadowControl,
+    FontControl,
+    TabSwitcher,
+    Preview,
+    ExportImport
+  },
+  methods: {
     setCustomTheme () {
       this.$store.dispatch('setOption', {
         name: 'customTheme',
@@ -394,7 +353,17 @@ export default {
         }
       })
     },
-
+    onImport (parsed) {
+      if (parsed._pleroma_theme_version === 1) {
+        this.normalizeLocalState(parsed, 1)
+      } else if (parsed._pleroma_theme_version === 2) {
+        this.normalizeLocalState(parsed.theme, 2)
+      }
+    },
+    importValidator (parsed) {
+      const version = parsed._pleroma_theme_version
+      return version >= 1 || version <= 2
+    },
     clearAll () {
       const state = this.$store.state.config.customTheme
       const version = state.colors ? 2 : 'l1'
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 9de60f7b..730bfef0 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -18,11 +18,14 @@
           <i class="icon-down-open"/>
         </label>
       </div>
-      <div class="import-export">
-        <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
-        <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
-        <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
-      </div>
+      <export-import
+        :exportObject='exportedTheme'
+        :exportLabel='$t("settings.export_theme")'
+        :importLabel='$t("settings.import_theme")'
+        :importFailedText='$t("settings.invalid_theme_imported")'
+        :onImport='onImport'
+        :validator='importValidator'
+        />
     </div>
     <div class="save-load-options">
       <span>
@@ -58,82 +61,7 @@
   </div>
 
   <div class="preview-container">
-    <div class="panel dummy" :style="previewRules">
-      <div class="panel-heading">
-        <div class="title">
-          {{$t('settings.style.preview.header')}}
-          <span class="badge badge-notification">
-            99
-          </span>
-        </div>
-        <span class="faint">
-          {{$t('settings.style.preview.header_faint')}}
-        </span>
-        <span class="alert error">
-          {{$t('settings.style.preview.error')}}
-        </span>
-        <button class="btn">
-          {{$t('settings.style.preview.button')}}
-        </button>
-      </div>
-      <div class="panel-body theme-preview-content">
-        <div class="post">
-          <div class="avatar">
-            ( ͡° ͜ʖ ͡°)
-          </div>
-          <div class="content">
-            <h4>
-              {{$t('settings.style.preview.content')}}
-            </h4>
-
-            <i18n path="settings.style.preview.text">
-              <code style="font-family: var(--postCodeFont)">
-                {{$t('settings.style.preview.mono')}}
-              </code>
-              <a style="color: var(--link)">
-                {{$t('settings.style.preview.link')}}
-              </a>
-            </i18n>
-
-            <div class="icons">
-              <i style="color: var(--cBlue)" class="icon-reply"/>
-              <i style="color: var(--cGreen)" class="icon-retweet"/>
-              <i style="color: var(--cOrange)" class="icon-star"/>
-              <i style="color: var(--cRed)" class="icon-cancel"/>
-            </div>
-          </div>
-        </div>
-
-        <div class="after-post">
-          <div class="avatar-alt">
-            :^)
-          </div>
-          <div class="content">
-            <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
-              <a style="color: var(--faintLink)">
-                {{$t('settings.style.preview.faint_link')}}
-              </a>
-            </i18n>
-          </div>
-        </div>
-        <div class="separator"></div>
-
-        <span class="alert error">
-          {{$t('settings.style.preview.error')}}
-        </span>
-        <input :value="$t('settings.style.preview.input')" type="text">
-
-        <div class="actions">
-          <span class="checkbox">
-            <input checked="very yes" type="checkbox" id="preview_checkbox">
-            <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
-          </span>
-          <button class="btn">
-            {{$t('settings.style.preview.button')}}
-          </button>
-        </div>
-      </div>
-    </div>
+    <preview :style="previewRules"/>
   </div>
 
   <keep-alive>
@@ -235,6 +163,7 @@
           <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
         </div>
       </div>
+
       <div :label="$t('settings.style.radii._tab_label')" class="radius-container">
         <div class="tab-header">
           <p>{{$t('settings.radii_help')}}</p>
@@ -249,6 +178,7 @@
         <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
         <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
       </div>
+
       <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
         <div class="tab-header shadow-selector">
           <div class="select-container">
@@ -294,6 +224,7 @@
           <p>{{$t('settings.style.shadows.filter_hint.spread_zero')}}</p>
         </div>
       </div>
+
       <div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
         <div class="tab-header">
           <p>{{$t('settings.style.fonts.help')}}</p>
diff --git a/src/modules/config.js b/src/modules/config.js
index fb9b3ca6..45ac8f65 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -1,5 +1,5 @@
 import { set, delete as del } from 'vue'
-import { setPreset, setColors } from '../services/style_setter/style_setter.js'
+import { setPreset, applyTheme } from '../services/style_setter/style_setter.js'
 
 const browserLocale = (window.navigator.language || 'en').split('-')[0]
 
@@ -57,7 +57,7 @@ const config = {
           setPreset(value, commit)
           break
         case 'customTheme':
-          setColors(value, commit)
+          applyTheme(value, commit)
       }
     }
   }

From c189a08dffd2373172d9fd34af5954af146c2f36 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 16:36:06 +0300
Subject: [PATCH 93/96] added keep-colors option

---
 .../style_switcher/style_switcher.js          | 88 ++++++++++---------
 .../style_switcher/style_switcher.scss        |  9 +-
 .../style_switcher/style_switcher.vue         | 15 +++-
 src/i18n/en.json                              |  1 +
 src/i18n/ru.json                              |  1 +
 5 files changed, 62 insertions(+), 52 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 50cd1e6f..6a4e1cba 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -38,6 +38,7 @@ export default {
       colorsInvalid: true,
       radiiInvalid: true,
 
+      keepColor: false,
       keepShadows: false,
       keepOpacity: false,
       keepRoundness: false,
@@ -296,31 +297,30 @@ export default {
       return !this.shadowsInvalid && !this.colorsInvalid && !this.radiiInvalid
     },
     exportedTheme () {
-      const saveEverything = !this.keepFonts && !this.keepShadows && !this.keepColors && !this.keepOpacity && !this.keepRoundness
+      const saveEverything = (
+        !this.keepFonts &&
+        !this.keepShadows &&
+        !this.keepOpacity &&
+        !this.keepRoundness &&
+        !this.keepColor
+      )
 
-      // TODO change into delete-less version.
-      const theme = {
-        shadows: this.shadowsLocal,
-        fonts: this.fontsLocal,
-        opacity: this.currentOpacity,
-        colors: this.currentColors,
-        radii: this.currentRadii
-      }
+      const theme = {}
 
-      if (!this.keepFonts && !saveEverything) {
-        delete theme.fonts
+      if (this.keepFonts || saveEverything) {
+        theme.fonts = this.fontsLocal
       }
-      if (!this.keepShadows && !saveEverything) {
-        delete theme.shadows
+      if (this.keepShadows || saveEverything) {
+        theme.shadows = this.shadowsLocal
       }
-      if (!this.keepOpacity && !saveEverything) {
-        delete theme.opacity
+      if (this.keepOpacity || saveEverything) {
+        theme.opacity = this.currentOpacity
       }
-      if (!this.keepColors && !saveEverything) {
-        delete theme.colors
+      if (this.keepColor || saveEverything) {
+        theme.colors = this.currentColors
       }
-      if (!this.keepRoundness && !saveEverything) {
-        delete theme.radii
+      if (this.keepRoundness || saveEverything) {
+        theme.radii = this.currentRadii
       }
 
       return {
@@ -438,21 +438,23 @@ export default {
         this.textColorLocal = rgb2hex(colors.fg)
       }
 
-      this.clearV1()
-      const keys = new Set(version !== 1 ? Object.keys(colors) : [])
-      if (version === 1 || version === 'l1') {
-        keys
-          .add('bg')
-          .add('link')
-          .add('cRed')
-          .add('cBlue')
-          .add('cGreen')
-          .add('cOrange')
-      }
+      if (!this.keepColor) {
+        this.clearV1()
+        const keys = new Set(version !== 1 ? Object.keys(colors) : [])
+        if (version === 1 || version === 'l1') {
+          keys
+            .add('bg')
+            .add('link')
+            .add('cRed')
+            .add('cBlue')
+            .add('cGreen')
+            .add('cOrange')
+        }
 
-      keys.forEach(key => {
-        this[key + 'ColorLocal'] = rgb2hex(colors[key])
-      })
+        keys.forEach(key => {
+          this[key + 'ColorLocal'] = rgb2hex(colors[key])
+        })
+      }
 
       if (!this.keepRoundness) {
         this.clearRoundness()
@@ -553,16 +555,18 @@ export default {
           this.clearOpacity()
         }
 
-        this.clearV1()
+        if (!this.keepColor) {
+          this.clearV1()
 
-        this.bgColorLocal = this.selected[1]
-        this.fgColorLocal = this.selected[2]
-        this.textColorLocal = this.selected[3]
-        this.linkColorLocal = this.selected[4]
-        this.cRedColorLocal = this.selected[5]
-        this.cGreenColorLocal = this.selected[6]
-        this.cBlueColorLocal = this.selected[7]
-        this.cOrangeColorLocal = this.selected[8]
+          this.bgColorLocal = this.selected[1]
+          this.fgColorLocal = this.selected[2]
+          this.textColorLocal = this.selected[3]
+          this.linkColorLocal = this.selected[4]
+          this.cRedColorLocal = this.selected[5]
+          this.cGreenColorLocal = this.selected[6]
+          this.cBlueColorLocal = this.selected[7]
+          this.cOrangeColorLocal = this.selected[8]
+        }
       } else if (this.selectedVersion >= 2) {
         this.normalizeLocalState(this.selected.theme, 2)
       }
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index f53f00a0..135c113a 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -54,11 +54,6 @@
     }
   }
 
-  .import-warning {
-    color: $fallback--cRed;
-    color: var(--cRed, $fallback--cRed);
-  }
-
   .tab-switcher {
     margin: 0 -1em;
   }
@@ -154,8 +149,10 @@
   .save-load-options {
     flex-wrap: wrap;
     margin-top: .5em;
-    span {
+    justify-content: center;
+    .keep-option {
       margin: 0 .5em .5em;
+      min-width: 25%;
     }
   }
 
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 730bfef0..6acb7755 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -28,28 +28,35 @@
         />
     </div>
     <div class="save-load-options">
-      <span>
+      <span class="keep-option">
+        <input
+          id="keep-color"
+          type="checkbox"
+          v-model="keepColor">
+        <label for="keep-color">{{$t('settings.style.switcher.keep_color')}}</label>
+      </span>
+      <span class="keep-option">
         <input
           id="keep-shadows"
           type="checkbox"
           v-model="keepShadows">
         <label for="keep-shadows">{{$t('settings.style.switcher.keep_shadows')}}</label>
       </span>
-      <span>
+      <span class="keep-option">
         <input
           id="keep-opacity"
           type="checkbox"
           v-model="keepOpacity">
         <label for="keep-opacity">{{$t('settings.style.switcher.keep_opacity')}}</label>
       </span>
-      <span>
+      <span class="keep-option">
         <input
           id="keep-roundness"
           type="checkbox"
           v-model="keepRoundness">
         <label for="keep-roundness">{{$t('settings.style.switcher.keep_roundness')}}</label>
       </span>
-      <span>
+      <span class="keep-option">
         <input
           id="keep-fonts"
           type="checkbox"
diff --git a/src/i18n/en.json b/src/i18n/en.json
index a1fc43aa..97dfcb77 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -191,6 +191,7 @@
     },
     "style": {
       "switcher": {
+        "keep_color": "Keep colors",
         "keep_shadows": "Keep shadows",
         "keep_opacity": "Keep opacity",
         "keep_roundness": "Keep roundness",
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 438e0608..c764005a 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -156,6 +156,7 @@
     "user_settings": "Настройки пользователя",
     "style": {
       "switcher": {
+        "keep_color": "Оставить цвета",
         "keep_shadows": "Оставить тени",
         "keep_opacity": "Оставить прозрачность",
         "keep_roundness": "Оставить скругление",

From 83b85cd412245b8bfb65ff650b5543da4974ae46 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 16:36:27 +0300
Subject: [PATCH 94/96] better layouting for import-export, error display fixes

---
 .../export_import/export_import.vue           | 16 +++++++-
 .../style_switcher/style_switcher.vue         | 38 ++++++++++---------
 2 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/src/components/export_import/export_import.vue b/src/components/export_import/export_import.vue
index 9914d54a..451a2668 100644
--- a/src/components/export_import/export_import.vue
+++ b/src/components/export_import/export_import.vue
@@ -1,8 +1,11 @@
 <template>
-<div class="import-export">
+<div class="import-export-container">
+  <slot name="before"/>
   <button class="btn" @click="exportData">{{ exportLabel }}</button>
   <button class="btn" @click="importData">{{ importLabel }}</button>
-  <p v-if="importFailed" class="import-warning">{{ importFailedText }}</p>
+  <slot name="afterButtons"/>
+  <p v-if="importFailed" class="alert error">{{ importFailedText }}</p>
+  <slot name="afterError"/>
 </div>
 </template>
 
@@ -73,3 +76,12 @@ export default {
   }
 }
 </script>
+
+<style lang="scss">
+.import-export-container {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: baseline;
+  justify-content: center;
+}
+</style>
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 6acb7755..84963c81 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -2,30 +2,32 @@
 <div class="style-switcher">
   <div class="presets-container">
     <div class="save-load">
-      <div class="presets">
-        {{$t('settings.presets')}}
-        <label for="preset-switcher" class='select'>
-          <select id="preset-switcher" v-model="selected" class="preset-switcher">
-            <option v-for="style in availableStyles"
-                    :value="style"
-                    :style="{
-                            backgroundColor: style[1] || style.theme.colors.bg,
-                            color: style[3] || style.theme.colors.text
-                            }">
-              {{style[0] || style.name}}
-            </option>
-          </select>
-          <i class="icon-down-open"/>
-        </label>
-      </div>
       <export-import
         :exportObject='exportedTheme'
         :exportLabel='$t("settings.export_theme")'
         :importLabel='$t("settings.import_theme")'
         :importFailedText='$t("settings.invalid_theme_imported")'
         :onImport='onImport'
-        :validator='importValidator'
-        />
+        :validator='importValidator'>
+        <template slot="before">
+          <div class="presets">
+            {{$t('settings.presets')}}
+            <label for="preset-switcher" class='select'>
+              <select id="preset-switcher" v-model="selected" class="preset-switcher">
+                <option v-for="style in availableStyles"
+                        :value="style"
+                        :style="{
+                                backgroundColor: style[1] || style.theme.colors.bg,
+                                color: style[3] || style.theme.colors.text
+                                }">
+                  {{style[0] || style.name}}
+                </option>
+              </select>
+              <i class="icon-down-open"/>
+            </label>
+          </div>
+        </template>
+      </export-import>
     </div>
     <div class="save-load-options">
       <span class="keep-option">

From c3f8b713a77adbac73678f3f1c7a9ab937ca5904 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 16:37:03 +0300
Subject: [PATCH 95/96] fixed wrong height for selects

---
 src/App.scss | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/App.scss b/src/App.scss
index 15dec7ec..5355d899 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -119,7 +119,7 @@ input, textarea, .select {
   box-sizing: border-box;
   display: inline-block;
   position: relative;
-  height: 29px;
+  height: 28px;
   line-height: 16px;
   hyphens: none;
 
@@ -136,7 +136,7 @@ input, textarea, .select {
     height: 100%;
     color: $fallback--text;
     color: var(--text, $fallback--text);
-    line-height: 29px;
+    line-height: 28px;
     z-index: 0;
     pointer-events: none;
   }
@@ -156,7 +156,7 @@ input, textarea, .select {
     font-size: 14px;
     width: 100%;
     z-index: 1;
-    height: 29px;
+    height: 28px;
     line-height: 16px;
   }
 

From 8fcc4c67667b0951d6c0d28cec320bd4b2f8f107 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 11 Dec 2018 19:09:00 +0300
Subject: [PATCH 96/96] fix

---
 static/styles.json | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/static/styles.json b/static/styles.json
index b6bd6530..00ad6ae1 100644
--- a/static/styles.json
+++ b/static/styles.json
@@ -7,9 +7,9 @@
   "monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672", "#F92672", "#a6e22e", "#66d9ef", "#f4bf75" ],
   "mammal": [ "Mammal", "#272c37", "#444b5d", "#f8f8f8", "#9bacc8", "#7f3142", "#2bd850", "#2b90d9", "#ca8f04" ],
 
-  "redmond-xx": "./static/themes/redmond-xx.json",
-  "redmond-xx-se": "./static/themes/redmond-xx-se.json",
-  "redmond-xxi": "./static/themes/redmond-xxi.json",
-  "breezy-dark": "./static/themes/breezy-dark.json",
-  "breezy-light": "./static/themes/breezy-light.json"
+  "redmond-xx": "/static/themes/redmond-xx.json",
+  "redmond-xx-se": "/static/themes/redmond-xx-se.json",
+  "redmond-xxi": "/static/themes/redmond-xxi.json",
+  "breezy-dark": "/static/themes/breezy-dark.json",
+  "breezy-light": "/static/themes/breezy-light.json"
 }