diff --git a/autoload/airline/themes/fresh.vim b/autoload/airline/themes/fresh.vim
deleted file mode 100644
index d67b5de..0000000
--- a/autoload/airline/themes/fresh.vim
+++ /dev/null
@@ -1,73 +0,0 @@
-" fresh palette
-let g:airline#themes#fresh#palette = {}
-
-" NORMAL mode
-let s:N1 = ['#005f00', '#afdf00', 22, 148, '']
-let s:N2 = ['#ffffff', '#005f00', 15, 22, '']
-let s:N3 = ['#ffffff', '#121212', 15, 233, 'bold']
-let s:W = ['#000000', '#8700df', 232, 92, '']
-let s:E = ['#000000', '#990000', 232, 160]
-let g:airline#themes#fresh#palette.normal =
-      \ airline#themes#generate_color_map(s:N1, s:N2, s:N3)
-let g:airline#themes#fresh#palette.normal.airline_warning = s:W
-let g:airline#themes#fresh#palette.normal.airline_error = s:E
-let g:airline#themes#fresh#palette.normal_modified = {
-      \ 'airline_c': ['#ffffff', '#5f0087', 15, 53, 'bold'], }
-
-" INSERT mode
-let s:I1 = ['#0000df', '#00dfff', 20, 45, '']
-let s:I2 = ['#ffffff', '#005fdf', 15, 26, '']
-let s:I3 = ['#ffffff', '#121212', 15, 233, 'bold']
-let g:airline#themes#fresh#palette.insert =
-      \ airline#themes#generate_color_map(s:I1, s:I2, s:I3)
-let g:airline#themes#fresh#palette.insert.airline_warning = s:W
-let g:airline#themes#fresh#palette.insert.airline_error = s:E
-let g:airline#themes#fresh#palette.insert_modified =
-      \ g:airline#themes#fresh#palette.normal_modified
-let g:airline#themes#fresh#palette.insert_paste = {
-      \ 'airline_a': [s:I1[0], '#ffff00', s:I1[2], 11, ''], }
-
-" REPLACE mode
-let s:R1 = [s:I2[0], '#af0000', s:I2[2], 124, '']
-let s:R2 = ['#ffffff', '#5f0000', 15, 52, '']
-let s:R3 = ['#ffffff', '#121212', 15, 233, 'bold']
-let g:airline#themes#fresh#palette.replace =
-      \ airline#themes#generate_color_map(s:R1, s:R2, s:R3)
-let g:airline#themes#fresh#palette.replace.airline_warning = s:W
-let g:airline#themes#fresh#palette.replace.airline_error = s:E
-let g:airline#themes#fresh#palette.replace_modified =
-      \ g:airline#themes#fresh#palette.normal_modified
-
-" VISAUL mode
-let s:V1 = ['#ff5f00', '#ff5f00', 52, 208, '']
-let s:V2 = ['#ffffff', '#005f00', 15, 124, '']
-let s:V3 = ['#ffffff', '#121212', 15, 233, 'bold']
-let g:airline#themes#fresh#palette.visual =
-      \ airline#themes#generate_color_map(s:V1, s:V2, s:V3)
-let g:airline#themes#fresh#palette.visual.airline_warning = s:W
-let g:airline#themes#fresh#palette.visual.airline_error = s:E
-let g:airline#themes#fresh#palette.visual_modified =
-      \ g:airline#themes#fresh#palette.normal_modified
-
-" INACTIVE mode
-let s:IA1 = ['#4e4e4e', '#1c1c1c', 239, 234, '']
-let s:IA2 = ['#4e4e4e', '#262626', 239, 235, '']
-let s:IA3 = ['#ffffff', '#121212', 15, 233, 'bold']
-let g:airline#themes#fresh#palette.inactive =
-      \ airline#themes#generate_color_map(s:IA1, s:IA2, s:IA3)
-let g:airline#themes#fresh#palette.inactive.airline_warning = s:IA2
-let g:airline#themes#fresh#palette.inactive.airline_error =  s:IA2
-let g:airline#themes#fresh#palette.inactive_modified = {
-      \ 'airline_c': ['#875faf', '', 97, '', ''], }
-
-let g:airline#themes#fresh#palette.accents = {
-      \ 'red': [ '#ff0000' , '' , 160 , ''  ] }
-
-if !get(g:, 'loaded_ctrlp', 0)
-  finish
-endif
-let g:airline#themes#fresh#palette.ctrlp =
-      \ airline#extensions#ctrlp#generate_color_map(
-      \   ['#d7d7ff', '#5f00af', 189, 55, ''],
-      \   ['#ffffff', '#875fd7', 231, 98, ''],
-      \   ['#5f00af', '#ffffff', 55, 231, 'bold'] )
diff --git a/plugin/settings.vim b/plugin/settings.vim
index 82c2b8c..55a4c64 100644
--- a/plugin/settings.vim
+++ b/plugin/settings.vim
@@ -16,12 +16,6 @@ if !has('nvim') && &ttimeoutlen == -1
   set ttimeoutlen=100
 endif
 
