diff --git a/.htaccess b/.htaccess
new file mode 100644
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,7 @@
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteBase /
+    RewriteCond %{REQUEST_FILENAME} !-f
+    RewriteCond %{REQUEST_FILENAME} !-d
+    RewriteRule . /index.php [L]
+</IfModule>
\ No newline at end of file
diff --git a/content/scenes/B00001001.tpl b/content/scenes/B00001001.tpl
--- a/content/scenes/B00001001.tpl
+++ b/content/scenes/B00001001.tpl
@@ -1,63 +1,63 @@
     <!-- JQuery -->
-    <script src="/js/jquery-1.3.2.min.js"></script>
+    <script src="{#StaticContentURL#}/js/jquery-1.3.2.min.js"></script>
     
     <!-- Tower navigation CSS -->
     <style>
     #tower {
-        background-image: url(/{$SCENE_URL}/{$CurrentPerso->location_global}/all.png);
+        background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/all.png);
         background-position: left;
         background-repeat: no-repeat;
         height: 442px;
     }
     
     #tower_hl {
         position: relative;
     }
     </style>
     
     <div id="tower"></div>
     
     <!-- Tower navigation JQuery code -->
     <script>
     var tower = {
         //The source to highlight picture
-        hl: '/{$SCENE_URL}/{$CurrentPerso->location_global}/hl.png',
+        hl: '{$SCENE_URL}/{$CurrentPerso->location_global}/hl.png',
         
         //The highlighted corridor (1-6). 0 = no hl
         i: 0,
         
         //The corridor 4 (top) hl starts at:
         hlStartPosition: [163, 93],
         
         //Gets CurrentPerso html code
         getHighlightCode: function () {
             return "<img id='tower_hl' src='" + this.hl + "' alt='Corridor " + this.i + "' />";
         },
         
         highlight: function (i) {
             //If already there, nothing to do
             if (this.i == i) return;
             
             //Puts hl
             this.i = i;
             $('#tower').html(this.getHighlightCode());
             var o = document.getElementById("tower_hl");
             o.style.left = this.hlStartPosition[0] + "px";
             o.style.top = this.hlStartPosition[1] + "px";
             
             //The 4 is okay
             if (i == 4) return;
             
             //Gets rotation angle
             if (i > 4) {
                 angle = 60 * (i - 4);
             } else {
                 angle = 180 + (i -1) * 60;
             }
         }
     }
     
     $(document).ready(function() {
       tower.highlight(3);
     });
     </script>
\ No newline at end of file
diff --git a/content/scenes/B00002.tpl b/content/scenes/B00002.tpl
--- a/content/scenes/B00002.tpl
+++ b/content/scenes/B00002.tpl
@@ -1,6 +1,6 @@
 {$code = substr($CurrentPerso->location_global, 0, 6)}
     <!-- {$code} -->
-    <img src="/{$SCENE_URL}/{$code}.png" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
+    <img src="{$SCENE_URL}/{$code}.png" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
     <map name="SceneMap" id="SceneMap">
         <area shape="circle" coords="155,144,93" href="{get_url('explore')}" alt="{$CurrentPerso->location->body->name}" />
     </map>
\ No newline at end of file
diff --git a/content/scenes/B00003.tpl b/content/scenes/B00003.tpl
--- a/content/scenes/B00003.tpl
+++ b/content/scenes/B00003.tpl
@@ -1,6 +1,6 @@
 {$code = substr($CurrentPerso->location_global, 0, 6)}
     <!-- {$code} -->
-    <img src="/{$SCENE_URL}/{$code}.jpg" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
+    <img src="{$SCENE_URL}/{$code}.jpg" alt="{sprintf(#SpaceAround#, $CurrentPerso->location->body->name)}" border="0" usemap="#SceneMap" />
     <map name="SceneMap" id="SceneMap">
         <area shape="circle" coords="732,207,129" href="{get_url('explore')}" alt="{$CurrentPerso->location->body->name}" />
     </map>
\ No newline at end of file
diff --git a/css/zed/login.css b/css/zed/login.css
--- a/css/zed/login.css
+++ b/css/zed/login.css
@@ -1,63 +1,63 @@
 body {
     margin: 0 0 0 0;
     background-color: #343434;
     font-family: "FixedSys", monospace;
 }
 
 #LoginBox {
-    background-image: url("/img/login/bg.jpg");
+    background-image: url("../../img/login/bg.jpg");
     width: 341px;
     height: 516px;
     margin: 0 auto 0 auto;
 }
 
 #LoginBox label { display:none; }
 
 #LoginBox input {
     width: 150px;
     font-weight: 900;
     border: none;
     background-color: #3b3f55;
     color: white;
 }
 
 #LoginBox #username {
     position: relative;
     top: 250px;
     left: 150px;
 }
 
 #LoginBox #password {
     position: relative;
     top: 300px;
     left: 150px;
 }
 
 #LoginBox #openid {
     position: relative;
     top: 390px;
     width: 230px;
     left: 50px;
     
     /* OpenID */
-    background-image: url("/img/login/openid.png");
+    background-image: url("../../img/login/openid.png");
     background-position: 0% 50%;
     background-repeat: no-repeat;
     padding-left: 20px;
 }
 
 #LoginBox #submit {
     position: relative;
     top: 420px;
     left: 250px;
     width: 50px;
 }
     
 .error {
     position: relative;
     width: 290px;
     margin: 0 10px 0 10px;
     text-align: right;
     color: #3b3f55;
     top: 274px;
 }
\ No newline at end of file
diff --git a/css/zed/theme.css b/css/zed/theme.css
--- a/css/zed/theme.css
+++ b/css/zed/theme.css
@@ -1,334 +1,334 @@
 @charset "utf-8";
 
 /*  -------------------------------------------------------------
     Zed
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Author:         Dereckson
     Tags:           space retro futurist
     Filename:       forms.css
     Version:        1.0
     Created:        2010-01-27
     Updated:        2010-01-27
     Licence:        Creative Commons BY 3.0
     -------------------------------------------------------------    */
 
 /*  -------------------------------------------------------------
     Page settings
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 body {
     margin: 28px 0 0 0;
     
     background-color: #343434;
-    background-image: url("/img/zed/topborder.png");
+    background-image: url("../../img/zed/topborder.png");
     background-position: top;
     background-repeat: repeat-x;
 
     font-family: "Calibri", "Lucida Sans Unicode", "Trebuchet MS", "Helvetica", "Arial", sans-serif;
     
     
     color: white;
 }
 
 
 h1, h2, h3, h4, h5, h6 {
     color: black;
 }
 
 pre {
     font-family: FixedSys, monospace;
 }
 
 /*  -------------------------------------------------------------
     Links
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 a {
     color: #1AC8E8;
     text-decoration: none;
 }
 
 a:visited {
     color: gray;
 }
 
 a:hover {
     color: red;
     text-decoration: none;
 }
 
 /*  -------------------------------------------------------------
     Notify messages
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 .notify {
 	padding-top:    25px;
 	padding-bottom: 25px;
 
 	margin-bottom: 10px;
 	
 	text-align: center;
 	background: #eeeeee;
 	font-size: 1.5em;
 	color: black;
 	
 	border: 5px solid #1AC8E8;
 	width: 950px;
 }
 
 .wap {
 	padding-top:    50px;
 	padding-bottom: 50px;
 
 	margin-bottom: 10px;	
 	
 	text-align: center;
 	background: #eeeeee;
 	font-size: 2em;
 	color: black;
 
 	border: 5px solid indianred;
 	width: 950px;
 	
 }
 
 /*  -------------------------------------------------------------
     Wall
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 .wall {
     text-align: left;
     float: right;
     font-size: 80%;
 }
 
 .wall_info {
     display: block;
     text-align: right;
 }
 
 /*  -------------------------------------------------------------
     Info
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 .info {
     font-size: 90%;
 }
 
 .info strong {
     display: inline-block;
     display: -moz-inline-box;
     width: 9em;
     min-width: 9em;
     font-weight: 600;
     color: #fd9800;
 }
 
 /*  -------------------------------------------------------------
     Avatars wall
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
     
 .avatar {
     float: left;
     margin-bottom: 2em;
     margin-right: 2em;
     text-align: center;
 }
 
 .avatar_name {
     display: block;
 }
 
 /*  -------------------------------------------------------------
     Messages
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
     
 .message {
     margin-bottom: 17px;
     padding: 8px 9px 8px 9px;
     width: 940px;
     font-size: 80%;
 }
 
 .message.light {
     background-color: #fafafa;
     border: 3px solid #dedede;
     width: 938px;
     color: black;
 }
 
 .message.light a {color: #343434;}
 
 .message.dark {
     background-color: #acc0c3;
     border: solid 3px #4e5758;
     width: 938px;
     
 }
 .message.dark a {color: #154c4c;}
 
 .message a:hover {
     font-weight: 900;
 }
 
 .message_info {
     text-align: right;
     margin-bottom: 1em;
 }
 
 .message_text {
     font-size: 1.25em;
 }
 
 .message_info {
     color: #343434;
 }
 
 /*  -------------------------------------------------------------
     Color boxes
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 .plum {
     background-color: plum;
     border: 1px solid #800080;
     color: black;
 }
 .plum a { color: #800080; }
 
 .green {
     background-color: beige;
     border: 1px solid darkgreen;
     color: black;
 }
 .green a { color: darkgreen; }
 
 .skyblue {
     background-color: lightskyblue;
     border: 1px solid #6e47fe;
 }
 .skyblue a { color:navy }
 
 .indigo {
     background-color: #AE97E1;
     border: 1px solid #C97FFF;
     
 }
 .indigo a {color: #800080;}
 
 .yellow {
     background-color: #FFFFCC;
     border: 1px solid #C4B963;
     
 }
 .yellow a {color: navy;}
 
 .orange {
     background-color: #FDD9AC;
     border: 1px solid #eaaf67;
 }
 .orange a {color: #43392e;}
 
 .red {
     background-color: #FFE4E1;
     border: solid 1px #DC7777;
     
 }
 .red a {color: #993333;}
 
 .black {
     background-color: black;
     color: #ccc;
     border: solid 2px #555;
 }
 
 .plum a:hover,
 .green a:hover,
 .skyblue a:hover,
 .indigo a:hover,
 .yellow a:hover,
 .orange a:hover,
 .red a:hover{
     font-weight: bold;
 }
 
 /*  -------------------------------------------------------------
     SmartLine
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 #SmartLine {
     width: 100%;
 }
 
 #SmartLine .left {
     background-color: green;
 }
 
 #SmartLine .right {
     float: right;
     text-align: right;
 }
 
 /* TODO: ajouter un s�lecteur de SmarLine pour chat/commandes (60px) */
 /* grid_1 alpha -> s�lecteur, grid_3 -> history, grid_12 > bar */
 
 #SmartLineHistory {
     width: 115%; /* d�passe de sa bordure */
 }
 
 #SmartLineBar{
     /* 99.6% for alignment with .message.light */
     width: 99.6%;
 }
 
 #SmartLineResults {
 	font-family: "Fixedsys Excelsior 3.01", FixedSys, Terminal;
 	font-size: 12pt;
 }
 
 #SmartLineResults .highlight {
 	color: #16c3cc;
 }
 
 #SmartLineResults .error {
 	color: red;
 }
 
 #SmartLineResults p {
     padding-left: 1em;
 }
 
 /*  -------------------------------------------------------------
     Floating panes
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 .floatingPaneTutorial {
     width: 957.5px;
     margin-bottom: 1em;
     color: black;
 }
 
 .floatingPaneTutorial a {
     color: navy;
 }
 
 .floatingPaneTutorial a:hover {
     color: #7F0707;
     font-weight: 900;
 }
 
 .floatingPaneTutorial p {
     color: black;
     margin: 0;
     padding: 5px 10px 0px 10px; 
 }
 
 .dojoxDockList {
     color: black;
 }
 
 /*  -------------------------------------------------------------
     Footer
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    */
 
 #footer {
     font-size: 80%;
 }
