diff --git a/Nomyx-Web.cabal b/Nomyx-Web.cabal
--- a/Nomyx-Web.cabal
+++ b/Nomyx-Web.cabal
@@ -1,5 +1,5 @@
 name: Nomyx-Web
-version: 0.7.4
+version: 0.7.5
 cabal-version: >=1.6
 build-type: Simple
 license: BSD3
@@ -16,8 +16,8 @@
 extra-source-files: README.md
  
 library
-    build-depends: Nomyx-Language         == 0.7.4,
-                   Nomyx-Core             == 0.7.4,
+    build-depends: Nomyx-Language         == 0.7.5,
+                   Nomyx-Core             == 0.7.5,
                    base                   >= 4.6 && <5,
                    blaze-html             == 0.7.*,
                    blaze-markup           == 0.6.*,
diff --git a/data/static/css/nomyx.css b/data/static/css/nomyx.css
--- a/data/static/css/nomyx.css
+++ b/data/static/css/nomyx.css
@@ -1,5 +1,7 @@
 h3{
-   color:#04B404;
+   color:#4D6A8A;
+   font-size: 18;
+   margin-top: 5pt;
 }
 
 #gameList {
@@ -91,8 +93,9 @@
    background-color:#F4F4F4;
    border:1px solid black;
    padding:10px;
-   width:98%;
+   width:97%;
    margin-bottom:5px;
+   margin-left:3px;
 }
 
 #showCodeLink {
@@ -112,18 +115,16 @@
    cursor: pointer;
 }
 
+.showHide {
+   position: absolute;
+   right: 15px;
+}
+
 #header {
-   border-top:1px solid silver;
-   border-bottom:1px solid silver;
-   margin-top:10px;
-   margin-bottom:10px;
-   color:gray;
-   padding-top:10px;
-   padding-bottom:5px;
-   background-color:#F4F4F4;
-   top:0;
-   position:relative;
-   width:100%;
+   background: #F4F4F4 url(/static/pictures/header-bg.jpg) repeat-x;
+   height:30pt;
+   opacity:0.7;
+   font:
 }
 
 #footer {
@@ -297,3 +298,9 @@
    padding-right: 20pt;
 }
 
+#headerTitle {
+   color: white;
+   font-size: 18;
+   font-family: verdana;
+   font-weight: bold;
+}
diff --git a/data/static/nomyx.js b/data/static/nomyx.js
--- a/data/static/nomyx.js
+++ b/data/static/nomyx.js
@@ -1,42 +1,99 @@
 function toggle_visibility(id_events, id_show) 
