From 2e7922e6854e228702f0f93451f630f6cf1a3eab Mon Sep 17 00:00:00 2001
From: Martin Persson <xarragon@gmail.com>
Date: Sat, 12 Dec 2015 21:18:27 +0100
Subject: [PATCH] Bug 15326: Add CMS feature

INCOMPLETE - For evaluation purposes only!

Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
Signed-off-by: Michal Denar <black23@gmail.com>
Rebased-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 Koha/CmsPage.pm                               |   53 +
 Koha/CmsPages.pm                              |  200 ++
 .../atomicupdate/bug15326-add_cms_pages.sql   |   17 +
 installer/data/mysql/kohastructure.sql        |   23 +
 installer/data/mysql/userpermissions.sql      |    1 +
 .../prog/en/includes/permissions.inc          |    5 +
 .../prog/en/modules/tools/cmspages.tt         |  238 ++
 .../prog/en/modules/tools/tools-home.tt       |    5 +
 .../bootstrap/en/includes/masthead.inc        |   14 +
 .../bootstrap/en/includes/navigation.inc      |   10 +-
 .../bootstrap/en/modules/opac-cmspages.tt     |   89 +
 koha-tmpl/opac-tmpl/bootstrap/less/opac.less  | 2684 +++++++++++++++++
 opac/opac-cmspages.pl                         |   52 +
 opac/opac-main.pl                             |    6 +-
 t/Pages.t                                     |   31 +
 t/db_dependent/Pages.t                        |   93 +
 tools/cmspages.pl                             |   90 +
 17 files changed, 3609 insertions(+), 2 deletions(-)
 create mode 100644 Koha/CmsPage.pm
 create mode 100644 Koha/CmsPages.pm
 create mode 100644 installer/data/mysql/atomicupdate/bug15326-add_cms_pages.sql
 create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/cmspages.tt
 create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-cmspages.tt
 create mode 100644 koha-tmpl/opac-tmpl/bootstrap/less/opac.less
 create mode 100755 opac/opac-cmspages.pl
 create mode 100644 t/Pages.t
 create mode 100644 t/db_dependent/Pages.t
 create mode 100755 tools/cmspages.pl