\ No newline at end of file
diff --git a/includes/config.php b/includes/config.php
--- a/includes/config.php
+++ b/includes/config.php
@@ -1,62 +1,128 @@
 <?php
 
 /*
  * Zed
  * (c) 2010, Dereckson, some rights reserved
  * Released under BSD license
  *
  * Autogenerable configuration file
  */
+
+////////////////////////////////////////////////////////////////////////////////
+///                                                                          ///
+/// I. SQL configuration                                                     ///
+///                                                                          ///
+////////////////////////////////////////////////////////////////////////////////
  
 //SQL configuration
-$Config['sql']['product'] = 'MySQL';
+$Config['sql']['product'] = 'MySQL';    //Only MySQL is currently implemented
 $Config['sql']['host'] = 'localhost';
 $Config['sql']['username'] = 'zed';
 $Config['sql']['password'] = 'zed';
 $Config['sql']['database'] = 'zed';
 
-//GRANT ALL PRIVILEGES on zed.* TO 'zed'@'localhost' IDENTIFIED by 'zed';
-
 //SQL tables
 $prefix = '';
 define('TABLE_API_KEYS', $prefix . 'api_keys');
 define('TABLE_COMMENTS', $prefix . 'comments');
 define('TABLE_LOG_SMARTLINE', $prefix . 'log_smartline');
 define('TABLE_MESSAGES', $prefix . 'messages');
 define('TABLE_MOTD', $prefix . 'motd');
 define('TABLE_PAGES', $prefix . 'pages');
 define('TABLE_PAGES_EDITS', $prefix . 'pages_edits');
 define('TABLE_PERSOS', $prefix . 'persos');
 define('TABLE_PERSOS_FLAGS', $prefix . 'persos_flags');
 define('TABLE_PROFILES', $prefix . 'profiles');
 define('TABLE_PROFILES_COMMENTS', $prefix . 'profiles_comments');
 define('TABLE_PROFILES_PHOTOS', $prefix . 'profiles_photos');
 define('TABLE_SESSIONS', $prefix . 'sessions');
 define('TABLE_USERS', $prefix . 'users');
 define('TABLE_USERS_OPENID', $prefix . 'users_openid');
 
+//Geo tables
 define('TABLE_BODIES', $prefix . 'geo_bodies');
-define('TABLE_LOCATIONS', $prefix . 'geo_locations');       //View
+define('TABLE_LOCATIONS', $prefix . 'geo_locations');   //Well... it's view
 define('TABLE_PLACES', $prefix . 'geo_places');
 
-//Script URL
-$Config['BaseURL'] = '/index.php';
+////////////////////////////////////////////////////////////////////////////////
+///                                                                          ///
+/// II. Site configuration                                                   ///
+///                                                                          ///
+////////////////////////////////////////////////////////////////////////////////
 
 //Default theme
 $Config['DefaultTheme'] = "Zed";
 
 //Dates
 date_default_timezone_set("UTC");
 
+////////////////////////////////////////////////////////////////////////////////
+///                                                                          ///
+/// III. Script URLs                                                         ///
+///                                                                          ///
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Without mod_rewrite:
+ * 
+ *   Subdirectory:
+ *     - $Config['SiteURL'] = 'http://zed.dereckson.be/hypership/index.php';
+ *     - $Config['BaseURL'] = '/hypership/index.php';
+ *
+ *   Root directory:
+ *     - $Config['SiteURL'] = 'http://zed.dereckson.be/index.php';
+ *     - $Config['BaseURL'] = '/index.php';
+ *
+ * With mod_rewrite:
+ * 
+ *   Subdirectory:
+ *     - $Config['SiteURL'] = 'http://zed.dereckson.be/hypership';
+ *     - $Config['BaseURL'] = '/hypership';
+ *
+ *     In .htaccess or your vhost definition:
+ *       RewriteEngine On
+ *       RewriteBase /hypership/
+ *       RewriteCond %{REQUEST_FILENAME} !-f
+ *       RewriteCond %{REQUEST_FILENAME} !-d
+ *       RewriteRule . /hypership/index.php [L]
+ *
+ *   Root directory:
+ *     - $Config['SiteURL'] = 'http://zed.dereckson.be';
+ *     - $Config['BaseURL'] = '';
+ *
+ *
+ * If you don't want to specify the server domain, you can use get_server_url:
+ *      $Config['SiteURL'] = get_server_url() . '/hypership';
+ *      $Config['SiteURL'] = get_server_url();
+ *  
+ * $Config['StaticContentURL'] is used to serve js, css, img and content
+ * directories. To improve site performance, you can use a CDN for that.
+ * 
+ * !!! No trailing slash !!!
+ *   
+ */
+
+$Config['SiteURL'] = get_server_url();
+$Config['BaseURL'] = '';
+
+$Config['StaticContentURL'] = $Config['SiteURL'];
+define('SCENE_URL', "$Config[StaticContentURL]/content/scenes");
+
+////////////////////////////////////////////////////////////////////////////////
+///                                                                          ///
+/// IV. Sessions                                                             ///
+///                                                                          ///
+////////////////////////////////////////////////////////////////////////////////
+
 //Sessions
 
 //If you want to use a common table of sessions / user handling
 //with several websites, specify a different resource id for each site.
 $Config['ResourceID'] = 21;
 
 //PHP variables
 ini_set('session.serialize_handler', 'wddx');
 ini_set('session.save_path', 'cache/sessions');
 ini_set('session.gc_maxlifetime', 345600);  //4 days, for week-end story pause and continue url
 
 ?>
