summaryrefslogtreecommitdiff
path: root/addons/website/static/src/scss/website.scss
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website/static/src/scss/website.scss
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website/static/src/scss/website.scss')
-rw-r--r--addons/website/static/src/scss/website.scss1437
1 files changed, 1437 insertions, 0 deletions
diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss
new file mode 100644
index 00000000..06627a58
--- /dev/null
+++ b/addons/website/static/src/scss/website.scss
@@ -0,0 +1,1437 @@
+///
+/// This file regroups the website design rules.
+///
+
+$-seen-urls: ();
+@each $alias, $key in $o-font-aliases-to-keys {
+ $-url: o-get-font-info($alias, 'url');
+ @if $-url and index($-seen-urls, $-url) == null {
+ $-seen-urls: append($-seen-urls, $-url);
+ @import url("https://fonts.googleapis.com/css?family=#{unquote($-url)}&display=swap");
+ }
+}
+
+:root {
+ // The theme customize modal JS will need to know the value of some scss
+ // variables used to render the user website, and those may have been
+ // customized by themes, the user or anything else (so there is no file to
+ // parse to get them). Those will be printed here as CSS variables.
+
+ @include print-variable('support-13-0-color-system', $o-support-13-0-color-system);
+ @include print-variable('has-customized-13-0-color-system', $o-has-customized-13-0-color-system);
+
+ // 1) Handle default values
+ @include print-variable('header-font-size', $font-size-base);
+
+ // 2) The values in the $theme-colors map are already printed by Bootstrap.
+
+ // 3) The values in the $colors map are also printed by Bootstrap. However,
+ // we have color variables which can contain a reference to a color
+ // combination and that is the info we want in that case. As a stable fix,
+ // we'll leave the original variable untouched but print a prefixed version
+ // of the variable with the correct reference value.
+ // TODO adapt in master
+ @each $key in ('menu', 'header-boxed', 'footer', 'copyright') {
+ $-value: map-get($o-color-palette, $key);
+ @if type-of($-value) == 'number' {
+ @include print-variable('bugfixed-#{$key}', $-value);
+ }
+ }
+
+ // 4) The Odoo values map, $o-website-values, must be printed.
+ @each $key, $value in $o-website-values {
+ @include print-variable($key, $value);
+ }
+
+ // 5) Use final value used by the theme
+ @include print-variable('body', $body-bg);
+
+ @include print-variable('logo-height', $o-theme-navbar-logo-height);
+ @include print-variable('fixed-logo-height', $o-theme-navbar-fixed-logo-height);
+
+ $-font-names: map-keys($o-theme-font-configs);
+ @include print-variable('number-of-fonts', length($-font-names));
+ $i: 1;
+ @each $font-name in $-font-names {
+ @include print-variable('font-number-#{$i}', $font-name);
+ $i: $i + 1;
+ }
+
+ @include print-variable('btn-padding-y', $btn-padding-y);
+ @include print-variable('btn-padding-x', $btn-padding-x);
+ @include print-variable('btn-font-size', $btn-font-size);
+ @include print-variable('btn-padding-y-sm', $btn-padding-y-sm);
+ @include print-variable('btn-padding-x-sm', $btn-padding-x-sm);
+ @include print-variable('btn-font-size-sm', $btn-font-size-sm);
+ @include print-variable('btn-padding-y-lg', $btn-padding-y-lg);
+ @include print-variable('btn-padding-x-lg', $btn-padding-x-lg);
+ @include print-variable('btn-font-size-lg', $btn-font-size-lg);
+ @include print-variable('btn-border-width', $btn-border-width);
+ @include print-variable('btn-border-radius', $btn-border-radius);
+ @include print-variable('btn-border-radius-sm', $btn-border-radius-sm);
+ @include print-variable('btn-border-radius-lg', $btn-border-radius-lg);
+
+ @include print-variable('input-padding-y', $input-padding-y);
+ @include print-variable('input-padding-x', $input-padding-x);
+ @include print-variable('input-font-size', $input-font-size);
+ @include print-variable('input-padding-y-sm', $input-padding-y-sm);
+ @include print-variable('input-padding-x-sm', $input-padding-x-sm);
+ @include print-variable('input-font-size-sm', $input-font-size-sm);
+ @include print-variable('input-padding-y-lg', $input-padding-y-lg);
+ @include print-variable('input-padding-x-lg', $input-padding-x-lg);
+ @include print-variable('input-font-size-lg', $input-font-size-lg);
+ @include print-variable('input-border-width', $input-border-width);
+ @include print-variable('input-border-radius', $input-border-radius);
+ @include print-variable('input-border-radius-sm', $input-border-radius-sm);
+ @include print-variable('input-border-radius-lg', $input-border-radius-lg);
+
+ @include print-variable('number-of-color-palettes', length($o-color-palettes) - 1); // -1 since the last one is the user customized one
+ @include print-variable('color-palettes-number', $o-original-color-palette-number);
+ @include print-variable('has-customized-colors', $o-has-customized-colors);
+
+ // 6) Get list of colorpalette custom colors
+ $custom-colors: ();
+ @each $key, $value in $o-color-palette {
+ $custom-colors: append($custom-colors, $key);
+ }
+ @include print-variable('custom-colors', $custom-colors);
+}
+
+#wrapwrap {
+ @if o-website-value('body-image') {
+ background-image: url("/#{str-slice(o-website-value('body-image'), 2)}");
+ background-position: center;
+ background-attachment: fixed;
+ @if o-website-value('body-image-type') == 'pattern' {
+ background-size: auto;
+ background-repeat: repeat;
+ } @else {
+ background-size: cover;
+ background-repeat: no-repeat;
+ }
+ }
+
+ @if o-website-value('layout') != 'full' {
+ > main {
+ background-color: o-color('o-cc1-bg');
+ }
+
+ @include media-breakpoint-up(sm) {
+ padding-right: $grid-gutter-width * 2;
+ padding-left: $grid-gutter-width * 2;
+
+ > * {
+ // When the website is visually acting like a container (eg.
+ // boxed layout), increase its maximum size to handle bigger
+ // horizontal paddings.
+ $-max-widths: ();
+ @each $key, $value in $container-max-widths {
+ $-max-widths: map-merge($-max-widths, (
+ #{$key}: $value + $grid-gutter-width * 2,
+ ));
+ }
+ @include make-container(0);
+ @include make-container-max-widths($-max-widths);
+ }
+
+ > header .container {
+ max-width: 100% !important;
+ }
+
+ // Vertical alignment when top-menu has visually "no background"
+ @if o-color('menu') == o-color('body') {
+ > header {
+ .navbar, .container {
+ padding-left: 0;
+ padding-right: 0;
+ }
+ }
+ }
+ }
+
+ @if o-website-value('layout') == 'framed' {
+ @include media-breakpoint-up(md) {
+ padding-top: $grid-gutter-width;
+ padding-bottom: $grid-gutter-width * 1.5;
+ }
+ } @else if o-website-value('layout') == 'postcard' {
+ @include media-breakpoint-up(md) {
+ $-border-radius: $border-radius-lg;
+ // Don't know why (browser rounding mistake?) but the inner
+ // border radius must be 1px lower for this to be visually ok
+ // (despite the fact there is no border or any space)
+ $-inner-border-radius: $-border-radius - 0.0625rem;
+ > * {
+ margin-bottom: $spacer * 2;
+ }
+ > header {
+ &, &.o_header_affix {
+ .navbar {
+ @include border-bottom-radius($-border-radius);
+ }
+ }
+ }
+ > main, > footer {
+ @include border-radius($-border-radius);
+
+ .oe_structure > :first-child {
+ @include border-top-radius($-inner-border-radius);
+ }
+ }
+ > main .oe_structure > :last-child,
+ .o_footer_copyright {
+ @include border-bottom-radius($-inner-border-radius);
+ }
+ }
+ }
+ }
+}
+
+.navbar {
+
+ .navbar-collapse {
+ min-width: 0; // Allows it to shrink during loading
+ }
+ .nav-item {
+ transition: opacity 1000ms ease 0s;
+ }
+ .btn {
+ // This was a default bootstrap style before but it was removed from
+ // the library at some point. It seems important in the header so that
+ // the header does not flicker during loading.
+ white-space: nowrap;
+ }
+ .o_menu_loading {
+ flex-wrap: nowrap !important;
+ overflow: hidden !important;
+
+ .nav-item {
+ opacity: 0 !important;
+ }
+ }
+}
+.navbar-brand, .navbar-text, .navbar .nav-link {
+ @if $o-theme-navbar-font != $o-theme-font {
+ font-family: $o-theme-navbar-font;
+ }
+}
+
+.navbar-light {
+ // Style only navbar-light which Odoo is only supposed to use in standard
+ // anyway. Automatically mimic navbar-dark if the user's menu color is dark.
+ // Note: this only works because navbar-light is defined before navbar-dark,
+ // we may want to use a safest way when possible.
+ @include o-apply-colors('menu');
+ @if (color-yiq(o-color('menu')) != $yiq-text-dark) {
+ @extend .navbar-dark;
+ }
+}
+
+$-header-nav-link-height: $nav-link-height;
+@if o-website-value('header-font-size') {
+ $-header-nav-link-height: o-website-value('header-font-size') * $line-height-base + $nav-link-padding-y * 2;
+ header {
+ font-size: o-website-value('header-font-size');
+
+ .dropdown-menu, .btn {
+ font-size: inherit;
+ }
+ }
+}
+@if $o-theme-navbar-logo-height {
+ // With default values, this makes it slightly bigger than standard
+ // navbar-brand, which is what we want
+ header .navbar-brand {
+ font-size: $o-theme-navbar-logo-height / $line-height-base;
+
+ $-logo-padding-y: max(0, $-header-nav-link-height - $o-theme-navbar-logo-height) / 2;
+ &, &.logo {
+ padding-top: $-logo-padding-y;
+ padding-bottom: $-logo-padding-y;
+ }
+ }
+}
+
+.o_footer {
+ @include o-apply-colors('footer');
+
+ .o_footer_copyright {
+ @include o-apply-colors('copyright', $background: o-color('footer'));
+ }
+}
+
+h2, h3, h4, h5, h6 {
+ color: color('o-cc1-h2');
+}
+h3, h4, h5, h6 {
+ color: color('o-cc1-h3');
+}
+h4, h5, h6 {
+ color: color('o-cc1-h4');
+}
+h5, h6 {
+ color: color('o-cc1-h5');
+}
+h6 {
+ color: color('o-cc1-h6');
+}
+.btn {
+ @if ($o-theme-buttons-font != $o-theme-font) {
+ font-family: $o-theme-buttons-font;
+ }
+}
+
+// Texts
+font[style*='background'],
+font[class*='bg-'] {
+ padding: 2px 6px 4px;
+}
+
+// Icons
+.fa {
+ font-family: "FontAwesome" !important;
+ $size: 3rem;
+
+ &.rounded-circle,
+ &.rounded,
+ &.rounded-0,
+ &.rounded-leaf,
+ &.img-thumbnail,
+ &.shadow {
+ display: inline-block;
+ vertical-align: middle;
+ text-align: center;
+ // fa-1x is not ouput
+ @include size($size);
+ line-height: $size;
+ @for $i from 2 through 5 {
+ &.fa-#{$i}x {
+ @include size($size + $i);
+ line-height: $size + $i;
+ }
+ }
+ // Default, if no background-color already selected
+ background-color: $gray-100;
+ }
+ &.img-thumbnail {
+ padding: 0;
+ }
+ &.rounded-leaf {
+ border-top-left-radius: $size;
+ border-bottom-right-radius: $size;
+ }
+ &.rounded-empty-circle {
+ @extend .rounded-circle;
+ border-width: ceil(1.4 * $border-width);
+ border-style: solid;
+ background: transparent;
+ }
+}
+// Smaller container
+.o_container_small {
+ @extend .container;
+ @include media-breakpoint-up(lg) {
+ max-width: map-get($container-max-widths, md);
+ }
+}
+
+// Buttons
+.btn {
+ &.flat {
+ border: 0;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+ @include button-size(0.75rem, 1.5rem, ($font-size-base * .75), $btn-line-height, 0);
+ &.btn-lg { @include button-size(1rem, 2rem, ($font-size-lg * .75), $btn-line-height-lg, 0); }
+ &.btn-sm { @include button-size(.5rem, 1rem, ($font-size-sm * .75), $btn-line-height-sm, 0); }
+ &.btn-xs { @include button-size(.25rem, .5rem, ($font-size-base * .5), $btn-line-height-sm, 0); }
+ }
+ &.rounded-circle {
+ border-radius: 100px !important;
+ @include button-size(0.45rem, 1.35rem, $font-size-base, $btn-line-height, 30px);
+ &.btn-lg { @include button-size(.6rem, 1.8rem, $font-size-lg, $btn-line-height-lg, 30px); }
+ &.btn-sm { @include button-size(.3rem, .9rem, $font-size-sm, $btn-line-height-sm, 30px); }
+ &.btn-xs { @include button-size(.15rem, .45rem, ($font-size-base * .75), $btn-line-height-sm, 30px); }
+ }
+}
+
+// Background Images
+.oe_img_bg {
+ background-size: cover;
+ background-repeat: no-repeat;
+
+ &.o_bg_img_opt_repeat {
+ background-size: auto;
+ background-repeat: repeat;
+ }
+
+ // Compatibility <= 13.0, TODO remove?
+ // -----------------------------------
+ &.o_bg_img_opt_contain {
+ background-size: contain;
+ background-position: center center;
+ }
+ &.o_bg_img_opt_custom {
+ background-size: auto;
+ }
+ &.o_bg_img_opt_repeat_x {
+ background-repeat: repeat-x;
+ }
+ &.o_bg_img_opt_repeat_y {
+ background-repeat: repeat-y;
+ }
+}
+
+// Background videos
+.o_bg_video_container {
+ @extend %o-we-background-layer;
+}
+.o_bg_video_iframe {
+ position: relative;
+ pointer-events: none !important;
+}
+.o_bg_video_loading {
+ @include o-position-absolute(0, 0 ,0 ,0);
+}
+.o_background_video, .parallax {
+ @extend %o-we-background-layer-parent;
+}
+
+// Probably outdated
+// Disable fixed height
+@media (max-width: 400px) {
+ section,
+ .parallax,
+ .row,
+ .hr,
+ .blockquote {
+ height: auto !important;
+ }
+}
+
+// Probably outdated
+// Table
+.table_desc {
+ margin: 0 0 20px 0;
+ width: 100%;
+ word-break: break-all;
+ border: 1px solid #dddddd;
+}
+.table_heading {
+ background-color: #f5f5f5;
+ border: 1px solid #dddddd;
+ color: #666666;
+ font-size: 14px;
+ padding: 4px;
+}
+table.table_desc tr td {
+ text-align: left;
+ padding: 5px;
+ font-size: 13px;
+ &:first-child {
+ width: 25%;
+ font-weight: bold;
+ border-bottom: 1px solid #c9c9c9;
+ border-right: 1px solid #c9c9c9;
+ border-left: none;
+ }
+ &:last-child {
+ border-bottom: 1px solid #c9c9c9;
+ }
+}
+
+// Jumbotron
+.jumbotron {
+ border-radius: 0;
+}
+
+.o_full_screen_height {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-around;
+ min-height: 100vh !important;
+}
+.o_half_screen_height {
+ @extend .o_full_screen_height;
+ min-height: 55vh !important;
+}
+
+// TODO remove cover_full and cover_mid classes (kept for compatibility for now)
+.cover_full {
+ @extend .o_full_screen_height;
+}
+.cover_mid {
+ @extend .o_half_screen_height;
+}
+
+// Allows custom border radius without contents overflowing.
+.card {
+ overflow: hidden;
+}
+
+//
+// Snippets
+//
+
+// Carousel -> TODO: should be versioned in 000.scss file but how ?
+.s_carousel,
+.s_quotes_carousel {
+
+ // Controls
+ .carousel-control-prev,
+ .carousel-control-next {
+ position: absolute;
+ cursor: pointer;
+ width: 8%;
+ opacity: 1;
+ }
+ @include media-breakpoint-down(sm) {
+ .carousel-control-prev,
+ .carousel-control-next {
+ display: none; // remove arrows on mobile
+ }
+ }
+ .carousel-control-prev { justify-content: flex-start; }
+ .carousel-control-next { justify-content: flex-end; }
+ .carousel-control-prev-icon,
+ .carousel-control-next-icon {
+ @include size(auto);
+ background-image: none;
+ color: $body-color;
+ &:before {
+ font-family: "FontAwesome";
+ display: inline-block;
+ background-color: #fff;
+ }
+ }
+ // Content
+ .carousel-inner {
+ overflow: hidden;
+ height: 100%;
+ .carousel-item {
+ height: 100%;
+ }
+ }
+ // Indicators
+ .carousel-indicators {
+ position: absolute;
+
+ li:hover:not(.active) {
+ background-color: rgba(255,255,255,.8);
+ }
+ }
+
+ // Default
+ &.s_carousel_default {
+ // Controls - chevron
+ .carousel-control-prev-icon:before { content: "\f053" #{"/*rtl:'\f054'*/"}; margin-left: 1.5rem; }
+ .carousel-control-next-icon:before { content: "\f054" #{"/*rtl:'\f053'*/"}; margin-right: 1.5rem; }
+ .carousel-control-prev-icon:before,
+ .carousel-control-next-icon:before {
+ background-color: rgba(0,0,0,0);
+ font-size: 2rem;
+ color: #fff;
+ text-shadow: $box-shadow-sm;
+ }
+ // Indicators
+ .carousel-indicators li {
+ height: .6rem;
+ margin-bottom: .5rem;
+ border: 0;
+ border-radius: $border-radius-sm;
+ box-shadow: $box-shadow-sm;
+ }
+ }
+
+ // Border
+ &.s_carousel_bordered {
+ border: 2rem solid rgba(0,0,0,0);
+ @include media-breakpoint-down(sm) {
+ border: 0.5rem solid rgba(0,0,0,0);
+ }
+ // Controls - caret
+ .carousel-control-prev-icon:before { content: "\f0d9"; }
+ .carousel-control-next-icon:before { content: "\f0da"; }
+ .carousel-control-prev-icon:before,
+ .carousel-control-next-icon:before {
+ @include size(2rem, 6rem);
+ line-height: 6rem;
+ font-size: 1.5rem;
+ }
+ // Indicators
+ .carousel-indicators li {
+ @include size(3rem, 1rem);
+ }
+ }
+
+ // Circle
+ &.s_carousel_rounded {
+ // Container
+ // .carousel-inner {
+ // border-top-left-radius: 10rem;
+ // border-bottom-right-radius: 10rem;
+ // }
+ // Controls - arrow
+ .carousel-control-prev { margin-left: 1.5rem; }
+ .carousel-control-next { margin-right: 1.5rem; }
+ .carousel-control-prev-icon:before { content: "\f060"; }
+ .carousel-control-next-icon:before { content: "\f061"; }
+ .carousel-control-prev-icon:before,
+ .carousel-control-next-icon:before {
+ @include size(4rem);
+ line-height: 4rem;
+ border-radius: 50%;
+ font-size: 1.25rem;
+ }
+ // Indicators
+ .carousel-indicators li {
+ @include size(1rem);
+ border-radius: 50%;
+ }
+ }
+
+ // Boxed
+ &.s_carousel_boxed {
+ @include make-container();
+ @include make-container-max-widths();
+ .carousel-item {
+ padding: 0 1rem;
+ }
+ // Controls - angle
+ .carousel-control-prev,
+ .carousel-control-next {
+ align-items: flex-end;
+ margin-bottom: 1.25rem;
+ }
+ .carousel-control-prev { margin-left: 3rem; }
+ .carousel-control-next { margin-right: 3rem; }
+ .carousel-control-prev-icon:before { content: "\f104"; }
+ .carousel-control-next-icon:before { content: "\f105"; }
+ .carousel-control-prev-icon:before,
+ .carousel-control-next-icon:before {
+ @include size(2rem);
+ line-height: 2rem;
+ font-size: 1.25rem;
+ }
+ // Indicators
+ .carousel-indicators li {
+ @include size(1rem);
+ &:hover:not(.active) {
+ background-color: rgba(255,255,255,.8);
+ }
+ }
+ }
+}
+
+
+.carousel .container {
+ .carousel-img img {
+ max-height: 95%;
+ padding: 10px;
+ }
+ > .carousel-caption {
+ @include o-position-absolute($right: 50%, $left: 50%);
+ bottom: 20px;
+ > div {
+ position: absolute;
+ text-align: left;
+ padding: 20px;
+ background: rgba(0, 0, 0, 0.4);
+ bottom: 20px;
+ }
+ }
+ > .carousel-image {
+ @include o-position-absolute($top: 5%, $bottom: 5%);
+ max-height: 90%;
+ margin: 0 auto;
+ }
+ .carousel-item.text_image .container {
+ > .carousel-caption {
+ left: 10%;
+ > div {
+ right: 50%;
+ margin-right: -20%;
+ max-width: 550px;
+ }
+ }
+ > .carousel-image {
+ right: 10%;
+ left: 50%;
+ }
+ }
+ .carousel-item.image_text .container {
+ > .carousel-caption {
+ right: 10%;
+ > div {
+ left: 50%;
+ margin-left: -20%;
+ max-width: 550px;
+ }
+ }
+ > .carousel-image {
+ right: 50%;
+ left: 10%;
+ }
+ }
+ .carousel-item.text_only .container {
+ > .carousel-caption {
+ left: 10%;
+ right: 10%;
+ top: 10%;
+ bottom: auto;
+ > div {
+ text-align: center;
+ background: transparent;
+ bottom: auto;
+ width: 100%;
+ }
+ }
+ > .carousel-image {
+ display: none !important;
+ }
+ }
+}
+
+// Parallax
+.parallax {
+ // TODO this introduces a limitation: no dropdown will be able to
+ // overflow. Maybe there is a better way to find.
+ &:not(.s_parallax_no_overflow_hidden) {
+ overflow: hidden;
+ }
+
+ > .s_parallax_bg {
+ @extend %o-we-background-layer;
+ }
+ @include media-breakpoint-up(xl) {
+ // Fixed backgrounds are disabled when using a mobile/tablet device,
+ // which is not a big deal but, on some of them (iOS...), defining the
+ // background as fixed breaks the background-size/position props.
+ // So we enable this only for >= XL devices.
+ &.s_parallax_is_fixed > .s_parallax_bg {
+ background-attachment: fixed;
+ }
+ }
+}
+// Keeps parallax snippet element selectable when Height = auto.
+.s_parallax {
+ min-height: 10px;
+}
+
+//
+// Layout
+//
+
+$-transition-duration: 200ms;
+
+// Affixed Header
+.o_header_affixed {
+ display: block;
+ @include o-position-absolute(0, 0, auto, 0);
+ position: fixed;
+ background: $light;
+
+ &:not(.o_header_no_transition) {
+ transition: transform $-transition-duration;
+ }
+
+ @if o-website-value('header-template') == 'boxed' {
+ background: transparent;
+ }
+
+ &.o_header_is_scrolled {
+ .navbar-brand {
+ font-size: $o-theme-navbar-fixed-logo-height / $line-height-base;
+
+ img {
+ height: $o-theme-navbar-fixed-logo-height;
+ }
+ }
+ @if o-website-value('header-template') == 'vertical' {
+ .o_header_centered_logo {
+ display: none;
+ }
+ @include media-breakpoint-up(lg) {
+ .navbar-brand {
+ font-size: 0;
+ opacity: 0;
+
+ img {
+ height: 0;
+ }
+ }
+ }
+ }
+ }
+ &.o_header_standard.o_header_is_scrolled {
+ @if index(('menu_logo_below', 'logo_menu_below'), o-website-value('header-template')) != null {
+ .navbar-brand {
+ &, img {
+ transition: none;
+ }
+ }
+ }
+ }
+}
+#oe_main_menu_navbar + #wrapwrap .o_header_affixed {
+ top: $o-navbar-height;
+}
+
+// Navbar
+.navbar .o_extra_menu_items.show > ul {
+ > li {
+ + li {
+ border-top: 1px solid gray('200');
+ }
+ > a.dropdown-toggle {
+ background-color: gray('200');
+ color: inherit; // Useful when the toggle is active
+ pointer-events: none; // hack to prevent clicking on it because dropdown always opened
+ }
+ > ul, > .o_mega_menu { // remove dropdown-menu default style as it is nested in another one
+ position: static;
+ float: none;
+ display: block;
+ max-height: none;
+ margin-top: 0;
+ padding: 0;
+ border: none;
+ box-shadow: none;
+ }
+ > .o_mega_menu .row > div { // remove mega menu col-lg-* style
+ max-width: none;
+ flex: auto;
+ }
+ }
+}
+
+$-off-canvas-hamburger: o-website-value('hamburger-type') == 'off-canvas';
+$-hamburger-left: o-website-value('hamburger-position') == 'left';
+$-hamburger-center: o-website-value('hamburger-position') == 'center';
+$-hamburger-right: o-website-value('hamburger-position') == 'right';
+
+$zindex-website-header: $zindex-fixed !default;
+
+header {
+ &#top {
+ // We need this z-index for the shadow option of the header but also
+ // to create a stacking context so that header dropdowns appear below
+ // and above the same elements as the header.
+ z-index: $zindex-website-header;
+ }
+ &:not(.o_header_no_transition) {
+ #top_menu_container {
+ transition: all $-transition-duration;
+ }
+ .navbar-brand {
+ transition: margin $-transition-duration, font-size $-transition-duration, opacity $-transition-duration ease-out;
+
+ img {
+ transition: height $-transition-duration;
+ }
+ }
+ }
+
+ // Dropdown menus
+
+ // In mobile there is no need to limit the height...
+ @include media-breakpoint-up(lg) {
+ .navbar .dropdown-menu {
+ max-height: 60vh;
+ overflow-y: auto;
+ overflow-x: hidden; // Needed because of container in container having 0px padding... TODO improve
+ }
+ }
+ // ... but we limit the navbar-collapse height
+ .navbar-collapse.show {
+ max-height: 80vh;
+ overflow-y: auto;
+ overflow-x: hidden; // Needed because of container in container having 0px padding... TODO improve
+ }
+
+ &:not(.o_header_is_scrolled) {
+ $-is-hamburger: o-website-value('header-template') == 'hamburger';
+ @include media-breakpoint-up(md) {
+ @if $-is-hamburger {
+ #top_menu_container {
+ padding-top: $spacer * 0.5;
+ padding-bottom: $spacer * 0.5;
+ }
+ }
+ }
+ }
+
+ #top_menu_container {
+ flex-direction: inherit;
+ }
+ @if $-hamburger-center {
+ .collapsing, .show {
+ #top_menu {
+ @if not $-off-canvas-hamburger {
+ padding-top: 15vh;
+ padding-bottom: 15vh;
+ }
+ text-align: center;
+ }
+ }
+ }
+
+ @include media-breakpoint-up(md) {
+ // Allow to center the logo, ignoring the toggler space
+ .o_navbar_toggler_container {
+ flex: 0 0 0;
+ min-width: 0;
+ direction: if($-hamburger-left, ltr, rtl);
+ }
+ }
+
+ nav.navbar {
+ @if o-website-value('menu-border-width') {
+ border: o-website-value('menu-border-width') o-website-value('menu-border-style') o-color('menu-border-color') !important;
+ }
+ border-radius: o-website-value('menu-border-radius') !important;
+ box-shadow: o-website-value('menu-box-shadow') !important;
+ }
+}
+
+@if $-off-canvas-hamburger {
+ #top_menu_collapse {
+
+ &.collapsing, &.show {
+ // Note: position relatively to the header instead of the viewport
+ // because fixed position cannot work inside an element whose CSS
+ // transform is different to none, which the header element is
+ // because of header effects.
+ @include o-position-absolute(0, 0, 0, 0);
+ z-index: $zindex-sticky;
+ height: 100vh;
+ max-height: 100vh;
+ transition: none;
+ transform: none;
+
+ &, & > .o_header_collapsed_content_wrapper {
+ // TODO improve: ugly code to reset a potential wrapper
+ display: flex !important;
+ flex-flow: if($-hamburger-left, row, row-reverse) nowrap !important;
+ align-items: stretch !important;
+ justify-content: flex-start !important;
+ }
+ > .o_header_collapsed_content_wrapper {
+ // TODO improve: ugly code to reset a potential wrapper
+ max-width: none !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+
+ .o_offcanvas_menu_backdrop {
+ @include o-position-absolute(0, 0, 0, 0);
+ opacity: .2;
+ cursor: pointer;
+ }
+
+ #top_menu {
+ flex: 0 0 auto !important;
+ overflow: auto;
+ flex-flow: column nowrap !important;
+ @if $-hamburger-center {
+ width: 100%;
+ max-width: none;
+ } @else {
+ max-width: 560px;
+ text-align: left !important;
+ }
+ min-width: 250px;
+ margin: 0 !important;
+ background-color: o-color('menu');
+ transition: transform $-transition-duration cubic-bezier(.694, .0482, .335, 1);
+
+ @if $-hamburger-center {
+ .o_offcanvas_menu_backdrop {
+ display: none;
+ }
+ .o_offcanvas_menu_toggler {
+ max-width: 90%;
+ }
+ }
+
+ .nav-item, .o_offcanvas_logo {
+ padding-left: $grid-gutter-width;
+ padding-right: $grid-gutter-width;
+ }
+ .nav-item, .dropdown-menu {
+ text-align: inherit;
+ }
+ .nav-item, .nav-link {
+ margin: 0 !important;
+ }
+
+ .navbar-toggler {
+ display: block !important;
+ }
+
+ // Open all dropdowns
+ .dropdown-toggle {
+ padding-bottom: $nav-link-padding-y*0.5;
+
+ &:after {
+ content: none;
+ }
+ }
+ .dropdown-menu {
+ display: block;
+ padding-top:0;
+ border: 0;
+ background: inherit;
+ color: inherit;
+ }
+ .dropdown-item {
+ padding-left: .5em;
+ padding-right: .5em;
+ }
+ }
+
+ .o_connected_user:not(.editor_has_snippets) header & {
+ top: -$o-navbar-height;
+ padding-top: $o-navbar-height;
+ }
+ }
+ &.collapsing #top_menu {
+ @if $-hamburger-center {
+ transform: translateY(-100%);
+ } @else if $-hamburger-left {
+ transform: translateX(-100%);
+ } @else if $-hamburger-right {
+ transform: translateX(100%);
+ }
+ }
+ &.show #top_menu {
+ transform: translate(0);
+ }
+
+ .o_offcanvas_menu_backdrop {
+ @if $-hamburger-left {
+ background-image: linear-gradient(90deg, currentColor 20%, transparent);
+ } @else {
+ background-image: linear-gradient(-90deg, currentColor 20%, transparent);
+ }
+ }
+ }
+}
+
+@if o-website-value('header-template') == 'vertical' {
+ header .o_header_centered_logo {
+ order: -1;
+ width: 50%;
+ margin-top: $spacer;
+
+ @include media-breakpoint-up(lg) {
+ order: inherit;
+ width: 40%;
+ margin-bottom: $spacer;
+ }
+ }
+ .navbar-nav {
+ padding-top: $navbar-padding-y;
+ padding-bottom: $navbar-padding-y;
+ }
+} @else if o-website-value('header-template') == 'sidebar' {
+ @include media-breakpoint-up(lg) {
+ #wrapwrap {
+ // Hack: padding is used by layout option (boxed, etc) so use
+ // border here to be able to combine the effect.
+ @if $-hamburger-right {
+ border-right: o-website-value('sidebar-width') solid transparent;
+ } @else {
+ border-left: o-website-value('sidebar-width') solid transparent;
+ }
+
+ > header {
+ @if $-hamburger-right {
+ @include o-position-absolute(0, 0, 0, auto);
+ } @else {
+ @include o-position-absolute(0, auto, 0, 0);
+ }
+ position: fixed;
+ z-index: $zindex-fixed;
+ display: flex;
+ width: o-website-value('sidebar-width');
+ transform: none !important;
+
+ .navbar {
+ width: 100%;
+ align-items: start;
+ padding: $spacer;
+
+ .navbar-brand {
+ max-width: 100%;
+ padding: 0 0 $spacer 0;
+ }
+ #top_menu_container {
+ flex-direction: column;
+ align-items: start;
+ padding: 0;
+ }
+ .navbar-nav {
+ flex-direction: column;
+ }
+ .nav-link,
+ .dropdown-item {
+ white-space: initial;
+ }
+ .dropdown-menu {
+ position: static;
+ }
+ }
+ }
+ }
+ body.o_connected_user {
+ &:not(.editor_has_snippets) #wrapwrap > header {
+ top: $o-navbar-height;
+ }
+ &.editor_has_snippets #wrapwrap > header {
+ @if $-hamburger-right {
+ right: $o-we-sidebar-width;
+ }
+ }
+ }
+ }
+} @else if o-website-value('header-template') == 'boxed' {
+ #wrapwrap:not(.o_header_overlay) .o_header_boxed_background {
+ @include o-apply-colors('header-boxed');
+ }
+} @else if o-website-value('header-template') == 'centered_logo' {
+ header .o_header_centered_logo {
+ @include media-breakpoint-up(lg) {
+ width: 50%;
+ }
+ }
+} @else if o-website-value('header-template') == 'hamburger-full' {
+ @if not $-off-canvas-hamburger {
+ @include media-breakpoint-up(md) {
+ #wrapwrap {
+ $o-hamburger-full-navbar-height: $o-theme-navbar-logo-height + ($navbar-padding-y * 2);
+ > header {
+ .navbar-collapse {
+ > .container {
+ height: calc(100vh - #{$o-navbar-height} - #{$o-hamburger-full-navbar-height});
+ transition: height .3s ease;
+ }
+ .nav-link {
+ padding-right: $nav-link-padding-x;
+ padding-left: $nav-link-padding-x;
+ }
+ .dropdown-menu {
+ position: absolute;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// Mega menu
+.o_mega_menu {
+ width: 100%;
+ padding: 0;
+ margin-top: 0;
+ border-radius: 0;
+ background-clip: unset; // Remove the 1px gap introduced by BS4
+
+ .container, .container-fluid {
+ // Need to reforce those because they are removed since its a container
+ // inside another container (the one in the navbar)
+ padding-left: $grid-gutter-width / 2;
+ padding-right: $grid-gutter-width / 2;
+ }
+}
+.o_mega_menu_container_size {
+ @include media-breakpoint-up(md) {
+ left: 50%;
+ transform: translateX(-50%);
+ }
+
+ $-mm-max-widths: ();
+ @each $k, $v in $container-max-widths {
+ $-mm-max-widths: map-merge($-mm-max-widths, (
+ #{$k}: $v - $grid-gutter-width,
+ ));
+ }
+ @include make-container-max-widths($-mm-max-widths);
+}
+
+#wrapwrap.o_header_overlay {
+ > header:not(.o_header_affixed):not(.o_top_menu_collapse_shown) {
+ @include o-position-absolute(0, 0, auto, 0);
+ z-index: 1000;
+
+ > .navbar {
+ @include o-apply-colors(1); // Reset to default colored components
+ background-color: transparent !important;
+ border-color: transparent;
+ color: inherit;
+
+ .nav-item {
+ > .nav-link {
+ &, &:hover {
+ background-color: transparent;
+ color: inherit;
+ }
+
+ &.active {
+ font-weight: bolder;
+ }
+ }
+ }
+ }
+ }
+}
+
+// Navbar Links Styles
+@if index(('block', 'border-bottom'), o-website-value('header-links-style')) {
+ @include media-breakpoint-up(md) {
+ .navbar,
+ .navbar-nav {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+ }
+}
+.navbar-nav {
+ .nav-link {
+ @if o-website-value('header-links-style') == 'outline' {
+ // Need to force the padding in this case so that it stays in mobile
+ padding-right: $navbar-nav-link-padding-x;
+ padding-left: $navbar-nav-link-padding-x;
+ border: $border-width solid transparent;
+ @include border-radius($nav-pills-border-radius);
+ } @else if o-website-value('header-links-style') == 'block' {
+ // There is no way to control navbar links vertical padding in BS4
+ // independently from nav ones, just double them here instead
+ padding-top: $nav-link-padding-y * 2;
+ padding-bottom: $nav-link-padding-y * 2;
+ @include border-radius(0);
+ } @else if o-website-value('header-links-style') == 'border-bottom' {
+ // There is no way to control navbar links vertical padding in BS4
+ // independently from nav ones, just double them here instead
+ padding-top: ($nav-link-padding-y * 2);
+ padding-bottom: ($nav-link-padding-y * 2);
+ border-bottom: $nav-link-padding-y solid transparent;
+
+ // Replace horizontal paddings by margins (do this with an extra
+ // class to override .navbar-expand-* paddings priority).
+ .navbar & {
+ padding-left: 0;
+ padding-right: 0;
+ margin: 0 $navbar-nav-link-padding-x;
+ }
+ }
+ }
+
+ @if index(('outline', 'border-bottom'), o-website-value('header-links-style')) {
+ .nav-link.active,
+ .show > .nav-link {
+ border-color: currentColor;
+ }
+ }
+}
+
+@if index(('slideout_slide_hover', 'slideout_shadow'), o-website-value('footer-effect')) {
+ @include media-breakpoint-up(lg) {
+ #wrapwrap.o_footer_effect_enable {
+ > main {
+ background-color: $body-bg;
+ @if o-website-value('footer-effect') == 'slideout_shadow' {
+ box-shadow: $box-shadow;
+ }
+ }
+ > footer {
+ @include o-position-sticky(auto, 0, 0, 0);
+ z-index: -1;
+ }
+ }
+ }
+}
+
+// Language selector
+.js_language_selector {
+ .dropdown-menu {
+ min-width: 0;
+ }
+ a.list-inline-item {
+ padding: 3px 0;
+
+ > * {
+ vertical-align: middle;
+ }
+ }
+}
+.o_lang_flag {
+ width: 1.5em;
+ height: 1.5em;
+ margin-right: 0.2em;
+ border-radius: $rounded-pill;
+}
+span.list-inline-item.o_add_language:last-child {
+ display: none !important; // Hide the separator if it is the last list item
+}
+
+// Footer scrolltop button
+@if o-website-value('footer-scrolltop') {
+ #o_footer_scrolltop {
+ $-footer-color: o-color('footer');
+ $-copyright-color: o-color('copyright');
+ $-copyright-color: mix(rgba($-copyright-color, 1.0), $-footer-color, percentage(alpha($-copyright-color)));
+
+ box-sizing: content-box;
+ width: 3rem;
+ height: 3rem;
+ border: 0;
+ padding: 0;
+ @include o-apply-colors('footer', $with-extras: false, $background: $-footer-color);
+ text-decoration: none;
+
+ @if $-footer-color == $-copyright-color {
+ color: rgba(color-yiq($-footer-color), 0.5);
+ }
+
+ @include hover-focus {
+ @include o-apply-colors($-copyright-color, $with-extras: false, $background: $-footer-color);
+ text-decoration: none;
+ }
+ }
+}
+
+// Figure with special style
+.o_figure_relative_layout {
+ position: relative;
+
+ .figure-img {
+ margin-bottom: 0;
+ }
+ .figure-caption {
+ @include o-position-absolute(auto, 0, 0, 0);
+ @include o-bg-color(rgba(theme-color('dark'), $o-theme-figcaption-opacity));
+ padding: $tooltip-padding-y $tooltip-padding-x;
+ font-weight: $font-weight-bold;
+ a {
+ color: inherit;
+ }
+ }
+}
+
+@each $color, $value in $theme-colors {
+ .bg-#{$color}-light {
+ background-color: rgba($value, 0.1);
+ }
+}
+
+@each $media, $color in $o-social-colors {
+ @include text-emphasis-variant(".text-#{$media}", $color);
+}
+
+// TODO: Will be handled properly in master/saas-12.2, temp fix for website_event.registration_attendee_details
+.modal-footer > .float-left {
+ margin-right: auto;
+}
+
+// CoverProperties
+.o_record_cover_container {
+ position: relative;
+
+ .o_record_cover_component {
+ @include o-position-absolute(0, 0, 0, 0);
+
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ }
+}
+
+// Scroll down button
+.o_scroll_button {
+ @include o-position-absolute(auto, 0, 0, 0);
+ display: flex;
+ width: 50px;
+ height: 50px;
+ animation: o-anim-heartbeat 2.6s ease-in-out 1s infinite;
+
+ &, &:hover {
+ text-decoration: none;
+ }
+ &:focus {
+ outline: none;
+ }
+ &:hover {
+ animation-iteration-count: 1;
+ }
+}
+
+// Attention keeper for the "scroll down" top-banner button
+@keyframes o-anim-heartbeat {
+ 0%, 14%, 35% {
+ transform: scale(1);
+ }
+ 7%, 21% {
+ transform: scale(1.3);
+ background-color: rgba(theme-color('primary'), 0.8);
+ }
+}
+
+// Ribbons
+$ribbon-padding: 100px;
+.o_ribbon {
+ margin: 0;
+ font-size: 1rem;
+ font-weight: bold;
+ white-space: nowrap;
+ text-align: center;
+ pointer-events: none;
+}
+
+.o_ribbon_right {
+ @include o-ribbon-right();
+}
+
+.o_ribbon_left {
+ @include o-ribbon-left();
+}
+
+.o_tag_right {
+ @include o-tag-right();
+}
+
+.o_tag_left {
+ @include o-tag-left();
+}
+
+// Cookies Bar
+#website_cookies_bar {
+ :not(.o_cookies_popup) {
+ bottom: 0;
+ }
+}
+
+.o_website_btn_loading {
+ cursor: wait;
+ opacity: $btn-disabled-opacity;
+ .fa:not(.fa-spin) {
+ display: none;
+ }
+}
+
+// Snippet Showcase
+.s_showcase_icon {
+ // Avoid images stretched depending on title size (when icons
+ // are images an not Font Awesome icons). Because the default
+ // value of "align-self" is "strech". We put this code here to
+ // avoid having to create a new scss file in a stable version.
+ align-self: flex-start;
+}
+
+// Bottom fixed element (e.g. livechat button)
+.modal-open .o_bottom_fixed_element, .o_bottom_fixed_element_hidden {
+ // Prevent bottom fixed elements from hidding buttons and
+ // hide them if a modal is open.
+ display: none !important;
+}