-{ 
+{
    var events = document.getElementById(id_events);
    var show = document.getElementById(id_show);
-   if (show.innerHTML == '[Click to show]') 
+   if (show.innerHTML == 'Click to show') 
    {
       events.style.display = 'block'; 
-      show.innerHTML = '[Click to hide]';
+      show.innerHTML = 'Click to hide';
    }
    else   
    {
       events.style.display = 'none'; 
-      show.innerHTML ='[Click to show]';
+      show.innerHTML ='Click to show';
    }
 }
 
 //toggle visibility for overlapping divs
 //all elements with the class name will be pushed back, 
 //while only the element with the id name is put on front
-function div_visibility(id_box, class_box, id_button, class_button)
+function divBoxvisibility(idDiv, classDiv, idButton, classButton)
 {
    //push back every divs
-   var boxes = document.getElementsByClassName(class_box);
+   var boxes = document.getElementsByClassName(classDiv);
    for (i = 0; i < boxes.length; i++) {
       boxes[i].style.display = 'none';
    }
 
    //pull front our div
-   var myBox = document.getElementById(id_box);
+   var myBox = document.getElementById(idDiv);
    myBox.style.display = 'inline';
 
    //unbold the text in the buttons
-   var buttons = document.getElementsByClassName(class_button);
+   var buttons = document.getElementsByClassName(classButton);
    for (i = 0; i < buttons.length; i++) {
       buttons[i].style.fontWeight = 'normal';
    }
 
    //pull front our div
-   var myButton = document.getElementById(id_button);
+   var myButton = document.getElementById(idButton);
    myButton.style.fontWeight = 'bold';
 
 }
+
+//function setDivVisibility(gn, divId, divClass) {
+function setDivVisibility(groupName, elementName) {
+
+   var idDiv       = elementName + "Div";
+   var classDiv    = groupName   + "Div";
+   var idButton    = elementName + "Button";
+   var classButton = groupName   + "Button";
+
+   divBoxvisibility(idDiv, classDiv, idButton, classButton);
+}
+
+function setDivVisibilityAndSave(groupName, elementName) {
+
+   setDivVisibility(groupName, elementName);
+   setCookie("divVis" + groupName, elementName);
+
+   console.log("saving div visibility: " + groupName + "=" + elementName);
+}
+
+function loadDivVisibility() {
+
+   console.log("loadDivVisibility");
+
+   cookies = getCookies("divVis");
+
+   console.log("loadDivVisibility:" + cookies);
+   for(var i=0; i<cookies.length; i++) {
+      element = cookies[i];
+      group = cookies[i].split('-')[0];
+      console.log("setting visibility: group = " + group + " element = " + element);
+      setDivVisibility(group, element);
+      
+   }
+}
+
+function setCookie(cname, cvalue) {
+    var d = new Date();
+    d.setTime(d.getTime() + (365*24*60*60*1000));
+    var expires = "expires="+d.toUTCString();
+    document.cookie = cname + "=" + encodeURIComponent(cvalue) + "; " + expires;
+} 
+
+function getCookies(cname) {
+
+    var allCookies = document.cookie.split(';');
+    console.log("getCookies:" + allCookies);
+    var results = [];
+    for(var i=0; i<allCookies.length; i++) {
+        nameValue = allCookies[i].split('=');
+        console.log("getCookies: nameValue[0]=" + nameValue[0] + " nameValue[1]=" + nameValue[1]);
+        if (nameValue[0].search(cname) != -1) {
+           results.push(nameValue[1]);
+        }
+    }
+    return results;
+} 
diff --git a/data/static/pictures/header-bg.jpg b/data/static/pictures/header-bg.jpg
new file mode 100644
Binary files /dev/null and b/data/static/pictures/header-bg.jpg differ
diff --git a/src/Nomyx/Web/Common.hs b/src/Nomyx/Web/Common.hs
--- a/src/Nomyx/Web/Common.hs
+++ b/src/Nomyx/Web/Common.hs
@@ -8,6 +8,7 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GADTs #-}
+{-# LANGUAGE ExtendedDefaultRules #-}
 
 module Nomyx.Web.Common where
 
@@ -159,19 +160,14 @@
       H.meta ! A.httpEquiv "Content-Type" ! content "text/html;charset=utf-8"
       H.meta ! A.name "keywords" ! A.content "Nomyx, game, rules, Haskell, auto-reference"
       H.script ! A.type_ "text/JavaScript" ! A.src "/static/nomyx.js" $ ""
-   H.body $ H.div ! A.id "container" $ do
+   H.body ! onload "loadDivVisibility()" $ H.div ! A.id "container" $ do
       H.div ! A.id "header" $ table ! width "100%" $ tr $ do
-         td headers
+         td (p headers ! A.id "headerTitle")
          when (isJust link) $ td ! A.style "text-align:right;" $ H.a "Back to main page" ! (href $ toValue $ fromJust link)
       body
       when footer $ H.div ! A.id "footer" $ "Copyright Corentin Dupont 2012-2013"
 
-appTemplate ::
-    ( Monad m)
-    => String -- ^ title
-    -> Html   -- ^ extra tags to include in \<head\>
-    -> Html   -- ^ contents to put inside \<body\>
-    -> m Response
+appTemplate :: ( Monad m) => String -> Html -> Html -> m Response
 appTemplate title headers body = return $ toResponse $ appTemplate' title headers body True Nothing
 
 -- | return the player number (user ID) based on the session cookie.
@@ -233,11 +229,12 @@
 
 showHideTitle :: String -> Bool -> Bool -> Html -> Html -> Html
 showHideTitle id visible empty title rest = do
-   div ! onclick (fromString $ printf "toggle_visibility('%sBody', '%sShow')" id id) $ table ! width "100%" $ tr $ do
-      td $ title ! width "80%"
-      td ! A.style "text-align:right;" $ h5 (if visible then "[Click to hide]" else "[Click to show]") ! A.id (fromString $ printf "%sShow" id) ! width "20%"
-   div ! A.id (fromString $ printf "%sBody" id) ! A.style (fromString $ "display:" ++ (if visible then "block;" else "none;")) $
-      if empty then toHtml $ "No " ++ id else rest
+   let id' = filter (/=' ') id
+   div $ table ! width "100%" $ tr $ do
+      td $ div $ title
+      td $ div $ a (if visible then "Click to hide" else "Click to show") ! A.id (fromString $ id' ++ "Show") ! A.class_ "button showHide" ! onclick (fromString $ printf "toggle_visibility('%sBody', '%sShow')" id' id')
+   div ! A.id (fromString $ id' ++ "Body") ! A.style (fromString $ "display:" ++ (if visible then "block;" else "none;")) $
+      if empty then (toHtml "No Rules") else rest
 
 titleWithHelpIcon :: Html -> String -> Html
 titleWithHelpIcon myTitle help = table ! width "100%" $ tr $ do
@@ -245,22 +242,13 @@
    td ! A.style "text-align:right;" $ img ! src "/static/pictures/help.jpg" ! A.title (toValue help)
 
 --mapping for the javascript function.
-divVisibility :: GameName -> String -> String -> String
-divVisibility gn boxName className =
-   printf "div_visibility('%s', '%s', '%s', '%s')"
-      (getIdBox gn boxName)
-      (getClassBox gn className)
-      (getIdButton gn boxName)
-      (getClassButton gn className)
-
-getIdBox, getClassBox, getIdButton, getClassButton :: String -> String -> String
-getIdBox       gn boxName   = gn ++ "IdBox" ++ boxName
-getClassBox    gn className = gn ++ "ClassBox" ++ className
-getIdButton    gn boxName   = gn ++ "IdButton" ++ boxName
-getClassButton gn className = gn ++ "ClassButton" ++ className
+setDivVisibilityAndSave :: String -> String -> String
+setDivVisibilityAndSave groupName elementName = printf "setDivVisibilityAndSave('%s', '%s')" groupName elementName
 
 defLink :: PlayerCommand -> Bool -> RoutedNomyxServer Text
 defLink a logged = if logged then showURL a else showURL (Auth $ AuthURL A_Login)
+
+trim = unwords . words
 
 instance FormError NomyxError where
     type ErrorInputType NomyxError = [HS.Input]
diff --git a/src/Nomyx/Web/Game/Infos.hs b/src/Nomyx/Web/Game/Infos.hs
--- a/src/Nomyx/Web/Game/Infos.hs
+++ b/src/Nomyx/Web/Game/Infos.hs
@@ -40,9 +40,8 @@
    modDel <- modalDel gn logged
    let isInGame = maybe False (\pn -> pn `elem` (_playerNumber <$> _players g)) mpn
    ok $ do
-      p $ do
-        h3 $ fromString $ _gameName g
-        when (isJust playAs) $ h4 $ fromString $ "You are playing as player " ++ (show $ fromJust playAs)
+      h3 $ fromString $ _gameName g
+      when (isJust playAs) $ h4 $ fromString $ "You are playing as player " ++ (show $ fromJust playAs)
       p $ pre $ fromString (_desc $ _gameDesc g)
       p $ h4 $ "This game is discussed in the " >> a "Forum" ! (A.href $ toValue (_forumURL $ _gameDesc g)) >> "."
       p $ h4 "Players in game:"
diff --git a/src/Nomyx/Web/Game/Rules.hs b/src/Nomyx/Web/Game/Rules.hs
--- a/src/Nomyx/Web/Game/Rules.hs
+++ b/src/Nomyx/Web/Game/Rules.hs
@@ -26,7 +26,7 @@
    viewRules (rejectedRules g) "Suppressed rules" False g >> br
 
 viewRules :: [RuleInfo] -> String -> Bool -> Game -> Html
-viewRules nrs title visible g = showHideTitle title visible (null nrs) (h4 $ toHtml (title ++ ":") ) $ table ! class_ "table" $ do
+viewRules nrs title visible g = showHideTitle ((_gameName g) ++ title) visible (null nrs) (h4 $ toHtml (title ++ ":") ) $ table ! class_ "table" $ do
    thead $ do
       td ! class_ "td" $ "#"
       td ! class_ "td" $ "Name"
@@ -43,13 +43,13 @@
       br
       div ! A.id "proposedBy" $ (fromString $ "by "  ++ (if _rProposedBy ri == 0 then "System" else pl))
    td ! class_ "td" $ fromString $ _rDescription ri
-   td ! class_ "td" $ viewRuleFunc ri
+   td ! class_ "td" $ viewRuleFunc ri (_gameName g)
 
-viewRuleFunc :: RuleInfo -> Html
-viewRuleFunc ri = do
+viewRuleFunc :: RuleInfo -> GameName -> Html
+viewRuleFunc ri gn = do
    let code = lines $ _rRuleCode ri
    let codeCutLines = 7
-   let ref = "openModalCode" ++ (show $ _rNumber ri)
+   let ref = "openModalCode" ++ (show $ _rNumber ri) ++ "game" ++ gn
    let assessedBy = case _rAssessedBy ri of
         Nothing -> "not assessed"
         Just 0  -> "the system"
diff --git a/src/Nomyx/Web/MainPage.hs b/src/Nomyx/Web/MainPage.hs
--- a/src/Nomyx/Web/MainPage.hs
+++ b/src/Nomyx/Web/MainPage.hs
@@ -120,22 +120,37 @@
    rf <- viewRuleForm mlr (isJust pi) isGameAdmin (_gameName g)
    vios <- viewIOs (fromMaybe pn playAs) g
    vgd <- viewGameDesc g  mpn playAs isGameAdmin
-   ok $ div ! A.id (fromString $ getIdBox "" gn) ! A.class_ (fromString $ (getClassBox "" "game") ++ " game") $ do
+   ok $ div ! A.id     (fromString $ (getElementName VisGame gn) ++ "Div")
+            ! A.class_ (fromString $ ((getGroupName VisGame) ++ "Div") ++ " game") $ do
       div ! A.id "titleBar" $ do
          let attr :: String -> Attribute
-             attr name = A.id (fromString $ getIdButton gn name) <> A.class_ (fromString $ (getClassButton gn "gameBox") ++ " button") <> onclick (fromString $ divVisibility gn name "gameBox")
+             attr name = A.id     (fromString $ (getElementName (VisGameTabs gn) name) ++ "Button")
+                      <> A.class_ (fromString $ (getGroupName (VisGameTabs gn)) ++ "Button" ++ " button")
+                      <> onclick  (fromString $ setDivVisibilityAndSave (getGroupName (VisGameTabs gn)) (getElementName (VisGameTabs gn) name))
          H.a "Description "    ! attr "gameDesc" ! A.style "fontWeight:bold;"
          H.a "Rules "          ! attr "rules"
          H.a "Inputs/Outputs " ! attr "ios"
          H.a "New rule "       ! attr "newRule"
          H.a "Details "        ! attr "details"
-      let attr name = A.id (fromString $ getIdBox gn name) <> A.class_ (fromString $ (getClassBox gn "gameBox") ++ " gameBox")
+      let attr name = A.id     (fromString $ (getElementName (VisGameTabs gn) name) ++ "Div")
+                   <> A.class_ (fromString $ (getGroupName (VisGameTabs gn)) ++ "Div" ++ " gameBox")
       div ! attr "gameDesc" ! A.style "display:inline;" $ vgd
       div ! attr "rules"    ! A.style "display:none;"   $ viewAllRules g
       div ! attr "ios"      ! A.style "display:none;"   $ vios
       div ! attr "newRule"  ! A.style "display:none;"   $ rf
       div ! attr "details"  ! A.style "display:none;"   $ viewDetails pn g
 
+data VisLevel = VisGame
+              | VisGameTabs GameName
+              deriving (Show)
+
+getElementName :: VisLevel -> String -> String
+getElementName vs name = (getGroupName vs) ++ "-" ++ (filter (/=' ') name)
+
+getGroupName :: VisLevel -> String
+getGroupName VisGame = "Game"
+getGroupName (VisGameTabs gn) = "GameTabs" ++ (filter (/=' ') gn)
+
 viewGameName :: Bool -> (Maybe PlayerNumber) -> GameInfo -> RoutedNomyxServer Html
 viewGameName isAdmin mpn gi = do
    let g = getGame gi
@@ -143,7 +158,9 @@
    let gn = _gameName g
    let canView = isGameAdmin || _isPublic gi
    ok $ when canView $ do
-      let attr = A.id (fromString $ getIdButton "" gn) <> A.class_ (fromString $ (getClassButton "" "game") ++ " button") <> onclick (fromString $ divVisibility "" gn "game")
+      let attr = A.id     (fromString $ ((getElementName VisGame gn) ++ "Button"))
+              <> A.class_ (fromString $ ((getGroupName VisGame) ++ "Button") ++ " button")
+              <> onclick  (fromString $ setDivVisibilityAndSave (getGroupName VisGame) (getElementName VisGame gn))
       tr $ td $ H.a (fromString (gn ++ "   ")) ! (A.title $ toValue Help.view) ! attr
 
 
