/**
 * @file
 * Everything this theme needs on top of stock Bootstrap.
 *
 * Bootstrap does the grid, the buttons and the forms; the rules here are the
 * hero's background image, the few hooks Drupal's markup adds that Bootstrap
 * has no class for, and the spacing a navbar with three separate blocks needs.
 */

/*
 * The footer stays at the bottom of the window on a short page. The body is a
 * flex column of full height (html.html.twig), but Drupal wraps the page in a
 * div of its own, so that div has to be a growing flex column too, or <main>
 * and the footer's mt-auto have no height to share.
 */
.dialog-off-canvas-main-canvas {
  display: flex;
  flex-direction: column;
  flex: 1 0 auto;
}

/* Anchor jumps must land below the sticky navbar, not behind it. */
html {
  scroll-padding-top: 5rem;
}

/*
 * Navigation. The blocks placed in the navbar (the language switcher and the
 * account menu) sit side by side, which takes two rows of flex rather than one:
 * every region renders inside a single bare wrapper <div> holding all of that
 * region's blocks, so the collapse arranges the wrappers and each wrapper has to
 * arrange its own blocks. Miss the second one and Bootstrap's navbar rules never
 * see the account menu as a flex item — it drops below the bar, with the dark
 * background ending above it.
 */
.navbar .navbar-collapse {
  gap: 1rem;
}

@media (min-width: 992px) {
  .navbar .navbar-collapse,
  .navbar .navbar-collapse > div {
    align-items: center;
    display: flex;
    justify-content: flex-end;
  }
}

/*
 * Status messages. The highlight region is never really empty — the messages
 * fallback <div> is always in it — so the container around it carries no margin
 * of its own, or every page in the site would start with a strip of white under
 * the navbar. The space a message needs comes from the message.
 */
[data-drupal-messages] .alert:first-child {
  margin-top: 1rem;
}

/*
 * The current language. Core marks it is-active; Bootstrap styles .active, so
 * without this the switcher shows both codes in the same shade and the reader
 * has to work out which page they are on.
 */
.navbar .nav-link.is-active {
  color: var(--bs-navbar-active-color);
}

.brand-logo {
  padding: 0;
}

.brand-logo img {
  display: block;
  height: 3rem;
  width: auto;
}

/*
 * Hero. The background is a real <img> with object-fit rather than a CSS
 * background image: it scales identically in every browser and can carry
 * loading="eager" and a width/height pair.
 */
.hero-section {
  min-height: 500px;
  overflow: hidden;
  position: relative;
}

.hero-bg {
  inset: 0;
  position: absolute;
}

.hero-bg img {
  display: block;
  height: 100%;
  object-fit: cover;
  object-position: center;
  width: 100%;
}

/* The dark wash that keeps the headline readable over any photo. */
.hero-bg::after {
  background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.7));
  content: "";
  inset: 0;
  position: absolute;
}

