:root {
  --bg: #0f1020;
  --bg-1: #171830;
  --bg-2: #1f2140;
  --bg-panel: rgba(23, 24, 48, 0.72);
  --border: rgba(200, 170, 110, 0.22);
  --border-strong: rgba(200, 170, 110, 0.55);
  --gold: #c8aa6e;
  --gold-soft: #a48546;
  --gold-bright: #f0d898;
  --crystal: #4fc3f7;
  --crystal-soft: #2a8ab9;
  --text: #e9e6dc;
  --text-dim: #a8a59a;
  --text-muted: #80806f;
  --danger: #e26a6a;
  --shadow-lg:
    0 30px 70px -25px rgba(0, 0, 0, 0.8), 0 10px 30px -10px rgba(0, 0, 0, 0.6);
  --shadow-sm: 0 4px 14px -4px rgba(0, 0, 0, 0.6);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

* {
  box-sizing: border-box;
}

/* ============ Motion layer ============ */

/* Every <img> fades in when its load event fires (or immediately on render if
   it was served from browser cache — see app.js image-fade helper). */
img {
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}
img.loaded,
img[src=""],
img:not([src]),
.tt-ghost img {
  opacity: 1;
}

/* Page transitions: the #view container fades + slides on each route render. */
.view {
  animation: view-in 0.32s var(--ease) both;
}
@keyframes view-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* List stagger: parent sets .stagger, children cascade in by index set on --i. */
.stagger > * {
  animation: stagger-in 0.42s var(--ease) both;
  animation-delay: calc(min(var(--i, 0), 20) * 28ms);
}
@keyframes stagger-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Cross-fade helper (targets a child element so the parent keeps its own
   transform — used by the tooltip where the outer container holds position). */
.xfade-leaving {
  animation: xfade-out 0.18s ease-out forwards;
}
@keyframes xfade-out {
  to {
    opacity: 0;
    transform: scale(0.985);
  }
}

/* Tooltip inner wrapper: owns the pop-in scale + fade animation so the outer
   container's positioning transform is never touched. Every time the inner
   content is replaced, a fresh .tt-fade element is created and its animation
   plays from the start. No leaving animation — it causes flicker (see JS). */
.tt-fade {
  opacity: 0;
  transform: scale(0.96);
  animation: tt-fade-in 0.22s var(--ease) forwards;
  transform-origin: center center;
}
@keyframes tt-fade-in {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Gold accent underlines draw in from the left on every mount. The bars are
   sized per-rule (48px panel headers, 72px rank groups), so we animate
   scaleX rather than width to keep one keyframe for all of them.
   (.panel h2::after lives in character.css; .landing__head / .rank-group
   below in this file.) */
.landing__head::after,
.rank-group__header::after,
.panel h2::after {
  transform-origin: left center;
  animation: underline-draw 0.7s var(--ease) 0.15s both;
}
@keyframes underline-draw {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* Scroll-reveal: [data-reveal] sections stay hidden until js/util.js's
   IntersectionObserver tags them .is-revealed on first viewport entry. */
[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
}
/* When a [data-reveal] element is also a .stagger child (e.g. past-event
   month groups), the reveal owns its entrance — the list stagger would
   make it visible before it ever scrolled into view. */
.stagger > [data-reveal]:not(.is-revealed) {
  animation: none;
}
[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  animation: stagger-in 0.5s var(--ease);
}

/* Cross-route View Transitions (app.js feature-detects startViewTransition;
   browsers without it ignore these selectors and keep the .view animation). */
::view-transition-old(root) {
  animation: vt-out 0.16s ease-out both;
}
::view-transition-new(root) {
  animation: vt-in 0.3s var(--ease) both;
}
@keyframes vt-out {
  to {
    opacity: 0;
    transform: translateY(-4px);
  }
}
@keyframes vt-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Ambient aether motes — fixed full-viewport layer behind the content
   (z-index 0; .view sits at 1). Elements are injected by Niara.initMotes()
   with per-mote CSS vars for duration / delay / sway / opacity. */
.motes {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.mote {
  position: absolute;
  bottom: -8px;
  border-radius: 50%;
  background: var(--gold-bright);
  box-shadow: 0 0 6px 1px rgba(200, 170, 110, 0.4);
  opacity: 0;
  animation: mote-rise var(--mote-dur, 26s) linear var(--mote-delay, 0s)
    infinite;
  will-change: transform, opacity;
}
.mote--crystal {
  background: var(--crystal);
  box-shadow: 0 0 6px 1px rgba(79, 195, 247, 0.35);
}
@keyframes mote-rise {
  0% {
    transform: translate3d(0, 0, 0);
    opacity: 0;
  }
  10% {
    opacity: var(--mote-o, 0.4);
  }
  50% {
    transform: translate3d(var(--mote-sway, 20px), -55vh, 0);
  }
  88% {
    opacity: var(--mote-o, 0.4);
  }
  100% {
    transform: translate3d(0, -110vh, 0);
    opacity: 0;
  }
}

/* Respect the user's motion preferences. */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  img {
    opacity: 1 !important;
  }
  .view,
  .stagger > * {
    animation: none !important;
  }
  .motes {
    display: none !important;
  }
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none !important;
  }
}

/* ============ Skip link (Phase 5.1) ============ */
/* First focusable element in the <body>. Hidden off-screen until focused, then
   it slides into the top-left so a keyboard user can jump past the header nav
   straight to #view. Sits above the sticky header (z-index 30). */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  transform: translateY(-120%);
  margin: 0.5rem;
  padding: 0.6rem 1rem;
  background: var(--bg-2);
  color: var(--gold-bright);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform 0.18s var(--ease);
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* ============ Styled in-app 404 (Phase 5.1) ============ */
.not-found {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.5rem;
  padding: 4rem 1.5rem;
  max-width: 32rem;
  margin: 0 auto;
}
.not-found__icon {
  width: 64px;
  height: 64px;
  fill: none;
  stroke: var(--gold);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
  margin-bottom: 0.5rem;
}
.not-found__title {
  font-family: "EB Garamond", serif;
  margin: 0;
}
.not-found__text {
  margin: 0 0 0.75rem;
}
.not-found__home {
  display: inline-block;
  padding: 0.6rem 1.2rem;
  background: var(--bg-2);
  color: var(--gold-bright);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-weight: 600;
  text-decoration: none;
  transition:
    border-color 0.18s var(--ease),
    background 0.18s var(--ease);
}
.not-found__home:hover,
.not-found__home:focus-visible {
  background: var(--bg-1);
  border-color: var(--gold);
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family:
    "Inter",
    system-ui,
    -apple-system,
    Segoe UI,
    Roboto,
    sans-serif;
  font-size: 15px;
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
/* Sticky-footer layout: header + view + footer stack as a 3-row grid. */
body {
  display: grid;
  grid-template-rows: auto 1fr auto;
}

body {
  background-image:
    radial-gradient(
      ellipse at 20% -10%,
      rgba(79, 195, 247, 0.08),
      transparent 55%
    ),
    radial-gradient(
      ellipse at 90% 10%,
      rgba(200, 170, 110, 0.1),
      transparent 60%
    ),
    radial-gradient(
      ellipse at 50% 110%,
      rgba(200, 170, 110, 0.06),
      transparent 50%
    ),
    linear-gradient(180deg, #0b0c1c 0%, #0f1020 30%, #0b0c1c 100%);
  background-attachment: fixed;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(
      45deg,
      rgba(255, 255, 255, 0.012) 0 1px,
      transparent 1px 80px
    ),
    repeating-linear-gradient(
      -45deg,
      rgba(255, 255, 255, 0.012) 0 1px,
      transparent 1px 80px
    );
  mix-blend-mode: overlay;
  z-index: 0;
}

h1,
h2,
h3,
h4 {
  font-family: "EB Garamond", "Cambria", serif;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--gold-bright);
  margin: 0 0 0.6em;
}

h1 {
  font-size: clamp(2.2rem, 4vw, 3.4rem);
  line-height: 1.1;
}
h2 {
  font-size: 1.6rem;
}
h3 {
  font-size: 1.15rem;
  color: var(--gold);
}

a {
  color: var(--crystal);
  text-decoration: none;
}
a:hover {
  color: #8fd9ff;
  text-decoration: underline;
}

.muted {
  color: var(--text-dim);
}
.hidden {
  display: none !important;
}
.dot {
  opacity: 0.35;
  padding: 0 0.4em;
}

/* ============ Header / Nav ============ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 0.85rem clamp(1rem, 3vw, 2.25rem);
  background: linear-gradient(
    180deg,
    rgba(15, 16, 32, 0.94) 0%,
    rgba(15, 16, 32, 0.72) 100%
  );
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-family: "EB Garamond", serif;
  font-size: 1.35rem;
  color: var(--text);
}
.brand:hover {
  text-decoration: none;
  color: var(--gold-bright);
}
.brand__mark {
  width: 22px;
  height: 22px;
  background:
    radial-gradient(
      circle at 50% 50%,
      var(--gold-bright) 0%,
      var(--gold) 45%,
      transparent 70%
    ),
    linear-gradient(135deg, var(--gold), var(--gold-soft));
  clip-path: polygon(50% 0, 100% 38%, 82% 100%, 18% 100%, 0 38%);
  filter: drop-shadow(0 0 6px rgba(200, 170, 110, 0.4));
}
.brand__name {
  font-weight: 600;
  letter-spacing: 0.06em;
}
.brand__tag {
  color: var(--gold);
  font-size: 0.85rem;
  letter-spacing: 0.12em;
  border-left: 1px solid var(--border);
  padding-left: 0.7rem;
}

.site-nav {
  display: flex;
  gap: 0.25rem;
  margin-left: 0.5rem;
  flex: 1;
}
.site-nav a {
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  color: var(--text-dim);
  font-size: 0.95rem;
  transition: all 0.2s var(--ease);
}
.site-nav a:hover {
  color: var(--gold-bright);
  text-decoration: none;
  background: rgba(200, 170, 110, 0.06);
}
.site-nav a.active {
  color: var(--gold-bright);
  background: rgba(200, 170, 110, 0.1);
  box-shadow: inset 0 0 0 1px var(--border-strong);
}

.site-badge {
  color: var(--gold);
  font-size: 0.82rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: linear-gradient(180deg, rgba(200, 170, 110, 0.06), transparent);
}
@media (max-width: 640px) {
  .site-badge {
    display: none;
  }
}

/* ============ Mobile nav drawer (≤720px) ============ */

/* The hamburger only exists at the nav-collapse breakpoint. Above 720px the
   inline .site-nav is shown and the button is removed from the layout. */
.nav-toggle {
  display: none;
  margin-left: auto;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--gold-bright);
  cursor: pointer;
  padding: 0;
  transition:
    border-color 0.2s var(--ease),
    background 0.2s var(--ease);
}
.nav-toggle:hover {
  border-color: var(--gold);
  background: rgba(200, 170, 110, 0.06);
}
.nav-toggle:focus-visible {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(200, 170, 110, 0.2);
}
/* Three-bar icon drawn with the element + its ::before/::after. */
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition:
    transform 0.2s var(--ease),
    opacity 0.2s var(--ease);
}
.nav-toggle__bars {
  position: relative;
}
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
}
.nav-toggle__bars::before {
  top: -6px;
}
.nav-toggle__bars::after {
  top: 6px;
}
/* Morph to an X while the drawer is open. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars {
  background: transparent;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  transform: translateY(6px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  transform: translateY(-6px) rotate(-45deg);
}

@media (max-width: 720px) {
  /* The header uses backdrop-filter, which makes it the containing block for
     position: fixed descendants (a CSS quirk shared by filter/transform). That
     would clip the drawer to the header's own ~70px height, so its panel
     background only covered the top strip and the links overflowed below with
     nothing behind them. Drop the blur on mobile so the fixed drawer is sized
     against the viewport (full height) and paints its background correctly.
     The header's gradient is opaque enough to stand in for the blur here. */
  .site-header {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .nav-toggle {
    display: flex;
  }

  /* Collapsed by default; opens as a vertical drawer pinned below the header. */
  .site-nav {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    flex: none;
    flex-direction: column;
    gap: 0.3rem;
    width: min(78vw, 300px);
    margin: 0;
    padding: 5rem 1.1rem 1.5rem;
    background: linear-gradient(
      180deg,
      rgba(15, 16, 32, 0.98),
      rgba(11, 12, 28, 0.98)
    );
    border-left: 1px solid var(--border-strong);
    box-shadow: -20px 0 50px -20px rgba(0, 0, 0, 0.8);
    transform: translateX(100%);
    opacity: 0;
    visibility: hidden;
    transition:
      transform 0.26s var(--ease),
      opacity 0.26s var(--ease),
      visibility 0s linear 0.26s;
  }
  .site-nav--open {
    transform: translateX(0);
    opacity: 1;
    visibility: visible;
    transition:
      transform 0.26s var(--ease),
      opacity 0.26s var(--ease);
  }
  .site-nav a {
    padding: 0.85rem 1rem;
    font-size: 1.05rem;
    border-radius: 6px;
  }
  /* The drawer lives INSIDE .site-header, which is its own stacking context
     (position: sticky + z-index: 30). A backdrop on <body> at z-index 35 would
     therefore paint over the entire header subtree — including the drawer — and
     swallow its clicks, regardless of the drawer's own z-index. Lift the whole
     header layer above the backdrop while the drawer is open so the drawer (and
     the toggle) stay on top and clickable. */
  body.nav-open .site-header {
    z-index: 45;
  }
  /* Dim backdrop behind the open drawer. */
  body.nav-open::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 40;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
    animation: nav-backdrop-in 0.26s var(--ease) both;
  }
}
@keyframes nav-backdrop-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav {
    transition: none !important;
  }
  .nav-toggle__bars,
  .nav-toggle__bars::before,
  .nav-toggle__bars::after {
    transition: none !important;
  }
  body.nav-open::after {
    animation: none !important;
  }
}

