Index: src/attach.c
==================================================================
--- src/attach.c
+++ src/attach.c
@@ -75,20 +75,20 @@
         zFilename = &zFilename[i+1];
         i = -1;
       }
     }
     if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
-      zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename);
+      zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename);
     }else{
-      zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename);
+      zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename);
     }
     @
     @ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
-    @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br>
+    @ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br />
     if( zComment ) while( isspace(zComment[0]) ) zComment++;
     if( zComment && zComment[0] ){
-      @ %w(zComment)<br>
+      @ %w(zComment)<br />
     }
     if( zPage==0 && zTkt==0 ){
       if( zSrc==0 || zSrc[0]==0 ){
         zSrc = "Deleted from";
       }else {
@@ -273,13 +273,13 @@
   style_header("Add Attachment");
   @ <h2>Add Attachment To %s(zTargetType)</h2>
   @ <form action="%s(g.zBaseURL)/attachadd" method="POST"
   @  enctype="multipart/form-data">
   @ File to Attach:
-  @ <input type="file" name="f" size="60"><br>
-  @ Description:<br>
-  @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br>
+  @ <input type="file" name="f" size="60"><br />
+  @ Description:<br />
+  @ <textarea name="comment" cols=80 rows=5 wrap="virtual"></textarea><br />
   if( zTkt ){
     @ <input type="hidden" name="tkt" value="%h(zTkt)">
   }else{
     @ <input type="hidden" name="page" value="%h(zPage)">
   }
@@ -351,11 +351,11 @@
     cgi_redirect(zFrom);
   }    
   style_header("Delete Attachment");
   @ <form action="%s(g.zBaseURL)/attachdelete" method="POST">
   @ <p>Confirm that you want to delete the attachment named
-  @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br>
+  @ "%h(zFile)" on %s(zTkt?"ticket":"wiki page") %h(zTarget):<br />
   if( zTkt ){
     @ <input type="hidden" name="tkt" value="%h(zTkt)">
   }else{
     @ <input type="hidden" name="page" value="%h(zPage)">
   }

Index: src/branch.c
==================================================================
--- src/branch.c
+++ src/branch.c
@@ -231,16 +231,19 @@
   }
   login_anonymous_available();
   compute_leaves(0, 1);
   style_sidebox_begin("Nomenclature:", "33%");
   @ <ol>
-  @ <li> An <a href="brlist">open branch</a> is a branch that has one or
+  @ <li> An <div class="sideboxDescribed"><a href="brlist">
+  @ open branch</a></div> is a branch that has one or
   @ more <a href="leaves">open leaves.</a>
   @ The presence of open leaves presumably means
   @ that the branch is still being extended with new check-ins.</li>
-  @ <li> A <a href="brlist?closed">closed branch</a> is a branch with only
-  @ <a href="leaves?closed">closed leaves</a>.
+  @ <li> A <div class="sideboxDescribed"><a href="brlist?closed">
+  @ closed branch</a></div> is a branch with only
+  @ <div class="sideboxDescribed"><a href="leaves?closed">
+  @ closed leaves</a></div>.
   @ Closed branches are fixed and do not change (unless they are first
   @ reopened)</li>
   @ </ol>
   style_sidebox_end();
 
@@ -284,13 +287,11 @@
   }
   if( cnt ){
     @ </ul>
   }
   db_finalize(&q);
-  @ </ul>
-  @ <br clear="both">
-  @ <script>
+  @ <script  type="text/JavaScript">
   @ function xin(id){
   @ }
   @ function xout(id){
   @ }
   @ </script>
@@ -341,14 +342,13 @@
     " ORDER BY event.mtime DESC",
     timeline_query_for_www(), TAG_BRANCH
   );
   www_print_timeline(&q, 0, brtimeline_extra);
   db_finalize(&q);
-  @ <br clear="both">
-  @ <script>
+  @ <script  type="text/JavaScript">
   @ function xin(id){
   @ }
   @ function xout(id){
   @ }
   @ </script>
   style_footer();
 }

Index: src/browse.c
==================================================================
--- src/browse.c
+++ src/browse.c
@@ -144,11 +144,11 @@
     char zShort[20];
     memcpy(zShort, zUuid, 10);
     zShort[10] = 0;
     @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>]
     @ %s(blob_str(&dirname))</h2>
-    zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix);
+    zSubdirLink = mprintf("%s/dir?ci=%S&amp;name=%T", g.zTop, zUuid, zPrefix);
     if( zD ){
       style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid);
       style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD);
     }else{
       style_submenu_element("All", "All", "%s/dir", g.zBaseURL);
@@ -157,13 +157,13 @@
     @ <h2>The union of all files from all check-ins
     @ %s(blob_str(&dirname))</h2>
     zSubdirLink = mprintf("%s/dir?name=%T", g.zBaseURL, zPrefix);
     if( zD ){
       style_submenu_element("Top", "Top", "%s/dir", g.zBaseURL);
-      style_submenu_element("Tip", "Tip", "%s/dir?name=%t&ci=tip",
+      style_submenu_element("Tip", "Tip", "%s/dir?name=%t&amp;ci=tip",
                             g.zBaseURL, zD);
-      style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&ci=trunk",
+      style_submenu_element("Trunk", "Trunk", "%s/dir?name=%t&amp;ci=trunk",
                              g.zBaseURL,zD);
     }else{
       style_submenu_element("Tip", "Tip", "%s/dir?ci=tip", g.zBaseURL);
       style_submenu_element("Trunk", "Trunk", "%s/dir?ci=trunk", g.zBaseURL);
     }
@@ -216,29 +216,30 @@
   mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
   cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
   nCol = 4;
   nRow = (cnt+nCol-1)/nCol;
   db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
-  @ <table border="0" width="100%%"><tr><td valign="top" width="25%%">
+  @ <table class="browser"><tr><td class="browser"><ul class="browser">
   i = 0;
   while( db_step(&q)==SQLITE_ROW ){
     const char *zFN;
     if( i==nRow ){
-      @ </td><td valign="top" width="25%%">
+      @ </ul></td><td class="browser"><ul class="browser">
       i = 0;
     }
     i++;
     zFN = db_column_text(&q, 0);
     if( zFN[0]=='/' ){
       zFN++;
       @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li>
     }else if( zCI ){
       const char *zUuid = db_column_text(&q, 1);
-      @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a>
+      @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a></li>
     }else{
-      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)</a>
+      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)
+      @     </a></li>
     }
   }
   db_finalize(&q);
-  @ </td></tr></table>
+  @ </ul></td></tr></table>
   style_footer();
 }

Index: src/db.c
==================================================================
--- src/db.c
+++ src/db.c
@@ -664,11 +664,11 @@
   }
 #endif
   if( file_isdir(zHome)!=1 ){
     fossil_fatal("invalid home directory: %s", zHome);
   }
-#ifndef __MINGW32__
+#ifndef _WIN32
   if( access(zHome, W_OK) ){
     fossil_fatal("home directory %s must be writeable", zHome);
   }
 #endif
   g.zHome = mprintf("%/", zHome);

Index: src/descendants.c
==================================================================
--- src/descendants.c
+++ src/descendants.c
@@ -318,14 +318,17 @@
   style_header("Leaves");
   login_anonymous_available();
   compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1);
   style_sidebox_begin("Nomenclature:", "33%");
   @ <ol>
-  @ <li> A <b>leaf</b> is a check-in with no descendants.</li>
-  @ <li> An <b>open leaf</b> is a leaf that does not have a "closed" tag
+  @ <li> A <div class="sideboxDescribed">leaf</div>
+  @ is a check-in with no descendants.</li>
+  @ <li> An <div class="sideboxDescribed">open leaf</div>
+  @ is a leaf that does not have a "closed" tag
   @ and is thus assumed to still be in use.</li>
-  @ <li> A <b>closed leaf</b> has a "closed" tag and is thus assumed to
+  @ <li> A <div class="sideboxDescribed">closed leaf</div>
+  @ has a "closed" tag and is thus assumed to
   @ be historical and no longer in active use.</li>
   @ </ol>
   style_sidebox_end();
 
   if( showAll ){
@@ -341,14 +344,14 @@
     " ORDER BY event.mtime DESC",
     timeline_query_for_www()
   );
   www_print_timeline(&q, TIMELINE_LEAFONLY, leaves_extra);
   db_finalize(&q);
-  @ <br clear="both">
-  @ <script>
+  @ <br />
+  @ <script  type="text/JavaScript">
   @ function xin(id){
   @ }
   @ function xout(id){
   @ }
   @ </script>
   style_footer();
 }

Index: src/finfo.c
==================================================================
--- src/finfo.c
+++ src/finfo.c
@@ -136,11 +136,11 @@
   hyperlinked_path(zFilename, &title);
   @ <h2>%b(&title)</h2>
   blob_reset(&title);
   pGraph = graph_init();
   @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
-  @ <table cellspacing=0 border=0 cellpadding=0>
+  @ <table class="timelineTable">
   while( db_step(&q)==SQLITE_ROW ){
     const char *zDate = db_column_text(&q, 0);
     const char *zCom = db_column_text(&q, 1);
     const char *zUser = db_column_text(&q, 2);
     int fpid = db_column_int(&q, 3);
@@ -157,22 +157,22 @@
     if( zBr==0 ) zBr = "trunk";
     gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr);
     if( memcmp(zDate, zPrevDate, 10) ){
       sprintf(zPrevDate, "%.10s", zDate);
       @ <tr><td>
-      @   <div class="divider"><nobr>%s(zPrevDate)</nobr></div>
+      @   <div class="divider">%s(zPrevDate)</div>
       @ </td></tr>
     }
     memcpy(zTime, &zDate[11], 5);
     zTime[5] = 0;
-    @ <tr><td valign="top" align="right">
+    @ <tr><td class="timelineTime">
     @ <a href="%s(g.zTop)/timeline?c=%t(zDate)">%s(zTime)</a></td>
-    @ <td width="20" align="left" valign="top"><div id="m%d(gidx)"></div></td>
+    @ <td class="timelineGraph"><div id="m%d(gidx)"></div></td>
     if( zBgClr && zBgClr[0] ){
-      @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
+      @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
     }else{
-      @ <td valign="top" align="left">
+      @ <td class="timelineTableCell">
     }
     sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid);
     sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin);
     if( zUuid ){
       if( g.okHistory ){
@@ -187,27 +187,29 @@
     hyperlink_to_uuid(zShortCkin);
     @ %h(zCom) (user: 
     hyperlink_to_user(zUser, zDate, "");
     @ branch: %h(zBr))
     if( g.okHistory && zUuid ){
+      const char *z = zFilename;
       if( fpid ){
         @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&amp;v2=%s(zUuid)">[diff]</a>
       }
-      @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&amp;filename=%h(zFilename)">
+      @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&amp;filename=%h(z)">
       @ [annotate]</a>
     }
-    @ </td>
+    @ </td></tr>
   }
   db_finalize(&q);
   if( pGraph ){
     graph_finish(pGraph, 1);
     if( pGraph->nErr ){
       graph_free(pGraph);
       pGraph = 0;
     }else{
-      @ <tr><td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
+      @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
+      @     </td></tr>
     }
   }
   @ </table>
   timeline_output_graph_javascript(pGraph);
   style_footer();
 }

Index: src/info.c
==================================================================
--- src/info.c
+++ src/info.c
@@ -194,15 +194,15 @@
       @ <div class="section">Tags And Properties</div>
       @ <ul>
     }
     @ <li>
     if( tagtype==0 ){
-      @ <b><s>%h(zTagname)</s></b> cancelled
+      @ <span class="infoTagCancelled">%h(zTagname)</span> cancelled
     }else if( zValue ){
-      @ <b>%h(zTagname)=%h(zValue)</b>
+      @ <span class="infoTag">%h(zTagname)=%h(zValue)</span>
     }else {
-      @ <b>%h(zTagname)</b>
+      @ <span class="infoTag">%h(zTagname)</span>
     }
     if( tagtype==2 ){
       if( zOrigUuid && zOrigUuid[0] ){
         @ inherited from
         hyperlink_to_uuid(zOrigUuid);
@@ -222,10 +222,11 @@
       }
       hyperlink_to_uuid(zSrcUuid);
       @ on
       hyperlink_to_date(zDate,0);
     }
+    @ </li>
   }
   db_finalize(&q);
   if( cnt ){
     @ </ul>
   }
@@ -276,18 +277,19 @@
     @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
     @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a>
     @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a>
     if( !showDiff ){
       @ &nbsp;&nbsp;
-      @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a>
+      @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&amp;v2=%S(zNew)">[diff]</a>
     }else{
       int rid1 = uuid_to_rid(zOld, 0);
       int rid2 = uuid_to_rid(zNew, 0);
       @ <blockquote><pre>
       append_diff(rid1, rid2);
       @ </pre></blockquote>
     }
+    @ </p>
   }else if( zOld ){
     @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
     @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a></p>
   }else{
     @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
@@ -354,11 +356,11 @@
                    TAG_COMMENT, rid);
     zUser = db_column_text(&q, 2);
     zComment = db_column_text(&q, 3);
     zDate = db_column_text(&q,1);
     @ <div class="section">Overview</div>
-    @ <p><table class="label-value">
+    @ <table class="label-value">
     @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
     if( g.okSetup ){
       @ (Record ID: %d(rid))
     }
     @ </td></tr>
@@ -397,13 +399,13 @@
       db_finalize(&q);
     }
     if( g.okHistory ){
       const char *zProjName = db_get("project-name", "unnamed");
       @ <tr><th>Timelines:</th><td>
-      @    <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a>
-      @    | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a>
-      @    | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&p=%S(zUuid)">both</a>
+      @   <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a>
+      @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a>
+      @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&amp;p=%S(zUuid)">both</a>
       db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
                      " WHERE rid=%d AND tagtype>0 "
                      "   AND tag.tagid=tagxref.tagid "
                      "   AND +tag.tagname GLOB 'sym-*'", rid);
       while( db_step(&q)==SQLITE_ROW ){
@@ -424,11 +426,11 @@
         @   | <a href="%s(g.zTop)/ci_edit?r=%S(zUuid)">edit</a>
       }
       @   </td>
       @ </tr>
     }
-    @ </table></p>
+    @ </table>
   }else{
     style_header("Check-in Information");
     login_anonymous_available();
   }
   db_finalize(&q);
@@ -616,11 +618,11 @@
 }
 
 
 /*
 ** WEBPAGE: vdiff
-** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN
+** URL: /vdiff?from=UUID&amp;to=UUID&amp;detail=BOOLEAN
 **
 ** Show all differences between two checkins.  
 */
 void vdiff_page(void){
   int ridFrom, ridTo;
@@ -638,11 +640,11 @@
   style_header("Check-in Differences");
   @ <h2>Difference From:</h2><blockquote>
   checkin_description(ridFrom);
   @ </blockquote><h2>To:</h2><blockquote>
   checkin_description(ridTo);
-  @ </blockquote><hr><p>
+  @ </blockquote><hr /><p>
 
   iFrom = iTo = 0;
   while( iFrom<mFrom.nFile && iTo<mTo.nFile ){
     int cmp;
     if( iFrom>=mFrom.nFile ){
@@ -880,18 +882,18 @@
   v1 = name_to_rid_www("v1");
   v2 = name_to_rid_www("v2");
   if( v1==0 || v2==0 ) fossil_redirect_home();
   style_header("Diff");
   @ <h2>Differences From:</h2>
-  @ <blockquote>
+  @ <blockquote><p>
   object_description(v1, 1, 0);
-  @ </blockquote>
+  @ </p></blockquote>
   @ <h2>To:</h2>
-  @ <blockquote>
+  @ <blockquote><p>
   object_description(v2, 1, 0);
-  @ </blockquote>
-  @ <hr>
+  @ </p></blockquote>
+  @ <hr />
   @ <blockquote><pre>
   content_get(v1, &c1);
   content_get(v2, &c2);
   blob_zero(&diff);
   text_diff(&c1, &c2, &diff, 4, 1);
@@ -994,27 +996,27 @@
   if( !g.okRead ){ login_needed(); return; }
   if( rid==0 ) fossil_redirect_home();
   if( g.okAdmin ){
     const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
     if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
-      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
+      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&amp;sub=1",
             g.zTop, zUuid);
     }else{
       style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
             g.zTop, zUuid);
     }
   }
   style_header("Hex Artifact Content");
   zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid);
   @ <h2>Artifact %s(zUuid):</h2>
-  @ <blockquote>
+  @ <blockquote><p>
   blob_zero(&downloadName);
   object_description(rid, 0, &downloadName);
   style_submenu_element("Download", "Download", 
         "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid);
-  @ </blockquote>
-  @ <hr>
+  @ </p></blockquote>
+  @ <hr />
   content_get(rid, &content);
   @ <blockquote><pre>
   hexdump(&content);
   @ </pre></blockquote>
   style_footer();
@@ -1076,21 +1078,21 @@
   if( !g.okRead ){ login_needed(); return; }
   if( rid==0 ) fossil_redirect_home();
   if( g.okAdmin ){
     const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
     if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
-      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
+      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&amp;sub=1",
             g.zTop, zUuid);
     }else{
       style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
             g.zTop, zUuid);
     }
   }
   style_header("Artifact Content");
   zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
   @ <h2>Artifact %s(zUuid)</h2>
-  @ <blockquote>
+  @ <blockquote><p>
   blob_zero(&downloadName);
   object_description(rid, 0, &downloadName);
   style_submenu_element("Download", "Download", 
           "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid);
   zMime = mimetype_from_name(blob_str(&downloadName));
@@ -1100,25 +1102,25 @@
         style_submenu_element("Html", "Html",
                               "%s/artifact?name=%s", g.zTop, zUuid);
       }else{
         renderAsHtml = 1;
         style_submenu_element("Text", "Text",
-                              "%s/artifact?name=%s&txt=1", g.zTop, zUuid);
+                              "%s/artifact?name=%s&amp;txt=1", g.zTop, zUuid);
       }
     }else if( strcmp(zMime, "application/x-fossil-wiki")==0 ){
       if( P("txt") ){
         style_submenu_element("Wiki", "Wiki",
                               "%s/artifact?name=%s", g.zTop, zUuid);
       }else{
         renderAsWiki = 1;
         style_submenu_element("Text", "Text",
-                              "%s/artifact?name=%s&txt=1", g.zTop, zUuid);
+                              "%s/artifact?name=%s&amp;txt=1", g.zTop, zUuid);
       }
     }
   }
-  @ </blockquote>
-  @ <hr>
+  @ </p></blockquote>
+  @ <hr />
   content_get(rid, &content);
   if( renderAsWiki ){
     wiki_convert(&content, 0, 0);
   }else if( renderAsHtml ){
     @ <div>
@@ -1131,11 +1133,11 @@
       @ <pre>
       @ %h(blob_str(&content))
       @ </pre>
       style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid);
     }else if( strncmp(zMime, "image/", 6)==0 ){
-      @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&m=%s(zMime)"></img>
+      @ <img src="%s(g.zBaseURL)/raw?name=%s(zUuid)&amp;m=%s(zMime)"></img>
       style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid);
     }else{
       @ <pre>
       hexdump(&content);
       @ </pre>
@@ -1164,11 +1166,11 @@
   rid = name_to_rid_www("name");
   if( rid==0 ){ fossil_redirect_home(); }
   zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
   if( g.okAdmin ){
     if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
-      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
+      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&amp;sub=1",
             g.zTop, zUuid);
     }else{
       style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
             g.zTop, zUuid);
     }
@@ -1442,11 +1444,11 @@
     int nTag = 0;
     @ <b>Preview:</b>
     @ <blockquote>
     @ <table border=0>
     if( zNewColor && zNewColor[0] ){
-      @ <tr><td bgcolor="%h(zNewColor)">
+      @ <tr><td style="background-color: %h(zNewColor);">
     }else{
       @ <tr><td>
     }
     wiki_convert(&comment, 0, WIKI_INLINE);
     blob_zero(&suffix);
@@ -1467,11 +1469,11 @@
     db_finalize(&q);
     blob_appendf(&suffix, ")");
     @ %s(blob_str(&suffix))
     @ </td></tr></table>
     @ </blockquote>
