/* Copyright (c) Fortanix, Inc.
|* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
|* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* stylelint-disable no-duplicate-selectors */

@use '../../styling/defs.scss' as bk;

@layer baklava.base {
  :root {
    // Height of the header needs to be known at root level so we can use it for things like `scroll-padding-top`.
    --bk-app-layout-header-height: 0;
    
    &:has(.bk-app-layout > [slot='header']) {
      // Calculate by: content height (spacing-9) + 2 times the block padding (padding-3).
      --bk-app-layout-header-height: calc(#{bk.$spacing-9} + 2 * #{bk.$spacing-3});
    }
  }
}

@layer baklava.layouts {
  .bk-app-layout {
    @include bk.component-base(bk-app-layout);
    container-type: inline-size;
    
    --bk-app-layout-sidebar-width-open: #{bk.rem-from-px(220)};
    --bk-app-layout-sidebar-width-closed: #{bk.rem-from-px(48)};
    --bk-app-layout-sidebar-width: var(--bk-app-layout-sidebar-width-open);
    
    /* Note: do not use vw/vh, because we may want to show the layout in a container (e.g. story) */
    min-inline-size: 100cqi;
    min-block-size: 100cqb;
    
    display: grid;
    // Note: use `minmax(0, 1fr)` to prevent blowout: https://css-tricks.com/preventing-a-grid-blowout
    grid:
      'breadcrumbs' max-content
      'content' 1fr
      'footer' max-content
      / minmax(0, 1fr);
    
    &:has(> [slot='header']) {
      grid:
        'header' var(--bk-app-layout-header-height)
        'breadcrumbs' max-content
        'content' 1fr
        'footer' max-content
        / minmax(0, 1fr);
    }
    &:has(> [slot='sidebar']) {
      grid:
        'sidebar breadcrumbs' max-content
        'sidebar content' 1fr
        'sidebar footer' max-content
        / var(--bk-app-layout-sidebar-width) minmax(0, 1fr);
    }
    &:has(> [slot='sidebar'], > [slot='sidebar']) {
      grid:
        'header  header' var(--bk-app-layout-header-height)
        'sidebar breadcrumbs' max-content
        'sidebar content' 1fr
        'sidebar footer' max-content
        / var(--bk-app-layout-sidebar-width) minmax(0, 1fr);
    }
    
    > [slot='header'] { grid-area: header; }
    > [slot='sidebar'] { grid-area: sidebar; }
    > [slot='breadcrumbs'] { grid-area: breadcrumbs; }
    > [slot='content'] { grid-area: content; }
    > [slot='footer'] { grid-area: footer; }
    
    > [slot='header'] {
      container: bk-app-layout__header / inline-size;
      overflow: hidden;
      
      background: bk.$theme-header-background-default;
      
      position: sticky;
      inset-block-start: 0;
      
      // Necessary despite the `sticky`, because the page content is a container, which generates a stacking context:
      // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context
      // Should be higher than the sidebar (which has `z-index: 1`), so that it remains under the header during scroll.
      z-index: 2;
      
      display: grid;
      grid:
        'logo account-actions user-actions' 1fr
        / var(--bk-app-layout-sidebar-width) max-content 1fr;
      
      > [slot='logo'] { grid-area: logo; }
      > [slot='actions'] { grid-column: account-actions-start / user-actions-end; }
      
      > [slot='logo'] {
        @include bk.focus-inset;
        padding-inline-start: bk.$spacing-4;
        display: flex;
        flex-direction: column;
        align-items: start;
        justify-content: center;
      }
    }
    
    > [slot='sidebar'] {
      container: bk-app-layout__sidebar / inline-size;
      
      // Set a z-index higher than the content, so that overflow from the content (e.g. in case of flex row-reverse)
      // does not overlay the sidebar. Should be lower than the header since the sidebar should scroll "underneath" it.
      z-index: 1;
      
      padding-block-end: bk.$spacing-8; // Some padding (e.g. for if the sidebar is larger than the viewport height)
      background: bk.$theme-side-nav-background-default;
      
      > aside {
        position: sticky;
        inset-block-start: var(--bk-app-layout-header-height);
        /*
        Note: if the sidebar itself overflows (in height), then we might want to make this scrollable, but this is hard:
          - https://stackoverflow.com/questions/16094785/fixed-position-div-that-needs-to-scroll-if-content-overflows
        However, the user can still scroll the fixed sidebar by just scrolling to the bottom of the content.
        */
      }
    }
    
    > [slot='breadcrumbs'] {
      container: bk-app-layout__breadcrumbs / inline-size;
      padding: bk.$spacing-5;
      padding-block-end: calc(bk.$spacing-7 - bk.$spacing-5);
    }
    
    > [slot='content'] {
      container: bk-app-layout__content / inline-size;
      padding: bk.$spacing-5;
    }
    
    > [slot='footer'] {
      container: bk-app-layout__footer / inline-size;
      
      padding: bk.$spacing-4 bk.$spacing-5;
      
      display: flex;
      font-size: 0.8rem;
    }
    
    @container (inline-size <= 768px) { // Tablet size
      --bk-app-layout-sidebar-width: 3.15rem;
      /*
      grid:
        'header' var(--bk-app-layout-header-height)
        'sidebar' max-content
        'content' 1fr
        'footer' max-content
        / 1fr;
        */
    }
    
    @media (prefers-reduced-motion: no-preference) {
      transition: grid 300ms;
    }
  }
}