/* ============ Main view ============ */

.view {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1600px;
  justify-self: center;
  padding: clamp(1.5rem, 3vw, 2.5rem) clamp(1rem, 2.5vw, 2rem);
  min-height: calc(100vh - 180px);
}

/* ============ Footer ============ */

.site-footer {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
  padding: 1.25rem clamp(1rem, 3vw, 2.25rem);
  border-top: 1px solid var(--border);
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.4));
  font-size: 0.82rem;
  color: var(--text-muted);
  letter-spacing: 0.08em;
}
.site-footer__login {
  color: var(--text-dim);
  text-decoration: none;
  transition: color 0.15s var(--ease);
}
.site-footer__login:hover {
  color: var(--gold-bright);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.55rem 1.1rem;
  font: inherit;
  font-size: 0.92rem;
  border-radius: 3px;
  border: 1px solid var(--border-strong);
  background: linear-gradient(
    180deg,
    rgba(200, 170, 110, 0.08),
    rgba(200, 170, 110, 0.02)
  );
  color: var(--gold-bright);
  cursor: pointer;
  transition: all 0.2s var(--ease);
  letter-spacing: 0.04em;
}
.btn:hover {
  border-color: var(--gold);
  background: linear-gradient(
    180deg,
    rgba(200, 170, 110, 0.18),
    rgba(200, 170, 110, 0.04)
  );
  box-shadow: 0 0 18px -4px rgba(200, 170, 110, 0.35);
  text-decoration: none;
}
.btn--primary {
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-soft) 100%);
  color: #1a1a2e;
  border-color: var(--gold-bright);
  font-weight: 600;
  position: relative;
  overflow: hidden;
}
/* Sheen sweep: a skewed highlight parked off the left edge that slides across
   on hover. The transition only exists on :hover so the un-hover snaps the
   sheen back instantly instead of replaying in reverse. */