-    @ <hr>
+    @ <hr />
     blob_reset(&suffix);
   }
   @ <p>Make changes to attributes of check-in
   @ [<a href="ci?name=%s(zUuid)">%s(zUuid)</a>]:</p>
   @ <form action="%s(g.zBaseURL)/ci_edit" method="POST">
@@ -1505,11 +1507,11 @@
   }
   @ Propagate color to descendants</input></td></tr>
   @ <tr>
   for(i=0; i<nColor; i++){
     if( aColor[i].zColor[0] ){
-      @ <td bgcolor="%h(aColor[i].zColor)">
+      @ <td style="background-color: %h(aColor[i].zColor);">
     }else{
       @ <td>
     }
     if( strcmp(zNewColor, aColor[i].zColor)==0 ){
       @ <input type="radio" name="clr" value="%h(aColor[i].zColor)" checked>
@@ -1541,13 +1543,13 @@
     int tagid = db_column_int(&q, 0);
     const char *zTagName = db_column_text(&q, 1);
     char zLabel[30];
     sprintf(zLabel, "c%d", tagid);
     if( P(zLabel) ){
-      @ <br><input type="checkbox" name="c%d(tagid)" checked>
+      @ <br /><input type="checkbox" name="c%d(tagid)" checked>
     }else{
-      @ <br><input type="checkbox" name="c%d(tagid)">
+      @ <br /><input type="checkbox" name="c%d(tagid)">
     }
     if( strncmp(zTagName, "sym-", 4)==0 ){
       @ Cancel tag <b>%h(&zTagName[4])</b>
     }else{
       @ Cancel special tag <b>%h(zTagName)</b>

Index: src/login.c
==================================================================
--- src/login.c
+++ src/login.c
@@ -153,21 +153,21 @@
     if( db_int(1, "SELECT 0 FROM user"
                   " WHERE uid=%d AND (pw=%Q OR pw=%Q)", 
                   g.userUid, zPasswd, zSha1Pw) ){
       sleep(1);
       zErrMsg = 
-         @ <p><font color="red">
+         @ <p><span class="loginError">
          @ You entered an incorrect old password while attempting to change
          @ your password.  Your password is unchanged.
-         @ </font></p>
+         @ </span></p>
       ;
     }else if( strcmp(zNew1,zNew2)!=0 ){
       zErrMsg = 
-         @ <p><font color="red">
+         @ <p><span class="loginError">
          @ The two copies of your new passwords do not match.
          @ Your password is unchanged.
-         @ </font></p>
+         @ </span></p>
       ;
     }else{
       char *zNewPw = sha1_shared_secret(zNew1, g.zLogin);
       db_multi_exec(
          "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
@@ -206,13 +206,13 @@
         zUsername, zPasswd, zSha1Pw
     );
     if( uid<=0 ){
       sleep(1);
       zErrMsg = 
-         @ <p><font color="red">
+         @ <p><span class="loginError">
          @ You entered an unknown user or an incorrect password.
-         @ </font></p>
+         @ </span></p>
       ;
     }else{
       char *zCookie;
       const char *zCookieName = login_cookie_name();
       const char *zExpire = db_get("cookie-expire","8766");
@@ -229,38 +229,38 @@
       redirect_to_g();
     }
   }
   style_header("Login/Logout");
   @ %s(zErrMsg)
-  @ <form action="login" method="POST">
+  @ <form action="login" method="post">
   if( P("g") ){
-    @ <input type="hidden" name="g" value="%h(P("g"))">
+    @ <input type="hidden" name="g" value="%h(P("g"))" />
   }
-  @ <table align="left" hspace="10">
+  @ <table class="login_out">
   @ <tr>
-  @   <td align="right">User ID:</td>
+  @   <td class="login_out_label">User ID:</td>
   if( anonFlag ){
-    @   <td><input type="text" id="u" name="u" value="anonymous" size=30></td>
+    @ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td>
   }else{
-    @   <td><input type="text" id="u" name="u" value="" size=30></td>
+    @ <td><input type="text" id="u" name="u" value="" size="30" /></td>
   }
   @ </tr>
   @ <tr>
-  @  <td align="right">Password:</td>
-  @   <td><input type="password" id="p" name="p" value="" size=30></td>
+  @  <td class="login_out_label">Password:</td>
+  @   <td><input type="password" id="p" name="p" value="" size="30" /></td>
   @ </tr>
   if( g.zLogin==0 ){
     zAnonPw = db_text(0, "SELECT pw FROM user"
                          " WHERE login='anonymous'"
                          "   AND cap!=''");
   }
   @ <tr>
   @   <td></td>
-  @   <td><input type="submit" name="in" value="Login"></td>
+  @   <td><input type="submit" name="in" value="Login" /></td>
   @ </tr>
   @ </table>
-  @ <script>document.getElementById('u').focus()</script>
+  @ <script type="text/JavaScript">document.getElementById('u').focus()</script>
   if( g.zLogin==0 ){
     @ <p>Enter
   }else{
     @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p>
     @ <p>To change your login to a different user, enter
@@ -273,46 +273,46 @@
     unsigned int uSeed = captcha_seed();
     char const *zDecoded = captcha_decode(uSeed);
     int bAutoCaptcha = db_get_boolean("auto-captcha", 1);
     char *zCaptcha = captcha_render(zDecoded);
 
-    @ <input type="hidden" name="cs" value="%u(uSeed)"/>
-    @ <p>Visitors may enter <b>anonymous</b> as the user-ID with
+    @ <p><input type="hidden" name="cs" value="%u(uSeed)" />
+    @ Visitors may enter <b>anonymous</b> as the user-ID with
     @ the 8-character hexadecimal password shown below:</p>
-    @ <center><table border="1" cellpadding="10"><tr><td><pre>
+    @ <div class="captcha"><table class="captcha"><tr><td><pre>
     @ %s(zCaptcha)
     @ </pre></td></tr></table>
     if( bAutoCaptcha ) {
         @ <input type="button" value="Fill out captcha"
         @  onclick="document.getElementById('u').value='anonymous';
-        @           document.getElementById('p').value='%s(zDecoded)';"/>
+        @           document.getElementById('p').value='%s(zDecoded)';" />
     }
-    @ </center>
+    @ </div>
     free(zCaptcha);
   }
   if( g.zLogin ){
-    @ <br clear="both"><hr>
+    @ <hr />
     @ <p>To log off the system (and delete your login cookie)
-    @  press the following button:<br>
-    @ <input type="submit" name="out" value="Logout"></p>
+    @  press the following button:<br />
+    @ <input type="submit" name="out" value="Logout" /></p>
   }
   @ </form>
   if( g.okPassword ){
-    @ <br clear="both"><hr>
+    @ <hr />
     @ <p>To change your password, enter your old password and your
     @ new password twice below then press the "Change Password"
     @ button.</p>
-    @ <form action="login" method="POST">
+    @ <form action="login" method="post">
     @ <table>
-    @ <tr><td align="right">Old Password:</td>
-    @ <td><input type="password" name="p" size=30></td></tr>
-    @ <tr><td align="right">New Password:</td>
-    @ <td><input type="password" name="n1" size=30></td></tr>
-    @ <tr><td align="right">Repeat New Password:</td>
-    @ <td><input type="password" name="n2" size=30></td></tr>
+    @ <tr><td class="login_out_label">Old Password:</td>
+    @ <td><input type="password" name="p" size="30" /></td></tr>
+    @ <tr><td class="login_out_label">New Password:</td>
+    @ <td><input type="password" name="n1" size="30" /></td></tr>
+    @ <tr><td class="login_out_label">Repeat New Password:</td>
+    @ <td><input type="password" name="n2" size="30" /></td></tr>
     @ <tr><td></td>
-    @ <td><input type="submit" value="Change Password"></td></tr>
+    @ <td><input type="submit" value="Change Password" /></td></tr>
     @ </table>
     @ </form>
   }
   style_footer();
 }
@@ -596,22 +596,22 @@
   if( !g.okHistory &&
       db_exists("SELECT 1 FROM user"
                 " WHERE login='anonymous'"
                 "   AND cap LIKE '%%h%%'") ){
     const char *zUrl = PD("REQUEST_URI", "index");
-    @ <p>Many <font color="red">hyperlinks are disabled.</font><br />
-    @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
+    @ <p>Many <span class="disabled">hyperlinks are disabled.</span><br />
+    @ Use <a href="%s(g.zTop)/login?anon=1&amp;g=%T(zUrl)">anonymous login</a>
     @ to enable hyperlinks.</p>
   }
 }
 
 /*
 ** While rendering a form, call this routine to add the Anti-CSRF token
 ** as a hidden element of the form.
 */
 void login_insert_csrf_secret(void){
-  @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)">
+  @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)" />
 }
 
 /*
 ** Before using the results of a form, first call this routine to verify
 ** that ths Anti-CSRF token is present and is valid.  If the Anti-CSRF token

Index: src/report.c
==================================================================
--- src/report.c
+++ src/report.c
@@ -277,13 +277,13 @@
   zSQL = db_column_text(&q, 1);
   zOwner = db_column_text(&q, 2);
   zClrKey = db_column_text(&q, 3);
   @ <table cellpadding=0 cellspacing=0 border=0>
   @ <tr><td valign="top" align="right">Title:</td><td width=15></td>
-  @ <td colspan=3>%h(zTitle)</td></tr>
+  @ <td colspan="3">%h(zTitle)</td></tr>
   @ <tr><td valign="top" align="right">Owner:</td><td></td>
-  @ <td colspan=3>%h(zOwner)</td></tr>
+  @ <td colspan="3">%h(zOwner)</td></tr>
   @ <tr><td valign="top" align="right">SQL:</td><td></td>
   @ <td valign="top"><pre>
   @ %h(zSQL)
   @ </pre></td>
   @ <td width=15></td><td valign="top">
@@ -393,21 +393,21 @@
     }
   }
   if( zOwner==0 ) zOwner = g.zLogin;
   style_submenu_element("Cancel", "Cancel", "reportlist");
   if( rn>0 ){
-    style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
+    style_submenu_element("Delete", "Delete", "rptedit?rn=%d&amp;del1=1", rn);
   }
   style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
   if( zErr ){
     @ <blockquote><font color="#ff0000"><b>%h(zErr)</b></font></blockquote>
   }
   @ <form action="rptedit" method="POST">
   @ <input type="hidden" name="rn" value="%d(rn)">
-  @ <p>Report Title:<br>
+  @ <p>Report Title:<br />
   @ <input type="text" name="t" value="%h(zTitle)" size="60"></p>
-  @ <p>Enter a complete SQL query statement against the "TICKET" table:<br>
+  @ <p>Enter a complete SQL query statement against the "TICKET" table:<br />
   @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea>
   @ </p>
   login_insert_csrf_secret();
   if( g.okAdmin ){
     @ <p>Report owner:
@@ -417,11 +417,11 @@
     @ <input type="hidden" name="w" value="%h(zOwner)">
   }
   @ <p>Enter an optional color key in the following box.  (If blank, no
   @ color key is displayed.)  Each line contains the text for a single
   @ entry in the key.  The first token of each line is the background
-  @ color for that line.<br>
+  @ color for that line.<br />
   @ <textarea name="k" rows="8" cols="50">%h(zClrKey)</textarea>
   @ </p>
   if( !g.okAdmin && strcmp(zOwner,g.zLogin)!=0 ){
     @ <p>This report format is owned by %h(zOwner).  You are not allowed
     @ to change it.</p>
@@ -448,11 +448,11 @@
   zSchema = db_text(0,"SELECT sql FROM sqlite_master WHERE name='ticket'");
   if( zSchema==0 ){
     zSchema = db_text(0,"SELECT sql FROM repository.sqlite_master"
                         " WHERE name='ticket'");
   }
-  @ <hr><h3>TICKET Schema</h3>
+  @ <hr /><h3>TICKET Schema</h3>
   @ <blockquote><pre>
   @ %h(zSchema)
   @ </pre></blockquote>
   @ <h3>Notes</h3>
   @ <ul>
@@ -829,14 +829,14 @@
     while( isspace(*zSafeKey) ) zSafeKey++;
     for(i=0; zSafeKey[i] && !isspace(zSafeKey[i]); i++){}
     for(j=i; isspace(zSafeKey[j]); j++){}
     for(k=j; zSafeKey[k] && zSafeKey[k]!='\n' && zSafeKey[k]!='\r'; k++){}
     if( !horiz ){
-      cgi_printf("<tr bgcolor=\"%.*s\"><td>%.*s</td></tr>\n",
+      cgi_printf("<tr style=\"background-color: %.*s;\"><td>%.*s</td></tr>\n",
         i, zSafeKey, k-j, &zSafeKey[j]);
     }else{
-      cgi_printf("<td bgcolor=\"%.*s\">%.*s</td>\n",
+      cgi_printf("<td style=\"background-color: %.*s;\">%.*s</td>\n",
         i, zSafeKey, k-j, &zSafeKey[j]);
     }
     zSafeKey += k;
   }
   free(zToFree);
@@ -907,11 +907,11 @@
   if( !tabs ){
     struct GenerateHTML sState;
 
     db_multi_exec("PRAGMA empty_result_callbacks=ON");
     style_submenu_element("Raw", "Raw", 
-      "rptview?tablist=1&%s", PD("QUERY_STRING",""));
+      "rptview?tablist=1&amp;%s", PD("QUERY_STRING",""));
     if( g.okAdmin 
        || (g.okTktFmt && g.zLogin && zOwner && strcmp(g.zLogin,zOwner)==0) ){
       style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn);
     }
     if( g.okTktFmt ){
@@ -921,12 +921,12 @@
       style_submenu_element("New Ticket", "Create a new ticket",
         "%s/tktnew", g.zTop);
     }
     style_header(zTitle);
     output_color_key(zClrKey, 1, 
-        "border=0 cellpadding=3 cellspacing=0 class=\"report\"");
-    @ <table border=1 cellpadding=2 cellspacing=0 class="report">
+        "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
+    @ <table border="1" cellpadding="2" cellspacing="0" class="report">
     sState.rn = rn;
     sState.nCount = 0;
     sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr1);
     sqlite3_exec(g.db, zSql, generate_html, &sState, &zErr2);
     sqlite3_set_authorizer(g.db, 0, 0);

Index: src/setup.c
==================================================================
--- src/setup.c
+++ src/setup.c
@@ -99,42 +99,40 @@
     return;
   }
 
   style_submenu_element("Add", "Add User", "setup_uedit");
   style_header("User List");
-  @ <table border="0" cellpadding="0" cellspacing="25">
-  @ <tr><td valign="top">
-  @ <b>Users:</b>
-  @ <table border="1" cellpadding="10"><tr><td>
-  @ <table cellspacing=0 cellpadding=0 border=0>
+  @ <table class="usetupLayoutTable">
+  @ <tr><td class="usetupColumnLayout">
+  @ <span class="note">Users:</span>
+  @ <table class="usetupUserList">
   @ <tr>
-  @   <th align="right">User&nbsp;ID</th><td width="20">&nbsp;</td>
-  @   <th>Capabilities</th><td width="15">&nbsp;</td>
-  @   <th>Contact&nbsp;Info</th>
+  @   <th class="usetupListUser" style="text-align: right;padding-right: 20px;">User&nbsp;ID</th>
+  @   <th class="usetupListCap" style="text-align: center;padding-right: 15px;">Capabilities</th>
+  @   <th class="usetupListCon"  style="text-align: left;">Contact&nbsp;Info</th>
   @ </tr>
   db_prepare(&s, "SELECT uid, login, cap, info FROM user ORDER BY login");
   while( db_step(&s)==SQLITE_ROW ){
     const char *zCap = db_column_text(&s, 2);
     if( strstr(zCap, "s") ) zCap = "s";
     @ <tr>
-    @ <td align="right">
+    @ <td class="usetupListUser" style="text-align: right;padding-right: 20px;white-space:nowrap;">
     if( g.okAdmin && (zCap[0]!='s' || g.okSetup) ){
       @ <a href="setup_uedit?id=%d(db_column_int(&s,0))">
     }
-    @ <nobr>%h(db_column_text(&s,1))</nobr>
+    @ %h(db_column_text(&s,1))
     if( g.okAdmin ){
       @ </a>
     }
-    @ </td><td>&nbsp;&nbsp;&nbsp;</td>
-    @ <td align="center">%s(zCap)</td>
-    @ <td>&nbsp;&nbsp;&nbsp;</td>
-    @ <td align="left">%s(db_column_text(&s,3))</td>
+    @ </td>
+    @ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td>
+    @ <td  class="usetupListCon"  style="text-align: left;">%s(db_column_text(&s,3))</td>
     @ </tr>
   }
-  @ </table></td></tr></table>
-  @ <td valign="top">
-  @ <b>Notes:</b>
+  @ </table>
+  @ </td><td class="usetupColumnLayout">
+  @ <span class="note">Notes:</span>
   @ <ol>
   @ <li><p>The permission flags are as follows:</p>
   @ <table>
      @ <tr><td valign="top"><b>a</b></td>
      @   <td><i>Admin:</i> Create and delete users</td></tr>
@@ -181,31 +179,35 @@
      @   user <tt>developer</tt></td></tr>
      @ <tr><td valign="top"><b>w</b></td>
      @   <td><i>Write-Tkt:</i> Edit tickets</td></tr>
      @ <tr><td valign="top"><b>z</b></td>
      @   <td><i>Zip download:</i> Download a baseline via the
-     @   <tt>/zip</tt> URL even without check<b>o</b>ut
-     @    and <b>h</b>istory permissions</td></tr>
+     @   <tt>/zip</tt> URL even without 
+     @    check<span class="capability">o</span>ut
+     @    and <span class="capability">h</span>istory permissions</td></tr>
   @ </table>
   @ </li>
   @
   @ <li><p>
-  @ Every user, logged in or not, inherits the privileges of <b>nobody</b>.
+  @ Every user, logged in or not, inherits the privileges of
+  @ <span class="usertype">nobody</span>.
   @ </p></li>
   @
   @ <li><p>
-  @ Any human can login as <b>anonymous</b> since the password is
-  @ clearly displayed on the login page for them to type.  The purpose
-  @ of requiring anonymous to log in is to prevent access by spiders.
+  @ Any human can login as <span class="usertype">anonymous</span> since the
+  @ password is clearly displayed on the login page for them to type. The
+  @ purpose of requiring anonymous to log in is to prevent access by spiders.
   @ Every logged-in user inherits the combined privileges of
-  @ <b>anonymous</b> and
-  @ <b>nobody</b>.
+  @ <span class="usertype">anonymous</span> and
+  @ <span class="usertype">nobody</span>.
   @ </p></li>
   @
   @ <li><p>
-  @ Users with privilege <b>v</b> inherit the combined privileges of
-  @ <b>developer</b>, <b>anonymous</b>, and <b>nobody</b>.
+  @ Users with privilege <span class="capability">v</span> inherit the combined
+  @ privileges of <span class="usertype">developer</span>,
+  @ <span class="usertype">anonymous</span>, and
+  @ <span class="usertype">nobody</span>.
   @ </p></li>
   @
   @ </ol>
   @ </td></tr></table>
   style_footer();
@@ -323,12 +325,12 @@
     }
     if( uid>0 &&
         db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid)
     ){
       style_header("User Creation Error");
-      @ <font color="red">Login "%h(zLogin)" is already used by a different
-      @ user.</font>
+      @ <span class="loginError">Login "%h(zLogin)" is already used by
+      @ a different user.</span>
       @
       @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
       style_footer();
       return;
     }
@@ -353,65 +355,69 @@
   if( uid ){
     zLogin = db_text("", "SELECT login FROM user WHERE uid=%d", uid);
     zInfo = db_text("", "SELECT info FROM user WHERE uid=%d", uid);
     zCap = db_text("", "SELECT cap FROM user WHERE uid=%d", uid);
     zPw = db_text("", "SELECT pw FROM user WHERE uid=%d", uid);
-    if( strchr(zCap, 'a') ) oaa = " checked";
-    if( strchr(zCap, 'b') ) oab = " checked";
-    if( strchr(zCap, 'c') ) oac = " checked";
-    if( strchr(zCap, 'd') ) oad = " checked";
-    if( strchr(zCap, 'e') ) oae = " checked";
-    if( strchr(zCap, 'f') ) oaf = " checked";
-    if( strchr(zCap, 'g') ) oag = " checked";
-    if( strchr(zCap, 'h') ) oah = " checked";
-    if( strchr(zCap, 'i') ) oai = " checked";
-    if( strchr(zCap, 'j') ) oaj = " checked";
-    if( strchr(zCap, 'k') ) oak = " checked";
-    if( strchr(zCap, 'm') ) oam = " checked";
-    if( strchr(zCap, 'n') ) oan = " checked";
-    if( strchr(zCap, 'o') ) oao = " checked";
-    if( strchr(zCap, 'p') ) oap = " checked";
-    if( strchr(zCap, 'r') ) oar = " checked";
-    if( strchr(zCap, 's') ) oas = " checked";
-    if( strchr(zCap, 't') ) oat = " checked";
-    if( strchr(zCap, 'u') ) oau = " checked";
-    if( strchr(zCap, 'v') ) oav = " checked";
-    if( strchr(zCap, 'w') ) oaw = " checked";
-    if( strchr(zCap, 'z') ) oaz = " checked";
+    if( strchr(zCap, 'a') ) oaa = " checked=\"checked\"";
+    if( strchr(zCap, 'b') ) oab = " checked=\"checked\"";
+    if( strchr(zCap, 'c') ) oac = " checked=\"checked\"";
+    if( strchr(zCap, 'd') ) oad = " checked=\"checked\"";
+    if( strchr(zCap, 'e') ) oae = " checked=\"checked\"";
+    if( strchr(zCap, 'f') ) oaf = " checked=\"checked\"";
+    if( strchr(zCap, 'g') ) oag = " checked=\"checked\"";
+    if( strchr(zCap, 'h') ) oah = " checked=\"checked\"";
+    if( strchr(zCap, 'i') ) oai = " checked=\"checked\"";
+    if( strchr(zCap, 'j') ) oaj = " checked=\"checked\"";
+    if( strchr(zCap, 'k') ) oak = " checked=\"checked\"";
+    if( strchr(zCap, 'm') ) oam = " checked=\"checked\"";
+    if( strchr(zCap, 'n') ) oan = " checked=\"checked\"";
+    if( strchr(zCap, 'o') ) oao = " checked=\"checked\"";
+    if( strchr(zCap, 'p') ) oap = " checked=\"checked\"";
+    if( strchr(zCap, 'r') ) oar = " checked=\"checked\"";
+    if( strchr(zCap, 's') ) oas = " checked=\"checked\"";
+    if( strchr(zCap, 't') ) oat = " checked=\"checked\"";
+    if( strchr(zCap, 'u') ) oau = " checked=\"checked\"";
+    if( strchr(zCap, 'v') ) oav = " checked=\"checked\"";
+    if( strchr(zCap, 'w') ) oaw = " checked=\"checked\"";
+    if( strchr(zCap, 'z') ) oaz = " checked=\"checked\"";
   }
 
   /* figure out inherited permissions */
   memset(inherit, 0, sizeof(inherit));
   if( strcmp(zLogin, "developer") ){
     char *z1, *z2;
     z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
     while( z1 && *z1 ){
-      inherit[0x7f & *(z1++)] = "<font color=\"red\">&bull;</font>";
+      inherit[0x7f & *(z1++)] =
+         "<span class=\"ueditInheritDeveloper\">&bull;</span>";
     }
     free(z2);
   }
   if( strcmp(zLogin, "reader") ){
     char *z1, *z2;
     z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
     while( z1 && *z1 ){
-      inherit[0x7f & *(z1++)] = "<font color=\"black\">&bull;</font>";
+      inherit[0x7f & *(z1++)] =
+          "<span class=\"ueditInheritReader\">&bull;</span>";
     }
     free(z2);
   }
   if( strcmp(zLogin, "anonymous") ){
     char *z1, *z2;
     z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
     while( z1 && *z1 ){
-      inherit[0x7f & *(z1++)] = "<font color=\"blue\">&bull;</font>";
+      inherit[0x7f & *(z1++)] =
+           "<span class=\"ueditInheritAnonymous\">&bull;</span>";
     }
     free(z2);
   }
   if( strcmp(zLogin, "nobody") ){
     char *z1, *z2;
     z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
     while( z1 && *z1 ){
-      inherit[0x7f & *(z1++)] = "<font color=\"green\">&bull;</font>";
+      inherit[0x7f & *(z1++)] =
+           "<span class=\"ueditInheritNobody\">&bull;</span>";
     }
     free(z2);
   }
 
   /* Begin generating the page
@@ -420,77 +426,79 @@
   if( uid ){
     style_header(mprintf("Edit User %h", zLogin));
   }else{
     style_header("Add A New User");
   }
-  @ <table align="left" hspace="20" vspace="10"><tr><td>
-  @ <form action="%s(g.zPath)" method="POST">
+  @ <div class="ueditCapBox">
+  @ <form action="%s(g.zPath)" method="post"><div>
   login_insert_csrf_secret();
   @ <table>
   @ <tr>
-  @   <td align="right"><nobr>User ID:</nobr></td>
+  @   <td class="usetupEditLabel">User ID:</td>
   if( uid ){
-    @   <td>%d(uid) <input type="hidden" name="id" value="%d(uid)"></td>
+    @   <td>%d(uid) <input type="hidden" name="id" value="%d(uid)" /></td>
   }else{
-    @   <td>(new user)<input type="hidden" name="id" value=0></td>
+    @   <td>(new user)<input type="hidden" name="id" value="0" /></td>
   }
   @ </tr>
+  @ <tr>
+  @   <td class="usetupEditLabel">Login:</td>
+  @   <td><input type="text" name="login" value="%h(zLogin)" /></td>
+  @ </tr>
   @ <tr>
-  @   <td align="right"><nobr>Login:</nobr></td>
-  @   <td><input type="text" name="login" value="%h(zLogin)"></td>
+  @   <td class="usetupEditLabel">Contact&nbsp;Info:</td>
+  @   <td><input type="text" name="info" size="40" value="%h(zInfo)" /></td>
   @ </tr>
   @ <tr>
-  @   <td align="right"><nobr>Contact&nbsp;Info:</nobr></td>
-  @   <td><input type="text" name="info" size=40 value="%h(zInfo)"></td>
-  @ </tr>
-  @ <tr>
-  @   <td align="right" valign="top">Capabilities:</td>
+  @   <td class="usetupEditLabel">Capabilities:</td>
   @   <td>
 #define B(x) inherit[x]
   if( g.okSetup ){
-    @    <input type="checkbox" name="as"%s(oas)/>%s(B('s'))Setup<br>
-  }
-  @    <input type="checkbox" name="aa"%s(oaa)/>%s(B('a'))Admin<br>
-  @    <input type="checkbox" name="ad"%s(oad)/>%s(B('d'))Delete<br>
-  @    <input type="checkbox" name="ae"%s(oae)/>%s(B('e'))Email<br>
-  @    <input type="checkbox" name="ap"%s(oap)/>%s(B('p'))Password<br>
-  @    <input type="checkbox" name="ai"%s(oai)/>%s(B('i'))Check-In<br>
-  @    <input type="checkbox" name="ao"%s(oao)/>%s(B('o'))Check-Out<br>
-  @    <input type="checkbox" name="ah"%s(oah)/>%s(B('h'))History<br>
-  @    <input type="checkbox" name="au"%s(oau)/>%s(B('u'))Reader<br>
-  @    <input type="checkbox" name="av"%s(oav)/>%s(B('v'))Developer<br>
-  @    <input type="checkbox" name="ag"%s(oag)/>%s(B('g'))Clone<br>
-  @    <input type="checkbox" name="aj"%s(oaj)/>%s(B('j'))Read Wiki<br>
-  @    <input type="checkbox" name="af"%s(oaf)/>%s(B('f'))New Wiki<br>
-  @    <input type="checkbox" name="am"%s(oam)/>%s(B('m'))Append Wiki<br>
-  @    <input type="checkbox" name="ak"%s(oak)/>%s(B('k'))Write Wiki<br>
-  @    <input type="checkbox" name="ab"%s(oab)/>%s(B('b'))Attachments<br>
-  @    <input type="checkbox" name="ar"%s(oar)/>%s(B('r'))Read Ticket<br>
-  @    <input type="checkbox" name="an"%s(oan)/>%s(B('n'))New Ticket<br>
-  @    <input type="checkbox" name="ac"%s(oac)/>%s(B('c'))Append Ticket<br>
-  @    <input type="checkbox" name="aw"%s(oaw)/>%s(B('w'))Write Ticket<br>
-  @    <input type="checkbox" name="at"%s(oat)/>%s(B('t'))Ticket Report<br>
-  @    <input type="checkbox" name="az"%s(oaz)/>%s(B('z'))Download Zip
+    @    <input type="checkbox" name="as"%s(oas) />%s(B('s'))Setup<br />
+  }
+  @    <input type="checkbox" name="aa"%s(oaa) />%s(B('a'))Admin<br />
+  @    <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br />
+  @    <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br />
+  @    <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br />
+  @    <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br />
+  @    <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br />
+  @    <input type="checkbox" name="ah"%s(oah) />%s(B('h'))History<br />
+  @    <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br />
+  @    <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br />
+  @    <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br />
+  @    <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br />
+  @    <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br />
+  @    <input type="checkbox" name="am"%s(oam) />%s(B('m'))Append Wiki<br />
+  @    <input type="checkbox" name="ak"%s(oak) />%s(B('k'))Write Wiki<br />
+  @    <input type="checkbox" name="ab"%s(oab) />%s(B('b'))Attachments<br />
+  @    <input type="checkbox" name="ar"%s(oar) />%s(B('r'))Read Ticket<br />
+  @    <input type="checkbox" name="an"%s(oan) />%s(B('n'))New Ticket<br />
+  @    <input type="checkbox" name="ac"%s(oac) />%s(B('c'))Append Ticket<br />
+  @    <input type="checkbox" name="aw"%s(oaw) />%s(B('w'))Write Ticket<br />
+  @    <input type="checkbox" name="at"%s(oat) />%s(B('t'))Ticket Report<br />
+  @    <input type="checkbox" name="az"%s(oaz) />%s(B('z'))Download Zip
   @   </td>
   @ </tr>
   @ <tr>
   @   <td align="right">Password:</td>
   if( zPw[0] ){
     /* Obscure the password for all users */
