diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -182,6 +182,8 @@
 - `filesdir`: list of directories containing static files (default: `files`)
 - `layout`: the default layout template for the site, relative to
   `sourcedir` (default: `layout.html.st`)
+- `navstyle`: either `top` for a top menu or `side` for a side
+  menu
 
 The directories specified by `sourcedir` and `datadir` are searched in
 order to find source/template or data files, respectively.  This allows
diff --git a/Yst/Config.hs b/Yst/Config.hs
--- a/Yst/Config.hs
+++ b/Yst/Config.hs
@@ -41,6 +41,10 @@
                     , indexFile     = indexfile
                     , pageIndex     = M.fromList $ map (\pg -> (pageUrl pg, pg)) ind
                     , navigation    = nav
+                    , navstyle      =
+                         case getStrAttrWithDefault "navstyle" "top" xs of
+                              "side"  -> SideNav
+                              _       -> TopNav
                     }
        _       -> errorExit 7 "Configuration file must be a YAML hash." >> return undefined
 
diff --git a/Yst/Render.hs b/Yst/Render.hs
--- a/Yst/Render.hs
+++ b/Yst/Render.hs
@@ -43,6 +43,7 @@
 import Data.Time
 import Control.Monad
 import Text.Pandoc.Error (handleError)
+import Data.Monoid
 
 -- | @relUrl a b@ returns a URL for @b@ relative to @a@.  So, for
 -- example, @relUrl "a" "a/b.html" = "b.html"@,
@@ -68,18 +69,36 @@
 dropCommon (x:xs) (y:ys) | x == y = dropCommon xs ys
 dropCommon xs ys = (xs,ys)
 
-renderNav :: String -> [NavNode] -> String
-renderNav targeturl nodes = TL.unpack $ renderText $
-  ul_ [class_ "nav navbar-nav"] $ mapM_ (renderNavNode targeturl) nodes
+renderNav :: NavStyle -> String -> [NavNode] -> String
+renderNav sty targeturl nodes = TL.unpack $ renderText $
+  ul_ [class_ classes] $ mapM_ (renderNavNode sty targeturl) nodes
+  where classes = case sty of
+                       TopNav -> "nav navbar-nav"
+                       SideNav -> "nav nav-pills nav-stacked"
 