.btn--primary::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -60%;
  width: 50%;
  background: linear-gradient(
    105deg,
    transparent,
    rgba(255, 255, 255, 0.45),
    transparent
  );
  transform: skewX(-20deg);
  pointer-events: none;
}
.btn--primary:hover::after {
  transform: translateX(320%) skewX(-20deg);
  transition: transform 0.55s var(--ease);
}
.btn--primary:hover {
  color: #0a0a14;
  filter: brightness(1.08);
}
.btn--ghost {
  background: transparent;
  color: var(--text-dim);
  border-color: var(--border);
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ============ Hero / Home ============ */

.hero {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  padding: clamp(2rem, 5vw, 3.5rem) 0;
}
@media (max-width: 760px) {
  .hero {
    grid-template-columns: 1fr;
    text-align: center;
    justify-items: center;
  }
}

.hero__crest {
  position: relative;
  margin-bottom: 1.8rem;
}

.crest-frame {
  position: relative;
  width: clamp(150px, 22vw, 220px);
  height: clamp(150px, 22vw, 220px);
  display: grid;
  place-items: center;
}

.crest-orbit {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
}
.crest-orbit--a {
  border: 1px dashed rgba(200, 170, 110, 0.25);
  animation: spin 60s linear infinite;
}
.crest-orbit--b {
  inset: -14px;
  border: 1px solid rgba(79, 195, 247, 0.2);
  animation: spin 90s linear infinite reverse;
}
.crest-orbit::before,
.crest-orbit::after {
  content: "";
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold-bright);
  box-shadow: 0 0 12px var(--gold);
}
.crest-orbit--a::before {
  top: -3px;
  left: calc(50% - 3px);
}
.crest-orbit--a::after {
  bottom: -3px;
  left: calc(50% - 3px);
  background: var(--crystal);
  box-shadow: 0 0 12px var(--crystal);
}