-    @   <td><input type="password" name="pw" value="**********"></td>
+    @   <td><input type="password" name="pw" value="**********" /></td>
   }else{
     /* Show an empty password as an empty input field */
-    @   <td><input type="password" name="pw" value=""></td>
+    @   <td><input type="password" name="pw" value="" /></td>
   }
   @ </tr>
   if( !higherUser ){
     @ <tr>
-    @   <td>&nbsp</td>
-    @   <td><input type="submit" name="submit" value="Apply Changes">
+    @   <td>&nbsp;</td>
+    @   <td><input type="submit" name="submit" value="Apply Changes" /></td>
     @ </tr>
   }
-  @ </table></td></tr></table>
+  @ </table>
+  @ </div></form>
+  @ </div>
   @ <h2>Privileges And Capabilities:</h2>
   @ <ul>
   if( higherUser ){
     @ <li><p><font color="blue"><b>
     @ User %h(zLogin) has Setup privileges and you only have Admin privileges
@@ -497,137 +505,160 @@
     @ so you are not permitted to make changes to %h(zLogin).
     @ </b></font></p></li>
     @
   }
   @ <li><p>
-  @ The <b>Setup</b> user can make arbitrary configuration changes.
-  @ An <b>Admin</b> user can add other users and change user privileges
+  @ The <span class="capability">Setup</span> user can make arbitrary
+  @ configuration changes. An <span class="usertype">Admin</span> user
+  @ can add other users and change user privileges
   @ and reset user passwords.  Both automatically get all other privileges
   @ listed below.  Use these two settings with discretion.
   @ </p></li>
   @
   @ <li><p>
-  @ The "<font color="green"><big>&bull;</big></font>" mark indicates
-  @ the privileges of "nobody" that are available to all users
-  @ regardless of whether or not they are logged in.
+  @ The "<span class="ueditInheritNobody"><big>&bull;</big></span>" mark
+  @ indicates the privileges of <span class="usertype">nobody</span> that
+  @ are available to all users regardless of whether or not they are logged in.
+  @ </p></li>
+  @
+  @ <li><p>
+  @ The "<span class="ueditInheritAnonymous"><big>&bull;</big></span>" mark
+  @ indicates the privileges of <span class="usertype">anonymous</span> that
+  @ are inherited by all logged-in users.
+  @ </p></li>
+  @
+  @ <li><p>
+  @ The "<span class="ueditInheritDeveloper"><big>&bull;</big></span>" mark
+  @ indicates the privileges of <span class="usertype">developer</span> that
+  @ are inherited by all users with the
+  @ <span class="capability">Developer</span> privilege.
+  @ </p></li>
+  @
+  @ <li><p>
+  @ The "<span class="ueditInheritReader"><big>&bull;</big></span>" mark
+  @ indicates the privileges of <span class="usertype">reader</span> that
+  @ are inherited by all users with the <span class="capability">Reader</span>
+  @ privilege.
+  @ </p></li>
+  @
+  @ <li><p>
+  @ The <span class="capability">Delete</span> privilege give the user the
+  @ ability to erase wiki, tickets, and attachments that have been added
+  @ by anonymous users.  This capability is intended for deletion of spam. 
+  @ The delete capability is only in effect for 24 hours after the item
+  @ is first posted.  The <span class="usertype">Setup</span> user can
+  @ delete anything at any time.
+  @ </p></li>
+  @
+  @ <li><p>
+  @ The <span class="capability">History</span> privilege allows a user
+  @ to see most hyperlinks. This is recommended ON for most logged-in users
+  @ but OFF for user "nobody" to avoid problems with spiders trying to walk
+  @ every historical version of every baseline and file.
+  @ </p></li>
+  @
+  @ <li><p>
+  @ The <span class="capability">Zip</span> privilege allows a user to
+  @ see the "download as ZIP"
+  @ hyperlink and permits access to the <tt>/zip</tt> page.  This allows
+  @ users to download ZIP archives without granting other rights like
+  @ <span class="capability">Read</span> or
+  @ <span class="capability">History</span>.  This privilege is recommended for
+  @ user <span class="usertype">nobody</span> so that automatic package
+  @ downloaders can obtain the sources without going through the login
+  @ procedure.
   @ </p></li>
   @
   @ <li><p>
-  @ The "<font color="blue"><big>&bull;</big></font>" mark indicates
-  @ the privileges of "anonymous" that are inherited by all logged-in users.
+  @ The <span class="capability">Check-in</span> privilege allows remote
+  @ users to "push". The <span class="capability">Check-out</span> privilege
+  @ allows remote users to "pull". The <span class="capability">Clone</span>
+  @ privilege allows remote users to "clone".
   @ </p></li>
   @
   @ <li><p>
-  @ The "<font color="red"><big>&bull;</big></font>" mark indicates
-  @ the privileges of "developer" that are inherited by all users with
-  @ the <b>Developer</b> privilege.
+  @ The <span class="capability">Read Wiki</span>,
+  @ <span class="capability">New Wiki</span>,
+  @ <span class="capability">Append Wiki</span>, and
+  @ <b>Write Wiki</b> privileges control access to wiki pages.  The
+  @ <span class="capability">Read Ticket</span>,
+  @ <span class="capability">New Ticket</span>,
+  @ <span class="capability">Append Ticket</span>, and
+  @ <span class="capability">Write Ticket</span> privileges control access
+  @ to trouble tickets.
+  @ The <span class="capability">Ticket Report</span> privilege allows
+  @ the user to create or edit ticket report formats.
   @ </p></li>
   @
   @ <li><p>
-  @ The "<font color="black"><big>&bull;</big></font>" mark indicates
-  @ the privileges of "reader" that are inherited by all users with
-  @ the <b>Reader</b> privilege.
-  @ </p></li>
-  @
-  @ <li><p>
-  @ The <b>Delete</b> privilege give the user the ability to erase
-  @ wiki, tickets, and attachments that have been added by anonymous
-  @ users.  This capability is intended for deletion of spam.  The
-  @ delete capability is only in effect for 24 hours after the item
-  @ is first posted.  The Setup user can delete anything at any time.
+  @ Users with the <span class="capability">Password</span> privilege
+  @ are allowed to change their own password.  Recommended ON for most
+  @ users but OFF for special users <span class="usertype">developer</span>,
+  @ <span class="usertype">anonymous</span>,
+  @ and <span class="usertype">nobody</span>.
   @ </p></li>
   @
   @ <li><p>
-  @ The <b>History</b> privilege allows a user to see most hyperlinks.
-  @ This is recommended ON for most logged-in users but OFF for
-  @ user "nobody" to avoid problems with spiders trying to walk every
-  @ historical version of every baseline and file.
-  @ </p></li>
-  @
-  @ <li><p>
-  @ The <b>Zip</b> privilege allows a user to see the "download as ZIP"
-  @ hyperlink and permits access to the <tt>/zip</tt> page.  This allows
-  @ users to download ZIP archives without granting other rights like
-  @ <b>Read</b> or <b>History</b>.  This privilege is recommended for
-  @ user <b>nobody</b> so that automatic package downloaders can obtain
-  @ the sources without going through the login procedure.
+  @ The <span class="capability">EMail</span> privilege allows the display of
+  @ sensitive information such as the email address of users and contact
+  @ information on tickets. Recommended OFF for 
+  @ <span class="usertype">anonymousy</span> and for
+  @ <span class="usertype">nobody</span> but ON for
+  @ <span class="usertype">developer</span>.
   @ </p></li>
   @
   @ <li><p>
-  @ The <b>Check-in</b> privilege allows remote users to "push".
-  @ The <b>Check-out</b> privilege allows remote users to "pull".
-  @ The <b>Clone</b> privilege allows remote users to "clone".
-  @ </li><p>
-  @
-  @ <li><p>
-  @ The <b>Read Wiki</b>, <b>New Wiki</b>, <b>Append Wiki</b>, and
-  @ <b>Write Wiki</b> privileges control access to wiki pages.  The
-  @ <b>Read Ticket</b>, <b>New Ticket</b>, <b>Append Ticket</b>, and
-  @ <b>Write Ticket</b> privileges control access to trouble tickets.
-  @ The <b>Ticket Report</b> privilege allows the user to create or edit
-  @ ticket report formats.
+  @ The <span class="capability">Attachment</span> privilege is needed in
+  @ order to add attachments to tickets or wiki.  Write privilege on the
+  @ ticket or wiki is also required.
   @ </p></li>
   @
-  @ <li><p>
-  @ Users with the <b>Password</b> privilege are allowed to change their
-  @ own password.  Recommended ON for most users but OFF for special
-  @ users "developer", "anonymous", and "nobody".
-  @ </p></li>
-  @
-  @ <li><p>
-  @ The <b>EMail</b> privilege allows the display of sensitive information
-  @ such as the email address of users and contact information on tickets.
-  @ Recommended OFF for "anonymous" and for "nobody" but ON for
-  @ "developer".
-  @ </p></li>
-  @
-  @ <li><p>
-  @ The <b>Attachment</b> privilege is needed in order to add attachments
-  @ to tickets or wiki.  Write privilege on the ticket or wiki is also
-  @ required.</p></li>
-  @
   @ <li><p>
   @ Login is prohibited if the password is an empty string.
   @ </p></li>
   @ </ul>
   @
   @ <h2>Special Logins</h2>
   @
   @ <ul>
   @ <li><p>
