diff --git a/client/themes/tyclipso/components/nav-footer.vue b/client/themes/tyclipso/components/nav-footer.vue
new file mode 100644
index 00000000..08e44fcd
--- /dev/null
+++ b/client/themes/tyclipso/components/nav-footer.vue
@@ -0,0 +1,61 @@
+
+ v-footer.justify-center(:color='bgColor', inset)
+ .caption.grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-1`')
+ template(v-if='company && company.length > 0 && contentLicense !== ``')
+ span(v-if='contentLicense === `alr`') {{ $t('common:footer.copyright', { company: company, year: currentYear, interpolation: { escapeValue: false } }) }} |
+ span(v-else) {{ $t('common:footer.license', { company: company, license: $t('common:license.' + contentLicense), interpolation: { escapeValue: false } }) }} |
+ span {{ $t('common:footer.poweredBy') }} #[a(href='https://wiki.js.org', ref='nofollow') Wiki.js]
+
+
+
+
+
diff --git a/client/themes/tyclipso/components/nav-sidebar.vue b/client/themes/tyclipso/components/nav-sidebar.vue
new file mode 100644
index 00000000..cb5ec0b8
--- /dev/null
+++ b/client/themes/tyclipso/components/nav-sidebar.vue
@@ -0,0 +1,238 @@
+
+ div
+ .pa-3.d-flex(v-if='navMode === `MIXED`', :class='$vuetify.theme.dark ? `grey darken-5` : `blue darken-3`')
+ v-btn(
+ depressed
+ :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`'
+ style='min-width:0;'
+ @click='goHome'
+ :aria-label='$t(`common:header.home`)'
+ )
+ v-icon(size='20') mdi-home
+ v-btn.ml-3(
+ v-if='currentMode === `custom`'
+ depressed
+ :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`'
+ style='flex: 1 1 100%;'
+ @click='switchMode(`browse`)'
+ )
+ v-icon(left) mdi-file-tree
+ .body-2.text-none {{$t('common:sidebar.browse')}}
+ v-btn.ml-3(
+ v-else-if='currentMode === `browse`'
+ depressed
+ :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`'
+ style='flex: 1 1 100%;'
+ @click='switchMode(`custom`)'
+ )
+ v-icon(left) mdi-navigation
+ .body-2.text-none {{$t('common:sidebar.mainMenu')}}
+ v-divider
+ //-> Custom Navigation
+ v-list.py-2(v-if='currentMode === `custom`', dense, :class='color', :dark='dark')
+ template(v-for='item of items')
+ v-list-item(
+ v-if='item.k === `link`'
+ :href='item.t'
+ :target='item.y === `externalblank` ? `_blank` : `_self`'
+ :rel='item.y === `externalblank` ? `noopener` : ``'
+ )
+ v-list-item-avatar(size='24', tile)
+ v-icon(v-if='item.c.match(/fa[a-z] fa-/)', size='19') {{ item.c }}
+ v-icon(v-else) {{ item.c }}
+ v-list-item-title {{ item.l }}
+ v-divider.my-2(v-else-if='item.k === `divider`')
+ v-subheader.pl-4(v-else-if='item.k === `header`') {{ item.l }}
+ //-> Browse
+ v-list.py-2(v-else-if='currentMode === `browse`', dense, :class='color', :dark='dark')
+ template(v-if='currentParent.id > 0')
+ v-list-item(v-for='(item, idx) of parents', :key='`parent-` + item.id', @click='fetchBrowseItems(item)', style='min-height: 30px;')
+ v-list-item-avatar(size='18', :style='`padding-left: ` + (idx * 8) + `px; width: auto; margin: 0 5px 0 0;`')
+ v-icon(small) mdi-folder-open
+ v-list-item-title {{ item.title }}
+ v-divider.mt-2
+ v-list-item.mt-2(v-if='currentParent.pageId > 0', :href='`/` + currentParent.path', :key='`directorypage-` + currentParent.id', :input-value='path === currentParent.path')
+ v-list-item-avatar(size='24')
+ v-icon mdi-text-box
+ v-list-item-title {{ currentParent.title }}
+ v-subheader.pl-4 {{$t('common:sidebar.currentDirectory')}}
+ template(v-for='item of currentItems')
+ v-list-item(v-if='item.isFolder', :key='`childfolder-` + item.id', @click='fetchBrowseItems(item)')
+ v-list-item-avatar(size='24')
+ v-icon mdi-folder
+ v-list-item-title {{ item.title }}
+ v-list-item(v-else, :href='`/` + item.locale + `/` + item.path', :key='`childpage-` + item.id', :input-value='path === item.path')
+ v-list-item-avatar(size='24')
+ v-icon mdi-text-box
+ v-list-item-title {{ item.title }}
+
+
+
diff --git a/client/themes/tyclipso/components/page.vue b/client/themes/tyclipso/components/page.vue
new file mode 100644
index 00000000..8d5b222d
--- /dev/null
+++ b/client/themes/tyclipso/components/page.vue
@@ -0,0 +1,659 @@
+
+ v-app(v-scroll='upBtnScroll', :dark='$vuetify.theme.dark', :class='$vuetify.rtl ? `is-rtl` : `is-ltr`')
+ nav-header(v-if='!printView')
+ v-navigation-drawer(
+ v-if='navMode !== `NONE` && !printView'
+ :class='$vuetify.theme.dark ? `grey darken-4-d4` : `primary`'
+ dark
+ app
+ clipped
+ mobile-breakpoint='600'
+ :temporary='$vuetify.breakpoint.smAndDown'
+ v-model='navShown'
+ :right='$vuetify.rtl'
+ )
+ vue-scroll(:ops='scrollStyle')
+ nav-sidebar(:color='$vuetify.theme.dark ? `grey darken-4-d4` : `primary`', :items='sidebarDecoded', :nav-mode='navMode')
+
+ v-fab-transition(v-if='navMode !== `NONE`')
+ v-btn(
+ fab
+ color='primary'
+ fixed
+ bottom
+ :right='$vuetify.rtl'
+ :left='!$vuetify.rtl'
+ small
+ @click='navShown = !navShown'
+ v-if='$vuetify.breakpoint.mdAndDown'
+ v-show='!navShown'
+ )
+ v-icon mdi-menu
+
+ v-main(ref='content')
+ template(v-if='path !== `home`')
+ v-toolbar(:color='$vuetify.theme.dark ? `grey darken-4-d3` : `grey lighten-3`', flat, dense, v-if='$vuetify.breakpoint.smAndUp')
+ //- v-btn.pl-0(v-if='$vuetify.breakpoint.xsOnly', flat, @click='toggleNavigation')
+ //- v-icon(color='grey darken-2', left) menu
+ //- span Navigation
+ v-breadcrumbs.breadcrumbs-nav.pl-0(
+ :items='breadcrumbs'
+ divider='/'
+ )
+ template(slot='item', slot-scope='props')
+ v-icon(v-if='props.item.path === "/"', small, @click='goHome') mdi-home
+ v-btn.ma-0(v-else, :href='props.item.path', small, text) {{props.item.name}}
+ template(v-if='!isPublished')
+ v-spacer
+ .caption.red--text {{$t('common:page.unpublished')}}
+ status-indicator.ml-3(negative, pulse)
+ v-divider
+ v-container.grey.pa-0(fluid, :class='$vuetify.theme.dark ? `darken-4-l3` : `lighten-4`')
+ v-row(no-gutters, align-content='center', style='height: 90px;')
+ v-col.page-col-content.is-page-header(offset-xl='2', offset-lg='3', style='margin-top: auto; margin-bottom: auto;', :class='$vuetify.rtl ? `pr-4` : `pl-4`')
+ .headline.grey--text(:class='$vuetify.theme.dark ? `text--lighten-2` : `text--darken-3`') {{title}}
+ .caption.grey--text.text--darken-1 {{description}}
+ v-divider
+ v-container.pl-5.pt-4(fluid, grid-list-xl)
+ v-layout(row)
+ v-flex.page-col-sd(lg3, xl2, v-if='$vuetify.breakpoint.lgAndUp')
+ v-card.mb-5(v-if='tocDecoded.length')
+ .overline.pa-5.pb-0(:class='$vuetify.theme.dark ? `blue--text text--lighten-2` : `primary--text`') {{$t('common:page.toc')}}
+ v-list.pb-3(dense, nav, :class='$vuetify.theme.dark ? `darken-3-d3` : ``')
+ template(v-for='(tocItem, tocIdx) in tocDecoded')
+ v-list-item(@click='$vuetify.goTo(tocItem.anchor, scrollOpts)')
+ v-icon(color='grey', small) {{ $vuetify.rtl ? `mdi-chevron-left` : `mdi-chevron-right` }}
+ v-list-item-title.px-3 {{tocItem.title}}
+ //- v-divider(v-if='tocIdx < toc.length - 1 || tocItem.children.length')
+ template(v-for='tocSubItem in tocItem.children')
+ v-list-item(@click='$vuetify.goTo(tocSubItem.anchor, scrollOpts)')
+ v-icon.px-3(color='grey lighten-1', small) {{ $vuetify.rtl ? `mdi-chevron-left` : `mdi-chevron-right` }}
+ v-list-item-title.px-3.caption.grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-1`') {{tocSubItem.title}}
+ //- v-divider(inset, v-if='tocIdx < toc.length - 1')
+
+ v-card.mb-5(v-if='tags.length > 0')
+ .pa-5
+ .overline.teal--text.pb-2(:class='$vuetify.theme.dark ? `text--lighten-3` : ``') {{$t('common:page.tags')}}
+ v-chip.mr-1.mb-1(
+ label
+ :color='$vuetify.theme.dark ? `teal darken-1` : `teal lighten-5`'
+ v-for='(tag, idx) in tags'
+ :href='`/t/` + tag.tag'
+ :key='`tag-` + tag.tag'
+ )
+ v-icon(:color='$vuetify.theme.dark ? `teal lighten-3` : `teal`', left, small) mdi-tag
+ span(:class='$vuetify.theme.dark ? `teal--text text--lighten-5` : `teal--text text--darken-2`') {{tag.title}}
+ v-chip.mr-1.mb-1(
+ label
+ :color='$vuetify.theme.dark ? `teal darken-1` : `teal lighten-5`'
+ :href='`/t/` + tags.map(t => t.tag).join(`/`)'
+ :aria-label='$t(`common:page.tagsMatching`)'
+ )
+ v-icon(:color='$vuetify.theme.dark ? `teal lighten-3` : `teal`', size='20') mdi-tag-multiple
+
+ v-card.mb-5(v-if='commentsEnabled && commentsPerms.read')
+ .pa-5
+ .overline.pb-2.blue-grey--text.d-flex.align-center(:class='$vuetify.theme.dark ? `text--lighten-3` : `text--darken-2`')
+ span {{$t('common:comments.sdTitle')}}
+ //- v-spacer
+ //- v-chip.text-center(
+ //- v-if='!commentsExternal'
+ //- label
+ //- x-small
+ //- :color='$vuetify.theme.dark ? `blue-grey darken-3` : `blue-grey darken-2`'
+ //- dark
+ //- style='min-width: 50px; justify-content: center;'
+ //- )
+ //- span {{commentsCount}}
+ .d-flex
+ v-btn.text-none(
+ @click='goToComments()'
+ :color='$vuetify.theme.dark ? `blue-grey` : `blue-grey darken-2`'
+ outlined
+ style='flex: 1 1 100%;'
+ small
+ )
+ span.blue-grey--text(:class='$vuetify.theme.dark ? `text--lighten-1` : `text--darken-2`') {{$t('common:comments.viewDiscussion')}}
+ v-tooltip(right, v-if='commentsPerms.write')
+ template(v-slot:activator='{ on }')
+ v-btn.ml-2(
+ @click='goToComments(true)'
+ v-on='on'
+ outlined
+ small
+ :color='$vuetify.theme.dark ? `blue-grey` : `blue-grey darken-2`'
+ :aria-label='$t(`common:comments.newComment`)'
+ )
+ v-icon(:color='$vuetify.theme.dark ? `blue-grey lighten-1` : `blue-grey darken-2`', dense) mdi-comment-plus
+ span {{$t('common:comments.newComment')}}
+
+ v-card.mb-5
+ .pa-5
+ .overline.indigo--text.d-flex(:class='$vuetify.theme.dark ? `text--lighten-3` : ``')
+ span {{$t('common:page.lastEditedBy')}}
+ v-spacer
+ v-tooltip(right, v-if='isAuthenticated')
+ template(v-slot:activator='{ on }')
+ v-btn.btn-animate-edit(
+ icon
+ :href='"/h/" + locale + "/" + path'
+ v-on='on'
+ x-small
+ v-if='hasReadHistoryPermission'
+ :aria-label='$t(`common:header.history`)'
+ )
+ v-icon(color='indigo', dense) mdi-history
+ span {{$t('common:header.history')}}
+ .body-2.grey--text(:class='$vuetify.theme.dark ? `` : `text--darken-3`') {{ authorName }}
+ .caption.grey--text.text--darken-1 {{ updatedAt | moment('calendar') }}
+
+ //- v-card.mb-5
+ //- .pa-5
+ //- .overline.pb-2.yellow--text(:class='$vuetify.theme.dark ? `text--darken-3` : `text--darken-4`') Rating
+ //- .text-center
+ //- v-rating(
+ //- v-model='rating'
+ //- color='yellow darken-3'
+ //- background-color='grey lighten-1'
+ //- half-increments
+ //- hover
+ //- )
+ //- .caption.grey--text 5 votes
+
+ v-card(flat)
+ v-toolbar(:color='$vuetify.theme.dark ? `grey darken-4-d3` : `grey lighten-3`', flat, dense)
+ v-spacer
+ v-tooltip(bottom)
+ template(v-slot:activator='{ on }')
+ v-btn(icon, tile, v-on='on', :aria-label='$t(`common:page.bookmark`)'): v-icon(color='grey') mdi-bookmark
+ span {{$t('common:page.bookmark')}}
+ v-menu(offset-y, bottom, min-width='300')
+ template(v-slot:activator='{ on: menu }')
+ v-tooltip(bottom)
+ template(v-slot:activator='{ on: tooltip }')
+ v-btn(icon, tile, v-on='{ ...menu, ...tooltip }', :aria-label='$t(`common:page.share`)'): v-icon(color='grey') mdi-share-variant
+ span {{$t('common:page.share')}}
+ social-sharing(
+ :url='pageUrl'
+ :title='title'
+ :description='description'
+ )
+ v-tooltip(bottom)
+ template(v-slot:activator='{ on }')
+ v-btn(icon, tile, v-on='on', @click='print', :aria-label='$t(`common:page.printFormat`)')
+ v-icon(:color='printView ? `primary` : `grey`') mdi-printer
+ span {{$t('common:page.printFormat')}}
+ v-spacer
+
+ v-flex.page-col-content(xs12, lg9, xl10)
+ v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasAnyPagePermissions')
+ template(v-slot:activator='{ on: onEditActivator }')
+ v-speed-dial(
+ v-model='pageEditFab'
+ direction='top'
+ open-on-hover
+ transition='scale-transition'
+ bottom
+ :right='!$vuetify.rtl'
+ :left='$vuetify.rtl'
+ fixed
+ dark
+ )
+ template(v-slot:activator)
+ v-btn.btn-animate-edit(
+ fab
+ color='primary'
+ v-model='pageEditFab'
+ @click='pageEdit'
+ v-on='onEditActivator'
+ :disabled='!hasWritePagesPermission'
+ :aria-label='$t(`common:page.editPage`)'
+ )
+ v-icon mdi-pencil
+ v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasReadHistoryPermission')
+ template(v-slot:activator='{ on }')
+ v-btn(
+ fab
+ small
+ color='white'
+ light
+ v-on='on'
+ @click='pageHistory'
+ )
+ v-icon(size='20') mdi-history
+ span {{$t('common:header.history')}}
+ v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasReadSourcePermission')
+ template(v-slot:activator='{ on }')
+ v-btn(
+ fab
+ small
+ color='white'
+ light
+ v-on='on'
+ @click='pageSource'
+ )
+ v-icon(size='20') mdi-code-tags
+ span {{$t('common:header.viewSource')}}
+ v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasWritePagesPermission')
+ template(v-slot:activator='{ on }')
+ v-btn(
+ fab
+ small
+ color='white'
+ light
+ v-on='on'
+ @click='pageDuplicate'
+ )
+ v-icon(size='20') mdi-content-duplicate
+ span {{$t('common:header.duplicate')}}
+ v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasManagePagesPermission')
+ template(v-slot:activator='{ on }')
+ v-btn(
+ fab
+ small
+ color='white'
+ light
+ v-on='on'
+ @click='pageMove'
+ )
+ v-icon(size='20') mdi-content-save-move-outline
+ span {{$t('common:header.move')}}
+ v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasDeletePagesPermission')
+ template(v-slot:activator='{ on }')
+ v-btn(
+ fab
+ dark
+ small
+ color='red'
+ v-on='on'
+ @click='pageDelete'
+ )
+ v-icon(size='20') mdi-trash-can-outline
+ span {{$t('common:header.delete')}}
+ span {{$t('common:page.editPage')}}
+ v-alert.mb-5(v-if='!isPublished', color='red', outlined, icon='mdi-minus-circle', dense)
+ .caption {{$t('common:page.unpublishedWarning')}}
+ .contents(ref='container')
+ slot(name='contents')
+ .comments-container#discussion(v-if='commentsEnabled && commentsPerms.read && !printView')
+ .comments-header
+ v-icon.mr-2(dark) mdi-comment-text-outline
+ span {{$t('common:comments.title')}}
+ .comments-main
+ slot(name='comments')
+ nav-footer
+ notify
+ search-results
+ v-fab-transition
+ v-btn(
+ v-if='upBtnShown'
+ fab
+ fixed
+ bottom
+ :right='$vuetify.rtl'
+ :left='!$vuetify.rtl'
+ small
+ :depressed='this.$vuetify.breakpoint.mdAndUp'
+ @click='$vuetify.goTo(0, scrollOpts)'
+ color='primary'
+ dark
+ :style='upBtnPosition'
+ :aria-label='$t(`common:actions.returnToTop`)'
+ )
+ v-icon mdi-arrow-up
+
+
+
+
+
diff --git a/client/themes/tyclipso/components/tabset.vue b/client/themes/tyclipso/components/tabset.vue
new file mode 100644
index 00000000..0b240c70
--- /dev/null
+++ b/client/themes/tyclipso/components/tabset.vue
@@ -0,0 +1,151 @@
+
+ .tabset.elevation-2
+ ul.tabset-tabs(ref='tabs')
+ slot(name='tabs')
+ .tabset-content(ref='content')
+ slot(name='content')
+
+
+
+
+
diff --git a/client/themes/tyclipso/js/app.js b/client/themes/tyclipso/js/app.js
new file mode 100644
index 00000000..34efb224
--- /dev/null
+++ b/client/themes/tyclipso/js/app.js
@@ -0,0 +1 @@
+/* THEME SPECIFIC JAVASCRIPT */
diff --git a/client/themes/tyclipso/scss/app.scss b/client/themes/tyclipso/scss/app.scss
new file mode 100644
index 00000000..f49873b0
--- /dev/null
+++ b/client/themes/tyclipso/scss/app.scss
@@ -0,0 +1,1005 @@
+/* THEME SPECIFIC STYLES */
+
+.v-main .contents {
+ color: mc('grey', '800');
+ padding: .5rem 0 50px;
+ position: relative;
+
+ > div > *:first-child {
+ margin-top: 0;
+ }
+
+ @at-root .theme--dark & {
+ color: mc('grey', '300');
+ }
+
+ // ---------------------------------
+ // LINKS
+ // ---------------------------------
+
+ a {
+ color: mc('blue', '700');
+
+ &.is-internal-link.is-invalid-page {
+ color: mc('red', '700');
+
+ @at-root .theme--dark & {
+ color: mc('red', '200');
+ }
+ }
+
+ &.is-external-link {
+ padding-right: 3px;
+
+ &::after {
+ font-family: 'Material Design Icons', sans-serif;
+ font-size: 24px/1;
+ padding-left: 3px;
+ display: inline-block;
+ content: '\F03CC';
+ color: mc('grey', '500');
+ text-decoration: none;
+ }
+ }
+
+ @at-root .theme--dark & {
+ color: mc('blue', '200');
+ }
+ }
+
+ // ---------------------------------
+ // HEADERS
+ // ---------------------------------
+
+ h1, h2, h3, h4, h5, h6 {
+ position: relative;
+
+ &:first-child {
+ padding-top: 0;
+ }
+
+ &:hover {
+ .toc-anchor {
+ display: block;
+ }
+ }
+
+ .toc-anchor {
+ display: none;
+ position: absolute;
+ right: 1rem;
+ bottom: .5rem;
+ font-size: 1.25rem;
+ text-decoration: none;
+ color: mc('grey', '500');
+ }
+
+ & + h2, & + h3, & + h4, & + h5, & + h6 {
+ margin-top: 8px;
+ }
+ }
+
+ h1 {
+ padding: 0;
+ color: mc('blue', '800');
+ margin-top: 2rem;
+ position: relative;
+
+ @at-root .theme--dark & {
+ color: mc('grey', '300');
+ }
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 2px;
+ background: linear-gradient(to right, mc('theme', 'primary'), rgba(mc('theme', 'primary'), 0));
+ border-radius: 3px;
+
+ @at-root .theme--dark & {
+ background: linear-gradient(to right, mc('blue', '300') 0%, mc('blue', '500') 10%, rgba(mc('blue', '900'), 0) 100%);
+ }
+
+ @at-root .is-rtl & {
+ background: linear-gradient(to left, mc('theme', 'primary'), rgba(mc('theme', 'primary'), 0));
+ }
+ @at-root .theme--dark.is-rtl & {
+ background: linear-gradient(to left, mc('grey', '600'), rgba(mc('grey', '600'), 0));
+ }
+ }
+ }
+ h2 {
+ margin: 1rem 0 0 0;
+ color: mc('grey', '800');
+ position: relative;
+
+ @at-root .theme--dark & {
+ color: mc('grey', '400');
+ }
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 1px;
+ background: linear-gradient(to right, mc('grey', '700'), rgba(mc('grey', '700'), 0));
+
+ @at-root .theme--dark & {
+ background: linear-gradient(to right, mc('grey', '300'), rgba(mc('grey', '700'), 0));
+ }
+
+ @at-root .is-rtl & {
+ background: linear-gradient(to left, mc('grey', '700'), rgba(mc('grey', '700'), 0));
+ }
+ @at-root .theme--dark.is-rtl & {
+ background: linear-gradient(to left, mc('grey', '300'), rgba(mc('grey', '700'), 0));
+ }
+ }
+ }
+ h3 {
+ margin: 8px 0 0 0;
+ color: mc('grey', '700');
+ position: relative;
+
+ @at-root .theme--dark & {
+ color: mc('grey', '600');
+ }
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 1px;
+ background: linear-gradient(to right, mc('grey', '500'), rgba(mc('grey', '500'), 0) 90%);
+ }
+ }
+ h4, h5, h6 {
+ font-size: 1rem;
+ margin: 8px 0 0 0;
+ color: mc('grey', '700');
+ position: relative;
+
+ @at-root .theme--dark & {
+ color: mc('grey', '600');
+ }
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 1px;
+ background: linear-gradient(to right, mc('grey', '500'), rgba(mc('grey', '500'), 0) 70%);
+ }
+ }
+ h5 {
+ &::after {
+ background: linear-gradient(to right, mc('grey', '500'), rgba(mc('grey', '500'), 0) 50%);
+ }
+ }
+ h6 {
+ &::after {
+ background: linear-gradient(to right, mc('grey', '500'), rgba(mc('grey', '500'), 0) 30%);
+ }
+ }
+
+ // ---------------------------------
+ // PARAGRAPHS
+ // ---------------------------------
+
+ p {
+ padding: 1rem 0 0 0;
+ margin: 0;
+
+ @at-root .contents > div > p:first-child {
+ padding-top: 0;
+ }
+
+ @at-root .v-application & {
+ margin-bottom: 0;
+ }
+ }
+
+ hr {
+ margin: 1rem 0;
+ height: 1px;
+ border: none;
+ background-color: mc('grey', '400');
+
+ @at-root .theme--dark & {
+ background-color: mc('grey', '700');
+ }
+ }
+
+ .emoji {
+ height: 1.25em;
+ margin: 0 1px -4px;
+ }
+
+ blockquote {
+ padding: 0 1rem 1rem 1rem;
+ background-color: mc('blue-grey', '50');
+ border-left: 55px solid mc('blue-grey', '500');
+ border-radius: .5rem;
+ margin: 1rem 0;
+ position: relative;
+
+ @at-root .theme--dark & {
+ background-color: mc('blue-grey', '900');
+ }
+
+ &::before {
+ display: inline-block;
+ font: normal normal normal 24px/1 "Material Design Icons", sans-serif;
+ position: absolute;
+ margin-top: -12px;
+ top: 50%;
+ left: -38px;
+ color: rgba(255, 255, 255, .7);
+ content: "\F0757";
+ }
+
+ > p:first-child .emoji {
+ margin-right: .5rem;
+ }
+
+ &.valign-center > p {
+ display: flex;
+ align-items: center;
+ }
+
+ &.is-info {
+ background-color: mc('blue', '50');
+ border-color: mc('blue', '300');
+ color: mc('blue', '900');
+
+ &::before {
+ content: "\F02FC";
+ }
+
+ code {
+ background-color: mc('blue', '50');
+ color: mc('blue', '800');
+ }
+
+ @at-root .theme--dark & {
+ background-color: mc('blue', '900');
+ color: mc('blue', '50');
+ border-color: mc('blue', '500');
+ }
+ }
+ &.is-warning {
+ background-color: mc('orange', '50');
+ border-color: mc('orange', '300');
+ color: darken(mc('orange', '900'), 10%);
+
+ &::before {
+ content: "\F0026";
+ }
+
+ code {
+ background-color: mc('orange', '50');
+ color: mc('orange', '800');
+ }
+
+ @at-root .theme--dark & {
+ background-color: darken(mc('orange', '900'), 5%);
+ color: mc('orange', '100');
+ border-color: mc('orange', '500');
+ box-shadow: 0 0 2px 0 mc('grey', '900');
+ }
+ }
+ &.is-danger {
+ background-color: mc('red', '50');
+ border-color: mc('red', '300');
+ color: mc('red', '900');
+
+ &::before {
+ content: "\F0159";
+ }
+
+ code {
+ background-color: mc('red', '50');
+ color: mc('red', '800');
+ }
+
+ @at-root .theme--dark & {
+ background-color: mc('red', '900');
+ color: mc('red', '100');
+ border-color: mc('red', '500');
+ }
+ }
+ &.is-success {
+ background-color: mc('green', '50');
+ border-color: mc('green', '300');
+ color: mc('green', '900');
+
+ &::before {
+ content: "\F0E1E";
+ }
+
+ code {
+ background-color: mc('green', '50');
+ color: mc('green', '800');
+ }
+
+ @at-root .theme--dark & {
+ background-color: mc('green', '900');
+ color: mc('green', '50');
+ border-color: mc('green', '500');
+ }
+ }
+ }
+
+ // ---------------------------------
+ // LISTS
+ // ---------------------------------
+
+ ol, ul:not(.tabset-tabs) {
+ padding-top: 1rem;
+ width: 100%;
+
+ @at-root .is-rtl & {
+ padding-left: 0;
+ padding-right: 1rem;
+ }
+
+ li > ul, li > ol {
+ padding-top: .5rem;
+ padding-left: 1rem;
+
+ @at-root .is-rtl & {
+ padding-left: 0;
+ padding-right: 1rem;
+ }
+ }
+
+ li + li {
+ margin-top: .5rem;
+ }
+
+ &.links-list {
+ padding-left: 0;
+ list-style-type: none;
+
+ @at-root .is-rtl & {
+ padding-right: 0;
+ }
+
+ li {
+ background-color: mc('grey', '50');
+ background-image: linear-gradient(to bottom, #FFF, mc('grey', '50'));
+ border-right: 1px solid mc('grey', '200');
+ border-bottom: 1px solid mc('grey', '200');
+ border-left: 5px solid mc('grey', '300');
+ box-shadow: 0 3px 8px 0 rgba(116, 129, 141, 0.1);
+ padding: 1rem;
+ border-radius: 5px;
+ font-weight: 500;
+
+ @at-root .is-rtl & {
+ border-left-width: 1px;
+ border-right-width: 5px;
+ }
+
+ &:hover {
+ background-image: linear-gradient(to bottom, #FFF, lighten(mc('blue', '50'), 4%));
+ border-left-color: mc('blue', '500');
+ cursor: pointer;
+
+ @at-root .is-rtl & {
+ border-left-color: mc('grey', '200');
+ border-right-width: mc('blue', '500');
+ }
+ }
+
+ &::before {
+ content: '';
+ display: none;
+ }
+
+ > a {
+ display: block;
+ text-decoration: none;
+ margin: -1rem;
+ padding: 1rem;
+
+ > em {
+ font-weight: 400;
+ font-style: normal;
+ color: mc('grey', '700');
+ display: inline-block;
+ padding-left: .5rem;
+ border-left: 1px solid mc('grey', '300');
+ margin-left: .5rem;
+
+ &.is-block {
+ display: block;
+ padding-left: 0;
+ margin-left: 0;
+ border-left: none;
+ }
+ }
+ }
+
+ > em {
+ font-weight: 400;
+ font-style: normal;
+ }
+
+ @at-root .theme--dark & {
+ background-color: mc('grey', '50');
+ background-image: linear-gradient(to bottom, lighten(mc('grey', '900'), 5%), mc('grey', '900'));
+ border-right: 1px solid mc('grey', '900');
+ border-bottom: 1px solid mc('grey', '900');
+ border-left: 5px solid mc('grey', '700');
+ box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.1);
+
+ @at-root .theme--dark.is-rtl & {
+ border-left-width: 1px;
+ border-right-width: 5px;
+ }
+
+ &:hover {
+ background-image: linear-gradient(to bottom, lighten(mc('grey', '900'), 2%), darken(mc('grey', '900'), 3%));
+ border-left-color: mc('indigo', '300');
+ cursor: pointer;
+
+ @at-root .theme--dark.is-rtl & {
+ border-left-color: mc('grey', '900');
+ border-right-width: mc('indigo', '300');
+ }
+ }
+ }
+ }
+ }
+
+ &.grid-list {
+ margin: 1rem 0 0 0;
+ background-color: #FFF;
+ border: 1px solid mc('grey', '200');
+ padding: 1px;
+ display: inline-block;
+ list-style-type: none;
+
+ @at-root .theme--dark & {
+ background-color: #000;
+ border: 1px solid mc('grey', '800');
+ }
+
+ li {
+ background-color: mc('grey', '50');
+ padding: .6rem 1rem;
+ display: block;
+
+ &:nth-child(odd) {
+ background-color: mc('grey', '100');
+ }
+
+ & + li {
+ margin-top: 0;
+ }
+
+ &::before {
+ content: '';
+ display: none;
+ }
+
+ @at-root .theme--dark & {
+ background-color: mc('grey', '900');
+
+ &:nth-child(odd) {
+ background-color: darken(mc('grey', '900'), 5%);
+ }
+ }
+ }
+ }
+ }
+
+ ul:not(.tabset-tabs) {
+ list-style: none;
+ > li::before {
+ position: absolute;
+ left: -1.1rem;
+ content: '\25b8';
+ color: mc('grey', '600');
+ width: 1.35rem;
+
+ @at-root .is-rtl & {
+ right: -1.1rem;
+ content: '\25C3';
+ }
+ }
+ }
+ ol, ul:not(.tabset-tabs) {
+ > li {
+ position: relative;
+ > p {
+ display:inline-block;
+ vertical-align:top;
+ padding-top:0;
+ }
+ }
+ }
+
+ // ---------------------------------
+ // CODE
+ // ---------------------------------
+
+ code {
+ background-color: mc('indigo', '50');
+ padding: 0 5px;
+ color: mc('indigo', '800');
+ font-family: 'Roboto Mono', monospace;
+ font-weight: normal;
+ font-size: 1rem;
+ box-shadow: none;
+
+ &::before, &::after {
+ display: none;
+ }
+
+ @at-root .theme--dark & {
+ background-color: darken(mc('grey', '900'), 5%);
+ color: mc('indigo', '100');
+ }
+ }
+
+ .prismjs{
+ border: none;
+ border-radius: 5px;
+ box-shadow: initial;
+ background-color: mc('grey', '900');
+ padding: 1rem 1rem 1rem 3rem;
+ margin: 1rem 0;
+
+ @at-root .theme--dark & {
+ background-color: darken(mc('grey', '900'), 5%);
+ }
+
+ > code {
+ background-color: transparent;
+ padding: 0;
+ color: #FFF;
+ box-shadow: initial;
+ display: block;
+ font-size: .85rem;
+ font-family: 'Roboto Mono', monospace;
+
+ &:after, &:before {
+ content: initial;
+ letter-spacing: initial;
+ }
+ }
+ }
+
+ .diagram {
+ margin-top: 1rem;
+ svg:first-child {
+ direction: ltr;
+ }
+ }
+
+ // ---------------------------------
+ // TASK LISTS
+ // ---------------------------------
+
+ .task-list-item {
+ position: relative;
+ list-style-type: none;
+
+ &-checkbox[disabled] {
+ display: none;
+
+ & + label {
+ padding-left: 1.5rem;
+ }
+
+ & + label::before {
+ position: absolute;
+ left: 0;
+ top: 2px;
+ content: ' ';
+ display: block;
+ width: 1.1rem;
+ height: 1.1rem;
+ background-color: #FFF;
+ border: 1px solid mc('grey', '400');
+ border-radius: 2px;
+ font-weight: bold;
+ font-size: .8rem;
+ line-height: 1rem;
+ text-align: center;
+
+ @at-root .theme--dark & {
+ background-color: mc('grey', '900');
+ border-color: mc('grey', '700');
+ }
+ }
+
+ &[checked] + label::before {
+ content: '✓';
+ }
+ }
+
+ .contains-task-list {
+ padding: .5rem 0 0 1.5rem;
+ }
+ }
+
+ // ---------------------------------
+ // TABLES
+ // ---------------------------------
+
+ table {
+ margin: .5rem 1.75rem;
+ border-spacing: 0;
+
+ th {
+ padding: .75rem;
+ border-bottom: 2px solid mc('grey', '500');
+ color: mc('grey', '600');
+ }
+
+ td {
+ padding: .75rem;
+ }
+
+ tr {
+ td {
+ border-bottom: 1px solid mc('grey', '200');
+ }
+ }
+ }
+
+ figure.table {
+ margin: 0;
+
+ > table {
+ background-color: #FFF;
+ margin: 0;
+ border-collapse: collapse;
+ box-shadow: 0 0 5px 0 rgba(0, 0, 0, .07);
+
+ @at-root .theme--dark & {
+ background-color: darken(mc('grey', '900'), 3%);
+ }
+
+ td, th {
+ border: 1px solid mc('blue-grey', '100');
+ box-shadow: inset -1px -1px 0 0 #FFF, inset 1px 0 0 #FFF;
+ padding: .5rem .75rem;
+
+ @at-root .theme--dark & {
+ border-color: mc('grey', '700');
+ box-shadow: inset -1px -1px 0 0 rgba(0,0,0, .5);
+ }
+ }
+
+ th {
+ background-color: lighten(mc('blue-grey', '50'), 1%);
+ font-weight: 700;
+ color: mc('blue-grey', '700');
+
+ @at-root .theme--dark & {
+ background-color: mc('grey', '800');
+ color: mc('grey', '400');
+ }
+ }
+
+ thead th {
+ border-bottom: 2px solid mc('blue-grey', '100');
+
+ @at-root .theme--dark & {
+ border-bottom: none;
+ }
+ }
+
+ tbody th {
+ background-color: lighten(mc('blue-grey', '50'), 4%);
+
+ @at-root .theme--dark & {
+ background-color: darken(mc('grey', '800'), 8%);
+ }
+ }
+ }
+ }
+
+ // ---------------------------------
+ // IMAGES
+ // ---------------------------------
+
+ img {
+ max-width: 100%;
+
+ &.align-left {
+ float: left;
+ margin: 0 1rem 1rem 0;
+ }
+ &.align-right {
+ float: right;
+ margin: 0 0 1rem 1rem;
+ z-index: 1;
+ position: relative;
+ }
+ &.align-center {
+ display: block;
+ max-width: 100%;
+ margin: auto;
+ }
+ &.align-abstopright {
+ position: absolute;
+ top: -90px;
+ right: 1rem;
+ height: calc(90px - 32px);
+ width: auto;
+
+ @at-root .is-rtl & {
+ left: 1rem;
+ right: initial;
+ }
+ }
+ &.decor-shadow {
+ box-shadow: 0 3px 8px 0 rgba(116, 129, 141, 0.1);
+ }
+ &.decor-outline {
+ border: 1px solid mc('grey', '400');
+ }
+ &.uml-diagram {
+ margin: 1rem 0;
+ }
+ }
+
+ figure.image {
+ margin: 1rem 0 0 0;
+
+ img {
+ margin: 0 auto;
+ }
+ figcaption {
+ padding: 4px 1rem;
+ text-align: center;
+ font-size: 12px;
+ color: mc('grey', '700');
+ background-color: mc('grey', '100');
+
+ @at-root .theme--dark & {
+ color: mc('grey', '400');
+ background-color: mc('grey', '800');
+ }
+ }
+ }
+
+ figure.image-style-align-right {
+ float: right;
+ }
+
+ figure.image-style-align-left {
+ float: left;
+ }
+
+ // ---------------------------------
+ // DETAILS
+ // ---------------------------------
+
+ details {
+ background-color: mc('grey', '50');
+ margin: 1rem 2rem;
+ border: 1px solid mc('grey', '300');
+ border-radius: 7px;
+
+ > p {
+ padding-left: 0;
+ }
+
+ summary {
+ border-radius: 7px;
+ background-color: mc('grey', '50');
+ cursor: pointer;
+ height: 40px;
+ display: flex;
+ align-items: center;
+ padding: 0 1rem;
+ transition: background-color .4s ease;
+
+ &:focus {
+ outline: none;
+ background-color: mc('grey', '100');
+ }
+ }
+
+ &[open] {
+ padding: 1rem;
+
+ summary {
+ background-color: mc('grey', '100');
+ border-bottom: 1px solid mc('grey', '300');
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ margin: -1rem -1rem 1rem -1rem;
+ }
+ }
+
+ @at-root .theme--dark & {
+ background-color: mc('grey', '900');
+ border-color: mc('grey', '700');
+
+ summary {
+ background-color: mc('grey', '900');
+ border-color: mc('grey', '700');
+ }
+
+ &[open] summary {
+ background-color: lighten(mc('grey', '900'), 5%);
+ }
+ }
+
+ }
+
+ // ---------------------------------
+ // HIGHLIGHTING
+ // ---------------------------------
+
+ mark {
+ &.pen-red {
+ color: mc('red', '500');
+ background-color: initial;
+ }
+ &.pen-green {
+ color: mc('green', '500');
+ background-color: initial;
+ }
+ &.marker-blue {
+ background-color: mc('blue', '300');
+ }
+ &.marker-yellow {
+ background-color: mc('yellow', '300');
+ }
+ &.marker-pink {
+ background-color: mc('pink', '300');
+ }
+ &.marker-green {
+ background-color: mc('green', '300');
+ }
+ }
+
+ .mention {
+ background-color: rgba(153, 0, 48, .1);
+ color: #990030;
+
+ @at-root .theme--dark & {
+ color: mc('pink', '500');
+ }
+ }
+
+}
+
+// ---------------------------------
+// COMMENTS
+// ---------------------------------
+
+.comments {
+ &-container {
+ border-radius: 7px;
+ }
+
+ &-header {
+ color: #FFF;
+ padding: 8px 20px;
+ font-size: 16px;
+ font-weight: 500;
+ background-color: mc('blue-grey', '500');
+ border-radius: 7px 7px 0 0;
+
+ @at-root .theme--dark & {
+ background-color: lighten(mc('blue-grey', '900'), 5%);
+ }
+ }
+
+ &-main {
+ background-color: mc('blue-grey', '50');
+ border-radius: 0 0 7px 7px;
+ padding: 20px;
+
+ @at-root .theme--dark & {
+ background-color: darken(mc('grey', '900'), 5%);
+ }
+ }
+}
+
+// ---------------
+// RTL FIXES
+// Vuetify GH Issue: https://github.com/vuetifyjs/vuetify/issues/6317
+// ---------------
+
+.is-rtl {
+ .page-col-content.is-page-header {
+ @each $size, $width in $grid-breakpoints {
+ @media (min-width: $width) {
+ @for $n from 0 through 12 {
+ &.offset-#{$size}-#{$n} {
+ margin-left: 0;
+ margin-right: ($n / 12 * 100) * 1%;
+ }
+ }
+ }
+ }
+ }
+}
+
+// ---------------
+// PRINT OVERRIDES
+// ---------------
+
+@media print {
+ .nav-header,
+ .v-navigation-drawer,
+ .v-btn--fab,
+ .page-col-sd,
+ .v-tooltip__content
+ {
+ display: none !important;
+ }
+
+ .layout {
+ display: block !important;
+ }
+
+ .page-col-content {
+ flex-basis: 100% !important;
+ flex-grow: 1 !important;
+ max-width: 100% !important;
+ margin-left: 0 !important;
+
+ > .v-toolbar {
+ border: 1px solid mc('grey', '300') !important;
+ border-radius: 7px !important;
+
+ & + .v-divider {
+ display: none !important;
+ }
+ }
+ }
+
+ .v-main {
+ padding: 0 !important;
+ font-size: 14px;
+ background-color: #FFF;
+ }
+
+ .v-main .contents {
+ color: #000;
+ background-color: #FFF;
+
+ @at-root .theme--dark & {
+ color: #000;
+ }
+
+ .prismjs{
+ box-shadow: none;
+ background-color: #FFF;
+
+ @at-root .theme--dark & {
+ background-color: #FFF;
+ }
+
+ > code {
+ color: #000;
+ box-shadow: none;
+ text-shadow: none;
+ }
+ }
+ }
+
+ .comments-container {
+ display: none;
+ }
+}
diff --git a/client/themes/tyclipso/theme.yml b/client/themes/tyclipso/theme.yml
new file mode 100644
index 00000000..7f3f42d4
--- /dev/null
+++ b/client/themes/tyclipso/theme.yml
@@ -0,0 +1,51 @@
+name: Tyclipso
+author: Carl Richter | Tyclipso GmbH
+site: https://tyclipso.net/
+version: 1.0.0
+requirements:
+ minimum: '>= 2.0.0'
+ maximum: '< 3.0.0'
+props:
+ sdPosition:
+ type: String
+ default: 'left'
+ title: Table of Contents Position
+ hint: Should the content sidebar be shown on the left or right.
+ enum:
+ - 'hidden'
+ - 'left'
+ - 'right'
+ order: 1
+ icon: mdi-border-vertical
+ showTOC:
+ type: Boolean
+ default: true
+ title: Display the Table of Contents
+ order: 2
+ showTags:
+ type: Boolean
+ default: true
+ title: Display the Page Tags
+ order: 3
+ showTags:
+ type: Boolean
+ default: true
+ title: Display the Page Author and Date
+ order: 4
+ showTags:
+ type: Boolean
+ default: true
+ title: Display the Page Rating
+ order: 5
+ showSocialBar:
+ type: Boolean
+ default: true
+ title: Display the Social Links Bar
+ order: 6
+ showEditSpeedDial:
+ type: Boolean
+ default: true
+ title: Display the Edit Speed Dial
+ hint: Shown in the lower right corner of the page.
+ order: 7
+
diff --git a/client/themes/tyclipso/thumbnail.png b/client/themes/tyclipso/thumbnail.png
new file mode 100644
index 00000000..489e3f83
Binary files /dev/null and b/client/themes/tyclipso/thumbnail.png differ