\ No newline at end of file
diff --git a/includes/core.php b/includes/core.php
--- a/includes/core.php
+++ b/includes/core.php
@@ -1,240 +1,320 @@
 <?php
 //No register globals
 ini_set('register_globals', 'off');
 //error_reporting(E_ALL & ~E_NOTICE);
 error_reporting(E_ALL & ~E_NOTICE);
 
 //Load libraries
 include_once("config.php");               //Site config
 include_once("error.php");               //Error management
 include_once("mysql.php");              //MySQL layer
 include_once("sessions.php");          //Sessions handler
 
 //Helpers
 
 //Gets username from specified user_id
 function get_name ($id) {
 	global $db;
 	$sql = 'SELECT perso_nickname FROM '. TABLE_PERSOS . " WHERE perso_id = '$id'";
 	if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't query persos table.", '', __LINE__, __FILE__, $sql);
 	$row = $db->sql_fetchrow($result);
 	return $row['perso_nickname'];
 }
 
 //Gets user_id from specified username
 function get_userid ($username) {
 	global $db;
 	$username = $db->sql_escape($username);
 	$sql = 'SELECT user_id FROM '. TABLE_USERS . " WHERE username LIKE '$username'";
 	if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't query users table.", '', __LINE__, __FILE__, $sql);
 	$row = $db->sql_fetchrow($result);
 	return $row['user_id'];
 }
 
 // ------------------------------------------------------------------------- //
 // Chaîne aléatoire                                                          //
 // ------------------------------------------------------------------------- //
 // Auteur: Pierre Habart                                                     //
 // Email:  p.habart@ifrance.com                                              //
 // Web:                                                                      //
 // ------------------------------------------------------------------------- //
 
 function genereString($format)
 {
     mt_srand((double)microtime()*1000000);
     $str_to_return="";
 
     $t_alphabet=explode(",","A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z");
     $t_number=explode(",","1,2,3,4,5,6,7,8,9,0");
 
     for ($i=0;$i<strlen($format);$i++)
     {
         if (ereg("^[a-zA-Z]",$format[$i]))
         {
             $add=$t_alphabet[mt_rand() % sizeof($t_alphabet)];
             if (ereg("^[a-z]",$format[$i]))
                 $add=strtolower($add);
         }
         elseif(ereg("^[0-9]",$format[$i]))
             $add=$t_number[mt_rand() % sizeof($t_number)];
         else $add="?";
 
         $str_to_return.=$add;
     }
     return $str_to_return;
 }
 
 function generer_hexa($longueur) {
         mt_srand((double)microtime()*1000000);
         $str_to_return="";
         $t_number=explode(",","1,2,3,4,5,6,7,8,9,0,A,B,C,D,E,F");
         for ($i = 0 ; $i < $longueur ; $i++) {
                 $str_to_return .= $t_number[mt_rand() % sizeof($t_number)];
         }
     return $str_to_return;
 }
 
 //Plural management
 
 function s ($amount) {
 	if ($amount > 1) return "s";
 }
 
 function x ($amount) {
 	if ($amount > 1) return "x";
 }
 
 //Debug
 
 function dprint_r ($mixed) {
 	echo "<pre>", print_r($mixed, true), "</pre>";
 }
 
 //GUID
 
 function new_guid() {
 	$characters = explode(",","a,b,c,d,e,f,0,1,2,3,4,5,6,7,8,9");
 	$guid = "";
 	for ($i = 0 ; $i < 36 ; $i++) {
 		if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
 			$guid .= "-";
 		} else {
 			$guid .= $characters[mt_rand() % sizeof($characters)];
 		}
 	}
 	return $guid;
 }
 
 
 function is_guid ($expression) {
     //We avoid regexp to speed up the check
     //A guid is a 36 characters string
     if (strlen($expression) != 36) return false;
     
     $expression = strtolower($expression);
 	for ($i = 0 ; $i < 36 ; $i++) {
 		if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
 			//with dashes
 			if ($expression[$i] != "-") return false;
 		} else {
 		    //and numbers
 			if (!is_numeric($expression[$i]) && $expression[$i] != 'a' && $expression[$i] != 'b' && $expression[$i] != 'c' && $expression[$i] != 'd' && $expression[$i] != 'e' && $expression[$i] != 'f' ) return false;
 		}
 	}
     return true;
 }
 
 //Gets file extension
 function get_extension ($file) {
     $dotPosition = strrpos($file, ".");
     return substr($file, $dotPosition + 1);
 }
 
 /*
  * Loads specified language Smarty configuration file
  *
  * @param string $file the file to load
  * @param mixed $sections array of section names, single section or null
  */
 function lang_load ($file, $sections = null) {
     global $smarty;
     
     //Loads English file as fallback if some parameters are missing
     if (file_exists("lang/en/$file"))
         $smarty->config_load("lang/en/$file", $sections);
     
     //Loads wanted file
     if (LANG != 'en' && file_exists('lang/' . LANG . '/' . $file))
         $smarty->config_load('lang/' . LANG . '/' . $file, $sections);
 }
 
 /*
  * Gets a specified language expression defined in configuration file
  *
  * @param string $key the configuration key matching the value to get
  * @return string The value in the configuration file
  */
 function lang_get ($key) {
     global $smarty;
     
     $smartyConfValue = $smarty->config_vars[$key];
     return $smartyConfValue ? $smartyConfValue : "#$key#";
 }
 
 /*
  * Converts a YYYYMMDD or YYYY-MM-DD timestamp to unixtime
  */
 function to_unixtime ($timestamp) {
 	switch (strlen($timestamp)) {
         case 8:
         //YYYYMMDD
         return mktime(0, 0, 0, substr($timestamp, 4, 2), substr($timestamp, 6, 2), substr($timestamp, 0, 4));
     
         case 10:
         //YYYY-MM-DD
         return mktime(0, 0, 0, substr($timestamp, 5, 2), substr($timestamp, 8, 2), substr($timestamp, 0, 4));
     
         default:
         throw new Exception("timestamp is not a valid YYYYMMDD or YYYY-MM-DD timestamp: $timestamp");
     }
 }
 
 /*
  * Converts a unixtime to the YYYYMMDD or YYYY-MM-DD timestamp format
  *
  * @param int $unixtime the time to convert
  * @param int $format 8 or 10. If 8 (default), will output YYYYMMDD. If 10, YYYY-MM-DD.
  */
 function to_timestamp ($unixtime = null, $format = 8) {   
 	//If no parameter is specified (or null, or false), current time is used
     //==== allows to_timestamp(0) to return correct 1970-1-1 value.
     if ($unixtime === null || $unixtime === false) $unixtime = time();
     
 	switch ($format) {
         case 8:
         //YYYYMMDD
         return date('Ymd', $unixtime);
     
         case 10:
         //YYYY-MM-DD
         return date('Y-m-d', $unixtime);
     
         default:
         throw new Exception("format must be 8 (YYYYMMDD) or 10 (YYYY-MM-DD) and not $format.");
     }
 }
 
 /*
  * Converts a unixtime to the Hypership time format.
  */
 function get_hypership_time ($unixtime = null) {
     //If unixtime is not specified, it's now
     if ($unixtime === null) $unixtime = time();
     
     //Hypership time is a count of days since launch @ 2010-01-25 00:00:00
     //Followed by a fraction of the current day /1000, like the internet time
     //but in UTC timezone and not Switzerland CET/CEST.
     //We don't need to use floor(), as we output the result at int, truncating
     //automatically decimal values instead of round it (like in C).
     $seconds = $unixtime - 1264377600;
     $days = $seconds / 86400;
     $fraction = ($seconds % 86400) / 86.4;
     return sprintf("%d.%03d", $days, $fraction);
 }
 
 /*
  * Gets URL
+ * @return string URL
  */
 function get_url () {
     global $Config;
     if (func_num_args() > 0) {
         $pieces = func_get_args();
         return $Config['BaseURL'] . '/' . implode('/', $pieces);
     } elseif ($Config['BaseURL'] == "" || $Config['BaseURL'] == "/index.php") {
         return "/";
     } else {
         return $Config['BaseURL'];
     }
 }
 
+/*
+ * Gets page URL
+ * @return string URL
+ */
+function get_page_url () {
+    $url = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO'];
+    if (substr($url, -10) == "/index.php") {
+	return substr($url, 0, -9);
+    }
+    return $url;
+}
+
+function get_server_url () {
+	switch ($port = $_SERVER['SERVER_PORT']) {
+		case '80':
+            return "http://$_SERVER[SERVER_NAME]";
+        
+        case '443':
+            return "https://$_SERVER[SERVER_NAME]";
+        
+        default:
+            return "http://$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
+	}
+}
+
+function get_current_url () {
+    return get_server_url() . $_SERVER['REQUEST_URI'];
+}
+
+function get_current_url_fragments () {
+    global $Config;
+            
+    //Gets relevant URL part from relevant $_SERVER variables
+    if (array_key_exists('PATH_INFO', $_SERVER)) {
+	//Without mod_rewrite, and url like /index.php/controller
+	//we use PATH_INFO. It's the easy case.
+	$url_source = $_SERVER["PATH_INFO"];
+    } elseif (array_key_exists('REDIRECT_URL', $_SERVER)) {
+	//With mod_rewrite, we can use REDIRECT_URL
+	$current_url = get_current_url();
+	
+	//Relevant URL part starts after the site URL
+	$len = strlen($Config['SiteURL']);
+	
+	//We need to assert it's the correct site
+	if (substr($current_url, 0, $len) != $Config['SiteURL']) {
+	    dieprint_r(GENERAL_ERROR, "Edit includes/config.php and specify the correct site URL<br /><strong>Current value:</strong> $Config[SiteURL]<br /><strong>Expected value:</strong> a string starting by " . get_server_url(), "Setup");
+	}
+	
+	//We takes the end of the URL, ie *FROM* $len position
+	$url_source = substr(get_server_url() . $_SERVER["REDIRECT_URL"], $len);
+    } else {
+	//Last possibility: use REQUEST_URI, but remove QUERY_STRING
+	//If you need to edit here, use $_SERVER['REQUEST_URI']
+	//but you need to discard $_SERVER['QUERY_STRING']
+	$current_url = get_current_url();
+	
+	//Relevant URL part starts after the site URL
+	$len = strlen($Config['SiteURL']);
+	
+	//We need to assert it's the correct site
+	if (substr($current_url, 0, $len) != $Config['SiteURL']) {
+	    dieprint_r(GENERAL_ERROR, "Edit includes/config.php and specify the correct site URL<br /><strong>Current value:</strong> $Config[SiteURL]<br /><strong>Expected value:</strong> a string starting by " . get_server_url(), "Setup");
+	}
+	
+	//We takes the end of the URL, ie *FROM* $len position
+	$url_source = substr(get_server_url() . $_SERVER["REQUEST_URI"], $len);
+
+	//But if there are a query string (?action=... we need to discard it)	
+	if ($_SERVER['QUERY_STRING']) {
+	    $url_source = substr($url_source, 0, strlen($url_source) - strlen($_SERVER['QUERY_STRING']) - 1);
+	}
+    }
+   
+    //$url_source = substr($current_url, $len);
+    if ($url_source == '/index.php') return array();
+    return explode('/', substr($url_source, 1));
+}
+
 ?>
