/*
 * The app shell: header, sidebar, brand text and theme toggle. Plain CSS rather than component styles so
 * pages rendered outside Vue, such as the API's own pages, can use the same look with the same markup.
 * TdkAppShell, TdkBrandText and TdkThemeToggle render these classes.
 */

.tdk-shell {
  --tdk-shell-sidebar: var(--tdk-sidebar-width);
  display: grid;
  grid-template-columns: var(--tdk-shell-sidebar) minmax(0, 1fr);
  grid-template-rows: var(--tdk-header-height) minmax(0, 1fr);
  grid-template-areas:
    'header header'
    'sidebar main';
  min-height: 100vh;
  /* Paints the sidebar column the full page height, past the sticky sidebar's viewport. */
  background: linear-gradient(
    to right,
    var(--tdk-shell-sidebar-bg) var(--tdk-shell-sidebar),
    transparent var(--tdk-shell-sidebar)
  );
  transition: grid-template-columns var(--tdk-transition);
}

.tdk-shell--narrow {
  background: none;
}

.tdk-shell--collapsed {
  --tdk-shell-sidebar: var(--tdk-sidebar-width-collapsed);
}

.tdk-shell--narrow {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    'header'
    'main';
}

.tdk-shell__skip {
  position: absolute;
  left: var(--tdk-space-4);
  top: -100px;
  z-index: calc(var(--tdk-z-header) + 1);
  padding: var(--tdk-space-2) var(--tdk-space-4);
  background: var(--tdk-color-primary);
  color: var(--tdk-color-primary-contrast);
  border-radius: var(--tdk-radius-sm);
}

.tdk-shell__skip:focus {
  top: var(--tdk-space-2);
}

.tdk-shell__header {
  grid-area: header;
  position: sticky;
  top: 0;
  z-index: var(--tdk-z-header);
  display: flex;
  align-items: center;
  gap: var(--tdk-space-3);
  padding: 0 var(--tdk-space-4);
  background: var(--tdk-shell-header-bg);
  -webkit-backdrop-filter: var(--tdk-panel-blur);
  backdrop-filter: var(--tdk-panel-blur);
  color: var(--tdk-shell-header-text);
  border-bottom: 1px solid var(--tdk-color-border-subtle);
  box-shadow: inset 0 -3px 0 var(--tdk-shell-accent);
}

/* Elevated access (a user with an Admin, Administrator or JoelBot role, per the API's
 * Authentication:ElevatedRoles): a red-tinted header with a red accent bar, so it's never mistaken
 * for a normal session. Red is outside the brand palette on purpose. */
.tdk-shell__header--elevated {
  background: color-mix(in srgb, var(--tdk-sev-critical) 9%, var(--tdk-shell-header-bg));
  box-shadow: inset 0 -3px 0 var(--tdk-sev-critical);
}

/* Settings > Red admin header turned off: a normal header; the badge and avatar ring stay. */
:root[data-elevated-tint='off'] .tdk-shell__header--elevated {
  background: var(--tdk-shell-header-bg);
  box-shadow: inset 0 -3px 0 var(--tdk-shell-accent);
}

.tdk-shell__admin-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px var(--tdk-space-2);
  border-radius: var(--tdk-radius-pill);
  background: var(--tdk-sev-critical);
  color: var(--tdk-sev-critical-on);
  font-size: var(--tdk-text-xs);
  font-weight: var(--tdk-weight-bold);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.tdk-shell__admin-badge svg {
  flex: none;
}

.tdk-shell__avatar--elevated {
  box-shadow:
    0 0 0 2px var(--tdk-shell-header-bg),
    0 0 0 4px var(--tdk-sev-critical);
}

.tdk-shell__menu {
  width: 36px;
  padding: 0;
}

.tdk-shell__brand {
  display: flex;
  align-items: center;
  gap: var(--tdk-space-3);
  min-width: 0;
}

.tdk-shell__mark {
  width: 32px;
  height: 32px;
  flex: none;
}

.tdk-shell__titles {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.15;
}