.crest-img {
  width: 78%;
  height: 78%;
  object-fit: contain;
  filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.6))
    drop-shadow(0 0 28px rgba(200, 170, 110, 0.25));
  animation: floaty 6s ease-in-out infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes floaty {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-6px);
  }
}

.hero__content {
  min-width: 0;
}

.hero__title {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  align-items: flex-start;
  margin: 0 0 0.8rem;
}
@media (max-width: 760px) {
  .hero__title {
    align-items: center;
  }
}
.hero__name {
  font-family: "EB Garamond", serif;
  font-size: clamp(3rem, 7vw, 5rem);
  font-weight: 600;
  letter-spacing: 0.08em;
  /* Two layers: a narrow moving highlight on top of the static gold ramp.
     Both clip to the glyphs; hero-shimmer slides the highlight across. */
  background-image:
    linear-gradient(
      110deg,
      transparent 0%,
      transparent 42%,
      rgba(255, 248, 224, 0.55) 50%,
      transparent 58%,
      transparent 100%
    ),
    linear-gradient(
      180deg,
      var(--gold-bright) 0%,
      var(--gold) 50%,
      var(--gold-soft) 100%
    );
  background-size:
    250% 100%,
    100% 100%;
  background-position:
    220% 0,
    0 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 8px rgba(200, 170, 110, 0.3));
  line-height: 1;
  animation: hero-shimmer 8s linear 1.2s infinite;
}
/* Sweep once, rest for the remainder of the cycle. */
@keyframes hero-shimmer {
  0% {
    background-position:
      220% 0,
      0 0;
  }
  18%,
  100% {
    background-position:
      -130% 0,
      0 0;
  }
}

