/* Component styles, collected here from the Vue components' <style scoped>
   blocks. The Nuxt build inlined these per-component; with templ there is
   no build step, so they live in one plain stylesheet next to the design
   system. Selectors are already BEM-ish and effectively scoped by name. */

.app-icon {
  flex-shrink: 0;
  display: block;
}

/* --- auth shell (was layouts/auth.vue) ------------------------------- */

.auth-shell {
  min-height: 100vh;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  background: var(--nm-bg);
}

.auth-shell__corner {
  position: absolute;
  top: 24px;
  right: 24px;
  z-index: 2;
}

/* --- header (was components/AppHeader.vue) --------------------------- */

.app-header {
  padding-left: 20px;
  padding-right: 20px;
  min-height: 64px;
  gap: 12px;
  /* anchor for the narrow-view dropdown panel */
  position: relative;
}

.app-header__brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--nm-text);
  font-weight: 600;
  font-size: 17px;
}

.app-header__brand .app-icon {
  color: var(--nm-accent);
}

.app-header__name {
  letter-spacing: -0.01em;
}

.app-header__nav {
  display: flex;
  gap: 0;
  margin-left: 12px;
  min-width: 0;
  overflow: hidden;
}

/* ponytail: no breakpoint. The links shrink and their labels clip away, so
   the header cannot outgrow the viewport at any width; the icons keep their
   size (.app-icon is flex-shrink: 0), so a fully clipped link is still an
   icon button with its title and aria-label intact. */
.app-header__navlink {
  color: var(--nm-text-muted);
  text-decoration: none;
  min-width: 0;
}

/* --- header menu (wide: flat row, narrow: hamburger) ------------------ */

/* Wide: the wrapper and its panel vanish from the box tree, so nav, spacer
   and locale strip are direct header flex children, same as before. */
.app-menu,
.app-menu__panel {
  display: contents;
}

/* Visually hidden but still focusable and still the open state. */
.app-menu__toggle {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.app-menu__button {
  display: none;
  cursor: pointer;
}

.app-menu__toggle:focus-visible + .app-menu__button {
  outline: 2px solid var(--nm-accent);
  outline-offset: 2px;
}

@media (max-width: 900px) {
  .app-menu {
    display: block;
  }
  .app-menu__button {
    display: inline-flex;
  }
  .app-menu__panel {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 20;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 8px;
    background: var(--nm-surface);
    border-bottom: 1px solid var(--nm-border);
  }
  .app-menu__toggle:checked ~ .app-menu__panel {
    display: flex;
  }
  .app-menu__panel .app-header__nav {
    flex-direction: column;
    align-items: stretch;
    margin-left: 0;
    overflow: visible;
  }
  .app-menu__panel .app-header__navlink {
    justify-content: flex-start;
  }
  .app-menu__panel .locale-strip {
    justify-content: flex-start;
    padding-top: 4px;
    border-top: 1px solid var(--nm-border);
  }
}
.app-header__navlink--active {
  color: var(--nm-text);
}

.app-header__spacer {
  flex: 1;
}

.app-header__avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--nm-surface-2);
  border: 1px solid var(--nm-border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--nm-text-muted);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}
.app-header__avatar:hover,
.app-header__avatar:focus-visible {
  border-color: var(--nm-border-strong);
  color: var(--nm-text);
}

.app-header__signout-form {
  display: contents;
}

.app-header__signout {
  min-height: 36px;
  padding: 0 8px;
  color: var(--nm-text-muted);
}

/* --- locale strip (was components/LocaleStrip.vue) ------------------- */

.locale-strip {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  color: var(--nm-text-muted);
  font-size: 13px;
}

.locale-strip form {
  display: contents;
}

.locale-strip__label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 12px;
}

/* Chevron on a setlist row — the Vue markup set this inline on <AppIcon>. */
.setlist__chev {
  color: var(--nm-text-faint);
}

/* Flipped chevron: the sprite carries one "chev-down" and the up variants
   rotate it (scroll-to-top, move-up buttons). */
.icon-flip {
  transform: rotate(180deg);
}

/* Library section labels — the Vue markup set these inline on the header
   and its pin icon. */
.library__pinned-icon {
  color: var(--nm-accent);
}
.library__section-count {
  margin-left: 4px;
}
.library__section-label--rest {
  margin-top: 8px;
}

/* Per-section outcome message on the song edit page. */
.admin-edit__flash {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}
.admin-edit__flash--ok {
  color: var(--nm-success);
}
.admin-edit__flash--err {
  color: var(--nm-danger);
}

/* Add-user card on the admin users page. */
/* No max-width: the cards sit above the user list, which fills the page,
   and two stacked blocks in different widths read as a mistake. The settings
   page constrains its card because it stands alone there. */
.admin-users__add {
  padding: 18px 20px;
  margin-bottom: 20px;
}
.admin-users__add-form {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.admin-users__add-form .nm-field {
  flex: 1 1 220px;
}
.admin-users__credential {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--nm-accent);
  border-radius: var(--nm-radius);
  font-size: 13px;
}
/* The password is shown once and has to be transcribed — give it room and
   let it be selected without catching the surrounding text. */
.admin-users__credential-pw {
  display: inline-block;
  margin-left: 12px;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--nm-surface-2);
  font-size: 15px;
  letter-spacing: 0.06em;
  user-select: all;
}

/* Invite links: long, must be transmitted exactly, so give them room. */
.admin-users__invite-url {
  flex: 1 1 320px;
  font-family: var(--nm-font-mono);
  font-size: 12px;
  word-break: break-all;
  user-select: all;
}
.admin-users__credential {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.admin-users__invites {
  margin-top: 6px;
}
.admin-users__invite-row {
  padding-left: 0;
  padding-right: 0;
}
/* A spent or expired invite is a record, not something to act on. */
.admin-users__invite-row--spent .primary,
.admin-users__invite-row--spent .secondary {
  color: var(--nm-text-faint);
}
