/*
 * auth.css — ShadowDark GM, Phase 1b (closed-beta LANDING + LOGIN + signed-in
 * nav affordance). Reuses the existing OSR system: Stone Wall surfaces, Mortar
 * Line borders, the accent stripe for live content, .field / .btn components.
 * No new visual vocabulary, no new colors — everything references base.css
 * tokens so a theme/accent change cascades automatically.
 *
 * Built from KDL 2026-06-27's direction (_team/design/user_profile_ux.md §3 + §5).
 */

/* ============================================================
   Standalone auth pages (/invite.html, /reset.html)
   These pages do NOT use the app shell or load app.js — they are focused
   single-task screens. The body stacks header / main / footer with the main
   centered in the viewport. Reuses the app-header / app-footer chrome from
   layout.css so the wordmark + attribution match the app exactly.
   ============================================================ */
.auth-standalone {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.auth-standalone__main {
  flex: 1 1 auto;
  width: 100%;
  padding: 0 var(--space-md);
}

/* ============================================================
   Landing + login view
   ============================================================ */

.auth-landing {
  /* Centered reading column — these are focused single-task screens, narrower
     than the wide content grid. */
  max-width: 34rem;
  /* Compact top gap so the mark sits higher; was --space-2xl (48px). */
  margin: var(--space-lg) auto 0;
  width: 100%;
}

/* Header: torch mark to the LEFT, the "Gate is Barred" notice to its right,
   vertically centered against the notice block. Stacks (logo above text) on
   narrow viewports so it never overflows. */
.auth-landing__header {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  margin-bottom: var(--space-lg);
}

.auth-landing__logo {
  display: block;
  flex: 0 0 auto;
  width: 80px;
  height: auto;
}

/* The notice takes the remaining row width beside the mark. */
.auth-landing__header .auth-landing__notice {
  flex: 1 1 auto;
  margin: 0;
}

@media (max-width: 30rem) {
  .auth-landing__header {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
}

/* The closed-beta notice reuses the parchment / accent-stripe "live content"
   panel recipe (.panel--parchment already supplies the left accent stripe). */
.auth-landing__notice {
  padding: var(--space-lg);
}

.auth-landing__notice-title {
  font-family: var(--font-heading);
  font-size: var(--text-h2);
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--color-heading);
  margin: 0 0 var(--space-sm);
}

.auth-landing__notice-body {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: var(--lh-body);
  color: var(--color-text);
  margin: 0;
}

/* Sign-in card — Stone Wall surface + 1px Mortar Line border, square corners. */
.auth-card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  padding: var(--space-lg);
  margin-top: var(--space-lg);
}

.auth-card__title {
  font-family: var(--font-heading);
  font-size: var(--text-h3);
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--color-heading);
  margin: 0 0 var(--space-lg);
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* Password field + show/hide toggle on one row. */
.auth-form__pw {
  display: flex;
  gap: var(--space-sm);
  align-items: stretch;
}

.auth-form__pw .field__input {
  flex: 1 1 auto;
}

/* Text-based Show/Hide toggle (not an icon-only control) — KDL 2026-06-27 §3 a11y. */
.auth-form__pw-toggle {
  appearance: none;
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
  cursor: pointer;
  flex: 0 0 auto;
  padding: 0 var(--space-md);

  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-cinzel-caps);

  transition:
    color var(--transition-fast),
    border-color var(--transition-fast);
}

.auth-form__pw-toggle:hover {
  color: var(--color-text);
  border-color: var(--color-text-muted);
}

.auth-form__pw-toggle:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.auth-form__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  align-items: center;
}

.auth-form__actions .btn {
  width: 100%;
}

/* "Forgot password?" — a quiet text link beneath Sign In (Email v2 §E). It is a
   <button> for semantics (it toggles an inline panel, not a navigation), styled
   as an underlined accent link so it never competes with the primary Sign In
   button above it. */
.auth-form__forgot-link {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--color-text-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--transition-fast);
}

.auth-form__forgot-link:hover {
  color: var(--color-accent);
}

.auth-form__forgot-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* The collapsible forgot-password panel, set off by the same "or" divider the
   Discord / request-access blocks use, so it reads as a secondary path within
   the Sign In card. Hidden until the link toggles it. */
.auth-form__forgot {
  margin-top: var(--space-md);
}

.auth-form__forgot[hidden] {
  display: none;
}

/* Generic inline error region. Void Red is an allowed system color for errors.
   The accent stripe + subdued danger background match the parchment recipe but
   in the danger family. */
.auth-form__error {
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  background-color: var(--color-danger-bg);
  border-left: 3px solid var(--color-danger);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: var(--lh-body);
}

.auth-form__error:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ============================================================
   Sign in with Discord (Surface 3) — secondary, below the password form.
   The password form stays primary; this is an alternative path, set off by an
   "or" rule. The button is the app's themed .btn--secondary (black + accent),
   never a bespoke white Discord button — only a small glyph carries the brand
   affinity. Full-width to match the primary Sign In button above.
   ============================================================ */

.auth-form__alt {
  margin-top: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* "or" divider: a centered label over a hairline rule. aria-hidden — purely
   decorative; the button's own label carries the meaning. */
.auth-form__divider {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--color-text-muted);
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
}

.auth-form__divider::before,
.auth-form__divider::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background-color: var(--color-border);
}

.auth-form__discord {
  width: 100%;
}

.auth-form__discord-glyph {
  display: inline-flex;
  align-items: center;
  /* The SVG inherits currentColor, so the glyph flips with the button label on
     hover/focus (accent -> auto-contrast ink) — no separate brand fill. */
}