-" TODO: These might be irrelevant with vim-airline
-" Show 2 line status
-set laststatus=2
-" Show the line and colum number of a cursor position
-set ruler
-
 " Enhanced command line completion
 set wildmenu
 " Command line history
diff --git a/plugin/statusline.vim b/plugin/statusline.vim
new file mode 100644
index 0000000..07b70ef
--- /dev/null
+++ b/plugin/statusline.vim
@@ -0,0 +1,159 @@
+" Show the statusline above the commandline.
+set laststatus=2
+
+" Define color variables.
+let g:statusline#light_green  = {'fg': ['235', '#080808'], 'bg': [ '35', '#0087ff']}
+let g:statusline#light_blue   = {'fg': ['235', '#080808'], 'bg': [ '33', '#0087ff']}
+let g:statusline#light_orange = {'fg': ['235', '#080808'], 'bg': ['209', '#eb754d']}
+let g:statusline#light_red    = {'fg': ['235', '#080808'], 'bg': ['124', '#af0000']}
+let g:statusline#light_grey   = {'fg': ['250', "#bcbcbc"], 'bg': ['236', "#303030"]}
+let g:statusline#light_violet = {'fg': ['235', '#080808'], 'bg': [ '99', '#986fec']}
+let g:statusline#dark_white   = {'fg': [ '15', '#ffffff'], 'bg': ['233', '#121212']}
+let g:statusline#dark_yellow  = {'fg': ['179', '#dfaf5f'], 'bg': ['233', '#121212']}
+
+" Create highlight groups.
+function! s:hi(group, color) abort
+  execute 'highlight '.a:group
+        \.' ctermfg='.a:color['fg'][0].' ctermbg='.a:color['bg'][0]
+        \.' guifg='.a:color['fg'][1].' guibg='.a:color['fg'][1]
+endfunction
+
+" StatusLineLight is shows the mode and cursor information, it is dynamically
+" changed by statusline#mode(), give it a default.
+call s:hi('StatusLineLight', g:statusline#light_grey)
+" StatusLineDusk is shows additional information which is not always present,
+" give it a muted color.
+call s:hi('StatusLineDusk', g:statusline#light_grey)
+" StatusLineDark shows the filename and filetype and takes up most of the
+" statusline, give it a dark background.
+call s:hi('StatusLineDark', g:statusline#dark_white)
+" StatusLineChange show changes in the file by changing the colour of the
+" filename, give if a dark background.
+call s:hi('StatusLineChange', g:statusline#dark_yellow)
+
+" Construct a statusline for special buffer types.
+function! statusline#special(group, name, title)
+  " Display current mode with dynamic highlights.
+  let l:mode = '%#'.a:group.'# '.a:name.' '
+  " Display filename with dark highlights.
+  let l:file = '%#StatusLineDark# '.a:title
+  " Display current/total lines and column with dynamic highlights.
+  let l:line = '%#'.a:group.'# ☰ %l/%L ㏑%2c '
+  " Combine the elements into a single string to be evaluated.
+  return l:mode.l:file.'%='.l:line
+endfunction
+
+" Construct a statusline for generic buffer types.
+function! statusline#generic(group, mode)
+  " Display current mode with dynamic highlights.
+  let l:mode = '%#'.a:group.'# '.a:mode.' '
+  " Display spell or paste if set with dusk highlights in a group to swallow
+  " the spaces when empty.
+  let l:edit = '%#StatusLineDusk#%( '
+        \.'%{&spell ? "Spell " : ""}'
+        \.'%{&paste ? "Paste " : ""}'
+        \.'%)'
+  " Display filename with dark or changed highlights.
+  let l:file = (&modified ? '%#StatusLineChange#' : '%#StatusLineDark#').' %f'
+  " Display readonly and nomodifiable if set.
+  let l:state = '%#StatusLineDark#'
+        \.'%{&readonly ? " 🔒" : ""}'
+        \.'%{&modifiable ? "" : " ⛔"}'
+  " Display filetype if set.
+  let l:type = '%#StatusLineDark# %{&filetype} '
+  " Display fileencoding if not utf-8 and fileformat if not unix with dusk
+  " highlights in a group to swallow spaces when empty.
+  let l:format = '%#StatusLineDusk#%( '
+        \.'%{&fileencoding ==# "utf-8" ? "" : &fileencoding}'
+        \.'%{&fileformat ==# "unix" ? "" : "[".&fileformat."]"}'
+        \.' %)'
+  " Display current/total lines and column with dynamic highlights.
+  let l:line = '%#'.a:group.'# ☰ %l/%L ㏑%2c '
+  " Combine the elements into a single string to be evaluated.
+  return l:mode.l:edit.l:file.l:state.'%='.l:type.l:format.l:line
+endfunction
+
+" Define active statusline, this statusline is dynamic with StatusLineLight
+" being updated based on the current mode and only used for current buffer.
+function! statusline#active()
+  let l:mode = statusline#mode()
+  if &buftype ==# 'help'
+    if l:mode ==# 'Normal'
+      let l:mode = 'Help'
+    endif
+    return statusline#special('StatusLineLight', l:mode, '%F')
+  elseif &buftype ==# 'quickfix'
+    " Quickfix list and location list have the same buftype, the window has a
+    " loclist flag, query the window info.
+    let l:info = getwininfo(win_getid())[0]
+    if l:mode ==# 'Normal'
+      let l:mode = l:info['loclist'] ? 'Location' : 'Quickfix'
+    endif
+    return statusline#special('StatusLineLight', l:mode,
+          \ get(l:info['variables'], 'quickfix_title', ''))
+  elseif &buftype ==# 'terminal'
+    return statusline#special('StatusLineLight', 'Terminal', '%f')
+  elseif &previewwindow
+    if l:mode ==# 'Normal'
+      let l:mode = 'Preview'
+    endif
+    return statusline#generic('StatusLineLight', l:mode)
+  endif
+  return statusline#generic('StatusLineLight', l:mode)
+endfunction
+
+" Define inactive statusline, this remains static until the buffer gains
+" focus again.
+function! statusline#inactive()
+  if &buftype ==# 'help'
+    let l:statusline = statusline#special('StatusLineDusk', 'Help', '%F')
+  elseif &buftype ==# 'quickfix'
+    " Quickfix list and location list have the same buftype, the window has a
+    " loclist flag, query the window info.
+    let l:info = getwininfo(win_getid())[0]
+    let l:statusline = statusline#special('StatusLineDusk',
+          \ l:info['loclist'] ? 'Location' : 'Quickfix',
+          \ get(l:info['variables'], 'quickfix_title', ''))
+  elseif &buftype ==# 'terminal'
+    let l:statusline = statusline#special('StatusLineDusk', 'Terminal', '%f')
+  elseif &previewwindow
+    let l:statusline = statusline#generic('StatusLineDusk', 'Preview')
+  else
+    let l:statusline = statusline#generic('StatusLineDusk', 'Idle')
+  endif
+  " Escape spaces and double quotes for use in setlocal.
+  let l:statusline = substitute(l:statusline, '\([ "]\)', '\\\0', 'g')
+  execute 'setlocal statusline='.l:statusline
+endfunction
+
+" Get statusline mode and update StatusLineLight.
+function! statusline#mode()
+  " Map modes to a human readable name and a color.
+  let l:mode = {
+  \   'n':  ['Normal',  g:statusline#light_green],
+  \   'i':  ['Insert',  g:statusline#light_blue],
+  \   'c':  ['Command', g:statusline#light_green],
+  \   'v':  ['Visual',  g:statusline#light_orange],
+  \   'V':  ['V-Line',  g:statusline#light_orange],
+  \   '': ['V-Block', g:statusline#light_orange],
+  \   'R':  ['Replace', g:statusline#light_red],
+  \   's':  ['Select',  g:statusline#light_violet],
+  \   'S':  ['S-Line',  g:statusline#light_violet],
+  \   '': ['S-Block', g:statusline#light_violet],
+  \   't':  ['Terminal',    g:statusline#light_grey],
+  \   '!':  ['Shell',   g:statusline#light_grey],
+  \}[mode()]
+  " Update the StatusLineLight color.
+  call s:hi('StatusLineLight', l:mode[1])
+  return l:mode[0]
+endfunction
+
+" Setup autocmds to set the statusline per buffer.
+augroup benieStatusLine
+  autocmd!
+  " Dynamically update the current buffer mode and color changes using %! to
+  " call a function which is always evaluated on statusline update.
+  autocmd BufEnter,WinEnter,BufWinEnter * setlocal statusline=%!statusline#active()
+  " Statically set the statusline when leaving the buffer.
+  autocmd BufLeave,WinLeave * call statusline#inactive()
+augroup END
diff --git a/vimrc b/vimrc
index f44701a..b2c8207 100644
--- a/vimrc
+++ b/vimrc
@@ -23,14 +23,6 @@ endif
 set runtimepath+=~/.config/work
 set packpath+=~/.config/work
 
-" vim-airline - improved status bar
-Pack 'vim-airline/vim-airline'
-let g:airline#extensions#branch#enabled = 0
-let g:airline#extensions#hunks#enabled = 0
-let g:airline#extensions#wordcount#enabled = 0
-for s:setting in ['left_sep', 'right_sep', 'section_error', 'section_warning']
-  exec 'let g:airline_'.s:setting.' = ""'
-endfor
 " tabline.vim - sanely numbered tabs
 Pack 'mkitt/tabline.vim'