diff --git a/config/awesome/rc.lua b/config/awesome/rc.lua
new file mode 100644
index 00000000..067b3835
--- /dev/null
+++ b/config/awesome/rc.lua
@@ -0,0 +1,683 @@
+-- If LuaRocks is installed, make sure that packages installed through it are
+-- found (e.g. lgi). If LuaRocks is not installed, do nothing.
+pcall(require, "luarocks.loader")
+
+-- Standard awesome library
+local awful = require "awful"
+local gears = require "gears"
+require "awful.autofocus"
+
+-- Widget and layout library
+local wibox = require "wibox"
+
+-- Theme handling library
+local beautiful = require "beautiful"
+
+-- Notification library
+local hotkeys_popup = require "awful.hotkeys_popup"
+local menubar = require "menubar"
+local naughty = require "naughty"
+
+-- Enable hotkeys help widget for VIM and other apps
+-- when client with a matching name is opened:
+require "awful.hotkeys_popup.keys"
+
+-- {{{ Error handling
+-- Check if awesome encountered an error during startup and fell back to
+-- another config (This code will only ever execute for the fallback config)
+if awesome.startup_errors then
+  naughty.notify {
+    preset = naughty.config.presets.critical,
+    title = "Oops, there were errors during startup!",
+    text = awesome.startup_errors,
+  }
+end
+
+-- Handle runtime errors after startup
+do
+  local in_error = false
+  awesome.connect_signal("debug::error", function(err)
+    -- Make sure we don't go into an endless error loop
+    if in_error then
+      return
+    end
+    in_error = true
+
+    naughty.notify {
+      preset = naughty.config.presets.critical,
+      title = "Oops, an error happened!",
+      text = tostring(err),
+    }
+    in_error = false
+  end)
+end
+-- }}}
+
+-- {{{ Variable definitions
+-- Themes define colours, icons, font and wallpapers.
+beautiful.init(gears.filesystem.get_configuration_dir() .. "theme.lua")
+
+awful.spawn.with_shell "awesome-autorun"
+
+-- This is used later as the default terminal and editor to run.
+terminal = "alacritty"
+editor = os.getenv "EDITOR" or "nano"
+editor_cmd = terminal .. " -e " .. editor
+
+-- Default modkey.
+-- Usually, Mod4 is the key with a logo between Control and Alt.
+-- If you do not like this or do not have such a key,
+-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
+-- However, you can use another modifier like Mod1, but it may interact with others.
+modkey = "Mod4"
+
+-- Table of layouts to cover with awful.layout.inc, order matters.
+awful.layout.layouts = {
+  awful.layout.suit.max,
+  awful.layout.suit.tile,
+  awful.layout.suit.floating,
+  -- awful.layout.suit.tile.left,
+  -- awful.layout.suit.tile.bottom,
+  -- awful.layout.suit.tile.top,
+  -- awful.layout.suit.fair,
+  -- awful.layout.suit.fair.horizontal,
+  -- awful.layout.suit.spiral,
+  -- awful.layout.suit.spiral.dwindle,
+  -- awful.layout.suit.max.fullscreen,
+  -- awful.layout.suit.magnifier,
+  -- awful.layout.suit.corner.nw,
+  -- awful.layout.suit.corner.ne,
+  -- awful.layout.suit.corner.sw,
+  -- awful.layout.suit.corner.se,
+}
+-- }}}
+
+-- {{{ Menu
+-- Create a launcher widget and a main menu
+myawesomemenu = {
+  {
+    "hotkeys",
+    function()
+      hotkeys_popup.show_help(nil, awful.screen.focused())
+    end,
+  },
+  { "manual", terminal .. " -e man awesome" },
+  { "edit config", editor_cmd .. " " .. awesome.conffile },
+  { "restart", awesome.restart },
+  {
+    "quit",
+    function()
+      awesome.quit()
+    end,
+  },
+}
+
+mymainmenu = awful.menu {
+  items = {
+    { "awesome", myawesomemenu, beautiful.awesome_icon },
+    { "open terminal", terminal },
+  },
+}
+
+mylauncher = awful.widget.launcher { image = beautiful.awesome_icon, menu = mymainmenu }
+
+-- Menubar configuration
+menubar.utils.terminal = terminal -- Set the terminal for applications that require it
+-- }}}
+
+-- Keyboard map indicator and switcher
+mykeyboardlayout = awful.widget.keyboardlayout()
+
+-- {{{ Wibar
+-- Create a textclock widget
+mytextclock = wibox.widget.textclock()
+
+-- Create a wibox for each screen and add it
+local taglist_buttons = gears.table.join(
+  awful.button({}, 1, function(t)
+    t:view_only()
+  end),
+  awful.button({ modkey }, 1, function(t)
+    if client.focus then
+      client.focus:move_to_tag(t)
+    end
+  end),
+  awful.button({}, 3, awful.tag.viewtoggle),
+  awful.button({ modkey }, 3, function(t)
+    if client.focus then
+      client.focus:toggle_tag(t)
+    end
+  end),
+  awful.button({}, 4, function(t)
+    awful.tag.viewnext(t.screen)
+  end),
+  awful.button({}, 5, function(t)
+    awful.tag.viewprev(t.screen)
+  end)
+)
+
+local tasklist_buttons = gears.table.join(
+  awful.button({}, 1, function(c)
+    if c == client.focus then
+      c.minimized = true
+    else
+      c:emit_signal("request::activate", "tasklist", { raise = true })
+    end
+  end),
+  awful.button({}, 3, function()
+    awful.menu.client_list { theme = { width = 250 } }
+  end),
+  awful.button({}, 4, function()
+    awful.client.focus.byidx(1)
+  end),
+  awful.button({}, 5, function()
+    awful.client.focus.byidx(-1)
+  end)
+)
+
+local function set_wallpaper(s)
+  -- Wallpaper
+  if beautiful.wallpaper then
+    local wallpaper = beautiful.wallpaper
+    -- If wallpaper is a function, call it with the screen
+    if type(wallpaper) == "function" then
+      wallpaper = wallpaper(s)
+    end
+    gears.wallpaper.maximized(wallpaper, s, true)
+  end
+end
+
+-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
+screen.connect_signal("property::geometry", set_wallpaper)
+
+awful.screen.connect_for_each_screen(function(s)
+  -- Wallpaper
+  set_wallpaper(s)
+
+  -- Each screen has its own tag table.
+  awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
+
+  -- Create a promptbox for each screen
+  s.mypromptbox = awful.widget.prompt()
+
+  -- Create an imagebox widget which will contain an icon indicating which layout we're using.
+  -- We need one layoutbox per screen.
+  s.mylayoutbox = awful.widget.layoutbox(s)
+  s.mylayoutbox:buttons(gears.table.join(
+    awful.button({}, 1, function()
+      awful.layout.inc(1)
+    end),
+    awful.button({}, 3, function()
+      awful.layout.inc(-1)
+    end),
+    awful.button({}, 4, function()
+      awful.layout.inc(1)
+    end),
+    awful.button({}, 5, function()
+      awful.layout.inc(-1)
+    end)
+  ))
+  -- Create a taglist widget
+  s.mytaglist = awful.widget.taglist {
+    screen = s,
+    filter = awful.widget.taglist.filter.all,
+    buttons = taglist_buttons,
+  }
+
+  -- Create a tasklist widget
+  s.mytasklist = awful.widget.tasklist {
+    screen = s,
+    filter = awful.widget.tasklist.filter.currenttags,
+    buttons = tasklist_buttons,
+  }
+
+  -- Create the wibox
+  s.mywibox = awful.wibar { position = "top", screen = s }
+
+  -- Add widgets to the wibox
+  s.mywibox:setup {
+    layout = wibox.layout.align.horizontal,
+    { -- Left widgets
+      layout = wibox.layout.fixed.horizontal,
+      s.mytaglist,
+      s.mypromptbox,
+    },
+    s.mytasklist, -- Middle widget
+    { -- Right widgets
+      layout = wibox.layout.fixed.horizontal,
+      -- mykeyboardlayout,
+      wibox.widget.systray(),
+      require "widgets.battery",
+      mytextclock,
+      s.mylayoutbox,
+    },
+  }
+end)
+-- }}}
+
+-- {{{ Mouse bindings
+root.buttons(gears.table.join(
+  awful.button({}, 3, function()
+    mymainmenu:toggle()
+  end),
+  awful.button({}, 4, awful.tag.viewnext),
+  awful.button({}, 5, awful.tag.viewprev)
+))
+-- }}}
+
+-- {{{ Key bindings
+globalkeys = gears.table.join(
+  awful.key({ modkey }, "s", hotkeys_popup.show_help, { description = "show help", group = "awesome" }),
+  awful.key({ modkey }, "Left", awful.tag.viewprev, { description = "view previous", group = "tag" }),
+  awful.key({ modkey }, "Right", awful.tag.viewnext, { description = "view next", group = "tag" }),
+  awful.key({ modkey }, "Escape", awful.tag.history.restore, { description = "go back", group = "tag" }),
+  awful.key({ modkey }, "j", function()
+    awful.client.focus.byidx(1)
+  end, { description = "focus next by index", group = "client" }),
+  awful.key({ modkey }, "k", function()
+    awful.client.focus.byidx(-1)
+  end, { description = "focus previous by index", group = "client" }),
+  awful.key({ modkey }, "w", function()
+    mymainmenu:show()
+  end, { description = "show main menu", group = "awesome" }),
+
+  -- Layout manipulation
+  awful.key({ modkey, "Shift" }, "j", function()
+    awful.client.swap.byidx(1)
+  end, { description = "swap with next client by index", group = "client" }),
+  awful.key({ modkey, "Shift" }, "k", function()
+    awful.client.swap.byidx(-1)
+  end, { description = "swap with previous client by index", group = "client" }),
+  awful.key({ modkey, "Control" }, "j", function()
+    awful.screen.focus_relative(1)
+  end, { description = "focus the next screen", group = "screen" }),
+  awful.key({ modkey, "Control" }, "k", function()
+    awful.screen.focus_relative(-1)
+  end, { description = "focus the previous screen", group = "screen" }),
+  awful.key({ modkey }, "u", awful.client.urgent.jumpto, { description = "jump to urgent client", group = "client" }),
+  awful.key({ modkey }, "Tab", function()
+    awful.client.focus.history.previous()
+    if client.focus then
+      client.focus:raise()
+    end
+  end, { description = "go back", group = "client" }),
+
+  -- Standard program
+  awful.key({ modkey }, "Return", function()
+    awful.spawn(terminal)
+  end, { description = "open a terminal", group = "launcher" }),
+  awful.key({ modkey, "Control" }, "r", awesome.restart, { description = "reload awesome", group = "awesome" }),
+  awful.key({ modkey, "Shift" }, "q", awesome.quit, { description = "quit awesome", group = "awesome" }),
+  awful.key({ modkey }, "l", function()
+    awful.tag.incmwfact(0.05)
+  end, { description = "increase master width factor", group = "layout" }),
+  awful.key({ modkey }, "h", function()
+    awful.tag.incmwfact(-0.05)
+  end, { description = "decrease master width factor", group = "layout" }),
+  awful.key({ modkey, "Shift" }, "h", function()
+    awful.tag.incnmaster(1, nil, true)
+  end, { description = "increase the number of master clients", group = "layout" }),
+  awful.key({ modkey, "Shift" }, "l", function()
+    awful.tag.incnmaster(-1, nil, true)
+  end, { description = "decrease the number of master clients", group = "layout" }),
+  awful.key({ modkey, "Control" }, "h", function()
+    awful.tag.incncol(1, nil, true)
+  end, { description = "increase the number of columns", group = "layout" }),
+  awful.key({ modkey, "Control" }, "l", function()
+    awful.tag.incncol(-1, nil, true)
+  end, { description = "decrease the number of columns", group = "layout" }),
+  awful.key({ modkey }, "space", function()
+    awful.layout.inc(1)
+  end, { description = "select next", group = "layout" }),
+  awful.key({ modkey, "Shift" }, "space", function()
+    awful.layout.inc(-1)
+  end, { description = "select previous", group = "layout" }),
+
+  awful.key({ modkey, "Control" }, "n", function()
+    local c = awful.client.restore()
+    -- Focus restored client
+    if c then
+      c:emit_signal("request::activate", "key.unminimize", { raise = true })
+    end
+  end, { description = "restore minimized", group = "client" }),
+
+  -- Prompt
+  awful.key({ modkey }, "r", function()
+    awful.screen.focused().mypromptbox:run()
+  end, { description = "run prompt", group = "launcher" }),
+
+  awful.key({ modkey, "Shift" }, "b", function()
+    awful.spawn "firefox"
+  end, { description = "run browser", group = "launcher" }),
+
+  awful.key({ modkey, "Shift" }, "f", function()
+    awful.spawn "thunar"
+  end, { description = "run browser", group = "launcher" }),
+
+  awful.key({ modkey }, "x", function()
+    awful.prompt.run {
+      prompt = "Run Lua code: ",
+      textbox = awful.screen.focused().mypromptbox.widget,
+      exe_callback = awful.util.eval,
+      history_path = awful.util.get_cache_dir() .. "/history_eval",
+    }
+  end, { description = "lua execute prompt", group = "awesome" }),
+  -- Menubar
+  awful.key({ modkey }, "p", function()
+    menubar.show()
+  end, { description = "show the menubar", group = "launcher" })
+)
+
+clientkeys = gears.table.join(
+  awful.key({ modkey }, "f", function(c)
+    c.fullscreen = not c.fullscreen
+    c:raise()
+  end, { description = "toggle fullscreen", group = "client" }),
+  awful.key({ modkey, "Shift" }, "c", function(c)
+    c:kill()
+  end, { description = "close", group = "client" }),
+  awful.key(
+    { modkey, "Control" },
+    "space",
+    awful.client.floating.toggle,
+    { description = "toggle floating", group = "client" }
+  ),
+  awful.key({ modkey, "Control" }, "Return", function(c)
+    c:swap(awful.client.getmaster())
+  end, { description = "move to master", group = "client" }),
+  awful.key({ modkey }, "o", function(c)
+    c:move_to_screen()
+  end, { description = "move to screen", group = "client" }),
+  awful.key({ modkey }, "t", function(c)
+    c.ontop = not c.ontop
+  end, { description = "toggle keep on top", group = "client" }),
+  awful.key({ modkey }, "n", function(c)
+    -- The client currently has the input focus, so it cannot be
+    -- minimized, since minimized clients can't have the focus.
+    c.minimized = true
+  end, { description = "minimize", group = "client" }),
+  awful.key({ modkey }, "m", function(c)
+    c.maximized = not c.maximized
+    c:raise()
+  end, { description = "(un)maximize", group = "client" }),
+  awful.key({ modkey, "Control" }, "m", function(c)
+    c.maximized_vertical = not c.maximized_vertical
+    c:raise()
+  end, { description = "(un)maximize vertically", group = "client" }),
+  awful.key({ modkey, "Shift" }, "m", function(c)
+    c.maximized_horizontal = not c.maximized_horizontal
+    c:raise()
+  end, { description = "(un)maximize horizontally", group = "client" })
+)
+
+-- Bind all key numbers to tags.
+-- Be careful: we use keycodes to make it work on any keyboard layout.
+-- This should map on the top row of your keyboard, usually 1 to 9.
+for i = 1, 9 do
+  globalkeys = gears.table.join(
+    globalkeys,
+
+    -- View tag only.
+    awful.key({ modkey }, "#" .. i + 9, function()
+      local screen = awful.screen.focused()
+      local tag = screen.tags[i]
+      if tag then
+        tag:view_only()
+      end
+    end, { description = "view tag #" .. i, group = "tag" }),
+
+    -- Toggle tag display.
+    awful.key({ modkey, "Control" }, "#" .. i + 9, function()
+      local screen = awful.screen.focused()
+      local tag = screen.tags[i]
+      if tag then
+        awful.tag.viewtoggle(tag)
+      end
+    end, { description = "toggle tag #" .. i, group = "tag" }),
+
+    -- Move client to tag.
+    awful.key({ modkey, "Shift" }, "#" .. i + 9, function()
+      if client.focus then
+        local tag = client.focus.screen.tags[i]
+        if tag then
+          client.focus:move_to_tag(tag)
+        end
+      end
+    end, { description = "move focused client to tag #" .. i, group = "tag" }),
+
+    -- Toggle tag on focused client.
+    awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, function()
+      if client.focus then
+        local tag = client.focus.screen.tags[i]
+        if tag then
+          client.focus:toggle_tag(tag)
+        end
+      end
+    end, { description = "toggle focused client on tag #" .. i, group = "tag" })
+  )
+end
+
+clientbuttons = gears.table.join(
+  awful.button({}, 1, function(c)
+    c:emit_signal("request::activate", "mouse_click", { raise = true })
+  end),
+
+  awful.button({ modkey }, 1, function(c)
+    c:emit_signal("request::activate", "mouse_click", { raise = true })
+    awful.mouse.client.move(c)
+  end),
+
+  awful.button({ modkey }, 3, function(c)
+    c:emit_signal("request::activate", "mouse_click", { raise = true })
+    awful.mouse.client.resize(c)
+  end)
+)
+
+-- Set keys
+root.keys(globalkeys)
+-- }}}
+
+-- {{{ Rules
+-- Rules to apply to new clients (through the "manage" signal).
+awful.rules.rules = {
+  -- All clients will match this rule.
+  {
+    rule = {},
+    properties = {
+      border_width = beautiful.border_width,
+      border_color = beautiful.border_normal,
+      focus = awful.client.focus.filter,
+      raise = true,
+      keys = clientkeys,
+      buttons = clientbuttons,
+      screen = awful.screen.preferred,
+      placement = awful.placement.no_overlap + awful.placement.no_offscreen,
+    },
+  },
+
+  -- Floating clients.
+  {
+    rule_any = {
+      instance = {
+        "DTA", -- Firefox addon DownThemAll.
+        "copyq", -- Includes session name in class.
+        "pinentry",
+      },
+
+      class = {
+        "Arandr",
+        "Blueman-manager",
+        "Gpick",
+        "Kruler",
+        "MessageWin", -- kalarm.
+        "Sxiv",
+        "Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size.
+        "Wpa_gui",
+        "veromix",
+        "xtightvncviewer",
+      },
+
+      -- Note that the name property shown in xprop might be set slightly after creation of the client
+      -- and the name shown there might not match defined rules here.
+      name = {
+        "Event Tester", -- xev.
+      },
+
+      role = {
+        "AlarmWindow", -- Thunderbird's calendar.
+        "ConfigManager", -- Thunderbird's about:config.
+        "pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
+      },
+    },
+
+    properties = { floating = true },
+  },
+
+  -- Add titlebars to normal clients and dialogs
+  { rule_any = { type = { "normal", "dialog" } }, properties = { titlebars_enabled = false } },
+
+  -- Set Firefox to always map on the tag named "2" on screen 1.
+  -- { rule = { class = "Firefox" },
+  --   properties = { screen = 1, tag = "2" } },
+
+  { rule = { class = "mpv" }, properties = { tag = "5", fullscreen = true } },
+
+  { rule = { name = "Podcasts - Pocket Casts" }, properties = { tag = "6" } },
+
+  { rule = { class = "kdenlive" }, properties = { tag = "7", fullscreen = true } },
+
+  { rule = { class = "0ad" }, properties = { tag = "8" } },
+
+  { rule = { class = "Slack" }, properties = { tag = "9" } },
+  { rule = { class = "discord" }, properties = { tag = "9" } },
+}
+-- }}}
+
+-- {{{ Signals
+-- Signal function to execute when a new client appears.
+client.connect_signal("manage", function(c)
+  -- Set the windows at the slave,
+  -- i.e. put it at the end of others instead of setting it master.
+  -- if not awesome.startup then awful.client.setslave(c) end
+
+  if awesome.startup and not c.size_hints.user_position and not c.size_hints.program_position then
+    -- Prevent clients from being unreachable after screen count changes.
+    awful.placement.no_offscreen(c)
+  end
+end)
+
+-- Add a titlebar if titlebars_enabled is set to true in the rules.
+client.connect_signal("request::titlebars", function(c)
+  -- buttons for the titlebar
+  local buttons = gears.table.join(
+    awful.button({}, 1, function()
+      c:emit_signal("request::activate", "titlebar", { raise = true })
+      awful.mouse.client.move(c)
+    end),
+    awful.button({}, 3, function()
+      c:emit_signal("request::activate", "titlebar", { raise = true })
+      awful.mouse.client.resize(c)
+    end)
+  )
+
+  awful.titlebar(c):setup {
+    { -- Left
+      awful.titlebar.widget.iconwidget(c),
+      buttons = buttons,
+      layout = wibox.layout.fixed.horizontal,
+    },
+
+    { -- Middle
+      { -- Title
+        align = "center",
+        widget = awful.titlebar.widget.titlewidget(c),
+      },
+      buttons = buttons,
+      layout = wibox.layout.flex.horizontal,
+    },
+
+    { -- Right
+      awful.titlebar.widget.floatingbutton(c),
+      awful.titlebar.widget.maximizedbutton(c),
+      awful.titlebar.widget.stickybutton(c),
+      awful.titlebar.widget.ontopbutton(c),
+      awful.titlebar.widget.closebutton(c),
+      layout = wibox.layout.fixed.horizontal(),
+    },
+
+    layout = wibox.layout.align.horizontal,
+  }
+end)
+
+-- Enable sloppy focus, so that focus follows mouse.
+client.connect_signal("mouse::enter", function(c)
+  c:emit_signal("request::activate", "mouse_enter", { raise = false })
+end)
+
+client.connect_signal("focus", function(c)
+  c.border_color = beautiful.border_focus
+end)
+client.connect_signal("unfocus", function(c)
+  c.border_color = beautiful.border_normal
+end)
+-- }}}
+
+--- {{{ Show low battery notifications.
+gears.timer {
+  timeout = 60,
+  call_now = true,
+  autostart = true,
+  callback = function()
+    awful.spawn.easy_async([[cat /sys/class/power_supply/BAT0/capacity]], function(stdout0)
+      battery_capacity = tonumber(stdout0)
+
+      awful.spawn.easy_async([[cat /sys/class/power_supply/BAT0/status]], function(stdout1)
+        battery_status = stdout1:sub(1, -2)
+      end)
+
+      if battery_status == "Discharging" then
+        if battery_capacity <= 15 then
+          battery_notify = naughty.notify {
+            title = "Battery warning\n",
+            text = "Battery is lower than 15%.\n" .. battery_status .. " at " .. battery_capacity .. "%.",
+            timeout = 3,
+          }
+        end
+      end
+    end)
+  end,
+}
+-- }}}
+
+-- {{{ No DPMS for fullscreen clients
+local fullscreened_clients = {}
+
+local function remove_client(tabl, c)
+  local index = awful.util.table.hasitem(tabl, c)
+  if index then
+    table.remove(tabl, index)
+    if #tabl == 0 then
+      awful.util.spawn "xset s on"
+      awful.util.spawn "xset +dpms"
+    end
+  end
+end
+
+client.connect_signal("property::fullscreen", function(c)
+  if c.fullscreen then
+    table.insert(fullscreened_clients, c)
+    if #fullscreened_clients == 1 then
+      awful.util.spawn "xset s off"
+      awful.util.spawn "xset -dpms"
+    end
+  else
+    remove_client(fullscreened_clients, c)
+  end
+end)
+
+client.connect_signal("unmanage", function(c)
+  if c.fullscreen then
+    remove_client(fullscreened_clients, c)
+  end
+end)
+-- }}}
diff --git a/config/awesome/stylua.toml b/config/awesome/stylua.toml
new file mode 100644
index 00000000..2c7fb8a9
--- /dev/null
+++ b/config/awesome/stylua.toml
@@ -0,0 +1,8 @@
+indent_type = "Spaces"
+indent_width = 2
+line_endings = "Unix"
+no_call_parentheses = true
+quote_style = "AutoPreferDouble"
+
+[sort_requires]
+enabled = true
diff --git a/config/awesome/theme.lua b/config/awesome/theme.lua
new file mode 100644
index 00000000..669b8c28
--- /dev/null
+++ b/config/awesome/theme.lua
@@ -0,0 +1,125 @@
+---------------------------
+-- Default awesome theme --
+---------------------------
+
+local theme_assets = require "beautiful.theme_assets"
+local xresources = require "beautiful.xresources"
+local dpi = xresources.apply_dpi
+
+local gfs = require "gears.filesystem"
+local themes_path = gfs.get_themes_dir()
+
+local theme = {}
+
+theme.font = "sans 9"
+
+theme.bg_normal = "#222222"
+theme.bg_focus = "#535d6c"
+theme.bg_urgent = "#ff0000"
+theme.bg_minimize = "#444444"
+theme.bg_systray = theme.bg_normal
+
+theme.fg_normal = "#aaaaaa"
+theme.fg_focus = "#ffffff"
+theme.fg_urgent = "#ffffff"
+theme.fg_minimize = "#ffffff"
+
+theme.useless_gap = dpi(0)
+theme.border_width = dpi(1)
+theme.border_normal = "#000000"
+theme.border_focus = "#535d6c"
+theme.border_marked = "#91231c"
+
+-- There are other variable sets
+-- overriding the default one when
+-- defined, the sets are:
+-- taglist_[bg|fg]_[focus|urgent|occupied|empty|volatile]
+-- tasklist_[bg|fg]_[focus|urgent]
+-- titlebar_[bg|fg]_[normal|focus]
+-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
+-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
+-- prompt_[fg|bg|fg_cursor|bg_cursor|font]
+-- hotkeys_[bg|fg|border_width|border_color|shape|opacity|modifiers_fg|label_bg|label_fg|group_margin|font|description_font]
+-- Example:
+--theme.taglist_bg_focus = "#ff0000"
+
+-- Generate taglist squares:
+local taglist_square_size = dpi(4)
+theme.taglist_squares_sel = theme_assets.taglist_squares_sel(taglist_square_size, theme.fg_normal)
+theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(taglist_square_size, theme.fg_normal)
+
+-- Variables set for theming notifications:
+-- notification_font
+-- notification_[bg|fg]
+-- notification_[width|height|margin]
+-- notification_[border_color|border_width|shape|opacity]
+
+-- Variables set for theming the menu:
+-- menu_[bg|fg]_[normal|focus]
+-- menu_[border_color|border_width]
+theme.menu_submenu_icon = themes_path .. "default/submenu.png"
+theme.menu_height = dpi(15)
+theme.menu_width = dpi(100)
+
+-- You can add as many variables as
+-- you wish and access them by using
+-- beautiful.variable in your rc.lua
+--theme.bg_widget = "#cc0000"
+
+-- Define the image to load
+theme.titlebar_close_button_normal = themes_path .. "default/titlebar/close_normal.png"
+theme.titlebar_close_button_focus = themes_path .. "default/titlebar/close_focus.png"
+
+theme.titlebar_minimize_button_normal = themes_path .. "default/titlebar/minimize_normal.png"
+theme.titlebar_minimize_button_focus = themes_path .. "default/titlebar/minimize_focus.png"
+
+theme.titlebar_ontop_button_normal_inactive = themes_path .. "default/titlebar/ontop_normal_inactive.png"
+theme.titlebar_ontop_button_focus_inactive = themes_path .. "default/titlebar/ontop_focus_inactive.png"
+theme.titlebar_ontop_button_normal_active = themes_path .. "default/titlebar/ontop_normal_active.png"
+theme.titlebar_ontop_button_focus_active = themes_path .. "default/titlebar/ontop_focus_active.png"
+
+theme.titlebar_sticky_button_normal_inactive = themes_path .. "default/titlebar/sticky_normal_inactive.png"
+theme.titlebar_sticky_button_focus_inactive = themes_path .. "default/titlebar/sticky_focus_inactive.png"
+theme.titlebar_sticky_button_normal_active = themes_path .. "default/titlebar/sticky_normal_active.png"
+theme.titlebar_sticky_button_focus_active = themes_path .. "default/titlebar/sticky_focus_active.png"
+
+theme.titlebar_floating_button_normal_inactive = themes_path .. "default/titlebar/floating_normal_inactive.png"
+theme.titlebar_floating_button_focus_inactive = themes_path .. "default/titlebar/floating_focus_inactive.png"
+theme.titlebar_floating_button_normal_active = themes_path .. "default/titlebar/floating_normal_active.png"
+theme.titlebar_floating_button_focus_active = themes_path .. "default/titlebar/floating_focus_active.png"
+
+theme.titlebar_maximized_button_normal_inactive = themes_path .. "default/titlebar/maximized_normal_inactive.png"
+theme.titlebar_maximized_button_focus_inactive = themes_path .. "default/titlebar/maximized_focus_inactive.png"
+theme.titlebar_maximized_button_normal_active = themes_path .. "default/titlebar/maximized_normal_active.png"
+theme.titlebar_maximized_button_focus_active = themes_path .. "default/titlebar/maximized_focus_active.png"
+
+-- theme.wallpaper = themes_path .. "default/background.png"
+
+-- You can use your own layout icons like this:
+theme.layout_fairh = themes_path .. "default/layouts/fairhw.png"
+theme.layout_fairv = themes_path .. "default/layouts/fairvw.png"
+theme.layout_floating = themes_path .. "default/layouts/floatingw.png"
+theme.layout_magnifier = themes_path .. "default/layouts/magnifierw.png"
+theme.layout_max = themes_path .. "default/layouts/maxw.png"
+theme.layout_fullscreen = themes_path .. "default/layouts/fullscreenw.png"
+theme.layout_tilebottom = themes_path .. "default/layouts/tilebottomw.png"
+theme.layout_tileleft = themes_path .. "default/layouts/tileleftw.png"
+theme.layout_tile = themes_path .. "default/layouts/tilew.png"
+theme.layout_tiletop = themes_path .. "default/layouts/tiletopw.png"
+theme.layout_spiral = themes_path .. "default/layouts/spiralw.png"
+theme.layout_dwindle = themes_path .. "default/layouts/dwindlew.png"
+theme.layout_cornernw = themes_path .. "default/layouts/cornernww.png"
+theme.layout_cornerne = themes_path .. "default/layouts/cornernew.png"
+theme.layout_cornersw = themes_path .. "default/layouts/cornersww.png"
+theme.layout_cornerse = themes_path .. "default/layouts/cornersew.png"
+
+-- Generate Awesome icon:
+theme.awesome_icon = theme_assets.awesome_icon(theme.menu_height, theme.bg_focus, theme.fg_focus)
+
+-- Define the icon theme for application icons. If not set then the icons
+-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
+theme.icon_theme = nil
+
+return theme
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/config/awesome/widgets/battery.lua b/config/awesome/widgets/battery.lua
new file mode 100644
index 00000000..74fb7f36
--- /dev/null
+++ b/config/awesome/widgets/battery.lua
@@ -0,0 +1,50 @@
+-------------------------------------------------
+-- Battery widget
+-------------------------------------------------
+
+local awful = require "awful"
+local gears = require "gears"
+local wibox = require "wibox"
+
+local text = wibox.widget {
+  font = "Hack 11",
+  widget = wibox.widget.textbox,
+}
+
+local widget = wibox.widget.background()
+widget:set_widget(text)
+
+gears.timer {
+  timeout = 20,
+  autostart = true,
+  call_now = true,
+  callback = function()
+    awful.spawn.easy_async_with_shell("cat /sys/class/power_supply/BAT*/uevent", function(out)
+      local capacity_raw = string.match(out, "POWER_SUPPLY_CAPACITY=%d*")
+      local capacity = string.sub(string.match(capacity_raw, "=%d*"), 2)
+
+      if tonumber(capacity) ~= 100 then
+        local status_raw = string.match(out, "POWER_SUPPLY_STATUS=%u")
+        local status_stripped = string.match(status_raw, "=%u")
+        local status_letter = string.match(status_stripped, "%u"):lower()
+
+        text:set_text("ba:" .. capacity .. status_letter)
+
+        local not_charging = status_letter == "d"
+        local is_bat_low = tonumber(capacity) < 21
+        local color = "#d2d4de"
+
+        if not_charging and is_bat_low then
+          color = "#e27878"
+        end
+
+        widget:set_fg(color)
+      else
+        text:set_text "ba:full"
+        widget:set_fg "#b4be82"
+      end
+    end)
+  end,
+}
+
+return widget
diff --git a/flake.nix b/flake.nix
index 0c4adcc5..07089b59 100644
--- a/flake.nix
+++ b/flake.nix
@@ -25,7 +25,14 @@
 
       username = "opdavies";
 
