@use "../../themes/ionic/ionic.globals.scss" as globals;

// Ionic Global Styles
// --------------------------------------------------

:root {
  /**
   * Set the theme colors from the
   * `ionic.theme.default.scss` file.
   */
  @include globals.set-theme-colors(globals.$ionic-colors);
  @include globals.generate-color-variables();

  @each $color-name, $value in globals.$ionic-colors {
    .ion-color-#{$color-name} {
      @include globals.generate-color($color-name);
    }
  }

  /* Default background color of all components to default background surface token */
  --background: #{globals.$ion-bg-surface-default};
}

html {
  --ion-dynamic-font: -apple-system-body;
}

body {
  background: var(--ion-background-color, #{globals.$ion-bg-body});
  color: var(--ion-text-color, #{globals.$ion-text-default});
}

body.backdrop-no-scroll {
  overflow: hidden;
}

// Modal - Card Style
// --------------------------------------------------

html.ionic ion-modal ion-header {
  box-shadow: none;
}

/**
 * Modals need additional padding on the
 * top of the header. We accomplish this by targeting
 * the first toolbar in the header.
 * Footer also needs this. We do not adjust the bottom
 * padding though because of the safe area.
 */
html.ionic ion-modal.modal-card ion-header ion-toolbar:first-of-type,
html.ionic ion-modal.modal-sheet ion-header ion-toolbar:first-of-type,
html.ionic ion-modal ion-footer ion-toolbar:first-of-type,
html.ionic ion-footer.modal-footer-moving ion-toolbar:first-of-type {
  padding-top: globals.$ion-space-400;
}

/**
* Modals need additional padding on the
* bottom of the header. We accomplish this by targeting
* the last toolbar in the header.
*/
html.ionic ion-modal.modal-card ion-header ion-toolbar:last-of-type,
html.ionic ion-modal.modal-sheet ion-header ion-toolbar:last-of-type,
html.ionic ion-modal ion-footer ion-toolbar:last-of-type {
  padding-bottom: globals.$ion-space-400;
}

/**
* Add padding on the left and right
* of toolbars while accounting for
* safe area values when in landscape.
*/
html.ionic ion-modal ion-toolbar,
html.ionic .modal-footer-moving ion-toolbar {
  padding-right: calc(var(--ion-safe-area-right) + #{globals.$ion-space-400});
  padding-left: calc(var(--ion-safe-area-left) + #{globals.$ion-space-400});
}

/**
* Add padding to the left, right, and bottom of `ion-content`
* within a modal.
*/
html.ionic ion-modal.modal-sheet ion-content {
  --padding-start: #{globals.$ion-space-400};
  --padding-end: #{globals.$ion-space-400};
  --padding-bottom: #{globals.$ion-space-400};
}

/**
 * Card style modal on iPadOS
 * should only have backdrop on first instance.
 */
@media screen and (min-width: 768px) {
  html.ionic ion-modal.modal-card:first-of-type {
    --backdrop-opacity: 0.18;
  }
}

/**
 * Subsequent modals should not have a backdrop/box shadow
 * as it will cause the screen to appear to get progressively
 * darker. With Ionic 6, declarative modals made it
 * possible to have multiple non-presented modals in the DOM,
 * so we could no longer rely on ion-modal:first-of-type.
 * Here we disable the opacity/box-shadow for every modal
 * that comes after the first presented modal.
 *
 * Note: ion-modal:not(.overlay-hidden):first-of-type
 * does not match the first modal to not have
 * the .overlay-hidden class, it will match the
 * first modal in general only if it does not
 * have the .overlay-hidden class.
 * The :nth-child() pseudo-class has support
 * for selectors which would help us here. At the
 * time of writing it does not have great cross browser
 * support.
 *
 * Note 2: This should only apply to non-card and
 * non-sheet modals. Card and sheet modals have their
 * own criteria for displaying backdrops/box shadows.
 *
 * Do not use :not(.overlay-hidden) in place of
 * .show-modal because that triggers a memory
 * leak in Blink: https://bugs.chromium.org/p/chromium/issues/detail?id=1418768
 */
ion-modal.modal-default.show-modal ~ ion-modal.modal-default {
  --backdrop-opacity: 0;
  --box-shadow: none;
}

/**
 * This works around a bug in WebKit where the
 * content will overflow outside of the bottom border
 * radius when re-painting. As long as a single
 * border radius value is set on .ion-page, this
 * issue does not happen. We set the top left radius
 * here because the top left corner will always have a
 * radius no matter the platform.
 * This behavior only applies to card modals.
 */
html.ionic ion-modal.modal-card .ion-page {
  border-top-left-radius: var(--border-radius);
}

// Page Container Structure
// --------------------------------------------------

.ion-page {
  @include globals.position(0, 0, 0, 0);

  display: flex;
  position: absolute;

  flex-direction: column;
  justify-content: space-between;

  contain: layout size style;
  z-index: 0;
}

/**
 * When making custom dialogs, using
 * ion-content is not required. As a result,
 * some developers may wish to have dialogs
 * that are automatically sized by the browser.
 * These changes allow certain dimension values
 * such as fit-content to work correctly.
 */
ion-modal > .ion-page {
  position: relative;

  height: 100%;

  contain: layout style;
}

.split-pane-visible > .ion-page.split-pane-main {
  position: relative;
}

ion-route,
ion-route-redirect,
ion-router,
ion-select-option,
ion-nav-controller,
ion-menu-controller,
ion-action-sheet-controller,
ion-alert-controller,
ion-loading-controller,
ion-modal-controller,
ion-picker-controller,
ion-popover-controller,
ion-toast-controller,
.ion-page-hidden {
  /* stylelint-disable-next-line declaration-no-important */
  display: none !important;
}

.ion-page-invisible {
  opacity: 0;
}

.can-go-back > ion-header ion-back-button {
  display: block;
}

// Ionic Safe Margins
// --------------------------------------------------

html.plt-ios.plt-hybrid,
html.plt-ios.plt-pwa {
  --ion-statusbar-padding: #{globals.$ion-space-500};
}

@supports (padding-top: 20px) {
  html {
    --ion-safe-area-top: var(--ion-statusbar-padding);
  }
}

@supports (padding-top: env(safe-area-inset-top)) {
  html {
    // `--safe-area-inset-*` are set by Capacitor
    // @see https://capacitorjs.com/docs/apis/system-bars#android-note
    --ion-safe-area-top: var(--safe-area-inset-top, env(safe-area-inset-top));
    --ion-safe-area-bottom: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
    --ion-safe-area-left: var(--safe-area-inset-left, env(safe-area-inset-left));
    --ion-safe-area-right: var(--safe-area-inset-right, env(safe-area-inset-right));
  }
}

// Global Card Styles
// --------------------------------------------------

ion-card.ion-color .ion-inherit-color,
ion-card-header.ion-color .ion-inherit-color {
  color: inherit;
}

ion-card-header + ion-card-content {
  padding-top: 0;
}

// Menu Styles
// --------------------------------------------------

.menu-content {
  transform: translate3d(0, 0, 0);
}

.menu-content-open {
  cursor: pointer;
  touch-action: manipulation;

  /**
   * The containing element itself should be clickable but
   * everything inside of it should not clickable when menu is open
   *
   * Setting pointer-events after scrolling has already started
   * will not cancel scrolling which is why we also set
   * overflow-y below.
   */
  pointer-events: none;

  /**
   * This accounts for scenarios where the main content itself
   * is scrollable.
   */
  overflow-y: hidden;
}

/**
 * Setting overflow cancels any in-progress scrolling
 * when the menu opens. This prevents users from accidentally
 * scrolling the main content while also dragging the menu open.
 * The code below accounts for both ion-content and then custom
 * scroll containers within ion-content (such as virtual scroll)
 */
.menu-content-open ion-content {
  --overflow: hidden;
}

.menu-content-open .ion-content-scroll-host {
  overflow: hidden;
}

.menu-content-reveal {
  box-shadow: #{globals.$ion-elevation-1};
}

.menu-content-push {
  box-shadow: #{globals.$ion-elevation-1};
}

// Accordion Styles
// --------------------------------------------------

// The toggle icon is nested in the accordion item so we need to
// style it from a global level.
ion-accordion > [slot="header"] .ion-accordion-toggle-icon {
  color: globals.$ion-icon-default;
  font-size: globals.$ion-scale-600;
}

ion-accordion.accordion-animated > [slot="header"] .ion-accordion-toggle-icon {
  transition: globals.$ion-transition-time-300 transform globals.$ion-transition-curve-quick;
}

@media (prefers-reduced-motion: reduce) {
  ion-accordion .ion-accordion-toggle-icon {
    /* stylelint-disable declaration-no-important */
    transition: none !important;
  }
}

/**
 * The > [slot="header"] selector ensures that we do
 * not modify toggle icons for any nested accordions. The state
 * of one accordion should not affect any accordions inside
 * of a nested accordion group.
 */
ion-accordion.accordion-expanding > [slot="header"] .ion-accordion-toggle-icon,
ion-accordion.accordion-expanded > [slot="header"] .ion-accordion-toggle-icon {
  transform: rotate(180deg);
}

// Items inside of an accordion should have reduced padding
// due to the padding added to the accordion content.
ion-accordion > [slot="content"] ion-item {
  @include globals.typography(globals.$ion-body-md-regular);

  color: globals.$ion-primitives-neutral-1000;

  --padding-top: #{globals.$ion-space-300};
  --padding-bottom: #{globals.$ion-space-300};
  --min-height: #{globals.$ion-scale-700};
}

ion-accordion > [slot="content"] ion-item:not([slot="header"]) {
  --padding-start: 0;
  --padding-end: 0;
}

// Datetime Styles
// --------------------------------------------------

// Safari/iOS 15 changes the appearance of input[type="date"].
// For backwards compatibility from Ionic 5/Safari 14 designs,
// we override the appearance only when using within an ion-input.
ion-input input::-webkit-date-and-time-value {
  text-align: start;
}

/**
 * The .ion-datetime-button-overlay class contains
 * styles that allow any modal/popover to be
 * sized according to the dimensions of the datetime
 * when used with ion-datetime-button.
 */
.ion-datetime-button-overlay {
  --width: fit-content;
  --height: fit-content;
}

/**
 * The grid variant can scale down when inline.
 * When used in a `fit-content` overlay, this causes
 * the overlay to shrink when the month/year picker is open.
 * Explicitly setting the dimensions lets us have a consistently
 * sized grid interface.
 */
.ion-datetime-button-overlay ion-datetime.datetime-grid {
  width: calc(#{globals.$ion-scale-7400} + #{globals.$ion-space-600});
  min-height: calc(#{globals.$ion-scale-7400} + #{globals.$ion-space-600});
}

// Popover Styles
// --------------------------------------------------

/**
 * If a popover has a child ion-content (or class equivalent) then the .popover-viewport element
 * should not be scrollable to ensure the inner content does scroll. However, if the popover
 * does not have a child ion-content (or class equivalent) then the .popover-viewport element
 * should remain scrollable. This code exists globally because popover targets
 * .popover-viewport using ::slotted which only supports simple selectors.
 *
 * Note that we do not need to account for .ion-content-scroll-host here because that
 * class should always be placed within ion-content even if ion-content is not scrollable.
 */
.popover-viewport:has(> ion-content) {
  overflow: hidden;
}