diff --git a/Koha/CmsPage.pm b/Koha/CmsPage.pm
new file mode 100644
index 0000000000..fd5b52ab31
--- /dev/null
+++ b/Koha/CmsPage.pm
@@ -0,0 +1,53 @@
+package Koha::CmsPage;
+
+# Copyright Halland County Library 2015
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Carp;
+
+use Koha::Database;
+
+use base qw( Koha::Object );
+
+=head1 NAME
+
+Koha::CmsPage - Koha Page Object class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub type {
+    return 'CmsPage';
+}
+
+=head1 AUTHOR
+
+Martin Persson <xarragon@gmail.com>
+Halland County Library
+
+=cut
+
+1;
diff --git a/Koha/CmsPages.pm b/Koha/CmsPages.pm
new file mode 100644
index 0000000000..b49881e09b
--- /dev/null
+++ b/Koha/CmsPages.pm
@@ -0,0 +1,200 @@
+package Koha::CmsPages;
+
+# Copyright Halland County Library 2015
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Carp qw( carp );
+
+use Koha::Database;
+use Koha::CmsPage;
+
+use base qw( Koha::Objects );
+
+=head1 NAME
+
+Koha::CmsPage - Koha CMS Page Object Class
+
+=head1 API
+
+=head2 Class Methods
+
+=cut
+
+=head3 type
+
+=cut
+
+sub type {
+    return 'CmsPage';
+}
+
+sub object_class {
+    return 'Koha::CmsPage';
+}
+
+=head3 add
+Adds a new page to the CMS database based on the input data.
+=cut
+
+sub add {
+    my ( $self, $input ) = @_;
+warn "input: ", scalar $input->param('location');
+    carp( 'Koha::CmsPages::add() undefined parameter: input' ) unless defined $input;
+    my $data = {
+        parent     =>   scalar          $input->param( 'parent' )     eq '' ? undef : scalar $input->param( 'parent' ),
+        location   =>   scalar          $input->param( 'location' )   eq '' ? undef : scalar $input->param( 'location'),
+        branchcode =>   scalar          $input->param( 'branchcode' ) eq '' ? undef : scalar $input->param( 'branchcode' ),
+        lang       =>   scalar          $input->param( 'lang' ),
+        sortorder  =>   scalar          $input->param( 'sortorder' ),
+        title      =>   scalar          $input->param( 'title' ),
+        title_link =>   scalar          $input->param( 'title_link' ),
+        publish    =>   defined (scalar $input->param( 'publish' )),
+        content    =>   scalar          $input->param( 'content' )
+    };
+
+    if (defined $input->param( 'id' )) {
+        $data->{'id'} = scalar $input->param( 'id' );
+    }
+
+    my $new_page = $self->_resultset()->update_or_create( $data, { key => 'primary' });
+
+    return $new_page;
+}
+
+=head3 list
+
+Lists pages based input filtering paramters for location, branch and language.
+
+=cut
+
+sub list {
+    my ( $self, $id, $disp, $branch, $lang ) = @_;
+
+    my $filter = { };
+    $filter->{'location'} = $disp   unless not defined $disp;
+    $filter->{'branch'}   = $branch unless not defined $branch;
+    $filter->{'lang'}     = $lang   unless not defined $lang;
+
+    my $pages = $self->_resultset()->search( undef, {
+        order_by => {
+		    -asc => [qw/parent location branchcode lang sortorder/]
+        }, where => $filter
+    } );
+
+    my $page_list = [];
+    my $parent_list = [];
+    my %index;
+    my $data;
+    while ( my $page = $pages->next ) {
+        my $new_page = {
+            id         => scalar $page->id,
+            parent     => scalar $page->parent,
+            branchcode => scalar $page->branchcode,
+            lang       => scalar $page->lang,
+            title_link => scalar $page->title_link,
+            title      => scalar $page->title,
+            sortorder  => scalar $page->sortorder,
+            location   => scalar $page->location,
+            publish    => scalar $page->publish,
+            content    => scalar $page->content,
+        };
+        push(@{ $page_list }, $new_page );
+
+        # If requested id, store in 'data' output (used for editing a page):
+        if ( defined $id && $id eq $new_page->{'id'} ) {
+            $data = $new_page;
+        } else {
+            push(@{ $parent_list }, $new_page );
+        }
+        $index{ $page->id } = $new_page;
+    }
+
+    # Replace parent id with a hash with id and title_link in it.
+    foreach my $page (@{ $page_list }) {
+        my $old_id = $page->{'parent'};
+        my $parent = { id => $old_id };
+        $parent->{'title_link'} = $index{ $old_id }->{'title_link'} unless not defined $old_id;
+        $page->{'parent'} = $parent;
+    }
+
+    return ( $page_list, $parent_list, $data );
+}
+
+=head3 page
+
+Retrieves all data to show a single CMS page.
+
+=cut
+
+sub page {
+	my ( $self, $id ) = @_;
+
+	carp( 'Missing CMS page id parameter in Koha::Pages::page' ) unless defined $id;
+
+	# Probably want to merge these to a single query:
+	my $top_links = $self->_resultset()->search(
+			{ parent => undef }, { qw/id title_link/ });
+
+	my $page_links = $self->_resultset()->search(
+			{ parent => $id }, { qw/id title_link/ });
+
+	my $page_data = $self->_resultset()->find( $id );
+
+	return ( $top_links, $page_links, $page_data );
+}
+
+=head3 child_links
+
+Lists pages which are children of a specific id (or undef for root).
+
+=cut
+
+sub child_links {
+    my ( $self, $id ) = @_;
+
+	# 'id' can be undefined if listing top-level links.
+    my $rs = $self->_resultset()->search({ parent => $id },
+            { columns => [qw/id title_link/] } );
+
+    return $rs;
+}
+
+=head3 remove
+
+Removes a page identified by id from the CMS database.
+
+=cut
+
+sub remove {
+    my ( $self, @ids ) = @_;
+
+    carp( 'Koha::CmsPages::remove() undefined parameter ids' ) unless @ids;
+
+    my $pages = $self->_resultset()->search({ id => \@ids });
+    $pages->delete;
+}
+
+=head1 AUTHOR
+
+Martin Persson <xarragon@gmail.com>
+Halland County Library
+
+=cut
+
+1;
diff --git a/installer/data/mysql/atomicupdate/bug15326-add_cms_pages.sql b/installer/data/mysql/atomicupdate/bug15326-add_cms_pages.sql
new file mode 100644
index 0000000000..74c45f7eac
--- /dev/null
+++ b/installer/data/mysql/atomicupdate/bug15326-add_cms_pages.sql
@@ -0,0 +1,17 @@
+ CREATE TABLE `cms_pages` (
+  `id` int(6) NOT NULL AUTO_INCREMENT,
+  `parent` int(6) DEFAULT NULL,
+  `branchcode` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
+  `lang` varchar(25) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+  `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
+  `title_link` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+  `sortorder` int(3) NOT NULL DEFAULT 0,
+  `location` tinyint(1) DEFAULT NULL,
+  `publish` tinyint(1) NOT NULL DEFAULT 0,
+  `content` text COLLATE utf8_unicode_ci,
+  PRIMARY KEY (`id`),
+  INDEX `parent_index` (`parent`),
+  INDEX `lang_index` (`lang`),
+  INDEX `branchcode_index` (`branchcode`),
+  CONSTRAINT `cmspages_branchcode_ibfk` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 6d7a4d28e1..5eecd2675b 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -4320,6 +4320,29 @@ CREATE TABLE IF NOT EXISTS stockrotationitems (
       ON UPDATE CASCADE ON DELETE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
+--
+-- Table structure for table 'cms_pages', used for CMS functionality.
+--
+
+DROP TABLE IF EXISTS `cms_pages`;
+ CREATE TABLE `cms_pages` (
+  `id` int(6) NOT NULL AUTO_INCREMENT,
+  `parent` int(6) DEFAULT NULL,
+  `branchcode` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
+  `lang` varchar(25) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
+  `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
+  `title_link` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+  `sortorder` int(3) NOT NULL DEFAULT 0,
+  `location` tinyint(1) DEFAULT NULL,
+  `publish` tinyint(1) NOT NULL DEFAULT 0,
+  `content` text COLLATE utf8_unicode_ci,
+  PRIMARY KEY (`id`),
+  INDEX `parent_index` (`parent`),
+  INDEX `lang_index` (`lang`),
+  INDEX `branchcode_index` (`branchcode`),
+  CONSTRAINT `pages_branchcode_ibfk` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
 /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
diff --git a/installer/data/mysql/userpermissions.sql b/installer/data/mysql/userpermissions.sql
index 6876fad8ac..6d52fc656f 100644
--- a/installer/data/mysql/userpermissions.sql
+++ b/installer/data/mysql/userpermissions.sql
@@ -89,6 +89,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES
    (13, 'access_files', 'Access to the files stored on the server'),
    (13, 'upload_general_files', 'Upload any file'),
    (13, 'upload_manage', 'Manage uploaded files'),
+   (13, 'edit_pages', 'Create, edit and delete CMS pages for OPAC and staff interfaces'),
    (15, 'check_expiration', 'Check the expiration of a serial'),
    (15, 'claim_serials', 'Claim missing serials'),
    (15, 'create_subscription', 'Create a new subscription'),
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
index 1763079fe9..8280f3b398 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
@@ -385,6 +385,11 @@
         <span class="sub_permission edit_news_subpermission">
             Write news for the OPAC and staff interfaces
         </span>
+        <span class="permissioncode">([% name | html %])</span>            
+    [%- CASE 'edit_pages' -%]
+        <span class="sub_permission edit_pages_subpermission">
+            Create, edit and delete CMS pages for OPAC and staff interfaces
+        </span>
         <span class="permissioncode">([% name | html %])</span>
     [%- CASE 'edit_notice_status_triggers' -%]
         <span class="sub_permission edit_notice_status_triggers_subpermission">
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cmspages.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cmspages.tt
new file mode 100644
index 0000000000..99f539d6e7
--- /dev/null
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/cmspages.tt
@@ -0,0 +1,238 @@
+[% USE KohaDates %]
+[% USE Koha %]
+[% SET link_opac_base = Koha.Preference( 'OPACBaseURL' ) %]
+[% SET link_opac = link_opac_base _ '/cgi-bin/koha/opac-cmspages.pl' %]
+[% INCLUDE 'doc-head-open.inc' %]
+<title>Koha &rsaquo; Tools &rsaquo; Pages</title>
+[% INCLUDE 'doc-head-close.inc' %]
+[% IF ( opac_page_count ) %]
+    <link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
+    [% INCLUDE 'datatables.inc' %]
+    <script type="text/javascript">//<![CDATA[
+    $(document).ready(function() {
+        $("#newst").dataTable($.extend(true, {}, dataTablesDefaults, {
+            "aoColumnDefs": [
+                { "aTargets": [ 0,-1,-2 ], "bSortable": false },
+                { "aTargets": [ 0, -1 ], "bSearchable": false },
+                { 'sType': "title-string", 'aTargets' : [ 'title-string'] }
+            ],
+            "sPaginationType": "full_numbers"
+        }));
+    });
+    //]]>
+    </script>
+[% END %]
+<script type="text/javascript" src="[% interface %]/lib/tiny_mce/tiny_mce.js"></script>
+<script type="text/javascript">//<![CDATA[
+var MSG_CONFIRM_DELETE_PAGE  = _("Are you sure you want to delete the selected page?");
+
+tinyMCE.init({
+    mode : "textareas",
+    theme : "advanced",
+    convert_urls : false,
+    relative_urls : false,
+    content_css : "[% themelang %]/css/tinymce.css",
+    plugins : "table,save,advhr,advlink,searchreplace,print,contextmenu",
+    theme_advanced_buttons1 : "save,|,bold,italic,|,cut,copy,paste,|,search,replace,|,justifyleft,justifycenter,justifyright,justifyfull,|,formatselect,|,link,unlink,anchor,cleanup,help,code,advhr,|,print",
+    theme_advanced_buttons2 : "tablecontrols,|,bullist,numlist,|,outdent,indent,|,undo,redo,|,removeformat,|,visualaid,|,sub,sup,|,charmap",
+    theme_advanced_buttons3 : "",
+    theme_advanced_toolbar_location : "top",
+    theme_advanced_toolbar_align : "left",
+    theme_advanced_path_location : "bottom",
+    theme_advanced_resizing : true,
+    plugin_insertdate_dateFormat : "%Y-%m-%d",
+    plugin_insertdate_timeFormat : "%H:%M:%S",
+    apply_source_formatting : true,
+    height : "300",
+    width : "700"
+//]]>
+});
+//]]>
+</script>
+</head>
+<body id="tools_koha-content" class="tools">
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'cat-search.inc' %]
+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; [% IF ( form ) %]<a href="[% link_self %]">Pages</a> &rsaquo; [% IF ( id ) %]
+Edit page[% ELSE %]Add page[% END %][% ELSE %]Pages[% END %]</div>
+
+[% IF ( form ) %]<div id="doc" class="yui-t7">[% ELSE %]<div id="doc3" class="yui-t2">[% END %]
+   <div id="bd">
+    <div id="yui-main">
+    <div class="yui-b">
+
+[% UNLESS ( link_opac_base && link_self) %]
+    <div class="dialog alert">
+    [% UNLESS ( link_opac_base ) %]
+    Warning: Preference <em>OPACBaseURL</em> not set, some links might not work!</div>
+    [% END %]
+    [% UNLESS ( link_self ) %]
+    Warning: Variable <em>link_self</em> not set, some links might not work!</div>
+    [% END %]
+[% END %]
+[% UNLESS ( form ) %]
+    [% IF error_message == 'title_missing' %]
+        <div class="dialog alert">Error: Required page title missing!</div>
+    [% END %]
+<div id="toolbar" class="btn-toolbar">
+    <a class="btn btn-small" id="newentry" href="[% link_self %]?op=form"><i class="icon-plus"></i> New page</a>
+</div>
+[% END %]
+<pre>DEBUG: [% debug %]</pre>
+<pre>DEBUG2: data.location: [% data.location %] data.branchcode: [% data.branchcode %]</pre>
+[% IF ( form ) %]
+        <form name="form" method="post" enctype="multipart/form-data" action="[% link_self %]" >
+            <input type="hidden" name="op" value="[% op %]" />
+            <input type="hidden" name="id" value="[% id %]" />
+            <fieldset class="rows">
+            <legend>Page</legend>
+            <ol>
+            <li>
+                <label for="disp">Display location</label>
+                <select id="disp" name="disp">
+                    <option value=""  [% IF ( data.disp == ""  ) %]selected="selected"[% END %]>All</option>
+                    <option value="1" [% IF ( data.disp == "1" ) %]selected="selected"[% END %]>Intranet</option>
+                    <option value="2" [% IF ( data.disp == "2" ) %]selected="selected"[% END %]>OPAC</option>
+                </select>
+            </li>
+            <li>
+                <label for="branch">Library: </label>
+                <select id="branch" name="branch">
+                    <option value=""[% IF ( data.branchcode == '' ) %] selected="selected"[% END %]>All libraries</option>
+                [% FOREACH branch_lis IN branch_list %]
+                    <option value="[% branch_lis.branchcode %]"[% IF ( branch_lis.branchcode == data.branchcode ) %] selected="selected"[% END %]>[% branch_lis.branchname %]</option>
+                [% END %]
+                </select>
+            </li>
+            <li>
+                <label for="lang">Language</label>
+<pre>LANG: [% lang %]</pre>
+                <select id="lang" name="lang">
+                    <option value="" [% IF ( data.lang == "" ) %]selected="selected"[% END %]>All</option>
+                    [% FOREACH lang_lis IN lang_list %]
+                        <option value="[% lang_lis.rfc4646_subtag %]" [% IF ( lang_lis.rfc4646_subtag == data.lang ) %]selected="selected"[% END %]>[% lang_lis.native_description %] ([% lang_lis.rfc4646_subtag %])</option>
+                    [% END %]
+                </select>
+            </li>
+            <li>
+                <label for="parent">Parent page: </label>
+                <select id="parent" name="parent">
+                    <option value="" [% IF ( data.id == "" ) %]selected="selected"[% END %]>No parent</option>
+                [% FOREACH parent_lis IN parent_list %]
+                        <option value="[% parent_lis.id %]" [% IF ( data.parent.id == parent_lis.id ) %]selected="selected"[% END %]>[% parent_lis.title_link %]</option>
+                [% END %]
+                </select>
+            </li>
+            <li>
+                <label for="title_link" class="required">Link title: </label>
+                <input id="title_link" size="30" type="text" name="title_link" value="[% data.title_link %]" required="required" class="required" /> <span class="required">Required</span>
+            </li>
+            <li>
+                <label for="title">Page title: </label>
+                <input id="title" size="30" type="text" name="title" value="[% data.title %]" />
+            </li>
+            <li>
+                <label for="number">Appear in position: </label>
+                <input id="sortorder" size="3" name="sortorder" type="text" value="[% IF ( data.sortorder ) %][% data.sortorder %][% ELSE %]0[% END %]" />
+            </li>
+            <li>
+                <label for="publish">Publish: </label>
+                <input type="checkbox" id="publish" name="publish"[% IF ( data.publish ) %] checked="checked"[% END %]/>
+            </li>
+            <li><label for="new">Content: </label>
+            <textarea name="content" id="content" cols="75" rows="10">[% data.content %]</textarea>
+            </li>
+            </ol>
+            </fieldset>
+            <fieldset class="action"><input class="button" type="submit" value="Save" /> <a class="cancel" href="[% link_self %]">Cancel</a></fieldset>
+        </form>
+    [% ELSE %]
+        <div style="margin-bottom:5px;">
+        <form name="form" method="post" action="[% link_self %]" >
+            <label for="disp">Display location:</label>
+            <select name="disp" id="disp">
+                <option value=""  [% IF ( disp == ""  ) %]selected="selected"[% END %]>All</option>
+                <option value="0" [% IF ( disp == "0" ) %]selected="selected"[% END %]>OPAC</option>
+                <option value="1" [% IF ( disp == "1" ) %]selected="selected"[% END %]>Librarian interface</option>
+            </select>
+
+            <label for="branch">Library: </label>
+            <select id="branch" name="branch">
+                <option value=""[% IF ( branch == "" ) %] selected="selected"[% END %]>All libraries</option>
+                [% FOREACH branch_lis IN branch_list %]
+                <option value="[% branch_lis.branchcode %]"[% IF ( branch_lis.branchcode == branch ) %] selected="selected"[% END %]>[% branch_lis.branchname %]</option>
+                [% END %]
+            </select>
+
+            <label for="lang">Language:</label>
+            <select name="lang" id="lang">
+                <option value="" [% IF ( lang == "" ) %]selected="selected"[% END %]>All</option>
+                [% FOREACH lang_lis IN lang_list %]
+                <option value="[% lang_lis.rfc4646_subtag %]" [% IF ( lang_lis.rfc4646_subtag == lang ) %]selected="selected"[% END %]>[% lang_lis.native_description %] ([% lang_lis.rfc4646_subtag %])</option>
+                [% END %]
+            </select>
+            <input type="submit" class="button" value="Filter" />
+        </form>
+        </div>
+        [% IF ( page_list_count ) %]
+        <form name="del_form" method="post" action="[% link_self %]" onsubmit='return confirm(MSG_CONFIRM_DELETE_PAGE)'>
+                <table id="newst">
+                   <thead><tr>
+                        <th>&nbsp;</th>
+                        <th>Pub.</th>
+                        <th>Parent</th>
+                        <th>Loc.</th>
+                        <th>Lib.</th>
+                        <th>Lang.</th>
+                        <th>Num.</th>
+                        <th>Link title</th>
+                        <th>Page title</th>
+                        <th>&nbsp;</th>
+                        <th>&nbsp;</th>
+                    </tr></thead>
+                    <tbody>[% FOREACH page_lis IN page_list %]
+                        <tr>
+                            <td>
+                                <input type="checkbox" name="ids" id="ids" value="[% page_lis.id %]" />
+                            </td>
+                            <td>[% IF ( page_lis.publish ) %]Yes[% ELSE %]No[% END %]</td>
+                            <td>[% page_lis.parent.title_link %]</td>
+                            <td>[% SWITCH page_lis.display %]
+                                [% CASE "0" %]
+                                    OPAC
+                                [% CASE "1" %]
+                                    Staff interface
+                                [% CASE "" %]
+                                    All
+                                [% END %]
+                            </td>
+                            <td>[% IF ( page_lis.branch == "" ) %]
+                                All
+                                [% ELSE %][% page_lis.branchname %]
+                                [% END %]</td>
+                            <td>[% IF ( page_lis.langcode == "" ) %]All[% ELSE %]
+                                [% page_lis.langcode %][% END %]</td>
+                            <td>[% page_lis.sortorder %]</td>
+                            <td><a href="[% link_self %]?op=form&amp;id=[% page_lis.id %]">[% page_lis.title_link %]</a></td>
+                            <td>[% page_lis.title %]</td>
+                            <td><a href="[% link_self %]?op=form&amp;id=[% page_lis.id %]">Edit</a></td>
+                            <td><a href="[% link_opac %]?id=[% page_lis.id %]">View</a></td>
+                        </tr>
+                    [% END %]</tbody>
+                </table>
+                <input type="hidden" name="op" value="del" />
+                <fieldset class="action"><input type="submit" class="button" value="Delete selected" /></fieldset>
+            </form>
+        [% ELSE %]
+            <p>No pages exists</p>
+        [% END %]
+    [% END %]
+</div>
+</div>
+[% UNLESS ( form ) %]
+    <div class="yui-b noprint">
+        [% INCLUDE 'tools-menu.inc' %]
+    </div>
+[% END %]
+</div>
+[% INCLUDE 'intranet-bottom.inc' %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt
index df906c3567..f4e8341cc2 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt
@@ -104,6 +104,11 @@
     <dd>Write news for the OPAC and staff interfaces</dd>
     [% END %]
 
+    [% IF ( CAN_user_tools_edit_pages ) %]
+    <dt><a href="/cgi-bin/koha/tools/cmspages.pl">Pages</a></dt>
+    <dd>Create and edit additional content pages</dd>
+    [% END %]
+
     [% IF ( CAN_user_tools_schedule_tasks ) %]
     <dt><a href="/cgi-bin/koha/tools/scheduler.pl">Task scheduler</a></dt>
     <dd>Schedule tasks to run</dd>
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc
index 9466c2d9c6..cd82fd4a11 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc
@@ -286,6 +286,20 @@
                                     [% END %]
                                 </ul>
                             </div> <!-- /#moresearches -->
+                            <div id="cms_nav_top">
+								[% IF ( cms_nav_top ) %]
+								<ul>
+									[% WHILE ( cms_item = cms_nav_top.next ) %]
+										[% IF ( cms_item.id == cms_page.id ) %]
+											<li class="cms_nav_top_active">
+										[% ELSE %]
+                                            <li>
+										[% END %]
+                                        <a href="/cgi-bin/koha/opac-cmspages.pl?id=[% cms_item.id %]">[% cms_item.title_link %]</a></li>
+									[% END %]
+								</ul>
+								[% END %]
+                            </div>
                     </div> <!-- /.row-fluid -->
 
                 [% END # / OpacPublic %]
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/navigation.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/navigation.inc
index d578857f17..2f58c25e72 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/navigation.inc
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/navigation.inc
@@ -1,5 +1,13 @@
 [% USE raw %]
-<div id="opacnav">[% OpacNav | $raw %]</div>
+<div id="opacnav">
+[% IF ( cms_nav_left ) %]
+<ul id="cms_nav_left">
+[% WHILE ( item = cms_nav_left.next ) %]
+    <li><a href="/cgi-bin/koha/opac-cmspages.pl?id=[% item.id %]">[% item.title_link | html %]</a></li>
+[% END %]
+</ul>
+[% END %]
+[% OpacNav | $raw %]</div>
 [% IF IsPatronPage %]
     <div id="usermenu">[% INCLUDE usermenu.inc %]</div>
 [% END %]
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-cmspages.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-cmspages.tt
new file mode 100644
index 0000000000..9bc3e35a40
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-cmspages.tt
@@ -0,0 +1,89 @@
+[% USE Koha %]
+[% USE Branches %]
+[% INCLUDE 'doc-head-open.inc' %]
+<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %][% IF (cms_page.title) %] - [% cms_page.title %][% ELSE %] catalog[% END%]</title>
+[% INCLUDE 'doc-head-close.inc' %]
+[% BLOCK cssinclude %][% END %]
+</head>
+[% INCLUDE 'bodytag.inc' bodyid='opac-cmspages' %]
+[% INCLUDE 'masthead.inc' %]
+
+<div class="main">
+    <ul class="breadcrumb">
+        <li><a href="/cgi-bin/koha/opac-main.pl">Home</a></li>
+        <li><span class="divider">&rsaquo;</span></li>
+        <li><a href="#">[% cms_page.title_link %]</a></li>
+    </ul>
+
+    [% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
+        [% IF ( loggedinusername ) %]
+            <div id="loggedin" class="container-fluid">
+        [% ELSE %]
+            <div id="notloggedin" class="container-fluid">
+        [% END %]
+    [% ELSE %]
+        <div id="notloggedin" class="container-fluid">
+    [% END %]
+
+    <div class="row-fluid">
+    [% IF ( OpacNav ||  OpacNavBottom ) %]
+        <div class="span2">
+            <div id="navigation">
+                [% INCLUDE 'navigation.inc' %]
+            </div>
+        </div>
+    [% END %]
+
+    [% IF ( OpacNav || OpacNavBottom ) %]
+        <div class="span7">
+    [% ELSE %]
+        <div class="span9">
+    [% END %]
+        [% cms_page.content %]
+        [% IF ( OpacMainUserBlock ) %]<div id="opacmainuserblock">[% OpacMainUserBlock %]</div>[% END %]
+        </div> <!-- / .span 7/9 -->
+
+        [% IF ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) || OpacNavRight ) %]
+            <div class="span3">
+                [% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
+                    [% UNLESS ( loggedinusername ) %]
+                        [% UNLESS ( casAuthentication || shibbolethAuthentication ) %]
+                            <div id="login">
+                                <form action="/cgi-bin/koha/opac-user.pl" method="post" name="auth" id="auth">
+                                    <input type="hidden" name="koha_login_context" value="opac" />
+                                    <fieldset class="brief">
+                                        <legend>Log in to your account:</legend>
+                                        <label for="userid">Login:</label><input type="text" id="userid" name="userid" />
+                                        <label for="password">Password:</label><input type="password" id="password" name="password" />
+                                    <fieldset class="action">
+                                        <input type="submit" value="Log in" class="btn" />
+                                    </fieldset>
+                                    [% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]<div id="patronregistration"><p>Don't have an account? <a href="/cgi-bin/koha/opac-memberentry.pl">Register here.</a></p></div>[% END %]
+                                    </fieldset>
+                                [% IF Koha.Preference( 'NoLoginInstructions' ) %]
+                                    <div id="nologininstructions-main">
+                                        [% Koha.Preference( 'NoLoginInstructions' ) %]
+                                    </div>
+                                [% END %]
+                                </form>
+                            </div> <!-- /#login -->
+                        [% END # /casAuthentication %]
+                        [% IF persona %]
+                            <a href="#" class="persona-button" id="browserid" ><span>Sign in with your email</span></a>
+                        [% END # /persona %]
+                    [% END # / loggedinusername %]
+                [% END # /opacuserlogin %]
+                [% IF ( OpacNavRight ) %]
+                    <div id="opacnavright">
+                        [% OpacNavRight %]
+                    </div>
+                [% END # /OpacNavRight %]
+            </div> <!-- / .span3 -->
+        [% END # /opacuserlogin || OpacNavRight %]
+
+        </div> <!-- /.container-fluid -->
+    </div> <!-- /.row-fluid -->
+</div> <!-- /.main -->
+
+[% INCLUDE 'opac-bottom.inc' %]
+[% BLOCK jsinclude %][% END %]
diff --git a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less b/koha-tmpl/opac-tmpl/bootstrap/less/opac.less
new file mode 100644
index 0000000000..2d0982e8e0
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/bootstrap/less/opac.less
@@ -0,0 +1,2684 @@
+@import "mixins.less";
+body {
+    background-color: #EAEAE6;
+}
+
+ /* Sticky footer styles */
+html,
+body {
+    height: 100%;
+    /* The html and body elements cannot have any padding or margin. */
+}
+
+.no-js {
+    .dateformat {
+        display: inline;
+        white-space: nowrap;
+    }
+    .modal-body {
+        padding: 0;
+    }
+    .selections-toolbar {
+        display: none;
+    }
+}
+
+.js {
+    .dateformat {
+        display: none;
+    }
+}
+
+/* Wrapper for page content to push down footer */
+#wrap {
+    min-height: 100%;
+    height: auto !important;
+    height: 100%;
+    /* Negative indent footer by it's height */
+    // margin: 0 auto -60px;
+}
+
+/* Set the fixed height of the footer here */
+#changelanguage {
+    // height: 60px;
+}
+
+.popup {
+    padding-left : 0;
+    padding-right: 0;
+}
+
+a {
+    color: @links;
+    &.cancel {
+        padding-left : 1em;
+    }
+    &:visited {
+        color: @links;
+    }
+    &.title {
+        font-weight: bold;
+        font-size : 108%;
+    }
+    &.btn {
+        &:visited {
+            color : #333;
+        }
+    }
+    &.btn-primary {
+        &:visited {
+            color : #FFF;
+        }
+    }
+    &.login-link {
+        color: #A6D8ED;
+        font-weight: bold;
+    }
+}
+
+.ui-widget-content a,
+.ui-widget-content a:visited {
+    color: @links;
+}
+
+h1 {
+    font-size : 140%;
+    line-height: 150%;
+    &#libraryname {
+        background: transparent url(../images/logo-koha.png) no-repeat scroll 0%;
+        border: 0;
+        float: left !important;
+        margin: 0;
+        padding: 0;
+        width: 120px;
+        a {
+            border: 0;
+            cursor: pointer;
+            display: block;
+            height: 0px !important;
+            margin: 0;
+            overflow: hidden;
+            padding: 40px 0 0;
+            text-decoration: none;
+            width: 120px;
+        }
+    }
+}
+
+h2 {
+
+    font-size : 130%;
+    line-height: 150%;
+}
+h3 {
+
+    font-size : 120%;
+    line-height: 150%;
+}
+h4 {
+
+    font-size : 110%;
+}
+h5 {
+
+    font-size : 100%;
+}
+
+caption {
+    font-size: 120%;
+    font-weight: bold;
+    margin : 0;
+    text-align: left;
+}
+
+input,
+textarea {
+    width: auto;
+}
+
+.input-fluid {
+    width : 50%;
+}
+
+legend {
+    font-size: 110%;
+    font-weight: bold;
+}
+
+table, td {
+    background-color: #FFF;
+}
+
+td {
+    .btn {
+        white-space: nowrap;
+    }
+    .btn-link {
+        padding: 0;
+    }
+}
+
+#advsearches,
+#booleansearch {
+    label {
+        display: inline;
+    }
+}
+
+#basketcount {
+    display : inline;
+    margin : 0;
+    padding : 0;
+    span {
+        background-color : #FFC;
+        color : #000;
+        display : inline;
+        font-size : 80%;
+        font-weight : normal;
+        margin : 0 0 0 .9em;
+        padding : 0 .3em 0 .3em;
+        .border-radius-all(3px);
+    }
+}
+
+
+#members {
+    display: block;
+    p {
+        color : #EEE;
+    }
+    a {
+        &.logout {
+            color : #E8583C;
+            font-weight: bold;
+            padding : 0 .3em 0 .3em;
+        }
+    }
+}
+
+#koha_url p {
+        color: #666666;
+        float : right;
+        margin: 0;
+}
+
+#moresearches {
+    margin: .5em 0 .5em 0;
+    padding: 0 .8em;
+    li {
+        display: inline;
+        white-space: nowrap;
+        &:after {
+            content : " | ";
+        }
+
+    }
+    ul {
+        margin : 0;
+        display: inline;
+    }
+    display: inline;
+}
+
+#moresearches li:last-child:after {
+    content : "";
+}
+
+#cms_nav_top {
+	li {
+		margin-bottom: -1em;
+		display: inline;
+		white-space: nowrap;
+		border-top-left-radius: 5px;
+		border-top-right-radius: 5px;
+		background-color: #eee;
+		border: 1px solid #D2D2CF;
+		border-bottom: none;
+		padding: 0.1em 0.8em 0em 0.8em;
+		font-weight: bold;
+		font-size: 1.2em;
+		border-bottom: 1px solid #D2D2CF;
+		a {
+			text-decoration: none;
+		}
+		&.cms_nav_top_active {
+			background-color: #fff;
+			border-bottom: 1px solid #FFF;
+		}
+	}
+	ul {
+		margin: 0;
+		display: inline;
+	}
+	display: inline;
+}
+
+ul#cms_nav_left {
+	list-style-type: none;
+	padding: 0;
+}
+
+#news {
+    margin : .5em 0;
+}
+
+.newscontainer {
+    border: 1px solid #ddd;
+    border-bottom-width: 0;
+    border-top-left-radius: 5px;
+    border-top-right-radius: 5px;
+}
+
+.newsheader {
+    background-color: #ecede6;
+    border-bottom: 1px solid #ddd;
+    margin: 0;
+    padding: 8px;
+}
+
+.newsbody {
+    padding: 8px;
+}
+
+.newsfooter {
+    border-bottom: 1px solid #ddd;
+    font-style: italic;
+    padding: 4px 8px;
+}
+
+#opacheader {
+    background-color: #DDD;
+}
+
+#selections,
+.selections {
+    font-weight : bold;
+}
+
+.actions {
+    a {
+        white-space: nowrap;
+        &.hold {
+            background-image : url("../images/sprite.png"); /* Place hold small */
+            background-position : -5px -542px;
+            background-repeat: no-repeat;
+            margin-right : 1em;
+            padding-left : 21px;
+            text-decoration : none;
+        }
+        &.article_request {
+            background-image : url("../images/sprite.png"); /* Place hold small */
+            background-position : -2px -26px;
+            background-repeat: no-repeat;
+            margin-right : 1em;
+            padding-left : 21px;
+            text-decoration : none;
+        }
+        &.addtocart {
+            background-image : url("../images/sprite.png"); /* Cart small */
+            background-position : -5px -572px;
+            background-repeat: no-repeat;
+            margin-right : 1em;
+            padding-left : 20px;
+            text-decoration : none;
+        }
+        &.addtoshelf {
+            background-image : url("../images/sprite.png"); /* MARC view */
+            background-position: -5px -27px;
+            background-repeat: no-repeat;
+            margin-right : 1em;
+            padding-left : 20px;
+            text-decoration : none;
+        }
+        &.addtolist {
+            background-position: -5px -27px;
+            margin-right : 1em;
+            padding-left : 20px;
+            text-decoration : none;
+        }
+        &.tag_add {
+            background-position: -5px -1110px;
+            margin-right : 1em;
+            padding-left : 20px;
+            text-decoration : none;
+        }
+        /* List contents remove from list link */
+        &.removefromlist  {
+            background-position : -8px -690px; /* Delete */
+            margin-right : 1em;
+            text-decoration : none;
+            padding-left : 15px;
+        }
+    }
+}
+
+/* Override Bootstrap alert */
+.alert {
+    background: #fffbe5; /* Old browsers */
+    background: -moz-linear-gradient(top,  #fffbe5 0%, #fff0b2 9%, #fff1a8 89%, #f7e665 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fffbe5), color-stop(9%,#fff0b2), color-stop(89%,#fff1a8), color-stop(100%,#f7e665)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top,  #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top,  #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top,  #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* IE10+ */
+    background: linear-gradient(to bottom,  #fffbe5 0%,#fff0b2 9%,#fff1a8 89%,#f7e665 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffbe5', endColorstr='#f7e665',GradientType=0 ); /* IE6-9 */
+    border-color : #D6C43B;
+    color: #333;
+}
+
+/* Override Bootstrap alert.alert-info */
+.alert-info {
+    background: #f4f6fa; /* Old browsers */
+    background: -moz-linear-gradient(top,  #f4f6fa 0%, #eaeef5 4%, #e8edf6 96%, #cddbf2 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f4f6fa), color-stop(4%,#eaeef5), color-stop(96%,#e8edf6), color-stop(100%,#cddbf2)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top,  #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top,  #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top,  #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* IE10+ */
+    background: linear-gradient(to bottom,  #f4f6fa 0%,#eaeef5 4%,#e8edf6 96%,#cddbf2 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f6fa', endColorstr='#cddbf2',GradientType=0 ); /* IE6-9 */
+    border-color : #C5D1E5;
+    color: #333;
+}
+
+/* Override Bootstrap alert.alert-success */
+.alert-success {
+    background: #f8ffe8; /* Old browsers */
+    background: -moz-linear-gradient(top,  #f8ffe8 0%, #e3f5ab 4%, #dcf48d 98%, #9ebf28 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8ffe8), color-stop(4%,#e3f5ab), color-stop(98%,#dcf48d), color-stop(100%,#9ebf28)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top,  #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top,  #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top,  #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* IE10+ */
+    background: linear-gradient(to bottom,  #f8ffe8 0%,#e3f5ab 4%,#dcf48d 98%,#9ebf28 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f8ffe8', endColorstr='#9ebf28',GradientType=0 ); /* IE6-9 */
+    border-color : #9FBA35;
+    color: #333;
+}
+
+.breadcrumb {
+    background-color: #F2F2EF;
+    font-size: 85%;
+    list-style: none outside none;
+    margin: 10px 20px;
+    padding: 5px 10px;
+    .border-radius-all(7px);
+}
+
+.form-inline {
+    display : inline;
+    padding: 0;
+    margin: 0;
+    fieldset {
+        margin: 0.3em 0;
+        padding: 0.3em;
+    }
+}
+
+.main {
+    background-color: #FFF;
+    border: 1px solid #D2D2CF;
+    .border-radius-all(7px);
+    .shadowed;
+    margin-top : 1px;
+    margin-bottom: 0.5em;
+}
+
+.mastheadsearch {
+    .border-radius-all(7px);
+    padding: .8em;
+    margin: .5em 0;
+    background: #c7c7c1;
+    /* Old browsers */
+    background: -moz-linear-gradient(top, #c7c7c1 38%, #a7a7a2 100%);
+    /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(38%,#c7c7c1), color-stop(100%,#a7a7a2));
+    /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top, #c7c7c1 38%,#a7a7a2 100%);
+    /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top, #c7c7c1 38%,#a7a7a2 100%);
+    /* Opera 11.10+ */
+    background: -ms-linear-gradient(top, #c7c7c1 38%,#a7a7a2 100%);
+    /* IE10+ */
+    background: linear-gradient(to bottom, #c7c7c1 38%,#a7a7a2 100%);
+    /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c7c7c1', endColorstr='#a7a7a2',GradientType=0 );
+    /* IE6-9 */
+    label {
+        font-size: 115%;
+        font-weight: bold;
+    }
+}
+
+.navbar-inverse .brand, .navbar-inverse .nav > li > a {
+    color: #9FE1FF;
+    font-weight: bold;
+}
+
+.navbar-fixed-bottom.navbar-static-bottom {
+    margin-top : .5em;
+    position: static;
+}
+
+#changelanguage .nav > .active > p {
+    padding : 0 15px;
+}
+
+.table-striped tbody > tr:nth-child(odd) > td,
+.table-striped tbody > tr:nth-child(odd) > th {
+  background-color: #F4F4F4;
+}
+
+
+/* jQuery UI standard tabs */
+.ui-tabs-nav .ui-tabs-active a,
+.ui-tabs-nav a:hover,
+.ui-tabs-nav a:focus,
+.ui-tabs-nav a:active,
+.ui-tabs-nav span.a {
+    background: none repeat scroll 0 0 transparent;
+    outline: 0 none;
+}
+
+.ui-widget,
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+    font-family : inherit;
+    font-size : inherit;
+}
+
+ul.ui-tabs-nav li {
+    list-style : none;
+}
+.ui-tabs.ui-widget-content {
+    background : transparent none;
+    border : 0;
+}
+
+.ui-tabs .ui-tabs-panel {
+    border : 1px solid #D8D8D8;
+    margin-bottom: 1em;
+}
+.ui-tabs-nav.ui-widget-header {
+    border : 0;
+    background : none;
+}
+.ui-tabs .ui-tabs-nav li {
+    background: #F3F3F3 none;
+    border-color: #D8D8D8;
+    margin-right : .4em;
+}
+
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+    background-color : #FFF;
+    border : 1px solid #D8D8D8;
+    border-bottom: 0;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a {
+    color : #000;
+    font-weight : bold;
+}
+
+.ui-tabs .ui-tabs-nav li.ui-state-default.ui-state-hover {
+    background : #F3F3F3 none;
+}
+
+.ui-tabs .ui-tabs-nav li.ui-tabs-active.ui-state-hover {
+    background : #FFF none;
+}
+
+.ui-tabs .ui-state-default a,
+.ui-tabs .ui-state-default a:link,
+.ui-tabs .ui-state-default a:visited {
+    color: #006699;
+}
+
+.ui-tabs .ui-state-hover a,
+.ui-tabs .ui-state-hover a:link,
+.ui-tabs .ui-state-hover a:visited {
+    color: #990033;
+}
+
+.statictabs {
+    ul {
+        background: none repeat scroll 0 0 transparent;
+        border: 0 none;
+        margin: 0;
+        padding: 0.2em 0.2em 0;
+        border-bottom-right-radius: 4px;
+        border-bottom-left-radius: 4px;
+        border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        color: #222222;
+        font-weight: bold;
+        font-size: 100%;
+        line-height: 1.3;
+        list-style: none outside none;
+        outline: 0 none;
+        text-decoration: none;
+        &:before {
+            content: "";
+            display: table;
+        }
+        &:after {
+            clear: both;
+            content: "";
+            display: table;
+        }
+    }
+    li {
+        background: none repeat scroll 0 0 #E6F0F2;
+        border: 1px solid #B9D8D9;
+        border-bottom: 0 none !important;
+        border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        float: left;
+        list-style: none outside none;
+        margin-bottom: 0;
+        margin-right: 0.4em;
+        padding: 0;
+        position: relative;
+        white-space: nowrap;
+        top: 1px;
+        color: #555555;
+        font-weight: normal;
+        &.active {
+            background-color: #FFFFFF;
+            color: #212121;
+            font-weight: normal;
+            padding-bottom: 1px;
+        }
+        a {
+            color: #004D99;
+            cursor: pointer;
+            float: left;
+            padding: 0.5em 1em;
+            text-decoration: none;
+            &:hover {
+                background-color : #EDF4F5;
+                border-top-right-radius: 4px;
+                border-top-left-radius: 4px;
+                color : #538200;
+            }
+        }
+        &.active {
+            a {
+                color: #000000;
+                font-weight: bold;
+                cursor: text;
+                background: none repeat scroll 0 0 transparent;
+                outline: 0 none;
+            }
+        }
+    }
+    .tabs-container {
+        border: 1px solid #B9D8D9;
+        background: none repeat scroll 0 0 transparent;
+        display: block;
+        padding: 1em 1.4em;
+        border-bottom-right-radius: 4px;
+        border-bottom-left-radius: 4px;
+        color: #222222;
+    }
+}
+
+/* End jQueryUI tab styles */
+
+/* jQuery UI Datepicker */
+.ui-datepicker table {width: 100%; font-size: .9em; border : 0; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { background : transparent none; padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }
+
+.ui-datepicker-trigger {
+    vertical-align: middle;
+    margin : 0 3px;
+}
+.ui-datepicker {
+    .shadowed;
+}
+/* End jQueryUI datepicker styles */
+
+
+/* jQueryUI Core */
+
+.ui-widget-content {
+    border: 1px solid #AAA;
+    background: #ffffff none;
+    color: #222222;
+}
+.ui-widget-header {
+    border: 1px solid #AAA;
+    background: #E6F0F2 none;
+    color: #222222;
+    font-weight: bold;
+}
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+    border: 1px solid #AAA;
+    background: #F4F8F9 none;
+    font-weight: normal;
+    color: #555555;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+    border: 1px solid #AAA;
+    background: #E6F0F2 none;
+    font-weight: normal;
+    color: #212121;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+    border: 1px solid #aaaaaa;
+    background: #ffffff none;
+    font-weight: normal;
+    color: #212121;
+}
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight  {border: 1px solid #fcefa1;
+    background: #fbf9ee;
+    color: #363636;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {border: 1px solid #cd0a0a;
+    background: #fef1ec;
+    color: #cd0a0a;
+}
+
+/* end jQueryUI core */
+
+/* jQueryUI autocomplete */
+
+.ui-autocomplete {
+    position: absolute;
+    cursor: default;
+    .shadowed;
+}
+.ui-autocomplete.ui-widget-content .ui-state-hover {
+    border: 1px solid #AAA;
+    background: #E6F0F2 none;
+    font-weight: normal;
+    color: #212121;
+}
+.ui-autocomplete-loading {
+    background: #FFF url("../../img/loading-small.gif") right center no-repeat;
+}
+.ui-menu li {
+    list-style:none;
+}
+
+/* end jQueryUI autocomplete */
+
+
+
+th {
+    background-color: #ECEDE6;
+}
+
+.item-thumbnail {
+    max-width: none;
+}
+
+.no-image {
+    background-color : #FFF;
+    border: 1px solid #AAA;
+    color : #979797;
+    display:block;
+    font-size : 86%;
+    font-weight : bold;
+    text-align : center;
+    width : 75px;
+    .border-radius-all(3px);
+}
+
+#bookcover .no-image {
+    margin-right : 10px;
+    margin-bottom : 10px;
+}
+
+td.overdue {
+    color : #cc3333;
+}
+table {
+    font-size: 90%;
+}
+th.sum {
+    text-align: right;
+}
+
+td.sum {
+    background-color: #FFC;
+    font-weight: bold;
+}
+
+th[scope=row] {
+    background-color: transparent;
+    text-align : right;
+}
+
+.required {
+    color : #C00;
+}
+
+.label {
+    background-color: transparent;
+    color: inherit;
+    display: inline;
+    font-weight: normal;
+    padding : 0;
+    text-shadow: none;
+}
+
+.blabel {
+    background-color: #999999;
+    border-radius: 3px;
+    color: #ffffff;
+    display: inline-block;
+    font-weight: bold;
+    padding: 2px 4px;
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+.label-important {
+  background-color: #b94a48;
+}
+.label-warning {
+  background-color: #f89406;
+}
+.label-success {
+  background-color: #468847;
+}
+.label-info {
+  background-color: #3a87ad;
+}
+.label-inverse {
+  background-color: #333333;
+}
+
+fieldset {
+    &.rows {
+        float : left;
+        font-size : 90%;
+        clear : left;
+        margin: .9em 0 0 0;
+        padding: 0;
+        width: 100%;
+        legend {
+            font-weight: bold;
+            font-size : 130%;
+        }
+        label,
+        .label {
+            float: left;
+            font-weight : bold;
+            width: 9em;
+            margin-right: 1em;
+            text-align: right;
+        }
+        label {
+            &.lradio {
+                float: none;
+                margin: inherit;
+                width: auto;
+            }
+        }
+        fieldset {
+            margin : 0;
+            padding : .3em;
+        }
+        ol {
+            padding: 1em 1em 0 1em;
+            list-style-type: none;
+            &.lradio {
+                label {
+                    width : auto;
+                    float : none;
+                    margin-right : 0;
+                    &.lradio {
+                        float : left;
+                        width : 12em;
+                        margin-right : 1em;
+                    }
+                }
+            }
+        }
+        li {
+            float : left;
+            clear : left;
+            padding-bottom: 1em;
+            list-style-type: none;
+            width: 100%;
+            &.lradio {
+                padding-left: 8.5em;
+                width : auto;
+                label {
+                    float : none;
+                    width : auto;
+                    margin : 0 0 0 1em;
+                }
+            }
+        }
+        .hint {
+            display: block;
+            margin-left : 11em;
+        }
+    }
+    &.action {
+        clear : both;
+        float : none;
+        border : none;
+        margin : 0;
+        padding : 1em 0 .3em 0;
+        width : auto;
+        p {
+            margin-bottom : 1em;
+        }
+    }
+    table {
+        font-size: 100%;
+    }
+}
+
+div.rows+div.rows {
+    margin-top : .6em;
+}
+
+div.rows {
+    float : left;
+    clear : left;
+    margin: 0 0 0 0;
+    padding: 0;
+    width: 100%;
+    span.label {
+        float: left;
+        font-weight : bold;
+        width: 9em;
+        margin-right: 1em;
+        text-align: left;
+    }
+    ol {
+        list-style-type: none;
+        margin-left : 0;
+        padding: .5em 1em 0 0;
+    }
+    li {
+        border-bottom :  1px solid #EEE;
+        float : left;
+        clear : left;
+        padding-bottom: .2em;
+        padding-top: .1em;
+        list-style-type: none;
+        width: 100%;
+    }
+    ul {
+        li {
+            margin-left : 7.3em;
+            &:first-child {
+                float: none;
+                clear: none;
+                margin-left: 0;
+            }
+        }
+    }
+    ol li li {
+        border-bottom: 0;
+    }
+}
+
+/* different sizes for different tags in opac-tags.tt */
+.tagweight0 {
+    font-size: 12px;
+}
+
+.tagweight1 {
+    font-size: 14px;
+}
+
+.tagweight2 {
+    font-size: 16px;
+}
+
+.tagweight3 {
+    font-size: 18px;
+}
+
+.tagweight4 {
+    font-size: 20px;
+}
+
+.tagweight5 {
+    font-size: 22px;
+}
+
+.tagweight6 {
+    font-size: 24px;
+}
+
+.tagweight7 {
+    font-size: 26px;
+}
+
+.tagweight8 {
+    font-size: 28px;
+}
+
+.tagweight9 {
+    font-size: 30px;
+}
+
+.toolbar {
+    background-color : #EEEEEE;
+    border : 1px solid #E8E8E8;
+    font-size : 85%;
+    padding:3px 3px 5px 5px;
+    vertical-align : middle;
+    a {
+        white-space: nowrap;
+    }
+    label {
+        display: inline;
+        font-size: 100%;
+        font-weight : bold;
+        margin-left : .5em;
+    }
+    select {
+        font-size: 97%;
+        height: auto;
+        line-height: inherit;
+        padding: 0;
+        margin: 0;
+        width : auto;
+        white-space: nowrap;
+    }
+    .hold,
+    #tagsel_tag {
+        padding-left: 28px;
+        font-size: 97%;
+        font-weight: bold;
+    }
+    #tagsel_form {
+        margin-top : .5em;
+    }
+    li {
+        display : inline;
+        list-style : none;
+        a {
+            border-left : 1px solid #e8e8e8;
+        }
+        &:first-child {
+            a {
+                border-left : 0;
+            }
+        }
+    }
+    ul {
+        padding-left : 0;
+    }
+}
+
+#basket .toolbar {
+    padding: 7px 5px 9px 9px;
+}
+
+#selections-toolbar,
+.selections-toolbar {
+    background: -moz-linear-gradient(top, #b2b2b2 0%, #e0e0e0 14%, #e8e8e8 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2b2b2), color-stop(14%,#e0e0e0), color-stop(100%,#e8e8e8)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* IE10+ */
+    background: linear-gradient(top, #b2b2b2 0%,#e0e0e0 14%,#e8e8e8 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e0e0e0', endColorstr='#e8e8e8',GradientType=0 ); /* IE6-9 */
+    margin : 0 0 1em 0;
+    padding-top : .5em;
+    padding-left : 10px;
+}
+
+.list-actions {
+    display : inline;
+}
+
+#tagsel_span input.submit,
+#tagsel_tag {
+    border : 0;
+    background-color: transparent;
+    font-size : 100%;
+    color: #0076B2;
+    cursor : pointer;
+    background-image : url("../images/sprite.png"); /* Tags */
+    background-position : 1px -643px;
+    background-repeat : no-repeat;
+    padding-left : 25px;
+    text-decoration: none;
+}
+
+#tagsel_tag.disabled {
+    background-position : -1px -667px;
+}
+
+
+#tagsel_span input:hover,
+#selections-toolbar input.hold:hover {
+    color: #005580;
+    text-decoration: underline;
+}
+
+#tagsel_span input.disabled,
+#tagsel_span input.disabled:hover,
+#tagsel_span input.hold.disabled,
+#tagsel_span input.hold.disabled:hover,
+#selections-toolbar input.hold.disabled,
+#selections-toolbar input.hold.disabled:hover,
+#selections-toolbar a.disabled,
+#selections-toolbar a.disabled:hover,
+.selections-toolbar a.disabled,
+.selections-toolbar a.disabled:hover {
+    color: #888888;
+    text-decoration: none;
+    padding-left : 23px;
+}
+
+.results_summary {
+    display: block;
+    font-size : 85%;
+    color: #707070;
+    padding : 0 0 .5em 0;
+    .results_summary {
+        font-size : 100%;
+    }
+    &.actions {
+        margin-top : .5em;
+    }
+    &.tagstatus {
+        display: inline;
+    }
+    .label {
+        color: #202020;
+    }
+    a {
+        font-weight: normal;
+    }
+}
+
+#views {
+    margin-bottom : .5em;
+    padding : 0 2em 0.2em 0.2em;
+}
+
+.view {
+    background-color : #F3F3F3;
+    border: 1px solid #C9C9C9;
+    border-radius: 4px;
+    display: inline-block;
+    padding: 0.2em 0.5em;
+    white-space: nowrap;
+}
+
+#bibliodescriptions,
+#isbdcontents {
+    clear : left;
+    margin-top : .5em;
+}
+
+.view {
+    a,
+    span {
+        background-image: url("../images/sprite.png");
+        background-repeat : no-repeat;
+        font-size : 87%;
+        padding-left: 15px;
+        text-decoration: none;
+    }
+}
+
+.view {
+    a {
+        font-weight : normal;
+    }
+}
+
+.current-view {
+    background-color: #fff;
+    font-weight: bold;
+}
+
+#MARCview {
+    background-position: -9px -27px;
+}
+#ISBDview {
+    background-position: -10px -56px;
+}
+#Normalview {
+    background-position: -8px 3px;
+}
+
+#bookcover {
+    float : left;
+    margin : 0;
+    padding : 0;
+    .no-image {
+        margin-right : 10px;
+        margin-bottom : 10px;
+    }
+    img {
+        margin : 0 1em 1em 0;
+    }
+}
+
+/* pagination */
+.results-pagination {
+    position: absolute;
+    top:32px;
+    left: -1px;
+    width: 100%;
+    height:auto;
+    border: 1px solid #D0D0D0;
+    display: none;
+    background-color:#F3F3F3;
+    padding-bottom:10px;
+    z-index: 100;
+}
+
+
+.back {
+    float:right;
+    input {
+        background:none!important;
+        color:#999!important;
+    }
+}
+
+.pagination_list {
+    ul {
+        padding-top: 40px;
+        padding-left:0px;
+    }
+    li {
+        list-style:none;
+        float:bottom;
+        padding:4px;
+        color:#999;
+        &.highlight {
+           background-color : #F3F3F3;
+           border-top : 1px solid #DDDDDD;
+           border-bottom : 1px solid #DDDDDD;
+        }
+        a {
+            padding-left:0px;
+        }
+    }
+    .li_pag_index {
+        color: #999999;
+        float: left;
+        font-size: 15px;
+        font-weight: bold;
+        padding-right: 10px;
+        text-align: right;
+        width: 13px;
+    }
+}
+
+.nav_results {
+    background-color: #F3F3F3;
+    border: 1px solid #D0D0D0;
+    font-size: 95%;
+    font-weight: bold;
+    margin-top: 0.5em;
+    position:relative;
+    .l_Results {
+        a {
+            background:#E1E1E1 url("../images/sprite.png") no-repeat 0px -504px; /* Browse results menu */
+            color:#006699;
+            display:block;
+            padding:8px 28px;
+            text-decoration:none;
+        }
+        &:hover {
+            background-color:#D9D9D9;
+        }
+    }
+}
+
+.pg_menu {
+    margin: 0;
+    border-top: 1px solid #D0D0D0;
+    white-space : nowrap;
+    li {
+        color:#B2B2B2;
+        display:inline;
+        list-style:none;
+        margin: 0;
+        &.back_results {
+            a {
+                border-left: 1px solid #D0D0D0;
+                border-right: 1px solid #D0D0D0;
+            }
+        }
+        a,
+        span {
+            background-color: #F3F3F3;
+            display : block;
+            float:left;
+            padding:.4em .5em;
+            text-decoration:none;
+            font-weight:normal;
+            text-align:center;
+        }
+        span {
+            color : #B2B2B2;
+        }
+    }
+}
+
+#listResults{
+    li {
+        background-color:#999999;
+        color:#C5C5C5;
+        font-weight:normal;
+        display:block;
+        margin-right:1px;
+        font-size: 80%;
+        padding: 0;
+        text-align:center;
+        min-width:18px;
+        &:hover {
+            background-color:#006699;
+        }
+        a {
+            color:#FFFFFF;
+            font-weight:normal;
+        }
+    }
+}
+
+/* nav */
+.nav_pages {
+    .close_pagination {
+        padding-right: 10px;
+        position: absolute;
+        right: 3px;
+        top: -25px;
+    }
+    .close_pagination a {
+        text-decoration:none!important;
+    }
+    ul {
+        padding-top: 10px;
+    }
+    li {
+        list-style:none;
+        float:left;
+        padding:4px;
+        color:#999;
+        a {
+            text-decoration:none!important;
+            &:hover {
+            text-decoration:underline;
+            }
+        }
+        ul {
+            float:left;
+        }
+    }
+}
+
+/* action buttons */
+#action {
+    margin : .5em 0 0 0;
+    background-color : #F3F3F3;
+    border : 1px solid #E8E8E8;
+    padding-bottom : 3px;
+    li {
+        list-style : none;
+        margin : .2em;
+        padding : .3em 0;
+    }
+    a {
+        font-weight: bold;
+        text-decoration : none;
+    }
+}
+
+#export,
+#moresearches_menu {
+    li {
+        padding : 0;
+        margin : 0;
+        a {
+            font-weight: normal;
+            &.menu-inactive {
+                font-weight: bold;
+            }
+        }
+    }
+}
+
+#format,
+#furthersearches {
+    padding-left : 35px;
+}
+.highlight_controls {
+    float: left;
+}
+a.addtocart,
+a.addtoshelf,
+a.brief,
+a.deleteshelf,
+a.deleteshelf.disabled,
+a.detail,
+a.download,
+a.editshelf,
+a.sharelist,
+a.empty,
+a.hide,
+a.highlight_toggle,
+a.hold,
+a.hold.disabled,
+a.incart,
+a.new,
+a.print-small,
+a.print-large,
+a.removeitems,
+a.removeitems.disabled,
+a.reserve,
+a.article_request,
+a.send,
+a.tag_add,
+a.removefromlist,
+input.hold,
+input.hold.disabled,
+input.editshelf,
+.newshelf,
+.newshelf.disabled,
+.deleteshelf {
+    background-image: url("../images/sprite.png");
+    background-repeat: no-repeat;
+}
+
+
+a.addtocart {
+    background-position: -5px -265px; /* Cart */
+    padding-left : 35px;
+}
+
+a.addtoshelf {
+    background-position: -5px -225px; /* Virtual shelf */
+    padding-left : 35px;
+}
+
+a.brief {
+
+    background-position : -2px -868px; /* Zoom out */
+    text-decoration : none;
+    padding-left : 27px;
+}
+
+a.cartRemove {
+    color: #cc3333;
+    font-size : 90%;
+    margin : 0;
+    padding: 0;
+}
+
+a.detail {
+    background-position : -2px -898px; /* Zoom in */
+    text-decoration : none;
+    padding-left : 27px;
+}
+
+a.download {
+    background-position : -5px -348px; /* Download */
+    padding-left : 20px;
+    text-decoration : none;
+}
+
+a.editshelf {
+    background-position : 2px -348px; /* List edit */
+    padding-left : 26px;
+    text-decoration : none;
+}
+
+a.sharelist {
+    background-position : 2px -1148px; /* List share */
+    padding-left : 26px;
+    text-decoration : none;
+}
+
+a.empty {
+    background-position : 2px -598px; /* Trash */
+    text-decoration : none;
+    padding-left : 30px;
+}
+
+a.hide {
+    background-position: -3px -814px; /* Close */
+    text-decoration : none;
+    padding-left : 26px;
+}
+
+a.highlight_toggle {
+    background-position: -5px -841px; /* Highlight */
+    display: none;
+    padding-left : 35px;
+}
+
+a.hold,
+input.hold {
+    background-position : -2px -453px; /* Toolbar place hold */
+    text-decoration : none;
+    padding-left : 23px;
+}
+
+a.hold.disabled,
+input.hold.disabled {
+    background-position : -5px -621px; /* Place hold disabled */
+}
+
+a.incart {
+    background-position: -5px -265px; /* Cart */
+    color : #666;
+    padding-left : 35px;
+}
+
+a.new {
+    background-image : url("../images/sprite.png"); /* New */
+    background-position : -4px -922px;
+    padding-left : 23px;
+    text-decoration : none;
+}
+
+a.print-small {
+    background-position : 0px -423px; /* Toolbar print */
+    text-decoration : none;
+    padding-left : 30px;
+}
+
+a.print-large {
+    background-position : -5px -186px; /* Toolbar print */
+    text-decoration : none;
+    padding-left : 35px;
+}
+
+a.removeitems,
+a.deleteshelf {
+    background-position : 2px -690px; /* Delete */
+    text-decoration : none;
+    padding-left : 25px;
+}
+
+a.removeitems.disabled,
+a.deleteshelf.disabled {
+    background-position : 2px -712px; /* Delete disabled */
+}
+
+a.reserve {
+    background-position: -6px -144px; /* Place hold */
+    padding-left : 35px;
+}
+
+a.article_request {
+    background-position: 0px -24px; /* Place article request */
+    padding-left : 35px;
+}
+
+a.send {
+    background-position : 2px -386px; /* Email */
+    text-decoration : none;
+    padding-left : 28px;
+}
+
+a.tag_add {
+    background-position: 3px -1111px; /* Tag results */
+    padding-left : 27px;
+    text-decoration: none;
+}
+
+input.hold {
+    background-color: transparent;
+    border : 0;
+    color: #0076B2;
+    font-weight: bold;
+}
+
+input.editshelf {
+    background-color: transparent;
+    background-position : 2px -734px; /* List edit */
+    border : 0;
+    color : #006699;
+    cursor : pointer;
+    filter: none;
+    font-size : 100%;
+    padding-left : 29px;
+    text-decoration : none;
+}
+
+.newshelf {
+    background-position: 2px -764px; /* List new */
+    border : 0;
+    color : #006699;
+    cursor : pointer;
+    filter: none;
+    font-size : 100%;
+    padding-left : 28px;
+    text-decoration : none;
+}
+
+.newshelf.disabled {
+    background-position: -4px -791px; /* List new disabled */
+}
+
+.deleteshelf {
+    background-color: transparent;
+    background-position : 2px -687px; /* Delete */
+    border : 0;
+    color : #006699;
+    cursor : pointer;
+    filter: none;
+    font-size : 100%;
+    padding-left : 25px;
+    text-decoration : none;
+}
+
+.links a {
+    font-weight : bold;
+}
+
+.deleteshelf:hover {
+    color: #990033;
+}
+
+
+.editshelf:active,
+.deleteshelf:active {
+    border : 0;
+}
+
+#tagslist li { display : inline; }
+
+#login4tags {
+    background-image: url("../images/sprite.png"); /* Tag results disabled */
+    background-position: -6px -1130px;
+    background-repeat: no-repeat;
+    padding-left : 20px;
+    text-decoration: none;
+}
+
+.tag_results_input {
+    margin-left: 1em;
+    padding: 0.3em;
+    font-size: 12px;
+    input[type="text"] {
+        font-size: inherit;
+        margin : 0;
+        padding : 0;
+    }
+    label {
+        display : inline;
+    }
+}
+
+.tagsinput {
+    input[type="text"] {
+        font-size: inherit;
+        margin : 0;
+        padding : 0;
+    }
+    label {
+        display : inline;
+    }
+}
+
+.branch-info-tooltip {
+    display: none;
+}
+
+.ui-tooltip-content p {
+        margin: 0.3em 0;
+}
+
+#social_networks {
+    a {
+        background: transparent url("../images/social-sprite.png") no-repeat;
+        display: block;
+        height : 20px !important;
+        width : 20px;
+        text-indent : -999em;
+    }
+    span {
+        color: #274D7F;
+        display : block;
+        float : left;
+        font-size: 85%;
+        font-weight: bold;
+        line-height: 2em;
+        margin : .5em 0 .5em .5em !important;
+    }
+    div {
+        float : left !important;
+        margin : .5em 0 .5em .2em !important;
+    }
+    #facebook {
+        background-position : -7px -35px;
+    }
+    #twitter {
+        background-position : -7px -5px;
+    }
+    #linkedin {
+        background-position : -7px -95px;
+    }
+    #delicious {
+        background-position : -7px -66px;
+    }
+    #email {
+        background-position : -7px -126px;
+    }
+}
+
+#marc {
+    td,
+    th {
+        background-color : transparent;
+        border : 0;
+        padding: 3px 5px;
+        text-align : left;
+    }
+    td:first-child {
+        text-indent : 2em;
+    }
+    p {
+        padding-bottom: .6em;
+        .label {
+            font-weight : bold;
+        }
+    }
+    ul {
+        padding-bottom: .6em;
+    }
+    .results_summary {
+        clear :  left;
+        ul {
+            display : inline;
+            float :  none;
+            clear :  none;
+            margin: 0;
+            padding: 0;
+            list-style : none;
+        }
+        li {
+            display: inline;
+        }
+    }
+}
+
+#items,
+#items td
+#items th {
+    border : 1px solid #EEE;
+    font-size : 90%;
+}
+
+#plainmarc table { border: 0; margin: .7em 0 0 0; font-family: monospace; font-size: 95%; }
+#plainmarc th { background-color : #FFF; border: 0; white-space: nowrap; text-align:left; vertical-align: top; padding: 2px; }
+#plainmarc td { border: 0; padding : 2px; vertical-align: top; }
+
+#renewcontrols {
+     float: right;
+     font-size: 66%;
+}
+
+#renewcontrols a {
+    background-repeat : no-repeat;
+    text-decoration:none;
+    padding : .1em .4em;
+    padding-left : 18px;
+}
+
+#renewselected_link {
+    background-image : url("../images/sprite.png");
+    background-position : -5px -986px;
+    background-repeat: no-repeat;
+}
+
+#renewall_link {
+    background-image : url("../images/sprite.png");
+    background-position : -8px -967px;
+    background-repeat: no-repeat;
+}
+
+.authref {
+    text-indent: 2em;
+}
+
+.authref .label {
+    font-style: italic;
+}
+
+.authstanza {
+    margin-top: 1em;
+}
+
+.authstanzaheading {
+    font-weight: bold;
+}
+.authorizedheading {
+    font-weight: bold;
+}
+.authstanza li {
+    margin-left: 0.5em;
+}
+.authres_notes, .authres_seealso, .authres_otherscript {
+  padding-top: .5em;
+}
+.authres_notes {
+  font-style: italic;
+}
+
+#didyoumean {
+    background-color: #EEE;
+    border: 1px solid #E8E8E8;
+    box-sizing: border-box;
+    margin: .5em 1.5em;
+    text-align: left;
+    padding: 0.5em;
+    .border-radius-all(3px);
+
+    &.dym-loaded {
+        border-color: #F4ECBE;
+        background-color: #FFFBEA;
+    }
+}
+
+.suggestionlabel {
+    font-weight: bold;
+}
+
+.searchsuggestion {
+    padding: 0.2em 0.5em;
+    display: inline-block;
+}
+
+.authlink {
+    padding-left: 0.25em;
+}
+#hierarchies a {
+    font-weight: normal;
+    text-decoration: underline;
+    color: #069;
+}
+
+#hierarchies a:hover {
+    color: #990033;
+}
+
+#top-pages {
+    margin: 0 0 0.5em;
+}
+.dropdown-menu > li > a {
+    font-size: 90%;
+}
+a.listmenulink:link,
+a.listmenulink:visited {
+    color : #0076B2;
+    font-weight: bold;
+}
+a.listmenulink:hover,
+a.listmenulink:active {
+    color : #FFF;
+    font-weight: bold;
+}
+#cartDetails,
+#cartUpdate,
+#holdDetails,
+#listsDetails {
+    background-color : #FFF;
+//    border: 1px solid #739acf;
+    border: 1px solid rgba(0, 0, 0, 0.2);
+    border-radius: 6px 6px 6px 6px;
+    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+    color : black;
+    display : none;
+    font-size: 90%;
+    margin : 0;
+    padding : 8px 20px;
+    text-align : center;
+    width : 180px;
+    z-index: 2;
+}
+#cartmenulink {
+    white-space: nowrap;
+}
+
+#search-facets,
+#menu {
+    border : 1px solid #D2D2CF;
+    .border-radius-all(7px);
+    ul {
+       margin : 0;
+        padding : .3em;
+    }
+    form {
+       margin : 0;
+    }
+    h4 {
+        font-size : 90%;
+        margin : 0 0 .6em 0;
+        text-align : center;
+        a {
+            background-color : #F2F2EF;
+            border-radius: 8px 8px 0 0;
+            border-bottom : 1px solid #D8D8D8;
+            display: block;
+            font-weight: bold;
+            padding : .7em .2em;
+            text-decoration: none;
+        }
+    }
+    li {
+        font-size: 90%;
+        font-weight : bold;
+        list-style-type : none;
+        li {
+            font-weight : normal;
+            font-size : 95%;
+            line-height: 125%;
+            margin-bottom : 2px;
+            padding : .1em .2em;
+        }
+        &.showmore {
+            a {
+                font-weight : bold;
+                text-indent : 1em;
+            }
+        }
+    }
+    a {
+        font-weight : normal;
+        text-decoration: underline;
+    }
+    .facet-count {
+        display: inline-block;
+    }
+
+}
+
+#menu {
+    font-size : 94%;
+    li {
+        list-style-type : none;
+        a {
+            background: #eeeeee;
+            text-decoration : none;
+            display : block;
+            border : 1px solid #D8D8D8;
+            border-radius: 5px 0 0 5px;
+            border-bottom-color:  #999;
+            font-size : 111%;
+            padding : .4em .6em;
+            margin : .4em 0;
+            margin-right: -1px;
+            &:hover {
+                background: #eaeef5;
+            }
+        }
+        &.active {
+            a {
+                background-color : #FFF;
+                background-image : none;
+                border-right-width: 0;
+                font-weight : bold;
+                &:hover {
+                    background-color : #fff;
+                }
+            }
+        }
+    }
+    h4 {
+        display: none;
+    }
+}
+
+#addto {
+    max-width : 10em;
+}
+
+/* Search results add to cart (lists disabled) */
+.addto a.addtocart {
+    background-image: url("../images/sprite.png"); /* Cart */
+    background-position: -5px -266px;
+    background-repeat: no-repeat;
+    text-decoration : none;
+    padding-left : 33px;
+}
+
+.searchresults {
+    p {
+        margin: 0;
+        padding: 0 0 .6em 0;
+        &.details {
+           color : #979797;
+        }
+    }
+    a {
+        &.highlight_toggle {
+            background-image: url("../images/sprite.png"); /* Highlight */
+            background-position: -11px -841px;
+            background-repeat: no-repeat;
+            display: none;
+            font-weight: normal;
+            padding : 0 10px 0 21px;
+        }
+    }
+    .commentline {
+        background-color : rgb(255, 255, 204);
+        background-color : rgba(255, 255, 204, 0.4);
+        border : 1px solid #CCC;
+        display: inline-block;
+        .border-radius-all(3px);
+        .shadowed;
+        margin : .3em;
+        padding : .4em;
+    }
+    .commentline.yours {
+        background-color : rgb(239, 254, 213);
+        background-color : rgba(239, 254, 213, 0.4);
+    }
+}
+
+.commentline .avatar {
+    float : right;
+    padding-left : .5em;
+}
+
+/* style for search terms in catalogsearch */
+.term {
+    /* color : blue; */
+    color : #990000;
+    background-color : #FFFFCC;
+}
+
+/* style for shelving location in catalogsearch */
+.shelvingloc {
+    display : block;
+    font-style : italic;
+}
+#CheckAll,
+#CheckNone,
+.CheckAll,
+.CheckNone {
+    font-weight : normal;
+    margin : 0 .5em;
+    text-decoration: underline;
+}
+
+span.sep {
+    color: #888;
+    padding: 0 .2em 0 .5em;
+    text-shadow: 1px 1px 0 #FFF;
+}
+
+/* style for PM-generated pagination bar */
+.pages {
+    margin: 20px 0;
+}
+.pages span:first-child,
+.pages a:first-child {
+    border-width: 1px 1px 1px 1px;
+    border-bottom-left-radius: 3px;
+    border-top-left-radius: 3px;
+}
+
+.pages span:last-child,
+.pages a:last-child {
+    border-width: 1px 1px 1px 0;
+    border-bottom-right-radius: 3px;
+    border-top-right-radius: 3px;
+}
+
+.pages .inactive,
+.pages .currentPage,
+.pages a {
+    -moz-border-bottom-colors: none;
+    -moz-border-left-colors: none;
+    -moz-border-right-colors: none;
+    -moz-border-top-colors: none;
+    background-color: #FFFFFF;
+    border-color: #DDDDDD;
+    border-image: none;
+    border-style: solid;
+    border-width: 1px 1px 1px 0;
+    float: left;
+    font-size: 11.9px;
+    line-height: 20px;
+    padding: 4px 12px;
+    text-decoration: none;
+}
+
+.pages .inactive {
+    background-color: #F5F5F5;
+}
+
+.pages a[rel='last'] {
+    border-bottom-right-radius: 3px;
+    border-top-right-radius: 3px;
+}
+
+.hold-message {
+    background-color: #FFF0B1;
+    display: inline-block;
+    margin: 0.5em;
+    padding: 0.2em 0.5em;
+    .border-radius-all(3px);
+}
+.reserve_date,
+.expiration_date {
+    white-space: nowrap;
+}
+.close {
+    color: #0088CC;
+    position: inherit;
+    top: auto;
+    right : auto;
+    filter : none;
+    float : none;
+    font-size: inherit;
+    font-weight: normal;
+    opacity: inherit;
+    text-shadow: none;
+}
+
+.close:hover {
+    color: #538200;
+    filter: inherit;
+    font-size: inherit;
+    opacity: inherit;
+}
+
+/* Redefine a new style for Bootstrap's class "close" since we use that already */
+/* Use <a class="closebtn" href="#">&times;</a> */
+.alert .closebtn{position:relative;top:-2px;right:-21px;line-height:20px;}
+.modal-header .closebtn{margin-top:2px;}
+.closebtn{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.closebtn:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);}
+button.closebtn{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;}
+.btn-group label,
+.btn-group select {
+    font-size: 13px;
+}
+
+.span2 select {
+    width: 100%;
+}
+
+.popup .main {
+    font-size: 90%;
+    padding: 0 1em;
+}
+
+.popup legend {
+    line-height: 1.5em;
+    margin-bottom : .5em;
+}
+
+.item-status {
+    display: block;
+    font-size: 95%;
+    margin-bottom: .5em;
+}
+
+.available {
+    color : #006600;
+}
+
+.unavailable {
+    color: #990033;
+}
+
+.waiting,.intransit,.notforloan,.checkedout,.lost,.notonhold {
+    display : block;
+}
+
+.notforloan {
+    color : #900;
+}
+
+.lost {
+    color : #666;
+}
+
+.suggestion {
+    background-color : #EEEEEB;
+    border : 1px solid #DDDED3;
+    margin : 1em auto;
+    padding : .5em;
+    width : 35%;
+    .border-radius-all(3px);
+}
+
+.librarypulldown .transl1 {
+    width : auto;
+}
+
+.nolibrarypulldown {
+    width : 68%;
+}
+
+.nolibrarypulldown .transl1 {
+    width : 87%;
+}
+
+#opac-main-search {
+    select {
+        width : auto;
+        max-width: 12em;
+    }
+}
+
+#logo {
+    background:transparent url("../images/koha-logo-navbar.png") no-repeat scroll 0%;
+    border: 0;
+    float : left !important;
+    margin:0;
+    padding:0;
+    width:100px;
+    a {
+        border:0;
+        cursor:pointer;
+        display:block;
+        height:0px !important;
+        margin:0;
+        overflow:hidden;
+        padding:40px 0 0;
+        text-decoration:none;
+        width:100px;
+    }
+}
+
+#user-menu-trigger {
+    display: none;
+    .icon-user {
+        background: transparent url("../lib/bootstrap/img/glyphicons-halflings-white.png") no-repeat;
+        background-position: -168px 0;
+        background-repeat: no-repeat;
+        height: 14px;
+        line-height: 14px;
+        margin : 12px 0 0;
+        vertical-align: text-top;
+        width: 14px;
+    }
+    .caret {
+        border-bottom-color: #999999;
+        border-top-color: #999999;
+        margin-top: 18px;
+    }
+}
+
+/* Class to be added to toolbar when it starts being fixed at the top of the screen*/
+.floating {
+    -webkit-box-shadow: 0px 3px 2px 0px rgba(0, 0, 0, .4);
+    box-shadow: 0px 3px 2px 0px rgba(0, 0, 0, .4);
+    margin-top: 0;
+}
+
+.tdlabel {
+    font-weight: bold;
+    display: none;
+}
+
+td img {
+    max-width: none;
+}
+
+#ulactioncontainer {
+    min-width: 16em;
+}
+
+.notesrow {
+    label {
+        font-weight: bold;
+    }
+    span {
+        display: block;
+    }
+}
+
+.thumbnail-shelfbrowser span {
+    margin: 0px auto;
+}
+
+.dropdown-menu > li > a.menu-inactive:hover {
+    background : #FFF none;
+    color : #000;
+}
+
+.table {
+    .sorting_asc {
+        padding-right: 19px;
+        background: url("../images/asc.gif") no-repeat scroll right center #ECEDE6;
+    }
+    .sorting_desc {
+        padding-right: 19px;
+        background: url("../images/desc.gif") no-repeat scroll right center #ECEDE6;
+    }
+    .sorting {
+        padding-right: 19px;
+        background: url("../images/ascdesc.gif") no-repeat scroll right center #ECEDE6;
+    }
+    .nosort,
+    .nosort.sorting_asc,
+    .nosort.sorting_desc,
+    .nosort.sorting {
+        padding-right: 19px;
+        background: #ECEDE6 none;
+    }
+    th,
+    td {
+        line-height: 135%;
+    }
+}
+.tags, .shelves {
+    ul {
+        display: inline;
+        list-style: none;
+        margin-left : 0;
+        li {
+            display: inline;
+        }
+    }
+}
+.coverimages {
+    float : right;
+}
+#i18nMenu {
+    margin-left : 1em;
+    li {
+        font-size : 85%;
+        li {
+            font-size: 100%;
+        }
+        li > a {
+            font-size : 100%;
+            &:hover {
+                color : #FFF;
+            }
+        }
+        a {
+            color : @links;
+        }
+    }
+    .dropdown-menu {
+        li {
+            p {
+                clear: both;
+                display: block;
+                font-weight: normal;
+                line-height: 20px;
+                padding: 3px 20px;
+                white-space: nowrap;
+            }
+        }
+    }
+}
+
+#subjectsList,
+#authorSearch {
+    label {
+        display :inline;
+        vertical-align: middle;
+    }
+    ul {
+        border-bottom: 1px solid #EEE;
+        list-style-type: none;
+        margin: 0;
+        padding: .6em 0;
+    }
+    li {
+        list-style-type: none;
+        margin: 0;
+        padding: 0;
+    }
+}
+
+
+#overdrive-results, #openlibrary-results {
+    font-weight: bold;
+    padding-left: 1em;
+}
+
+.throbber {
+    vertical-align: middle;
+}
+
+#overdrive-results-list .star-rating-control {
+    display: block;
+    overflow: auto;
+}
+
+#shelfbrowser {
+    table {
+        margin : 0;
+    }
+    table,
+    td,
+    th {
+        border : 0;
+        font-size : 90%;
+        text-align : center;
+    }
+    td,
+    th {
+        padding: 3px 5px;
+        width : 20%;
+    }
+    a {
+        display : block;
+        font-size : 110%;
+        font-weight : bold;
+        text-decoration : none;
+    }
+    #browser_next,
+    #browser_previous {
+        background-image : url("../images/sprite.png");
+        background-repeat: no-repeat;
+        width : 16px;
+        a {
+            cursor: pointer;
+            display : block;
+            height: 0 !important;
+            margin: 0;
+            overflow: hidden;
+            padding: 50px 0 0;
+            text-decoration: none;
+            width: 16px;
+        }
+    }
+    #browser_previous {
+        background-position: -9px -1007px;
+    }
+    #browser_next {
+        background-position: -9px -1057px;
+    }
+}
+
+#holds {
+    margin : 0 auto;
+    max-width: 800px;
+}
+.holdrow {
+    clear : both;
+    padding: 0 1em 1em 1em;
+    border-bottom:1px solid #CCC;
+    margin-bottom:.5em;
+    fieldset {
+        border : 0;
+        margin : 0;
+        float: none;
+        .label {
+            font-size: 14px;
+        }
+    }
+    label {
+        display: inline;
+    }
+}
+.hold-options {
+    clear : both;
+}
+.toggle-hold-options {
+    background-color: #eee;
+    clear : both;
+    display : block;
+    font-weight : bold;
+    margin: 1em 0;
+    padding: .5em;
+}
+.copiesrow {
+    clear : both;
+}
+
+#idreambooksreadometer {
+    float: right;
+}
+
+a.idreambooksrating {
+    font-size: 30px;
+    color: #29ADE4;
+    padding-left: 85px;
+    line-height: 30px;
+    text-decoration: none;
+}
+
+.idreambookslegend {
+    font-size: small;
+}
+
+a.reviewlink,
+a.reviewlink:visited {
+    text-decoration: none;
+    color: black;
+    font-weight: normal;
+}
+
+.idreambookssummary a {
+    color: #707070;
+    text-decoration: none;
+}
+
+.idreambookssummary img,
+.idbresult img {
+    vertical-align: middle;
+}
+
+.idbresult {
+    color: #29ADE4;
+    text-align: center;
+    margin: 0.5em;
+    padding: 0.5em;
+}
+
+.idbresult a,
+.idbresult a:visited {
+    text-decoration: none;
+    color: #29ADE4;
+}
+
+.idbresult img {
+    padding-right: 6px;
+}
+
+.js-show {
+    display: none;
+}
+
+.modal-nojs {
+    .modal-header,
+    .modal-footer {
+        display: none;
+    }
+}
+
+.contents {
+    width: 75%;
+}
+
+
+.contentblock {
+    font-size : 95%;
+    line-height: 135%;
+    position: relative;
+    margin-left: 2em;
+}
+
+.contents {
+    .t:first-child:before {
+        content: "→ ";
+    }
+    .t:before {
+        content: "\A → ";
+        white-space: pre;
+    }
+    .t {
+        font-weight: bold;
+        display: inline;
+    }
+    .r {
+        display: inline;
+    }
+}
+
+.m880 {
+    display:block;
+    text-align:right;
+    float:right;
+    width:50%;
+    padding-left:20px;
+}
+
+#memberentry-form input.error {
+    border-color: #c00;
+    box-shadow: 0 1px 1px #c00 inset, 0 0 8px #c00;
+    color: red; outline: 0 none;
+}
+
+#memberentry-form input.error:focus {
+    border-color: #c00;
+    box-shadow: 0 1px 1px #c00 inset, 0 0 8px #c00;
+    color: red; outline: 0 none;
+}
+
+#memberentry-form label.error {
+    color: #c00; float: none;
+    font-size: 90%;
+}
+
+#illrequests {
+    .illrequest-actions {
+        .btn,
+        .cancel {
+            margin-right: 5px;
+        }
+        padding-top: 20px;
+        margin-bottom: 20px;
+    }
+    #illrequests-create-button {
+        margin-bottom: 20px;
+    }
+    .bg-info {
+        overflow: auto;
+        position: relative;
+    }
+    .bg-info {
+        #search-summary {
+            -webkit-transform: translateY(-50%);
+            -ms-transform: translateY(-50%);
+            -o-transform: translateY(-50%);
+            transform: translateY(-50%);
+            position: absolute;
+            top: 50%;
+        }
+
+    }
+    #freeform-fields .custom-name {
+        float: left;
+        width: 8em;
+        margin-right: 1em;
+        text-align: right;
+    }
+    .dropdown:hover .dropdown-menu.nojs {
+        display: block;
+    }
+}
+
+#dc_fieldset {
+    border: 1px solid #dddddd;
+    border-width: 1px;
+    padding: 5px;
+    border-radius: 10px
+}
+
+.label_dc{
+    display: inline;
+    padding: 0px;
+    margin: 0px;
+    cursor: pointer;
+}
+
+.btn-danger {
+    color: white !important;
+}
+
+.count_label {
+    @base: #369;
+    background-color: @base;
+    border-radius: 5px;
+    color: #FFF;
+    display: inline-block;
+    font-weight: bold;
+    min-width: 1.5em;
+    padding: .2em;
+    text-align: center;
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+
+    &:hover {
+        background-color: lighten( @base, 20% );
+    }
+}
+
+.user_checkouts_count {
+
+}
+
+.user_overdues_count,
+.user_fines_count {
+    background-color: #990000;
+    &:hover {
+        background-color: lighten( #990000, 10% );
+    }
+}
+
+.user_holds_pending_count {
+
+}
+
+.user_holds_waiting_count {
+    background-color: #538200;
+    &:hover {
+        background-color: lighten( #538200, 10% );
+    }
+}
+
+#user_summary {
+    border: 1px solid #EAEAE6;
+    border-radius: 7px;
+    margin-bottom: 1em;
+    padding-bottom: .5em;
+
+    h3 {
+        background-color: #EAEAE6;
+        border-top-left-radius: 6px;
+        border-top-right-radius: 6px;
+        box-shadow: 0 1px 1px 0 rgba(0,0,0,0.2);
+        margin-top: 0;
+        padding: .2em 0;
+        text-align: center;
+    }
+
+    ul {
+        list-style-type: none;
+        margin: 0 0 .2em 0;
+
+        a {
+            display: block;
+            font-weight: bold;
+            padding: .2em 1em;
+        }
+    }
+}
+
+
+
+@import "responsive.less";
diff --git a/opac/opac-cmspages.pl b/opac/opac-cmspages.pl
new file mode 100755
index 0000000000..eaace18356
--- /dev/null
+++ b/opac/opac-cmspages.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Copyright Halland County Library 2015
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+use CGI;
+use C4::Auth;
+use C4::Output;
+use C4::Languages qw( getTranslatedLanguages accept_language );
+use Koha::CmsPages;
+
+my $input  = new CGI;
+my $id     = scalar $input->param( 'id' )     // '';
+my $lang   = scalar $input->param( 'lang' )   // '';
+my $branch = scalar $input->param( 'branch' ) // '';
+
+my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+    {
+        template_name   => "opac-cmspages.tt",
+        type            => "opac",
+        query           => $input,
+        authnotrequired => ( C4::Context->preference( "OpacPublic" ) ? 1 : 0 ),
+        flagsrequired   => { borrow => 1 },
+    }
+);
+
+my ( $theme, $news_lang, $availablethemes ) = C4::Templates::themelanguage(
+    C4::Context->config( 'opachtdocs'), 'opac-cmspages.tt', 'opac', $input );
+
+my ($cms_nav_top, $cms_nav_left, $cms_data) = Koha::CmsPages->page( $id );
+$template->param(
+	cms_page     => $cms_data,
+    cms_nav_top  => $cms_nav_top,
+    cms_nav_left => $cms_nav_left,
+);
+
+output_html_with_http_headers $input, $cookie, $template->output;
diff --git a/opac/opac-main.pl b/opac/opac-main.pl
index 965618c5d3..7b88b00b30 100755
--- a/opac/opac-main.pl
+++ b/opac/opac-main.pl
@@ -30,6 +30,7 @@ use C4::Overdues;
 use Koha::Checkouts;
 use Koha::Holds;
 use Koha::News;