\ No newline at end of file
diff --git a/includes/error.php b/includes/error.php
--- a/includes/error.php
+++ b/includes/error.php
@@ -1,165 +1,166 @@
 <?php
 // Gestionnaire d'erreur
 //
 // SQL_ERROR  : Erreur de requêtes SQL
 // HACK_ERROR : Appel d'une page où l'utilisateur n'a pas accès
 
 //Constantes
 define ("SQL_ERROR",  65);
 define ("HACK_ERROR", 99);
 define ("GENERAL_ERROR", 117);
 
 function dieprint_r ($var, $title = '') {
     if (!$title) $title = 'Debug';
+    
     message_die(GENERAL_ERROR, '<pre>' . print_r($var, true) .'</pre>', $title);
 }
 
 function message_die ($msg_code, $msg_text = '', $msg_title = '', $err_line = '', $err_file = '', $sql = '') {
     global $smarty, $db;
 
     if ($smarty) {
         $debug_text = $msg_text;
 
         if ($err_line && $err_file)
             $debug_text .= ' &mdash; ' . $err_file. ', ' . lang_get('line') . ' ' . $err_line ;
         
         switch ($msg_code) {
             case HACK_ERROR:
                 $smarty->assign('TITLE', lang_get('UnauthorizedAccess'));
                 break;
             
             case SQL_ERROR:
                 $smarty->assign('TITLE', lang_get('SQLError'));
                 $sql_error = $db->sql_error();
                 if ($sql_error['message'] != '') {
                     $debug_text .= '<br />' . lang_get('Error') . ' n° ' . $sql_error['code'] . lang_get('_t') .
                                 ' ' .$sql_error['message'];
                 }
                 $debug_text .= "</p><h2>Query:</h2><p>$sql";
                 break;
             
             default:
                 $smarty->assign('WAP', "Message code error.<br />Expected: HACK_ERROR, SQL_ERROR, GENERAL_ERROR");
                 //Falls to GENERAL_ERROR
             
             case GENERAL_ERROR:
                 if ($msg_title)
 		    $smarty->assign('TITLE', $msg_title);
 		else
 		    $smarty->assign('TITLE', lang_get('GeneralError'));
                 break;
         }
         
         
         $smarty->assign('ERROR_TEXT', $debug_text);
         $template = (defined('HEADER_PRINTED') &&  HEADER_PRINTED) ? "error_block.tpl" : "error.tpl";
 	$smarty->display($template);
         exit;
     } else {
         old_message_die($msg_code, $msg_text, $msg_title, $err_line, $err_file, $sql);
     }
 }
 
 function old_message_die($msg_code, $msg_text = '', $msg_title = '', $err_line = '', $err_file = '', $sql = '')
 {
 	global $db, $Utilisateur;
 	$sql_store = $sql;
 	
 	if ($msg_code == HACK_ERROR && $Utilisateur[user_id] < 1000) {
 		global $LoginResult;
 		foreach ($_POST as $name => $value) {
 			$champs .= "<input type=hidden name=$name value=\"$value\" />";
 		}
 		$titre = "Qui êtes-vous ?";
 		$debug_text = "Vous devez être authentifié pour accéder à cette page.";
 		$debug_text .= "
 		<FORM method='post'>
 		$champs
 		<table border='0'>
 		  <tr>
 			<td><STRONG>Login</STRONG></td>
 			<td><input name='Login' type='text' id='Login'  value='$_POST[Login]' size='10' /></td>
 			<td><STRONG>Mot de passe</STRONG></td>
 			<td>
 				<input name='MotDePasse' type='password' id='MotDePasse' size='10' />
 				<input type='submit' name='LoginBox' value='Connexion' />
 			</td>
 		  </tr>
 		  <tr> 
 			<td align=center COLSPAN=4><a href='/?Topic=My&Article=Enregistrer'>Je d&eacute;sire ouvrir un compte</a></td>
 		  </tr>
 		</TABLE><span class=error>$LoginResult</span>
 		</FORM>
 		";
 	} elseif ($msg_code == HACK_ERROR) {
 		$titre = "Accès non autorisé";
 		$debug_text = $msg_text;
 	} elseif ($msg_code == SQL_ERROR) {
 		$titre = "Erreur dans la requête SQL";
 		$sql_error = $db->sql_error();
 		$debug_text = $msg_text;
 		if ( $err_line != '' && $err_file != '') $debug_text .= ' dans ' . $err_file. ', ligne ' . $err_line ;
 		if ( $sql_error['message'] != '' ) $debug_text .= '<br />Erreur n° ' . $sql_error['code'] . ' : ' . $sql_error['message'];
 		if ( $sql_store != '' ) $debug_text .= "<br /><strong>$sql_store</strong>";
 	} elseif ($msg_code == GENERAL_ERROR) {
 	    $titre = $msg_title;
 	    $debug_text = $msg_text;
 	    if ($err_line && $err_file) {
 		    $debug_text .= "<BR />$err_file, ligne $err_line";
 	    }
 	}	
 	
 	echo "
 	<TABLE height='100%' cellSpacing=0 cellPadding=0 width='100%' border=0>
   <TBODY>
   <TR>
     <TD vAlign=top align=middle>
       <TABLE cellSpacing=0 cellPadding=0 border=0>
         <TBODY> 
         <TR>
           <TD vAlign=top rowSpan=5><IMG height=177 alt='' 
             src='/_pict/error/notfound.jpg' width=163 border=0></TD>
           <TD colSpan=4><IMG height=2 alt='' src='/_pict/error/mrblue.gif' 
             width=500 border=0></TD>
           <TD><IMG height=2 alt='' src='/_pict/error/undercover.gif' width=1 
             border=0></TD></TR>
         <TR>
           <TD vAlign=bottom rowSpan=4 bgcolor='#FFFFFF'><IMG height=43 alt='' 
             src='/_pict/error/ecke.gif' width=14 border=0></TD>
           <TD vAlign=center align=middle rowSpan=2 bgcolor='#FFFFFF'> 
             <TABLE cellSpacing=1 cellPadding=0 width=470 border=0>
               <TBODY>
               <TR>
                 <TD><FONT face='Verdana, Helvetica, sans-serif' color=red 
                   size=4><B>$titre</B></FONT><BR>
                   <IMG height=5 alt='' 
                   src='/_pict/error/undercover.gif' width=14 border=0><BR></TD></TR>
               <TR>
                 <TD><FONT face='Verdana, Helvetica, sans-serif' color=black 
                   size=2>$debug_text</FONT></TD></TR></TBODY></TABLE></TD>
           <TD align=right width=2 rowSpan=2 bgcolor='#FFFFFF'><IMG height=146 alt='' 
             src='/_pict/error/mrblue.gif' width=2 border=0></TD>
           <TD bgcolor='#FFFFFF'><IMG height=132 alt='' src='/_pict/error/undercover.gif' width=1 
             border=0></TD>
         </TR>
         <TR>
           <TD><IMG height=14 alt='' src='/_pict/error/undercover.gif' width=1 
             border=0></TD></TR>
         <TR>
           <TD colSpan=2><IMG height=2 alt='' src='/_pict/error/mrblue.gif' 
             width=486 border=0></TD>
           <TD><IMG height=2 alt='' src='/_pict/error/undercover.gif' width=1 
             border=0></TD></TR>
         <TR>
           <TD colSpan=2><IMG height=27 alt='' src='/_pict/error/undercover.gif' 
             width=486 border=0></TD>
           <TD><IMG height=27 alt='' src='/_pict/error/undercover.gif' width=1 
             border=0></TD></TR></TBODY></TABLE>
       <P>&nbsp;</P>
       </TD></TR></TBODY></TABLE>
 	";
 	
 	exit;
 }
 
 ?>