.tdk-shell__title {
  font-family: var(--tdk-font-heading);
  font-weight: var(--tdk-weight-bold);
  font-size: var(--tdk-text-md);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tdk-shell__subtitle {
  font-size: var(--tdk-text-xs);
  color: var(--tdk-color-text-secondary);
}

.tdk-shell__env {
  padding: 0.0625rem 0.5rem;
  border-radius: var(--tdk-radius-pill);
  background: var(--tdk-sev-medium);
  color: var(--tdk-sev-medium-on);
  font-size: var(--tdk-text-xs);
  font-weight: var(--tdk-weight-bold);
  letter-spacing: 0.04em;
}

.tdk-shell__header-actions {
  display: flex;
  align-items: center;
  gap: var(--tdk-space-2);
  margin-left: auto;
}

.tdk-shell__sign-in {
  width: 36px;
  padding: 0;
}

.tdk-shell__user {
  position: relative;
}

.tdk-shell__avatar {
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: var(--tdk-color-primary);
  color: var(--tdk-color-primary-contrast);
  font-size: var(--tdk-text-sm);
  font-weight: var(--tdk-weight-bold);
  cursor: pointer;
}

.tdk-shell__user-menu {
  position: absolute;
  right: 0;
  top: calc(100% + var(--tdk-space-2));
  z-index: var(--tdk-z-overlay);
  min-width: 220px;
  padding: var(--tdk-space-2);
  background: var(--tdk-color-surface);
  border: 1px solid var(--tdk-color-border-subtle);
  border-radius: var(--tdk-radius-md);
  box-shadow: var(--tdk-shadow-lg);
}

.tdk-shell__user-info {
  display: flex;
  flex-direction: column;
  padding: var(--tdk-space-2) var(--tdk-space-3) var(--tdk-space-3);
  border-bottom: 1px solid var(--tdk-color-border-subtle);
  margin-bottom: var(--tdk-space-1);
  font-size: var(--tdk-text-sm);
}

.tdk-shell__user-info span {
  color: var(--tdk-color-text-secondary);
  overflow-wrap: anywhere;
}

.tdk-shell__user-item {
  display: flex;
  align-items: center;
  gap: var(--tdk-space-2);
  width: 100%;
  padding: var(--tdk-space-2) var(--tdk-space-3);
  border: 0;
  border-radius: var(--tdk-radius-sm);
  background: transparent;
  font-size: var(--tdk-text-sm);
  text-align: left;
  cursor: pointer;
}

.tdk-shell__user-item:hover {
  background: var(--tdk-color-hover-wash);
}

.tdk-shell__overlay {
  position: fixed;
  inset: var(--tdk-header-height) 0 0 0;
  z-index: calc(var(--tdk-z-sidebar) - 1);
  background: var(--tdk-color-overlay);
}

.tdk-shell__sidebar {
  grid-area: sidebar;
  position: sticky;
  top: var(--tdk-header-height);
  z-index: var(--tdk-z-sidebar);
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--tdk-header-height));
  padding: var(--tdk-space-4) var(--tdk-space-2);
  overflow-x: hidden;
  overflow-y: auto;
  background: var(--tdk-shell-sidebar-bg);
  color: var(--tdk-shell-sidebar-text);
  border-right: 1px solid var(--tdk-shell-sidebar-edge);
}

.tdk-shell--narrow .tdk-shell__sidebar {
  position: fixed;
  left: 0;
  width: var(--tdk-sidebar-width);
  transform: translateX(-100%);
  transition: transform var(--tdk-transition);
}

.tdk-shell--drawer-open .tdk-shell__sidebar {
  transform: none;
  box-shadow: var(--tdk-shadow-lg);
}

.tdk-shell__nav-group + .tdk-shell__nav-group {
  margin-top: var(--tdk-space-4);
}

.tdk-shell__nav-section {
  margin: 0 0 var(--tdk-space-1);
  padding: 0 var(--tdk-space-3);
  font-size: var(--tdk-text-xs);
  font-weight: var(--tdk-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tdk-shell-sidebar-section);
  white-space: nowrap;
}

.tdk-shell__nav-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.tdk-shell__nav-link {
  display: flex;
  align-items: center;
  gap: var(--tdk-space-3);
  min-height: 40px;
  padding: 0 var(--tdk-space-3);
  border-radius: var(--tdk-radius-sm);
  color: inherit;
  text-decoration: none;
  font-size: var(--tdk-text-sm);
  white-space: nowrap;
}

