diff --git a/src/browser.zig b/src/browser.zig
index 4f450f8cb4a25113920db6dc08613309e4b5bf27..469bc8c7e2f3ab4641f9d81ccd604cd09daadd94 100644
--- a/src/browser.zig
+++ b/src/browser.zig
@@ -85,8 +85,8 @@ fn sortLt(_: void, ap: ?*model.Entry, bp: ?*model.Entry) bool {
             if (sortIntLt(a.blocks, b.blocks)) |r| return r;
         },
         .items => {
-            const ai = if (a.dir()) |d| d.total_items else 0;
-            const bi = if (b.dir()) |d| d.total_items else 0;
+            const ai = if (a.dir()) |d| d.items else 0;
+            const bi = if (b.dir()) |d| d.items else 0;
             if (sortIntLt(ai, bi)) |r| return r;
             if (sortIntLt(a.blocks, b.blocks)) |r| return r;
             if (sortIntLt(a.size, b.size)) |r| return r;
@@ -208,11 +208,15 @@ const Row = struct {
         }
         if (main.config.show_graph == .both) ui.addch(' ');
         if (main.config.show_graph == .both or main.config.show_graph == .graph) {
-            const perblock = std.math.divCeil(u64, if (main.config.show_blocks) dir_max_blocks else dir_max_size, bar_size) catch unreachable;
+            const perblock = std.math.divFloor(u64, if (main.config.show_blocks) dir_max_blocks else dir_max_size, bar_size) catch unreachable;
             const num = if (main.config.show_blocks) item.blocks else item.size;
             var i: u32 = 0;
+            var siz: u64 = 0;
             self.bg.fg(.graph);
-            while (i < bar_size) : (i += 1) ui.addch(if (i*perblock <= num) '#' else ' ');
+            while (i < bar_size) : (i += 1) {
+                siz = saturateAdd(siz, perblock);
+                ui.addch(if (siz <= num) '#' else ' ');
+            }
         }
         self.bg.fg(.default);
         ui.addch(']');
@@ -221,14 +225,16 @@ const Row = struct {
     fn items(self: *Self) void {
         if (!main.config.show_items) return;
         defer self.col += 7;
-        const d = if (self.item) |d| d.dir() orelse return else return;
-        const n = d.total_items;
+        const n = (if (self.item) |d| d.dir() orelse return else return).items;
         ui.move(self.row, self.col);
         self.bg.fg(.num);
         if (n < 1000)
             ui.addprint("  {d:>4}", .{n})
-        else if (n < 100_000)
-            ui.addprint("{d:>6.3}", .{ @intToFloat(f32, n) / 1000 })
+        else if (n < 10_000) {
+            ui.addch(' ');
+            ui.addnum(self.bg, n);
+        } else if (n < 100_000)
+            ui.addnum(self.bg, n)
         else if (n < 1000_000) {
             ui.addprint("{d:>5.1}", .{ @intToFloat(f32, n) / 1000 });
             self.bg.fg(.default);
@@ -360,18 +366,20 @@ pub fn draw() !void {
     ui.move(ui.rows-1, 0);
     ui.hline(' ', ui.cols);
     ui.move(ui.rows-1, 1);
+    ui.style(if (main.config.show_blocks) .bold_hd else .hd);
     ui.addstr("Total disk usage: ");
     ui.addsize(.hd, blocksToSize(dir_parents.top().entry.blocks));
+    ui.style(if (main.config.show_blocks) .hd else .bold_hd);
     ui.addstr("  Apparent size: ");
     ui.addsize(.hd, dir_parents.top().entry.size);
     ui.addstr("  Items: ");
-    ui.addnum(.hd, dir_parents.top().total_items);
+    ui.addnum(.hd, dir_parents.top().items);
 
     if (need_confirm_quit) drawQuit();
     if (sel_row > 0) ui.move(sel_row, 0);
 }
 
-fn sortToggle(col: main.SortCol, default_order: main.SortOrder) void {
+fn sortToggle(col: main.config.SortCol, default_order: main.config.SortOrder) void {
     if (main.config.sort_col != col) main.config.sort_order = default_order
     else if (main.config.sort_order == .asc) main.config.sort_order = .desc
     else main.config.sort_order = .asc;
diff --git a/src/main.zig b/src/main.zig
index b34a59236c6e4c4f46884bb7145ddcde552f687f..573b9318329ae08125849dafb8c77caaaf82b24a 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -9,40 +9,38 @@ const c = @cImport(@cInclude("locale.h"));
 
 pub const allocator = std.heap.c_allocator;
 
-pub const SortCol = enum { name, blocks, size, items, mtime };
-pub const SortOrder = enum { asc, desc };
-
-pub const Config = struct {
-    same_fs: bool = true,
-    extended: bool = false,
-    follow_symlinks: bool = false,
-    exclude_caches: bool = false,
-    exclude_kernfs: bool = false,
-    exclude_patterns: std.ArrayList([:0]const u8) = std.ArrayList([:0]const u8).init(allocator),
-
-    update_delay: u64 = 100*std.time.ns_per_ms,
-    scan_ui: enum { none, line, full } = .full,
-    si: bool = false,
-    nc_tty: bool = false,
-    ui_color: enum { off, dark } = .off,
-    thousands_sep: []const u8 = ".",
-
-    show_hidden: bool = true,
-    show_blocks: bool = true,
-    show_items: bool = false,
-    show_mtime: bool = false,
-    show_graph: enum { off, graph, percent, both } = .graph,
-    sort_col: SortCol = .blocks,
-    sort_order: SortOrder = .desc,
-    sort_dirsfirst: bool = false,
-
-    read_only: bool = false,
-    can_shell: bool = true,
-    confirm_quit: bool = false,
+pub const config = struct {
+    pub const SortCol = enum { name, blocks, size, items, mtime };
+    pub const SortOrder = enum { asc, desc };
+
+    pub var same_fs: bool = true;
+    pub var extended: bool = false;
+    pub var follow_symlinks: bool = false;
+    pub var exclude_caches: bool = false;
+    pub var exclude_kernfs: bool = false;
+    pub var exclude_patterns: std.ArrayList([:0]const u8) = std.ArrayList([:0]const u8).init(allocator);
+
+    pub var update_delay: u64 = 100*std.time.ns_per_ms;
+    pub var scan_ui: enum { none, line, full } = .full;
+    pub var si: bool = false;
+    pub var nc_tty: bool = false;
+    pub var ui_color: enum { off, dark } = .off;
+    pub var thousands_sep: []const u8 = ",";
+
+    pub var show_hidden: bool = true;
+    pub var show_blocks: bool = true;
+    pub var show_items: bool = false;
+    pub var show_mtime: bool = false;
+    pub var show_graph: enum { off, graph, percent, both } = .graph;
+    pub var sort_col: SortCol = .blocks;
+    pub var sort_order: SortOrder = .desc;
+    pub var sort_dirsfirst: bool = false;
+
+    pub var read_only: bool = false;
+    pub var can_shell: bool = true;
+    pub var confirm_quit: bool = false;
 };
 
-pub var config = Config{};
-
 pub var state: enum { scan, browse } = .browse;
 
 // Simple generic argument parser, supports getopt_long() style arguments.
@@ -298,30 +296,30 @@ test "argument parser" {
     const l = L{ .lst = &lst };
     const T = struct {
         a: Args(L),
-        fn opt(self: *@This(), isopt: bool, val: []const u8) void {
+        fn opt(self: *@This(), isopt: bool, val: []const u8) !void {
             const o = self.a.next().?;
-            std.testing.expectEqual(isopt, o.opt);
-            std.testing.expectEqualStrings(val, o.val);
-            std.testing.expectEqual(o.is(val), isopt);
+            try std.testing.expectEqual(isopt, o.opt);
+            try std.testing.expectEqualStrings(val, o.val);
+            try std.testing.expectEqual(o.is(val), isopt);
         }
-        fn arg(self: *@This(), val: []const u8) void {
-            std.testing.expectEqualStrings(val, self.a.arg());
+        fn arg(self: *@This(), val: []const u8) !void {
+            try std.testing.expectEqualStrings(val, self.a.arg());
         }
     };
     var t = T{ .a = Args(L).init(l) };
-    t.opt(false, "a");
-    t.opt(true, "-a");
-    t.opt(true, "-b");
-    t.arg("cd=e");
-    t.opt(true, "--opt1");
-    t.arg("arg1");
-    t.opt(true, "--opt2");
-    t.arg("arg2");
-    t.opt(true, "-x");
-    t.arg("foo");
-    t.opt(false, "");
-    t.opt(false, "--arg");
-    t.opt(false, "");
-    t.opt(false, "-");
-    std.testing.expectEqual(t.a.next(), null);
+    try t.opt(false, "a");
+    try t.opt(true, "-a");
+    try t.opt(true, "-b");
+    try t.arg("cd=e");
+    try t.opt(true, "--opt1");
+    try t.arg("arg1");
+    try t.opt(true, "--opt2");
+    try t.arg("arg2");
+    try t.opt(true, "-x");
+    try t.arg("foo");
+    try t.opt(false, "");
+    try t.opt(false, "--arg");
+    try t.opt(false, "");
+    try t.opt(false, "-");
+    try std.testing.expectEqual(t.a.next(), null);
 }
diff --git a/src/model.zig b/src/model.zig
index c5ea1ceab0d4ad122ca48daa04cf3ce418295728..31474cfc343c4292756e8ce1e7eb3bf25e812338 100644
--- a/src/model.zig
+++ b/src/model.zig
@@ -113,6 +113,7 @@ pub const Entry = packed struct {
             if (self.ext()) |e|
                 if (p.entry.ext()) |pe|
                     if (e.mtime > pe.mtime) { pe.mtime = e.mtime; };
+            p.items = saturateAdd(p.items, 1);
 
             // Hardlink in a subdirectory with a different device, only count it the first time.
             if (self.link() != null and dev != p.dev) {
@@ -128,12 +129,10 @@ pub const Entry = packed struct {
                     add_total = true;
                     p.shared_size = saturateAdd(p.shared_size, self.size);
                     p.shared_blocks = saturateAdd(p.shared_blocks, self.blocks);
-                    p.shared_items = saturateAdd(p.shared_items, 1);
                 // Encountered this file in this dir the same number of times as its link count, meaning it's not shared with other dirs.
                 } else if(d.entry.key.num_files == l.nlink) {
                     p.shared_size = saturateSub(p.shared_size, self.size);
                     p.shared_blocks = saturateSub(p.shared_blocks, self.blocks);
-                    p.shared_items = saturateSub(p.shared_items, 1);
                 }
             } else {
                 add_total = true;
@@ -141,7 +140,6 @@ pub const Entry = packed struct {
             if(add_total) {
                 p.entry.size = saturateAdd(p.entry.size, self.size);
                 p.entry.blocks = saturateAdd(p.entry.blocks, self.blocks);
-                p.total_items = saturateAdd(p.total_items, 1);
             }
         }
     }
@@ -161,10 +159,7 @@ pub const Dir = packed struct {
     // (space reclaimed by deleting a dir =~ entry. - shared_)
     shared_blocks: u64,
     shared_size: u64,
-    shared_items: u32,
-    total_items: u32,
-    // TODO: ncdu1 only keeps track of a total item count including duplicate hardlinks.
-    // That number seems useful, too. Include it somehow?
+    items: u32,
 
     // Indexes into the global 'devices' array
     dev: DevId,
diff --git a/src/ui.zig b/src/ui.zig
index c56e7be5f38a83561e7c85c9c4303aacdc86ed1a..73183f2b49743777c74dd1dd3101ff972da5618f 100644
--- a/src/ui.zig
+++ b/src/ui.zig
@@ -118,25 +118,25 @@ pub fn shorten(in: [:0]const u8, max_width: u32) ![:0] const u8 {
     return try arrayListBufZ(&shorten_buf);
 }
 
-fn shortenTest(in: [:0]const u8, max_width: u32, out: [:0]const u8) void {
-    std.testing.expectEqualStrings(out, shorten(in, max_width) catch unreachable);
+fn shortenTest(in: [:0]const u8, max_width: u32, out: [:0]const u8) !void {
+    try std.testing.expectEqualStrings(out, try shorten(in, max_width));
 }
 
 test "shorten" {
     _ = c.setlocale(c.LC_ALL, ""); // libc wcwidth() may not recognize Unicode without this
     const t = shortenTest;
-    t("abcde", 3, "...");
-    t("abcde", 5, "abcde");
-    t("abcde", 4, "...e");
-    t("abcdefgh", 6, "a...gh");
-    t("abcdefgh", 7, "ab...gh");
-    t("ABCDEFGH", 16, "ABCDEFGH");
-    t("ABCDEFGH", 7, "A...H");
-    t("ABCDEFGH", 8, "A...H");
-    t("ABCDEFGH", 9, "A...GH");
-    t("AaBCDEFGH", 8, "A...H"); // could optimize this, but w/e
-    t("ABCDEFGaH", 8, "A...aH");
-    t("ABCDEFGH", 15, "ABC...FGH");
+    try t("abcde", 3, "...");
+    try t("abcde", 5, "abcde");
+    try t("abcde", 4, "...e");
+    try t("abcdefgh", 6, "a...gh");
+    try t("abcdefgh", 7, "ab...gh");
+    try t("ABCDEFGH", 16, "ABCDEFGH");
+    try t("ABCDEFGH", 7, "A...H");
+    try t("ABCDEFGH", 8, "A...H");
+    try t("ABCDEFGH", 9, "A...GH");
+    try t("AaBCDEFGH", 8, "A...H"); // could optimize this, but w/e
+    try t("ABCDEFGaH", 8, "A...aH");
+    try t("ABCDEFGH", 15, "ABC...FGH");
 }
 
 // ncurses_refs.c
@@ -167,6 +167,9 @@ const styles = [_]StyleDef{
     .{  .name = "bold",
         .off  = .{ .fg = -1,              .bg = -1,             .attr = c.A_BOLD },
         .dark = .{ .fg = -1,              .bg = -1,             .attr = c.A_BOLD } },
+    .{  .name = "bold_hd",
+        .off  = .{ .fg = -1,              .bg = -1,             .attr = c.A_BOLD|c.A_REVERSE },
+        .dark = .{ .fg = c.COLOR_BLACK,   .bg = c.COLOR_CYAN,   .attr = c.A_BOLD } },
     .{  .name = "box_title",
         .off  = .{ .fg = -1,              .bg = -1,             .attr = c.A_BOLD },
         .dark = .{ .fg = c.COLOR_BLUE,    .bg = -1,             .attr = c.A_BOLD } },