/* Choreographed hero entrance: crest → name → tag → slogan → badges. Reuses
   the stagger-in keyframe at explicit offsets so the cascade reads as one
   deliberate sequence rather than a uniform list stagger. */
.hero__crest {
  animation: stagger-in 0.55s var(--ease) both;
}
.hero__title .hero__name {
  /* combine with the shimmer above — entrance first, shimmer loops after */
  animation:
    stagger-in 0.5s var(--ease) 0.08s both,
    hero-shimmer 8s linear 1.2s infinite;
}
.hero__tag {
  animation: stagger-in 0.5s var(--ease) 0.18s both;
}
.hero__slogan {
  animation: stagger-in 0.5s var(--ease) 0.26s both;
}
.hero__badges {
  animation: stagger-in 0.5s var(--ease) 0.34s both;
}
.hero__content .home-banner {
  animation: stagger-in 0.5s var(--ease) 0.42s both;
}
@media (prefers-reduced-motion: reduce) {
  .hero__name,
  .hero__title .hero__name {
    animation: none !important;
    background-position:
      -130% 0,
      0 0;
  }
  .hero__crest,
  .hero__tag,
  .hero__slogan,
  .hero__badges,
  .hero__cta,
  .hero__recruit-chip,
  .hero__content .home-banner {
    animation: none !important;
  }
}
.hero__tag {
  font-size: 0.95rem;
  letter-spacing: 0.25em;
  color: var(--gold);
  text-transform: uppercase;
}

.hero__slogan {
  font-family: "EB Garamond", serif;
  font-style: italic;
  font-size: 1.2rem;
  line-height: 1.5;
  color: var(--text-dim);
  margin: 0.5rem 0 1.5rem;
}

.hero__badges {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
@media (max-width: 760px) {
  .hero__badges {
    justify-content: center;
  }
}

.hero__facts {
  color: var(--text-dim);
  font-size: 0.95rem;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: center;
}
.hero__facts .dot {
  color: var(--gold);
  opacity: 0.5;
}
@media (max-width: 760px) {
  .hero__facts {
    justify-content: center;
  }
}

/* ---- State-aware hero CTA + recruitment chip (community.js#hydrateAbout) ---- */
.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1rem;
  animation: stagger-in 0.5s var(--ease) 0.42s both;
}
.hero__cta .btn {
  padding: 0.7rem 1.4rem;
  font-size: 0.98rem;
  border-radius: 6px;
}
@media (max-width: 760px) {
  .hero__cta {
    justify-content: center;
  }
}

.hero__recruit-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
  padding: 0.34rem 0.8rem;
  border-radius: 999px;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  border: 1px solid var(--border);
  color: var(--text-dim);
  background: rgba(255, 255, 255, 0.04);
  animation: stagger-in 0.5s var(--ease) 0.18s both;
}
.hero__recruit-chip::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}
.hero__recruit-chip--open {
  color: #7fe0a8;
  border-color: rgba(95, 200, 140, 0.4);
  background: rgba(95, 200, 140, 0.1);
}
.hero__recruit-chip--open::before {
  background: #5fc88c;
  box-shadow: 0 0 8px #5fc88c;
}
.hero__recruit-chip--closed {
  color: var(--text-muted);
  border-color: var(--border);
  background: rgba(255, 255, 255, 0.03);
}

/* Closed-doors state: drain the gold from crest + wordmark so the page never
   lies about being shut, without rebuilding the hero. */
.hero--closed .crest-img,
.hero--closed .crest-orbit {
  filter: grayscale(1) brightness(0.85);
  opacity: 0.72;
}
.hero--closed .hero__name {
  filter: grayscale(0.9);
}
.badge {
  display: inline-block;
  padding: 0.25rem 0.8rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.badge--gold {
  color: var(--gold-bright);
  border-color: var(--gold);
  background: rgba(200, 170, 110, 0.08);
}

/* ============ Home crew strip (member-avatar teaser) ============ */

.home-crew {
  margin-top: 2rem;
}
.home-crew__avatars {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 0.4rem;
}
.crew-avatar {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  padding: 2px;
  background: linear-gradient(
    135deg,
    var(--gold),
    var(--gold-soft),
    var(--crystal-soft)
  );
  box-shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.6);
  display: block;
  flex: none;
  transition:
    transform 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
}
.crew-avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  background: var(--bg-2);
}
.crew-avatar:hover {
  transform: translateY(-3px);
  box-shadow:
    0 8px 18px -6px rgba(0, 0, 0, 0.7),
    0 0 0 1px var(--border-strong);
  text-decoration: none;
}
.crew-avatar--more {
  display: grid;
  place-items: center;
  background: rgba(200, 170, 110, 0.08);
  border: 1px solid var(--border);
  color: var(--gold-bright);
  font-family: "EB Garamond", serif;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

/* ============ Landing grid (estate + recruitment + upcoming) ============ */

.landing-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin-top: 2rem;
}
@media (min-width: 900px) {
  .landing-grid {
    grid-template-columns: minmax(260px, 1fr) 1.2fr 1.2fr;
  }
}
@media (min-width: 700px) and (max-width: 899px) {
  .landing-grid {
    grid-template-columns: 1fr 1fr;
  }
  .estate-plaque {
    grid-column: span 2;
  }
}