\ No newline at end of file
diff --git a/includes/geo/scene.php b/includes/geo/scene.php
--- a/includes/geo/scene.php
+++ b/includes/geo/scene.php
@@ -1,130 +1,130 @@
 <?php
 
 /*
  * Geo scene class
  *
  * 0.1    2010-01-30 17:42    DcK
  *
  * @package Zed
  * @subpackage Geo
  * @copyright Copyright (c) 2010, Dereckson
  * @license Released under BSD license
  * @version 0.1
  *
  */
 
 require_once('location.php');
 if (!defined('SCENE_DIR')) define('SCENE_DIR', 'content/scenes');
 
 class GeoScene {
     /*
      * @var string Last error warning
      */
     public $lastError;
     
     /*
      * @var string File scene to serve
      */
     public $sceneFile;
        
     /*
      * @var GeoLocation the location to print the scene
      */
     public $location;
     
     /*
      * Initializes a new GeoScene instance
      * @param GeoLocation $location location the scene is to print
      */
     function __construct ($location) {
         $this->location = $location;
  
         //Gets local scene
         if ($location->containsLocalLocation) {
             if ($this->get_local_scene()) return;
         }
         
         //Gets global scene
         if ($location->containsGlobalLocation) {
             if ($this->get_global_scene()) return;
         }
         
         //If not scene found, let's set a warning
         $this->lastError = "No scene found.";
     }
     
     /*
      * Gets local scene
      * @return boolean true if a scene have been found ; otherwise, false.
      */
     private function get_local_scene () {
         return false;
     }
     
     /*
      * Gets global scene
      * @return boolean true if a scene have been found ; otherwise, false.
      */
     private function get_global_scene () {
         $location = $this->location;
         if ($location->place) {
             if ($this->try_get_scene($location->global)) {
                 return true;
             }
         }
         if ($location->body) {
             if ($this->try_get_scene('B' . $location->body->code)) {
                 return true;
             }
         }
         return false;
     }
     
     public static function get_file_extension ($file) {
         $pathinfo = pathinfo($file);
         return $pathinfo['extension'];
     }
     
     public function render () {
         if ($file = $this->sceneFile) {
             switch ($ext = GeoScene::get_file_extension($file)) {
                 case 'png':
                 case 'jpg':
                 case 'gif':
                 case 'bmp':
                     echo "<img src=\"$file\" />";
                     break;
                     
                 case 'tpl':
                     global $smarty;
                     $template_dir = $smarty->template_dir;
                     $smarty->template_dir = getcwd();
-                    $smarty->assign("SCENE_URL", SCENE_DIR);
+                    $smarty->assign("SCENE_URL", defined('SCENE_URL') ? SCENE_URL : '/' . SCENE_DIR);
                     $smarty->display($file);
                     $smarty->template_dir = $template_dir;
                     break;
                 
                 case 'php':
                     message_die(HACK_ERROR, ".php scene files not allowed without review", '', __LINE__, __FILE__);
                     
                 default:
                     message_die(GENERAL_ERROR, "Can't handle $ext extension for $file scene", 'GeoScene render error', __LINE__, __FILE__);
             }
             echo "\n\n";
         }
     }
     
     private function try_get_scene ($code) {
         $file = SCENE_DIR . "/$code";
         $extensions = array('tpl', 'png', 'jpg', 'gif', 'bmp', 'swf', 'html', 'php');
         foreach ($extensions as $ext) {
             if (file_exists("$file.$ext")) {
                 $this->sceneFile = "$file.$ext";
                 return true;
             }
         }
         return false;
     }
 }
 
 ?>
\ No newline at end of file
diff --git a/includes/login.php b/includes/login.php
--- a/includes/login.php
+++ b/includes/login.php
@@ -1,106 +1,106 @@
 <?php
 
 /*
  * Zed
  * (c) 2010, Dereckson, some rights reserved
  * Released under BSD license
  *
  * Login/logout
  */
 
 if (!file_exists('/dev/urandom')) {
     //We're on Windows, without reliable source of random numbers
     define('Auth_OpenID_RAND_SOURCE', null);
 }
 
 require_once('Auth/OpenID/Consumer.php');
 require_once('Auth/OpenID/DumbStore.php');
 //require_once('Auth/OpenID/FileStore.php');
 
 /*
 function get_openid_consumer () {
     if (!file_exists('/dev/urandom')) {
         //We're on Windows, without reliable source of random numbers
         define('Auth_OpenID_RAND_SOURCE', null);
     }
    
     $fs = new Auth_OpenID_FileStore('cache/openid');
     return new Auth_OpenID_Consumer($fs);
 }
 */
 
 function openid_login ($url) {
     global $db, $_SESSION, $LoginError, $LoginSuccessful;
     $url = $db->sql_escape($url);
     $sql = 'SELECT user_id FROM ' . TABLE_USERS_OPENID
           . " WHERE openid_url LIKE '$url'";
     if ($user_id = $db->sql_query_express($sql)) {
         $sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$user_id' WHERE session_id LIKE '$_SESSION[ID]'";
         if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de procéder à la connexion", '', __LINE__, __FILE__, $sql);
         $LoginSuccessful = true;
         setcookie("LastOpenID", $url, time() + 2592000);
-        header("location: /");
+        header("location: " . get_url());
     } else {
         $LoginError = "To join Zed, you need an invite. Read the source to get one.";
     }
 }
 
 if ($_GET['action'] == 'openid.login') {
     //Gets Auth_OpenID_Consumer instance
     $fs = new Auth_OpenID_DumbStore("rien n'est sûr mais c'est une piste");
     //$fs = new Auth_OpenID_FileStore('cache/openid');
     $consumer = new Auth_OpenID_Consumer($fs);
     //$consumer = get_openid_consumer();
     
     //Completes the OpenID transaction
-    $reply = $consumer->complete("http://" . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]);
+    $reply = $consumer->complete(get_server_url() . $_SERVER['REQUEST_URI']);
     if ($reply->status == Auth_OpenID_SUCCESS) {
         openid_login($reply->endpoint->claimed_id);
     } elseif ($reply->message) {
         $LoginError = "[OpenID] $reply->message";
     } else {
         $LoginError = "[OpenID] $reply->status";
     }    
 } elseif ($_POST['LogIn']) {
 	//User have filled login form
     if ($_POST['openid']) {        
         //Gets Auth_OpenID_Consumer instance
         $fs = new Auth_OpenID_DumbStore("rien n'est sûr mais c'est une piste");
         //$fs = new Auth_OpenID_FileStore('cache/openid');
         $consumer = new Auth_OpenID_Consumer($fs);
         //$consumer = get_openid_consumer();
             
         //Starts the OpenID transaction and redirects user to provider url
         if ($request = $consumer->begin($_POST['openid'])) {
-            $url = $request->redirectURL("http://zed.dereckson.be", "http://zed.dereckson.be/?action=openid.login", false);
+	    $url = $request->redirectURL(get_server_url(), "$Config[SiteURL]/?action=openid.login", false);
             header("location: $url");
             $LoginError = '<a href="' . $url . '">Click here to continue login</a>';
         } else {
             $LoginError = 'Invalid OpenID URL.';
         }
     } else {
         //GESTION LOGIN
         $Login = $_POST['username'];
         $sql = "SELECT user_password, user_id FROM " . TABLE_USERS . " WHERE username = '$Login'";
         if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Impossible d'interroger le listing des utilisateurs", '', __LINE__, __FILE__, $sql);
         if ($row = $db->sql_fetchrow($result)) {
             if (!$row['user_password']) {
                 $LoginError = "This account exists but haven't a password defined. Use OpenID or contact dereckson (at) espace-win.org to fix that.";
             } elseif ($row['user_password'] != md5($_POST['password'])) {
                 //PASS NOT OK
                 $LoginError = "Incorrect password.";
             } else {
                 $sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$row[user_id]' WHERE session_id LIKE '$_SESSION[ID]'";
                 if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Impossible de procéder à la connexion", '', __LINE__, __FILE__, $sql);
                 $LoginSuccessful = true;
                 setcookie("LastUsername", $Login, time() + 2592000);
             }				
         } else {
             //Login n'existe pas
             $LoginError = "Login not found.";
         }
     }
 } elseif ($_POST['LogOut'] || $_GET['action'] == "user.logout") {
     Logout();
 }
 ?>