-      mkNixos = import ./lib/nixos { inherit inputs self username; };
+      mkNixos = import ./lib/nixos {
+        inherit
+          inputs
+          pkgs
+          self
+          username
+          ;
+      };
       mkWsl = import ./lib/wsl2 { inherit inputs self username; };
 
       inherit (pkgs) mkShell;
diff --git a/lib/nixos/default.nix b/lib/nixos/default.nix
index 17f875d8..842004bc 100644
--- a/lib/nixos/default.nix
+++ b/lib/nixos/default.nix
@@ -1,5 +1,6 @@
 {
   inputs,
+  pkgs,
   self,
   username,
 }:
@@ -37,7 +38,14 @@ inputs.nixpkgs.lib.nixosSystem {
       };
     }
 
-    (import ./modules/awesome.nix)
+    (import ./modules/awesome.nix {
+      inherit
+        inputs
+        pkgs
+        self
+        username
+        ;
+    })
     (import ./modules/gnome.nix)
     # (import ./modules/sway.nix { inherit inputs username; })
 
diff --git a/lib/nixos/home-manager/desktop.nix b/lib/nixos/home-manager/desktop.nix
index 5d301971..123ba1b5 100644
--- a/lib/nixos/home-manager/desktop.nix
+++ b/lib/nixos/home-manager/desktop.nix
@@ -8,7 +8,7 @@
   imports = [
     ./modules/alacritty.nix
     ./modules/autorandr.nix
-    ./modules/awesome.nix
+    # ./modules/awesome.nix
     ./modules/copyq.nix
     ./modules/dunst.nix
     ./modules/espanso.nix
diff --git a/lib/nixos/home-manager/modules/awesome.nix b/lib/nixos/home-manager/modules/awesome.nix
deleted file mode 100644
index eb470a9f..00000000
--- a/lib/nixos/home-manager/modules/awesome.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  xsession.windowManager.awesome = {
-    enable = true;
-    noArgb = true;
-  };
-}
diff --git a/lib/nixos/modules/awesome.nix b/lib/nixos/modules/awesome.nix
index 6f82ce12..005b4ef4 100644
--- a/lib/nixos/modules/awesome.nix
+++ b/lib/nixos/modules/awesome.nix
@@ -1,9 +1,35 @@
-{ pkgs, ... }:
 {
-  environment.systemPackages = with pkgs; [ nitrogen ];
+  pkgs,
+  self,
+  username,
+  ...
+}:
+
+let
+  inherit (pkgs) writeShellScriptBin;
+
+  script-autostart = writeShellScriptBin "awesome-autostart" ''
+    set -o errexit
+
+    ${pkgs.nitrogen}/bin/nitrogen --set-zoom-fill --random "''${HOME}/Pictures/Wallpaper"
+  '';
+in
+{
+  environment.systemPackages = with pkgs; [
+    script-autostart
+
+    nitrogen
+  ];
 
   services.xserver.windowManager.awesome = {
     enable = true;
     noArgb = true;
   };
+
+  home-manager.users.${username} = {
+    xdg.configFile.awesome = {
+      source = "${self}/config/awesome";
+      recursive = true;
+    };
+  };
 }