-  @ No login is required for user "<b>nobody</b>".  The capabilities
-  @ of the <b>nobody</b> user are inherited by all users, regardless of
-  @ whether or not they are logged in.  To disable universal access
-  @ to the repository, make sure no user named "<b>nobody</b>" exists or
-  @ that the <b>nobody</b> user has no capabilities enabled.
-  @ The password for <b>nobody</b> is ignore.  To avoid problems with
-  @ spiders overloading the server, it is recommended
-  @ that the 'h' (History) capability be turned off for the <b>nobody</b>
-  @ user.
+  @ No login is required for user <span class="usertype">nobody</span>. The
+  @ capabilities of the <span class="usertype">nobody</span> user are
+  @ inherited by all users, regardless of whether or not they are logged in.
+  @ To disable universal access to the repository, make sure no user named 
+  @ <span class="usertype">nobody</span> exists or that the
+  @ <span class="usertype">nobody</span> user has no capabilities
+  @ enabled. The password for <span class="usertype">nobody</span> is ignore.
+  @ To avoid problems with spiders overloading the server, it is recommended
+  @ that the <span class="capability">h</span> (History) capability be turned 
+  @ off for the <span class="usertype">nobody</span> user.
   @ </p></li>
   @
   @ <li><p>
-  @ Login is required for user "<b>anonymous</b>" but the password
-  @ is displayed on the login screen beside the password entry box
+  @ Login is required for user <span class="usertype">anonymous</span> but the
+  @ password is displayed on the login screen beside the password entry box
   @ so anybody who can read should be able to login as anonymous.
   @ On the other hand, spiders and web-crawlers will typically not
-  @ be able to login.  Set the capabilities of the anonymous user
-  @ to things that you want any human to be able to do, but not any
+  @ be able to login.  Set the capabilities of the
+  @ <span class="usertype">anonymous</span>
+  @ user to things that you want any human to be able to do, but not any
   @ spider.  Every other logged-in user inherits the privileges of
-  @ <b>anonymous</b>.
+  @ <span class="usertype">anonymous</span>.
   @ </p></li>
   @
   @ <li><p>
-  @ The "<b>developer</b>" user is intended as a template for trusted users
-  @ with check-in privileges.  When adding new trusted users, simply
-  @ select the <b>Developer</b> privilege to cause the new user to inherit
-  @ all privileges of the "developer" user.  Similarly, the "<b>reader</b>"
-  @ user is a template for users who are allowed more access than anonymous,
-  @ but less than a developer.
+  @ The <span class="usertype">developer</span> user is intended as a template
+  @ for trusted users with check-in privileges. When adding new trusted users,
+  @ simply select the <span class="capability">developer</span> privilege to
+  @ cause the new user to inherit all privileges of the 
+  @ <span class="usertype">developer</span>
+  @ user.  Similarly, the <span class="usertype">reader</span> user is a 
+  @ template for users who are allowed more access than
+  @ <span class="usertype">anonymous</span>,
+  @ but less than a <span class="usertype">developer</span>.
   @ </p></li>
   @ </ul>
-  @ </form>
   style_footer();
 }
 
 
 /*
@@ -651,13 +682,14 @@
       db_set(zVar, iQ ? "1" : "0", 0);
       iVal = iQ;
     }
   }
   if( iVal ){
-    @ <input type="checkbox" name="%s(zQParm)" checked><b>%s(zLabel)</b></input>
+    @ <input type="checkbox" name="%s(zQParm)" checked="checked" />
+    @ <b>%s(zLabel)</b>
   }else{
-    @ <input type="checkbox" name="%s(zQParm)"><b>%s(zLabel)</b></input>
+    @ <input type="checkbox" name="%s(zQParm)" /><b>%s(zLabel)</b>
   }
 }
 
 /*
 ** Generate an entry box for an attribute.
@@ -674,11 +706,11 @@
   if( zQ && strcmp(zQ,zVal)!=0 ){
     login_verify_csrf_secret();
     db_set(zVar, zQ, 0);
     zVal = zQ;
   }
-  @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)">
+  @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" />
   @ <b>%s(zLabel)</b>
 }
 
 /*
 ** Generate a text box for an attribute.
@@ -698,11 +730,12 @@
     db_set(zVar, zQ, 0);
     z = zQ;
   }
   if( rows>0 && cols>0 ){
     @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea>
-    @ <b>%s(zLabel)</b>
+    if (zLabel && *zLabel)
+      @ <span class="textareaLabel">%s(zLabel)</span>
   }
 }
 
 
 /*
@@ -714,57 +747,57 @@
     login_needed();
   }
 
   style_header("Access Control Settings");
   db_begin_transaction();
-  @ <form action="%s(g.zBaseURL)/setup_access" method="POST">
+  @ <form action="%s(g.zBaseURL)/setup_access" method="post"><div>
   login_insert_csrf_secret();
-  @ <hr>
+  @ <hr />
   onoff_attribute("Require password for local access",
      "localauth", "localauth", 0);
   @ <p>When enabled, the password sign-in is required for
   @ web access coming from 127.0.0.1.  When disabled, web access
   @ from 127.0.0.1 is allows without any login - the user id is selected
   @ from the ~/.fossil database. Password login is always required
   @ for incoming web connections on internet addresses other than
-  @ 127.0.0.1.</p></li>
+  @ 127.0.0.1.</p>
 
-  @ <hr>
+  @ <hr />
   onoff_attribute("Allow REMOTE_USER authentication",
      "remote_user_ok", "remote_user_ok", 0);
   @ <p>When enabled, if the REMOTE_USER environment variable is set to the
   @ login name of a valid user and no other login credentials are available,
   @ then the REMOTE_USER is accepted as an authenticated user.
-  @ </p></li>
+  @ </p>
 
-  @ <hr>
+  @ <hr />
   entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
   @ <p>The number of hours for which a login is valid.  This must be a
   @ positive number.  The default is 8760 hours which is approximately equal
   @ to a year.</p>
 
-  @ <hr>
+  @ <hr />
   entry_attribute("Download packet limit", 10, "max-download", "mxdwn",
                   "5000000");
   @ <p>Fossil tries to limit out-bound sync, clone, and pull packets
   @ to this many bytes, uncompressed.  If the client requires more data
   @ than this, then the client will issue multiple HTTP requests.
   @ Values below 1 million are not recommended.  5 million is a
   @ reasonable number.</p>
 
-  @ <hr>
+  @ <hr />
   onoff_attribute("Show javascript button to fill in CAPTCHA",
                   "auto-captcha", "autocaptcha", 0);
   @ <p>When enabled, a button appears on the login screen for user
   @ "anonymous" that will automatically fill in the CAPTCHA password.
   @ This is less secure that forcing the user to do it manually, but is
   @ probably secure enough and it is certainly more convenient for
   @ anonymous users.</p>
 
-  @ <hr>
-  @ <p><input type="submit"  name="submit" value="Apply Changes"></p>
-  @ </form>
+  @ <hr />
+  @ <p><input type="submit"  name="submit" value="Apply Changes" /></p>
+  @ </div></form>
   db_end_transaction(0);
   style_footer();
 }
 
 /*
@@ -776,42 +809,42 @@
     login_needed();
   }
 
   style_header("Timeline Display Preferences");
   db_begin_transaction();
-  @ <form action="%s(g.zBaseURL)/setup_timeline" method="POST">
+  @ <form action="%s(g.zBaseURL)/setup_timeline" method="post"><div>
   login_insert_csrf_secret();
 
-  @ <hr>
+  @ <hr />
   onoff_attribute("Allow block-markup in timeline",
                   "timeline-block-markup", "tbm", 0);
   @ <p>In timeline displays, check-in comments can be displayed with or
   @ without block markup (paragraphs, tables, etc.)</p>
 
-  @ <hr>
+  @ <hr />
   onoff_attribute("Use Universal Coordinated Time (UTC)",
                   "timeline-utc", "utc", 1);
   @ <p>Show times as UTC (also sometimes called Greenwich Mean Time (GMT) or
   @ Zulu) instead of in local time.</p>
 
-  @ <hr>
+  @ <hr />
   onoff_attribute("Show version differences by default",
                   "show-version-diffs", "vdiff", 0);
   @ <p>On the version-information pages linked from the timeline can either
   @ show complete diffs of all file changes, or can just list the names of
   @ the files that have changed.  Users can get to either page by
   @ clicking.  This setting selects the default.</p>
 
-  @ <hr>
+  @ <hr />
   entry_attribute("Max timeline comment length", 6,
                   "timeline-max-comment", "tmc", "0");
   @ <p>The maximum length of a comment to be displayed in a timeline.
   @ "0" there is no length limit.</p>
 
-  @ <hr>
-  @ <p><input type="submit"  name="submit" value="Apply Changes"></p>
-  @ </form>
+  @ <hr />
+  @ <p><input type="submit"  name="submit" value="Apply Changes" /></p>
+  @ </div></form>
   db_end_transaction(0);
   style_footer();
 }
 
 /*
@@ -823,11 +856,11 @@
     login_needed();
   }
 
   style_header("WWW Configuration");
   db_begin_transaction();
-  @ <form action="%s(g.zBaseURL)/setup_config" method="POST">
+  @ <form action="%s(g.zBaseURL)/setup_config" method="post"><div>
   login_insert_csrf_secret();
   @ <hr />
   entry_attribute("Project Name", 60, "project-name", "pn", "");
   @ <p>Give your project a name so visitors know what this site is about.
   @ The project name will also be used as the RSS feed title.</p>
@@ -840,36 +873,37 @@
   entry_attribute("Index Page", 60, "index-page", "idxpg", "/home");
   @ <p>Enter the pathname of the page to display when the "Home" menu
   @ option is selected and when no pathname is
   @ specified in the URL.  For example, if you visit the url:</p>
   @
-  @ <blockquote>%h(g.zBaseURL)</blockquote>
+  @ <blockquote><p>%h(g.zBaseURL)</p></blockquote>
   @
   @ <p>And you have specified an index page of "/home" the above will
   @ automatically redirect to:</p>
   @
-  @ <blockquote>%h(g.zBaseURL)/home</blockquote>
+  @ <blockquote><p>%h(g.zBaseURL)/home</p></blockquote>
   @
   @ <p>The default "/home" page displays a Wiki page with the same name
   @ as the Project Name specified above.  Some sites prefer to redirect
   @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p>
   @ <hr />
   onoff_attribute("Use HTML as wiki markup language",
     "wiki-use-html", "wiki-use-html", 0);
-  @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed but
-  @ all other wiki formatting will be ignored. This option is helpful if you have
-  @ chosen to use a rich HTML editor for wiki markup such as TinyMCE.</p>
+  @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed
+  @ but all other wiki formatting will be ignored. This option is helpful
+  @ if you have chosen to use a rich HTML editor for wiki markup such as
+  @ TinyMCE.</p>
   @ <p><strong>CAUTION:</strong> when
   @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki.
   @ No sanitization is done. This means that it is very possible for malicious
   @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p>
   @ <p>This should <strong>only</strong> be enabled when wiki editing is limited
   @ to trusted users. It should <strong>not</strong> be used on a publically
   @ editable wiki.</p>
   @ <hr />
-  @ <p><input type="submit"  name="submit" value="Apply Changes"></p>
-  @ </form>
+  @ <p><input type="submit"  name="submit" value="Apply Changes" /></p>
+  @ </div></form>
   db_end_transaction(0);
   style_footer();
 }
 
 /*
@@ -892,30 +926,27 @@
   if( P("submit")!=0 ){
     db_end_transaction(0);
     cgi_redirect("setup_editcss");
   }
   style_header("Edit CSS");
-  @ <form action="%s(g.zBaseURL)/setup_editcss" method="POST">
+  @ <form action="%s(g.zBaseURL)/setup_editcss" method="post"><div>
   login_insert_csrf_secret();
   @ Edit the CSS below:<br />
   textarea_attribute("", 40, 80, "css", "css", zDefaultCSS);
   @ <br />
-  @ <input type="submit" name="submit" value="Apply Changes">
-  @ <input type="submit" name="clear" value="Revert To Default">
-  @ </form>
-  @ <p><b>Note:</b> Press your browser Reload button after modifying the
-  @ CSS in order to pull in the modified CSS file.</p>
-  @ <hr>
+  @ <input type="submit" name="submit" value="Apply Changes" />
+  @ <input type="submit" name="clear" value="Revert To Default" />
+  @ </div></form>
+  @ <p><span class="note">Note:</span> Press your browser Reload button after
+  @ modifying the CSS in order to pull in the modified CSS file.</p>
+  @ <hr />
   @ The default CSS is shown below for reference.  Other examples
   @ of CSS files can be seen on the <a href="setup_skin">skins page</a>.
   @ See also the <a href="setup_header">header</a> and
   @ <a href="setup_footer">footer</a> editing screens.
   @ <blockquote><pre>
-  @ %h(zDefaultCSS)
-  @ %h(zTableLabelValueCSS)
-  @ %h(zDivSidebox)
-  @ %h(zDivSideboxTitle)
+  cgi_append_default_css();
   @ </pre></blockquote>
   style_footer();
   db_end_transaction(0);
 }
 
@@ -933,21 +964,21 @@
     cgi_replace_parameter("header", zDefaultHeader);
   }else{
     textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader);
   }
   style_header("Edit Page Header");
-  @ <form action="%s(g.zBaseURL)/setup_header" method="POST">
+  @ <form action="%s(g.zBaseURL)/setup_header" method="post"><div>
   login_insert_csrf_secret();
   @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   @ generate the beginning of every page through start of the main
   @ menu.</p>
   textarea_attribute("", 40, 80, "header", "header", zDefaultHeader);
   @ <br />
-  @ <input type="submit" name="submit" value="Apply Changes">
-  @ <input type="submit" name="clear" value="Revert To Default">
-  @ </form>
-  @ <hr>
+  @ <input type="submit" name="submit" value="Apply Changes" />
+  @ <input type="submit" name="clear" value="Revert To Default" />
+  @ </div></form>
+  @ <hr />
   @ The default header is shown below for reference.  Other examples
   @ of headers can be seen on the <a href="setup_skin">skins page</a>.
   @ See also the <a href="setup_editcss">CSS</a> and
   @ <a href="setup_footer">footer</a> editing screeens.
   @ <blockquote><pre>
@@ -971,20 +1002,20 @@
     cgi_replace_parameter("footer", zDefaultFooter);
   }else{
     textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter);
   }
   style_header("Edit Page Footer");
-  @ <form action="%s(g.zBaseURL)/setup_footer" method="POST">
+  @ <form action="%s(g.zBaseURL)/setup_footer" method="post"><div>
   login_insert_csrf_secret();
   @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
   @ generate the end of every page.</p>
   textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter);
   @ <br />
-  @ <input type="submit" name="submit" value="Apply Changes">
-  @ <input type="submit" name="clear" value="Revert To Default">
-  @ </form>
-  @ <hr>
+  @ <input type="submit" name="submit" value="Apply Changes" />
+  @ <input type="submit" name="clear" value="Revert To Default" />
+  @ </div></form>
+  @ <hr />
   @ The default footer is shown below for reference.  Other examples
   @ of footers can be seen on the <a href="setup_skin">skins page</a>.
   @ See also the <a href="setup_editcss">CSS</a> and
   @ <a href="setup_header">header</a> editing screens.
   @ <blockquote><pre>
@@ -1034,31 +1065,31 @@
     cgi_redirect("setup_logo");
   }
   style_header("Edit Project Logo");
   @ <p>The current project logo has a MIME-Type of <b>%h(zMime)</b> and looks
   @ like this:</p>
-  @ <blockquote><img src="%s(g.zTop)/logo" alt="logo"></blockquote>
+  @ <blockquote><p><img src="%s(g.zTop)/logo" alt="logo" /></p></blockquote>
   @
   @ <p>The logo is accessible to all users at this URL:
   @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>.
   @ The logo may or may not appear on each
   @ page depending on the <a href="setup_editcss">CSS</a> and
   @ <a href="setup_header">header setup</a>.</p>
   @
-  @ <form action="%s(g.zBaseURL)/setup_logo" method="POST"
-  @  enctype="multipart/form-data">
+  @ <form action="%s(g.zBaseURL)/setup_logo" method="post"
+  @  enctype="multipart/form-data"><div>
   @ <p>To set a new logo image, select a file to use as the logo using
   @ the entry box below and then press the "Change Logo" button.</p>
   login_insert_csrf_secret();
   @ Logo Image file:
-  @ <input type="file" name="im" size="60" accepts="image/*"><br>
-  @ <input type="submit" name="set" value="Change Logo">
-  @ <input type="submit" name="clr" value="Revert To Default">
-  @ </form>
+  @ <input type="file" name="im" size="60" accept="image/*" /><br />
+  @ <input type="submit" name="set" value="Change Logo" />
+  @ <input type="submit" name="clr" value="Revert To Default" />
+  @ </div></form>
   @
-  @ <p><b>Note:</b>  Your browser has probably cached the logo image, so
-  @ you will probably need to press the Reload button on your browser after
-  @ changing the logo to provoke your browser to reload the new logo image.
-  @ </p>
+  @ <p><span class="note">Note:</span>  Your browser has probably cached the
+  @ logo image, so you will probably need to press the Reload button on your
+  @ browser after changing the logo to provoke your browser to reload the new
+  @ logo image. </p>
   style_footer();
   db_end_transaction(0);
 }

Index: src/shun.c
==================================================================
--- src/shun.c
+++ src/shun.c
@@ -112,63 +112,63 @@
   @ or artifacts that by design or accident interfere with the processing
   @ of the repository.  Do not shun artifacts merely to remove them from
   @ sight - set the "hidden" tag on such artifacts instead.</p>
   @ 
   @ <blockquote>
-  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
+  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div>
   login_insert_csrf_secret();
-  @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50">
-  @ <input type="submit" name="add" value="Shun">
-  @ </form>
+  @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
+  @ <input type="submit" name="add" value="Shun" />
+  @ </div></form>
   @ </blockquote>
   @
   @ <p>Enter the UUID of a previous shunned artifact to cause it to be
   @ accepted again in the repository.  The artifact content is not
   @ restored because the content is unknown.  The only change is that
   @ the formerly shunned artifact will be accepted on subsequent sync
   @ operations.</p>
   @
   @ <blockquote>
-  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
+  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div>
   login_insert_csrf_secret();
-  @ <input type="text" name="uuid" size="50">
-  @ <input type="submit" name="sub" value="Accept">
-  @ </form>
+  @ <input type="text" name="uuid" size="50" />
+  @ <input type="submit" name="sub" value="Accept" />
+  @ </div></form>
   @ </blockquote>
   @
   @ <p>Press the Rebuild button below to rebuild the respository.  The
   @ content of newly shunned artifacts is not purged until the repository
   @ is rebuilt.  On larger repositories, the rebuild may take minute or
   @ two, so be patient after pressing the button.</p>
   @
   @ <blockquote>
-  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
+  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><div>
   login_insert_csrf_secret();
-  @ <input type="submit" name="rebuild" value="Rebuild">
-  @ </form>
+  @ <input type="submit" name="rebuild" value="Rebuild" />
+  @ </div></form>
   @ </blockquote>
   @ 
-  @ <hr><p>Shunned Artifacts:</p>
-  @ <blockquote>
+  @ <hr /><p>Shunned Artifacts:</p>
+  @ <blockquote><p>
   db_prepare(&q, 
      "SELECT uuid, EXISTS(SELECT 1 FROM blob WHERE blob.uuid=shun.uuid)"
      "  FROM shun ORDER BY uuid");
   while( db_step(&q)==SQLITE_ROW ){
     const char *zUuid = db_column_text(&q, 0);
     int stillExists = db_column_int(&q, 1);
     cnt++;
     if( stillExists ){
-      @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br>
+      @ <b><a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a></b><br />
     }else{
-      @ <b>%s(zUuid)</b><br>
+      @ <b>%s(zUuid)</b><br />
     }
   }
   if( cnt==0 ){
     @ <i>no artifacts are shunned on this server</i>
   }
   db_finalize(&q);
-  @ </blockquote>
+  @ </p></blockquote>
   style_footer();
 }
 
 /*
 ** Remove from the BLOB table all artifacts that are in the SHUN table.
@@ -229,14 +229,15 @@
   @
   @ <p>Click on the "rcvid" to show a list of specific artifacts received
   @ by a transaction.  After identifying illicit artifacts, remove them
   @ using the "Shun" feature.</p>
   @
-  @ <table cellpadding=0 cellspacing=0 border=0>
-  @ <tr><th>rcvid</th><th width=15>
-  @     <th>Date</th><th width=15><th>User</th>
-  @     <th width=15><th>IP&nbsp;Address</th></tr>
+  @ <table cellpadding="0" cellspacing="0" border="0">
+  @ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th>
+  @     <th style="padding-right: 15px;text-align: left;">Date</th>
+  @     <th style="padding-right: 15px;text-align: left;">User</th>
+  @     <th style="text-align: left;">IP&nbsp;Address</th></tr>
   cnt = 0;
   while( db_step(&q)==SQLITE_ROW ){
     int rcvid = db_column_int(&q, 0);
     const char *zUser = db_column_text(&q, 1);
     const char *zDate = db_column_text(&q, 2);
@@ -245,14 +246,14 @@
       style_submenu_element("Older", "Older",
          "rcvfromlist?ofst=%d", ofst+30);
     }else{
       cnt++;
       @ <tr>
-      @ <td><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td><td>
-      @ <td>%s(zDate)</td><td>
-      @ <td>%h(zUser)</td><td>
-      @ <td>&nbsp;%s(zIpAddr)&nbsp</td>
+      @ <td style="padding-right: 15px;text-align: right;"><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td>
+      @ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td>
+      @ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td>
+      @ <td style="text-align: left;">%s(zIpAddr)</td>
       @ </tr>
     }
   }
   db_finalize(&q);
   @ </table>
@@ -277,11 +278,11 @@
     "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr"
     "  FROM rcvfrom LEFT JOIN user USING(uid)"
     " WHERE rcvid=%d",
     rcvid
   );
-  @ <table cellspacing=15 cellpadding=0 border=0>
+  @ <table cellspacing="15" cellpadding="0" border="0">
   @ <tr><td valign="top" align="right"><b>rcvid:</b></td>
   @ <td valign="top">%d(rcvid)</td></tr>
   if( db_step(&q)==SQLITE_ROW ){
     const char *zUser = db_column_text(&q, 0);
     const char *zDate = db_column_text(&q, 1);
@@ -302,10 +303,12 @@
   while( db_step(&q)==SQLITE_ROW ){
     int rid = db_column_int(&q, 0);
     const char *zUuid = db_column_text(&q, 1);
     int size = db_column_int(&q, 2);
     @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">%s(zUuid)</a>
-    @ (rid: %d(rid), size: %d(size))<br>
+    @ (rid: %d(rid), size: %d(size))<br />
   }
   @ </td></tr>
   @ </table>
+  db_finalize(&q);
+  style_footer();
 }

Index: src/skins.c
==================================================================
--- src/skins.c
+++ src/skins.c
@@ -165,11 +165,11 @@
 @ <body>
 @ <div class="header">
 @   <div class="logo">
 @     <img src="$baseurl/logo" alt="logo">
 @   </div>
-@   <div class="title"><small>$<project_name></small><br>$<title></div>
+@   <div class="title"><small>$<project_name></small><br />$<title></div>
 @   <div class="status"><nobr><th1>
 @      if {[info exists login]} {
 @        puts "Logged in as $login"
 @      } else {
 @        puts "Not logged in"
@@ -600,11 +600,11 @@
 @ </head>
 @ <body>
 @ <div class="header">
 @   <div class="logo">
 @     <!-- <img src="$baseurl/logo" alt="logo"> -->
-@     <br><nobr>$<project_name></nobr>
+@     <br /><nobr>$<project_name></nobr>
 @   </div>
 @   <div class="title">$<title></div>
 @   <div class="status"><nobr><th1>
 @      if {[info exists login]} {
 @        puts "Logged in as $login"
@@ -731,18 +731,18 @@
   db_begin_transaction();
 
   /* Process requests to delete a user-defined skin */
   if( P("del1") && (zName = skinVarName(P("sn"), 1))!=0 ){
     style_header("Confirm Custom Skin Delete");
-    @ <form action="%s(g.zBaseURL)/setup_skin" method="POST">
+    @ <form action="%s(g.zBaseURL)/setup_skin" method="post"><div>
     @ <p>Deletion of a custom skin is a permanent action that cannot
     @ be undone.  Please confirm that this is what you want to do:</p>
-    @ <input type="hidden" name="sn" value="%h(P("sn"))">
-    @ <input type="submit" name="del2" value="Confirm - Delete The Skin">
-    @ <input type="submit" name="cancel" value="Cancel - Do Not Delete">
+    @ <input type="hidden" name="sn" value="%h(P("sn"))" />
+    @ <input type="submit" name="del2" value="Confirm - Delete The Skin" />
+    @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" />
     login_insert_csrf_secret();
-    @ </form>
+    @ </div></form>
     style_footer();
     return;
   }
   if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){
     db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
@@ -812,15 +812,15 @@
   for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){
     z = aBuiltinSkin[i].zName;
     if( strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){
       @ <li><p>%h(z).&nbsp;&nbsp; <b>Currently In Use</b></p>
     }else{
-      @ <li><form action="%s(g.zBaseURL)/setup_skin" method="POST">
+      @ <li><form action="%s(g.zBaseURL)/setup_skin" method="post"><div>
       @ %h(z).&nbsp;&nbsp; 
-      @ <input type="hidden" name="sn" value="%h(z)">
-      @ <input type="submit" name="load" value="Use This Skin">
-      @ </form></li>
+      @ <input type="hidden" name="sn" value="%h(z)" />
+      @ <input type="submit" name="load" value="Use This Skin" />
+      @ </div></form></li>
     }
   }
   db_prepare(&q,
      "SELECT substr(name, 6), value FROM config"
      " WHERE name GLOB 'skin:*'"

Index: src/stat.c
==================================================================
--- src/stat.c
+++ src/stat.c
@@ -28,15 +28,17 @@
 ** Show statistics and global information about the repository.
 */
 void stat_page(void){
   i64 t;
   int n, m, fsize;
+  int szMax, szAvg;
   char zBuf[100];
+
   login_check_credentials();
   if( !g.okRead ){ login_needed(); return; }
   style_header("Repository Statistics");
-  @ <p><table class="label-value">
+  @ <table class="label-value">
   @ <tr><th>Repository&nbsp;Size:</th><td>
   fsize = file_size(g.zRepositoryName);
   @ %d(fsize) bytes
   @ </td></tr>
   @ <tr><th>Number&nbsp;Of&nbsp;Artifacts:</th><td>
@@ -44,14 +46,21 @@
   m = db_int(0, "SELECT count(*) FROM delta");
   @ %d(n) (stored as %d(n-m) full text and %d(m) delta blobs)
   @ </td></tr>
   if( n>0 ){
     int a, b;
+    Stmt q;
     @ <tr><th>Uncompressed&nbsp;Artifact&nbsp;Size:</th><td>
-    t = db_int64(0, "SELECT total(size) FROM blob WHERE size>0");
+    db_prepare(&q, "SELECT total(size), avg(size), max(size)"
+                   " FROM blob WHERE size>0");
+    db_step(&q);
+    t = db_column_int64(&q, 0);
+    szAvg = db_column_int(&q, 1);
+    szMax = db_column_int(&q, 2);
+    db_finalize(&q);
     sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", t);
-    @ %d((int)(((double)t)/(double)n)) bytes average, %s(zBuf) bytes total
+    @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) bytes total
     @ </td></tr>
     @ <tr><th>Compression&nbsp;Ratio:</th><td>
     if( t/fsize < 5 ){
       b = 10;
       fsize /= 10;
@@ -82,10 +91,12 @@
   @ </td></tr>
   @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
   n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
                 " + 0.99");
   @ %d(n) days
+  sqlite3_snprintf(sizeof(zBuf), zBuf, "%.2f", n/365.24);
+  @ or approximately %s(zBuf) years
   @ </td></tr>
   @ <tr><th>Project&nbsp;ID:</th><td>
   @ %h(db_get("project-code",""))
   @ </td></tr>
   @ <tr><th>Server&nbsp;ID:</th><td>
@@ -94,19 +105,20 @@
 
   @ <tr><th>Fossil&nbsp;Version:</th><td>
   @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
   @ </td></tr>
   @ <tr><th>SQLite&nbsp;Version:</th><td>
-  @ %h(db_text(0, "SELECT substr(sqlite_source_id(),1,30)"))
-  @ (%h(SQLITE_VERSION))
+  sqlite3_snprintf(sizeof(zBuf), zBuf, "%.19s [%.10s] (%s)",
+                   SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20], SQLITE_VERSION);
+  @ %s(zBuf)
   @ </td></tr>
   @ <tr><th>Database&nbsp;Stats:</th><td>
   @ %d(db_int(0, "PRAGMA %s.page_count", g.zRepoDb)) pages,
   @ %d(db_int(0, "PRAGMA %s.page_size", g.zRepoDb)) bytes/page,
   @ %d(db_int(0, "PRAGMA %s.freelist_count", g.zRepoDb)) free pages,
   @ %s(db_text(0, "PRAGMA %s.encoding", g.zRepoDb)),
   @ %s(db_text(0, "PRAGMA %s.journal_mode", g.zRepoDb)) mode
   @ </td></tr>
 
-  @ </table></p>
+  @ </table>
   style_footer();
 }