/* ============ Estate plaque ============ */

.estate-plaque {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 1.75rem 1.25rem;
  background:
    radial-gradient(ellipse at top, rgba(200, 170, 110, 0.06), transparent 70%),
    linear-gradient(180deg, rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.15));
  border: 1px solid var(--border-strong);
  position: relative;
}
.estate-plaque::before,
.estate-plaque::after {
  content: "";
  position: absolute;
  left: 8%;
  right: 8%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0.5;
}
.estate-plaque::before {
  top: 8px;
}
.estate-plaque::after {
  bottom: 8px;
}
.plaque__top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--gold);
  margin-bottom: 0.8rem;
}
.plaque__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--gold);
  color: var(--gold-bright);
  font-size: 1rem;
  border-radius: 50%;
}
.plaque__label {
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
}
.plaque__name {
  font-family: "EB Garamond", serif;
  font-size: 1.7rem;
  color: var(--gold-bright);
  margin: 0 0 0.8rem;
  line-height: 1.15;
  letter-spacing: 0.02em;
}
.plaque__address {
  color: var(--text);
  font-family: "EB Garamond", serif;
  font-size: 1.02rem;
  line-height: 1.55;
}
.plaque__address > div:not(:last-child) {
  margin-bottom: 0.1rem;
}
.plaque__size {
  margin-top: 0.8rem;
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.landing__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
  position: relative;
}
.landing__head::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 48px;
  height: 2px;
  background: linear-gradient(90deg, var(--gold), transparent);
}
.landing__head h2 {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 1.15rem;
}
.landing__head h2::after {
  display: none;
}
.landing__more {
  font-size: 0.82rem;
  color: var(--text-dim);
}
.landing__more:hover {
  color: var(--gold-bright);
  text-decoration: none;
}

.badge--closed {
  color: var(--text-muted);
  border-color: var(--border);
  background: rgba(255, 255, 255, 0.03);
}

/* ============ Page Header / Toolbar ============ */

.page-header {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  justify-content: space-between;
  margin-bottom: 1.5rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
}
.page-header h2 {
  font-size: 2rem;
  letter-spacing: 0.04em;
  margin: 0;
}

.toolbar {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}
.toolbar input,
.toolbar select {
  background: var(--bg-1);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0.5rem 0.8rem;
  font: inherit;
  font-size: 0.9rem;
}
.toolbar input {
  flex: 1 1 260px;
  min-width: 0;
}
.toolbar input:focus,
.toolbar select:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(200, 170, 110, 0.15);
}
/* Touch: ≥44px tall search/filter controls. */
@media (pointer: coarse) {
  .toolbar input,
  .toolbar select {
    min-height: 44px;
    font-size: 1rem; /* also stops iOS zoom-on-focus for <16px inputs */
  }
}

/* Role quick-filter pills (roster toolbar). */
.role-filter {
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}
.role-pill {
  background: var(--bg-1);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0.5rem 0.85rem;
  font: inherit;
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition:
    border-color 0.15s,
    color 0.15s,
    background 0.15s;
}
.role-pill:hover {
  color: var(--text);
  border-color: var(--border-strong);
}
.role-pill.is-active {
  color: var(--bg);
  background: var(--gold);
  border-color: var(--gold);
  font-weight: 600;
}
.role-pill:focus-visible {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(200, 170, 110, 0.15);
}
@media (pointer: coarse) {
  .role-pill {
    min-height: 44px;
    font-size: 1rem;
  }
}

/* Per-card sort-metric line shown under name/rank on the flat (non-rank) sorts. */
.card__metric {
  margin: 0;
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold);
}

/* ============ Roster Grid ============ */