/* ============================================================
   Request early access (public funnel) — the form BELOW the Sign In card on
   the gate, for logged-out visitors. Reuses the .auth-card surface + .auth-form
   + .field components wholesale so it matches the gate exactly; no new visual
   vocabulary. Sign In stays primary; this is the secondary, opt-in path, set off
   by the same "or" divider the Discord block uses.
   ============================================================ */

.auth-request__lede {
  margin: 0 0 var(--space-lg);
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: var(--lh-body);
  color: var(--color-text-muted);
}

/* The optional-field hint after a label (de-emphasized). Scoped to the request
   form so it never collides with the global .field__hint defined elsewhere
   (bug.css). */
.auth-request .field__hint {
  font-weight: 400;
  font-style: italic;
  color: var(--color-text-muted);
}

.auth-request__note {
  resize: vertical;
  min-height: 4.5rem;
  font-family: var(--font-body);
}

/* Live character counter — muted, right-aligned, small. Mirrors the note cap. */
.auth-request__counter {
  margin: var(--space-xs) 0 0;
  text-align: right;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* Honeypot (SEC-7): visually + semantically removed from the page for humans,
   but still a real, focusable-by-bots input in the DOM. Positioned OFF-SCREEN
   rather than display:none / visibility:hidden, which some bots skip. aria-hidden
   on the wrapper keeps it out of the accessibility tree; tabindex=-1 on the input
   keeps it out of keyboard tab order. */
.auth-request__hp {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ============================================================
   Signed-in nav affordance — right-aligned Profile dropdown
   The Profile .nav-menu lives in the existing menubar. It is pushed to the far
   right with margin-left:auto so it reads as account chrome, distinct from the
   left-aligned content sections. It reuses the existing .nav-menu / .mode-btn /
   .nav-menu__panel patterns wholesale.
   ============================================================ */

.nav-menu--profile {
  margin-left: auto;
}

/* The dropdown panel opens flush to the RIGHT edge under the trigger (the
   content menus open left-aligned; the right-pushed account menu mirrors that). */
.nav-menu--profile .nav-menu__panel {
  left: auto;
  right: 0;
}

/* Small avatar/seal glyph to the left of the PROFILE label (engraved icon
   style: 1.5px stroke, currentColor — inherits the nav text color). */
.nav-menu__avatar {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
}

/* The signed-in username shown beneath/within the dropdown trigger context.
   Kept subtle so the label still reads PROFILE first. */
.nav-menu__username {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: none;
}

/* Pending-friend-request accent on the Profile trigger (Email v2 §D). A subtle
   accent asterisk that sits between the username and the caret; it appears only
   when the user has incoming pending friend requests. The visible glyph is
   decorative (aria-hidden); the count is announced via an sr-only label on the
   role="status" wrapper. Kept quiet — it reads as an accent, not a badge. */
.nav-menu__pending {
  display: inline-flex;
  align-items: center;
  margin-left: 0.1em;
}
.nav-menu__pending[hidden] {
  display: none;
}
.nav-menu__pending-mark {
  color: var(--color-accent, #6495ED);
  font-size: 1.15em;
  line-height: 0;
  /* Nudge the asterisk up so it reads as a superscript accent on the label. */
  transform: translateY(-0.12em);
}

/* Sign out is a real action button styled as a menuitem; it inherits the
   .nav-menu__item look. No extra rules needed beyond nav.css. */

/* Hidden state for the whole Profile menu when logged out. [hidden] is honored
   app-wide, but the menubar is a flex container, so enforce none explicitly. */
[data-auth-profile][hidden] {
  display: none !important;
}

/* ============================================================
   Enforced-landing menubar gate (Phase 1c)
   When enforcement is ON and no user is signed in, the closed-beta landing
   REPLACES the app (KDL 2026-06-27 §3) — the section menubar must not be reachable behind
   it. auth.js sets [hidden] on .mode-bar and body.auth-gated; this enforces the
   hide explicitly since the menubar is a flex container (matching the
   [data-auth-profile][hidden] pattern above). Belt-and-suspenders: the body
   class also covers the bar in case the [hidden] attribute is ever overridden.
   ============================================================ */
.mode-bar[hidden],
body.auth-gated .mode-bar {
  display: none !important;
}

/* ============================================================
   Center the gate login in the viewport (KDL 2026-06-30, Ken)
   When the screen is taller/wider than the login block, center it on BOTH axes
   instead of pinning it to the top. The gate renders into #app-content, which is
   the flex:1 growth row of the .app-shell flex column — so making that row a
   centering flex container centers the landing block in the leftover space
   between the header and footer.

   Scoped to body.auth-gated so ONLY the enforced gate is affected; the signed-in
   app keeps its top-aligned content. Using `margin: auto` on the landing block
   (rather than justify-content:center) centers it when there's spare room but
   lets it top-align and scroll naturally when the form is TALLER than the space
   (no clipping on short viewports). The landing keeps its own 34rem max-width, so
   on small/medium screens where the form fills the space the layout is unchanged.
   ============================================================ */
body.auth-gated #app-content {
  display: flex;
  flex-direction: column;
}

body.auth-gated .auth-landing {
  /* Override the top-pinned `var(--space-lg) auto 0`: auto on all sides lets the
     flex parent center the block vertically AND horizontally when space allows. */
  margin: auto;
}

/* ============================================================
   Responsive
   ============================================================ */

@media (max-width: 600px) {
  .auth-landing {
    margin-top: var(--space-xl);
  }

  /* On the narrowest screens the right-pushed Profile menu can wrap; keep it
     anchored right within the wrapped row. */
  .nav-menu--profile {
    margin-left: auto;
  }
}