Index: src/style.c
==================================================================
--- src/style.c
+++ src/style.c
@@ -139,20 +139,23 @@
   }
   @ <div class="content">
   cgi_destination(CGI_BODY);
 
   /* Put the footer at the bottom of the page.
+  ** the additional clear/both is needed to extend the content
+  ** part to the end of an optional sidebox.
   */
-  @ </div><br clear="both"/>
+  @ <div style="clear: both;"></div>
+  @ </div>
   zFooter = db_get("footer", (char*)zDefaultFooter);
   if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
   Th_Render(zFooter);
   if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
   
   /* Render trace log if TH1 tracing is enabled. */
   if( g.thTrace ){
-    cgi_append_content("<font color=\"red\"><hr>\n", -1);
+    cgi_append_content("<font color=\"red\"><hr />\n", -1);
     cgi_append_content(blob_str(&g.thLog), blob_size(&g.thLog));
     cgi_append_content("</font>\n", -1);
   }
 }
 
@@ -179,27 +182,27 @@
 const char zDefaultHeader[] = 
 @ <html>
 @ <head>
 @ <title>$<project_name>: $<title></title>
 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
-@       href="$baseurl/timeline.rss">
+@       href="$baseurl/timeline.rss" />
 @ <link rel="stylesheet" href="$baseurl/style.css?default" type="text/css"
-@       media="screen">
+@       media="screen" />
 @ </head>
 @ <body>
 @ <div class="header">
 @   <div class="logo">
 @     <img src="$baseurl/logo" alt="logo">
 @   </div>
-@   <div class="title"><small>$<project_name></small><br>$<title></div>
-@   <div class="status"><nobr><th1>
+@   <div class="title"><small>$<project_name></small><br />$<title></div>
+@   <div class="status"><th1>
 @      if {[info exists login]} {
 @        puts "Logged in as $login"
 @      } else {
 @        puts "Not logged in"
 @      }
-@   </th1></nobr></div>
+@   </th1></div>
 @ </div>
 @ <div class="mainmenu"><th1>
 @ html "<a href='$baseurl$index_page'>Home</a> "
 @ if {[anycap jor]} {
 @   html "<a href='$baseurl/timeline'>Timeline</a> "
@@ -274,11 +277,11 @@
 @   font-weight: bold;
 @   text-align: center;
 @   padding: 0 0 0 1em;
 @   color: #558195;
 @   vertical-align: bottom;
-@   width: 100%;
+@   width: 100% ;
 @ }
 @
 @ /* The login status message in the top right-hand corner */
 @ div.status {
 @   display: table-cell;
@@ -286,16 +289,17 @@
 @   vertical-align: bottom;
 @   color: #558195;
 @   font-size: 0.8em;
 @   font-weight: bold;
 @   min-width: 200px;
+@   white-space: nowrap;
 @ }
 @
 @ /* The header across the top of the page */
 @ div.header {
 @   display: table;
-@   width: 100%;
+@   width: 100% ;
 @ }
 @
 @ /* The main menu bar that appears at the top of the page beneath
 @ ** the header */
 @ div.mainmenu {
@@ -339,10 +343,11 @@
 @   padding: 1px 1px 1px 1px;
 @   font-size: 1.2em;
 @   font-weight: bold;
 @   background-color: #558195;
 @   color: white;
+@   white-space: nowrap;
 @ }
 @
 @ /* The "Date" that occurs on the left hand side of timelines */
 @ div.divider {
 @   background: #a1c4d4;
@@ -368,83 +373,344 @@
 @ div.footer a { color: white; }
 @ div.footer a:link { color: white; }
 @ div.footer a:visited { color: white; }
 @ div.footer a:hover { background-color: white; color: #558195; }
 @ 
-@ /* <verbatim> blocks */
+@ /* verbatim blocks */
 @ pre.verbatim {
 @    background-color: #f5f5f5;
 @    padding: 0.5em;
 @}
 @
-;
-const char zTableLabelValueCSS[] = 
 @ /* The label/value pairs on (for example) the ci page */
 @ table.label-value th {
 @   vertical-align: top;
 @   text-align: right;
 @   padding: 0.2ex 2ex;
 @ }
-;
-const char zDivSidebox[] =
-@ /* The nomenclature sidebox for branches,.. */
-@ div.sidebox {
-@   float: right;
-@   border-width: medium;
-@   border-style: double;
-@   margin: 10;
-@ }
-;
-const char zDivSideboxTitle[] =
-@ /* The nomenclature title in sideboxes for branches,.. */
-@ div.sideboxTitle {
-@   display: inline;
-@   font-weight: bold;
-@ }
+@
 ;
 
 
-/* The following table holds the names of CSS elements and the CSS
-** text that implements those elements.
+/* The following table contains bits of default CSS that must
+** be included if they are not found in the application-defined
+** CSS.
 */
-static const struct {
-  const char *zElement;   /* Name of the CSS element */
-  const char *zText;      /* Text of the element */
-} cssElements[] = {
-  { "table.label-value", zTableLabelValueCSS },
-  { "div.sidebox",       zDivSidebox         },
-  { "div.sideboxTitle",  zDivSideboxTitle    },
+const struct strctCssDefaults {
+  char const * const elementClass;  /* Name of element needed */
+  char const * const comment;       /* Comment text */
+  char const * const value;         /* CSS text */
+} cssDefaultList[] = {
+  { "",
+    "",
+    zDefaultCSS
+  },
+  { "div.sidebox",
+    "The nomenclature sidebox for branches,..",
+    @   float: right;
+    @   background-color: white;
+    @   border-width: medium;
+    @   border-style: double;
+    @   margin: 10;
+  },
+  { "div.sideboxTitle",
+    "The nomenclature title in sideboxes for branches,..",
+    @   display: inline;
+    @   font-weight: bold;
+  },
+  { "div.sideboxDescribed",
+    "The defined element in sideboxes for branches,..",
+    @   display: inline;
+    @   font-weight: bold;
+  },
+  { "span.disabled",
+    "The defined element in sideboxes for branches,..",
+    @   color: red;
+  },
+  { "span.timelineDisabled",
+    "The suppressed duplicates lines in timeline, ..",
+    @   font-style: italic;
+    @   font-size: small;
+  },
+  { "table.timelineTable",
+    "the format for the timeline data table",
+    @   cellspacing: 0;
+    @   border: 0;
+    @   cellpadding: 0
+  },
+  { "td.timelineTableCell",
+    "the format for the timeline data cells",
+    @   valign: top;
+    @   align: left;
+  },
+  { "span.timelineLeaf",
+    "the format for the timeline leaf marks",
+    @   font-weight: bold;
+  },
+  { "a.timelineHistLink",
+    "the format for the timeline version links",
+    @
+  },
+  { "span.timelineHistDsp",
+    "the format for the timeline version display(no history permission!)",
+    @   font-weight: bold;
+  },
+  { "td.timelineTime",
+    "the format for the timeline time display",
+    @   vertical-align: top;
+    @   text-align: right;
+  },
+  { "td.timelineGraph",
+    "the format for the grap placeholder cells in timelines",
+    @ width: 20;
+    @ text-align: left;
+    @ vertical-align: top;
+  },
+  { "a.tagLink",
+    "the format for the tag links",
+    @
+  },
+  { "span.tagDsp",
+    "the format for the tag display(no history permission!)",
+    @   font-weight: bold;
+  },
+  { "span.wikiError",
+    "the format for wiki errors",
+    @   font-weight: bold;
+    @   color: red;
+  },
+  { "span.infoTagCancelled",
+    "the format for fixed/canceled tags,..",
+    @   font-weight: bold;
+    @   text-decoration: line-through;
+  },
+  { "span.infoTag",
+    "the format for tags,..",
+    @   font-weight: bold;
+  },
+  { "span.wikiTagCancelled",
+    "the format for fixed/cancelled tags,.. on wiki pages",
+    @   text-decoration: line-through;
+  },
+  { "table.browser",
+    "format for the file display table",
+    @ /* the format for wiki errors */
+    @   width: 100% ;
+    @   border: 0;
+  },
+  { "td.browser",
+    "format for cells in the file browser",
+    @   width: 24% ;
+    @   vertical-align: top;
+  },
+  { "ul.browser",
+    "format for the list in the file browser",
+    @   margin-left: 0.5em;
+    @   padding-left: 0.5em;
+  },
+  { "table.login_out",
+    "table format for login/out label/input table",
+    @   text-align: left;
+    @   margin-right: 10px;
+    @   margin-left: 10px;
+    @   margin-top: 10px;
+  },
+  { "div.captcha",
+    "captcha display options",
+    @   text-align: center;
+  },
+  { "table.captcha",
+    "format for the layout table, used for the captcha display",
+    @   margin: auto;
+    @   padding: 10px;
+    @   outline-width: 1;
+    @   outline-style: double;
+  },
+  { "td.login_out_label",
+    "format for the label cells in the login/out table",
+    @   text-align: center;
+  },
+  { "span.loginError",
+    "format for login error messages",
+    @   color: red;
+  },
+  { "span.note",
+    "format for leading text for notes",
+    @   font-weight: bold;
+  },
+  { "span.textareaLabel",
+    "format for textare labels",
+    @   font-weight: bold;
+  },
+  { "table.usetupLayoutTable",
+    "format for the user setup layout table",
+    @   outline-style: none;
+    @   padding: 0;
+    @   margin: 25px;
+  },
+  { "td.usetupColumnLayout",
+    "format of the columns on the user setup list page",
+    @   vertical-align: top
+  },
+  { "table.usetupUserList",
+    "format for the user list table on the user setup page",
+    @   outline-style: double;
+    @   outline-width: 1;
+    @   padding: 10px;
+  },
+  { "th.usetupListUser",
+    "format for table header user in user list on user setup page",
+    @   text-align: right;
+    @   padding-right: 20px;
+  },
+  { "th.usetupListCap",
+    "format for table header capabilities in user list on user setup page",
+    @   text-align: center;
+    @   padding-right: 15px;
+  },
+  { "th.usetupListCon",
+    "format for table header contact info in user list on user setup page",
+    @   text-align: left;
+  },
+  { "td.usetupListUser",
+    "format for table cell user in user list on user setup page",
+    @   text-align: right;
+    @   padding-right: 20px;
+    @   white-space:nowrap;
+  },
+  { "td.usetupListCap",
+    "format for table cell capabilities in user list on user setup page",
+    @   text-align: center;
+    @   padding-right: 15px;
+  },
+  { "td.usetupListCon",
+    "format for table cell contact info in user list on user setup page",
+    @   text-align: left
+  },
+  { "div.ueditCapBox",
+    "layout definition for the capabilities box on the user edit detail page",
+    @   float: left;
+    @   margin-right: 20px;
+    @   margin-bottom: 20px;
+  },
+  { "td.usetupEditLabel",
+    "format of the label cells in the detailed user edit page",
+    @   text-align: right;
+    @   vertical-align: top;
+    @   white-space: nowrap;
+  },
+  { "span.ueditInheritNobody",
+    "color for capabilities, inherited by nobody",
+    @   color: green;
+  },
+  { "span.ueditInheritDeveloper",
+    "color for capabilities, inherited by developer",
+    @   color: red;
+  },
+  { "span.ueditInheritReader",
+    "color for capabilities, inherited by reader",
+    @   color: black;
+  },
+  { "span.ueditInheritAnonymous",
+    "color for capabilities, inherited by anonymous",
+    @   color: blue;
+  },
+  { "span.capability",
+    "format for capabilites, mentioned on the user edit page",
+    @   font-weight: bold;
+  },
+  { "span.usertype",
+    "format for different user types, mentioned on the user edit page",
+    @   font-weight: bold;
+  },
+  { "span.usertype:before",
+    "leading text for user types, mentioned on the user edit page",
+    @   content:"'";
+  },
+  { "span.usertype:after",
+    "trailing text for user types, mentioned on the user edit page",
+    @   content:"'";
+  },
+  { "span.wikiruleHead",
+    "format for leading text in wikirules definitions",
+    @   font-weight: bold;
+  },
+  { "td.tktDspLabel",
+    "format for labels on ticket display page",
+    @   text-align: right;
+  },
+  { "td.tktDspValue",
+    "format for values on ticket display page",
+    @   text-align: left;
+    @   vertical-align: top;
+    @   background-color: #d0d0d0;
+  },
+  { "span.tktError",
+    "format for ticket error messages",
+    @   color: red;
+    @   font-weight: bold;
+  },
+  { 0,
+    0,
+    0
+  }
 };
+
+/*
+** Append all of the default CSS to the CGI output.
+*/
+void cgi_append_default_css(void) {
+  int i;
+
+  for (i=0;cssDefaultList[i].elementClass;i++){
+    if (cssDefaultList[i].elementClass[0]){
+      cgi_printf("/* %s */\n%s {\n%s\n}\n\n",
+		 cssDefaultList[i].comment,
+		 cssDefaultList[i].elementClass,
+		 cssDefaultList[i].value
+		);
+    }else{
+      cgi_printf("%s",
+		 cssDefaultList[i].value
+		);
+    }
+  }
+}
 
 /*
 ** WEBPAGE: style.css
 */
 void page_style_css(void){
-  const char *zCSS;
+  const char *zCSS    = 0;
   int i;
 
   cgi_set_content_type("text/css");
   zCSS = db_get("css",(char*)zDefaultCSS);
   /* append user defined css */
   cgi_append_content(zCSS, -1);
   /* add special missing definitions */
-  for(i=0; i<count(cssElements); i++){
-    if( strstr(cssElements[i].zElement, zCSS)==0 ){
-      cgi_append_content(cssElements[i].zText, -1);
+  for (i=1;cssDefaultList[i].elementClass;i++)
+    if (!strstr(zCSS,cssDefaultList[i].elementClass)) {
+      cgi_append_content("/* ", -1);
+      cgi_append_content(cssDefaultList[i].comment, -1);
+      cgi_append_content(" */\n", -1);
+      cgi_append_content(cssDefaultList[i].elementClass, -1);
+      cgi_append_content(" {\n", -1);
+      cgi_append_content(cssDefaultList[i].value, -1);
+      cgi_append_content("}\n\n", -1);
     }
-  }
   g.isConst = 1;
 }
 
 /*
 ** WEBPAGE: test_env
 */
 void page_test_env(void){
   style_header("Environment Test");
 #if !defined(_WIN32)
-  @ uid=%d(getuid()), gid=%d(getgid())<br>
+  @ uid=%d(getuid()), gid=%d(getgid())<br />
 #endif
-  @ g.zBaseURL = %h(g.zBaseURL)<br>
-  @ g.zTop = %h(g.zTop)<br>
+  @ g.zBaseURL = %h(g.zBaseURL)<br />
+  @ g.zTop = %h(g.zTop)<br />
   cgi_print_all();
   style_footer();
 }

Index: src/tag.c
==================================================================
--- src/tag.c
+++ src/tag.c
@@ -514,13 +514,14 @@
   );
   @ <ul>
   while( db_step(&q)==SQLITE_ROW ){
     const char *zName = db_column_text(&q, 0);
     if( g.okHistory ){
-      @ <li><a href=%s(g.zBaseURL)/timeline?t=%T(zName)>%h(zName)</a></li>
+      @ <li><a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zName)">
+      @ %h(zName)</a></li>
     }else{
-      @ <li><strong>%h(zName)</strong></li>
+      @ <li><span class="tagDsp">%h(zName)</span></li>
     }
   }
   @ </ul>
   db_finalize(&q);
   style_footer();
@@ -542,13 +543,14 @@
     rid
   );
   while( db_step(&q)==SQLITE_ROW ){
     const char *zTagName = db_column_text(&q, 0);
     if( g.okHistory ){
-      @ <a href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">[%h(zTagName)]</a>
+      @ <a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">
+      @ [%h(zTagName)]</a>
     }else{
-      @ <b>[%h(zTagName)]</b>
+      @ <span class="tagDsp">[%h(zTagName)]</span>
     }
   }
   db_finalize(&q);
 }
 
