diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/website/static/src/scss | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/website/static/src/scss')
17 files changed, 4145 insertions, 0 deletions
diff --git a/addons/website/static/src/scss/bootstrap_overridden.scss b/addons/website/static/src/scss/bootstrap_overridden.scss new file mode 100644 index 00000000..e43f0684 --- /dev/null +++ b/addons/website/static/src/scss/bootstrap_overridden.scss @@ -0,0 +1,132 @@ +// +// Color system +// + +// Use auto threshold for yiq colors +// Note: also need to be defined here so that color-yiq below works +$yiq-contrasted-threshold: false !default; + +// Customize the light and dark text colors for use in our YIQ color contrast function. +$yiq-text-dark: o-color('900') !default; +$yiq-text-light: o-color('white') !default; + +// Spacing +// +// Control the default styling of most Bootstrap elements by modifying these +// variables. Mostly focused on spacing. +// You can add more entries to the $spacers map, should you need more variation. + +$spacer: 1rem !default; // Need to predefine as used below + +// Body +// +// Settings for the `<body>` element. + +$body-bg: if(o-website-value('layout') != 'full', o-color('body'), o-color('o-cc1-bg')) !default; +$body-color: o-color('o-cc1-text') or color-yiq(o-color('o-cc1-bg')) !default; + +// Links +// +// Style anchor elements. + +$-link-color: o-color('o-cc1-link'); +$-link-color: if($-link-color, $-link-color, o-color('primary')); +$link-color: auto-contrast($-link-color, o-color('o-cc1-bg'), 'o-cc1-link') !default; +$link-hover-color: auto-contrast(darken($link-color, 15%), o-color('o-cc1-bg'), 'o-cc1-link') !default; +$link-decoration: if(o-website-value('link-underline') == 'always', underline, none) !default; +$link-hover-decoration: if(o-website-value('link-underline') != 'never', underline, none) !default; + +// Components +// +// Define common padding and border radius sizes and more. + +// Note: for the 'active' color, color preset edition is not really flexible but +// this could come in a future update. +$component-active-bg: o-color('o-cc1-btn-primary') !default; +$component-active-color: if($component-active-bg, color-yiq($component-active-bg), null) !default; + +// Fonts +// +// Font, line-height, and color for body text, headings, and more. + +$font-family-sans-serif: $o-theme-font !default; + +$font-size-base: o-website-value('font-size-base') !default; + +$h1-font-size: $font-size-base * $o-theme-h1-font-size-multiplier !default; +$h2-font-size: $font-size-base * $o-theme-h2-font-size-multiplier !default; +$h3-font-size: $font-size-base * $o-theme-h3-font-size-multiplier !default; +$h4-font-size: $font-size-base * $o-theme-h4-font-size-multiplier !default; +$h5-font-size: $font-size-base * $o-theme-h5-font-size-multiplier !default; +$h6-font-size: $font-size-base * $o-theme-h6-font-size-multiplier !default; + +$headings-font-family: $o-theme-headings-font !default; +$headings-color: o-color('o-cc1-headings') !default; + +$text-muted: mute-color($body-color) !default; + +// Buttons +// +// For each of Bootstrap's buttons, define text, background, and border color. + +$btn-padding-y: o-website-value('btn-padding-y') !default; +$btn-padding-x: o-website-value('btn-padding-x') !default; +$btn-font-size: o-website-value('btn-font-size') !default; + +$btn-padding-y-sm: o-website-value('btn-padding-y-sm') !default; +$btn-padding-x-sm: o-website-value('btn-padding-x-sm') !default; +$btn-font-size-sm: o-website-value('btn-font-size-sm') !default; + +$btn-padding-y-lg: o-website-value('btn-padding-y-lg') !default; +$btn-padding-x-lg: o-website-value('btn-padding-x-lg') !default; +$btn-font-size-lg: o-website-value('btn-font-size-lg') !default; + +$btn-border-width: o-website-value('btn-border-width') !default; + +$btn-border-radius: o-website-value('btn-border-radius') !default; +$btn-border-radius-lg: o-website-value('btn-border-radius-lg') !default; +$btn-border-radius-sm: o-website-value('btn-border-radius-sm') !default; + +// Forms + +$input-padding-y: o-website-value('input-padding-y') !default; +$input-padding-x: o-website-value('input-padding-x') !default; +$input-font-size: o-website-value('input-font-size') !default; + +$input-padding-y-sm: o-website-value('input-padding-y-sm') !default; +$input-padding-x-sm: o-website-value('input-padding-x-sm') !default; +$input-font-size-sm: o-website-value('input-font-size-sm') !default; + +$input-padding-y-lg: o-website-value('input-padding-y-lg') !default; +$input-padding-x-lg: o-website-value('input-padding-x-lg') !default; +$input-font-size-lg: o-website-value('input-font-size-lg') !default; + +$input-border-width: o-website-value('input-border-width') !default; + +$input-border-radius: o-website-value('input-border-radius') !default; +$input-border-radius-lg: o-website-value('input-border-radius-lg') !default; +$input-border-radius-sm: o-website-value('input-border-radius-sm') !default; + +// Navbar + +// Increase default navbar padding for some navbar styles +$navbar-padding-y: if(index(('fill', 'pills', 'outline'), o-website-value('header-links-style')), ($spacer / 2) * 1.25, null) !default; +$navbar-nav-link-padding-x: if(index(('outline', 'block'), o-website-value('header-links-style')), .5rem * 3, null) !default; +$navbar-nav-link-padding-x: if(o-website-value('header-links-style') == 'border-bottom', .5rem * 2, null) !default; + +// Jumbotron + +$jumbotron-bg: transparent !default; + +// Bootstrap Review + +$o-btn-outline-defaults: () !default; +@each $color in ('primary', 'secondary') { + @if o-website-value('btn-#{$color}-outline') { + $o-btn-outline-defaults: append($o-btn-outline-defaults, $color); + } +} + +// Increase default navbar pills padding for 'pills' mode and add big radius +$o-navbar-nav-pills-link-padding-x: if(o-website-value('header-links-style') == 'pills', 1rem * 1.5, null) !default; +$o-navbar-nav-pills-link-border-radius: if(o-website-value('header-links-style') == 'pills', 10rem, null) !default; diff --git a/addons/website/static/src/scss/compatibility/bs3_for_12_0.scss b/addons/website/static/src/scss/compatibility/bs3_for_12_0.scss new file mode 100644 index 00000000..179584b7 --- /dev/null +++ b/addons/website/static/src/scss/compatibility/bs3_for_12_0.scss @@ -0,0 +1,355 @@ +/** + * This file's purpose is to *ease* migration from 11.0. + */ + +// Restore gray utilities +$-compat-gray-map: ( + 'gray-darker': '900', + 'gray-dark': '900', + 'gray': '700', + 'gray-light': '600', + 'gray-lighter': '200', +) !default; +@each $old, $new in $-compat-gray-map { + @if not map-has-key($grays, $old) { + @include bg-variant(".bg-#{$old}", gray($new)); + @include text-emphasis-variant(".text-#{$old}", gray($new)); + } +} + +// Restore media ? + +// Restore progress bars +@each $color, $value in $theme-colors { + @include bg-variant(".progress-bar-#{$color}", $value); +} + +// Adapt radio ? + +// Adapt labels +.label { + @extend .badge; +} +@each $color, $value in $theme-colors { + .label-#{$color} { + @include badge-variant($value); + } +} +.label-default { + @include badge-variant(theme-color('secondary')); +} + +// Adapt center-block +.center-block { + display: block; + margin: auto; +} + +// Adapt pull-* classes +.pull-left { + float: left; +} +.pull-right { + float: right; +} + +// Adapt pagination +.pagination > li { + @extend .page-item; + > a { + @extend .page-link; + } +} + +// Adapt carousel +.carousel .item { + @extend .carousel-item; +} + +// Adapt checkboxes ? + +// Adapt tables +.table-condensed { + @extend .table-sm; +} + +// Adapt forms +.control-label { + @extend .col-form-label; +} +.help-block { + @extend .form-text; +} +.has-error .form-control { + @extend .is-invalid; +} +.has-success .form-control { + @extend .is-valid; +} +.form-horizontal .form-group { + @extend .row; +} + +// Adapt list-inline +.list-inline > li { + @extend .list-inline-item; +} + +// Adapt list-group +.panel .list-group { + @extend .list-group-flush; +} + +// Adapt image utilies +.img-rounded { + @extend .rounded; +} +.img-circle { + @extend .rounded-circle; +} + +// Adapt input group +.input-group { + .input-group-btn:first-child { + @extend .input-group-prepend; + } + .form-control ~ .input-group-btn { + @extend .input-group-append; + } + .input-group-addon { + @extend .input-group-append; + @extend .input-group-text; + } +} + +// Adapt panels +.panel { + @extend .card; +} +@each $color, $value in $theme-colors { + @include bg-variant(".panel-#{$color}", $value); +} +@include bg-variant(".panel-default", $white); +.panel-heading { + @extend .card-header; +} +.panel-body { + @extend .card-body; +} +.panel-footer { + @extend .card-footer; +} +.well { + @extend .card; + @extend .card-body; +} + +// Adapt grid (push-pull ?) +$-compat-breakpoints: ( + xs: map-get($grid-breakpoints, 'xs'), + sm: map-get($grid-breakpoints, 'md'), + md: map-get($grid-breakpoints, 'lg'), + lg: map-get($grid-breakpoints, 'xl'), +); +@each $breakpoint in map-keys($-compat-breakpoints) { + $infix: breakpoint-infix($breakpoint, $-compat-breakpoints); + $infix: if($infix != "", $infix, "-xs"); + + @include media-breakpoint-up($breakpoint, $-compat-breakpoints) { + // `$grid-columns - 1` because offsetting by the width of an entire row isn't possible + @for $i from 0 through ($grid-columns - 1) { + .col#{$infix}-offset-#{$i} { + @include make-col-offset($i, $grid-columns); + } + } + } +} + +// Adapt breadcrumb +.breadcrumb > li { + @extend .breadcrumb-item; +} + +// Adapt nav +.nav > li { + @extend .nav-item; + > a { + @extend .nav-link; + } +} +.nav-stacked { + flex-direction: column; +} +@include bg-variant(".navbar-default", $light); + +// Adapt img-responsive +.img-responsive { + @extend .img-fluid; +} + +// Adapt dropdowns +.dropdown-menu { + a { + @extend .dropdown-item; + } + .divider { + @extend .dropdown-divider; + } +} +.dropdown-toggle .caret { + display: none; +} + +// Adapt buttons +.btn-default { + @include button-variant(theme-color('secondary'), theme-color('secondary')); +} +.btn-xs { + @extend .btn-sm; +} + +// Adapt display classes +.hide { + display: none !important; +} +// The 'show' class could be supported if defined here and like that, +// unfortunately, BS4 still defines a 'show' class for other purposes which +// conflict with this (tab-pane, fade effects, ...). Adding more complex rules +// won't solve the problem as they would change css rules priorities. +// .show { +// display: block !important; +// } +.hidden { + display: none !important; +} +.visible { + &-xs, &-sm, &-md, &-lg { + &, &-block, &-inline, &-inline-block { + display: none !important; + } + } + &-xs { + &, &-block { + @include media-breakpoint-down(sm) { + display: block !important; + } + } + &-inline { + @include media-breakpoint-down(sm) { + display: inline !important; + } + } + &-inline-block { + @include media-breakpoint-down(sm) { + display: inline-block !important; + } + } + } + &-sm { + &, &-block { + @include media-breakpoint-only(md) { + display: block !important; + } + } + &-inline { + @include media-breakpoint-only(md) { + display: inline !important; + } + } + &-inline-block { + @include media-breakpoint-only(md) { + display: inline-block !important; + } + } + } + &-md { + &, &-block { + @include media-breakpoint-only(lg) { + display: block !important; + } + } + &-inline { + @include media-breakpoint-only(lg) { + display: inline !important; + } + } + &-inline-block { + @include media-breakpoint-only(lg) { + display: inline-block !important; + } + } + } + &-lg { + &, &-block { + @include media-breakpoint-up(xl) { + display: block !important; + } + } + &-inline { + @include media-breakpoint-up(xl) { + display: inline !important; + } + } + &-inline-block { + @include media-breakpoint-up(xl) { + display: inline-block !important; + } + } + } +} +.hidden { + &-xs { + @include media-breakpoint-down(sm) { + display: none !important; + } + } + &-sm { + @include media-breakpoint-only(md) { + display: none !important; + } + } + &-md { + @include media-breakpoint-only(lg) { + display: none !important; + } + } + &-lg { + @include media-breakpoint-up(xl) { + display: none !important; + } + } +} +.visible-print { + display: none !important; + + @media print { + display: block !important; + } + + &-block { + display: none !important; + + @media print { + display: block !important; + } + } + &-inline { + display: none !important; + + @media print { + display: inline !important; + } + } + &-inline-block { + display: none !important; + + @media print { + display: inline-block !important; + } + } +} +.hidden-print { + @media print { + display: none !important; + } +} diff --git a/addons/website/static/src/scss/options/colors/user_color_palette.scss b/addons/website/static/src/scss/options/colors/user_color_palette.scss new file mode 100644 index 00000000..7abaee4a --- /dev/null +++ b/addons/website/static/src/scss/options/colors/user_color_palette.scss @@ -0,0 +1,4 @@ + +$o-user-color-palette: map-merge($o-user-color-palette, o-map-omit(( + // -- hook -- +))); diff --git a/addons/website/static/src/scss/options/colors/user_theme_color_palette.scss b/addons/website/static/src/scss/options/colors/user_theme_color_palette.scss new file mode 100644 index 00000000..300db091 --- /dev/null +++ b/addons/website/static/src/scss/options/colors/user_theme_color_palette.scss @@ -0,0 +1,4 @@ + +$o-user-theme-color-palette: map-merge($o-user-theme-color-palette, o-map-omit(( + // -- hook -- +))); diff --git a/addons/website/static/src/scss/options/ripple_effect.scss b/addons/website/static/src/scss/options/ripple_effect.scss new file mode 100644 index 00000000..cff35300 --- /dev/null +++ b/addons/website/static/src/scss/options/ripple_effect.scss @@ -0,0 +1,28 @@ +@keyframes o-btn-ripple { + 100% { + opacity: 0; + transform: scale(2.5); + } +} + +.o_ripple_item { + display: none; + position: absolute; + z-index: -1; + border-radius: 100%; + opacity: .3; + background: currentColor; + pointer-events: none; + transform: scale(0); +} + +.o_js_ripple_effect { + transform-style: preserve-3d; + position: relative !important; + overflow: hidden !important; + + .o_ripple_item { + display: block; + animation: o-btn-ripple ease-in; + } +} diff --git a/addons/website/static/src/scss/options/user_values.scss b/addons/website/static/src/scss/options/user_values.scss new file mode 100644 index 00000000..3b6899ad --- /dev/null +++ b/addons/website/static/src/scss/options/user_values.scss @@ -0,0 +1,7 @@ +// This file is meant to be edited automatically by the user. The variables it +// contains should not be renamed otherwise it would break existing customers +// customizations. + +$o-user-website-values: map-merge($o-user-website-values, o-map-omit(( + // -- hook -- +))); diff --git a/addons/website/static/src/scss/primary_variables.scss b/addons/website/static/src/scss/primary_variables.scss new file mode 100644 index 00000000..5d1bd417 --- /dev/null +++ b/addons/website/static/src/scss/primary_variables.scss @@ -0,0 +1,409 @@ + +//------------------------------------------------------------------------------ +// Colors +//------------------------------------------------------------------------------ + +$o-base-color-palette: map-merge($o-base-color-palette, ( + 'body': $o-portal-default-body-bg, + 'menu': 1, // o_cc1 + 'menu-border-color': null, // Default to classes used on the template + 'header-boxed': '200', + 'footer': 5, // o_cc5 + 'copyright': 'black-15', +)); + +// By default, all user color palette values are null. Each null value is +// automatically replaced with corresponsing color of chosen color palette. +$o-user-color-palette: () !default; + +// By default, all user theme color palette values are null. Each null value +// is automatically replaced with corresponsing color of chosen theme color +// palette. +$o-user-theme-color-palette: () !default; + +$o-social-colors: ( + 'facebook': #3B5999, + 'twitter': #55ACEE, + 'linkedin': #0077B5, + 'google-plus': #DD4B39, + 'youtube': #ff0000, + 'github': #1a1e22, + 'instagram': #cf2872, + 'whatsapp': #25d366, + 'pinterest': #C8232C, +); + +$o-theme-figcaption-opacity: 0.6; + +$o-theme-generic-color-palettes: ( + ( + 'o-color-1': #984c46, + 'o-color-2': #23323b, + 'o-color-3': #eceae4, + 'o-color-4': #FFFFFF, + 'o-color-5': #16121f, + + 'menu': 3, + 'footer': 3, + ), + ( + 'o-color-1': #B99932, + 'o-color-2': #DED1C1, + 'o-color-3': #F5F5F5, + 'o-color-4': #FFFFFF, + 'o-color-5': #373737, + + 'menu': 5, + 'copyright': 4, + ), + ( + 'o-color-1': #f8882f, + 'o-color-2': #6a7c8f, + 'o-color-3': #fdf8ef, + 'o-color-4': #FFFFFF, + 'o-color-5': #212c39, + ), + ( + 'o-color-1': #6E7993, + 'o-color-2': #96848C, + 'o-color-3': #8F9AA2, + 'o-color-4': #D5D5D5, + 'o-color-5': #313347, + + 'menu': 5, + ), + ( + 'o-color-1': #F7CF41, + 'o-color-2': #1A2930, + 'o-color-3': #989898, + 'o-color-4': #FFFFFF, + 'o-color-5': #0B1612, + + 'menu': 3, + 'footer': 3, + ), + ( + 'o-color-1': #45859A, + 'o-color-2': #B57D4D, + 'o-color-3': #F5F5F5, + 'o-color-4': #FFFFFF, + 'o-color-5': #10273C, + + 'menu': 2, + 'footer': 2, + 'copyright': 5, + ), + ( + 'o-color-1': #1a547a, + 'o-color-2': #ddc76a, + 'o-color-3': #D6E6F1, + 'o-color-4': #FFFFFF, + 'o-color-5': #2b3442, + + 'o-cc5-link': 'o-color-4', + 'o-cc5-text': #9b9ba0, + + 'menu': 5, + 'footer': 5, + 'copyright': 3, + ), + ( + 'o-color-1': #763240, + 'o-color-2': #C19F7F, + 'o-color-3': #FFFFFF, + 'o-color-4': #EAEAEA, + 'o-color-5': #2F2F2F, + + 'o-cc4-headings': 'o-color-3', + 'o-cc4-link': 'o-color-3', + 'o-cc4-text': rgba(#fff, .8), + + 'o-cc5-headings': 'o-color-3', + 'o-cc5-link': 'o-color-3', + 'o-cc5-text': rgba(#fff, .8), + + 'footer': 1, + 'copyright': 4, + ), + ( + 'o-color-1': #4DC5C1, + 'o-color-2': #EC576B, + 'o-color-3': #E5E337, + 'o-color-4': #FFFFFF, + 'o-color-5': #000000, + + 'menu': 5, + ), + ( + 'o-color-1': #b56355, + 'o-color-2': #6ba17a, + 'o-color-3': #ebe6ea, + 'o-color-4': #FFFFFF, + 'o-color-5': #343733, + + 'footer': 2, + ), + ( + 'o-color-1': #01ACAB, + 'o-color-2': #FEDC3D, + 'o-color-3': #FAE8E0, + 'o-color-4': #FFFFFF, + 'o-color-5': #000000, + + 'footer': 1, + ), + ( + 'o-color-1': #926190, + 'o-color-2': #F3E0CD, + 'o-color-3': #F9EFE9, + 'o-color-4': #FFFFFF, + 'o-color-5': #291528, + + 'o-cc4-headings': 'o-color-4', + 'o-cc4-link': 'o-color-4', + 'o-cc4-text': rgba(#fff, .8), + + 'o-cc5-headings': 'o-color-4', + 'o-cc5-link': 'o-color-4', + 'o-cc5-text': rgba(#fff, .6), + ), + ( + 'o-color-1': #478FA2, + 'o-color-2': #CECECE, + 'o-color-3': #E8E9E9, + 'o-color-4': #FFFFFF, + 'o-color-5': #173F54, + + 'footer': 1, + 'copyright': 1, + ), + ( + 'o-color-1': #3CC37C, + 'o-color-2': #E9C893, + 'o-color-3': #F5F5F5, + 'o-color-4': #FFFFFF, + 'o-color-5': #1F3A2A, + + 'footer': 1, + 'copyright': 5, + ), + ( + 'o-color-1': #01524B, + 'o-color-2': #1993A3, + 'o-color-3': #dddde6, + 'o-color-4': #FFFFFF, + 'o-color-5': #011D1B, + + 'o-cc4-btn-primary': 'o-color-4', + 'o-cc4-link': 'o-color-4', + 'o-cc4-text': rgba(#fff, .8), + + 'o-cc5-btn-primary': 'o-color-4', + 'o-cc5-link': 'o-color-4', + 'o-cc5-text': rgba(#fff, .6), + + 'footer': 2, + 'copyright': 5, + ), + ( + 'o-color-1': #464D77, + 'o-color-2': #36827f, + 'o-color-3': #f2f0ec, + 'o-color-4': #FFFFFF, + 'o-color-5': #22263c, + + 'o-cc4-btn-primary': 'o-color-4', + 'o-cc4-link': 'o-color-4', + 'o-cc4-text': rgba(#fff, .8), + + 'o-cc5-btn-primary': 'o-color-4', + 'o-cc5-btn-secondary': #d6d4d0, + 'o-cc5-link': 'o-color-4', + 'o-cc5-text': rgba(#fff, .6), + + 'menu': 2, + 'footer': 2, + 'copyright': 5, + ), + ( + 'o-color-1': #4717f6, + 'o-color-2': #A43ACB, + 'o-color-3': #FAFAFA, + 'o-color-4': #FFFFFF, + 'o-color-5': #0F0A19, + + 'menu': 5, + 'footer': 5, + ), +); + +//------------------------------------------------------------------------------ +// Website customizations +//------------------------------------------------------------------------------ + +$o-base-website-values-palette: ( + 'font-size-base': 1rem, // Need a set value as the value is used in bootstrap_overridden files + 'google-fonts': null, + + 'body-image': null, + 'body-image-type': 'image', // 'image' or 'pattern' + + 'layout': 'full', // 'full' / 'boxed' + 'color-palettes-number': null, // Default to the individual variables for each color palette type + + 'btn-primary-outline': false, + 'btn-secondary-outline': false, + 'link-underline': 'hover', // 'never' / 'hover' / 'always' + 'btn-ripple': false, + + 'btn-padding-y': null, // Default to BS + 'btn-padding-x': null, // Default to BS + 'btn-font-size': null, // Default to BS + 'btn-padding-y-sm': null, // Default to portal value + 'btn-padding-x-sm': null, // Default to portal value + 'btn-font-size-sm': null, // Default to BS + 'btn-padding-y-lg': null, // Default to BS + 'btn-padding-x-lg': null, // Default to BS + 'btn-font-size-lg': null, // Default to BS + 'btn-border-width': null, // Default to BS + 'btn-border-radius': null, // Default to BS + 'btn-border-radius-sm': null, // Default to BS + 'btn-border-radius-lg': null, // Default to BS + + 'input-padding-y': null, // Default to BS + 'input-padding-x': null, // Default to BS + 'input-font-size': null, // Default to BS + 'input-padding-y-sm': null, // Default to BS + 'input-padding-x-sm': null, // Default to BS + 'input-font-size-sm': null, // Default to BS + 'input-padding-y-lg': null, // Default to BS + 'input-padding-x-lg': null, // Default to BS + 'input-font-size-lg': null, // Default to BS + 'input-border-width': null, // Default to BS + 'input-border-radius': null, // Default to BS + 'input-border-radius-sm': null, // Default to BS + 'input-border-radius-lg': null, // Default to BS + + // A key from the $o-theme-font-configs map (null = default to the first key) + 'font': null, + 'headings-font': null, + 'navbar-font': null, + 'buttons-font': null, + + 'header-template': 'default', // 'default' / 'hamburger' / 'vertical' / 'sidebar' + 'header-font-size': null, // Default to BS (normal font-size) + 'header-links-style': 'default', // 'default' / 'fill' / 'outline' / 'pills' / 'block' / 'border-bottom' + 'logo-height': null, // Default to navbar height (see portal) + 'hamburger-type': 'default', // 'default' / 'off-canvas' + 'hamburger-position': 'left', // 'left' / 'center' / 'right' + 'menu-border-width': null, // Default to classes used on the template + 'menu-border-style': solid, // Default to classes used on the template + 'menu-border-radius': null, // Default to classes used on the template + 'menu-box-shadow': null, // Default to classes used on the template + 'sidebar-width': 18.75rem, // 300px + + 'footer-template': 'default', + 'footer-effect': null, // null / 'slideout_slide_hover' / 'slideout_shadow' + 'footer-scrolltop': false, +); +$o-font-aliases-to-keys: ( + 'base': 'font', + 'headings': 'headings-font', + 'navbar': 'navbar-font', + 'buttons': 'buttons-font', +); +$o-website-values-palettes: ( + ( + 'headings-font': 'Source Sans Pro', + 'navbar-font': 'Source Sans Pro', + 'buttons-font': 'Source Sans Pro', + ), +) !default; +$o-website-values-palette-number: 1 !default; + +// By default, all user website values are null. Each null value is +// automatically replaced with corresponsing value of chosen values palette. +$o-user-website-values: () !default; + +//------------------------------------------------------------------------------ +// Fonts +//------------------------------------------------------------------------------ + +// Those are BS values, except BS hardcodes them inside the $hx-font-size +// variables directly and don't make them customizable. +$o-theme-h1-font-size-multiplier: 2.5 !default; +$o-theme-h2-font-size-multiplier: 2 !default; +$o-theme-h3-font-size-multiplier: 1.75 !default; +$o-theme-h4-font-size-multiplier: 1.5 !default; +$o-theme-h5-font-size-multiplier: 1.25 !default; +$o-theme-h6-font-size-multiplier: 1 !default; + +// Map: +// <font-name>: ( +// 'family': <css font family list>, +// 'url': <related part of google fonts URL>, +// 'properties' (optional): ( +// <font-alias>: ( +// <website-value-key>: <value>, +// ..., +// ), +// ..., +// ) +// ) +$o-theme-font-configs: ( + 'Roboto': ( + 'family': ('Roboto', sans-serif), + 'url': 'Roboto:300,300i,400,400i,700,700i', + ), + 'Open Sans': ( + 'family': ('Open Sans', sans-serif), + 'url': 'Open+Sans:300,300i,400,400i,700,700i', + ), + 'Source Sans Pro': ( + 'family': ('Source Sans Pro', sans-serif), + 'url': 'Source+Sans+Pro:300,300i,400,400i,700,700i', + ), + 'Raleway': ( + 'family': ('Raleway', sans-serif), + 'url': 'Raleway:300,300i,400,400i,700,700i', + ), + 'Noto Serif': ( + 'family': ('Noto Serif', serif), + 'url': 'Noto+Serif:300,300i,400,400i,700,700i', + ), + 'Arvo': ( + 'family': ('Arvo', Times, serif), + 'url': 'Arvo:300,300i,400,400i,700,700i', + ), +) !default; + +//------------------------------------------------------------------------------ +// Mixins +//------------------------------------------------------------------------------ + +@mixin o-ribbon-right() { + @include o-position-absolute($top: 0, $right: 0); + padding: 0.5rem $ribbon-padding; + // 0.708 is 1 - cos(45deg) + // Transforms are applied right-to-left + // Cannot use matrix because of the use of % values. + transform: translateX(calc(-0.708 * (100% - #{2 * $ribbon-padding}))) rotate(45deg) translateX(calc(100% - #{$ribbon-padding})); + transform-origin: top right; +}; + +@mixin o-ribbon-left() { + @include o-position-absolute($top: 0, $left: 0); + padding: 0.5rem $ribbon-padding; + transform: translateX(calc(0.708 * (100% - #{2 * $ribbon-padding}) - 100%)) rotate(-45deg) translateX($ribbon-padding); + transform-origin: top right; +}; + +@mixin o-tag-right() { + @include o-position-absolute($top: 0, $right: 0); + padding: 0.25rem 1rem; +}; + +@mixin o-tag-left() { + @include o-position-absolute($top: 0, $left: 0); + padding: 0.25rem 1rem; +}; diff --git a/addons/website/static/src/scss/secondary_variables.scss b/addons/website/static/src/scss/secondary_variables.scss new file mode 100644 index 00000000..53f8f9ed --- /dev/null +++ b/addons/website/static/src/scss/secondary_variables.scss @@ -0,0 +1,194 @@ +//------------------------------------------------------------------------------ +// Website customizations +//------------------------------------------------------------------------------ + +// Complete the base website values palette with the first defined font +$-first-font-name: nth(map-keys($o-theme-font-configs), 1); +@each $alias, $key in $o-font-aliases-to-keys { + @if map-get($o-base-website-values-palette, $key) == null { + $o-base-website-values-palette: map-merge($o-base-website-values-palette, ( + $key: $-first-font-name, + )); + } +} + +@function o-add-font-config($values) { + @each $alias, $key in $o-font-aliases-to-keys { + $font-name: map-get($values, $key); + $font-config: o-safe-get($o-theme-font-configs, $font-name, ()); + $font-properties: o-safe-get($font-config, 'properties', ()); + $type-font-properties: o-safe-get($font-properties, $alias, ()); + $values: map-merge($values, $type-font-properties); + } + @return $values; +} + +// Some fonts have been renamed in a stable version, and for retro compatibility +// for users which have a custom user_values.css as attachment with an old font +// already used, we map the old font with the new `similar` font +$o-fonts-similar: ( + 'Droid Serif': 'Noto Serif', + 'SinKinSans': 'Spartan', + 'Proxima': 'Montserrat', + 'Comic Sans MS': 'Comic Neue', + 'Fontastique': 'Bubblegum Sans', + 'Luminari': 'Eagle Lake', + 'Fecske': 'Marcellus', + 'Din Alternate': 'Roboto', +); + +@function o-map-font-aliases($values) { + $-values: $values; + @each $key in map-values($o-font-aliases-to-keys) { + $value: map-get($values, $key); + @if ($value and map-has-key($o-fonts-similar, $value)) { + $-values: map-merge($-values, ( + $key: map-get($o-fonts-similar, $value), + )); + } + } + @return $-values; +}; + +// By default, most website palette values are null. Each null value is +// automatically replaced with corresponsing values in chosen default values +// palette. +$-website-values-default: o-safe-nth($o-website-values-palettes, $o-website-values-palette-number, ()); +$-website-values-default: map-merge($o-base-website-values-palette, o-map-omit($-website-values-default)); +$o-user-website-values: o-map-font-aliases(o-map-omit($o-user-website-values)); +$-actual-user-website-values-palette: map-merge($-website-values-default, $o-user-website-values); +// Default font selection + User font selection have been merged, now need to +// add the right associated font default config +$-actual-user-website-values-palette: o-add-font-config($-actual-user-website-values-palette); +// Reforce the properties which already had a set values in the user map (the +// font properties override the default palette values but not the user ones) +$-actual-user-website-values-palette: map-merge($-actual-user-website-values-palette, $o-user-website-values); +$o-website-values-palettes: append($o-website-values-palettes, $-actual-user-website-values-palette); + +// Enable last website values palette, which is now the user customized one +$o-website-values-palette-number: length($o-website-values-palettes); +$o-website-values: $-actual-user-website-values-palette !default; +@function o-website-value($key) { + @return map-get($o-website-values, $key); +} + +$o-theme-navbar-logo-height: o-website-value('logo-height') !default; +$o-theme-navbar-fixed-logo-height: o-website-value('fixed-logo-height') !default; + +//------------------------------------------------------------------------------ +// Colors +//------------------------------------------------------------------------------ + +// First change the palette number to the actual user choice if any. +$-color-palettes-number: o-website-value('color-palettes-number'); +@if $-color-palettes-number { + $o-color-palette-number: $-color-palettes-number; + $o-theme-color-palette-number: $-color-palettes-number; + $o-gray-color-palette-number: $-color-palettes-number; +} + +$o-has-customized-13-0-color-system: + not not (map-get($o-user-theme-color-palette, 'primary') + or map-get($o-user-theme-color-palette, 'secondary') + or map-get($o-user-theme-color-palette, 'alpha') + or map-get($o-user-theme-color-palette, 'beta') + or map-get($o-user-theme-color-palette, 'gamma') + or map-get($o-user-theme-color-palette, 'delta') + or map-get($o-user-theme-color-palette, 'epsilon')); + +$o-has-customized-colors: + not not (length(map-keys(o-map-omit($o-user-color-palette))) > 0 + or map-get($o-user-theme-color-palette, 'success') + or map-get($o-user-theme-color-palette, 'info') + or map-get($o-user-theme-color-palette, 'warning') + or map-get($o-user-theme-color-palette, 'danger')); + +// Color palette +// ------------- + +// Add generic color palettes +$o-color-palettes: join($o-color-palettes, $o-theme-generic-color-palettes); + +// By default, most user color palette values are null. Each null value is +// automatically replaced with corresponsing colors in chosen default color +// palette. +$-palette-default: o-safe-nth($o-color-palettes, $o-color-palette-number, ()); +$-actual-user-color-palette: map-merge($-palette-default, o-map-omit($o-user-color-palette)); +$o-color-palettes: append($o-color-palettes, $-actual-user-color-palette); + +// Theme color palette +// ------------------- + +// alpha -> epsilon colors are from the old color system, this is kept for +// compatibility: Generate default theme color scheme if alpha is set +$-alpha: map-get($o-user-theme-color-palette, 'alpha'); +@if ($-alpha) { + $o-user-theme-color-palette: map-merge(( + beta: lighten(desaturate($-alpha, 60%), 30%), + gamma: desaturate(adjust-hue($-alpha, -45deg), 10%), + delta: desaturate(adjust-hue($-alpha, 45deg), 10%), + epsilon: desaturate(adjust-hue($-alpha, 180deg), 10%), + ), o-map-omit($o-user-theme-color-palette)); +} + +// By default, all user theme color palette values are null. Each null value is +// automatically replaced with corresponsing colors in chosen default theme +// color palette. +$-palette-default: o-safe-nth($o-theme-color-palettes, $o-theme-color-palette-number, ()); +$-actual-user-theme-color-palette: map-merge($-palette-default, o-map-omit($o-user-theme-color-palette)); +// Always remove the primary/secondary which were customizable in some theme +// in Odoo <= 13.3. The customer can always rechoose the right color in the +// Odoo color system as the first two ones are mapped to primary/secondary. +$-actual-user-theme-color-palette: map-remove($-actual-user-theme-color-palette, + 'primary', + 'secondary' +); +$o-theme-color-palettes: append($o-theme-color-palettes, $-actual-user-theme-color-palette); + +// --- + +// Enable last color and theme color palettes, which are now the user customized +// color palettes. +$o-original-color-palette-number: $o-color-palette-number; +$o-color-palette-number: length($o-color-palettes); +$o-theme-color-palette-number: length($o-theme-color-palettes); + +$o-we-auto-contrast-exclusions: () !default; +$o-we-auto-contrast-exclusions: join($o-we-auto-contrast-exclusions, map-keys(o-map-omit($o-user-color-palette))); + +//------------------------------------------------------------------------------ +// Fonts +//------------------------------------------------------------------------------ + +// Merge base fonts with user-added google fonts +@each $font-name in (o-website-value('google-fonts') or ()) { + $o-theme-font-configs: map-merge($o-theme-font-configs, ( + $font-name: ( + 'family': (quote($font-name), sans-serif), + 'url': quote($font-name) + ':300,300i,400,400i,700,700i', + ), + )); +} + +// Add odoo unicode support for all fonts +@each $font-name, $font-config in $o-theme-font-configs { + $o-theme-font-configs: map-merge($o-theme-font-configs, ( + $font-name: map-merge($font-config, ( + 'family': o-add-unicode-support-font(map-get($font-config, 'family')), + )), + )); +} + +// Function which allows to retrieve a base info (family, url, properties) about +// a component (base, navbar, ...)'s font. The font name is retrievable via a +// simple o-website-value call. +@function o-get-font-info($alias: 'base', $config-key: 'family') { + $key: map-get($o-font-aliases-to-keys, $alias); + $font-name: o-website-value($key); + $-font-config: o-safe-get($o-theme-font-configs, $font-name, ()); + @return map-get($-font-config, $config-key); +} +$o-theme-font: o-get-font-info('base') or (sans-serif,) !default; +$o-theme-headings-font: o-get-font-info('headings') or $o-theme-font !default; +$o-theme-navbar-font: o-get-font-info('navbar') or $o-theme-font !default; +$o-theme-buttons-font: o-get-font-info('buttons') or $o-theme-font !default; diff --git a/addons/website/static/src/scss/user_custom_bootstrap_overridden.scss b/addons/website/static/src/scss/user_custom_bootstrap_overridden.scss new file mode 100644 index 00000000..ecf5d460 --- /dev/null +++ b/addons/website/static/src/scss/user_custom_bootstrap_overridden.scss @@ -0,0 +1,22 @@ +// +// /!\ +// This file is meant to regroup your bootstrap customizations. In that file, +// you must define variables *ONLY*. If you want to introduce new CSS rules +// for your website, check the 'user_custom_rules.scss' file you can also edit. +// /!\ +// +// You can change the value of a variable you can find in the bootstrap 4 +// documentation (or in the file /web/static/lib/bootstrap/scss/_variables.scss) +// and Odoo will automatically adapt its design to your new bootstrap. For +// example, doing this will make some shadows and gradients appear, especially +// for your buttons design: +// +// $enable-shadows: true; +// $enable-gradients: true; +// +// Notice that Odoo already overrides bootstrap variables according to your +// choices in the "Customize Theme" dialog, you should first take a look at +// it and do customizations this way. Indeed, if you overridde the same +// variables, Odoo will either have to ignore them or not be able to make +// the "Customize Theme" dialog work for these variables anymore. +// diff --git a/addons/website/static/src/scss/user_custom_rules.scss b/addons/website/static/src/scss/user_custom_rules.scss new file mode 100644 index 00000000..181c4c17 --- /dev/null +++ b/addons/website/static/src/scss/user_custom_rules.scss @@ -0,0 +1,8 @@ +// +// This file is meant to regroup your design customizations. For example, doing +// this will separate your footer with a dotted border using your primary color. +// +// footer { +// border-top: 5px dotted theme-color('primary'); +// } +// diff --git a/addons/website/static/src/scss/website.backend.scss b/addons/website/static/src/scss/website.backend.scss new file mode 100644 index 00000000..1122930e --- /dev/null +++ b/addons/website/static/src/scss/website.backend.scss @@ -0,0 +1,452 @@ +.o_dashboards { + background-color: #ececec; + + .o_website_dashboard { + background-color: #ececec; + div.o_box { + @include clearfix; + color: $o-main-color-muted; + background-color: $o-view-background-color; + background-size: cover; + margin-top: $o-horizontal-padding; + position: static; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.3); + + h2, h4 { + text-transform: uppercase; + margin-top: 0; + color: $o-brand-odoo; + } + + h4 { margin: 0 0 0 8px; } + + .col-lg-7, .col-12 { + padding: 15px; + + .js_field_selection { + width: 30%; + margin: 0 0 20px 0; + float: right; + border-radius: 0; + } + + .table-responsive { + border: none; + } + + table { + + tr:first-child { + background: white; + } + + tr:nth-child(even):not(:hover) { + background: #f5f6f7; + } + + th { + text-transform: uppercase; + color: $o-main-text-color; + border-top-width: 0px; + } + td, th { + text-align: right; + border-left: none; + + &:first-child { + text-align: left; + } + } + .o_tooltip_key { + text-align: left; + } + } + } + } + + .o_dashboard_common { + .o_box { + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + > .o_inner_box { + @include media-breakpoint-down(sm) { + flex: 1 1 200px; + display: block !important; + } + @include media-breakpoint-up(md) { + flex: 0 0 16.6%; + } + } + } + .o_inner_box { + padding-top: 10px; + text-align: center; + border: 1px solid $o-view-background-color; + height: 80px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + cursor: pointer; + color: white; + background-color: $o-brand-primary; + &:hover { + background-color: darken($o-brand-primary, 10%); + } + &.o_primary { + background-color: $o-brand-odoo; + color: white; + &:hover { + background-color: darken($o-brand-odoo, 10%); + } + } + .o_highlight { + font-size: 27px; + } + } + } + + .o_graph_sales { + direction: ltr#{"/*rtl:ignore*/"}; + .o_legend0 { + background-color: $o-brand-primary; + } + .o_legend1 { + background-color: $o-main-color-muted; + } + } + + .o_dashboard_visits { + + h2 { + padding: 15px; + } + + .o_demo_background { + + margin-top: 16px; + height: 300px; + background-size: 100% !important; + background: url("/website/static/src/img/website_dashboard_visit_demo.png") no-repeat; + position: relative; + + .o_buttons { + position: relative; + + > button { + display: block; + } + } + + .o_layer { + background-color: rgba(255,255,255,.3); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + } + + .o_properties_selection { + + @include media-breakpoint-up(lg) { + display: flex; + } + + margin-top: 10px; + margin-bottom: 10px; + } + + .gapi-analytics-auth-styles-signinbutton { + cursor: pointer; + } + + .ActiveUsers { + position: relative; + float: right; + right: 10px; + border: 1px solid gray('200'); + font-weight: 300; + white-space: nowrap; + padding: .5em 1.5em; + margin: .5em; + text-transform: uppercase; + } + + .ActiveUsers-value { + font-weight: 300; + margin-right: -.25em; + } + + .ActiveUsers.is-increasing { + animation: increase 3s; + } + + .ActiveUsers.is-decreasing { + animation: decrease 3s; + } + + @keyframes increase { + 10% { + background-color: lighten($o-brand-primary, 30%); + border-color: $o-brand-primary; + color: $o-brand-primary; + } + } + + @keyframes decrease { + 10% { + background-color: lighten($o-brand-primary, 30%); + border-color: $o-brand-primary; + color: $o-brand-primary; + } + } + } + + tr.o_product_template { + cursor: pointer; + color: $o-main-text-color; + } + + .o_loader { + text-align: center; + width: 100%; + height: 20em; + } + } +} + +.oe_stat_button { + &.o_stat_button_info:hover { + color: #666666 !important; + background-color: transparent !important; + opacity: 0.8 !important; + cursor: default !important; + } +} + +.o_kanban_view.o_theme_kanban { + $o-theme-kanban-gray: #fcfcfc; + background-color: $o-theme-kanban-gray; + + /// Un-grouped Layout (default) + &.o_kanban_ungrouped { + justify-content: space-between; + margin: 0 0 0 ($o-kanban-record-margin - 2 * $grid-gutter-width); + + @include media-breakpoint-down(sm) { + padding-left: $o-horizontal-padding - $o-kanban-record-margin; + padding-right: $o-horizontal-padding; + } + + .o_kanban_record { + flex: 1 0 220px; + } + } + + .o_kanban_record { + margin-left: $grid-gutter-width * 2; + padding: 0; + box-shadow: none; + background: none; + border: none; + + .o_theme_preview_top { + position: relative; + border: 1px solid darken($o-theme-kanban-gray, 20%); + border-radius: 2px; + transform-origin: center bottom; + transition: all .1s ease 0s; + + .o_theme_cover, .o_theme_logo, .o_theme_screenshot { + width: 100%; + padding-bottom: 127%; + background-repeat: no-repeat; + background-position: center top; + background-size: 40% 32%; + } + + .o_theme_cover { + background-size: contain; + } + + .o_theme_screenshot { + background-size: cover; + } + } + + .o_theme_preview_bottom { + h5, h6 { + line-height: 16px; + } + } + + .o_button_area { + @include o-position-absolute(0, 0, 0, 0); + transition: opacity 100ms ease 0s; + display: flex; + flex-flow: column nowrap; + justify-content: center; + transform: translate3d(0,0,0); + background-image: linear-gradient(0deg, rgba(black, 0.6), rgba(black, 0.3)); + padding: 10% 20%; + opacity: 0; + visibility: hidden; + + > .btn { + padding: $btn-padding-y-lg $btn-padding-x-lg; + } + + hr { + width: 100%; + } + } + + .o_theme_preview_top:hover { + transition: all .3s ease 0s; + transform: translateY(-10px); + border-color: darken($o-theme-kanban-gray, 26%); + box-shadow: 0 15px 12px -8px rgba(0, 0, 0, .4); + + .o_theme_screenshot { + animation: o_theme_screenshot_scroll 4s linear .25s infinite alternate; + } + @keyframes o_theme_screenshot_scroll { + 25% { + background-position: center top; + } + 75%, 100% { + background-position: center bottom; + } + } + + .o_button_area { + opacity: 1; + visibility: visible; + transition: opacity 0.2s ease 0.1s; + } + } + + &.o_theme_installed .o_theme_preview_top { + border: 3px solid $o-brand-primary; + } + } + + /// Grouped Layout + &.o_kanban_grouped { + .o_kanban_group { + background-color: $o-theme-kanban-gray; + padding: 0 20px; + + .o_kanban_header { + height: 30px; + + .o_column_title { + padding: 0; + color: $body-color; + } + + &:hover, &.show { + .o_kanban_config { + display: none; + } + } + } + + .o_theme_preview_top { + border-color: darken($o-theme-kanban-gray, 16%); + } + + &:nth-child(even) { + background-color: darken($o-theme-kanban-gray, 4%); + + .o_theme_cover, .o_theme_logo { + background-color: white; + } + } + } + + .o_kanban_record { + width: 100%; + margin-left: 0; + margin-right: 0; + + .o_theme_preview_top { + .o_theme_cover, .o_theme_logo { + padding-bottom: 50%; + background-size: 32% 62%; + } + + .o_theme_cover { + background-size: cover; + } + } + } + } +} + +.o_view_form_theme_preview_controller { + .o_control_panel > div:first-of-type { + display: none; + } + div.o_form_nosheet { + padding: 0px; + height:100%; + width:100%; + } + + .is_mobile { + @include media-breakpoint-up(md) { + iframe { + // mobile frame is rounded + border-radius: 15px; + height: 735px; + } + .img_mobile { + pointer-events: none; + display: block !important; + position: absolute; + top: 16px; + left: calc(50% - 200px) + } + .o_field_iframe_preview { + margin: auto !important; + padding: 53px 11px 58px 28px; + width: 416px; + } + } + } + +} +.o_view_kanban_theme_preview_controller { + .o_control_panel > div:nth-child(2) { + display: none; + } +} + + +.o_theme_install_loader_container { + background-color: rgba($o-shadow-color, .9); + pointer-events: all; + font-size: 4.5rem; + justify-content: space-evenly; + .o_tooltip { + top: 0 !important; + left: 0 !important; + margin-right: 7px !important; + padding-left: 28px !important; + } + .o_theme_install_loader_tip { + font-size: 0.5em; + } +} +.o_theme_install_loader { + position: relative; + display: inline-block; + width: 400px; + height: 220px; + background-image: url('/website/static/src/img/theme_loader.gif'); + background-size: cover; + border-radius: 6px; +} diff --git a/addons/website/static/src/scss/website.edit_mode.scss b/addons/website/static/src/scss/website.edit_mode.scss new file mode 100644 index 00000000..33d7e7ed --- /dev/null +++ b/addons/website/static/src/scss/website.edit_mode.scss @@ -0,0 +1,220 @@ +$-editor-messages-margin-x: 2%; +%o-editor-messages { + width: 100% - $-editor-messages-margin-x * 2; // Need to be forced here to avoid flickering + margin: 20px $-editor-messages-margin-x; + border: 2px dashed #999999; + padding: 12px 0px; + text-align: center; + color: #999999; + + &:before { + content: attr(data-editor-message); + display: block; + font-size: 20px; + line-height: 50px; // Useful for the "wizz" animation on snippet click to be more visible + } + &:after { + content: attr(data-editor-sub-message); + display: block; + } +} +.o_we_snippet_area_animation { + animation-delay: 999ms; // Disable it but allow to inherit the animation + + &::before { + animation: inherit; + animation-delay: 0ms; + } +} + +.o_editable { + &:not(:empty), &[data-oe-type] { + &:not([data-oe-model="ir.ui.view"]):not([data-oe-type="html"]):not(.o_editable_no_shadow):not([data-oe-type="image"]):hover, + &.o_editable_date_field_linked { + box-shadow: $o-brand-odoo 0 0 5px 2px inset; + } + &[data-oe-type="image"]:not(.o_editable_no_shadow):hover { + position: relative; + + &:after { + content: ""; + pointer-events: none; + @include o-position-absolute(0, 0, 0, 0); + z-index: 1; + box-shadow: $o-brand-odoo 0 0 5px 2px inset; + } + } + } + &:focus, &[data-oe-type] { + min-height: 0.8em; + min-width: 8px; + + // TODO this feature just needs to be reviewed to not have to make + // exceptions such as this + &#o_footer_scrolltop_wrapper { + min-height: 0; + min-width: 0; + } + } + &.o_is_inline_editable { + display: inline-block; + } + .btn, &.btn { + -webkit-user-select: auto; + -moz-user-select: auto; + -ms-user-select: auto; + user-select: auto; + cursor: text!important; + } + /* Summernote not Support for placeholder text https://github.com/summernote/summernote/issues/581 */ + &[placeholder]:empty:not(:focus):before { + content: attr(placeholder); + opacity: 0.3; + } + + &.oe_structure.oe_empty, &[data-oe-type=html], .oe_structure.oe_empty { + &#wrap:empty, &#wrap > .oe_drop_zone.oe_insert:not(.oe_vertical):only-child { + @extend %o-editor-messages; + padding: 112px 0px; + } + > .oe_drop_zone.oe_insert:not(.oe_vertical):only-child { + @extend %o-editor-messages; + height: auto; + color: $o-brand-odoo; + } + > p:empty:only-child { + color: #aaa; + } + } +} +.editor_enable [data-oe-readonly]:hover { + cursor: default; +} +.oe_structure_solo > .oe_drop_zone { + // TODO implement something more robust. This is currently for our only + // use case of oe_structure_solo: the footer. The dropzone in there need to + // be 1px lower that the end-of-page dropzone to distinguish them. The + // usability has to be reviewed anyway. + transform: translateY(10px); // For some reason "1px" is not enough... +} + +/* Prevent the text contents of draggable elements from being selectable. */ +[draggable] { + user-select: none; +} + +.oe_editable:focus, +.css_editable_hidden, +.editor_enable .css_editable_mode_hidden { + outline: none!important; +} + +.editor_enable .css_non_editable_mode_hidden, +.o_editable .media_iframe_video .css_editable_mode_display { + display: block!important; +} + +// TODO: in master check if the class / rule is relevant at all +.editor_enable [data-oe-type=html].oe_no_empty:empty { + height: 16px!important; +} + +// EDITOR BAR +table.editorbar-panel { + cursor: pointer; + width: 100%; + td { border: 1px solid #aaa} + td.selected { background-color: #b1c9d9} +} +.link-style { + .dropdown > .btn { + min-width: 160px; + } + .link-style { + display: none; + } + li { + text-align: center; + label { + width: 100px; + margin: 0 5px; + } + } + .col-md-2 > * { + line-height: 2em; + } +} + +// fontawesome +.note-editable .fa { + cursor: pointer; +} + +// parallax dropzones are in conflict with outside of parallax dropzones +.parallax .oe_structure > .oe_drop_zone { + &:first-child { + top: 16px; + } + &:last-child { + bottom: 16px; + } +} + +.editor_enable .o_add_language { + display: none !important; +} + +// Facebook Page +.editor_enable .o_facebook_page:not(.o_facebook_preview) { + iframe { + pointer-events: none; + } + .o_facebook_alert .o_add_facebook_page { + cursor: pointer; + } +} + +body.editor_enable.editor_has_snippets { + padding-top: 0 !important; + + .s_popup .modal { + // s_popup in edit mode + background-color: transparent; + + &.fade .modal-dialog { + transform: none; + } + } + + #oe_main_menu_navbar + #wrapwrap .o_header_affixed { + top: 0; + } +} + +.editor_has_snippets { + .o_header_affixed { + right: $o-we-sidebar-width !important; + } +} + +.editor_enable { + @if o-website-value('header-template') == 'sidebar' { + #wrapwrap > header { + @if o-website-value('hamburger-position') != 'right' { + right: $o-we-sidebar-width; + } + } + } +} + +//s_dynamic_snippet +body.editor_enable { + .s_dynamic { + > * { + pointer-events: none; + } + [data-url] { + cursor: inherit; + } + } +} diff --git a/addons/website/static/src/scss/website.editor.ui.scss b/addons/website/static/src/scss/website.editor.ui.scss new file mode 100644 index 00000000..ebf94697 --- /dev/null +++ b/addons/website/static/src/scss/website.editor.ui.scss @@ -0,0 +1,79 @@ + +.o_homepage_editor_welcome_message { + padding-top: 128px; + padding-bottom: 128px; + font-family: Roboto, $font-family-sans-serif; +} + +// INPUTS +$o-we-switch-size: 2ex !default; +$o-we-switch-inactive-color: #F7F7F7 !default; +.o_switch { + display: flex; + align-items: center; + font-weight: normal; + cursor: pointer; + + > input { + display: none; + + + span { + background-color: $o-we-switch-inactive-color; + box-shadow: inset 0 0 0px 1px darken($o-we-switch-inactive-color, 10%); + border-radius: 100rem; + height: $o-we-switch-size; + width: $o-we-switch-size * 1.8; + margin-right: 0.5em; + display: inline-block; + transition: all 0.3s cubic-bezier(0.19, 1, 0.22, 1); + + &:after { + content: ""; + background: white; + display: block; + width: $o-we-switch-size - 0.2; + height: $o-we-switch-size - 0.2; + margin-top: 0.1ex; + margin-left: 0.1ex; + border-radius: 100rem; + transition: all 0.3s cubic-bezier(0.19, 1, 0.22, 1); + box-shadow: 0 1px 1px darken($o-we-switch-inactive-color, 35%), inset 0 0 0 1px lighten($o-we-switch-inactive-color, 10%); + } + } + + &:checked+span { + box-shadow: none; + background: $o-we-color-success; + + &:after { + margin-left: ($o-we-switch-size*1.8 - $o-we-switch-size) + 0.1; + } + } + } + + &.o_switch_danger { + >input { + &:not(:checked)+span { + box-shadow: none; + background: $o-we-color-danger; + } + } + } +} + +.o_new_content_loader_container { + background-color: rgba($o-shadow-color, .9); + pointer-events: all; + font-size: 3.5rem; + justify-content: center; + z-index: $zindex-modal - 1; +} +.o_new_content_loader { + position: relative; + display: inline-block; + width: 400px; + height: 220px; + background-image: url('/website/static/src/img/theme_loader.gif'); + background-size: cover; + border-radius: 6px; +} 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; +} diff --git a/addons/website/static/src/scss/website.ui.scss b/addons/website/static/src/scss/website.ui.scss new file mode 100644 index 00000000..da23fabc --- /dev/null +++ b/addons/website/static/src/scss/website.ui.scss @@ -0,0 +1,513 @@ +/// +/// This file regroups main website UI layout rules (when the user is connected) +/// and the UI components rules. +/// + +// LAYOUTING +body { + // Set frontend direction that will be flipped with + // rtlcss for right-to-left text direction. + direction: ltr; +} +body.o_connected_user { + padding-top: $o-navbar-height!important; + + &.o_fullscreen_transition { + transition: padding 400ms ease 0s; + + #oe_main_menu_navbar, #web_editor-top-edit, .o_we_website_top_actions, #oe_snippets { + transition: transform 400ms ease 0s !important; + } + .o_header_affixed { + transition: top 0.35s !important; + } + } + &.o_fullscreen { + padding-top: 0 !important; + + &.editor_enable.editor_has_snippets { + padding-right: 0 !important; + } + #oe_main_menu_navbar, #web_editor-top-edit { + transform: translateY(-100%); + } + .o_we_website_top_actions, #oe_snippets { + transform: translateX(100%); + } + .o_header_affixed { + top: 0 !important; + right: 0 !important; + } + } +} + +// MAIN MENU STYLE (added above navbar.scss) +#oe_main_menu_navbar { + @include o-w-preserve-dropdown-menus; + @include o-position-absolute(0, 0, auto, 0); + position: fixed; + z-index: $zindex-modal - 10; + font-family: $o-we-font-family; + font-size: 14px; + + a:hover, a:focus { + text-decoration: none; + } + .dropdown-menu { + font-size: inherit; + border-radius: 0; + color: $dropdown-link-active-color; + } + + .o_menu_sections { + .o_mobile_preview a { + text-align: center; + font-size: 20px; + } + } + .o_menu_systray { + > li > a { + padding: 0 $grid-gutter-width/2; + + &.css_edit_dynamic{ + padding: 0 $grid-gutter-width/4; + } + + &[data-action="edit"], &[data-action="translate"], &.css_edit_dynamic { + @include button-variant($o-brand-primary, $o-brand-primary); + } + + &, &:hover, &:focus { + text-decoration: none; + } + } + + .o_mobile_preview a { + text-align: center; + font-size: 20px; + } + } + @include media-breakpoint-down(sm) { + #oe_applications { + position: inherit; + z-index: 1002; + } + } +} + +@mixin o-w-close-icon($size:12px, $color:#000, $color-hover:#000, $thickness: 1px, $opacity: 0.7, $opacity-hover: 1) { + color: transparent; + position: relative; + display: inline-block; + opacity: $opacity; + width: $size; + height: $size; + + &:hover, &:focus { + outline: none; + opacity: $opacity-hover; + + &::after, &::before { + background: $color-hover; + } + } + + &:after, &:before { + content: ''; + margin-top: -1px; + background: $color; + @include size(100%, $thickness); + @include o-position-absolute(50%, $left:0); + transform: rotate(45deg); + } + + &:after { + transform: rotate(-45deg); + } +} + +// BLOCKING LOADER +#o_website_page_loader { + @include o-position-absolute(0, 0, 0, 0); + z-index: $zindex-modal - 1; + background-color: rgba(0, 0, 0, 0.8); +} + +// MODALS +body .modal { + &.o_technical_modal { + @include o-w-preserve-base; + @include o-w-preserve-dropdown-menus; + @include o-w-preserve-headings; + @include o-w-preserve-forms; + @include o-w-preserve-links; + @include o-w-preserve-btn; + @include o-w-preserve-cards; + @include o-w-preserve-modals; + @include o-w-preserve-tabs; + } + + // MOBILE PREVIEW + &.oe_mobile_preview { + text-align: center; + + .modal-dialog { + display: inline-block; + width: auto; + + .modal-content { + background-color: black!important; + border: 3px outset gray; + border-radius: 20px; + + .modal-header { + border: none; + cursor: pointer; + font-family: $o-we-font-family; + + &, .close { + color: white; + } + + h4 { + font-family: inherit; + font-weight: normal; + color: inherit; + + .fa { + margin-left: $grid-gutter-width/2; + } + } + .close { + color: #4e525b; + } + } + + .modal-body { + background-color: inherit!important; + border-radius: 20px; + padding: 15px; + + $mobile-preview-width: 320px; + $mobile-preview-height: 530px; + + display: flex; + width: $mobile-preview-width + 15; + height: $mobile-preview-height; + transition: all 400ms ease 0s; + + &.o_invert_orientation { + width: $mobile-preview-height + 15; + height: $mobile-preview-width; + } + + > iframe { + display: block; + width: 100%; + border: none; + } + } + + .modal-footer { + display: none; + } + } + } + } + + // TOP MENU EDITOR + .oe_menu_editor { + ul { + padding-left: 37px; + } + + li { + margin-top: -1px; + + .input-group-addon { + border-radius: 0; + } + } + } + + // SEO CONFIGURATION + &.oe_seo_configuration { + #language-box { + padding-right: 25px; + background-color: white; + } + .o_seo_og_image { + .o_meta_img { + position: relative; + transition: border-color 200ms; + display: inline-block; + border: 2px solid gray('400'); + + > img { + width: 70px; + height: 70px; + object-fit: cover; + cursor: pointer; + } + + &:hover { + border-color: $o-brand-primary; + } + + &.o_active_image { + border-color: $o-brand-primary; + + &:before { + @include o-position-absolute($right: 0); + content: ''; + border: 16px solid rgba($o-brand-primary, 0.8); + border-left-color: transparent; + border-bottom-color: transparent; + } + + &:after { + @include o-position-absolute(2px, 3px); + display: inline-block; + content: "\f00c"; + font-family: FontAwesome; + color: white; + font-size: 12px; + } + } + .o-custom-label { + @include o-position-absolute($bottom: 0px); + background: rgba(gray('800'), 0.6); + font-size: 12px; + } + } + .o_meta_img_upload { + transition: 200ms; + display: inline-block; + padding: 23px 27px; + border: 3px dashed lighten(gray('700'), 30%); + vertical-align: top; + cursor: pointer; + color: lighten(gray('600'), 30%); + + &:hover { + border-color: $o-brand-primary; + color: $o-brand-primary; + } + } + .o_meta_active_img { + height: 240px; + object-fit: cover; + } + } + + div.oe_seo_preview_g { + list-style: none; + font-family: arial, sans-serif; + + .r { + cursor: pointer; + color:#1a0dab; + font-size: 18px; + overflow: hidden; + text-overflow: ellipsis; + -webkit-text-overflow: ellipsis; + white-space: nowrap; + } + + .s { + font-size: 13px; + line-height: 18px; + color: #545454; + .kv { + color: #006621; + font-size: 14px; + line-height: 18px; + } + } + } + + td.o_seo_keyword_suggestion span.o_seo_suggestion.badge { + cursor: pointer; + } + } +} + +// ADD NEW PAGE MODAL + +.o_new_content_open { + // Kill the scroll on the body + overflow: hidden; +} + +#o_new_content_menu_choices { + @include o-w-preserve-base; + @include o-position-absolute($o-navbar-height, 0, 0, 0); + position: fixed; + display: flex; + overflow: auto; + background-color: rgba(0, 0, 0, 0.8); + font-family: $o-we-font-family; + + &::before { + content: " "; + @include o-position-absolute(0, 0, 0, 0); + z-index: -1; + pointer-events: none; + } + + .container { + max-width: 720px; + margin: auto; + } + + .o_new_content_element { + opacity: 0; + animation: fadeInDownSmall 1s forwards; + + .o_uninstalled_module { + filter: brightness(70%) contrast(60%); + + } + + .module_icon { + display: block; + margin: auto; + } + + a { + display: block; + font-size: 34px; + text-align: center; + text-decoration: none; + + i { + width: 110px; + height: 110px; + border: 3px solid lighten(#2C2C36, 10%); + border-radius: 100%; + line-height: 104px; + background-color: #2C2C36; + color: white; + + transition: all 0.5s cubic-bezier(0.19, 1, 0.22, 1) 0s; + } + p { + color: white; + margin-top: 0.7em; + font-size: 0.5em; + } + + &:hover, &:focus { + text-decoration: none; + outline: none; // remove ugly dotted border on Firefox + i { + border-color: #1cc1a9; + box-shadow: 0 0 10px rgba(28, 193, 169, 0.46); + } + } + } + } +} + +// LOGIN FORM +.oe_login_form, .oe_signup_form, .oe_reset_password_form { + max-width: 300px; + position: relative; + margin: 50px auto; +} + +// ACE EDITOR +.o_ace_view_editor { + @include o-w-preserve-base; + @include o-w-preserve-btn; + @include o-w-preserve-forms; + + @include o-position-absolute($o-navbar-height, 0, 0); + position: fixed; + z-index: $zindex-modal; +} + +// POPOVER NAVIGATION +.tour .popover-navigation { + margin-left: 13px; + margin-bottom: 8px; +} + +// PUBLISH +.css_published { + .btn-danger, .css_publish { + display: none; + } +} +.css_unpublished { + .btn-success, .css_unpublish { + display: none; + } +} +[data-publish='off'] > *:not(.css_options) { + opacity: 0.5; +} + +// Do not show path behind the links in browser printing +@media print { + a[href]:after { + content: initial; + } +} + +// Pages Management +.o_page_management_info { + .o_switch { + padding-top: 9px; + } +} +#list_website_pages { + th { + background-color: $o-brand-odoo; + color: white; + } + td, th { + padding: 0.45rem; + } + td { + > a.fa { + margin-left: 5px; + color: $o-brand-odoo; + } + .text-muted { + opacity: 0.5; + } + } + .fa-check, .fa-eye-slash { + color: $info; + } +} + +.ui-autocomplete.o_website_ui_autocomplete { + max-width: 400px; + font-size: $o-we-sidebar-font-size; + border: none; + background-color: $o-we-sidebar-content-field-dropdown-bg; + box-shadow: $o-we-sidebar-content-field-dropdown-shadow; + > li { + border-bottom: $o-we-sidebar-content-field-border-width solid lighten($o-we-sidebar-content-field-dropdown-border-color, 15%); + border-radius: $o-we-sidebar-content-field-border-radius; + background-color: $o-we-sidebar-content-field-clickable-bg; + color: $o-we-sidebar-content-field-clickable-color; + &.ui-menu-item { + > div { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: 20px; + &.ui-state-active { + border: $o-we-sidebar-content-field-dropdown-border-width solid transparent; + background-color: $o-we-sidebar-content-field-dropdown-item-bg-hover; + } + } + } + &.ui-autocomplete-category { + background-color: $o-we-bg-lighter; + } + } +} diff --git a/addons/website/static/src/scss/website.wysiwyg.scss b/addons/website/static/src/scss/website.wysiwyg.scss new file mode 100644 index 00000000..32c86a63 --- /dev/null +++ b/addons/website/static/src/scss/website.wysiwyg.scss @@ -0,0 +1,235 @@ + +@each $font-name, $font-config in $o-theme-font-configs { + $url: map-get($font-config, 'url'); + @if $url { + @import url("https://fonts.googleapis.com/css?family=#{unquote($url)}&display=swap"); + } +} + +:root { + // Override css variables to influence the default style of the editor + // without duplicating the css. + @include print-variable('o-we-toolbar-height', $o-navbar-height); + + // Need info about the color of each color palette + @for $index from 1 through length($o-color-palettes) - 1 { // Not the user one + @each $name, $color in nth($o-color-palettes, $index) { + @include print-variable('o-palette-#{$index}-#{$name}', $color); + } + } +} + +// EDITOR TOP BAR AND POPOVER +.o_we_website_top_actions { + @include o-position-absolute($top: 0, $right: 0); + z-index: ($zindex-fixed + $zindex-modal-backdrop) / 2 + 2; // $o-we-zindex + display: flex; + justify-content: flex-end; + width: $o-we-sidebar-width; + height: $o-we-sidebar-top-height; + background-color: $o-we-sidebar-tabs-bg; + + .btn-group, .btn { + height: 100%; + } + + .btn { + border: none; + border-radius: 0; + padding: 0.375rem 0.75rem; + font-size: $o-we-font-size; + font-family: $o-we-font-family; + font-weight: 400; + line-height: 1; + + &.btn-primary { + @include button-variant($o-brand-primary, $o-brand-primary); + } + &.btn-secondary { + @include button-variant($o-we-sidebar-tabs-bg, $o-we-sidebar-tabs-bg); + } + &:focus, &:active, &:focus:active { + outline: none; + box-shadow: none; + } + } + + .dropdown-menu { + left: auto; + right: 0; + } +} + +#oe_snippets { + top: $o-we-sidebar-top-height; +} + +.note-statusbar { + display: none; +} + +// TRANSLATIONS +.oe_translate_examples li { + margin: 10px; + padding: 4px; +} + +html[lang] > body.editor_enable [data-oe-translation-state] { + background: rgba($o-we-content-to-translate-color, 0.5) !important; + + &[data-oe-translation-state="translated"] { + background: rgba($o-we-translated-content-color, 0.5) !important; + } + + &.o_dirty { + background: rgba($o-we-translated-content-color, 0.25) !important; + } +} + +// SNIPPET PANEL +$i: 1; +@each $font-name, $font-config in $o-theme-font-configs { + we-toggler.o_we_option_font_#{$i}, we-button.o_we_option_font_#{$i} > div { + font-family: o-safe-get($font-config, 'family', $font-family-base); + + &::before { + content: $font-name; + } + } + $i: $i + 1; +} +.o_we_add_google_font_btn { + border-top: 1px solid currentColor !important; +} + +#oe_snippets > .o_we_customize_panel { + .o_we_user_value_widget.o_palette_color_preview_button { + > div { + display: flex; + flex: 1 1 auto; + align-items: stretch; + } + .o_palette_color_preview { + flex: 1 0 0; + margin: 1px 0; + transition: flex 150ms ease 0s; + } + &:not(:hover) .o_palette_color_preview { + &:nth-child(4), &:nth-child(5) { + flex: 0 0 0; + } + } + } + + we-select.o_scroll_effects_selector we-button { + padding-top: $o-we-item-spacing; + padding-bottom: $o-we-item-spacing; + + img { + max-height: 80px; + width: auto; + margin-right: $o-we-item-spacing; + margin-left: $o-we-item-spacing * .5; + } + } + + //---------------------------------------------------------------------- + // 'Options' Tab Specific Components + //---------------------------------------------------------------------- + + // Theme Colors Editor + .o_we_theme_colors_selector { + + > we-title { + display: none + } + .o_we_so_color_palette.o_we_user_value_widget { + + + .o_we_so_color_palette { + margin-left: 10px; + } + .o_we_color_preview { + width: $o-we-sidebar-content-field-colorpicker-size-large; + height: $o-we-sidebar-content-field-colorpicker-size-large; + } + } + > div, we-select.o_we_theme_colors_select, we-toggler { + display: flex; + } + > div { + align-items: stretch; + width: 100%; + } + we-select.o_we_theme_colors_select { + justify-content: flex-end; + margin-left: auto; + + > div, we-toggler { + height: 100%; + } + } + we-toggler { + align-items: center; + padding: 0 0.4rem; + font-size: 1.5em; + + &:after { + content: none; + } + } + } + + // Palettes Dropdown + .o_palette_color_preview_button > div { + min-height: 24px; + } + + // CC Edition + .o_we_cc_preview_wrapper { + // Use box-shadow rather than border-bottom in order to + // avoid misalignments in the 'Options' tab. + border: 1px solid; + border-color: rgba($o-we-item-standup-color-light, .2) $o-we-sidebar-content-field-dropdown-border-color transparent; + box-shadow: 0 1px 0 $o-we-item-standup-color-dark; + + + .o_we_collapse_toggler { + height: 35px; // FIXME hardcoded... + } + } +} + +// SNIPPET OPTIONS +.o_we_border_preview { + display: inline-block; + width: 999px; + max-width: 100%; + margin-bottom: 2px; + border-width: 4px; + border-bottom: none !important; +} + +.pac-container { // google map autosuggestion + z-index: $zindex-modal-backdrop; // > $o-we-zindex + width: $o-we-sidebar-width !important; + font-size: $o-we-sidebar-font-size; + margin-left: -$o-we-sidebar-width/2; + border-top: none; + background-color: $o-we-sidebar-content-field-dropdown-bg; + box-shadow: $o-we-sidebar-content-field-dropdown-shadow; + &:after { + display: none; + } + .pac-item { + border-top: $o-we-sidebar-content-field-border-width solid lighten($o-we-sidebar-content-field-dropdown-border-color, 15%); + border-radius: $o-we-sidebar-content-field-border-radius; + background-color: $o-we-sidebar-content-field-clickable-bg; + color: $o-we-sidebar-content-field-clickable-color; + &:hover { + background-color: $o-we-sidebar-content-field-dropdown-item-bg-hover; + cursor: pointer; + } + } + .pac-item-query { + color: $o-we-sidebar-content-field-clickable-color; + } +} diff --git a/addons/website/static/src/scss/website_visitor_views.scss b/addons/website/static/src/scss/website_visitor_views.scss new file mode 100644 index 00000000..ee209181 --- /dev/null +++ b/addons/website/static/src/scss/website_visitor_views.scss @@ -0,0 +1,46 @@ +.o_wvisitor_kanban { + &.o_kanban_ungrouped { + padding:0px; + .o_wvisitor_kanban_card { + width: 100%; + margin: 0px; + border-top: 0px !important; + &:first-child { + border-bottom: 1px solid #dee2e6 !important; + } + .o_kanban_detail_ungrouped { + .o_wvisitor_kanban_image { + width: 56px; + height: 56px; + top: 0px; + position: absolute; + } + .o_wvisitor_name { + padding-left: 72px; + } + .w_visitor_kanban_actions_ungrouped { + button { + float: right; + margin: 4px; + } + } + .o_country_flag { + margin-right: 8px; + } + } + .oe_kanban_details { + display:none !important; + } + } + } + &.o_kanban_grouped { + .o_kanban_detail_ungrouped { + display:none !important; + } + } +} + +.o_country_flag { + width:24px; + height: 16px; +}
\ No newline at end of file |