/* Order section, lifted off the white trial section above it. */
.section-alt {
  background: linear-gradient(180deg, #f4f7fb 0%, #e7eef7 100%);
  border-top: 1px solid rgba(13, 110, 253, 0.12);
}

/*
 * Forms.
 *
 * Bootstrap marks a required field with no visible sign, and Drupal only adds
 * the .form-required class to the label.
 */
.form-required::after {
  color: var(--bs-danger);
  content: " *";
}

/*
 * The live quote the order form recalculates over AJAX, laid out as a receipt:
 * item, how it is counted, amount — amounts right-aligned in one column, the
 * total under a rule and larger than the rest.
 */
.nexia-order-quote {
  margin: 1.5rem 0;
  padding: 1.25rem 1.5rem;
  background: var(--bs-light);
  border: 1px solid var(--bs-border-color);
  border-radius: 0.75rem;
  max-width: 34rem;
}
.nexia-order-quote__title {
  margin: 0 0 0.75rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
}
.nexia-order-quote__rows {
  margin: 0;
}
.nexia-order-quote__row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "label amount" "detail amount";
  column-gap: 1rem;
  align-items: baseline;
  padding: 0.5rem 0;
}
.nexia-order-quote__row + .nexia-order-quote__row {
  border-top: 1px dashed var(--bs-border-color);
}
.nexia-order-quote__row dt {
  grid-area: label;
  font-weight: 600;
}
.nexia-order-quote__row dd {
  margin: 0;
}
.nexia-order-quote__detail {
  grid-area: detail;
  font-size: 0.9rem;
  color: var(--bs-secondary-color);
}
.nexia-order-quote__amount {
  grid-area: amount;
  align-self: center;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.nexia-order-quote__row--total {
  grid-template-areas: "label amount";
  margin-top: 0.25rem;
  padding-top: 0.75rem;
  border-top: 2px solid var(--bs-body-color) !important;
}
.nexia-order-quote__row--total dt,
.nexia-order-quote__row--total .nexia-order-quote__amount {
  font-size: 1.35rem;
  font-weight: 700;
}

/* The tick list in the free trial section. */
.trial-list svg {
  flex: 0 0 auto;
}

/*
 * Status messages in a modal (js/messages-modal.js).
 *
 * Wide enough for a paragraph (modal-lg), never taller than most of the
 * window: modal-dialog-scrollable scrolls the body, and the cap below keeps a
 * long message from turning the dialog into a column. The dialog pops in from
 * slightly smaller with a small overshoot, over a blurred page.
 */
.nexia-messages-modal {
  --nexia-accent: var(--bs-primary);
}
.nexia-messages-modal--status { --nexia-accent: var(--bs-success); }
.nexia-messages-modal--warning { --nexia-accent: var(--bs-warning); }
.nexia-messages-modal--error { --nexia-accent: var(--bs-danger); }

.nexia-messages-modal .modal-content {
  border: 0;
  border-top: 6px solid var(--nexia-accent);
  border-radius: 1rem;
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, .25);
  overflow: hidden;
}
.nexia-messages-modal .modal-header {
  gap: .75rem;
  border-bottom: 0;
  padding: 1.5rem 1.5rem .5rem;
}
.nexia-messages-modal__icon {
  display: inline-flex;
  color: var(--nexia-accent);
}
.nexia-messages-modal .modal-body {
  max-height: min(60vh, 32rem);
  padding: .5rem 1.5rem 1rem;
  font-size: 1.0625rem;
  line-height: 1.6;
}
.nexia-messages-modal .modal-footer {
  border-top: 0;
  padding: 0 1.5rem 1.5rem;
}
.nexia-messages-modal__message + .nexia-messages-modal__message {
  margin-top: .75rem;
  padding-top: .75rem;
  border-top: 1px solid var(--bs-border-color);
}
.nexia-messages-modal__message ul {
  margin-bottom: 0;
}

/* The pop: Bootstrap's .fade handles opacity; this replaces its slide-down. */
.nexia-messages-modal.fade .modal-dialog {
  transform: scale(.85) translateY(1.5rem);
  transition: transform .45s cubic-bezier(.34, 1.56, .64, 1);
}
.nexia-messages-modal.show .modal-dialog {
  transform: none;
}
.nexia-messages-modal.show .nexia-messages-modal__icon svg {
  animation: nexia-icon-pop .5s .15s cubic-bezier(.34, 1.56, .64, 1) both;
}
@keyframes nexia-icon-pop {
  from { transform: scale(0) rotate(-30deg); }
  to { transform: none; }
}
body:has(.nexia-messages-modal.show) .modal-backdrop.show {
  backdrop-filter: blur(3px);
  background-color: rgba(15, 23, 42, .55);
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .nexia-messages-modal.fade .modal-dialog,
  .nexia-messages-modal.show .nexia-messages-modal__icon svg {
    transition: none;
    animation: none;
    transform: none;
  }
}

/*
 * Logged in with core's admin sidebar (Navigation module): its flyouts and
 * top bar sit at z-index 490-601, while Bootstrap's sticky-top puts the navbar
 * at 1020, so the navbar covered the top of an opened flyout. Under the admin
 * layers but still over the page. Visitors have no .admin-toolbar and keep
 * Bootstrap's value.
 */
body:has(.admin-toolbar) .navbar.sticky-top {
  z-index: 400;
}
