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
     }
   }