+use Koha::CmsPages qw( list );
 
 my $input = new CGI;
 my $dbh   = C4::Context->dbh;
@@ -109,7 +110,10 @@ $template->param(
     daily_quote         => $quote,
 );
 
-# If GoogleIndicTransliteration system preference is On Set parameter to load Google's javascript in OPAC search screens
+$template->param(
+    cms_nav_top => Koha::CmsPages->child_links( undef ),
+);
+
 if (C4::Context->preference('GoogleIndicTransliteration')) {
         $template->param('GoogleIndicTransliteration' => 1);
 }
diff --git a/t/Pages.t b/t/Pages.t
new file mode 100644
index 0000000000..5e6d4634d2
--- /dev/null
+++ b/t/Pages.t
@@ -0,0 +1,31 @@
+#!/usr/bin/perl
+
+use Modern::Perl;
+use Carp;
+use Test::More tests => 2;
+use Data::Dumper::Concise;
+
+BEGIN {
+    use_ok('C4::Content');
+}
+
+my $src = [
+    { id => '1', parent => '' },
+    { id => '2', parent => '1' },
+    { id => '3', parent => '1' },
+    { id => '4', parent => '2' },
+    { id => '5', parent => '2' },
+];
+
+my $expected = [
+    { id => '1', children => [
+        { id => '2', children => [
+            { id => '4', children => [] },
+            { id => '5', children => [] } ]
+        },
+        { id => '3', children => [] } ]
+    },
+];
+
+my $output = C4::Content::_SQLToPerl($src);
+is_deeply($output, $expected);
diff --git a/t/db_dependent/Pages.t b/t/db_dependent/Pages.t
new file mode 100644
index 0000000000..2c98c3874a
--- /dev/null
+++ b/t/db_dependent/Pages.t
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+# Copyright Halland County Library 2015.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 2;
+use Test::Warn;
+use Data::Dumper::Concise;
+
+use C4::Context;
+use Koha::Database;
+use t::lib::TestBuilder;
+
+BEGIN {
+    use_ok('Koha::Objects');
+    use_ok('Koha::CmsPages');
+}
+
+my $builder = t::lib::TestBuilder->new();
+
+# Start transaction
+my $dbh = C4::Context->dbh;
+$dbh->{ AutoCommit } = 0;
+$dbh->{ RaiseError } = 1;
+$dbh->do( 'DELETE FROM items' );
+$dbh->do( 'DELETE FROM borrowers' );
+$dbh->do( 'DELETE FROM branches' );
+$dbh->do( 'DELETE FROM cms_pages' );
+
+my $branchcode = $builder->build({ source => 'Branch' });
+
+my $page10 = $builder->build({
+	source => 'CmsPage',
+	value  => {
+		parent     => undef,
+		title_link => 'page 10',
+		title      => 'full page 10',
+		published  => 1,
+		sortorder  => 1,
+	}
+});
+my $page11 = $builder->build({
+	source => 'CmsPage',
+	value  => {
+		parent     => $page10->{'id'},
+		title_link => 'subpage 11',
+		title      => 'full subpage 11',
+		published  => 1,
+		sortorder  => 0,
+	}
+});
+my $page12 = $builder->build({
+	source => 'CmsPage',
+	value  => {
+		parent     => $page10->{'id'},
+		title_link => 'subpage 12',
+		title      => 'full subpage 12',
+		published  => 1,
+		sortorder  => 1,
+	}
+});
+my $page20 = $builder->build({
+	source => 'CmsPage',
+	value  => {
+		parent     => undef,
+		title_link => 'page 20',
+		title      => 'full page 20',
+		published  => 0,
+		sortorder  => 2,
+	}
+});
+
+my $result = Koha::CmsPages->child_links( undef );
+is_deeply( $result, [ $page10, $page20 ]);
+
+$dbh->rollback();
+
+1;
diff --git a/tools/cmspages.pl b/tools/cmspages.pl
new file mode 100755
index 0000000000..314724a594
--- /dev/null
+++ b/tools/cmspages.pl
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Script to manage CMS pages.
+# Copyright (C) 2015 Halland County Library
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+use CGI qw( -utf8 );
+use C4::Auth;
+use C4::Output;
+use C4::Languages qw( getTranslatedLanguages );
+use Koha::Database;
+use Koha::CmsPages;
+
+my $link_self = '/cgi-bin/koha/tools/cmspages.pl';
+
+my $cgi    = new CGI;
+my $op     = scalar $cgi->param( 'op' )     // '';
+my $id     = scalar $cgi->param( 'id' )     // '';
+my $lang   = scalar $cgi->param( 'lang' )   // '';
+my $branch = scalar $cgi->param( 'branch' ) // '';
+my $disp   = scalar $cgi->param( 'disp' )   // '';
+
+my ( $template, $borrowernumber, $cookie ) = get_template_and_user({
+    template_name   => 'tools/cmspages.tt',
+    query           => $cgi,
+    type            => 'intranet',
+    authnotrequired => 0,
+    flagsrequired   => { tools => 'edit_pages' },
+});
+
+# Filter selection
+$template->param(
+    lang   => $lang,
+    branch => $branch,
+    disp   => $disp
+);
+
+my $schema = Koha::Database->new->schema;
+my @branches = $schema->resultset( 'Branch' )->all;
+$template->param( branch_list => @branches );
+
+my $lang_list = getTranslatedLanguages;
+
+# List all pages, if id is set generate parent page list and data.
+my ( $page_list, $parent_list, $page_data ) = Koha::CmsPages->list( $id );
+
+$template->param(
+    page_list_count => scalar $page_list,
+    page_list       => $page_list,
+    parent_list     => $parent_list,
+    data            => $page_data,
+    lang_list       => $lang_list
+);
+
+# Used for adding or editing a page.
+if ( $op eq 'form' ) {
+    $template->param(
+        form => 1,
+        id   => $id,
+        op   => 'add'
+    );
+}
+
+if ( $op eq 'add' ) {
+    Koha::CmsPages->add( $cgi );
+    print $cgi->redirect( $link_self );
+
+} elsif ( $op eq 'del' ) {
+    # param => multi_param; no list-ctx warnings
+    Koha::CmsPages->remove( $cgi->multi_param( 'ids' ) );
+    print $cgi->redirect( $link_self );
+}
+
+$template->param( link_self => $link_self );
+output_html_with_http_headers $cgi, $cookie, $template->output;
-- 
2.20.1