, or .
+
+.list-group {
+ padding-right: 0; // reset padding because ul and ol
+ padding-left: initial;
+}
+
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/media-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/media-rtl.less
new file mode 100644
index 0000000000..9dd84247ff
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/media-rtl.less
@@ -0,0 +1,47 @@
+// RTL Media objects
+// --------------------------------------------------
+
+
+// Media image alignment
+// -------------------------
+
+.media {
+ > .pull-left {
+ margin-right: 10px;
+ &.flip {
+ margin-right: 0;
+ margin-left: 10px;
+ }
+ }
+ > .pull-right {
+ margin-left: 10px;
+ &.flip {
+ margin-left: 0;
+ margin-right: 10px;
+ }
+ }
+}
+
+.media-right,
+.media > .pull-right {
+ padding-right: 10px;
+ padding-left: initial;
+}
+
+.media-left,
+.media > .pull-left {
+ padding-left: 10px;
+ padding-right: initial;
+}
+
+
+// Media list variation
+// -------------------------
+
+// Undo default ul/ol styles
+.media-list {
+ padding-right: 0;
+ padding-left: initial;
+ list-style: none;
+}
+
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/mixins-flipped.less b/frontend/less/espo-rtl/bootstrap-rtl/mixins-flipped.less
new file mode 100644
index 0000000000..8c5d1e715f
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/mixins-flipped.less
@@ -0,0 +1,39 @@
+// Mixins
+// --------------------------------------------------
+
+// Utilities
+@import "../bootstrap/less/mixins/hide-text.less";
+@import "../bootstrap/less/mixins/opacity.less";
+@import "../bootstrap/less/mixins/image.less";
+@import "../bootstrap/less/mixins/labels.less";
+@import "../bootstrap/less/mixins/reset-filter.less";
+@import "../bootstrap/less/mixins/resize.less";
+@import "../bootstrap/less/mixins/responsive-visibility.less";
+@import "../bootstrap/less/mixins/size.less";
+@import "../bootstrap/less/mixins/tab-focus.less";
+@import "../bootstrap/less/mixins/text-emphasis.less";
+@import "../bootstrap/less/mixins/text-overflow.less";
+@import "../bootstrap/less/mixins/vendor-prefixes.less";
+
+// Components
+@import "../bootstrap/less/mixins/alerts.less";
+@import "../bootstrap/less/mixins/buttons.less";
+@import "../bootstrap/less/mixins/panels.less";
+@import "mixins/pagination-rtl.less"; // RTL
+@import "../bootstrap/less/mixins/list-group.less";
+@import "../bootstrap/less/mixins/nav-divider.less";
+@import "../bootstrap/less/mixins/forms.less";
+@import "../bootstrap/less/mixins/progress-bar.less";
+@import "../bootstrap/less/mixins/table-row.less";
+
+// Skins
+@import "../bootstrap/less/mixins/background-variant.less";
+@import "mixins/border-radius-flipped.less"; //FLIPPED
+@import "mixins/gradients-rtl.less"; // RTL
+
+// Layout
+@import "../bootstrap/less/mixins/clearfix.less";
+@import "../bootstrap/less/mixins/center-block.less";
+@import "../bootstrap/less/mixins/nav-vertical-align.less";
+@import "mixins/grid-framework-rtl.less"; // RTL
+@import "mixins/grid-rtl.less"; // RTL
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/mixins-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/mixins-rtl.less
new file mode 100644
index 0000000000..e8c121ba2d
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/mixins-rtl.less
@@ -0,0 +1,39 @@
+// Mixins
+// --------------------------------------------------
+
+// Utilities
+@import "../../espo/bootstrap/mixins/hide-text.less";
+@import "../../espo/bootstrap/mixins/opacity.less";
+@import "../../espo/bootstrap/mixins/image.less";
+@import "../../espo/bootstrap/mixins/labels.less";
+@import "../../espo/bootstrap/mixins/reset-filter.less";
+@import "../../espo/bootstrap/mixins/resize.less";
+@import "../../espo/bootstrap/mixins/responsive-visibility.less";
+@import "../../espo/bootstrap/mixins/size.less";
+@import "../../espo/bootstrap/mixins/tab-focus.less";
+@import "../../espo/bootstrap/mixins/text-emphasis.less";
+@import "../../espo/bootstrap/mixins/text-overflow.less";
+@import "../../espo/bootstrap/mixins/vendor-prefixes.less";
+
+// Components
+@import "../../espo/bootstrap/mixins/alerts.less";
+@import "../../espo/bootstrap/mixins/buttons.less";
+@import "../../espo/bootstrap/mixins/panels.less";
+@import "mixins/pagination-rtl.less"; // RTL
+@import "../../espo/bootstrap/mixins/list-group.less";
+@import "../../espo/bootstrap/mixins/nav-divider.less";
+@import "../../espo/bootstrap/mixins/forms.less";
+@import "../../espo/bootstrap/mixins/progress-bar.less";
+@import "../../espo/bootstrap/mixins/table-row.less";
+
+// Skins
+@import "../../espo/bootstrap/mixins/background-variant.less";
+@import "../../espo/bootstrap/mixins/border-radius.less";
+@import "mixins/gradients-rtl.less"; // RTL
+
+// Layout
+@import "../../espo/bootstrap/mixins/clearfix.less";
+@import "../../espo/bootstrap/mixins/center-block.less";
+@import "../../espo/bootstrap/mixins/nav-vertical-align.less";
+@import "mixins/grid-framework-rtl.less"; // RTL
+@import "mixins/grid-rtl.less"; // RTL
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/mixins/border-radius-flipped.less b/frontend/less/espo-rtl/bootstrap-rtl/mixins/border-radius-flipped.less
new file mode 100644
index 0000000000..bddaeca3b8
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/mixins/border-radius-flipped.less
@@ -0,0 +1,10 @@
+// Single side flipped border-radius
+
+.border-right-radius(@radius) {
+ border-bottom-left-radius: @radius;
+ border-top-left-radius: @radius;
+}
+.border-left-radius(@radius) {
+ border-bottom-right-radius: @radius;
+ border-top-right-radius: @radius;
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/mixins/gradients-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/mixins/gradients-rtl.less
new file mode 100644
index 0000000000..3a69ad9797
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/mixins/gradients-rtl.less
@@ -0,0 +1,24 @@
+// RTL Gradients
+
+#gradient {
+
+ // Horizontal gradient, from right to left
+ //
+ // Creates two color stops, start and end, by specifying a color and position for each color stop.
+ // Color stops are not available in IE9 and below.
+ .horizontal(@start-color: #333; @end-color: #555; @start-percent: 0%; @end-percent: 100%) {
+ background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+
+ background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12
+ background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
+ background-repeat: repeat-x;
+ filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down
+ }
+
+ .horizontal-three-colors(@start-color: #c3325f; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #00b3ee) {
+ background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
+ background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
+ background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
+ background-repeat: no-repeat;
+ filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/mixins/grid-framework-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/mixins/grid-framework-rtl.less
new file mode 100644
index 0000000000..fd736be24c
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/mixins/grid-framework-rtl.less
@@ -0,0 +1,96 @@
+// RTL Framework grid generation
+//
+// Used only by Bootstrap to generate the correct number of grid classes given
+// any value of `@grid-columns`.
+
+.make-rtl-grid-columns() {
+ // Common styles for all sizes of grid columns, widths 1-12
+ .col(@index) { // initial
+ @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
+ .col((@index + 1), @item);
+ }
+ .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
+ @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
+ .col((@index + 1), ~"@{list}, @{item}");
+ }
+ .col(@index, @list) when (@index > @grid-columns) { // terminal
+ @{list} {
+ position: relative;
+ // Prevent columns from collapsing when empty
+ min-height: 1px;
+ // Inner gutter via padding
+ padding-left: (@grid-gutter-width / 2);
+ padding-right: (@grid-gutter-width / 2);
+ }
+ }
+ .col(1); // kickstart it
+}
+
+.float-rtl-grid-columns(@class) {
+ .col(@index) { // initial
+ @item: ~".col-@{class}-@{index}";
+ .col((@index + 1), @item);
+ }
+ .col(@index, @list) when (@index =< @grid-columns) { // general
+ @item: ~".col-@{class}-@{index}";
+ .col((@index + 1), ~"@{list}, @{item}");
+ }
+ .col(@index, @list) when (@index > @grid-columns) { // terminal
+ @{list} {
+ float: right;
+ }
+ }
+ .col(1); // kickstart it
+}
+
+.calc-rtl-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
+ .col-@{class}-@{index} {
+ width: percentage((@index / @grid-columns));
+ }
+}
+.calc-rtl-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {
+ .col-@{class}-push-@{index} {
+ right: percentage((@index / @grid-columns));
+ left: 0;
+ }
+}
+.calc-rtl-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {
+ .col-@{class}-push-0 {
+ right: auto;
+ left: 0;
+ }
+}
+.calc-rtl-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {
+ .col-@{class}-pull-@{index} {
+ left: percentage((@index / @grid-columns));
+ right: auto;
+ }
+}
+.calc-rtl-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {
+ .col-@{class}-pull-0 {
+ left: auto;
+ right: auto;
+ }
+}
+.calc-rtl-grid-column(@index, @class, @type) when (@type = offset) {
+ .col-@{class}-offset-@{index} {
+ margin-right: percentage((@index / @grid-columns));
+ margin-left: 0;
+ }
+}
+
+// Basic looping in LESS
+.loop-rtl-grid-columns(@index, @class, @type) when (@index >= 0) {
+ .calc-rtl-grid-column(@index, @class, @type);
+ // next iteration
+ .loop-rtl-grid-columns((@index - 1), @class, @type);
+}
+
+// Create grid for specific class
+.make-rtl-grid(@class) {
+ .float-rtl-grid-columns(@class);
+ .loop-rtl-grid-columns(@grid-columns, @class, width);
+ .loop-rtl-grid-columns(@grid-columns, @class, pull);
+ .loop-rtl-grid-columns(@grid-columns, @class, push);
+ .loop-rtl-grid-columns(@grid-columns, @class, offset);
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/mixins/grid-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/mixins/grid-rtl.less
new file mode 100644
index 0000000000..f6e186983e
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/mixins/grid-rtl.less
@@ -0,0 +1,98 @@
+// RTL Grid system
+//
+// Generate semantic rtl grid columns with these mixins.
+
+// Generate the extra small columns
+.make-xs-column(@columns; @gutter: @grid-gutter-width) {
+ float: right;
+}
+.make-xs-column-offset(@columns) {
+ margin-right: percentage((@columns / @grid-columns));
+ margin-left: 0;
+}
+.make-xs-column-push(@columns) {
+ right: percentage((@columns / @grid-columns));
+ left: auto;
+}
+.make-xs-column-pull(@columns) {
+ left: percentage((@columns / @grid-columns));
+ right: auto;
+}
+
+// Generate the small columns
+.make-sm-column(@columns; @gutter: @grid-gutter-width) {
+
+ @media (min-width: @screen-sm-min) {
+ float: right;
+ }
+}
+.make-sm-column-offset(@columns) {
+ @media (min-width: @screen-sm-min) {
+ margin-right: percentage((@columns / @grid-columns));
+ margin-left: 0;
+ }
+}
+.make-sm-column-push(@columns) {
+ @media (min-width: @screen-sm-min) {
+ right: percentage((@columns / @grid-columns));
+ left: auto;
+ }
+}
+.make-sm-column-pull(@columns) {
+ @media (min-width: @screen-sm-min) {
+ left: percentage((@columns / @grid-columns));
+ right: auto;
+ }
+}
+
+// Generate the medium columns
+.make-md-column(@columns; @gutter: @grid-gutter-width) {
+
+ @media (min-width: @screen-md-min) {
+ float: right;
+ }
+}
+.make-md-column-offset(@columns) {
+ @media (min-width: @screen-md-min) {
+ margin-right: percentage((@columns / @grid-columns));
+ margin-left: 0;
+ }
+}
+.make-md-column-push(@columns) {
+ @media (min-width: @screen-md-min) {
+ right: percentage((@columns / @grid-columns));
+ left: auto;
+ }
+}
+.make-md-column-pull(@columns) {
+ @media (min-width: @screen-md-min) {
+ left: percentage((@columns / @grid-columns));
+ right: auto;
+ }
+}
+
+// Generate the large columns
+.make-lg-column(@columns; @gutter: @grid-gutter-width) {
+
+ @media (min-width: @screen-lg-min) {
+ float: right;
+ }
+}
+.make-lg-column-offset(@columns) {
+ @media (min-width: @screen-lg-min) {
+ margin-right: percentage((@columns / @grid-columns));
+ margin-left: 0;
+ }
+}
+.make-lg-column-push(@columns) {
+ @media (min-width: @screen-lg-min) {
+ right: percentage((@columns / @grid-columns));
+ left: auto;
+ }
+}
+.make-lg-column-pull(@columns) {
+ @media (min-width: @screen-lg-min) {
+ left: percentage((@columns / @grid-columns));
+ right: auto;
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/mixins/pagination-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/mixins/pagination-rtl.less
new file mode 100644
index 0000000000..92c3a234ec
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/mixins/pagination-rtl.less
@@ -0,0 +1,18 @@
+// Pagination
+
+.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {
+ > li {
+ &:first-child {
+ > a,
+ > span {
+ .border-right-radius(@border-radius);
+ }
+ }
+ &:last-child {
+ > a,
+ > span {
+ .border-left-radius(@border-radius);
+ }
+ }
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/modals-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/modals-rtl.less
new file mode 100644
index 0000000000..0a373c8385
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/modals-rtl.less
@@ -0,0 +1,27 @@
+//
+// RTL Modals
+// --------------------------------------------------
+
+// Footer (for actions)
+.modal-footer {
+ text-align: left; // right align buttons
+
+ &.flip {
+ text-align: right;
+ }
+ // Properly space out buttons
+ .btn + .btn {
+ margin-left: auto;
+ margin-right: 5px;
+ }
+ // but override that for button groups
+ .btn-group .btn + .btn {
+ margin-right: -1px;
+ margin-left: auto;
+ }
+ // and override it for block buttons as well
+ .btn-block + .btn-block {
+ margin-right: 0;
+ margin-left: auto;
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/navbar-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/navbar-rtl.less
new file mode 100644
index 0000000000..792376cf1b
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/navbar-rtl.less
@@ -0,0 +1,135 @@
+//
+// RTL Navbars
+// --------------------------------------------------
+
+
+// Navbar heading
+//
+// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy
+// styling of responsive aspects.
+
+.navbar-header {
+
+ @media (min-width: @grid-float-breakpoint) {
+ float: right;
+ }
+}
+
+
+// Navbar collapse (body)
+//
+// Group your navbar content into this for easy collapsing and expanding across
+// various device sizes. By default, this content is collapsed when <768px, but
+// will expand past that for a horizontal display.
+//
+// To start (on mobile devices) the navbar links, forms, and buttons are stacked
+// vertically and include a `max-height` to overflow in case you have too much
+// content for the user's viewport.
+
+.navbar-collapse {
+ padding-right: @navbar-padding-horizontal;
+ padding-left: @navbar-padding-horizontal;
+}
+
+
+// Brand/project name
+
+.navbar-brand {
+ float: right;
+
+ @media (min-width: @grid-float-breakpoint) {
+ .navbar > .container &,
+ .navbar > .container-fluid & {
+ margin-right: -@navbar-padding-horizontal;
+ margin-left: auto;
+ }
+ }
+}
+
+
+// Navbar toggle
+//
+// Custom button for toggling the `.navbar-collapse`, powered by the collapse
+// JavaScript plugin.
+
+.navbar-toggle {
+ float: left;
+ margin-left: @navbar-padding-horizontal;
+ margin-right: auto;
+}
+
+
+// Navbar nav links
+//
+// Builds on top of the `.nav` components with its own modifier class to make
+// the nav the full height of the horizontal nav (above 768px).
+
+.navbar-nav {
+
+ @media (max-width: @grid-float-breakpoint-max) {
+ // Dropdowns get custom display when collapsed
+ .open .dropdown-menu {
+ > li > a,
+ .dropdown-header {
+ padding: 5px 25px 5px 15px;
+ }
+ }
+ }
+
+ // Uncollapse the nav
+ @media (min-width: @grid-float-breakpoint) {
+ float: right;
+
+ > li {
+ float: right !important;
+ }
+
+ }
+}
+
+@media (min-width: @grid-float-breakpoint) {
+ .navbar-left {
+ float: right !important;
+ &.flip {
+ float: right !important;
+ }
+ }
+
+ .navbar-right {
+ float: left !important;
+ &:last-child {
+ margin-left: -@navbar-padding-horizontal;
+ margin-right: auto;
+ }
+
+ &.flip {
+ float: left !important;
+ margin-left: -@navbar-padding-horizontal;
+ margin-right: auto;
+ }
+
+ .dropdown-menu {
+ left: 0;
+ right: auto;
+ }
+ }
+}
+
+// Text in navbars
+//
+// Add a class to make any element properly align itself vertically within the navbars.
+
+.navbar-text {
+
+ @media (min-width: @grid-float-breakpoint) {
+ float: right;
+
+ // Outdent the form if last child to line up with content down the page
+ &.navbar-right:last-child {
+ margin-left: 0;
+ margin-right: auto;
+ }
+ }
+}
+
+
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/navs-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/navs-rtl.less
new file mode 100644
index 0000000000..6810031094
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/navs-rtl.less
@@ -0,0 +1,97 @@
+//
+// Navs
+// --------------------------------------------------
+
+
+// Base class
+// --------------------------------------------------
+
+.nav {
+ padding-right: 0; // Override default ul/ol
+ padding-left: initial;
+}
+
+
+// Tabs
+// -------------------------
+
+// Give the tabs something to sit on
+.nav-tabs {
+ > li {
+ float: right;
+
+ // Actual tabs (as links)
+ > a {
+ margin-left: auto;
+ margin-right: -2px;
+ border-radius: @border-radius-base @border-radius-base 0 0;
+ }
+ }
+}
+
+
+// Pills
+// -------------------------
+.nav-pills {
+ > li {
+ float: right;
+
+ // Links rendered as pills
+ > a {
+ border-radius: @nav-pills-border-radius;
+ }
+ + li {
+ margin-right: 2px;
+ margin-left: auto;
+ }
+ }
+}
+
+
+// Stacked pills
+.nav-stacked {
+ > li {
+ float: none;
+ + li {
+ margin-right: 0; // no need for this gap between nav items
+ margin-left: auto;
+ }
+ }
+}
+
+
+// Nav variations
+// --------------------------------------------------
+
+// Justified nav links
+// -------------------------
+
+.nav-justified {
+
+ //To fix the overridden style by line 21
+ > li{
+ float: none;
+ }
+
+ > .dropdown .dropdown-menu {
+ right: auto;
+ }
+}
+
+// Move borders to anchors instead of bottom of list
+//
+// Mixin for adding on top the shared `.nav-justified` styles for our tabs
+.nav-tabs-justified {
+
+ > li > a {
+ // Override margin from .nav-tabs
+ margin-left: 0;
+ margin-right: auto;
+ }
+
+ @media (min-width: @screen-sm-min) {
+ > li > a {
+ border-radius: @border-radius-base @border-radius-base 0 0;
+ }
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/normalize-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/normalize-rtl.less
new file mode 100644
index 0000000000..c1250b9e7e
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/normalize-rtl.less
@@ -0,0 +1,15 @@
+//
+// 1. Set direction to RTL
+//
+
+html {
+ direction: rtl;
+}
+
+//
+// Remove default margin.
+//
+
+body {
+ direction: rtl;
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/pager-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/pager-rtl.less
new file mode 100644
index 0000000000..b00b3b0540
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/pager-rtl.less
@@ -0,0 +1,24 @@
+//
+// RTL Pager pagination
+// --------------------------------------------------
+
+
+.pager {
+ padding-right: 0;
+ padding-left: initial;
+
+ .next {
+ > a,
+ > span {
+ float: left;
+ }
+ }
+
+ .previous {
+ > a,
+ > span {
+ float: right;
+ }
+ }
+
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/pagination-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/pagination-rtl.less
new file mode 100644
index 0000000000..04355eb5a7
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/pagination-rtl.less
@@ -0,0 +1,32 @@
+//
+// RTL Pagination (multiple pages)
+// --------------------------------------------------
+.pagination {
+ padding-right: 0;
+
+ > li {
+ > a,
+ > span {
+ float: right; // Collapse white-space
+ margin-right: -1px;
+ margin-left: 0px;
+ }
+ &:first-child {
+ > a,
+ > span {
+ margin-left: 0;
+ .border-right-radius(@border-radius-base);
+ .border-left-radius(0);
+ }
+ }
+ &:last-child {
+ > a,
+ > span {
+ margin-right: -1px;
+ .border-left-radius(@border-radius-base);
+ .border-right-radius(0);
+ }
+ }
+ }
+
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/panels-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/panels-rtl.less
new file mode 100644
index 0000000000..a686b9feea
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/panels-rtl.less
@@ -0,0 +1,70 @@
+//
+// RTL Panels
+// --------------------------------------------------
+
+// Tables in panels
+//
+// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and
+// watch it go full width.
+
+.panel {
+ // Add border top radius for first one
+ > .table:first-child,
+ > .table-responsive:first-child > .table:first-child {
+
+ > thead:first-child,
+ > tbody:first-child {
+ > tr:first-child {
+ td:first-child,
+ th:first-child {
+ border-top-right-radius: (@panel-border-radius - 1);
+ border-top-left-radius: 0;
+ }
+ td:last-child,
+ th:last-child {
+ border-top-left-radius: (@panel-border-radius - 1);
+ border-top-right-radius: 0;
+ }
+ }
+ }
+ }
+ // Add border bottom radius for last one
+ > .table:last-child,
+ > .table-responsive:last-child > .table:last-child {
+
+ > tbody:last-child,
+ > tfoot:last-child {
+ > tr:last-child {
+ td:first-child,
+ th:first-child {
+ border-bottom-left-radius: (@panel-border-radius - 1);
+ border-top-right-radius: 0;
+ }
+ td:last-child,
+ th:last-child {
+ border-bottom-right-radius: (@panel-border-radius - 1);
+ border-top-left-radius: 0;
+ }
+ }
+ }
+ }
+ > .table-bordered,
+ > .table-responsive > .table-bordered {
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th:first-child,
+ > td:first-child {
+ border-right: 0;
+ border-left: none;
+ }
+ > th:last-child,
+ > td:last-child {
+ border-right: none;
+ border-left: 0;
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/popovers-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/popovers-rtl.less
new file mode 100644
index 0000000000..ce62b02e13
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/popovers-rtl.less
@@ -0,0 +1,33 @@
+//
+// Popovers
+// --------------------------------------------------
+
+
+.popover {
+ left: auto;
+ text-align: right;
+}
+
+.popover {
+ &.top > .arrow {
+ right: 50%;
+ left: auto;
+ margin-right: -@popover-arrow-outer-width;
+ margin-left: auto;
+ &:after {
+ margin-right: -@popover-arrow-width;
+ margin-left: auto;
+ }
+ }
+ &.bottom > .arrow {
+ right: 50%;
+ left: auto;
+ margin-right: -@popover-arrow-outer-width;
+ margin-left: auto;
+ &:after {
+ margin-right: -@popover-arrow-width;
+ margin-left: auto;
+ }
+ }
+
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/progress-bars-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/progress-bars-rtl.less
new file mode 100644
index 0000000000..9b5b9f76e0
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/progress-bars-rtl.less
@@ -0,0 +1,8 @@
+//
+// RTL Progress bars
+// --------------------------------------------------
+
+// Bar of progress
+.progress-bar {
+ float: right;
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/responsive-embed-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/responsive-embed-rtl.less
new file mode 100644
index 0000000000..87bc416db0
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/responsive-embed-rtl.less
@@ -0,0 +1,15 @@
+// RTL Embeds responsive
+//
+// Credit: Nicolas Gallagher and SUIT CSS.
+
+.embed-responsive {
+
+ .embed-responsive-item,
+ iframe,
+ embed,
+ object {
+ right: 0;
+ left: auto;
+ }
+
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/tables-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/tables-rtl.less
new file mode 100644
index 0000000000..956e6ade46
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/tables-rtl.less
@@ -0,0 +1,47 @@
+//
+// Tables
+// --------------------------------------------------
+
+//TODO
+caption {
+ text-align: right;
+}
+
+th {
+ text-align: right;
+}
+
+// Responsive tables
+//
+// Wrap your tables in `.table-responsive` and we'll make them mobile friendly
+// by enabling horizontal scrolling. Only applies <768px. Everything above that
+// will display normally.
+
+.table-responsive {
+ @media screen and (max-width: @screen-xs-max) {
+
+ // Special overrides for the bordered tables
+ > .table-bordered {
+ border: 0;
+
+ // Nuke the appropriate borders so that the parent can handle them
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th:first-child,
+ > td:first-child {
+ border-right: 0;
+ border-left: initial;
+ }
+ > th:last-child,
+ > td:last-child {
+ border-left: 0;
+ border-right: initial;
+ }
+ }
+ }
+
+ }
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/type-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/type-rtl.less
new file mode 100644
index 0000000000..62cb748803
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/type-rtl.less
@@ -0,0 +1,70 @@
+//
+// RTL Typography
+// --------------------------------------------------
+
+// Flipped Alignment
+.flip.text-left { text-align: right; }
+.flip.text-right { text-align: left; }
+
+// List options
+
+// Unstyled keeps list items block level, just removes default browser padding and list-style
+.list-unstyled {
+ padding-right: 0;
+ padding-left: initial;
+}
+
+// Inline turns list items into inline-block
+.list-inline {
+ .list-unstyled();
+ margin-right: -5px;
+ margin-left: 0;
+}
+
+dd {
+ margin-right: 0; // Undo browser default
+ margin-left: initial;
+}
+
+// Horizontal description lists
+//
+// Defaults to being stacked without any of the below styles applied, until the
+// grid breakpoint is reached (default of ~768px).
+
+.dl-horizontal {
+
+ @media (min-width: @grid-float-breakpoint) {
+ dt {
+ float: right;
+ clear: right;
+ text-align: left;
+ }
+ dd {
+ margin-right: @component-offset-horizontal;
+ margin-left: 0;
+ }
+ }
+ @media (max-width: @grid-float-breakpoint) {
+ dt {
+ text-align: right;
+ }
+ }
+}
+
+// Blockquotes
+blockquote {
+ border-right: 5px solid @blockquote-border-color;
+ border-left: 0;
+}
+
+// Opposite alignment of blockquote
+//
+// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.
+.blockquote-reverse,
+blockquote.pull-left {
+ padding-left: 15px;
+ padding-right: 0;
+ border-left: 5px solid @blockquote-border-color;
+ border-right: 0;
+ text-align: left;
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/utilities-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/utilities-rtl.less
new file mode 100644
index 0000000000..eaf8db421c
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/utilities-rtl.less
@@ -0,0 +1,15 @@
+//
+// Temporary RTL style to fix bugs rapidly.
+// They will move to some place more appropriate later.
+// --------------------------------------------------
+
+.pull-right {
+ &.flip {
+ float: left !important;
+ }
+}
+.pull-left {
+ &.flip {
+ float: right !important;
+ }
+}
diff --git a/frontend/less/espo-rtl/bootstrap-rtl/variables-rtl.less b/frontend/less/espo-rtl/bootstrap-rtl/variables-rtl.less
new file mode 100644
index 0000000000..13afd053b7
--- /dev/null
+++ b/frontend/less/espo-rtl/bootstrap-rtl/variables-rtl.less
@@ -0,0 +1,8 @@
+//
+// RTL Variables
+// --------------------------------------------------
+
+
+//== Media Objects on pull-left/pull-right + flip
+//REMOVED @media-pull-margin: 10px;
+
diff --git a/frontend/less/espo-rtl/custom.less b/frontend/less/espo-rtl/custom.less
new file mode 100644
index 0000000000..f2a80ee346
--- /dev/null
+++ b/frontend/less/espo-rtl/custom.less
@@ -0,0 +1,232 @@
+ .dropdown-menu {
+ left: auto;
+ right: 0;
+}
+
+ .dropdown-menu-right {
+ left: 0;
+ right: auto;
+}
+
+.dropdown-menu-left {
+ left: auto;
+ right: 0;
+}
+
+.list .checkbox-dropdown {
+ margin-left: -10px;
+ margin-right: 0;
+}
+
+.list-buttons-container > div {
+ float: right;
+ margin-left: @panel-padding;
+ margin-right: 0;
+}
+
+.list-buttons-container > div.total-count {
+ margin-left: 0;
+ margin-right: 0;
+ float: left;
+ padding: 6px 0;
+}
+
+li .preset .pull-right {
+ float: left !important;
+}
+
+.preset > div {
+ padding-right: 0;
+ padding-left: 20px;
+}
+
+ul.dropdown-menu > li.checkbox {
+ padding: 3px 20px 3px 0;
+}
+
+.remove-filter.pull-right {
+ float: left !important;
+}
+
+.modal-body > div > .list > table td:first-child,
+.modal-body > div > .list > table th:first-child {
+ padding-right: @panel-padding;
+ padding-left: @table-cell-padding / 2;
+}
+.modal-body > div > .list > table td:last-child,
+.modal-body > div > .list > table th:last-child {
+ padding-left: @panel-padding;
+ padding-right: @table-cell-padding / 2;
+}
+
+#main > .list-container > .list {
+ margin-left: -@container-padding;
+ margin-right: -@container-padding;
+}
+#main > .list-container > .list > table td:first-child,
+#main > .list-container > .list > table th:first-child {
+ padding-right: @panel-padding;
+ padding-left: @table-cell-padding / 2;
+}
+#main > .list-container > .list > table td:last-child,
+#main > .list-container > .list > table th:last-child {
+ padding-left: @panel-padding;
+ padding-right: @table-cell-padding / 2;
+}
+
+.panel-body .no-side-margin {
+
+ > table td:first-child,
+ > table th:first-child {
+ padding-right: @panel-padding;
+ padding-left: @table-cell-padding / 2;
+ }
+
+ > table td:last-child,
+ > table th:last-child {
+ padding-left: @panel-padding;
+ padding-right: @table-cell-padding / 2;
+ }
+}
+
+.modal-footer .btn {
+ float: right;
+}
+
+.detail-button-container > .pull-right,
+.edit-button-container > .pull-right
+{
+ float: left !important;
+}
+
+.header-buttons.pull-right {
+ float: left !important;
+}
+
+.header-breadcrumbs > .pull-left {
+ float: right !important;
+}
+
+.calendar-container .range-switch-group .btn {
+ direction: ltr;
+}
+
+.calendar-container .button-container > div > div.pull-right {
+ float: left !important;
+}
+
+.dropdown-menu > li > a > span.pull-right {
+ float: left !important;
+}
+
+.panel > .panel-heading > .pull-right.btn-group {
+ float: left !important;
+ .dropdown-menu {
+ left: 0;
+ right: auto;
+ }
+}
+
+.panel-heading > .btn-group {
+ right: 0;
+ margin-left: -11px;
+}
+
+.panel > .panel-heading > .pull-right.dropdown {
+ float: left !important;
+ right: 0;
+ margin-left: -11px;
+ .dropdown-menu {
+ left: 0;
+ right: auto;
+ }
+}
+
+.panel .panel-heading > a.pull-right {
+ float: left !important;
+}
+
+.cell > a.pull-right {
+ float: left !important;
+}
+
+.inline-save-link {
+ margin-left: 8px;
+}
+
+.inline-cancel-link {
+ margin-left: 0;
+}
+
+td.cell[data-name="buttons"] > .btn-group {
+ margin-right: -17px;
+}
+
+.list-expanded > .list-group > .list-group-item > .pull-right {
+ float: left !important;
+}
+
+.list-expanded > .list-group > .list-group-item > .pull-right > .list-row-buttons {
+ float: left !important;
+ margin-right: 0;
+ margin-left: -16px;
+}
+
+.link-container > .list-group-item > .pull-right {
+ float: left !important;
+}
+
+.link-container > .list-group-item > .pull-left > .pull-right {
+ float: left !important;
+}
+
+.link-container > .list-group-item > .pull-left {
+ float: right !important;
+}
+
+.field .link-container .list-group-item.link-with-role a {
+ margin-right: 14px;
+}
+
+#global-search-panel {
+ left: 35px;
+ right: auto;
+}
+
+#notifications-panel {
+ left: 0;
+ right: auto;
+ .panel .panel-heading .pull-right {
+ float: left !important;
+ }
+}
+
+.page-header > div.row > div > .pull-right {
+ float: left !important;
+}
+
+.grid-stack {
+ direction: ltr;
+}
+
+.grid-stack > div {
+ direction: rtl;
+}
+
+.dynamic-logic-expression-container {
+ .pull-right {
+ float: left !important;
+ }
+}
+
+#fields-panel .cell .field {
+ .pull-right {
+ float: left !important;
+ }
+}
+
+.gray-box {
+ .pull-right {
+ float: left !important;
+ }
+}
\ No newline at end of file
diff --git a/frontend/less/espo-rtl/main.less b/frontend/less/espo-rtl/main.less
new file mode 100644
index 0000000000..2621c0d596
--- /dev/null
+++ b/frontend/less/espo-rtl/main.less
@@ -0,0 +1,15 @@
+@import "../espo/bootstrap/bootstrap.less";
+
+@import "bootstrap-rtl/bootstrap-rtl.less";
+
+@import "../espo/variables.less";
+@import "variables.less";
+
+@import "../espo/mixins.less";
+@import "../espo/misc.less";
+@import "../espo/layout.less";
+@import "../espo/custom.less";
+
+@import "custom.less";
+
+@import "bootstrap-rtl/utilities-rtl.less";
diff --git a/frontend/less/espo-rtl/variables.less b/frontend/less/espo-rtl/variables.less
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frontend/less/espo-vertical/custom.less b/frontend/less/espo-vertical/custom.less
index 45e8b4668b..700751be0b 100644
--- a/frontend/less/espo-vertical/custom.less
+++ b/frontend/less/espo-vertical/custom.less
@@ -12,7 +12,7 @@
}
#global-search-input {
- border: 1px solid @main-gray;
+ border: 1px solid @top-navbar-bg-color;
font-size: 13px;
width: 200px;
}
@@ -38,4 +38,5 @@
#global-search-panel {
margin-top: -1px;
}
-}
\ No newline at end of file
+}
+
diff --git a/frontend/less/espo-vertical/layout.less b/frontend/less/espo-vertical/layout.less
index 30b44bb549..00e27ead89 100644
--- a/frontend/less/espo-vertical/layout.less
+++ b/frontend/less/espo-vertical/layout.less
@@ -199,7 +199,7 @@ body > #header .navbar-brand span.home-icon {
left: 0;
height: @tob-bar-height;
width: 100%;
- background-color: @main-gray;
+ background-color: @top-navbar-bg-color;
margin-left: @navbar-width;
padding-right: @navbar-width;
}
diff --git a/frontend/less/espo-vertical/variables.less b/frontend/less/espo-vertical/variables.less
index 6abbbaf284..4aace55c32 100644
--- a/frontend/less/espo-vertical/variables.less
+++ b/frontend/less/espo-vertical/variables.less
@@ -1,3 +1,4 @@
@navbar-width: 153px;
@navbar-minimized-width: 40px;
-@tob-bar-height: 30px;
\ No newline at end of file
+@tob-bar-height: 30px;
+@top-navbar-bg-color: @main-gray;
\ No newline at end of file
diff --git a/frontend/less/espo/custom.less b/frontend/less/espo/custom.less
index 8c1495627e..ec0c4ed510 100644
--- a/frontend/less/espo/custom.less
+++ b/frontend/less/espo/custom.less
@@ -98,6 +98,10 @@ label {
min-height: 33px;
}
+.page-header > .row {
+ min-height: 33px;
+}
+
.modal-header {
background-color: @default-heading-bg-color;
}
@@ -446,7 +450,7 @@ select[multiple].input-sm {
}
.input-group-btn > select.form-control {
- position: relative;
+ position: relative;
display: inline-block;
width: auto;
vertical-align: middle;
@@ -458,6 +462,10 @@ select[multiple].input-sm {
margin-left: -1px;
}
+.input-group > .middle-element {
+ margin-left: 0 !important;
+}
+
.input-group .form-control:focus {
z-index: 3;
}
@@ -789,7 +797,7 @@ td.cell[data-name="buttons"] > .btn-group {
}
.panel {
- border-width: 2px;
+ border-width: @panel-border-width;
}
.panel-heading > .btn-group > .btn {
@@ -839,13 +847,13 @@ td.cell[data-name="buttons"] > .btn-group {
.stick-sub {
position: fixed;
top: 0;
- margin: 44px 0 0;
+ margin: 44px 0 0 -@container-padding;
z-index: 4;
}
.stick-sub.button-container {
background-color: @body-bg;
- padding: 3px @container-padding*2 3px 0;
+ padding: 3px @container-padding 0 @container-padding;
width: 100%;
}
@@ -959,7 +967,7 @@ body > footer > p a:visited {
.record .middle > .panel:first-child {
margin-top: 0;
- border-top-width: 2px;
+ border-top-width: @panel-border-width;
}
.record .middle > .panel {
@@ -1255,7 +1263,9 @@ h5 {
width: 270px;
}
-
+.inline-cancel-link {
+ margin-left: 8px;
+}
.dynamic-logic-expression-container {
div.item-list {
@@ -1288,6 +1298,18 @@ h5 {
}
}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ margin-left: -1px;
+}
+
+.input-group > .input-group-btn > .btn:hover,
+.input-group > .input-group-btn > .btn:focus,
+.input-group > .input-group-btn > .btn.active {
+ z-index: 3;
+}
+
@media screen and (min-width: @screen-sm-min) {
#global-search-panel {
margin-top: 5px;
diff --git a/frontend/less/espo/variables.less b/frontend/less/espo/variables.less
index b83d6a6f79..27d274603b 100644
--- a/frontend/less/espo/variables.less
+++ b/frontend/less/espo/variables.less
@@ -121,3 +121,5 @@
@logo-height: 44px;
@dashlet-unit-height: 155px;
+
+@panel-border-width: 2px;
diff --git a/frontend/less/hazyblue/custom.less b/frontend/less/hazyblue/custom.less
new file mode 100644
index 0000000000..2d51e3cec7
--- /dev/null
+++ b/frontend/less/hazyblue/custom.less
@@ -0,0 +1,103 @@
+.panel-heading {
+ border-bottom-width: 0;
+}
+
+.panel-default.note-editor .panel-heading .btn-default {
+ background-color: @btn-default-bg;
+ border-color: @btn-default-border;
+}
+
+.panel-default .panel-heading .btn-default {
+ background-color: @panel-default-heading-bg;
+ border-color: @panel-default-heading-bg;
+}
+
+.panel-title {
+ font-size: 15px;
+ line-height: 16px;
+}
+
+.modal-content {
+ background-color: @white-color;
+}
+
+.modal-content > .modal-body {
+ background-color: @body-bg;
+}
+
+.modal-body > .list-group {
+ background-color: @white-color;
+}
+
+.list-container > .list {
+ background-color: @white-color;
+}
+
+.modal-footer {
+ margin-top: 0;
+}
+
+.panel-heading > .btn-group {
+ top: -5px;
+ right: -10px;
+}
+
+table.table {
+ background-color: @white-color;
+}
+
+.record .middle > .panel:first-child {
+ border-top-width: 1px;
+}
+
+.record .middle > .panel {
+ border-top-width: 1px;
+}
+
+.dashlet-body .list-container > .list,
+.panel-body .list-container > .list {
+ box-shadow: none;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+}
+
+.list-container > .list,
+.panel,
+.dashlet-container {
+ -webkit-box-shadow: 3px 3px 4px rgba(0,0,0,0.13);
+ -moz-box-shadow: 3px 3px 4px rgba(0,0,0,0.13);
+ box-shadow: 3px 3px 4px rgba(0,0,0,0.13);
+}
+
+@media (min-width: 768px) {
+ .modal-dialog > .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0,0,0,0.5);
+ -moz-box-shadow: 0 5px 15px -3px rgba(0,0,0,0.5);
+ box-shadow: 0 5px 15px rgba(0,0,0,0.5);
+ }
+}
+
+.panel.sticked {
+ border-top-width: 1px;
+}
+
+.list-container .list-buttons-container {
+ margin-bottom: 10px;
+}
+
+.modal-header {
+ background-color: @white-color;
+}
+
+.calendar-container > .calendar,
+.calendar-container > .timeline {
+ background-color: @white-color;
+}
+
+.field .list-group {
+ background-color: @white-color;
+}
+
+.field .grid-stack-item-content {
+ border: 1px solid @default-border-color;
+}
\ No newline at end of file
diff --git a/frontend/less/hazyblue/main.less b/frontend/less/hazyblue/main.less
new file mode 100644
index 0000000000..d762432b54
--- /dev/null
+++ b/frontend/less/hazyblue/main.less
@@ -0,0 +1,17 @@
+@import "../espo/bootstrap/bootstrap.less";
+
+@import "../espo/variables.less";
+@import "../espo-vertical/variables.less";
+
+@import "../espo/mixins.less";
+
+@import "../espo/misc.less";
+@import "../espo-vertical/layout.less";
+@import "../espo/custom.less";
+@import "../espo-vertical/custom.less";
+
+@import "variables.less";
+
+@import "custom.less";
+
+@import "../espo/bootstrap/utilities.less";
diff --git a/frontend/less/hazyblue/variables.less b/frontend/less/hazyblue/variables.less
new file mode 100644
index 0000000000..300bb21fdf
--- /dev/null
+++ b/frontend/less/hazyblue/variables.less
@@ -0,0 +1,17 @@
+@navbar-inverse-bg: #546E7A;
+@body-bg: #ececec;
+@top-navbar-bg-color: @body-bg;
+
+@white-color: #FFF;
+
+@panel-default-heading-bg: @white-color;
+
+@panel-border-width: 0;
+
+@panel-default-border: #dcdcdc;
+
+@btn-default-bg: #f7f7f7;
+@btn-default-border: #cccccc;
+
+@brand-success: #85b75f;
+@brand-primary: #537898;
\ No newline at end of file