-renderNavNode :: String -> NavNode -> Html ()
-renderNavNode targeturl (NavPage tit pageurl) =
-  li_ [class_ "active" | pageurl == targeturl] (a_ [href_ pageurl'] (toHtml tit))
+renderNavNode :: NavStyle -> String -> NavNode -> Html ()
+renderNavNode _ targeturl (NavPage tit pageurl) =
+  li_ [class_ "active" | pageurl == targeturl]
+   (a_ [href_ pageurl'] (toHtml tit))
     where targetdir = takeUrlDir targeturl
           pageurl' = T.pack $ relUrl targetdir pageurl
-renderNavNode targeturl (NavMenu tit nodes) = li_ [] $
+renderNavNode TopNav targeturl (NavMenu tit nodes) = li_ [] $
     do a_ [class_ "dropdown-toggle", data_ "toggle" "dropdown"] (toHtml tit)
-       ul_ [class_ "dropdown-menu"] (mapM_ (renderNavNode targeturl) nodes)
+       ul_ [class_ "dropdown-menu"]
+         (mapM_ (renderNavNode TopNav targeturl) nodes)
+renderNavNode SideNav targeturl node@(NavMenu tit nodes) = li_ [] $
+    do a_ [id_ buttonId,
+           class_ "submenu collapsed", data_ "toggle" "collapse",
+           data_ "target" ("#" <> submenuId)]
+           (toHtml tit)
+       ul_ [id_ submenuId,
+            class_ ("nav collapse" <> if expanded then " in" else "")]
+           (mapM_ (renderNavNode SideNav targeturl) nodes)
+    where submenuId = T.replace " " "_" $ T.pack ("menu-" ++ tit)
+          buttonId = T.replace " " "_" $ T.pack ("menu-label-" ++ tit)
+          expanded = targeturl `elem` (getUrls node)
+          getUrls (NavPage _ u) = [u]
+          getUrls (NavMenu _ ns) = concatMap getUrls ns
 
 formatFromExtension :: FilePath -> Format
 formatFromExtension f = case (map toLower $ takeExtension f) of
@@ -99,7 +118,7 @@
 
 renderPage :: Site -> Page -> IO String
 renderPage site page = do
-  let menuHtml = renderNav (pageUrl page) (navigation site)
+  let menuHtml = renderNav (navstyle site) (pageUrl page) (navigation site)
   let layout = fromMaybe (defaultLayout site) $ layoutFile page
   srcDirs <- mapM canonicalizePath $ sourceDir site
   gs <- mapM directoryGroupRecursive srcDirs
diff --git a/Yst/Types.hs b/Yst/Types.hs
--- a/Yst/Types.hs
+++ b/Yst/Types.hs
@@ -45,7 +45,11 @@
   , indexFile     :: FilePath
   , pageIndex     :: M.Map String Page
   , navigation    :: [NavNode]
+  , navstyle      :: NavStyle
   } deriving (Show, Read, Eq)
+
+data NavStyle = TopNav | SideNav
+  deriving (Show, Read, Eq)
 
 data Source = TemplateFile FilePath
             | SourceFile FilePath
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,12 @@
+yst 0.7 (released 07 Mar 2018)
+
+  * Added NavStyle type.
+  * Added navstyle field to Site.
+  * Added navstyle parameter to config.yaml (values `top` or `side`).
+    This controls the CSS used for the menu.  Top is default as
+    before.
+  * Removed old js/nav.js and css/hk-pyg.css from the demo site.
+
 yst 0.6.0.1 (released 20 Feb 2018)
 
   * Update to work with pandoc 2.1.
diff --git a/demo/files/css/hk-pyg.css b/demo/files/css/hk-pyg.css
deleted file mode 100644
--- a/demo/files/css/hk-pyg.css
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Loosely based on pygment's default colors */
-table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre 
-   { margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
-td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; } 
-td.sourceCode { padding-left: 5px; }
-pre.sourceCode { }
-pre.sourceCode span.kw { color: #007020; font-weight: bold; } 
-pre.sourceCode span.dt { color: #902000; }
-pre.sourceCode span.dv { color: #40a070; }
-pre.sourceCode span.bn { color: #40a070; }
-pre.sourceCode span.fl { color: #40a070; }
-pre.sourceCode span.ch { color: #4070a0; }
-pre.sourceCode span.st { color: #4070a0; }
-pre.sourceCode span.co { color: #60a0b0; font-style: italic; }
-pre.sourceCode span.ot { color: #007020; }
-pre.sourceCode span.al { color: red; font-weight: bold; }
-pre.sourceCode span.fu { color: #06287e; }
-pre.sourceCode span.re { }
-pre.sourceCode span.er { color: red; font-weight: bold; }
diff --git a/demo/files/css/screen.css b/demo/files/css/screen.css
--- a/demo/files/css/screen.css
+++ b/demo/files/css/screen.css
@@ -1,5 +1,3 @@
-@import url("hk-pyg.css");
-
 body { padding-top: 60px;       /* make room for top-fixed navbar */
       font-size: 14pt;
       line-height: 1.4em; }
diff --git a/demo/files/js/nav.js b/demo/files/js/nav.js
deleted file mode 100644
--- a/demo/files/js/nav.js
+++ /dev/null
@@ -1,8 +0,0 @@
-$(document).ready(function(){
-  $('.tree-toggle').click(function () {
-    $(this).parent().children('ul.tree').toggle(200);
-  });
-  $('.tree-toggle').each(function () {
-    $(this).parent().children('ul.tree').toggle(0);
-  });
-});
diff --git a/demo/layout.html.st b/demo/layout.html.st
--- a/demo/layout.html.st
+++ b/demo/layout.html.st
@@ -17,7 +17,6 @@
             type="text/javascript"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
 
-    <script src="$root$js/nav.js" type="text/javascript"></script>
     <link rel="stylesheet" type="text/css" href="$root$css/screen.css" />
     <link rel="stylesheet" type="text/css" media="print" href="$root$css/print.css" />
   </head>
diff --git a/yst.cabal b/yst.cabal
--- a/yst.cabal
+++ b/yst.cabal
@@ -1,5 +1,5 @@
 name:                yst
-version:             0.6.0.1
+version:             0.7
 Tested-With:         GHC == 7.8.3
 Cabal-version:       >= 1.8
 build-type:          Simple
@@ -36,8 +36,6 @@
                      demo/layout.tex.st
                      demo/room101.txt
                      demo/room203.txt
-                     demo/files/js/nav.js
-                     demo/files/css/hk-pyg.css
                      demo/files/css/print.css
                      demo/files/css/screen.css
 