.roster-groups {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.rank-group__header {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 0 0 1rem;
  padding-bottom: 0.5rem;
  position: relative;
  border-bottom: 1px solid var(--border);
  color: var(--gold);
}
.rank-group__header::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 72px;
  height: 2px;
  background: linear-gradient(90deg, var(--gold), transparent);
}
.rank-group__header::before {
  content: "";
  width: 8px;
  height: 8px;
  background: var(--gold);
  transform: rotate(45deg);
  flex-shrink: 0;
  box-shadow: 0 0 6px rgba(200, 170, 110, 0.5);
}
.rank-group__name {
  font-family: "EB Garamond", serif;
  font-size: 1.25rem;
  letter-spacing: 0.03em;
  color: var(--gold-bright);
  flex: 1;
}
.rank-group__count {
  font-size: 0.68rem;
  color: var(--text-muted);
  background: rgba(200, 170, 110, 0.08);
  border: 1px solid var(--border);
  padding: 0.1rem 0.6rem;
  border-radius: 999px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.roster-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
  content-visibility: auto;
  contain-intrinsic-size: 320px;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.85rem 0.75rem;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  transition:
    transform 0.2s var(--ease),
    border-color 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
  cursor: pointer;
}
.card--master {
  border-color: var(--gold);
  background:
    radial-gradient(ellipse at top, rgba(200, 170, 110, 0.12), transparent 60%),
    var(--bg-panel);
  box-shadow: 0 0 0 1px rgba(200, 170, 110, 0.15) inset;
}
.card--master::after {
  content: "";
  position: absolute;
  top: 6px;
  right: 6px;
  width: 18px;
  height: 18px;
  background: radial-gradient(
    circle at 50% 50%,
    var(--gold-bright) 0%,
    var(--gold) 45%,
    transparent 70%
  );
  clip-path: polygon(50% 0, 100% 38%, 82% 100%, 18% 100%, 0 38%);
  opacity: 0.9;
}
.card--master .card__rank {
  color: var(--gold-bright);
  font-weight: 600;
}
.card::before {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: 3px;
  background: radial-gradient(
    ellipse at top,
    rgba(200, 170, 110, 0.09),
    transparent 60%
  );
  opacity: 0;
  transition: opacity 0.2s var(--ease);
  pointer-events: none;
}
.card > * {
  position: relative;
}
.card:hover,
.card:focus-visible {
  transform: translateY(-2px);
  border-color: var(--gold);
  box-shadow:
    0 6px 18px -8px rgba(0, 0, 0, 0.7),
    0 0 0 1px rgba(200, 170, 110, 0.25);
  outline: none;
}
.card:hover::before,
.card:focus-visible::before {
  opacity: 1;
}

.card__avatar {
  width: 74px;
  height: 74px;
  align-self: center;
  border-radius: 50%;
  padding: 2px;
  background: linear-gradient(
    135deg,
    var(--gold),
    var(--gold-soft),
    var(--crystal-soft)
  );
  box-shadow: 0 4px 14px -3px rgba(0, 0, 0, 0.6);
}
.card--master .card__avatar {
  padding: 3px;
  background: conic-gradient(
    from 180deg at 50% 50%,
    var(--gold-bright),
    var(--gold),
    var(--gold-bright),
    var(--gold),
    var(--gold-bright)
  );
  box-shadow: 0 0 18px -4px rgba(200, 170, 110, 0.7);
}
.card__avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  background: var(--bg-2);
}

.card__body {
  text-align: center;
}
.card__name {
  font-family: "EB Garamond", serif;
  font-size: 1.15rem;
  margin: 0 0 0.2rem;
  color: var(--text);
}
.card__rank {
  color: var(--gold);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  margin: 0 0 0.4rem;
  text-transform: uppercase;
}
.card__job {
  font-size: 0.82rem;
  margin: 0;
}

/* At-a-glance card summary: role coverage + jobs-at-cap + top item level
   (roster.js#fillRoleSummary). Role colours mirror the character page's
   job-group headers so a tank reads blue everywhere. */
.card__roles {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.35rem 0.55rem;
  margin-top: 0.5rem;
  font-size: 0.72rem;
}
.card__role-dots {
  display: inline-flex;
  gap: 0.22rem;
}
.role-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
}
.role-dot--tank {
  background: #86a4e5;
}
.role-dot--healer {
  background: #88c79a;
}
.role-dot--dps {
  background: #e5908f;
}
.card__cap {
  color: var(--text-dim);
  letter-spacing: 0.02em;
}
.card__ilvl {
  color: var(--gold-bright);
  background: rgba(200, 170, 110, 0.1);
  border: 1px solid rgba(200, 170, 110, 0.28);
  border-radius: 5px;
  padding: 0.12rem 0.42rem;
  font-size: 0.68rem;
}

/* ============ Highlights strip ============ */