.tdk-shell__nav-link:hover {
  background: var(--tdk-shell-sidebar-hover-bg);
  color: var(--tdk-shell-sidebar-hover-text);
}

.tdk-shell__nav-link--active,
.tdk-shell__nav-link--active:hover {
  background: var(--tdk-shell-sidebar-active-bg);
  color: var(--tdk-shell-sidebar-active-text);
  font-weight: var(--tdk-weight-semibold);
}

/* Expandable items (TdkNavItem.children): the link, a chevron to open its list, then the list. */
.tdk-shell__nav-parent {
  display: flex;
  align-items: center;
  gap: 2px;
}

.tdk-shell__nav-parent > .tdk-shell__nav-link {
  flex: 1;
  min-width: 0;
}

.tdk-shell__nav-expand {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: var(--tdk-radius-sm);
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.tdk-shell__nav-expand:hover {
  background: var(--tdk-shell-sidebar-hover-bg);
  color: var(--tdk-shell-sidebar-hover-text);
}

.tdk-shell__nav-expand .tdk-icon {
  transform: rotate(-90deg);
  transition: transform var(--tdk-transition);
}

.tdk-shell__nav-expand--open .tdk-icon {
  transform: none;
}

.tdk-shell__nav-children {
  margin: 2px 0 var(--tdk-space-2) calc(var(--tdk-space-3) + 10px);
  padding: 0 0 0 var(--tdk-space-3);
  border-left: 1px solid var(--tdk-shell-sidebar-rule);
  list-style: none;
}

.tdk-shell__nav-child {
  display: block;
  padding: 5px var(--tdk-space-3);
  border-radius: var(--tdk-radius-sm);
  color: inherit;
  font-size: var(--tdk-text-sm);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tdk-shell__nav-child:hover {
  background: var(--tdk-shell-sidebar-hover-bg);
  color: var(--tdk-shell-sidebar-hover-text);
}

.tdk-shell__nav-child--active,
.tdk-shell__nav-child--active:hover {
  box-shadow: inset 2px 0 0 var(--tdk-shell-accent);
  color: var(--tdk-shell-sidebar-hover-text);
  font-weight: var(--tdk-weight-semibold);
}

.tdk-shell__nav-ext {
  margin-left: auto;
  opacity: 0.7;
}

.tdk-shell--collapsed .tdk-shell__nav-label,
.tdk-shell--collapsed .tdk-shell__nav-ext,
.tdk-shell--collapsed .tdk-shell__nav-expand,
.tdk-shell--collapsed .tdk-shell__nav-children,
.tdk-shell--collapsed .tdk-shell__sidebar-footer {
  display: none !important;
}

/* Collapsed, a section heading keeps its height, so the links don't jump when the sidebar collapses or expands.
 * Its text is hidden and a short rule marks the section instead. */
.tdk-shell--collapsed .tdk-shell__nav-section {
  position: relative;
  overflow: hidden;
  color: transparent;
  user-select: none;
}

.tdk-shell--collapsed .tdk-shell__nav-section::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 30%;
  right: 30%;
  border-top: 1px solid var(--tdk-shell-sidebar-rule);
}

.tdk-shell--collapsed .tdk-shell__nav-link {
  justify-content: center;
  padding: 0;
}

.tdk-shell__sidebar-bottom {
  margin-top: auto;
  padding-top: var(--tdk-space-4);
}

/* No wrapping, like the nav labels: while the sidebar widens from collapsed, the text is clipped rather than reflowed
 * through a narrow column. */
.tdk-shell__sidebar-footer {
  padding: 0 var(--tdk-space-3);
  overflow: hidden;
  font-size: var(--tdk-text-xs);
  color: var(--tdk-shell-sidebar-section);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tdk-shell__sidebar-actions {
  display: flex;
  align-items: center;
  gap: var(--tdk-space-1);
  margin-top: var(--tdk-space-3);
  padding-top: var(--tdk-space-3);
  border-top: 1px solid var(--tdk-shell-sidebar-rule);
}

.tdk-shell__sidebar-action {
  display: inline-flex;
  align-items: center;
  gap: var(--tdk-space-2);
  min-height: 40px;
  padding: 0 var(--tdk-space-3);
  border: 0;
  border-radius: var(--tdk-radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--tdk-text-sm);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.tdk-shell__sidebar-action--icon {
  justify-content: center;
  width: 40px;
  padding: 0;
}

.tdk-shell__sidebar-action:hover {
  background: var(--tdk-shell-sidebar-hover-bg);
  color: var(--tdk-shell-sidebar-hover-text);
}

.tdk-shell__sidebar-action.tdk-shell__nav-link--active {
  background: var(--tdk-shell-sidebar-active-bg);
  color: var(--tdk-shell-sidebar-active-text);
}

.tdk-shell--collapsed .tdk-shell__sidebar-actions {
  flex-direction: column;
  border-top: 0;
  padding-top: 0;
}

.tdk-shell--collapsed .tdk-shell__sidebar-action {
  justify-content: center;
  width: 40px;
  padding: 0;
}

.tdk-shell__main {
  grid-area: main;
  display: flex;
  flex-direction: column;
  min-width: 0;
  outline: none;
}

.tdk-shell__content {
  flex: 1;
  width: 100%;
  max-width: var(--tdk-content-max);
  margin: 0 auto;
  padding: var(--tdk-space-6);
}

.tdk-shell__footer {
  padding: var(--tdk-space-4) var(--tdk-space-6);
  border-top: 1px solid var(--tdk-color-border-subtle);
  font-size: var(--tdk-text-xs);
  color: var(--tdk-color-text-muted);
}

@media (max-width: 640px) {
  .tdk-shell__content {
    padding: var(--tdk-space-4);
  }

  .tdk-shell__subtitle,
  .tdk-shell__env {
    display: none;
  }
}

@media print {
  .tdk-shell {
    display: block;
  }

  .tdk-shell__header,
  .tdk-shell__sidebar,
  .tdk-shell__skip {
    display: none;
  }
}

/* TdkThemeToggle */
.tdk-theme-toggle {
  width: 36px;
  padding: 0;
}

/* TdkBrandText */
.tdk-brand {
  display: inline-block;
  white-space: nowrap;
  font-weight: var(--tdk-weight-semibold);
}

.tdk-brand__text {
  display: inline-block;
  background:
    linear-gradient(100deg, transparent 0 42%, var(--tdk-brand-hi) 50%, transparent 58% 100%) 100%
      0 / 300% 100% no-repeat,
    linear-gradient(90deg, var(--tdk-brand-blue), var(--tdk-brand-green));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation:
    tdk-brand-type 1s steps(var(--tdk-brand-steps), end) 0.35s both,
    tdk-brand-shine 8s ease-in-out 2.4s infinite;
}

/* Caret */
.tdk-brand::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 1.05em;
  margin-left: 3px;
  vertical-align: -2px;
  border-radius: 1px;
  background: var(--tdk-brand-green);
  opacity: 0;
  animation: tdk-brand-caret 0.6s 1.35s 4 forwards;
}

.tdk-brand--done .tdk-brand__text {
  animation: tdk-brand-shine 8s ease-in-out 2.4s infinite;
}

.tdk-brand--done::after,
.tdk-brand--still::after {
  animation: none;
}

.tdk-brand--still .tdk-brand__text {
  animation: none;
}

@keyframes tdk-brand-type {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes tdk-brand-caret {
  0%,
  49% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}

@keyframes tdk-brand-shine {
  0%,
  72% {
    background-position:
      100% 0,
      0 0;
    filter: none;
  }
  86% {
    filter: drop-shadow(0 0 6px var(--tdk-brand-glow));
  }
  100% {
    background-position:
      0 0,
      0 0;
    filter: none;
  }
}

/* An infinite shimmer at the global reduced-motion duration would flicker; rest instead. */
@media (prefers-reduced-motion: reduce) {
  .tdk-brand__text,
  .tdk-brand::after {
    animation: none !important;
  }
}

@media print {
  .tdk-brand__text {
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--tdk-brand-blue);
  }

  .tdk-brand::after {
    display: none;
  }
}

@media (forced-colors: active) {
  .tdk-brand__text {
    background: none;
    -webkit-text-fill-color: currentColor;
    animation: none;
  }

  .tdk-brand::after {
    display: none;
  }
}