@@ -573,14 +575,14 @@
     " ORDER BY event.mtime DESC",
     timeline_query_for_www()
   );
   www_print_timeline(&q, 0, tagtimeline_extra);
   db_finalize(&q);
-  @ <br clear="both">
-  @ <script>
+  @ <br />
+  @ <script  type="text/JavaScript">
   @ function xin(id){
   @ }
   @ function xout(id){
   @ }
   @ </script>
   style_footer();
 }

Index: src/th_main.c
==================================================================
--- src/th_main.c
+++ src/th_main.c
@@ -278,11 +278,12 @@
     blob_reset(&name);
     for(i=0; i<nElem; i++){
       zH = htmlize((char*)azElem[i], aszElem[i]);
       if( zValue && aszElem[i]==nValue 
              && memcmp(zValue, azElem[i], nValue)==0 ){
-        z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH);
+        z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>",
+                     zH, zH);
       }else{
         z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
       }
       free(zH);
       sendText(z, -1, 0);

Index: src/timeline.c
==================================================================
--- src/timeline.c
+++ src/timeline.c
@@ -48,13 +48,14 @@
 */
 void hyperlink_to_uuid(const char *zUuid){
   char zShortUuid[UUID_SIZE+1];
   shorten_uuid(zShortUuid, zUuid);
   if( g.okHistory ){
-    @ <a href="%s(g.zBaseURL)/info/%s(zShortUuid)">[%s(zShortUuid)]</a>
+    @ <a class="timelineHistLink" href="%s(g.zBaseURL)/info/%s(zShortUuid)">
+    @ [%s(zShortUuid)]</a>
   }else{
-    @ <b>[%s(zShortUuid)]</b>
+    @ <span class="timelineHistDsp">[%s(zShortUuid)]</span>
   }
 }
 
 /*
 ** Generate a hyperlink that invokes javascript to highlight
@@ -83,11 +84,11 @@
 void hyperlink_to_diff(const char *zV1, const char *zV2){
   if( g.okHistory ){
     if( zV2==0 ){
       @ <a href="%s(g.zBaseURL)/diff?v2=%s(zV1)">[diff]</a>
     }else{
-      @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&v2=%s(zV2)">[diff]</a>
+      @ <a href="%s(g.zBaseURL)/diff?v1=%s(zV1)&amp;v2=%s(zV2)">[diff]</a>
     }
   }
 }
 
 /*
@@ -109,11 +110,11 @@
 */
 void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
   if( zSuf==0 ) zSuf = "";
   if( g.okHistory ){
     if( zD && zD[0] ){
-      @ <a href="%s(g.zTop)/timeline?c=%T(zD)&u=%T(zU)">%h(zU)</a>%s(zSuf)
+      @ <a href="%s(g.zTop)/timeline?c=%T(zD)&amp;u=%T(zU)">%h(zU)</a>%s(zSuf)
     }else{
       @ <a href="%s(g.zTop)/timeline?u=%T(zU)">%h(zU)</a>%s(zSuf)
     }
   }else{
     @ %s(zU)
@@ -189,14 +190,17 @@
   }else{
     wikiFlags = WIKI_INLINE | WIKI_NOBLOCK;
   }
   if( tmFlags & TIMELINE_GRAPH ){
     pGraph = graph_init();
+    /* style is not moved to css, because this is
+    ** a technical div for the timeline graph
+    */
     @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
   }
 
-  @ <table cellspacing=0 border=0 cellpadding=0>
+  @ <table class="timelineTable">
   blob_zero(&comment);
   while( db_step(pQuery)==SQLITE_ROW ){
     int rid = db_column_int(pQuery, 0);
     const char *zUuid = db_column_text(pQuery, 1);
     int isLeaf = db_column_int(pQuery, 5);
@@ -218,30 +222,30 @@
         }
       }
     }
     prevTagid = tagid;
     if( suppressCnt ){
-      @ <tr><td><td><td>
-      @ <small><i>... %d(suppressCnt) similar
-      @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr>
+      @ <tr><td /><td /><td>
+      @ <span class="timelineDisabled">... %d(suppressCnt) similar
+      @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr>
       suppressCnt = 0;
     }
     if( strcmp(zType,"div")==0 ){
-      @ <tr><td colspan=3><hr></td></tr>
+      @ <tr><td colspan="3"><hr /></td></tr>
       continue;
     }
     if( memcmp(zDate, zPrevDate, 10) ){
       sprintf(zPrevDate, "%.10s", zDate);
       @ <tr><td>
-      @   <div class="divider"><nobr>%s(zPrevDate)</nobr></div>
+      @   <div class="divider">%s(zPrevDate)</div>
       @ </td></tr>
     }
     memcpy(zTime, &zDate[11], 5);
     zTime[5] = 0;
     @ <tr>
-    @ <td valign="top" align="right">%s(zTime)</td>
-    @ <td width="20" align="left" valign="top">
+    @ <td class="timelineTime">%s(zTime)</td>
+    @ <td class="timelineGraph">
     if( pGraph && zType[0]=='c' ){
       int nParent = 0;
       int aParent[32];
       const char *zBr;
       int gidx;
@@ -267,24 +271,25 @@
       }
       gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr);
       db_reset(&qbranch);
       @ <div id="m%d(gidx)"></div>
     }
+    @</td>
     if( zBgClr && zBgClr[0] ){
-      @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
+      @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
     }else{
-      @ <td valign="top" align="left">
+      @ <td class="timelineTableCell">
     }
     if( zType[0]=='c' ){
       hyperlink_to_uuid(zUuid);
       if( isLeaf ){
         if( db_exists("SELECT 1 FROM tagxref"
                       " WHERE rid=%d AND tagid=%d AND tagtype>0",
                       rid, TAG_CLOSED) ){
-          @ <b>Closed-Leaf:</b>
+          @ <span class="timelineLeaf">Closed-Leaf:</span>
         }else{
-          @ <b>Leaf:</b>
+          @ <span class="timelineLeaf">Leaf:</span>
         }
       }
     }else if( (tmFlags & TIMELINE_ARTID)!=0 ){
       hyperlink_to_uuid(zUuid);
     }
@@ -309,23 +314,27 @@
       xExtra(rid);
     }
     @ </td></tr>
   }
   if( suppressCnt ){
-    @ <tr><td><td><td>
-    @ <small><i>... %d(suppressCnt) similar
-    @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr>
+    @ <tr><td /><td /><td>
+    @ <span class="timelineDisabled">... %d(suppressCnt) similar
+    @ event%s(suppressCnt>1?"s":"") omitted.</span></td></tr>
     suppressCnt = 0;
   }
   if( pGraph ){
     graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
     if( pGraph->nErr ){
       graph_free(pGraph);
       pGraph = 0;
     }else{
-      @ <tr><td><td>
+      /* style is not moved to css, because this is
+      ** a technical div for the timeline graph
+      */
+      @ <tr><td /><td>
       @ <div id="grbtm" style="width:%d(pGraph->mxRail*20+30)px;"></div>
+      @ </td></tr>
     }
   }
   @ </table>
   timeline_output_graph_javascript(pGraph);
 }
@@ -337,11 +346,11 @@
 void timeline_output_graph_javascript(GraphContext *pGraph){
   if( pGraph && pGraph->nErr==0 ){
     GraphRow *pRow;
     int i;
     char cSep;
-    @ <script type="text/JavaScript">
+    @ <script  type="text/JavaScript">
     cgi_printf("var rowinfo = [\n");
     for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
       cgi_printf("{id:\"m%d\",bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,au:",
         pRow->idx,
         pRow->zBgClr,
@@ -883,15 +892,15 @@
     }else if( zBrName ){
       blob_appendf(&desc, " related to \"%h\"", zBrName);
       tmFlags |= TIMELINE_DISJOINT;
     }
     if( zAfter ){
-      blob_appendf(&desc, " occurring on or after %h.<br>", zAfter);
+      blob_appendf(&desc, " occurring on or after %h.<br />", zAfter);
     }else if( zBefore ){
-      blob_appendf(&desc, " occurring on or before %h.<br>", zBefore);
+      blob_appendf(&desc, " occurring on or before %h.<br />", zBefore);
     }else if( zCirca ){
-      blob_appendf(&desc, " occurring around %h.<br>", zCirca);
+      blob_appendf(&desc, " occurring around %h.<br />", zCirca);
     }
     if( zSearch ){
       blob_appendf(&desc, " matching \"%h\"", zSearch);
     }
     if( g.okHistory ){

Index: src/tkt.c
==================================================================
--- src/tkt.c
+++ src/tkt.c
@@ -313,11 +313,11 @@
     style_submenu_element("New Ticket", "Create a new ticket",
         "%s/tktnew", g.zTop);
   }
   if( g.okApndTkt && g.okAttach ){
     style_submenu_element("Attach", "Add An Attachment",
-        "%s/attachadd?tkt=%T&from=%s/tktview/%t",
+        "%s/attachadd?tkt=%T&amp;from=%s/tktview/%t",
         g.zTop, zUuid, g.zTop, zUuid);
   }
   style_header("View Ticket");
   if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
   ticket_init();
@@ -342,24 +342,24 @@
     while( db_step(&q)==SQLITE_ROW ){
       const char *zDate = db_column_text(&q, 0);
       const char *zFile = db_column_text(&q, 1);
       const char *zUser = db_column_text(&q, 2);
       if( cnt==0 ){
-        @ <hr><h2>Attachments:</h2>
+        @ <hr /><h2>Attachments:</h2>
         @ <ul>
       }
       cnt++;
       if( g.okRead && g.okHistory ){
-        @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&file=%t(zFile)">
+        @ <li><a href="%s(g.zTop)/attachview?tkt=%s(zFullName)&amp;file=%t(zFile)">
         @ %h(zFile)</a>
       }else{
         @ %h(zFile)
       }
       @ added by %h(zUser) on
       hyperlink_to_date(zDate, ".");
       if( g.okWrTkt && g.okAttach ){
-        @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&file=%t(zFile)&from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>]
+        @ [<a href="%s(g.zTop)/attachdelete?tkt=%s(zFullName)&amp;file=%t(zFile)&amp;from=%s(g.zTop)/tktview%%3fname=%s(zFullName)">delete</a>]
       }
     }
     if( cnt ){
       @ </ul>
     }
@@ -511,12 +511,13 @@
   if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1);
   ticket_init();
   getAllTicketFields();
   initializeVariablesFromDb();
   initializeVariablesFromCGI();
-  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
+  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p>
   login_insert_csrf_secret();
+  @ </p>
   zScript = ticket_newpage_code();
   Th_Store("login", g.zLogin);
   Th_Store("date", db_text(0, "SELECT datetime('now')"));
   Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
                    (void*)&zNewUuid, 0);
@@ -554,34 +555,36 @@
     cgi_redirectf("tktview?name=%T", zName);
   }
   style_header("Edit Ticket");
   if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE
           || !validate16(zName,nName) ){
-    @ <font color="red"><b>Not a valid ticket id: \"%h(zName)\"</b></font>
+    @ <span class="tktError">Not a valid ticket id: \"%h(zName)\"</span>
     style_footer();
     return;
   }
   nRec = db_int(0, "SELECT count(*) FROM ticket WHERE tkt_uuid GLOB '%q*'",
                 zName);
   if( nRec==0 ){
-    @ <font color="red"><b>No such ticket: \"%h(zName)\"</b></font>
+    @ <span class="tktError">No such ticket: \"%h(zName)\"</span>
     style_footer();
     return;
   }
   if( nRec>1 ){
-    @ <font color="red"><b>%d(nRec) tickets begin with: \"%h(zName)\"</b></font>
+    @ <span class="tktError"><b>%d(nRec) tickets begin with:
+    @ \"%h(zName)\"</span>
     style_footer();
     return;
   }
   if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
   ticket_init();
   getAllTicketFields();
   initializeVariablesFromCGI();
   initializeVariablesFromDb();
-  @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
-  @ <input type="hidden" name="name" value="%s(zName)">
+  @ <form method="post" action="%s(g.zBaseURL)/%s(g.zPath)"><p>
+  @ <input type="hidden" name="name" value="%s(zName)" />
   login_insert_csrf_secret();
+  @ </p>
   zScript = ticket_editpage_code();
   Th_Store("login", g.zLogin);
   Th_Store("date", db_text(0, "SELECT datetime('now')"));
   Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
   Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
@@ -624,11 +627,11 @@
   return 0;
 }
 
 /*
 ** WEBPAGE: tkttimeline
-** URL: /tkttimeline?name=TICKETUUID&y=TYPE
+** URL: /tkttimeline?name=TICKETUUID&amp;y=TYPE
 **
 ** Show the change history for a single ticket in timeline format.
 */
 void tkttimeline_page(void){
   Stmt q;
@@ -644,11 +647,11 @@
   if( !g.okHistory || !g.okRdTkt ){ login_needed(); return; }
   zUuid = PD("name","");
   zType = PD("y","a");
   if( zType[0]!='c' ){
     style_submenu_element("Check-ins", "Check-ins",
-       "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid);
+       "%s/tkttimeline?name=%T&amp;y=ci", g.zTop, zUuid);
   }else{
     style_submenu_element("Timeline", "Timeline",
        "%s/tkttimeline?name=%T", g.zTop, zUuid);
   }
   style_submenu_element("History", "History",
@@ -776,12 +779,12 @@
         @ <p>Ticket change
         @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zShort)</a>]
         @ (rid %d(rid)) by
         hyperlink_to_user(m.zUser,zDate," on");
         hyperlink_to_date(zDate, ":");
-        ticket_output_change_artifact(&m);
         @ </p>
+        ticket_output_change_artifact(&m);
       }
       manifest_clear(&m);
     }
   }
   db_finalize(&q);

Index: src/tktsetup.c
==================================================================
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -130,21 +130,21 @@
       db_set(zDbField, z, 0);
       if( xRebuild ) xRebuild();
       cgi_redirect("tktsetup");
     }
   }
-  @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
+  @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="post"><div>
   login_insert_csrf_secret();
   @ <p>%s(zDesc)</p>
   @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
-  @ <blockquote>
-  @ <input type="submit" name="submit" value="Apply Changes">
-  @ <input type="submit" name="clear" value="Revert To Default">
-  @ <input type="submit" name="setup" value="Cancel">
-  @ </blockquote>
-  @ </form>
-  @ <hr>
+  @ <blockquote><p>
+  @ <input type="submit" name="submit" value="Apply Changes" />
+  @ <input type="submit" name="clear" value="Revert To Default" />
+  @ <input type="submit" name="setup" value="Cancel" />
+  @ </p></blockquote>
+  @ </div></form>
+  @ <hr />
   @ <h2>Default %s(zTitle)</h2>
   @ <blockquote><pre>
   @ %h(zDfltValue)
   @ </pre></blockquote>
   style_footer();