.highlights {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}
.highlight-card {
  position: relative;
  padding: 1.5rem 1.25rem 1.25rem;
  background:
    radial-gradient(ellipse at top, rgba(200, 170, 110, 0.06), transparent 70%),
    var(--bg-panel);
  border: 1px solid var(--border);
  border-top: 1px solid var(--border-strong);
  border-radius: 4px;
  overflow: hidden;
  text-align: center;
}
.highlight-card::before {
  content: "";
  position: absolute;
  left: 15%;
  right: 15%;
  top: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0.7;
}
.highlight-card__mark {
  width: 46px;
  height: 46px;
  margin: 0 auto 0.75rem;
  display: grid;
  place-items: center;
  font-family: "EB Garamond", serif;
  font-size: 1.4rem;
  color: var(--gold-bright);
  background: rgba(200, 170, 110, 0.06);
  border: 1px solid var(--gold);
  border-radius: 50%;
  box-shadow: 0 0 14px -4px rgba(200, 170, 110, 0.4);
}
.highlight-card__mark--maelstrom {
  color: #e07e6b;
  border-color: #c35246;
  background: rgba(195, 82, 70, 0.08);
  box-shadow: 0 0 14px -4px rgba(195, 82, 70, 0.5);
}
.highlight-card__mark--adders {
  color: #e5d07b;
  border-color: #b8a355;
  background: rgba(184, 163, 85, 0.08);
}
.highlight-card__mark--flames {
  color: #e0a17c;
  border-color: #b97a50;
  background: rgba(185, 122, 80, 0.08);
}
.highlight-card__label {
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.4rem;
}
.highlight-card__value {
  font-family: "EB Garamond", serif;
  font-size: 1.6rem;
  color: var(--text);
  line-height: 1.2;
  margin-bottom: 0.3rem;
}
.highlight-card__sub {
  color: var(--text-dim);
  font-size: 0.9rem;
}
.highlight-card--link {
  display: block;
  text-decoration: none;
  color: inherit;
  transition:
    border-color 0.2s var(--ease),
    transform 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
}
.highlight-card--link:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px);
  box-shadow: 0 10px 20px -10px rgba(0, 0, 0, 0.6);
  text-decoration: none;
}

/* ============ Recruitment / Home banner / Upcoming ============ */

.recruit-status {
  margin: 0.5rem 0 0.75rem;
}
.recruit-body {
  white-space: pre-line;
}

.home-banner {
  margin-top: 2rem;
  max-width: 60ch;
  padding: 1rem 1.25rem;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--crystal);
  border-radius: 3px;
  color: var(--text-dim);
  white-space: pre-line;
  font-size: 0.95rem;
}
.home-upcoming {
  text-align: left;
}
.home-upcoming__row {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.65rem 0.5rem;
  border-bottom: 1px solid var(--border);
  color: var(--text-dim);
  text-decoration: none;
  transition: background 0.15s var(--ease);
}
.home-upcoming__row:last-child {
  border-bottom: 0;
}
.home-upcoming__row:hover {
  background: rgba(200, 170, 110, 0.05);
  text-decoration: none;
  color: var(--text);
}
.home-upcoming__when {
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold);
}
.home-upcoming__label {
  font-family: "EB Garamond", serif;
  font-size: 1rem;
  color: var(--text);
  line-height: 1.35;
  overflow-wrap: break-word;
}

/* --- Mobile tweaks --- */
@media (max-width: 760px) {
  .site-nav a {
    padding: 0.4rem 0.6rem;
    font-size: 0.88rem;
  }
  .brand__tag {
    display: none;
  }
  .roster-grid {
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  }
  .card__avatar {
    width: 72px;
    height: 72px;
  }
  #tooltip-container {
    width: calc(100vw - 32px);
  }
}

/* ============ Skeleton loaders ============ */

@keyframes niara-shimmer {
  from {
    background-position: 200% 0;
  }
  to {
    background-position: -200% 0;
  }
}
.skeleton {
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.04) 0%,
    rgba(255, 255, 255, 0.09) 40%,
    rgba(200, 170, 110, 0.12) 50%,
    rgba(255, 255, 255, 0.09) 60%,
    rgba(255, 255, 255, 0.04) 100%
  );
  background-size: 200% 100%;
  animation: niara-shimmer 1.6s linear infinite;
  border-radius: 3px;
  display: inline-block;
}
.skeleton--text {
  height: 0.85em;
  vertical-align: middle;
}
.skeleton--box {
  display: block;
  width: 100%;
  border-radius: 3px;
}
.skeleton--bar {
  display: block;
  width: 100%;
  height: 4px;
  border-radius: 2px;
}
.skeleton--fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
}

.skeleton-gear {
  pointer-events: none;
}
.skeleton-gear__lines {
  flex: 1;
}

/* --- Toast --- */
.toast {
  position: fixed;
  bottom: 80px;
  left: 50%;
  transform: translateX(-50%) translateY(10px);
  background: var(--bg-2);
  border: 1px solid var(--border-strong);
  color: var(--text);
  padding: 0.7rem 1.2rem;
  border-radius: 3px;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transition:
    opacity 0.2s,
    transform 0.2s;
  pointer-events: none;
  z-index: 200;
  font-size: 0.9rem;
}
.toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.toast--error {
  border-color: var(--danger);
  color: var(--danger);
}
