// Name:            Off-canvas
// Description:     Component to create an off-canvas sidebar
//
// Component:       `ui-offcanvas`
//
// Sub-objects:     `ui-offcanvas-bar`
//                  `ui-offcanvas-container`
//                  `ui-offcanvas-page`
//
// Adopted:         `ui-offcanvas-close`
//
// Modifiers:       `ui-offcanvas-flip`
//                  `ui-offcanvas-bar-animation`
//                  `ui-offcanvas-reveal`
//                  `ui-offcanvas-overlay`
//                  `ui-offcanvas-container-animation`
//
// States:          `ui-open`
//
// ========================================================================


// Variables
// ========================================================================

@offcanvas-z-index:                             @global-z-index;

@offcanvas-bar-width:                           270px;
@offcanvas-bar-padding-vertical:                @global-margin;
@offcanvas-bar-padding-horizontal:              @global-margin;
@offcanvas-bar-background:                      @global-secondary-background;
@offcanvas-bar-color-mode:                      light;

@offcanvas-bar-width-m:                         350px;
@offcanvas-bar-padding-vertical-m:              @global-medium-gutter;
@offcanvas-bar-padding-horizontal-m:            @global-medium-gutter;

@offcanvas-close-position:                      20px;
@offcanvas-close-padding:                       5px;

@offcanvas-overlay-background:                  rgba(0,0,0,0.1);


/* ========================================================================
   Component: Off-canvas
 ========================================================================== */

/*
 * 1. Hide by default
 * 2. Set position
 */

.ui-offcanvas {
  /* 1 */
  display: none;
  /* 2 */
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: @offcanvas-z-index;
}

/*
 * Flip modifier
 */

.ui-offcanvas-flip .ui-offcanvas {
  right: 0;
  left: auto;
}


/* Bar
 ========================================================================== */

/*
 * 1. Set position
 * 2. Size and style
 * 3. Allow scrolling
 */

.ui-offcanvas-bar {
  /* 1 */
  position: absolute;
  top: 0;
  bottom: 0;
  left: -@offcanvas-bar-width;
  /* 2 */
  box-sizing: border-box;
  width: @offcanvas-bar-width;
  padding: @offcanvas-bar-padding-vertical @offcanvas-bar-padding-horizontal;
  background: @offcanvas-bar-background;
  /* 3 */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  .hook-offcanvas-bar;
}

/* Tablet landscape and bigger */
@media (min-width: @breakpoint-medium) {

  .ui-offcanvas-bar {
    left: -@offcanvas-bar-width-m;
    width: @offcanvas-bar-width-m;
    padding: @offcanvas-bar-padding-vertical-m @offcanvas-bar-padding-horizontal-m;
  }

}

// Color Mode
.ui-offcanvas-bar:extend(.ui-light all) when (@offcanvas-bar-color-mode = light) {}
.ui-offcanvas-bar:extend(.ui-dark all) when (@offcanvas-bar-color-mode = dark) {}

/* Flip modifier */
.ui-offcanvas-flip .ui-offcanvas-bar {
  left: auto;
  right: -@offcanvas-bar-width;
}

/* Tablet landscape and bigger */
@media (min-width: @breakpoint-medium) {

  .ui-offcanvas-flip .ui-offcanvas-bar { right: -@offcanvas-bar-width-m; }

}

/*
 * Open
 */

.ui-open > .ui-offcanvas-bar { left: 0; }
.ui-offcanvas-flip .ui-open > .ui-offcanvas-bar {
  left: auto;
  right: 0;
}

/*
 * Slide Animation (Used in slide and push mode)
 */

.ui-offcanvas-bar-animation { transition: left 0.3s ease-out; }
.ui-offcanvas-flip .ui-offcanvas-bar-animation { transition-property: right; }

/*
 * Reveal Animation
 * 1. Set position
 * 2. Clip the bar
 * 3. Animation
 * 4. Reset position
 */

.ui-offcanvas-reveal {
  /* 1 */
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  /* 2 */
  width: 0;
  overflow: hidden;
  /* 3 */
  transition: width 0.3s ease-out;
}

.ui-offcanvas-reveal .ui-offcanvas-bar {
  /* 4 */
  left: 0;
}

.ui-offcanvas-flip .ui-offcanvas-reveal .ui-offcanvas-bar {
  /* 4 */
  left: auto;
  right: 0;
}

.ui-open > .ui-offcanvas-reveal { width: @offcanvas-bar-width; }

/* Tablet landscape and bigger */
@media (min-width: @breakpoint-medium) {

  .ui-open > .ui-offcanvas-reveal { width: @offcanvas-bar-width-m; }

}

/*
 * Flip modifier
 */

.ui-offcanvas-flip .ui-offcanvas-reveal {
  right: 0;
  left: auto;
}


/* Close
 * Adopts `ui-close`
 ========================================================================== */

.ui-offcanvas-close {
  position: absolute;
  z-index: @offcanvas-z-index;
  top: @offcanvas-close-position;
  right: @offcanvas-close-position;
  padding: @offcanvas-close-padding;
  .hook-offcanvas-close;
}


/* Overlay
 ========================================================================== */

/*
 * Overlay the whole page. Needed for the `::before`
 * 1. Using `100vw` so no modification is needed when off-canvas is flipped
 * 2. Allow for closing with swipe gesture on devices with pointer events.
 */

.ui-offcanvas-overlay {
  /* 1 */
  width: 100vw;
  /* 2 */
  touch-action: none;
}

/*
 * 1. Mask the whole page
 * 2. Fade-in transition
 */

.ui-offcanvas-overlay::before {
  /* 1 */
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: @offcanvas-overlay-background;
  /* 2 */
  opacity: 0;
  transition: opacity 0.15s linear;
  .hook-offcanvas-overlay;
}

.ui-offcanvas-overlay.ui-open::before { opacity: 1; }


/* Prevent scrolling
 ========================================================================== */

/*
 * Prevent horizontal scrollbar when the content is slide-out
 * Has to be on the `html` element too to make it work on the `body`
 */

.ui-offcanvas-page,
.ui-offcanvas-container { overflow-x: hidden; }


/* Container
 ========================================================================== */

/*
 * Prepare slide-out animation (Used in reveal and push mode)
 * Using `position: left` instead of `transform` because position `fixed` elements like sticky navbars
 * lose their fixed state and behaves like `absolute` within a transformed container
 * 1. Provide a fixed width and prevent shrinking
 */

.ui-offcanvas-container {
  position: relative;
  left: 0;
  transition: left 0.3s ease-out;
  /* 1 */
  box-sizing: border-box;
  width: 100%;
}

/*
 * Activate slide-out animation
 */

:not(.ui-offcanvas-flip).ui-offcanvas-container-animation { left: @offcanvas-bar-width; }

.ui-offcanvas-flip.ui-offcanvas-container-animation { left: -@offcanvas-bar-width; }

/* Tablet landscape and bigger */
@media (min-width: @breakpoint-medium) {

  :not(.ui-offcanvas-flip).ui-offcanvas-container-animation { left: @offcanvas-bar-width-m; }

  .ui-offcanvas-flip.ui-offcanvas-container-animation { left: -@offcanvas-bar-width-m; }

}


// Hooks
// ========================================================================

.hook-offcanvas-misc;

.hook-offcanvas-bar() {}
.hook-offcanvas-close() {}
.hook-offcanvas-overlay() {}
.hook-offcanvas-misc() {}
