@use '../tokens' as t;

// Grid areas, not floats or fixed positioning: the areas re-flow at one breakpoint and the
// writing mode is handled by the grid itself, so RTL needs no second rule.
.shell {
  display: grid;
  // `minmax(0, …)`, never the implicit `auto`: an auto track is at least its content's min-content
  // width, so a header that did not shrink laid a 390px phone out 429px wide.
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: 'header' 'sidebar' 'main' 'footer';
  grid-template-rows: auto auto 1fr auto;
  min-block-size: 100dvh;
  background: t.role('bg');
  color: t.role('fg');

  @include t.respond-to(md) {
    grid-template-columns: var(--shell-sidebar, 16rem) minmax(0, 1fr);
    grid-template-areas: 'header header' 'sidebar main' 'footer footer';
    grid-template-rows: auto 1fr auto;
  }
}

.no-sidebar {
  grid-template-areas: 'header' 'main' 'footer';
  grid-template-rows: auto 1fr auto;

  @include t.respond-to(md) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: 'header' 'main' 'footer';
  }
}

// Off-screen but focusable — the first Tab on any page reveals it.
.skip {
  @include t.focus-ring;
  @include t.transition(translate);
  position: fixed;
  z-index: t.z(skip-nav);
  inset-block-start: t.space(2);
  inset-inline-start: t.space(2);
  padding-block: t.space(2);
  padding-inline: t.space(4);
  border: 1px solid t.role('line');
  border-radius: t.radius(md);
  background: t.role('surface-raised');
  color: t.role('fg-strong');
  box-shadow: t.shadow(md);
  font-weight: t.weight(semibold);
  text-decoration: none;
  translate: 0 -400%;

  &:focus-visible {
    translate: 0 0;
  }
}

// The bar the banner sits in: the menu button (below `md`) and the app's header, side by side.
.top {
  display: flex;
  min-inline-size: 0;
  align-items: center;
  gap: t.space(2);
  grid-area: header;
  padding-inline-start: t.space(2);
  border-block-end: 1px solid t.role('line');
  background: t.role('surface');

  @include t.respond-to(md) {
    padding-inline-start: 0;
  }
}

.menuOnly {
  display: none;
}

.header {
  @include t.row(t.space(4), center, space-between);
  flex: 1;
  min-inline-size: 0;
  padding-block: t.space(3);
  padding-inline: t.space(4);
}

// Hidden unless the engine can open the panel it names: a button that does nothing is worse than
// the band an engine without popovers still shows. A touch target: this bar exists for a phone.
.menuButton,
.close {
  @include t.focus-ring;
  @include t.touch-target;
  display: none;
  align-items: center;
  justify-content: center;
  gap: t.space(2);
  padding-inline: t.space(3);
  border: 0;
  border-radius: t.radius(md);
  background: none;
  color: t.role('fg-strong');
  font: inherit;
  cursor: pointer;

  &:hover {
    background: t.role('bg-soft');
  }
}

.close {
  margin-inline-start: auto;
}

// On a phone the menu button is its icon; the label stays in the accessibility tree as its name.
.menuLabel {
  @include t.respond-down(sm) {
    @include t.visually-hidden;
  }
}

.sticky {
  position: sticky;
  z-index: t.z(sticky);
  inset-block-start: 0;
}

// From `md` the sidebar is the inline-start column; below it, the popover panel further down.
// Every `[popover]` gets a UA style — fixed, centred, bordered, hidden while closed — so the
// in-flow box undoes each, and is what an engine without popovers shows at every width.
.sidebar {
  @include t.custom-scrollbar;
  display: block;
  position: static;
  inset: auto;
  inline-size: auto;
  block-size: auto;
  margin: 0;
  grid-area: sidebar;
  padding: t.space(4);
  border: 0;
  border-block-end: 1px solid t.role('line');
  background: t.role('bg-soft');
  color: t.role('fg');
  overflow: auto;

  // Deliberately not sticky: a sticky sidebar and a sticky header both anchored at 0 overlap,
  // and the header's height is not knowable in CSS. The page scrolls as one.
  @include t.respond-to(md) {
    border-block-end: 0;
    border-inline-end: 1px solid t.role('line');
  }
}

.main {
  grid-area: main;
  min-inline-size: 0;
  padding-block: t.space(6);
  padding-inline: t.space(4);

  // The skip link moves focus here; the ring would otherwise draw around the whole page.
  &:focus-visible {
    outline: none;
  }

  @include t.respond-to(md) {
    padding-inline: t.space(6);
  }
}

.footer {
  grid-area: footer;
  padding-block: t.space(5);
  padding-inline: t.space(4);
  border-block-start: 1px solid t.role('line');
  background: t.role('surface');
  color: t.role('fg-muted');
  font-size: t.text(sm);
}

// --- Below `md`, where the engine has popovers: the sidebar is an edge panel ----------------------
// The same look as `Drawer`'s inline-start side — raised surface, line edge, scrim — so the two
// off-canvas surfaces in an app read as one.
@include t.respond-down(md) {
  @supports selector(:popover-open) {
    .sidebar:not(:popover-open) {
      display: none;
    }

    .sidebar:popover-open {
      @include t.scrim-backdrop;
      position: fixed;
      inset-block: 0;
      inset-inline-start: 0;
      inset-inline-end: auto;
      inline-size: min(var(--shell-sidebar, 16rem), calc(100vw - #{t.space(12)}));
      block-size: 100dvh;
      max-block-size: 100dvh;
      border-block-end: 0;
      border-inline-end: 1px solid t.role('line');
      background: t.role('surface-raised');
      box-shadow: t.shadow(xl);
    }

    .menuButton,
    .close {
      display: inline-flex;
    }

    .menuOnly {
      display: flex;
    }
  }
}