\ No newline at end of file
diff --git a/index.php b/index.php
--- a/index.php
+++ b/index.php
@@ -1,185 +1,187 @@
 <?php
 
 /*
  * Zed
  * (c) 2010, Dereckson, some rights reserved
  * Released under BSD license
  *
  * Application entry point
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// Initialization
 ///
 
 //Pluton library
 include('includes/core.php');
 
 //Session
 $IP = encode_ip($_SERVER["REMOTE_ADDR"]);
 require_once('includes/story/story.php'); //this class can be stored in session
 session_start();
 $_SESSION[ID] = session_id();
 session_update(); //updates or creates the session
 
 include("includes/login.php"); //login/logout
 $CurrentUser = get_logged_user(); //Gets current user infos
 
 //Gets current perso
 require_once('includes/objects/perso.php');
 if ($perso_id = $CurrentUser->session['perso_id']) {
     $CurrentPerso = new Perso($perso_id);
 }
 
 //Skin and accent to load
 define('THEME', $CurrentUser->session['Skin']);
 define('ACCENT', $CurrentUser->session['Skin_accent']);
 
 //Loads Smarty
 require('includes/Smarty/Smarty.class.php');
 $smarty = new Smarty();
 $current_dir = dirname(__FILE__);
 $smarty->template_dir = $current_dir . '/skins/' . THEME;
 
 $smarty->compile_dir = $current_dir . '/cache/compiled';
 $smarty->cache_dir = $current_dir . '/cache';
 $smarty->config_dir = $current_dir;
 
+$smarty->config_vars['StaticContentURL'] = $Config['StaticContentURL'];
+
 //Loads language files
 define('LANG', 'fr');
 lang_load('core.conf');
 
 if ($CurrentUser->id < 1000) {   
     //Anonymous user, proceed to login
     if (array_key_exists('LastUsername', $_COOKIE))
         $smarty->assign('username', $_COOKIE['LastUsername']);
     if (array_key_exists('LastOpenID', $_COOKIE))
         $smarty->assign('OpenID', $_COOKIE['LastOpenID']);
     $smarty->assign('LoginError', $LoginError);
     $smarty->display('login.tpl');
     exit;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// Perso selector
 ///
 
 //Handles form
 if ($_POST['form'] == 'perso.create') {
     $perso = new Perso();
     $perso->load_from_form();
     $perso->user_id = $CurrentUser->id;
     
     //Validates forms
     if (!$perso->name) $errors[] = lang_get("NoFullnameSpecified");
     if (!$perso->race) {
         $errors[] = lang_get("NoRaceSpecified");
         $perso->race = "being";
     }
     if (!$perso->sex) $errors[] = lang_get("NoSexSpecified");
     if (!$perso->nickname) {
         $errors[] = lang_get("NoNicknameSpecified");
     } else if (!Perso::is_available_nickname($perso->nickname)) {
         $errors[] = lang_get("UnavailableNickname");
     }
     
     //Save or prints again forms
     if (!$errors) {
         $perso->save_to_database();
         $smarty->assign('NOTIFY', lang_get('NewCharacterCreated'));
         $CurrentPerso = $perso;
         set_info('perso_id', $perso->id);
         $CurrentPerso->setflag("site.lastlogin", $_SERVER['REQUEST_TIME']);
     } else {
         $smarty->assign('WAP', join("<br />", $errors));
         $smarty->assign('perso', $perso);
     }    
 }
 
 if ($_GET['action'] == 'perso.logout') {
     //User wants to change perso
     $CurrentPerso = null;
     set_info('perso_id', null);
     clean_session();
 } elseif ($_GET['action'] == 'perso.select') {
     //User have selected a perso
     $CurrentPerso = new Perso($_GET['perso_id']);
     if ($CurrentPerso->user_id != $CurrentUser->id) {
         //Hack
         message_die(HACK_ERROR, "This isn't your perso.");
     }
     set_info('perso_id', $CurrentPerso->id);
     $CurrentPerso->setflag("site.lastlogin", $_SERVER['REQUEST_TIME']);
 }
 
 if (!$CurrentPerso) {   
     switch ($count = Perso::get_persos_count($CurrentUser->id)) {
         case 0:
             //Create a perso
             $smarty->display("perso_create.tpl");
             exit;
         
         case 1:
             //Autoselect
             $CurrentPerso = Perso::get_first_perso($CurrentUser->id);
             set_info('perso_id', $CurrentPerso->id);
             $CurrentPerso->setflag("site.lastlogin", $_SERVER['REQUEST_TIME']);
             break;
             
         default:
             //Pick a perso
             $persos = Perso::get_persos($CurrentUser->id);
             $smarty->assign("PERSOS", $persos);
             $smarty->display("perso_select.tpl");
             $_SESSION['UserWithSeveralPersos'] = true;
             exit;
     }
 }
 
 //Assigns current perso object as Smarty variable
 $smarty->assign('CurrentPerso', $CurrentPerso);
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// Tasks to execute before calling the URL controller:
 ///     - assert the perso is somewhere
 ///     - executes the smartline
 ///
 
 //If the perso location is unknown, ejects it to an asteroid
 if (!$CurrentPerso->location_global) {
     require_once('includes/geo/place.php');
     $smarty->assign('NOTIFY', lang_get('NewLocationNotify'));
     $CurrentPerso->move_to(GeoPlace::get_start_location());
 }
 
 //SmartLine
 include("includes/SmartLine/ZedSmartLine.php");
 
 ////////////////////////////////////////////////////////////////////////////////
 ///
 /// Calls the specific controller to serve the requested page
 ///
 
-$url = explode('/', substr($_SERVER['PATH_INFO'], 1));
-
+$url = get_current_url_fragments();
+    
 switch ($controller = $url[0]) {
     case '':
         include('controllers/home.php');
         break;
 
     case 'request':
     case 'page':
     case 'explore':
         include("controllers/$controller.php");
         break;
 
 
     default:
         //TODO: returns a 404 error
         dieprint_r($url, 'Unknown URL');
 }
 
 ?>
\ No newline at end of file
diff --git a/js/tour.js b/js/tour.js
--- a/js/tour.js
+++ b/js/tour.js
@@ -1,134 +1,134 @@
         var tour = {           
             //Default language
             lang: "en",
             
             //Translated in
             langs: "en,fr",
             
             //Current highlight showed
             current: -1,
             
             //File extension
             extension: "png",
             
             //Highlights files and position
             //File: /img/tour/{filename}.{extension}
             highlights: [
                          ["create", 13, 18],
                          ["lounge", 339, 107],
                          ["play", 22, 345],
                          ["explore", 325, 373]
                         ],
             
             //The center x, y coordinate
             //It's used to determinate what highlight to print
             center: [368, 390],
             
             //Gets the highlight index, from position
             where: function(x, y) {
                 if (x < this.center[0]) {
                     //We're at left from center point
                     return (y < this.center[1]) ? 0 : 2;
                 } else {
                     //We're at right from center point
                     return (y < this.center[1]) ? 1 : 3;
                 }
             },
             
             //Determines if we're inside the #Tour id
             isInside: function (pageX, pageY) {
                 var tourOffset = $("#Tour").offset();
                 return pageX >= tourOffset.left && pageY >= tourOffset.top
                 && pageX <= tourOffset.left + $("#Tour").width()
                 && pageY <= tourOffset.top + $("#Tour").height();
             },
             
             //Shows the highlight at specified the page position
             showAt: function (pageX, pageY) {
                 var tourOffset = $("#Tour").offset();
                 this.show(
                     this.where(pageX - tourOffset.left , pageY - tourOffset.top)
                 );
             },
             
             //Shows the specified highlight
             show: function (i) {
                 if (this.current != i) {
                     var filename = this.highlights[i][0] + "_" + this.lang + "." + this.extension;
-                    var code = '<img src="/img/tour/' +  filename + '" alt="' + this.highlights[i][0] + '" />';
+                    var code = '<img src="img/tour/' +  filename + '" alt="' + this.highlights[i][0] + '" />';
                     $('#TourHighlight').empty().html(code);
                     var o = document.getElementById("TourHighlight");
                     o.style.left = this.highlights[i][1] + "px";
                     o.style.top = this.highlights[i][2] + "px";
                     this.current = i;
                 }
             },
             
             //Hides highlight
             hideall: function () {
                 if (this.current > -1) {
                     this.current = -1;
                     $('#TourHighlight').empty();
                 }
             },
             
             //Runs the animation
             run: function (delay) {
                 //Highlight order
                 //[0, 1, 3, 2] is a counterwise move
                 var order = [0, 1, 3, 2];
                                 
                 //Prints first hightlight
                 this.show(order[0]);
                 
                 //Prints next highlights
                 n = this.highlights.length;
                 for (i = 1 ; i < n ; i++) {
                     setTimeout('tour.show(' + order[i] + ')', delay * i);
                 }
                 
                 //Prints back the first, and enables rollover
                 setTimeout('tour.show(' + order[0] + ')', delay * n);
                 setTimeout('tour.enableRollover()', delay * n);
             },
                        
             //Enables rollovers
             enableRollover: function () {
                 //Enables panel on click
                 $('#Tour').bind("mousemove mouseout", function(e) {
                     if (tour.isInside(e.pageX, e.pageY)) {
                         tour.showAt(e.pageX, e.pageY);
                     } else {
                         tour.hideall();
                     }             
                 });
             },            
             
             //Gets client language
             getLanguage: function () {
                 var lang = navigator.language;
                 if (lang == undefined) lang = navigator.userLanguage;
                 if (lang == undefined) return "";
                 
                 //fr-be -> fr
                 var pos = lang.indexOf('-');
                 if (pos > -1) lang = lang.substring(0, pos);
                 
                 return lang.toLowerCase();
             },
             
             //Initializes tour
             init: function () {
                 //Tries to localize
                 var lang = this.getLanguage();
                 if (this.langs.indexOf(lang) > -1) this.lang = lang;
                 
                 //Runs tour animation
                 //The rollover will be enabled at anim end
                 this.run(900);
             }
         }
                 
         $(document).ready(function() {
           tour.init();          
         });
\ No newline at end of file
diff --git a/skins/zed/error.tpl b/skins/zed/error.tpl
--- a/skins/zed/error.tpl
+++ b/skins/zed/error.tpl
@@ -1,43 +1,43 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
     <title>{#SiteTitle#}</title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <link rel="stylesheet" type="text/css" href="/css/960.css" media="screen" />
-    <link rel="stylesheet" href="/css/zed/theme.css" />
+    <link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/960.css" media="screen" />
+    <link rel="stylesheet" href="{#StaticContentURL#}/css/zed/theme.css" />
 </head>
 <body>
 <div class="container_16">
 {if $WAP}
     
     <!-- WAP -->
     <div class="grid_16 alpha omega">
         <div class="wap">{$WAP}</div>
     </div>
 {/if}
 {if $NOTIFY}
     
     <!-- Notify -->
     <div class="grid_16 alpha omega">
         <div class="notify">{$NOTIFY}</div>
     </div>
 {/if}
 
     <div class="grid_16 alpha omega">
         <h1>{$TITLE}</h1>
         <p>{$ERROR_TEXT}</p>
-        <p><a href="/">{#BackToHome#}</a></p>
+        <p><a href="{get_url()}">{#BackToHome#}</a></p>
     </div>
     <div class="clear"></div>
     <hr />
     <div id="footer">
         <div class="grid_12 alpha">
             <p>[ {#Product#} / {#FatalErrorScreen#} ]</p>
         </div>
         <div class="grid_4 omega">
-            <p style="text-align: right">[ <a href="/?action=user.logout">{#Logout#}</a> ]</p>
+            <p style="text-align: right">[ <a href="{get_url()}?action=user.logout">{#Logout#}</a> ]</p>
         </div>
     </div>
 </div>
 </body>
 </html>
\ No newline at end of file
diff --git a/skins/zed/error_block.tpl b/skins/zed/error_block.tpl
--- a/skins/zed/error_block.tpl
+++ b/skins/zed/error_block.tpl
@@ -1,17 +1,17 @@
     <div class="clear clearfix"></div>
     <div class="grid_16 alpha omega">
         <h1>{$TITLE}</h1>
         <p>{$ERROR_TEXT}</p>
-        <p><a href="/">{#BackToHome#}</a></p>
+        <p><a href="{get_url()}">{#BackToHome#}</a></p>
     </div>
     <div class="clear"></div>
     <hr />
     <div class="grid_12 alpha">
         <p>[ {#Product#} / {#FatalErrorInterrupt#} ]</p>
     </div>
     <div class="grid_4 omega">
-        <p style="text-align: right">[ <a href="/?action=user.logout">{#Logout#}</a> ]</p>
+        <p style="text-align: right">[ <a href="{get_url()}?action=user.logout">{#Logout#}</a> ]</p>
     </div>
 </div>
 </body>
 </html>
\ No newline at end of file
diff --git a/skins/zed/footer.tpl b/skins/zed/footer.tpl
--- a/skins/zed/footer.tpl
+++ b/skins/zed/footer.tpl
@@ -1,18 +1,18 @@
 
 
     <div class="clear"></div>
 {include file="smartline.tpl"}
 
     <!-- Footer -->
     <hr />
     <div id="footer">
         <div class="grid_8 alpha">
             <p>[ {#Product#} / {$CurrentPerso->location_global} {$CurrentPerso->location_local} / {if $screen}{$screen}{else}Untitled screen{/if} ]</p>
         </div>
         <div class="grid_8 omega" style="float: right">
-            <p style="text-align: right">[ {if $MultiPerso}<a href="/?action=perso.logout">{sprintf(#SwapPerso#, $CurrentPerso->name)}</a> | {/if}<a href="/?action=user.logout">{#Logout#}</a> ]</p>
+            <p style="text-align: right">[ {if $MultiPerso}<a href="{get_url()}?action=perso.logout">{sprintf(#SwapPerso#, $CurrentPerso->name)}</a> | {/if}<a href="{get_url()}?action=user.logout">{#Logout#}</a> ]</p>
         </div>
     </div>
 </div>
 </body>
 </html>
\ No newline at end of file
diff --git a/skins/zed/header.tpl b/skins/zed/header.tpl
--- a/skins/zed/header.tpl
+++ b/skins/zed/header.tpl
@@ -1,59 +1,59 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
     <title>{$PAGE_TITLE} - {#SiteTitle#}</title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <link rel="stylesheet" type="text/css" href="/css/960.css" media="screen" />
-    <link rel="stylesheet" href="/css/zed/theme.css" />
-    <script type="text/javascript" src="/js/misc.js"></script>
+    <link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/960.css" media="screen" />
+    <link rel="stylesheet" href="{#StaticContentURL#}/css/zed/theme.css" />
+    <script type="text/javascript" src="{#StaticContentURL#}/js/misc.js"></script>
 {foreach from=$PAGE_CSS item=css}
-    <link rel="stylesheet" href="/css/{$css}" />
+    <link rel="stylesheet" href="{#StaticContentURL#}/css/{$css}" />
 {/foreach}
 {foreach from=$PAGE_JS item=js}
-    <script src="/js/{$js}"></script>
+    <script src="{#StaticContentURL#}/js/{$js}"></script>
 {/foreach}
     {if $DOJO}
-    <script type="text/javascript" src="/js/dojo/dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true" ></script>
+    <script type="text/javascript" src="{#StaticContentURL#}/js/dojo/dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true" ></script>
     {/if}
 </head>
 <body{if $DIJIT} class="tundra"{/if}>
 <div class="container_16">
     <!-- Header -->
     <div class="grid_4 alpha">
-        <a href="/"><img src="/img/zed/logo.png" src="Zed logo" /></a>
+        <a href="{get_url()}"><img src="{#StaticContentURL#}/img/zed/logo.png" src="Zed logo" border=0 /></a>
     </div>
     <div class="grid_12 omega">
         <div class="wall">
             <p>
                 {$WALL_TEXT}
                 <br /><span class="wall_info">-- <a href="{$WALL_USER_URL}">{$WALL_USER}</a></span>
             </p>
         </div>
     </div>
     <div class="clear"></div>
 {if $WAP}
     
     <!-- WAP -->
     <div class="grid_16 alpha omega">
         <div class="wap">{$WAP}</div>
     </div>
     <div class="clear"></div>
 {/if}
 {if $NOTIFY}
     
     <!-- Notify -->
     <div class="grid_16 alpha omega">
         <div class="notify">{$NOTIFY}</div>
     </div>
     <div class="clear"></div>
 {/if}
 
     <!-- Where? When? -->
     <p class="info">
         <strong>Current location</strong> {$CurrentPerso->where()}<br />
         <strong>Hypership time</strong> <span id="HypershipTime">{get_hypership_time()}</span>
     </p>
 {if $SmartLine_STDOUT || $SmartLine_STDERR}
 {include file="smartline_results.tpl"}
 {/if}
 
diff --git a/skins/zed/login.tpl b/skins/zed/login.tpl
--- a/skins/zed/login.tpl
+++ b/skins/zed/login.tpl
@@ -1,65 +1,65 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
     <title>{#SiteTitle#}</title>
-    <link rel="Stylesheet" href="/css/zed/login.css" type="text/css" />
+    <link rel="Stylesheet" href="{#StaticContentURL#}/css/zed/login.css" type="text/css" />
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>
 <body>
 <!-- Login form -->
 <div id="LoginBox">
-    <form method="post" action="/">
+    <form method="post" action="{get_url()}">
         <div class="row">
             <label for="username">{#Login#}{#_t#}</label>
             <input type="text" id="username" name="username" value="{$username}" />
         </div>
         <div class="row">
             <label for="password">{#Password#}{#_t#}</label>
             <input type="password" id="password" name="password" />
         </div>
         <div class="row">
             <label for="openid">{#OpenID#}{#_t#}</label>
             <input type="text" id="openid" name="openid" value="{$OpenID}" />
         </div>
         <div class="row">
             <input type="submit" id="submit" name="LogIn" value="{#OK#}" />
         </div>
     </form>
 {if $LoginError}
         <div class=row>
             <p class="error">&nbsp;&nbsp;&nbsp;&nbsp;{$LoginError}</p>
         </div>
 {/if}
 </div>
 
 {$code = genereString('AAA111')}
 <!--
 
             XXXXXXX             XX
             X    X               X
                 X                X               Invitation code:
                 X    XXXXX   XXXXX               {$code}
                X    X     X X    X
               X     XXXXXXX X    X
               X     X       X    X
              X    X X     X X    X
             XXXXXXX  XXXXX   XXXXXX
 
 Welcome to the Zed beta. We're happy you're reading the source :)
 
 If you want to know what we're building, check http://zed.dereckson.be/tour.html
 
 If you wish an access, send a mail to zedinvite (alt+64) dereckson.be
 and specify the following code: {$code}
 
                                     * * * *
                                     
 Bienvenue dans la version bêta de Zed. Heureux que vous consultiez la source.
 
 Un petit aperçu de ce que l'on crée est sur http://zed.dereckson.be/tour.html
 
 Pour obtenir un accès, envoyez un mail à zedinvite (alt+64) dereckson.be
 en spécifiant le code suivant : {$code}
 -->
 </body>
 </html>
\ No newline at end of file
diff --git a/skins/zed/perso_footer.tpl b/skins/zed/perso_footer.tpl
--- a/skins/zed/perso_footer.tpl
+++ b/skins/zed/perso_footer.tpl
@@ -1,11 +1,11 @@
     <div class="clear"></div>
     <hr />
     <div class="grid_12 alpha">
         <p>[ {#Product#} ]</p>
     </div>
     <div class="grid_4 omega">
-        <p style="text-align: right">[ <a href="/?action=user.logout">{#Logout#}</a> ]</p>
+        <p style="text-align: right">[ <a href="{get_url()}?action=user.logout">{#Logout#}</a> ]</p>
     </div
 </div>
 </body>
 </html>
\ No newline at end of file
diff --git a/skins/zed/perso_header.tpl b/skins/zed/perso_header.tpl
--- a/skins/zed/perso_header.tpl
+++ b/skins/zed/perso_header.tpl
@@ -1,39 +1,39 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
     <title>{#SiteTitle#}</title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <link rel="stylesheet" type="text/css" href="/css/960.css" media="screen" />
-    <link rel="stylesheet" href="/css/zed/theme.css" />
+    <link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/960.css" media="screen" />
+    <link rel="stylesheet" href="{#StaticContentURL#}/css/zed/theme.css" />
     
     <!-- Calls dojo -->
-    <script src="/js/dojo/dojo/dojo.js" type="text/javascript"
+    <script src="/{#StaticContentURL#}js/dojo/dojo/dojo.js" type="text/javascript"
             djConfig="isDebug: false, parseOnLoad: true"></script>
-    <link rel="stylesheet" href="/css/zed/forms.css" />
+    <link rel="stylesheet" href="{#StaticContentURL#}/css/zed/forms.css" />
     <script type="text/javascript">
         dojo.require("dijit.form.Form");
         
         dojo.require("dijit.form.ValidationTextBox");
         dojo.require("dijit.form.TextBox");
         dojo.require("dijit.form.FilteringSelect");
         dojo.require("dijit.form.Button");
     
         dojo.require("dojo.parser");
     </script>
 </head>
 <body class="tundra">
 <div class="container_16">
 {if $WAP}
     
     <!-- WAP -->
     <div class="grid_16 alpha omega">
         <div class="wap">{$WAP}</div>
     </div>
 {/if}
 {if $NOTIFY}
     
     <!-- Notify -->
     <div class="grid_16 alpha omega">
         <div class="notify">{$NOTIFY}</div>
     </div>
 {/if}
diff --git a/skins/zed/perso_select.tpl b/skins/zed/perso_select.tpl
--- a/skins/zed/perso_select.tpl
+++ b/skins/zed/perso_select.tpl
@@ -1,18 +1,18 @@
 {include file="perso_header.tpl"}
 <div class="grid_16">
     <h2>{#PickPerso#}</h2>
 {foreach from=$PERSOS item=perso}
         <!-- {$perso->name} -->
         <div class="avatar">
-            <a href="/?action=perso.select&perso_id={$perso->id}">
+            <a href="{get_url()}?action=perso.select&perso_id={$perso->id}">
 {if $perso->avatar}
-                <img src="/users/_avatars/{$perso->avatar}" />
+                <img src="{#StaticContentURL#}/content/users/_avatars/{$perso->avatar}" />
 {else}
-                <img src="/img/misc/NoAvatar.png" alt="{#NoAvatar#}" />
+                <img src="{#StaticContentURL#}/img/misc/NoAvatar.png" alt="{#NoAvatar#}" />
 {/if}
             </a>
-            <span class="avatar_name"><a href="/?action=perso.select&perso_id={$perso->id}">{$perso->name}</a></span>
+            <span class="avatar_name"><a href="{get_url()}?action=perso.select&perso_id={$perso->id}">{$perso->name}</a></span>
         </div>
         
 {/foreach}
 {include file="perso_footer.tpl"}
\ No newline at end of file
diff --git a/skins/zed/smartline.tpl b/skins/zed/smartline.tpl
--- a/skins/zed/smartline.tpl
+++ b/skins/zed/smartline.tpl
@@ -1,26 +1,26 @@
 
     <!-- SmartLine -->
     <div class="grid_16 alpha omega" id="SmartLine">
-        <form method="post" name="SmartLine" action="{get_url()}">
+        <form method="post" name="SmartLine" action="{get_page_url()}">
 {if $SmartLineHistory}
             <!-- SmartLine history -->
             <div class="grid_4 left alpha">
                 <select name="SmartLineHistory" id="SmartLineHistory" class="black" onChange=UpdateSmartLine()>
                     <option value="">[ {#SmartLineHistory#} ]</option>
 {foreach from=$SmartLineHistory item=command}
                     <option value="{$command->text|escape}">{$command->time} | {$command->text|escape}</option>
 {/foreach}
                 </select>
             </div>
             <!-- SmartLine line -->
             <div class="grid_12 right omega">
 {else}
             <!-- SmartLine line -->
             <div class="grid_16 alpha omega left" style="width: 100.2%">
 {/if}
                 <input name="C" type="text" id="SmartLineBar" maxlength=255 class="black" style="text-align: left;">
             </div>
         </form>
     </div>
     
     <div class="clear"></div>
diff --git a/skins/zed/tutorial/dojo.tpl b/skins/zed/tutorial/dojo.tpl
--- a/skins/zed/tutorial/dojo.tpl
+++ b/skins/zed/tutorial/dojo.tpl
@@ -1,4 +1,4 @@
 
 
     <!-- DOJO -->
-    <script type="text/javascript" src="/js/dojo/dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true" ></script>
+    <script type="text/javascript" src="{#StaticContentURL#}/js/dojo/dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true" ></script>
diff --git a/skins/zed/tutorial/hypership_reach.tpl b/skins/zed/tutorial/hypership_reach.tpl
--- a/skins/zed/tutorial/hypership_reach.tpl
+++ b/skins/zed/tutorial/hypership_reach.tpl
@@ -1,18 +1,18 @@
     <!-- Floating panes -->
-    <script type="text/javascript" src="/js/dojo/dojox/layout/FloatingPane.js"></script>
-    <link rel="stylesheet" type="text/css" href="/js/dojo/dojox/layout/resources/FloatingPane.css" />
-    <link rel="stylesheet" type="text/css" href="/js/dojo/dojox/layout/resources/ResizeHandle.css" />
+    <script type="text/javascript" src="{#StaticContentURL#}/js/dojo/dojox/layout/FloatingPane.js"></script>
+    <link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/js/dojo/dojox/layout/resources/FloatingPane.css" />
+    <link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/js/dojo/dojox/layout/resources/ResizeHandle.css" />
 
     <!-- Dock -->
     <style type="text/css">
-            @import "/js/dojo/dojo/resources/dojo.css";
-            @import "/js/dojo/dijit/themes/dijit.css";
-            @import "/js/dojo/dijit/themes/tundra/tundra.css";
+            @import "{#StaticContentURL#}/js/dojo/dojo/resources/dojo.css";
+            @import "{#StaticContentURL#}/js/dojo/dijit/themes/dijit.css";
+            @import "{#StaticContentURL#}/js/dojo/dijit/themes/tundra/tundra.css";
     </style>
 
     <!-- Help to reach the hypership -->
     <div dojoType="dojox.layout.FloatingPane" title="Join the hypership" resizable="true" id="floaterHypershipReach" class="floatingPaneTutorial" duration="300">
         <p>{sprintf(#WhereYouAre#, $CurrentPerso->where(), lang_get($CurrentPerso->location->body_kind))}</p>
         <p>{#WhereTheHypershipIs#}</p>
         <p>{#HowToJoinIt#}</p>
     </div>
\ No newline at end of file
diff --git a/tour.html b/tour.html
--- a/tour.html
+++ b/tour.html
@@ -1,46 +1,46 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 	<head>
 		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
 		<title>Enter</title>
-		<link rel="stylesheet" type="text/css" href="/css/grid.css" media="screen" />
-        <script src="/js/jquery-1.3.2.min.js"></script>
-        <script src="/js/dimensions.js"></script>
-        <script src="/js/tour.js"></script>
+		<link rel="stylesheet" type="text/css" href="css/grid.css" media="screen" />
+        <script src="js/jquery-1.3.2.min.js"></script>
+        <script src="js/dimensions.js"></script>
+        <script src="js/tour.js"></script>
         <script>
 
         </script>
         <style>
             body {
                 background-color: #343434;
             }
         
             H1 {
                 font-family: Helvetica, Arial;
             }
         
             #Tour {
                 background-image: url(img/tour/bg.jpg);
                 height: 748px;
                 width: 748px;
                 margin: auto auto auto auto;
                 z-index: 20;
             }
             
             #TourHighlight {
                 position: relative;
                 z-index: 50;
             }
         </style>
 	</head>
 	<body>
         <div class="container_16">
             <div class="grid_16">
                 <div id="Tour">
                     <div id="TourHighlight"></div>
                 </div>
             </div>
             <div class="clear"></div>
         </div>
     </body>
 </html>
\ No newline at end of file