@@ -153,13 +153,13 @@
 /*
 ** WEBPAGE: tktsetup_tab
 */
 void tktsetup_tab_page(void){
   static const char zDesc[] =
-  @ <p>Enter a valid CREATE TABLE statement for the "ticket" table.  The
+  @ Enter a valid CREATE TABLE statement for the "ticket" table.  The
   @ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime"
-  @ with an unique index on "tkt_uuid" and "tkt_mtime".</p>
+  @ with an unique index on "tkt_uuid" and "tkt_mtime".
   ;
   tktsetup_generic(
     "Ticket Table Schema",
     "ticket-table",
     zDefaultTicketTable,
@@ -229,12 +229,12 @@
 /*
 ** WEBPAGE: tktsetup_com
 */
 void tktsetup_com_page(void){
   static const char zDesc[] =
-  @ <p>Enter TH1 script that initializes variables prior to generating
-  @ any of the ticket view, edit, or creation pages.</p>
+  @ Enter TH1 script that initializes variables prior to generating
+  @ any of the ticket view, edit, or creation pages.
   ;
   tktsetup_generic(
     "Ticket Common Script",
     "ticket-common",
     zDefaultTicketCommon,
@@ -250,80 +250,80 @@
 @   if {[info exists submit]} {
 @      set status Open
 @      submit_ticket
 @   }
 @ </th1>
-@ <h1 align="center">Enter A New Ticket</h1>
+@ <h1 style="text-align: center;">Enter A New Ticket</h1>
 @ <table cellpadding="5">
 @ <tr>
 @ <td colspan="2">
-@ Enter a one-line summary of the ticket:<br>
-@ <input type="text" name="title" size="60" value="$<title>">
+@ Enter a one-line summary of the ticket:<br />
+@ <input type="text" name="title" size="60" value="$<title>" />
 @ </td>
 @ </tr>
 @ 
 @ <tr>
-@ <td align="right">Type:
+@ <td style="text-align: center;">Type:
 @ <th1>combobox type $type_choices 1</th1>
 @ </td>
 @ <td>What type of ticket is this?</td>
 @ </tr>
 @ 
 @ <tr>
-@ <td align="right">Version: 
-@ <input type="text" name="foundin" size="20" value="$<foundin>">
+@ <td style="text-align: center;">Version: 
+@ <input type="text" name="foundin" size="20" value="$<foundin>" />
 @ </td>
 @ <td>In what version or build number do you observe the problem?</td>
 @ </tr>
 @ 
 @ <tr>
-@ <td align="right">Severity:
+@ <td style="text-align: center;">Severity:
 @ <th1>combobox severity $severity_choices 1</th1>
 @ </td>
 @ <td>How debilitating is the problem?  How badly does the problem
 @ affect the operation of the product?</td>
 @ </tr>
 @ 
 @ <tr>
-@ <td align="right">EMail:
-@ <input type="text" name="private_contact" value="$<private_contact>" size="30">
+@ <td style="text-align: center;">EMail:
+@ <input type="text" name="private_contact" value="$<private_contact>" size="30" />
 @ </td>
-@ <td><u>Not publicly visible</u>. Used by developers to contact you with
-@ questions.</td>
+@ <td><span style="text-decoration: underline;">Not publicly visible</span>.
+@ Used by developers to contact you with questions.</td>
 @ </tr>
 @ 
 @ <tr>
 @ <td colspan="2">
 @ Enter a detailed description of the problem.
 @ For code defects, be sure to provide details on exactly how
 @ the problem can be reproduced.  Provide as much detail as
 @ possible.
-@ <br>
+@ <br />
 @ <th1>set nline [linecount $comment 50 10]</th1>
 @ <textarea name="comment" cols="80" rows="$nline"
-@  wrap="virtual" class="wikiedit">$<comment></textarea><br>
-@ <input type="submit" name="preview" value="Preview">
+@  wrap="virtual" class="wikiedit">$<comment></textarea><br />
+@ <input type="submit" name="preview" value="Preview" /></td>
 @ </tr>
 @
 @ <th1>enable_output [info exists preview]</th1>
 @ <tr><td colspan="2">
-@ Description Preview:<br><hr>
+@ Description Preview:<br /><hr />
 @ <th1>wiki $comment</th1>
-@ <hr>
+@ <hr />
 @ </td></tr>
 @ <th1>enable_output 1</th1>
 @ 
 @ <tr>
-@ <td align="right">
-@ <input type="submit" name="submit" value="Submit">
+@ <td style="text-align: center;">
+@ <input type="submit" name="submit" value="Submit" />
 @ </td>
 @ <td>After filling in the information above, press this button to create
 @ the new ticket</td>
 @ </tr>
 @ <tr>
-@ <td align="right">
-@ <input type="submit" name="cancel" value="Cancel">
+@ <td style="text-align: center;">
+@ <input type="submit" name="cancel" value="Cancel" />
 @ </td>
 @ <td>Abandon and forget this ticket</td>
 @ </tr>
 @ </table>
 ;
@@ -338,12 +338,12 @@
 /*
 ** WEBPAGE: tktsetup_newpage
 */
 void tktsetup_newpage_page(void){
   static const char zDesc[] =
-  @ <p>Enter HTML with embedded TH1 script that will render the "new ticket"
-  @ page</p>
+  @ Enter HTML with embedded TH1 script that will render the "new ticket"
+  @ page
   ;
   tktsetup_generic(
     "HTML For New Tickets",
     "ticket-newpage",
     zDefaultNew,
@@ -354,51 +354,50 @@
   );
 }
 
 static const char zDefaultView[] =
 @ <table cellpadding="5">
-@ <tr><td align="right">Ticket&nbsp;UUID:</td><td bgcolor="#d0d0d0" colspan="3">
-@ $<tkt_uuid>
-@ </td></tr>
-@ <tr><td align="right">Title:</td>
-@ <td bgcolor="#d0d0d0" colspan="3" valign="top">
+@ <tr><td class="tktDspLabel">Ticket&nbsp;UUID:</td>
+@ <td class="tktDspValue" colspan="3">$<tkt_uuid></td></tr>
+@ <tr><td class="tktDspLabel">Title:</td>
+@ <td class="tktDspValue" colspan="3">
 @ <th1>wiki $title</th1>
 @ </td></tr>
-@ <tr><td align="right">Status:</td><td bgcolor="#d0d0d0">
+@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue">
 @ $<status>
 @ </td>
-@ <td align="right">Type:</td><td bgcolor="#d0d0d0">
+@ <td class="tktDspLabel">Type:</td><td class="tktDspValue">
 @ $<type>
 @ </td></tr>
-@ <tr><td align="right">Severity:</td><td bgcolor="#d0d0d0">
+@ <tr><td class="tktDspLabel">Severity:</td><td class="tktDspValue">
 @ $<severity>
 @ </td>
-@ <td align="right">Priority:</td><td bgcolor="#d0d0d0">
+@ <td class="tktDspLabel">Priority:</td><td class="tktDspValue">
 @ $<priority>
 @ </td></tr>
-@ <tr><td align="right">Subsystem:</td><td bgcolor="#d0d0d0">
+@ <tr><td class="tktDspLabel">Subsystem:</td><td class="tktDspValue">
 @ $<subsystem>
 @ </td>
-@ <td align="right">Resolution:</td><td bgcolor="#d0d0d0">
+@ <td class="tktDspLabel">Resolution:</td><td class="tktDspValue">
 @ $<resolution>
 @ </td></tr>
-@ <tr><td align="right">Last&nbsp;Modified:</td><td bgcolor="#d0d0d0">
+@ <tr><td class="tktDspLabel">Last&nbsp;Modified:</td><td class="tktDspValue">
 @ $<tkt_datetime>
 @ </td>
 @ <th1>enable_output [hascap e]</th1>
-@   <td align="right">Contact:</td><td bgcolor="#d0d0d0">
+@   <td class="tktDspLabel">Contact:</td><td class="tktDspValue">
 @   $<private_contact>
 @   </td>
 @ <th1>enable_output 1</th1>
 @ </tr>
-@ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td>
-@ <td colspan="3" valign="top" bgcolor="#d0d0d0">
+@ <tr><td class="tktDspLabel">Version&nbsp;Found&nbsp;In:</td>
+@ <td colspan="3" valign="top" class="tktDspValue">
 @ $<foundin>
 @ </td></tr>
 @ <tr><td>Description &amp; Comments:</td></tr>
-@ <tr><td colspan="4" bgcolor="#d0d0d0">
-@ <span  bgcolor="#d0d0d0"><th1>wiki $comment</th1></span>
+@ <tr><td colspan="4" class="tktDspValue">
+@ <th1>wiki $comment</th1>
 @ </td></tr>
 @ </table>
 ;
 
 
@@ -412,12 +411,11 @@
 /*
 ** WEBPAGE: tktsetup_viewpage
 */
 void tktsetup_viewpage_page(void){
   static const char zDesc[] =
-  @ <p>Enter HTML with embedded TH1 script that will render the "view ticket"
-  @ page</p>
+  @ Enter HTML with embedded TH1 script that will render the "view ticket" page
   ;
   tktsetup_generic(
     "HTML For Viewing Tickets",
     "ticket-viewpage",
     zDefaultView,
@@ -432,51 +430,51 @@
 @ <th1>
 @   if {![info exists username]} {set username $login}
 @   if {[info exists submit]} {
 @     if {[info exists cmappnd]} {
 @       if {[string length $cmappnd]>0} {
-@         set ctxt "\n\n<hr><i>[htmlize $login]"
+@         set ctxt "\n\n<hr /><i>[htmlize $login]"
 @         if {$username ne $login} {
 @           set ctxt "$ctxt claiming to be [htmlize $username]"
 @         }
-@         set ctxt "$ctxt added on [date]:</i><br>\n$cmappnd"
+@         set ctxt "$ctxt added on [date]:</i><br />\n$cmappnd"
 @         append_field comment $ctxt
 @       }
 @     }
 @     submit_ticket
 @   }
 @ </th1>
 @ <table cellpadding="5">
-@ <tr><td align="right">Title:</td><td>
-@ <input type="text" name="title" value="$<title>" size="60">
+@ <tr><td class="tktDspLabel">Title:</td><td>
+@ <input type="text" name="title" value="$<title>" size="60" />
 @ </td></tr>
-@ <tr><td align="right">Status:</td><td>
+@ <tr><td class="tktDspLabel">Status:</td><td>
 @ <th1>combobox status $status_choices 1</th1>
 @ </td></tr>
-@ <tr><td align="right">Type:</td><td>
+@ <tr><td class="tktDspLabel">Type:</td><td>
 @ <th1>combobox type $type_choices 1</th1>
 @ </td></tr>
-@ <tr><td align="right">Severity:</td><td>
+@ <tr><td class="tktDspLabel">Severity:</td><td>
 @ <th1>combobox severity $severity_choices 1</th1>
 @ </td></tr>
-@ <tr><td align="right">Priority:</td><td>
+@ <tr><td class="tktDspLabel">Priority:</td><td>
 @ <th1>combobox priority $priority_choices 1</th1>
 @ </td></tr>
-@ <tr><td align="right">Resolution:</td><td>
+@ <tr><td class="tktDspLabel">Resolution:</td><td>
 @ <th1>combobox resolution $resolution_choices 1</th1>
 @ </td></tr>
-@ <tr><td align="right">Subsystem:</td><td>
+@ <tr><td class="tktDspLabel">Subsystem:</td><td>
 @ <th1>combobox subsystem $subsystem_choices 1</th1>
 @ </td></tr>
 @ <th1>enable_output [hascap e]</th1>
-@   <tr><td align="right">Contact:</td><td>
+@   <tr><td class="tktDspLabel">Contact:</td><td>
 @   <input type="text" name="private_contact" size="40"
-@    value="$<private_contact>">
+@    value="$<private_contact>" />
 @   </td></tr>
 @ <th1>enable_output 1</th1>
-@ <tr><td align="right">Version&nbsp;Found&nbsp;In:</td><td>
-@ <input type="text" name="foundin" size="50" value="$<foundin>">
+@ <tr><td class="tktDspLabel">Version&nbsp;Found&nbsp;In:</td><td>
+@ <input type="text" name="foundin" size="50" value="$<foundin>" />
 @ </td></tr>
 @ <tr><td colspan="2">
 @ <th1>
 @   if {![info exists eall]} {set eall 0}
 @   if {[info exists aonlybtn]} {set eall 0}
@@ -484,45 +482,45 @@
 @   if {![hascap w]} {set eall 0}
 @   if {![info exists cmappnd]} {set cmappnd {}}
 @   set nline [linecount $comment 15 10]
 @   enable_output $eall
 @ </th1>
-@   Description And Comments:<br>
+@   Description And Comments:<br />
 @   <textarea name="comment" cols="80" rows="$nline"
-@    wrap="virtual" class="wikiedit">$<comment></textarea><br>
-@   <input type="hidden" name="eall" value="1">
-@   <input type="submit" name="aonlybtn" value="Append Remark">
-@   <input type="submit" name="preview1btn" value="Preview">
+@    wrap="virtual" class="wikiedit">$<comment></textarea><br />
+@   <input type="hidden" name="eall" value="1" />
+@   <input type="submit" name="aonlybtn" value="Append Remark" />
+@   <input type="submit" name="preview1btn" value="Preview" />
 @ <th1>enable_output [expr {!$eall}]</th1>
 @   Append Remark from 
-@   <input type="text" name="username" value="$<username>" size="30">:<br>
+@   <input type="text" name="username" value="$<username>" size="30" />:<br />
 @   <textarea name="cmappnd" cols="80" rows="15"
-@    wrap="virtual" class="wikiedit">$<cmappnd></textarea><br>
+@    wrap="virtual" class="wikiedit">$<cmappnd></textarea><br />
 @ <th1>enable_output [expr {[hascap w] && !$eall}]</th1>
-@   <input type="submit" name="eallbtn" value="Edit All">
+@   <input type="submit" name="eallbtn" value="Edit All" />
 @ <th1>enable_output [expr {!$eall}]</th1>
-@   <input type="submit" name="preview2btn" value="Preview">
+@   <input type="submit" name="preview2btn" value="Preview" />
 @ <th1>enable_output 1</th1>
 @ </td></tr>
 @
 @ <th1>enable_output [info exists preview1btn]</th1>
 @ <tr><td colspan="2">
-@ Description Preview:<br><hr>
+@ Description Preview:<br /><hr />
 @ <th1>wiki $comment</th1>
-@ <hr>
+@ <hr />
 @ </td></tr>
 @ <th1>enable_output [info exists preview2btn]</th1>
 @ <tr><td colspan="2">
-@ Description Preview:<br><hr>
+@ Description Preview:<br /><hr />
 @ <th1>wiki $cmappnd</th1>
-@ <hr>
+@ <hr />
 @ </td></tr>
 @ <th1>enable_output 1</th1>
 @
 @ <tr><td align="right"></td><td>
-@ <input type="submit" name="submit" value="Submit Changes">
-@ <input type="submit" name="cancel" value="Cancel">
+@ <input type="submit" name="submit" value="Submit Changes" />
+@ <input type="submit" name="cancel" value="Cancel" />
 @ </td></tr>
 @ </table>
 ;
 
 /*
@@ -535,12 +533,11 @@
 /*
 ** WEBPAGE: tktsetup_editpage
 */
 void tktsetup_editpage_page(void){
   static const char zDesc[] =
-  @ <p>Enter HTML with embedded TH1 script that will render the "edit ticket"
-  @ page</p>
+  @ Enter HTML with embedded TH1 script that will render the "edit ticket" page
   ;
   tktsetup_generic(
     "HTML For Editing Tickets",
     "ticket-editpage",
     zDefaultEdit,
@@ -585,12 +582,11 @@
 /*
 ** WEBPAGE: tktsetup_reportlist
 */
 void tktsetup_reportlist(void){
   static const char zDesc[] =
-  @ <p>Enter HTML with embedded TH1 script that will render the "report list"
-  @ page</p>
+  @ Enter HTML with embedded TH1 script that will render the "report list" page
   ;
   tktsetup_generic(
     "HTML For Report List",
     "ticket-reportlist",
     zDefaultReportList,
@@ -633,13 +629,13 @@
 /*
 ** WEBPAGE: tktsetup_rpttplt
 */
 void tktsetup_rpttplt_page(void){
   static const char zDesc[] =
-  @ <p>Enter the default ticket report format template.  This is the
+  @ Enter the default ticket report format template.  This is the
   @ the template report format that initially appears when creating a
-  @ new ticket summary report.</p>
+  @ new ticket summary report.
   ;
   tktsetup_generic(
     "Default Report Template",
     "ticket-report-template",
     zDefaultReport,
@@ -674,13 +670,13 @@
 /*
 ** WEBPAGE: tktsetup_keytplt
 */
 void tktsetup_keytplt_page(void){
   static const char zDesc[] =
-  @ <p>Enter the default ticket report color-key template.  This is the
+  @ Enter the default ticket report color-key template.  This is the
   @ the color-key that initially appears when creating a
-  @ new ticket summary report.</p>
+  @ new ticket summary report.
   ;
   tktsetup_generic(
     "Default Report Color-Key Template",
     "ticket-key-template",
     zDefaultKey,
@@ -703,34 +699,34 @@
   if( P("setup") ){
     cgi_redirect("tktsetup");
   }
   style_header("Ticket Display On Timelines");
   db_begin_transaction();
-  @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST">
+  @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="post"><div>
   login_insert_csrf_secret();
 
-  @ <hr>
+  @ <hr />
   entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title");
   @ <p>An SQL expression in a query against the TICKET table that will
   @ return the title of the ticket for display purposes.</p>
 
-  @ <hr>
+  @ <hr />
   entry_attribute("Ticket Status", 40, "ticket-status-column", "s", "status");
   @ <p>The name of the column in the TICKET table that contains the ticket
   @ status in human-readable form.  Case sensitive.</p>
 
-  @ <hr>
+  @ <hr />
   entry_attribute("Ticket Closed", 40, "ticket-closed-expr", "c",
                   "status='Closed'");
   @ <p>An SQL expression that evaluates to true in a TICKET table query if
   @ the ticket is closed.</p>
 
-  @ <hr>
+  @ <hr />
   @ <p>
-  @ <input type="submit"  name="submit" value="Apply Changes">
-  @ <input type="submit" name="setup" value="Cancel">
+  @ <input type="submit"  name="submit" value="Apply Changes" />
+  @ <input type="submit" name="setup" value="Cancel" />
   @ </p>
-  @ </form>
+  @ </div></form>
   db_end_transaction(0);
   style_footer();
   
 }

Index: src/translate.c
==================================================================
--- src/translate.c
+++ src/translate.c
@@ -66,15 +66,16 @@
 
 /*
 ** Translate the input stream into the output stream
 */
 static void trans(FILE *in, FILE *out){
-  int i, j, k;        /* Loop counters */
-  char c1, c2;        /* Characters used to start a comment */
-  int lastWasEq = 0;  /* True if last non-whitespace character was "=" */
-  char zLine[2000];   /* A single line of input */
-  char zOut[4000];    /* The input line translated into appropriate output */
+  int i, j, k;          /* Loop counters */
+  char c1, c2;          /* Characters used to start a comment */
+  int lastWasEq = 0;    /* True if last non-whitespace character was "=" */
+  int lastWasComma = 0; /* True if last non-whitespace character was "," */
+  char zLine[2000];     /* A single line of input */
+  char zOut[4000];      /* The input line translated into appropriate output */
 
   c1 = c2 = '-';
   while( fgets(zLine, sizeof(zLine), in) ){
     for(i=0; zLine[i] && isspace(zLine[i]); i++){}
     if( zLine[i]!='@' ){
@@ -85,14 +86,16 @@
         c1 = zLine[14];
         c2 = zLine[15];
       }
       i += strlen(&zLine[i]);
       while( i>0 && isspace(zLine[i-1]) ){ i--; }
-      lastWasEq = i>0 && zLine[i-1]=='=';
-    }else if( lastWasEq ){
+      lastWasEq    = i>0 && zLine[i-1]=='=';
+      lastWasComma = i>0 && zLine[i-1]==',';
+    }else if( lastWasEq || lastWasComma){
       /* If the last non-whitespace character before the first @ was
-      ** an "=" then generate a string literal.  But skip comments
+      ** an "="(var init/set) or a ","(const definition in list) then
+      ** generate a string literal.  But skip comments
       ** consisting of all text between c1 and c2 (default "--")
       ** and end of line.
       */
       int indent, omitline;
       i++;

Index: src/update.c
==================================================================
--- src/update.c
+++ src/update.c
@@ -111,10 +111,11 @@
     tid = db_int(0, "SELECT rid FROM leaves, event"
                     " WHERE event.objid=leaves.rid"
                     " ORDER BY event.mtime DESC"); 
   }
 
+  if( tid==vid ) return;  /* Nothing to update */
   db_begin_transaction();
   vfile_check_signature(vid, 1);
   if( !nochangeFlag ) undo_begin();
   load_vfile_from_rid(tid);
 

Index: src/url.c
==================================================================
--- src/url.c
+++ src/url.c
@@ -351,11 +351,11 @@
       zName2 = 0;
       z = zValue2;
       if( z==0 ) continue;
     }
     blob_appendf(&p->url, "%s%s=%T", zSep, p->azName[i], z);
-    zSep = "&";
+    zSep = "&amp;";
   }
   if( zName1 && zValue1 ){
     blob_appendf(&p->url, "%s%s=%T", zSep, zName1, zValue1);
   }
   if( zName2 && zValue2 ){

Index: src/wiki.c
==================================================================
--- src/wiki.c
+++ src/wiki.c
@@ -48,15 +48,15 @@
 /*
 ** Output rules for well-formed wiki pages
 */
 static void well_formed_wiki_name_rules(void){
   @ <ul>
-  @ <li> Must not begin or end with a space.
+  @ <li> Must not begin or end with a space.</li>
   @ <li> Must not contain any control characters, including tab or
-  @      newline.
-  @ <li> Must not have two or more spaces in a row internally.
-  @ <li> Must be between 3 and 100 characters in length.
+  @      newline.</li>
+  @ <li> Must not have two or more spaces in a row internally.</li>
+  @ <li> Must be between 3 and 100 characters in length.</li>
   @ </ul>
 }
 
 /*
 ** Check a wiki name.  If it is not well-formed, then issue an error
@@ -63,12 +63,12 @@
 ** and return true.  If it is well-formed, return false.
 */
 static int check_name(const char *z){
   if( !wiki_name_is_wellformed((const unsigned char *)z) ){
     style_header("Wiki Page Name Error");
-    @ The wiki name "<b>%h(z)</b>" is not well-formed.  Rules for
-    @ wiki page names:
+    @ The wiki name "<span class="wikiError">%h(z)</span>" is not well-formed.
+    @ Rules for wiki page names:
     well_formed_wiki_name_rules();
     style_footer();
     return 1;
   }
   return 0;
@@ -155,14 +155,14 @@
     if( g.okNewWiki ){
       @ <li>  Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li>
     }
     @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a>
     @      available on this server.</li>
-	@ <li> <form method="GET" action="%s(g.zBaseURL)/wfind">
-	@     Search wiki titles: <input type="text" name="title"/>
-        @  &nbsp; <input type="submit" />
-	@ </li>
+    @ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div>
+    @     Search wiki titles: <input type="text" name="title"/>
+    @  &nbsp; <input type="submit" /></div></form>
+    @ </li>
     @ </ul>
     style_footer();
     return;
   }
   if( check_name(zPageName) ) return;
@@ -194,11 +194,11 @@
       style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
            g.zTop, zPageName);
     }
     if( rid && g.okApndWiki && g.okAttach ){
       style_submenu_element("Attach", "Add An Attachment",
-           "%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
+           "%s/attachadd?page=%T&amp;from=%s/wiki%%3fname=%T",
            g.zTop, zPageName, g.zTop, zPageName);
     }
     if( rid && g.okApndWiki ){
       style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T",
            g.zTop, zPageName);
@@ -227,19 +227,20 @@
       @ <hr><h2>Attachments:</h2>
       @ <ul>
     }
     cnt++;
     if( g.okHistory && g.okRead ){
-      @ <li><a href="%s(g.zTop)/attachview?page=%s(zPageName)&file=%t(zFile)">
+      @ <li>
+      @ <a href="%s(g.zTop)/attachview?page=%s(zPageName)&amp;file=%t(zFile)">
       @ %h(zFile)</a>
     }else{
       @ <li>%h(zFile)
     }
     @ added by %h(zUser) on
     hyperlink_to_date(zDate, ".");
     if( g.okWrWiki && g.okAttach ){
-      @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&file=%t(zFile)&from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>]
+      @ [<a href="%s(g.zTop)/attachdelete?page=%s(zPageName)&amp;file=%t(zFile)&amp;from=%s(g.zTop)/wiki%%3fname=%s(zPageName)">delete</a>]
     }
   }
   if( cnt ){
     @ </ul>
   }
@@ -351,30 +352,30 @@
   zHtmlPageName = mprintf("Edit: %s", zPageName);
   style_header(zHtmlPageName);
   if( P("preview")!=0 ){
     blob_zero(&wiki);
     blob_append(&wiki, zBody, -1);
-    @ Preview:<hr>
+    @ Preview:<hr />
     wiki_convert(&wiki, 0, 0);
-    @ <hr>
+    @ <hr />
     blob_reset(&wiki);
   }
   for(n=2, z=zBody; z[0]; z++){
     if( z[0]=='\n' ) n++;
   }
   if( n<20 ) n = 20;
   if( n>40 ) n = 40;
-  @ <form method="POST" action="%s(g.zBaseURL)/wikiedit">
+  @ <form method="post" action="%s(g.zBaseURL)/wikiedit"><div>
   login_insert_csrf_secret();
-  @ <input type="hidden" name="name" value="%h(zPageName)">
+  @ <input type="hidden" name="name" value="%h(zPageName)" />
   @ <textarea name="w" class="wikiedit" cols="80" 
   @  rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
-  @ <br>
-  @ <input type="submit" name="preview" value="Preview Your Changes">
-  @ <input type="submit" name="submit" value="Apply These Changes">
-  @ <input type="submit" name="cancel" value="Cancel">
-  @ </form>
+  @ <br />
+  @ <input type="submit" name="preview" value="Preview Your Changes" />
+  @ <input type="submit" name="submit" value="Apply These Changes" />
+  @ <input type="submit" name="cancel" value="Cancel" />
+  @ </div></form>
   if( !isSandbox ){
     manifest_clear(&m);
   }
   style_footer();
 }
@@ -396,21 +397,20 @@
   zName = PD("name","");
   if( zName[0] && wiki_name_is_wellformed((const unsigned char *)zName) ){
     cgi_redirectf("wikiedit?name=%T", zName);
   }
   style_header("Create A New Wiki Page");
-  @ <p>Rules for wiki page names:
+  @ <p>Rules for wiki page names:</p>
   well_formed_wiki_name_rules();
-  @ </p>
-  @ <form method="POST" action="%s(g.zBaseURL)/wikinew">
+  @ <form method="post" action="%s(g.zBaseURL)/wikinew">
   @ <p>Name of new wiki page:
-  @ <input type="text" width="35" name="name" value="%h(zName)">
-  @ <input type="submit" value="Create">
+  @ <input style="width: 35;" type="text" name="name" value="%h(zName)" />
+  @ <input type="submit" value="Create" />
   @ </p></form>
   if( zName[0] ){
-    @ <p><b><font color="red">
-    @ "%h(zName)" is not a valid wiki page name!</font></b></p>
+    @ <p><span class="wikiError">
+    @ "%h(zName)" is not a valid wiki page name!</span></p>
   }
   style_footer();
 }
 
 
@@ -537,15 +537,15 @@
   zUser = PD("u", g.zLogin);
   @ <form method="POST" action="%s(g.zBaseURL)/wikiappend">
   login_insert_csrf_secret();
   @ <input type="hidden" name="name" value="%h(zPageName)">
   @ Your Name:
-  @ <input type="text" name="u" size="20" value="%h(zUser)"><br>
-  @ Comment to append:<br>
+  @ <input type="text" name="u" size="20" value="%h(zUser)"><br />
+  @ Comment to append:<br />
   @ <textarea name="r" class="wikiedit" cols="80" 
   @  rows="10" wrap="virtual">%h(PD("r",""))</textarea>
-  @ <br>
+  @ <br />
   @ <input type="submit" name="preview" value="Preview Your Comment">
   @ <input type="submit" name="submit" value="Append Your Changes">
   @ <input type="submit" name="cancel" value="Cancel">
   @ </form>
   style_footer();
@@ -560,11 +560,11 @@
 ** Function called to output extra text at the end of each line in
 ** a wiki history listing.
 */
 static void wiki_history_extra(int rid){
   if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){
-    @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&a=%d(rid)">[diff]</a>
+    @ <a href="%s(g.zTop)/wdiff?name=%t(zWikiPageName)&amp;a=%d(rid)">[diff]</a>
   }
 }
 
 /*
 ** WEBPAGE: whistory
@@ -740,39 +740,39 @@
   @ </ol>
   @ <p>We call the first five rules above "wiki" formatting rules.  The
   @ last two rules are the HTML formatting rule.</p>
   @ <h2>Formatting Rule Details</h2>
   @ <ol>
-  @ <li> <p><b>Paragraphs</b>.  Any sequence of one or more blank lines forms
+  @ <li> <p><span class="wikiruleHead">Paragraphs</span>.  Any sequence of one or more blank lines forms
   @ a paragraph break.  Centered or right-justified paragraphs are not
   @ supported by wiki markup, but you can do these things if you need them
-  @ using HTML.</p>
-  @ <li> <p><b>Bullet Lists</b>.
+  @ using HTML.</p></li>
+  @ <li> <p><span class="wikiruleHead">Bullet Lists</span>.
   @ A bullet list item is a line that begins with a single "*" character
   @ surrounded on
   @ both sides by two or more spaces or by a tab.  Only a single level
-  @ of bullet list is supported by wiki.  For nested lists, use HTML.</p>
-  @ <li> <p><b>Enumeration Lists</b>.
+  @ of bullet list is supported by wiki.  For nested lists, use HTML.</p></li>
+  @ <li> <p><span class="wikiruleHead">Enumeration Lists</span>.
   @ An enumeration list item is a line that begins with a single "#" character
   @ surrounded on both sides by two or more spaces or by a tab.  Only a single
   @ level of enumeration list is supported by wiki.  For nested lists or for
-  @ enumerations that count using letters or roman numerials, use HTML.</p>
-  @ <li> <p><b>Indented Paragraphs</b>.
+  @ enumerations that count using letters or roman numerials, use HTML.</p></li>
+  @ <li> <p><span class="wikiruleHead">Indented Paragraphs</span>.
   @ Any paragraph that begins with two or more spaces or a tab and
   @ which is not a bullet or enumeration list item is rendered 
   @ indented.  Only a single level of indentation is supported by wiki; use
-  @ HTML for deeper indentation.</p>
-  @ <li> <p><b>Hyperlinks</b>.
+  @ HTML for deeper indentation.</p></li>
+  @ <li> <p><span class="wikiruleHead">Hyperlinks</span>.
   @ Text within square brackets ("[...]") becomes a hyperlink.  The
   @ target can be a wiki page name, the artifact ID of a check-in or ticket,
   @ the name of an image, or a URL.  By default, the target is displayed
   @ as the text of the hyperlink.  But you can specify alternative text
   @ after the target name separated by a "|" character.</p>
   @ <p>You can also link to internal anchor names using [#anchor-name], providing
   @ you have added the necessary "&lt;a name="anchor-name"&gt;&lt;/a&gt;"
-  @ tag to your wiki page.</p>
-  @ <li> <p><b>HTML</b>.
+  @ tag to your wiki page.</p></li>
+  @ <li> <p><span class="wikiruleHead">HTML</span>.
   @ The following standard HTML elements may be used:
   @ &lt;a&gt;
   @ &lt;address&gt;
   @ &lt;b&gt;
   @ &lt;big&gt;
@@ -822,16 +822,16 @@
   @ &lt;verbatim&gt; and &lt;nowiki&gt;.
   @ No other elements are allowed.  All attributes are checked and
   @ only a few benign attributes are allowed on each element.
   @ In particular, any attributes that specify javascript or CSS
   @ are elided.</p></li>
-  @ <li><p><b>Special Markup.</b>
+  @ <li><p><span class="wikiruleHead">Special Markup.</span>
   @ The &lt;nowiki&gt; tag disables all wiki formatting rules
   @ through the matching &lt;/nowiki&gt; element.
   @ The &lt;verbatim&gt; tag works like &lt;pre&gt; with the addition
   @ that it also disables all wiki and HTML markup
-  @ through the matching &lt;/verbatim&gt;.
+  @ through the matching &lt;/verbatim&gt;.</p></li>
   @ </ol>
   style_footer();
 }
 
 /*

Index: src/wikiformat.c
==================================================================
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -321,21 +321,21 @@
 }
 
 /*
 ** Token types
 */
-#define TOKEN_MARKUP        1    /* <...> */
-#define TOKEN_CHARACTER     2    /* "&" or "<" not part of markup */
-#define TOKEN_LINK          3    /* [...] */
-#define TOKEN_PARAGRAPH     4    /* blank lines */
-#define TOKEN_NEWLINE       5    /* A single "\n" */
-#define TOKEN_BUL_LI        6    /*  "  *  " */
-#define TOKEN_NUM_LI        7    /*  "  #  " */
-#define TOKEN_ENUM          8    /*  "  \(?\d+[.)]?  " */
-#define TOKEN_INDENT        9    /*  "   " */
-#define TOKEN_RAW           10   /* Output exactly (used when wiki-use-html==1) */
-#define TOKEN_TEXT          11   /* None of the above */
+#define TOKEN_MARKUP        1  /* <...> */
+#define TOKEN_CHARACTER     2  /* "&" or "<" not part of markup */
+#define TOKEN_LINK          3  /* [...] */
+#define TOKEN_PARAGRAPH     4  /* blank lines */
+#define TOKEN_NEWLINE       5  /* A single "\n" */
+#define TOKEN_BUL_LI        6  /*  "  *  " */
+#define TOKEN_NUM_LI        7  /*  "  #  " */
+#define TOKEN_ENUM          8  /*  "  \(?\d+[.)]?  " */
+#define TOKEN_INDENT        9  /*  "   " */
+#define TOKEN_RAW           10 /* Output exactly (used when wiki-use-html==1) */
+#define TOKEN_TEXT          11 /* None of the above */
 
 /*
 ** State flags
 */
 #define AT_NEWLINE          0x001  /* At start of a line */
@@ -745,10 +745,13 @@
 static void renderMarkup(Blob *pOut, ParsedMarkup *p){
   int i;
   if( p->endTag ){
     blob_appendf(pOut, "</%s>", aMarkup[p->iCode].zName);
   }else{
+    /* Close active paragraph for several elements, which are not allowed
+    ** in paragraphs in XHTML.
+    */
     blob_appendf(pOut, "<%s", aMarkup[p->iCode].zName);
     for(i=0; i<p->nAttr; i++){
       blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iACode].zName);
       if( p->aAttr[i].zValue ){
         const char *zVal = p->aAttr[i].zValue;
@@ -756,10 +759,13 @@
           blob_appendf(pOut, "=\"%s%s\"", g.zBaseURL, zVal);
         }else{
           blob_appendf(pOut, "=\"%s\"", zVal);
         }
       }
+    }
+    if (p->iType & MUTYPE_SINGLE){
+      blob_append(pOut, " /", 2);
     }
     blob_append(pOut, ">", 1);
   }
 }
 
@@ -885,12 +891,13 @@
 
 /*
 ** Begin a new paragraph if that something that is needed.
 */
 static void startAutoParagraph(Renderer *p){
-  if( p->wantAutoParagraph==0 || p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
-  blob_appendf(p->pOut, "<p>", -1);
+  if( p->wantAutoParagraph==0 ) return;
+  if( p->wikiList==MARKUP_OL || p->wikiList==MARKUP_UL ) return;
+  blob_appendf(p->pOut, "<p type=\"auto\">", -1);
   pushStack(p, MARKUP_P);
   p->wantAutoParagraph = 0;
   p->inAutoParagraph = 1;
 }
 
@@ -1019,17 +1026,18 @@
       /* Special display processing for tickets.  Display the hyperlink
       ** as crossed out if the ticket is closed.
       */
       if( isClosed ){
         if( g.okHistory ){
-          blob_appendf(p->pOut,"<a href=\"%s/info/%s\"><s>",
-              g.zBaseURL, zTarget
+          blob_appendf(p->pOut,
+             "<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">",
+             g.zBaseURL, zTarget
           );
-          zTerm = "</s></a>";
+          zTerm = "</span></a>";
         }else{
-          blob_appendf(p->pOut,"<s>");
-          zTerm = "</s>";
+          blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">");
+          zTerm = "</span>";
         }
       }else{
         if( g.okHistory ){
           blob_appendf(p->pOut,"<a href=\"%s/info/%s\">",
               g.zBaseURL, zTarget
@@ -1133,10 +1141,11 @@
         }else{
           if( p->wikiList!=MARKUP_UL ){
             if( p->wikiList ){
               popStackToTag(p, p->wikiList);
             }
+            endAutoParagraph(p);
             pushStack(p, MARKUP_UL);
             blob_append(p->pOut, "<ul>", 4);
             p->wikiList = MARKUP_UL;
           }
           popStackToTag(p, MARKUP_LI);
@@ -1152,10 +1161,11 @@
         }else{
           if( p->wikiList!=MARKUP_OL ){
             if( p->wikiList ){
               popStackToTag(p, p->wikiList);
             }
+            endAutoParagraph(p);
             pushStack(p, MARKUP_OL);
             blob_append(p->pOut, "<ol>", 4);
             p->wikiList = MARKUP_OL;
           }
           popStackToTag(p, MARKUP_LI);
@@ -1171,10 +1181,11 @@
         }else{
           if( p->wikiList!=MARKUP_OL ){
             if( p->wikiList ){
               popStackToTag(p, p->wikiList);
             }
+            endAutoParagraph(p);
             pushStack(p, MARKUP_OL);
             blob_append(p->pOut, "<ol>", 4);
             p->wikiList = MARKUP_OL;
           }
           popStackToTag(p, MARKUP_LI);
@@ -1233,11 +1244,13 @@
         p->state = savedState;
         blob_append(p->pOut, zClose, -1);
         break;
       }
       case TOKEN_TEXT: {
-        startAutoParagraph(p);
+        int i;
+        for(i=0; i<n && isspace(z[i]); i++){}
+        if( i<n ) startAutoParagraph(p);
         blob_append(p->pOut, z, n);
         break;
       }
       case TOKEN_RAW: {
         blob_append(p->pOut, z, n);
@@ -1347,16 +1360,19 @@
               blob_appendf(p->pOut, "<pre name='code' class='%s'>",
                 markup.aAttr[vAttrIdx].zValue);
               vAttrDidAppend=1;
             }
           }
-          if( !vAttrDidAppend )
+          if( !vAttrDidAppend ) {
+            endAutoParagraph(p);
             blob_append(p->pOut, "<pre class='verbatim'>",-1);
+          }
           p->wantAutoParagraph = 0;
         }else
         if( markup.iType==MUTYPE_LI ){
           if( backupToType(p, MUTYPE_LIST)==0 ){
+            endAutoParagraph(p);
             pushStack(p, MARKUP_UL);
             blob_append(p->pOut, "<ul>", 4);
           }
           pushStack(p, MARKUP_LI);
           renderMarkup(p->pOut, &markup);
@@ -1384,12 +1400,22 @@
           pushStack(p, markup.iCode);
         }else
         {
           if( markup.iType==MUTYPE_FONT ){
             startAutoParagraph(p);
-          }else if( markup.iType==MUTYPE_BLOCK ){
+          }else if( markup.iType==MUTYPE_BLOCK || markup.iType==MUTYPE_LIST ){
             p->wantAutoParagraph = 0;
+          }
+          if(   markup.iCode==MARKUP_HR
+             || markup.iCode==MARKUP_H1
+             || markup.iCode==MARKUP_H2
+             || markup.iCode==MARKUP_H3
+             || markup.iCode==MARKUP_H4
+             || markup.iCode==MARKUP_H5
+             || markup.iCode==MARKUP_P
+          ){
+            endAutoParagraph(p);
           }
           if( (markup.iType & MUTYPE_STACK )!=0 ){
             pushStack(p, markup.iCode);
           }
           renderMarkup(p->pOut, &markup);