/* ==========================================================================
   Laguna Games — site.css. The ONLY hand-written stylesheet (01-conventions).
   Sections: fonts / tokens / Bootstrap variable overrides / components / errors.
   No SASS. Override Bootstrap via its CSS variables only.
   ========================================================================== */

/* --- Rubik (vendored, cyrillic+latin subsets) --- */
@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../vendor/fonts/rubik/rubik-400.a557ab58cf8b.woff2") format("woff2");
}
@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../vendor/fonts/rubik/rubik-500.6751d6fe8ab5.woff2") format("woff2");
}
@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../vendor/fonts/rubik/rubik-700.bcec09303ec8.woff2") format("woff2");
}

/* --- Design tokens --- */
:root {
  --lg-accent: #2bd9c7;
  --lg-accent-rgb: 43, 217, 199;
  --lg-accent-hover: #21b3a5;
  --lg-accent-hover-rgb: 33, 179, 165;
  --lg-bg: #0f1519;
  --lg-surface: #161d23;
  --lg-danger: #ea868f; /* form error text/border on the dark theme */
}

/* --- Bootstrap dark-theme overrides (site.css loads AFTER bootstrap.min.css) --- */
[data-bs-theme="dark"] {
  --bs-body-bg: var(--lg-bg);
  --bs-body-font-family: "Rubik", system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --bs-primary: var(--lg-accent);
  --bs-primary-rgb: var(--lg-accent-rgb);
  --bs-link-color: var(--lg-accent);
  --bs-link-color-rgb: var(--lg-accent-rgb);
  --bs-link-hover-color: var(--lg-accent-hover);
  --bs-link-hover-color-rgb: var(--lg-accent-hover-rgb);
  --bs-tertiary-bg: var(--lg-surface);
  --bs-focus-ring-color: rgba(var(--lg-accent-rgb), 0.25);
}

/* Buttons: .btn-primary does NOT follow --bs-primary at runtime; override its own vars.
   Teal is light — use dark text for contrast, never white. */
.btn-primary {
  --bs-btn-bg: var(--lg-accent);
  --bs-btn-border-color: var(--lg-accent);
  --bs-btn-color: var(--lg-bg);
  --bs-btn-hover-bg: var(--lg-accent-hover);
  --bs-btn-hover-border-color: var(--lg-accent-hover);
  --bs-btn-hover-color: var(--lg-bg);
  --bs-btn-active-bg: var(--lg-accent-hover);
  --bs-btn-active-border-color: var(--lg-accent-hover);
  --bs-btn-active-color: var(--lg-bg);
  --bs-btn-disabled-bg: var(--lg-accent);
  --bs-btn-disabled-border-color: var(--lg-accent);
  --bs-btn-disabled-color: var(--lg-bg);
  --bs-btn-focus-shadow-rgb: var(--lg-accent-rgb);
}
.btn-outline-primary {
  --bs-btn-color: var(--lg-accent);
  --bs-btn-border-color: var(--lg-accent);
  --bs-btn-hover-bg: var(--lg-accent);
  --bs-btn-hover-border-color: var(--lg-accent);
  --bs-btn-hover-color: var(--lg-bg);
  --bs-btn-active-bg: var(--lg-accent);
  --bs-btn-active-border-color: var(--lg-accent);
  --bs-btn-active-color: var(--lg-bg);
  --bs-btn-focus-shadow-rgb: var(--lg-accent-rgb);
}

/* Form focus (Bootstrap compiles these colors; vars alone don't reach them) */
.form-control:focus,
.form-select:focus {
  border-color: var(--lg-accent);
  box-shadow: 0 0 0 0.25rem rgba(var(--lg-accent-rgb), 0.25);
}

/* Pagination (used by news list from M3) */
.pagination {
  --bs-pagination-color: var(--lg-accent);
  --bs-pagination-hover-color: var(--lg-accent-hover);
  --bs-pagination-active-bg: var(--lg-accent);
  --bs-pagination-active-border-color: var(--lg-accent);
  --bs-pagination-active-color: var(--lg-bg);
}

/* Surfaces */
.card {
  --bs-card-bg: var(--lg-surface);
}
.dropdown-menu {
  --bs-dropdown-bg: var(--lg-surface);
}
.navbar .nav-link.active {
  color: var(--lg-accent);
}

/* Home hero: subtle dark gradient tinted with the accent */
.hero {
  background: linear-gradient(180deg, rgba(var(--lg-accent-rgb), 0.08) 0%, var(--lg-bg) 100%);
  border: 1px solid var(--lg-surface);
  border-radius: 0.5rem;
  padding: 3rem 1.5rem;
}

/* Auth / profile forms render via {{ form.as_div }} (no widget-tweaks dep);
   style the bare controls to Bootstrap's .form-control look (12-accounts.md). */
.form-styled input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
.form-styled textarea,
.form-styled select {
  display: block;
  width: 100%;
  padding: 0.5rem 0.75rem;
  color: var(--bs-body-color);
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.375rem;
}
.form-styled input:focus,
.form-styled textarea:focus,
.form-styled select:focus {
  border-color: var(--lg-accent);
  box-shadow: 0 0 0 0.25rem rgba(var(--lg-accent-rgb), 0.25);
  outline: 0;
}
.form-styled > div {
  margin-bottom: 1rem;
}
.form-styled label {
  margin-bottom: 0.25rem;
  font-weight: 500;
}
.form-styled input[type="file"] {
  color: var(--bs-body-color);
}
.form-styled .helptext {
  display: block;
  /* Compact: the password-validator help is four lines long (set-password page). */
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--bs-secondary-color);
  opacity: 0.85;
  margin-top: 0.25rem;
}
.form-styled ul {
  list-style: none;
  padding-left: 0;
  margin: 0;
}
.form-styled .errorlist {
  color: #ea868f;
  font-size: 0.9rem;
  margin-top: 0.25rem;
}

/* Avatar (12-accounts.md): stored file is exactly 256x256; the empty-state
   placeholder reuses the vendored bi-person-circle glyph at the same box. */
.avatar {
  width: 256px;
  height: 256px;
  border-radius: 0.5rem;
  object-fit: cover;
}
.avatar-placeholder {
  width: 256px;
  height: 256px;
  font-size: 256px;
  line-height: 1;
  color: var(--bs-secondary-color);
}

/* Error pages (500.html is standalone and relies ONLY on these rules) */
.error-page {
  min-height: 100vh;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background-color: var(--lg-bg);
  color: #dee2e6;
  font-family: "Rubik", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}
.error-page h1 {
  font-size: 4rem;
  color: var(--lg-accent);
}
.error-page a {
  color: var(--lg-accent);
}

/* Server-status widget (15-core-pages.md §5.7) */
.status-dot {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  vertical-align: baseline;
}
.status-dot--online {
  background-color: var(--bs-success);
  animation: lg-pulse 2s infinite;
}
.status-dot--offline { background-color: var(--bs-secondary); }
.connect-address { font-size: 1.25rem; user-select: all; }

@keyframes lg-pulse {
  0% { box-shadow: 0 0 0 0 rgba(var(--bs-success-rgb), 0.5); }
  70% { box-shadow: 0 0 0 0.45rem rgba(var(--bs-success-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--bs-success-rgb), 0); }
}

/* Live-status block markup (_server_status.html) — surface-agnostic so it looks
   right both inside the opener widget and the home dashboard card. */
.ss__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.ss__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.ss__badge--online {
  color: var(--bs-success);
  background-color: rgba(var(--bs-success-rgb), 0.12);
}
.ss__badge--offline {
  color: var(--bs-secondary-color);
  background-color: rgba(var(--bs-secondary-rgb), 0.15);
}
.ss__count {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 600;
}
.ss__count i,
.ss__map i { color: var(--lg-accent); }
.ss__name {
  font-weight: 600;
  font-size: 1.1rem;
  margin: 0 0 0.35rem;
}
.ss__map {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--bs-secondary-color);
  margin: 0;
}
.ss__map--muted { color: var(--bs-secondary-color); }
.ss__bar {
  margin-top: 0.9rem;
  height: 0.4rem;
  border-radius: 999px;
  background-color: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
.ss__bar > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--lg-accent), var(--lg-accent-hover));
  transition: width 0.4s ease;
}

/* ==========================================================================
   Chat shoutbox (14-chat.md §5.10; UI v2 in DEVIATIONS.md). Discord-style rows:
   colored avatar disc + colored name. The window is a .chat-fill wrapper with an
   absolutely-positioned .chat-scroll layer inside: the message history never
   contributes to page/grid height — the surrounding layout sets the height and
   the history scrolls within it (both /chat/ and the dashboard rail).
   ========================================================================== */
.chat-fill {
  position: relative;
  flex: 1 1 auto;
  min-height: 14rem;
}
.chat-scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  padding: 1rem 1.05rem;
}
.chat-scroll,
.dash-cbox {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
/* Short history: anchor messages to the bottom (next to the input), like any
   chat. Resolves to 0 once the box overflows. */
.chat-scroll > :first-child {
  margin-top: auto;
}
/* Search results (/chat/search/): plain chat rows in a card */
.chat-sres {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
/* /chat/ page: base.html gets .lg-content--fill so the chat card can stretch
   to the bottom of the viewport-high content column. */
.lg-content--fill {
  display: flex;
  flex-direction: column;
}
.chat-full {
  flex: 1 1 auto;
  min-height: 24rem;
}
/* Day-change separator: «сегодня» / «вчера» / «17 июля» pill between rows */
.chat-day {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin: 0.35rem 0 0.05rem;
}
.chat-day::before,
.chat-day::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--bs-border-color-translucent);
}
.chat-day__label {
  flex: 0 0 auto;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--lg-accent);
  background: rgba(var(--lg-accent-rgb), 0.12);
  border-radius: 999px;
  padding: 0.18rem 0.65rem;
}
/* Icon-only send button (paper airplane) next to the input */
.chat-sendbtn {
  display: inline-flex;
  align-items: center;
  padding-inline: 0.9rem;
}
/* Paperclip attach button: a <label> wrapping a hidden file input, so it needs
   no JS to open the picker. The count pill lights up via site.js. */
.chat-attach {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-bottom: 0;
}
.chat-attach input[type="file"] {
  display: none;
}
.chat-attach__count {
  min-width: 1.1rem;
  height: 1.1rem;
  padding: 0 0.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  background: var(--lg-accent);
  color: var(--lg-bg);
}
/* Image gallery in a chat row. Fixed thumbnail height (not max-height): the
   rows keep their size before the images finish loading, so the scroll-pinning
   maths in site.js stay correct across polls. Click opens the lightbox. */
.chat-row__imgs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.3rem;
}
.chat-row__imgs .fm-img img {
  height: 8rem;
  width: auto;
  max-width: 100%;
}
.chat-row {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
}
.chat-row__ava {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.82rem;
  color: #0f1519; /* palette colors are light — dark text for contrast */
  background: var(--cu, var(--lg-accent));
}
.chat-row__ava--img {
  object-fit: cover;
  background: none;
}
.chat-row__body {
  min-width: 0;
  flex: 1;
}
.chat-row__top {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.chat-row__name {
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--cu, var(--lg-accent));
  text-decoration: none;
}
.chat-row__name:hover {
  text-decoration: underline;
}
.chat-row__time {
  font-size: 0.68rem;
  color: var(--bs-secondary-color);
}
.chat-row__text {
  font-size: 0.92rem;
  color: var(--bs-body-color);
  word-break: break-word;
}
.chat-msg-hidden {
  opacity: 0.5;
}

/* Per-user color palette (paired with chat_extras.name_color_index). Light hues
   that read well as names on the dark surface and take dark avatar text. */
.lg-cu--0 { --cu: #2bd9c7; }
.lg-cu--1 { --cu: #6ea8ff; }
.lg-cu--2 { --cu: #e6c04d; }
.lg-cu--3 { --cu: #e879a6; }
.lg-cu--4 { --cu: #a98bff; }
.lg-cu--5 { --cu: #6cd67f; }

/* Legal pages: Privacy Policy + Personal-data Consent (core/privacy_policy,
   core/consent). Reader-friendly long-form layout with a sticky TOC. */
.legal-header {
  background: linear-gradient(180deg, rgba(var(--lg-accent-rgb), 0.08) 0%, var(--lg-bg) 100%);
  border: 1px solid var(--lg-surface);
  border-radius: 0.5rem;
  padding: 2.5rem 1.75rem;
  margin-bottom: 2rem;
}
.legal-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--lg-accent);
}
.legal-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin-top: 1rem;
  font-size: 0.9rem;
  color: var(--bs-secondary-color);
}
.legal-meta a {
  text-decoration: none;
}

/* Sticky table of contents (lg and up). Below lg it renders inline. */
.legal-toc {
  position: sticky;
  top: 5rem;
  font-size: 0.9rem;
}
.legal-toc .toc-title {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--bs-secondary-color);
  margin-bottom: 0.75rem;
}
.legal-toc ol {
  list-style: none;
  counter-reset: toc;
  padding-left: 0;
  margin: 0;
  border-left: 1px solid var(--bs-border-color-translucent);
}
.legal-toc li {
  counter-increment: toc;
}
.legal-toc a {
  display: block;
  padding: 0.3rem 0 0.3rem 1rem;
  margin-left: -1px;
  border-left: 1px solid transparent;
  color: var(--bs-secondary-color);
  text-decoration: none;
  line-height: 1.35;
}
.legal-toc a::before {
  content: counter(toc) ". ";
  color: var(--bs-secondary-color);
  opacity: 0.6;
}
.legal-toc a:hover {
  color: var(--lg-accent);
  border-left-color: var(--lg-accent);
}

/* Article body */
.legal-body {
  max-width: 46rem;
}
.legal-section {
  scroll-margin-top: 5rem;
  padding-top: 0.5rem;
}
.legal-section + .legal-section {
  margin-top: 2.5rem;
  border-top: 1px solid var(--bs-border-color-translucent);
  padding-top: 2rem;
}
.legal-section > h2 {
  font-size: 1.4rem;
  margin-bottom: 1rem;
}
.legal-section h3 {
  font-size: 1.1rem;
  color: var(--lg-accent);
  margin-top: 1.5rem;
  margin-bottom: 0.75rem;
}
.legal-section p,
.legal-section li {
  color: var(--bs-body-color);
}
.legal-lead {
  font-size: 1.05rem;
  color: var(--bs-secondary-color);
}
.legal-callout {
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-left: 3px solid var(--lg-accent);
  border-radius: 0.375rem;
  padding: 0.85rem 1.1rem;
  margin: 1.25rem 0;
}

/* ==========================================================================
   Landing / opener page (core/opener.html) — bespoke, standalone, no navbar.
   Two-column hero: live server + community on the left, registration on the
   right. Full-viewport dark stage with an accent glow.
   ========================================================================== */
.lg-opener {
  min-height: 100vh;
  margin: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow-x: hidden;
  background-color: var(--lg-bg);
}

/* Looping gameplay video behind everything; fixed so it covers the viewport
   even when the page scrolls. Kept dim by the .lg-glow scrim above it. */
.lg-video {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.lg-video--hidden {
  visibility: hidden; /* stays in the layout/compositor, just not painted */
}

/* The "noclip wall": a black panel that sweeps left→right over the video
   while site.js swaps the two buffers. Wider than the viewport so its soft
   gradient edges (the wall's "thickness") never show while it fully covers
   the screen. Linear timing on both phases = constant camera speed. */
.lg-wall {
  position: fixed;
  top: 0;
  bottom: 0;
  left: -10vw;
  width: 120vw;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent, #06090b 4rem, #06090b calc(100% - 4rem), transparent);
  transform: translateX(-130vw); /* parked off the left edge */
}
.lg-wall.is-covering {
  transform: translateX(0);
  transition: transform 0.35s linear;
}
.lg-wall.is-revealing {
  transform: translateX(130vw);
  transition: transform 0.35s linear;
}

@media (prefers-reduced-motion: reduce) {
  .lg-video,
  .lg-wall {
    display: none; /* back to the pure-CSS dark stage; site.js also bails out */
  }
}

/* Scrim over the video (keeps text readable) + ambient accent glow */
.lg-glow {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(60rem 40rem at 12% -10%, rgba(var(--lg-accent-rgb), 0.16), transparent 60%),
    radial-gradient(48rem 34rem at 100% 110%, rgba(var(--lg-accent-rgb), 0.10), transparent 55%),
    rgba(15, 21, 25, 0.78); /* --lg-bg at ~78% — scrim over the video */
}

.lg-hero {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 1.25rem;
}
.lg-hero__inner {
  width: 100%;
  max-width: 1080px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
}
@media (min-width: 992px) {
  .lg-hero__inner {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: 3.5rem;
    align-items: center;
  }
}

/* --- Left column: server & community --- */
.lg-title-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}
.lg-logo {
  /* Same artwork as the favicon; scale with the title size. */
  width: clamp(3.25rem, 7vw, 4.5rem);
  height: auto;
  flex-shrink: 0;
}
.lg-title {
  /* Fills the row next to the logo; the SVG inside stretches the text to
     end exactly at the widget's right edge. */
  flex: 1;
  min-width: 0;
  margin-bottom: 0; /* spacing owned by .lg-title-row */
}
.lg-title__fit {
  display: block;
  width: 100%;
  height: auto;
}
.lg-lead {
  color: var(--bs-secondary-color);
  margin-bottom: 1.75rem;
}
.lg-lead__fit {
  /* Scales with the column, so the text always ends at the widget's edge. */
  display: block;
  width: 100%;
  height: auto;
}

/* Server widget: a two-zone card — live status on top (htmx-refreshed) and the
   static connect address below. The status markup itself (.ss) is styled in the
   shared server-status section so it also dresses the home dashboard card. */
.lg-widget {
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.85rem;
  overflow: hidden;
  margin-bottom: 1.75rem;
  box-shadow: 0 1rem 2.25rem rgba(0, 0, 0, 0.25);
}
.lg-widget__live {
  padding: 1.35rem 1.4rem;
}
.lg-widget__connect {
  padding: 1.05rem 1.4rem 1.2rem;
  border-top: 1px solid var(--bs-border-color-translucent);
  background-color: rgba(0, 0, 0, 0.18);
}
.lg-widget__label {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.72rem;
  color: var(--bs-secondary-color);
  margin-bottom: 0.5rem;
}
.lg-widget__addr-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.lg-widget__addr {
  flex: 1 1 8rem;
  background-color: var(--lg-bg);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.4rem;
  padding: 0.5rem 0.75rem;
  font-size: 1.2rem;
  letter-spacing: 0.02em;
  color: var(--lg-accent);
  user-select: all;
}
.lg-widget__copy {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Social row: VK + TikTok side by side, equal widths */
.lg-social { display: flex; gap: 0.6rem; }
.lg-social .lg-vk { flex: 1 1 0; min-width: 0; }
.lg-vk {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1.4rem;
  border-radius: 0.85rem;
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  color: var(--bs-body-color);
  text-decoration: none;
  font-weight: 500;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.lg-vk:hover {
  border-color: #0077ff;
  transform: translateY(-1px);
  color: var(--bs-body-color);
}
.lg-vk__logo {
  flex-shrink: 0;
}
.lg-vk__arrow {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
}
.lg-vk__tiktok { flex-shrink: 0; font-size: 1.45rem; line-height: 1; }
.lg-vk--tiktok:hover { border-color: #ff0050; }

/* --- Right column: registration panel --- */
.lg-signup {
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.85rem;
  padding: 2rem;
  box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.35);
}
@media (min-width: 992px) {
  .lg-signup { padding: 2.5rem; }
}
.lg-signup__title {
  font-size: 1.6rem;
  font-weight: 700;
  margin-bottom: 1.5rem;
}

/* Single-page auth: fade the panel content out/in as htmx swaps it. */
#auth-panel {
  transition: opacity 0.18s ease;
}
#auth-panel.htmx-swapping {
  opacity: 0;
}

/* Password-reset intro line */
.lg-signup__hint {
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
  margin-bottom: 1.25rem;
}

/* Terminal confirmation panels (email sent / verify e-mail) */
.lg-auth-msg {
  text-align: center;
  padding: 0.5rem 0;
}
.lg-auth-msg__icon {
  display: block;
  font-size: 2.75rem;
  line-height: 1;
  color: var(--lg-accent);
  margin-bottom: 0.85rem;
}
.lg-auth-msg p {
  color: var(--bs-secondary-color);
  margin-bottom: 0;
}

/* Inputs sit on a darker fill for depth against the surface card */
.lg-form .form-control {
  background-color: var(--lg-bg);
  border-color: var(--bs-border-color-translucent);
}
.lg-form .form-control:focus {
  background-color: var(--lg-bg);
  border-color: var(--lg-accent);
  box-shadow: 0 0 0 0.25rem rgba(var(--lg-accent-rgb), 0.25);
}
.lg-form .form-floating > label {
  color: var(--bs-secondary-color);
}
.lg-form .btn-primary {
  margin-top: 0.5rem;
}
/* Required legal-consent checkboxes */
.lg-consent {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}
.lg-consent .form-check {
  margin-bottom: 0;
  font-size: 0.85rem;
}
.lg-consent a {
  color: var(--bs-secondary-color);
  text-decoration: underline;
}
.lg-consent a:hover {
  color: var(--lg-accent);
}

/* Checkbox theming shared by the consent block and the login "remember me"
   row — both live inside .lg-form. */
.lg-form .form-check-label {
  color: var(--bs-secondary-color);
}
.lg-form .form-check-input {
  background-color: var(--lg-bg);
  border-color: var(--bs-border-color-translucent);
}
.lg-form .form-check-input:checked {
  background-color: var(--lg-accent);
  border-color: var(--lg-accent);
}
.lg-form .form-check-input:focus {
  border-color: var(--lg-accent);
  box-shadow: 0 0 0 0.2rem rgba(var(--lg-accent-rgb), 0.25);
}

/* Inline form errors (opener auth panel: register + login) */
.lg-form__errors {
  background-color: rgba(var(--bs-danger-rgb), 0.12);
  border: 1px solid rgba(var(--bs-danger-rgb), 0.35);
  color: var(--lg-danger);
  border-radius: 0.5rem;
  padding: 0.6rem 0.85rem;
  font-size: 0.88rem;
  margin-bottom: 1rem;
}
.lg-form__errors ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.lg-field__error {
  color: var(--lg-danger);
  font-size: 0.82rem;
  margin-top: 0.3rem;
}
.lg-form .form-control.is-invalid {
  background-image: none;  /* drop Bootstrap's icon; we show our own message */
  border-color: var(--lg-danger);
}

/* Login: "remember me" + "forgot password" row */
.lg-login-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0.25rem 0 1.25rem;
  font-size: 0.85rem;
}
.lg-login-row .form-check {
  margin-bottom: 0;
  min-height: auto;
}
.lg-login-row a {
  color: var(--bs-secondary-color);
  text-decoration: none;
  white-space: nowrap;
}
.lg-login-row a:hover {
  color: var(--lg-accent);
}

/* Login prompt below the divider, vertically centred against the card's own
   bottom padding (2rem base / 2.5rem ≥lg) so the gaps above and below match. */
.lg-signup__login {
  margin-top: 1.75rem;
  padding-top: 2rem;
  border-top: 1px solid var(--bs-border-color-translucent);
  text-align: center;
  color: var(--bs-secondary-color);
}
@media (min-width: 992px) {
  .lg-signup__login { padding-top: 2.5rem; }
}

/* --- Footer --- */
.lg-foot {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--bs-border-color-translucent);
  background-color: rgba(0, 0, 0, 0.2);
}
.lg-foot__inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 1.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  font-size: 0.88rem;
}
.lg-foot__copy {
  color: var(--bs-secondary-color);
}
.lg-foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin-right: auto;
}
.lg-foot__links a {
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.lg-foot__links a:hover {
  color: var(--lg-accent);
}

/* Cross-links block at the foot of each legal page */
.legal-related {
  margin-top: 3rem;
}
.legal-related .card {
  height: 100%;
  transition: border-color 0.15s ease;
}
.legal-related a.card {
  text-decoration: none;
  color: inherit;
  display: block;
}
.legal-related a.card:hover {
  border-color: var(--lg-accent);
}

/* --- "Link your game account" panel (opener_link) --- */
.lg-link__lead {
  margin-bottom: 0.75rem;
}
.lg-link__cmd {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.25rem 0 1rem;
}
.lg-link__code {
  flex: 1 1 auto;
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 0.4rem 0.7rem;
  border-radius: 0.4rem;
  background: rgba(var(--lg-accent-rgb), 0.12);
  color: var(--lg-accent);
}
.lg-link__hint {
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
}
.lg-link__regen {
  margin-top: 0.25rem;
}

/* Floating messages on the opener shell (e.g. "Вы вышли." after logout) */
.lg-messages {
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1080;
  width: min(92%, 32rem);
}

/* Messages rendered inside the swapped auth panel (e.g. "Вы вышли." after logout) */
.lg-panel-messages {
  margin-bottom: 1rem;
}

/* Cyrillic descenders (д, ц, щ …) make the default text-decoration-skip-ink cut a
   link-button's underline short (e.g. «Обновить код» underlines only «Обновить ко»).
   Force a continuous underline on link-style buttons. */
.btn-link {
  text-decoration-skip-ink: none;
}

/* Honeypot: off-screen field bots fill and humans don't (bot-mitigation, 18-security). */
.lg-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ==========================================================================
   Internal navbar polish (base.html): brand logo, live «онлайн» pill, avatar
   chip on the user dropdown. Applies only to the .navbar (opener has none).
   ========================================================================== */
.navbar {
  border-bottom: 1px solid var(--bs-border-color-translucent);
}
.navbar-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}
.lg-brand__logo {
  width: 34px;
  height: 34px;
}
.lg-nav-online {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--bs-success);
  background-color: rgba(var(--bs-success-rgb), 0.12);
}
.lg-nav-online .status-dot {
  width: 0.55rem;
  height: 0.55rem;
}
.lg-nav-ava {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1; /* center the single glyph — default line-height rides it high */
  color: var(--lg-bg);
  background: linear-gradient(135deg, var(--lg-accent), var(--lg-accent-hover));
}
.navbar .dropdown-toggle.lg-user-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* ==========================================================================
   Post-login dashboard (core/home.html): two-column «command center».
   Main = news; sticky right rail = server widget + live chat + community.
   ========================================================================== */
.dash-greet {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}
.dash-greet__title {
  font-size: 1.6rem;
  font-weight: 700;
  margin: 0;
}
.dash-greet__sub {
  color: var(--bs-secondary-color);
  font-size: 0.95rem;
}

.dash-sec-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}
.dash-sec-head h2 {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.dash-sec-head h2 i {
  color: var(--lg-accent);
}
.dash-sec-head a {
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.dash-sec-head a:hover {
  color: var(--lg-accent);
}

/* News cards — horizontal, magazine-style */
.dash-news {
  display: flex;
  gap: 1rem;
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.75rem;
  overflow: hidden;
  margin-bottom: 1rem;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.dash-news:hover {
  border-color: var(--lg-accent);
  transform: translateY(-2px);
}
.dash-news__thumb {
  flex: 0 0 150px;
  align-self: stretch;
  min-height: 7rem;
  object-fit: cover;
  background: linear-gradient(135deg, #1b2a2f, #0f1519);
  display: flex;
  align-items: center;
  justify-content: center;
}
.dash-news__thumb i {
  font-size: 2.2rem;
  color: rgba(255, 255, 255, 0.15);
}
.dash-news__body {
  flex: 1;
  min-width: 0;
  padding: 0.9rem 1rem 0.9rem 0;
}
.dash-news__date {
  color: var(--bs-secondary-color);
  font-size: 0.78rem;
  margin-bottom: 0.35rem;
}
.dash-news__title {
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--bs-emphasis-color);
  margin: 0 0 0.35rem;
}
.dash-news__teaser {
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
  margin: 0;
}
.dash-empty {
  color: var(--bs-secondary-color);
}

/* Right rail */
@media (min-width: 992px) {
  .dash-rail {
    position: sticky;
    top: 5rem;
  }
}
.dash-panel {
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.85rem;
  box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.25);
  margin-bottom: 1.25rem;
  overflow: hidden;
}
.dash-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--bs-border-color-translucent);
}
.dash-panel__head h2 {
  font-size: 0.95rem;
  font-weight: 700;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.dash-panel__head h2 i {
  color: var(--lg-accent);
}
.dash-panel__head a {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.dash-panel__head a:hover {
  color: var(--lg-accent);
}
.dash-panel__body {
  padding: 1.1rem;
}

/* Server-widget connect sub-block */
.dash-connect {
  padding: 1rem 1.1rem 1.15rem;
  border-top: 1px solid var(--bs-border-color-translucent);
  background-color: rgba(0, 0, 0, 0.18);
}
.dash-connect__label {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.7rem;
  color: var(--bs-secondary-color);
  margin-bottom: 0.5rem;
}
.dash-connect__row {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.dash-connect__addr {
  display: block;
  text-align: center;
  background-color: var(--lg-bg);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.4rem;
  padding: 0.5rem 0.7rem;
  color: var(--lg-accent);
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  user-select: all;
}

/* Chat rail */
.dash-cbox {
  max-height: 19rem;
  overflow-y: auto;
  padding: 0.95rem 1.1rem;
}
.dash-cinput {
  padding: 0.75rem 1.1rem;
  border-top: 1px solid var(--bs-border-color-translucent);
}
.dash-cinput .text-body-secondary {
  margin: 0;
  font-size: 0.9rem;
}

/* ==========================================================================
   DASHBOARD REDESIGN (M-dash) — left sidebar shell + command-center home.
   Card system: .mod / .mod__h / .mod__b. Chat rows reuse .chat-row/.lg-cu.
   All grid placement is class-based (no inline style=, CSP per 01-conventions).
   ========================================================================== */

/* --- App shell: sticky left sidebar + content column --- */
.lg-app { display: flex; align-items: flex-start; min-height: 100vh; }
.lg-rail {
  position: sticky;
  top: 0;
  height: 100vh;
  flex: 0 0 232px;
  width: 232px;
  background: #11171d;
  border-right: 1px solid var(--bs-border-color-translucent);
  display: flex;
  flex-direction: column;
  padding: 1rem 0.7rem;
  z-index: 20;
}
.lg-rail__brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.35rem 0.6rem 1.1rem;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--bs-emphasis-color);
  text-decoration: none;
}
.lg-rail__brand img { width: 34px; height: 34px; }
.lg-rail__nav { display: flex; flex-direction: column; gap: 0.15rem; }
.lg-rail__link {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.6rem 0.75rem;
  border-radius: 0.6rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
  font-weight: 500;
  border-left: 3px solid transparent;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.lg-rail__link i { font-size: 1.15rem; width: 1.3rem; text-align: center; }
/* Unread-count pill («Контакты»: new ticket messages for this viewer) */
.lg-rail__badge {
  margin-left: auto;
  min-width: 1.35rem;
  height: 1.35rem;
  padding: 0 0.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1; /* inherited 1.5 pushes the digit off-center in the circle */
  padding-top: 1px; /* digits sit above center of the em box (unused descender) */
  font-variant-numeric: tabular-nums; /* uniform digit widths, optically centered */
  background: var(--lg-accent);
  color: var(--lg-bg);
}
.lg-rail__link:hover { background-color: rgba(255, 255, 255, 0.04); color: var(--bs-body-color); }
.lg-rail__link.active {
  color: var(--lg-accent);
  background-color: rgba(var(--lg-accent-rgb), 0.1);
  border-left-color: var(--lg-accent);
}
.lg-rail__spacer { flex: 1 1 auto; }
.lg-rail__user { position: relative; }
.lg-rail__userbtn {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.55rem 0.6rem;
  border-radius: 0.6rem;
  background-color: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--bs-border-color-translucent);
  color: var(--bs-body-color);
  text-decoration: none;
}
.lg-rail__userbtn:hover { background-color: rgba(255, 255, 255, 0.06); color: var(--bs-body-color); }
.lg-rail__ava {
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.9rem; line-height: 1;
  color: var(--lg-bg);
  background: linear-gradient(135deg, var(--lg-accent), var(--lg-accent-hover));
}
.lg-rail__ava--img { object-fit: cover; background: none; }
.lg-rail__uname { flex: 1; min-width: 0; font-weight: 600; font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lg-rail__user .dropdown-menu { width: 100%; }

.lg-shell { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; min-height: 100vh; }
.lg-content { width: 100%; max-width: 1320px; margin-inline: auto; padding: 1.4rem 1.75rem; flex: 1 1 auto; }
.lg-foot { border-top: 1px solid var(--bs-border-color-translucent); margin-top: auto; }
.lg-foot__inner { max-width: 1320px; margin-inline: auto; padding: 0.85rem 1.75rem; }

/* --- Player header (on the background, no card) --- */
.pg-head { display: flex; align-items: center; gap: 1.05rem; padding: 0 0.2rem; margin: 0.3rem 0 1.4rem; }
.pg-head__ava {
  width: 60px; height: 60px; flex: 0 0 60px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1.55rem; line-height: 1;
  color: var(--lg-bg);
  background: linear-gradient(135deg, var(--lg-accent), var(--lg-accent-hover));
}
.pg-head__m { flex: 1; min-width: 0; }
.pg-head h1 { font-size: 1.65rem; font-weight: 800; margin: 0 0 0.5rem; }
.nick { background: linear-gradient(90deg, var(--lg-accent), #5cf08a); -webkit-background-clip: text; background-clip: text; color: transparent; }
.chips { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.32rem 0.72rem; border-radius: 999px;
  font-size: 0.8rem; font-weight: 600;
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--bs-border-color-translucent);
  color: var(--bs-body-color);
}
.chip i { font-size: 0.9rem; }
.chip--fire { color: #ffb454; border-color: rgba(255, 180, 84, 0.3); background: rgba(255, 180, 84, 0.1); }
.chip--fire i { color: #ff9e3d; }
.chip--acc { color: var(--bs-success); border-color: rgba(var(--bs-success-rgb), 0.3); background: rgba(var(--bs-success-rgb), 0.1); }
/* A chip can be a link (dashboard game-role → profile «Мои привилегии»,
   streak → the streak leaderboard) */
a.chip { text-decoration: none; }
a.chip:hover { border-color: var(--lg-accent); color: var(--lg-accent); }
a.chip--fire:hover { border-color: #ff9e3d; color: #ffb454; }

/* --- Card system --- */
.mod {
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.9rem;
  box-shadow: 0 1rem 2.25rem rgba(0, 0, 0, 0.2);
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
}
.mod__h { display: flex; align-items: center; justify-content: space-between; padding: 0.8rem 1.05rem; border-bottom: 1px solid var(--bs-border-color-translucent); flex: 0 0 auto; }
.mod__h h2 { font-size: 0.9rem; font-weight: 700; margin: 0; display: flex; align-items: center; gap: 0.5rem; }
.mod__h h2 i { color: var(--lg-accent); }
.mod__h a { font-size: 0.76rem; color: var(--bs-secondary-color); text-decoration: none; }
.mod__h a:hover { color: var(--lg-accent); }
.mod__b { padding: 1rem 1.05rem; flex: 1 1 auto; min-height: 0; }

/* --- Dashboard grid (asymmetric; class-based placement) --- */
.dash-grid { display: grid; grid-template-columns: 1.4fr 1fr 1.05fr; gap: 1.1rem; align-items: stretch; }
.dash-grid > .gp-pin { grid-column: 1 / 3; grid-row: 1 / 2; }
.dash-grid > .gp-list { grid-column: 1 / 2; grid-row: 2 / 3; }
.dash-grid > .gp-server { grid-column: 1 / 2; grid-row: 3 / 4; }
.dash-grid > .gp-right { grid-column: 2 / 3; grid-row: 2 / 4; align-self: stretch; }
.dash-grid > .gp-chat { grid-column: 3 / 4; grid-row: 1 / 4; }

/* --- Pinned news (standalone rounded card) --- */
.news-pin {
  position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: center;
  min-height: 120px; padding: 1.1rem 1.2rem; color: inherit; text-decoration: none;
  background: var(--lg-surface); border: 1px solid var(--bs-border-color-translucent); border-radius: 0.9rem;
  transition: border-color 0.15s ease;
}
.news-pin:hover { border-color: var(--lg-accent); }
.news-pin::before { content: ""; position: absolute; inset: 0; background: radial-gradient(20rem 12rem at 90% 12%, rgba(var(--lg-accent-rgb), 0.2), transparent 60%); pointer-events: none; }
.news-pin > * { position: relative; }
.news-pin__tag {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.62rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em;
  /* line-height 1 + a hair more top padding: uppercase glyphs have no descender,
     so an evenly padded box renders them optically high. */
  line-height: 1; padding: 0.27rem 0.55rem 0.21rem;
  border-radius: 0.35rem; background: var(--lg-accent); color: var(--lg-bg); margin-bottom: 0.5rem;
}
/* The icon font's baseline shift (-0.125em) fights the flex centering. */
.news-pin__tag i::before { vertical-align: 0; }
.news-pin__title { margin: 0 0 0.25rem; color: var(--bs-emphasis-color); font-size: 1.18rem; line-height: 1.15; font-weight: 700; }
.news-pin__teaser { margin: 0; color: var(--bs-secondary-color); font-size: 0.86rem; }

/* --- News list (standalone rounded card) --- */
.news-list { background: var(--lg-surface); border: 1px solid var(--bs-border-color-translucent); border-radius: 0.9rem; padding: 0.55rem 1.2rem 1rem; }
.news-list__h { display: flex; align-items: center; justify-content: space-between; padding-top: 0.5rem; margin-bottom: 0.1rem; }
.news-list__h h2 { font-size: 0.9rem; font-weight: 700; margin: 0; display: flex; align-items: center; gap: 0.5rem; }
.news-list__h h2 i { color: var(--lg-accent); }
.news-list__h a { font-size: 0.76rem; color: var(--bs-secondary-color); text-decoration: none; }
.news-list__h a:hover { color: var(--lg-accent); }
.nli { display: flex; gap: 0.7rem; padding: 0.55rem 0; border-top: 1px solid rgba(255, 255, 255, 0.06); text-decoration: none; }
.nli:first-of-type { border-top: 0; }
.nli__dt { flex: 0 0 46px; font-size: 0.72rem; color: var(--bs-secondary-color); padding-top: 0.1rem; }
.nli__b { min-width: 0; }
.nli__title { display: block; font-size: 0.88rem; color: var(--bs-emphasis-color); font-weight: 600; margin-bottom: 0.1rem; }
.nli__teaser { display: block; font-size: 0.78rem; color: var(--bs-secondary-color); }
.dash-empty { color: var(--bs-secondary-color); }

/* --- Server card sections (status via {% server_status_widget %}, then players + connect) --- */
.srv-players { padding: 0 1.05rem 0.4rem; }
.plbtn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; width: 100%;
  padding: 0.5rem 0.9rem; border: 1px solid rgba(var(--lg-accent-rgb), 0.4);
  background: rgba(var(--lg-accent-rgb), 0.08); color: var(--lg-accent);
  border-radius: 0.5rem; font-weight: 600; font-size: 0.85rem;
}
.srv-players__soon { color: var(--bs-secondary-color); font-size: 0.85rem; margin: 0.7rem 0 0.2rem; }
/* Live player list (core/_server_players.html, htmx-fetched into the collapse) */
.plist { margin: 0.55rem 0 0.2rem; max-height: 14rem; overflow-y: auto; }
.plist__row {
  display: flex; align-items: baseline; gap: 0.6rem;
  padding: 0.28rem 0.1rem; font-size: 0.85rem;
  border-top: 1px solid var(--bs-border-color-translucent);
}
.plist__row:first-child { border-top: 0; }
.plist__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.plist__score { color: var(--lg-accent); font-weight: 700; white-space: nowrap; }
.plist__score i { margin-right: 0.25rem; }
.plist__time { color: var(--bs-secondary-color); font-size: 0.78rem; white-space: nowrap; }
.srv-conn { padding: 0.9rem 1.05rem 1.05rem; border-top: 1px solid var(--bs-border-color-translucent); background: rgba(0, 0, 0, 0.18); }
.srv-conn__l { display: block; font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--bs-secondary-color); margin-bottom: 0.45rem; }
.srv-conn__col { display: flex; flex-direction: column; gap: 0.45rem; }
.srv-conn__addr { display: block; text-align: center; background: var(--lg-bg); border: 1px solid var(--bs-border-color-translucent); border-radius: 0.4rem; padding: 0.5rem; color: var(--lg-accent); font-size: 0.95rem; white-space: nowrap; overflow: hidden; user-select: all; }
.srv-conn__col .btn { width: 100%; }

/* --- Right-column stack (leaderboards + privileges + VK), bottoms aligned --- */
.rstack { display: flex; flex-direction: column; gap: 1.1rem; min-height: 0; }
/* Grow to align bottoms when there's room, but never shrink below content
   (flex-basis auto + default min-height:auto) so leaderboard rows never clip. */
.rstack .mod { flex: 1 1 auto; }
.rstack .priv-card { flex: 0 0 auto; }
.rstack .lg-social { flex: 0 0 auto; margin-top: auto; }

/* --- Leaderboard rows --- */
.lb-row { display: flex; align-items: center; gap: 0.55rem; padding: 0.32rem 0; }
.lb-row__rank { width: 20px; height: 20px; flex: 0 0 20px; border-radius: 0.3rem; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 0.72rem; color: var(--lg-bg); background: #2a343b; }
.lb-row__rank--1 { background: linear-gradient(135deg, #ffd76a, #e0a92e); }
.lb-row__rank--2 { background: linear-gradient(135deg, #d4dde3, #9aa7b0); }
.lb-row__rank--3 { background: linear-gradient(135deg, #e0955a, #b3763e); }
.lb-row__name { font-weight: 600; font-size: 0.84rem; }
.lb-row__score { margin-left: auto; font-weight: 700; color: var(--lg-accent); font-size: 0.82rem; }

/* Player name → profile link (leaderboard rows, /top/ table). Unobtrusive:
   inherits the row's color, accent only on hover. */
.player-link { color: inherit; text-decoration: none; }
.player-link:hover { color: var(--lg-accent); text-decoration: underline; }

/* --- Top players page (/top/) --- */
.top-tabs { display: flex; gap: 0.4rem; margin: 0 0.2rem 1.1rem; flex-wrap: wrap; }
.top-tab {
  display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.5rem 0.95rem;
  border-radius: 0.7rem; text-decoration: none; font-weight: 600; font-size: 0.86rem;
  color: var(--bs-secondary-color); border: 1px solid var(--bs-border-color-translucent);
  background: var(--bs-tertiary-bg);
}
.top-tab i { font-size: 0.95rem; }
.top-tab:hover { color: var(--bs-body-color); }
.top-tab.active { color: var(--lg-bg); background: var(--lg-accent); border-color: transparent; }
.top-tab.active i { color: var(--lg-bg); }

.top-card .mod__h { gap: 0.75rem; flex-wrap: wrap; }
.top-search { position: relative; display: flex; align-items: center; margin-left: auto; }
.top-search i { position: absolute; left: 0.65rem; color: var(--bs-secondary-color); font-size: 0.85rem; pointer-events: none; }
.top-search input {
  padding: 0.35rem 0.7rem 0.35rem 2rem; border-radius: 0.6rem; font-size: 0.82rem;
  color: var(--bs-body-color); background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color-translucent); min-width: 12rem;
}
.top-search input:focus { outline: none; border-color: var(--lg-accent); }

.top-table-wrap { overflow-x: auto; }
.top-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.top-table th {
  text-align: left; font-weight: 600; font-size: 0.74rem; text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--bs-secondary-color);
  padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--bs-border-color-translucent);
}
.top-table td { padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--bs-border-color-translucent); }
.top-table tbody tr:last-child td { border-bottom: none; }
.top-table tbody tr:hover td { background: var(--bs-tertiary-bg); }
.top-c-rank { width: 3.2rem; }
.top-c-val { text-align: right; font-weight: 700; color: var(--lg-accent); white-space: nowrap; }
/* Right-align the value header too (beats `.top-table th`'s left) so «Убийств» /
   «Опыт, мин.» / «Дней» line up over their right-aligned numbers. */
th.top-c-val { text-align: right; color: var(--bs-secondary-color); }
.top-c-name { font-weight: 600; }
.top-c-title { color: var(--bs-secondary-color); }
.top-rank {
  display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem;
  height: 1.5rem; padding: 0 0.35rem; border-radius: 0.35rem; font-weight: 800; font-size: 0.74rem;
  color: var(--lg-bg); background: #2a343b;
}
.top-rank--1 { background: linear-gradient(135deg, #ffd76a, #e0a92e); }
.top-rank--2 { background: linear-gradient(135deg, #d4dde3, #9aa7b0); }
.top-rank--3 { background: linear-gradient(135deg, #e0955a, #b3763e); }
.top-empty { text-align: center; color: var(--bs-secondary-color); padding: 1.6rem 0.6rem; }

.top-pager { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1rem; }
.top-pager__btn {
  display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.4rem 0.85rem;
  border-radius: 0.6rem; text-decoration: none; font-size: 0.83rem; font-weight: 600;
  color: var(--bs-body-color); border: 1px solid var(--bs-border-color-translucent);
}
.top-pager__btn:hover { border-color: var(--lg-accent); color: var(--lg-accent); }
.top-pager__btn.disabled { color: var(--bs-secondary-color); opacity: 0.5; pointer-events: none; }
.top-pager__pos { font-size: 0.82rem; color: var(--bs-secondary-color); }

/* --- Privileges (gold) --- */
.priv-card {
  display: flex; align-items: center; gap: 0.8rem; padding: 1rem 1.1rem; text-decoration: none;
  background: linear-gradient(135deg, rgba(230, 192, 77, 0.16), rgba(202, 154, 45, 0.04));
  border: 1px solid rgba(230, 192, 77, 0.35); border-radius: 0.9rem;
}
/* Shiny gem: a soft, wide highlight GLIDES across the gold glyph (gradient
   clipped to the icon's ::before text) while the glow swells; a small sparkle
   twinkles once per cycle — one smooth, periodic diamond shine, then a rest. */
.priv-card__gemwrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  font-size: 1.6rem;
  line-height: 1;
}
.priv-card__gem {
  font-size: 1em;
  animation: lg-gem-glow 5s ease-in-out infinite;
}
.priv-card__gem::before {
  background: linear-gradient(100deg,
    #caa032 0%, #e6c04d 30%, #f6e19a 43%, #fffdf0 50%, #f6e19a 57%, #e6c04d 70%, #caa032 100%);
  background-size: 300% 100%;
  background-position: -40% 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: lg-gem-shine 5s ease-in-out infinite;
}
/* Two small sparkles at the gem's shoulders, twinkling in sequence (a small
   delay between them) around the moment the light passes. */
.priv-card__spark {
  position: absolute;
  width: 0.36em;
  height: 0.36em;
  background: radial-gradient(closest-side, #ffffff, #fffdf0 40%, rgba(255, 253, 240, 0) 72%);
  clip-path: polygon(50% 0, 58% 42%, 100% 50%, 58% 58%, 50% 100%, 42% 58%, 0 50%, 42% 42%);
  opacity: 0;
  transform: scale(0.2) rotate(-20deg);
  pointer-events: none;
  animation: lg-gem-sparkle 5s ease-in-out infinite;
}
.priv-card__spark--l { top: -0.05em; left: -0.1em; width: 0.46em; height: 0.46em; }
.priv-card__spark--r { top: 0.42em; right: 0.06em; width: 0.3em; height: 0.3em; animation-delay: 0.4s; }
@keyframes lg-gem-shine {
  0% { background-position: 200% 0; }
  34% { background-position: -40% 0; }
  100% { background-position: -40% 0; }
}
@keyframes lg-gem-glow {
  /* The glow slides left→right: it swells on the LEFT as the left sparkle fires,
     then travels to the RIGHT for the right sparkle, then settles. */
  0%, 44%, 100% { filter: drop-shadow(0 0 6px rgba(230, 192, 77, 0.4)); }
  11% { filter: drop-shadow(-0.16em 0 12px rgba(255, 240, 190, 0.85)); }
  22% { filter: drop-shadow(0.16em 0 12px rgba(255, 240, 190, 0.9)); }
}
@keyframes lg-gem-sparkle {
  0%, 100% { opacity: 0; transform: scale(0.2) rotate(-25deg); }
  13% { opacity: 1; transform: scale(1) rotate(5deg); }
  28% { opacity: 0; transform: scale(0.45) rotate(30deg); }
}
@media (prefers-reduced-motion: reduce) {
  .priv-card__gem,
  .priv-card__gem::before,
  .priv-card__spark { animation: none; }
  .priv-card__gem { filter: drop-shadow(0 0 8px rgba(230, 192, 77, 0.5)); }
}
.priv-card__t { display: block; font-weight: 800; color: #f2dc92; }
.priv-card__s { display: block; font-size: 0.8rem; color: #c9b981; margin-top: 0.1rem; }
.priv-card__ar { margin-left: auto; color: #e6c04d; }

/* --- Chat rail (reuses chat/_messages.html rows; window CSS lives with the
   chat shoutbox section: .chat-fill / .chat-scroll) --- */
.chat-send { padding: 0.7rem 1.05rem; border-top: 1px solid var(--bs-border-color-translucent); flex: 0 0 auto; }

/* --- Mobile fallback (polish deferred): stack the shell + grid --- */
@media (max-width: 991.98px) {
  .lg-app { flex-direction: column; }
  .lg-rail {
    /* relative + high z-index (not static): the bar must sit above the page
       content so the user dropdown, which hangs below it, is not painted over
       by the first content block. Stays under modals/lightbox (1080). */
    position: relative; z-index: 1040;
    width: 100%; height: auto; flex: 0 0 auto;
    flex-direction: row; align-items: center; gap: 0.3rem;
    padding: 0.5rem 0.75rem;
    border-right: 0; border-bottom: 1px solid var(--bs-border-color-translucent);
  }
  .lg-rail__brand { padding: 0.3rem 0.5rem; flex: 0 0 auto; }
  .lg-rail__brand span { display: none; }
  /* Only the links scroll horizontally — an overflow on .lg-rail itself would
     also clip the user dropdown, which hangs below the bar. */
  .lg-rail__nav { flex-direction: row; gap: 0.15rem; flex: 1 1 auto; min-width: 0; overflow-x: auto; }
  .lg-rail__link { border-left: 0; white-space: nowrap; }
  .lg-rail__spacer { display: none; }
  .lg-rail__user { flex: 0 0 auto; margin-left: auto; }
  .lg-rail__uname { display: none; }
  /* The button is just an avatar here, so the desktop width:100% is useless. */
  .lg-rail__user .dropdown-menu { width: auto; min-width: 11rem; }
  .lg-content { padding: 1.1rem; }
  /* TOP: cap nicknames at ~17 characters with an ellipsis — long ones widened
     the table and forced the whole page to scroll sideways. Full nick in the
     title attribute. */
  .top-name {
    display: inline-block; max-width: 17ch; vertical-align: bottom;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .dash-grid { grid-template-columns: 1fr; }
  .dash-grid > .gp-pin,
  .dash-grid > .gp-list,
  .dash-grid > .gp-server,
  .dash-grid > .gp-right,
  .dash-grid > .gp-chat { grid-column: auto; grid-row: auto; }
  /* Stacked column: nothing external drives the height, so fix the window. */
  .dash-grid > .gp-chat .chat-fill { flex: 0 0 auto; height: 24rem; }
}

/* ==========================================================================
   Rules page (core/rules) — website rules + game-server (Jail) rules.
   Same visual language as the legal pages: hero header, sticky grouped TOC,
   long-form sectioned body. Adds a numbered "rule code + text" list and the
   authority (ranks/points) block specific to the game server.
   ========================================================================== */
.rules-header {
  background: linear-gradient(180deg, rgba(var(--lg-accent-rgb), 0.08) 0%, var(--lg-bg) 100%);
  border: 1px solid var(--lg-surface);
  border-radius: 0.5rem;
  padding: 2.5rem 1.75rem;
  margin-bottom: 2rem;
}
.rules-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--lg-accent);
}
.rules-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin-top: 1rem;
  font-size: 0.9rem;
  color: var(--bs-secondary-color);
}
.rules-meta a { text-decoration: none; }
.rules-lead {
  font-size: 1.05rem;
  color: var(--bs-secondary-color);
  max-width: 46rem;
}

/* Sticky grouped table of contents (lg and up); inline below lg. */
.rules-toc {
  position: sticky;
  top: 5rem;
  font-size: 0.9rem;
}
.rules-toc-group + .rules-toc-group { margin-top: 1.5rem; }
.rules-toc-title {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--lg-accent);
  margin-bottom: 0.6rem;
}
.rules-toc ul {
  list-style: none;
  padding-left: 0;
  margin: 0;
  border-left: 1px solid var(--bs-border-color-translucent);
}
.rules-toc a {
  display: block;
  padding: 0.3rem 0 0.3rem 1rem;
  margin-left: -1px;
  border-left: 1px solid transparent;
  color: var(--bs-secondary-color);
  text-decoration: none;
  line-height: 1.35;
}
.rules-toc a:hover {
  color: var(--lg-accent);
  border-left-color: var(--lg-accent);
}

/* Article body */
.rules-body { max-width: 46rem; }

/* Major part divider ("Часть I / II") */
.rules-part {
  scroll-margin-top: 5rem;
  margin-bottom: 1.5rem;
}
.rules-part:not(:first-child) {
  margin-top: 3rem;
  border-top: 1px solid var(--bs-border-color-translucent);
  padding-top: 2.5rem;
}
.rules-part-num {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--lg-accent);
}
.rules-part h2 {
  font-size: 1.75rem;
  margin: 0.35rem 0 0.5rem;
}

.rules-section {
  scroll-margin-top: 5rem;
  margin-top: 2rem;
}
.rules-section > h3 {
  font-size: 1.2rem;
  color: var(--lg-accent);
  margin-bottom: 1rem;
}

/* Numbered rule list: monospace code badge + text. The codes are meaningful
   (rules cross-reference each other, e.g. "правило 0.7"), so they are shown. */
.rule-list {
  list-style: none;
  padding-left: 0;
  margin: 0;
}
.rule-list > li {
  display: flex;
  gap: 0.85rem;
  padding: 0.55rem 0;
}
.rule-list > li + li {
  border-top: 1px solid var(--bs-border-color-translucent);
}
.rule-code {
  flex: 0 0 auto;
  min-width: 3.1rem;
  height: fit-content;
  text-align: center;
  font-family: var(--bs-font-monospace);
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--lg-accent);
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.3rem;
  padding: 0.1rem 0.4rem;
}
.rule-text { flex: 1 1 auto; }

/* Callout note (e.g. "these rules are also in the in-game MOTD"). */
.rules-callout {
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-left: 3px solid var(--lg-accent);
  border-radius: 0.375rem;
  padding: 0.85rem 1.1rem;
  margin: 1.25rem 0;
}

/* Authority (ranks + points) block, game-server only. */
.authority-cols {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
}
.authority-card {
  background-color: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.5rem;
  padding: 1.1rem 1.25rem;
}
.authority-card h4 {
  font-size: 1.05rem;
  margin-bottom: 0.75rem;
}
.authority-points {
  list-style: none;
  padding-left: 0;
  margin: 0 0 1rem;
  font-size: 0.95rem;
}
.authority-points li { padding: 0.15rem 0; }
.authority-points .pts {
  font-family: var(--bs-font-monospace);
  font-weight: 500;
  color: var(--lg-accent);
  margin-right: 0.4rem;
}
.authority-ranks {
  list-style: none;
  padding-left: 0;
  margin: 0;
  font-size: 0.92rem;
}
.authority-ranks li { padding: 0.3rem 0; }
.authority-ranks li + li { border-top: 1px solid var(--bs-border-color-translucent); }
.rank-name { color: var(--lg-accent); font-weight: 500; }

/* Weekend-games accordion (click a mode to read its description). Themed via
   Bootstrap's own accordion CSS variables — no component rules copied. */
.rules-games {
  --bs-accordion-bg: var(--lg-surface);
  --bs-accordion-border-color: var(--bs-border-color-translucent);
  --bs-accordion-border-radius: 0.5rem;
  --bs-accordion-inner-border-radius: 0.5rem;
  --bs-accordion-btn-color: var(--bs-body-color);
  --bs-accordion-btn-bg: var(--lg-surface);
  --bs-accordion-active-color: var(--lg-accent);
  --bs-accordion-active-bg: rgba(var(--lg-accent-rgb), 0.08);
  --bs-accordion-btn-focus-border-color: var(--lg-accent);
  --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--lg-accent-rgb), 0.25);
}
.rules-games .accordion-button { font-weight: 500; }
.rules-games .accordion-body p:last-child { margin-bottom: 0; }

@media (max-width: 575.98px) {
  .authority-cols { grid-template-columns: 1fr; }
}

/* --- Profile pages (/u/<username>/, /player/<steam_id>/) --- */
.pf-head { flex-wrap: wrap; }
.pg-head__ava--img { object-fit: cover; background: none; border: 1px solid var(--bs-border-color-translucent); }
.pg-head__ava--ghost { background: #2a343b; color: var(--bs-secondary-color); font-size: 1.7rem; }
.pf-edit { flex: 0 0 auto; margin-left: auto; align-self: flex-start; margin-top: 0.3rem; }
.chip--mono { font-family: var(--bs-font-monospace); font-size: 0.72rem; letter-spacing: -0.01em; }
.chip .flag { width: 18px; height: 12px; border-radius: 2px; object-fit: cover; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.15); }

.profile-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 1.1rem; align-items: start; }
.pf-span2 { grid-column: 1 / -1; }

/* «Мои привилегии» on the own profile (doc 32 §2): a normal module with the
   dashboard's animated gem in the header. */
.pf-priv__gemwrap { font-size: 1.05rem; color: #e6c04d; }
.pf-priv__ci { margin-right: 0.5rem; font-size: 0.85rem; }
.pf-priv__ci--vip { color: #a98bff; }
.pf-priv__ci--adm { color: var(--lg-accent); }
/* Each row is a small grid — name | state stacked over the auth chip |
   button — so the VIP and Админ rows align into clean columns whatever
   state combination is present. */
.pf-priv__rows { margin-bottom: 0.9rem; }
.pf-priv__row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr) auto;
  grid-auto-rows: min-content;
  column-gap: 1rem;
  row-gap: 0.2rem;
  align-items: center;
  padding: 0.6rem 0;
}
.pf-priv__row + .pf-priv__row { border-top: 1px dashed var(--bs-border-color-translucent); }
.pf-priv__name {
  grid-column: 1;
  grid-row: 1 / span 2;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 700;
}
.pf-priv__name i { color: var(--lg-accent); }
.pf-priv__state { grid-column: 2; grid-row: 1; font-size: 0.9rem; }
.pf-priv__state--ok { color: #7ce8dc; }
.pf-priv__state--off { color: var(--bs-secondary-color); }
.pf-priv__auth { grid-column: 2; grid-row: 2; }
/* No auth chip in the row (inactive privilege): let the state span both grid
   rows, or a tall spanning button would center the name across two rows while
   the state stays pinned in the first — a visible vertical mismatch. */
.pf-priv__row--bare .pf-priv__state { grid-row: 1 / span 2; }
.pf-priv__row .btn { grid-column: 3; grid-row: 1 / span 2; justify-self: end; }
@media (max-width: 575.98px) {
  .pf-priv__row { grid-template-columns: 5.2rem minmax(0, 1fr); }
  .pf-priv__row .btn { grid-column: 1 / -1; grid-row: auto; justify-self: start; margin-top: 0.35rem; }
}
.pf-priv__h { font-size: 1rem; margin: 1rem 0 0.5rem; }
.pf-priv__cmds { list-style: none; margin: 0 0 0.8rem; padding: 0; }
.pf-priv__cmds li { padding: 0.3rem 0; font-size: 0.9rem; }
.pf-priv__cmds code,
.pf-priv__auth code,
.pf-priv__more code,
.pf-priv__cmdnote code {
  padding: 0.15rem 0.45rem;
  border-radius: 0.4rem;
  background: rgba(var(--lg-accent-rgb), 0.1);
  border: 1px solid rgba(var(--lg-accent-rgb), 0.35);
  color: #7ce8dc;
}
.pf-priv__auth { font-size: 0.8rem; color: var(--bs-secondary-color); }
/* Click-to-expand extras: change auth method / password command */
.pf-priv__more { margin: 0 0 0.6rem; }
.pf-priv__more summary {
  cursor: pointer;
  list-style: none;
  font-size: 0.82rem;
  color: var(--bs-secondary-color);
  text-decoration: underline dotted;
  text-underline-offset: 0.2em;
}
.pf-priv__more summary::-webkit-details-marker { display: none; }
.pf-priv__more summary:hover { color: var(--lg-accent); }
.pf-priv__more summary i { margin-right: 0.2rem; }
.pf-priv__more p {
  margin: 0.4rem 0 0;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
  max-width: 44rem;
}
.pf-priv__note,
.pf-priv__cmdnote { font-size: 0.85rem; color: var(--bs-secondary-color); margin: 0 0 0.6rem; }
.pf-priv__note i { color: var(--lg-accent); margin-right: 0.25rem; }

.pf-bio { margin-bottom: 0.9rem; }
.pf-row { display: flex; align-items: center; gap: 0.55rem; padding: 0.38rem 0; font-size: 0.88rem; }
.pf-row i { color: var(--lg-accent); font-size: 1rem; }
.pf-row__svg { width: 1rem; height: 1rem; flex: 0 0 auto; color: var(--lg-accent); }
.pf-row__l { color: var(--bs-secondary-color); }
.pf-row__v { margin-left: auto; font-weight: 600; text-decoration: none; color: var(--bs-body-color); }
a.pf-row__v:hover { color: var(--lg-accent); }

/* "На сервере" rows: rank pill + board name/title + value */
.pf-stats .lb-row { padding: 0.45rem 0; }
.pf-rank {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.6rem; height: 1.55rem; padding: 0 0.4rem; border-radius: 0.4rem;
  font-weight: 800; font-size: 0.76rem;
  color: var(--bs-body-color); background: rgba(255, 255, 255, 0.08);
}
.pf-rank--1 { color: var(--lg-bg); background: linear-gradient(135deg, #ffd76a, #e0a92e); }
.pf-rank--2 { color: var(--lg-bg); background: linear-gradient(135deg, #d4dde3, #9aa7b0); }
.pf-rank--3 { color: var(--lg-bg); background: linear-gradient(135deg, #e0955a, #b3763e); }
.pf-stat__m { display: flex; flex-direction: column; min-width: 0; }
.pf-stat__l { font-weight: 600; font-size: 0.86rem; }
.pf-stat__t { color: var(--bs-secondary-color); font-size: 0.76rem; }

/* --- Activity heatmap (GitHub-style; columns = weeks, rows = Mon..Sun) --- */
/* Fluid grid: square cells stretch to fill the card; below the 11px floor the
   grid overflows into horizontal scrolling (hm-main) while day labels stay put. */
.hm-wrap { display: flex; gap: 7px; padding-bottom: 4px; }
/* minmax(0, 1fr) + line-height 1: a plain 1fr row can never shrink below its
   text, so on phones (11px cells) the label rows were taller than the grid rows
   and every label drifted lower than its row — Вс ended up past the last cell. */
.hm-days { display: grid; grid-template-rows: repeat(7, minmax(0, 1fr)); row-gap: 3px; margin-top: 18px; flex: 0 0 auto; }
.hm-days span { font-size: 0.62rem; line-height: 1; color: var(--bs-secondary-color); display: flex; align-items: center; }
.hm-main { flex: 1 1 auto; min-width: 0; overflow-x: auto; }
.hm-months { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(11px, 1fr); column-gap: 3px; height: 18px; }
.hm-months span { font-size: 0.62rem; color: var(--bs-secondary-color); white-space: nowrap; overflow: visible; }
.hm-grid { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(11px, 1fr); column-gap: 3px; }
.hm-col { display: grid; grid-template-rows: repeat(7, auto); row-gap: 3px; }
.hm-cell { width: 100%; aspect-ratio: 1; height: auto; border-radius: 3px; background: rgba(255, 255, 255, 0.07); display: block; }
.hm-legend .hm-cell { width: 12px; height: 12px; aspect-ratio: auto; display: inline-block; }
.hm-cell--void { background: transparent; }
/* Days before the tracker went live (gameserver.activity.START_DATE): a faint × */
.hm-cell--pre {
  background:
    linear-gradient(45deg, transparent 42%, rgba(255, 255, 255, 0.09) 46%, rgba(255, 255, 255, 0.09) 54%, transparent 58%),
    linear-gradient(-45deg, transparent 42%, rgba(255, 255, 255, 0.09) 46%, rgba(255, 255, 255, 0.09) 54%, transparent 58%);
}
/* Legend swatches: full-intensity role colors (cell colors themselves are the
   server-computed weighted mix and arrive as inline styles). */
.hm--t { background: #e04654; }
.hm--ct { background: #4d9fe8; }
.hm--simon { background: #3fbf62; }
.hm--spec { background: #9aa7b0; }
.hm-total { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.76rem; color: var(--bs-secondary-color); }
.hm-total i { color: var(--lg-accent); }
.hm-legend { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 0.7rem; font-size: 0.72rem; color: var(--bs-secondary-color); }
.hm-legend > span { display: inline-flex; align-items: center; gap: 0.4rem; }

@media (max-width: 767.98px) {
  .profile-grid { grid-template-columns: 1fr; }
}

/* --- Profile: ban history card + danger chip --- */
.chip--danger { color: #ff6b6b; border-color: rgba(255, 107, 107, 0.3); background: rgba(255, 107, 107, 0.1); }
.chip--danger i { color: #ff5252; }
.pf-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.4rem; height: 1.4rem; padding: 0 0.4rem; border-radius: 999px;
  font-weight: 700; font-size: 0.72rem;
  color: var(--bs-body-color); background: rgba(255, 255, 255, 0.08);
}
.pf-count--danger { color: #ff6b6b; background: rgba(255, 107, 107, 0.12); }
.ban-row { display: flex; align-items: center; gap: 0.7rem; padding: 0.45rem 0; }
.ban-row + .ban-row { border-top: 1px solid var(--bs-border-color-translucent); }
.ban-row__date { flex: 0 0 auto; font-size: 0.78rem; color: var(--bs-secondary-color); font-variant-numeric: tabular-nums; }
.ban-row__m { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.ban-row__reason { font-weight: 600; font-size: 0.86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ban-row__meta { color: var(--bs-secondary-color); font-size: 0.76rem; }
.ban-more { margin: 0.5rem 0 0; font-size: 0.74rem; color: var(--bs-secondary-color); }

/* Collapsible ban-history header (Bootstrap collapse toggles .collapsed) */
button.mod__h { width: 100%; background: none; border: 0; border-bottom: 1px solid var(--bs-border-color-translucent); color: inherit; cursor: pointer; text-align: left; }
button.mod__h.collapsed { border-bottom-color: transparent; }
button.mod__h:hover { background: rgba(255, 255, 255, 0.03); }
.pf-bans-right { display: inline-flex; align-items: center; gap: 0.5rem; }
.pf-bans-chev { color: var(--bs-secondary-color); font-size: 0.8rem; transition: transform 0.2s ease; }
button.mod__h:not(.collapsed) .pf-bans-chev { transform: rotate(180deg); }

/* --- Site moderation: actions dropdown, banned page, chat mute notice --- */
.pf-actions { flex: 0 0 auto; margin-left: auto; align-self: flex-start; margin-top: 0.3rem; }
.pf-actions__menu { min-width: 240px; padding: 0.9rem 1rem; }
.pf-actions__label { display: block; font-size: 0.74rem; font-weight: 600; color: var(--bs-secondary-color); margin: 0.55rem 0 0.2rem; }
.pf-actions__menu input, .pf-actions__menu select { width: 100%; font-size: 0.85rem; }
.pf-actions__revoke,
.pf-actions__purge { border-top: 1px solid var(--bs-border-color-translucent); margin-top: 0.8rem; padding-top: 0.8rem; display: flex; flex-direction: column; gap: 0.5rem; }
.banned-box { max-width: 480px; margin: 8vh auto 0; }
.banned-box__icon { font-size: 3rem; color: #ff6b6b; }
.chat-muted { color: var(--bs-secondary-color); font-size: 0.86rem; display: flex; align-items: center; gap: 0.5rem; }
.chat-muted i { color: #ff6b6b; }

/* ==========================================================================
   Contacts page (core/contacts) — hero header (rules-page language), feedback
   form in a .mod card, right rail of contact-channel cards + server address.
   ========================================================================== */
.contact-head {
  background: linear-gradient(180deg, rgba(var(--lg-accent-rgb), 0.08) 0%, var(--lg-bg) 100%);
  border: 1px solid var(--lg-surface);
  border-radius: 0.5rem;
  padding: 2.5rem 1.75rem;
  margin-bottom: 1.5rem;
}
.contact-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--lg-accent);
}
.contact-lead {
  margin-top: 0.75rem;
  font-size: 1.05rem;
  color: var(--bs-secondary-color);
  max-width: 46rem;
}

.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 23rem;
  gap: 1.1rem;
  /* Columns match heights: the channel cards in .contact-side grow to fill,
     so the rail's bottom lines up with the «Поддержка» card. */
  align-items: stretch;
}
@media (max-width: 991.98px) {
  .contact-grid { grid-template-columns: 1fr; }
}

.contact-form-card textarea { resize: vertical; }
.contact-form-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.25rem;
}
.contact-form-foot .btn { flex: 0 0 auto; }
.contact-form-note {
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
}
.contact-form-note i { color: var(--lg-accent); }
.contact-optional { font-weight: 400; font-size: 0.8em; color: var(--bs-secondary-color); }

/* Right rail: one card per contact channel (e-mail, VK, Telegram, Discord).
   Cards split the column height equally (content stays vertically centered),
   so the rail always matches the left card's height. */
.contact-side { display: flex; flex-direction: column; gap: 0.9rem; }
.contact-side > .contact-ch { flex: 1 1 auto; }
.contact-ch {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.95rem 1.05rem;
  border-radius: 0.9rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  color: var(--bs-body-color);
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.contact-ch:hover { border-color: var(--lg-accent); transform: translateY(-1px); color: var(--bs-body-color); }
.contact-ch__icon {
  flex: 0 0 auto;
  width: 2.7rem;
  height: 2.7rem;
  display: grid;
  place-items: center;
  border-radius: 0.75rem;
  background: rgba(var(--lg-accent-rgb), 0.12);
  color: var(--lg-accent);
  font-size: 1.25rem;
}
/* The VK app mark is a self-colored squircle — no tinted plate behind it. */
.contact-ch__icon--vk { background: none; border-radius: 0; }
.contact-ch--vk:hover { border-color: #0077ff; }
.contact-ch__icon--tg { background: rgba(42, 171, 238, 0.12); color: #2aabee; }
.contact-ch__icon--ds { background: rgba(88, 101, 242, 0.14); color: #7289da; }
.contact-ch__body { display: flex; flex-direction: column; min-width: 0; gap: 0.05rem; }
.contact-ch__t { font-weight: 600; font-size: 0.92rem; }
.contact-ch__v { color: var(--lg-accent); font-size: 0.86rem; overflow: hidden; text-overflow: ellipsis; }
.contact-ch__s { color: var(--bs-secondary-color); font-size: 0.76rem; }
.contact-ch__arrow { margin-left: auto; flex: 0 0 auto; font-size: 0.85rem; color: var(--bs-secondary-color); }

/* ==========================================================================
   Tickets (support threads): list, create form, chat thread. Форма reuses the
   .contact-form-* classes above; here are list rows, badges and chat bubbles.
   ========================================================================== */
.tk-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.4rem;
}
.tk-head__actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }
/* Unread pill inside buttons («Мои заявки» on /contacts/, «Входящие заявки»).
   Inverts on hover: outline-primary buttons fill with the accent there. */
.btn .tk-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.3rem;
  height: 1.3rem;
  padding: 0 0.38rem;
  margin-left: 0.45rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1; /* see .lg-rail__badge */
  padding-top: 1px;
  font-variant-numeric: tabular-nums;
  background: var(--lg-accent);
  color: var(--lg-bg);
}
.btn:hover .tk-count { background: var(--lg-bg); color: var(--lg-accent); }
/* Inside a filled primary button the accent pill would vanish — invert it. */
.btn-primary .tk-count { background: var(--lg-bg); color: var(--lg-accent); }
.tk-back {
  display: inline-flex;
  align-items: center;
  margin-bottom: 1rem;
  font-size: 0.85rem;
  text-decoration: none;
  color: var(--bs-secondary-color);
}
.tk-back:hover { color: var(--lg-accent); }
.tk-narrow { max-width: 46rem; }

/* --- List rows --- */
.tk-list { display: flex; flex-direction: column; gap: 0.7rem; }
.tk-item {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.9rem 1.05rem;
  border-radius: 0.9rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  color: var(--bs-body-color);
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.tk-item:hover { border-color: var(--lg-accent); transform: translateY(-1px); color: var(--bs-body-color); }
.tk-item__id {
  flex: 0 0 auto;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--bs-secondary-color);
  font-variant-numeric: tabular-nums;
}
.tk-item__m { display: flex; flex-direction: column; min-width: 0; gap: 0.1rem; flex: 1 1 auto; }
.tk-item__subject {
  font-weight: 600;
  font-size: 0.95rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tk-item__meta { color: var(--bs-secondary-color); font-size: 0.78rem; }
.tk-item__ar { flex: 0 0 auto; font-size: 0.8rem; color: var(--bs-secondary-color); }

.tk-badge {
  flex: 0 0 auto;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  border: 1px solid transparent;
}
.tk-badge--open {
  color: var(--lg-accent);
  border-color: rgba(var(--lg-accent-rgb), 0.35);
  background: rgba(var(--lg-accent-rgb), 0.1);
}
.tk-badge--answered {
  color: var(--bs-success);
  border-color: rgba(var(--bs-success-rgb), 0.35);
  background: rgba(var(--bs-success-rgb), 0.1);
}
.tk-badge--closed {
  color: var(--bs-secondary-color);
  border-color: var(--bs-border-color-translucent);
  background: rgba(255, 255, 255, 0.04);
}
.tk-badge--waiting {
  color: var(--bs-warning);
  border-color: rgba(var(--bs-warning-rgb), 0.35);
  background: rgba(var(--bs-warning-rgb), 0.1);
}

/* Unread markers on list rows */
.tk-item--unread { border-color: rgba(var(--lg-accent-rgb), 0.45); }
.tk-new {
  flex: 0 0 auto;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1; /* see .lg-rail__badge */
  background: var(--lg-accent);
  color: var(--lg-bg);
}

.tk-empty {
  text-align: center;
  padding: 3.5rem 1.5rem;
  border: 1px dashed var(--bs-border-color-translucent);
  border-radius: 0.9rem;
}
.tk-empty__icon { display: block; font-size: 2.2rem; color: var(--bs-secondary-color); margin-bottom: 0.5rem; }

/* --- Detail: header, staff bar, chat thread --- */
.tk-detail-head {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.tk-detail-head__m { flex: 1 1 auto; min-width: 0; }
.tk-detail-head__subject { font-size: 1.35rem; font-weight: 700; margin: 0 0 0.15rem; }

.tk-staffbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  margin-bottom: 1rem;
  border-radius: 0.6rem;
  font-size: 0.85rem;
  color: var(--bs-warning);
  border: 1px solid rgba(var(--bs-warning-rgb), 0.35);
  background: rgba(var(--bs-warning-rgb), 0.08);
}
.tk-staffbar a { color: inherit; font-weight: 600; }

.tk-thread { display: flex; flex-direction: column; gap: 0.8rem; margin-bottom: 1.1rem; }
.tk-msg {
  max-width: 85%;
  align-self: flex-start;
  padding: 0.7rem 0.95rem;
  border-radius: 0.85rem;
  border-bottom-left-radius: 0.25rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
}
.tk-msg--mine {
  align-self: flex-end;
  border-radius: 0.85rem;
  border-bottom-right-radius: 0.25rem;
  background: rgba(var(--lg-accent-rgb), 0.08);
  border-color: rgba(var(--lg-accent-rgb), 0.25);
}
.tk-msg__head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.76rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
}
.tk-msg--staff .tk-msg__head { color: var(--lg-accent); }
.tk-msg__head i { font-size: 0.8rem; }
.tk-msg__dt { font-weight: 400; color: var(--bs-secondary-color); }
.tk-msg__text { font-size: 0.92rem; overflow-wrap: anywhere; }
.tk-msg__atts { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.tk-att {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-size: 0.76rem;
  text-decoration: none;
  color: var(--bs-body-color);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--bs-border-color-translucent);
}
.tk-att:hover { border-color: var(--lg-accent); color: var(--lg-accent); }

/* --- Reply composer --- */
.tk-reply textarea { resize: vertical; }
.tk-reply__note { font-size: 0.85rem; color: var(--bs-secondary-color); margin-bottom: 0.7rem; }
.tk-reply__foot {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 0.8rem;
}
.tk-reply__attach { flex: 1 1 16rem; }

/* Contacts page: the support-entry card (left column of .contact-grid) */
.contact-tickets__lead { color: var(--bs-secondary-color); }
.contact-tickets__btns { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 1rem; }
/* Staff inbox view has a single button; the card stretches to the contact rail's
   height, so a small top-left button floats in empty space. Make the card fill
   its body and anchor a full-width CTA to the bottom. */
.contact-tickets:has(.contact-tickets__btns--solo) { display: flex; flex-direction: column; height: 100%; }
.contact-tickets__btns--solo { margin-top: auto; margin-bottom: auto; }
.contact-tickets__btns--solo .btn { flex: 1 1 auto; }
/* Buttons carrying the unread pill: flex-center the label and the pill —
   as inline content the pill sits on the text baseline and rides too high. */
.contact-tickets__btns .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* --- Forum (templates/forum/, docs/components/24-forum.md) ------------------ */

/* Section rows on the forum index */
.fm-secs { display: flex; flex-direction: column; gap: 0.7rem; }
.fm-sec {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.85rem 1rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.7rem;
  text-decoration: none;
  color: var(--bs-body-color);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.fm-sec:hover { border-color: var(--cu, var(--lg-accent)); transform: translateY(-1px); color: var(--bs-body-color); }
.fm-sec__icon {
  flex: 0 0 auto;
  width: 2.7rem;
  height: 2.7rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.7rem;
  font-size: 1.25rem;
  color: var(--cu, var(--lg-accent));
  background: color-mix(in srgb, var(--cu, var(--lg-accent)) 16%, transparent);
}
.fm-sec__icon--lg { width: 3.2rem; height: 3.2rem; font-size: 1.5rem; }
.fm-sec__m { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.fm-sec__name { font-weight: 700; }
.fm-sec__desc {
  color: var(--bs-secondary-color);
  font-size: 0.82rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fm-sec__last { flex: 0 0 14rem; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.fm-sec__lasttitle { font-size: 0.82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-sec__lastmeta { font-size: 0.75rem; color: var(--bs-secondary-color); }
.fm-sec__stats { display: flex; gap: 0.4rem; flex: 0 0 auto; }
.fm-stat {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  padding: 0.2rem 0.55rem;
  border-radius: 2rem;
  border: 1px solid var(--bs-border-color-translucent);
  color: var(--bs-secondary-color);
}
.fm-stat i { font-size: 0.8rem; color: var(--cu, var(--lg-accent)); }
.fm-headline { display: flex; align-items: center; gap: 0.9rem; min-width: 0; }

/* Topic rows in a subforum */
.fm-topics { display: flex; flex-direction: column; gap: 0.55rem; margin-bottom: 1rem; }
.fm-topic {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.7rem 0.95rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.7rem;
  text-decoration: none;
  color: var(--bs-body-color);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.fm-topic:hover { border-color: var(--lg-accent); transform: translateY(-1px); color: var(--bs-body-color); }
.fm-topic--pinned {
  border-color: rgba(var(--lg-accent-rgb), 0.4);
  background: linear-gradient(90deg, rgba(var(--lg-accent-rgb), 0.07), var(--lg-surface) 55%);
}
.fm-topic__m { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.fm-topic__title {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fm-topic__pin { color: var(--lg-accent); font-size: 0.85rem; margin-right: 0.15rem; }
.fm-topic__lock { color: var(--bs-secondary-color); font-size: 0.85rem; margin-right: 0.15rem; }
.fm-topic__meta { font-size: 0.76rem; color: var(--bs-secondary-color); }
.fm-topic__replies {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.82rem;
  padding: 0.25rem 0.6rem;
  border-radius: 2rem;
  border: 1px solid var(--bs-border-color-translucent);
  color: var(--bs-secondary-color);
}
.fm-topic__replies i { color: var(--lg-accent); font-size: 0.85rem; }
.fm-topic__last { flex: 0 0 9.5rem; display: flex; flex-direction: column; gap: 0.05rem; }
.fm-topic__lastat { font-size: 0.76rem; }
.fm-topic__lastby { font-size: 0.72rem; color: var(--bs-secondary-color); }

/* Avatar disc (shared by topic rows and posts); img variant for real avatars */
.fm-ava {
  flex: 0 0 auto;
  width: 2.3rem;
  height: 2.3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-weight: 700;
  color: var(--lg-bg);
  background: var(--cu, var(--lg-accent));
}
.fm-ava--img { object-fit: cover; background: none; }

/* Topic page */
.fm-thread-head {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.fm-thread-head__m { flex: 1 1 auto; min-width: 0; }
.fm-thread-head__title { font-size: 1.35rem; font-weight: 700; margin: 0 0 0.15rem; }
.fm-thread-head__actions { display: flex; gap: 0.45rem; flex-wrap: wrap; }

.fm-posts { display: flex; flex-direction: column; gap: 0.8rem; margin: 1rem 0; }
.fm-post {
  display: flex;
  gap: 0;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.7rem;
  overflow: hidden;
}
.fm-post:target { border-color: var(--lg-accent); }
.fm-post--deleted { opacity: 0.6; border-style: dashed; }
.fm-post__side {
  flex: 0 0 9.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.9rem 0.7rem;
  border-right: 1px solid var(--bs-border-color-translucent);
  background: rgba(0, 0, 0, 0.12);
  text-align: center;
}
.fm-post__side .fm-ava { width: 2.8rem; height: 2.8rem; font-size: 1.1rem; }
.fm-post__name {
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--bs-body-color);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.fm-post__name:hover { color: var(--lg-accent); }
.fm-tag {
  font-size: 0.68rem;
  padding: 0.1rem 0.5rem;
  border-radius: 2rem;
  color: var(--lg-accent);
  border: 1px solid rgba(var(--lg-accent-rgb), 0.35);
  background: rgba(var(--lg-accent-rgb), 0.1);
}
.fm-post__main { flex: 1 1 auto; min-width: 0; padding: 0.75rem 1rem 0.9rem; }
.fm-post__head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
}
.fm-post__dt { color: var(--bs-secondary-color); text-decoration: none; }
.fm-post__dt:hover { color: var(--lg-accent); }
.fm-post__edited { display: inline-flex; align-items: center; gap: 0.25rem; font-style: italic; }
.fm-post__sp { flex: 1 1 auto; }
.fm-act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  border: 0;
  border-radius: 0.45rem;
  background: transparent;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.fm-act:hover { background: rgba(var(--lg-accent-rgb), 0.12); color: var(--lg-accent); }
.fm-act--danger:hover { background: rgba(234, 134, 143, 0.12); color: var(--lg-danger); }
.fm-post__delnote {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  color: var(--lg-danger);
  margin-bottom: 0.5rem;
}

/* Rendered post Markdown */
.fm-md { font-size: 0.92rem; overflow-wrap: anywhere; }
.fm-md > :last-child { margin-bottom: 0; }
.fm-md blockquote {
  margin: 0.6rem 0;
  padding: 0.4rem 0.8rem;
  border-left: 3px solid var(--lg-accent);
  background: rgba(var(--lg-accent-rgb), 0.06);
  border-radius: 0 0.4rem 0.4rem 0;
  color: var(--bs-secondary-color);
}
.fm-md pre {
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.45rem;
  padding: 0.6rem 0.8rem;
}
.fm-md table { width: auto; }
.fm-md th, .fm-md td { border: 1px solid var(--bs-border-color-translucent); padding: 0.25rem 0.6rem; }

/* Reply box + notices */
.fm-reply textarea { resize: vertical; }
.fm-mutebar,
.fm-closedbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  border-radius: 0.7rem;
  border: 1px solid var(--bs-border-color-translucent);
  background: var(--lg-surface);
  color: var(--bs-secondary-color);
  font-size: 0.88rem;
  margin-bottom: 1rem;
}
.fm-mutebar i { color: var(--lg-danger); }
.fm-closedbar i { color: var(--bs-secondary-color); }

/* Mobile: stack post author strip horizontally, hide wide columns */
@media (max-width: 767.98px) {
  .fm-sec__last { display: none; }
  .fm-topic__last { display: none; }
  .fm-post { flex-direction: column; }
  .fm-post__side {
    flex-direction: row;
    flex-basis: auto;
    border-right: 0;
    border-bottom: 1px solid var(--bs-border-color-translucent);
    padding: 0.55rem 0.8rem;
    text-align: left;
  }
  .fm-post__side .fm-ava { width: 2rem; height: 2rem; font-size: 0.9rem; }
}

/* Markdown toolbar above forum textareas */
.fm-mdbar {
  display: flex;
  align-items: center;
  gap: 0.2rem;
  flex-wrap: wrap;
  margin-bottom: 0.45rem;
}
.fm-mdbtn {
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.45rem;
  background: transparent;
  color: var(--bs-secondary-color);
  font-size: 1rem;
}
.fm-mdbtn:hover {
  color: var(--lg-accent);
  border-color: rgba(var(--lg-accent-rgb), 0.5);
  background: rgba(var(--lg-accent-rgb), 0.08);
}
.fm-mdbar__sep {
  width: 1px;
  height: 1.2rem;
  background: var(--bs-border-color-translucent);
  margin: 0 0.25rem;
}
.fm-mdbar__hint { margin-left: auto; font-size: 0.72rem; color: var(--bs-secondary-color); }
@media (max-width: 575.98px) { .fm-mdbar__hint { display: none; } }

/* Mentions (docs/components/25-mentions.md): pills, post/chat highlights, chips */
.fm-mention-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 1px 0.35rem 0;
  margin-left: 0.35rem;
  border-radius: 999px;
  background: var(--lg-accent);
  color: var(--lg-bg);
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1; /* see .lg-rail__badge */
  vertical-align: 0.1rem;
}
.fm-post--mentioned {
  border-color: rgba(var(--lg-accent-rgb), 0.45);
  background: linear-gradient(90deg, rgba(var(--lg-accent-rgb), 0.06), var(--lg-surface) 45%);
}
.fm-post__youtag {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: var(--lg-accent);
  font-weight: 600;
}
/* Mention chips in rendered post bodies: profile links minted by
   mentions.service.linkify — no extra HTML attributes, so the nh3 allowlist
   stays unchanged. */
.fm-md a[href^="/u/"] {
  display: inline-block;
  padding: 0 0.35rem;
  border-radius: 0.4rem;
  background: rgba(var(--lg-accent-rgb), 0.12);
  color: var(--lg-accent);
  text-decoration: none;
  font-weight: 600;
}
.fm-md a[href^="/u/"]:hover { background: rgba(var(--lg-accent-rgb), 0.22); }
.chat-row--mentioned {
  background: rgba(var(--lg-accent-rgb), 0.08);
  border-radius: 0.5rem;
  box-shadow: inset 2px 0 0 var(--lg-accent);
}

/* @username autocomplete dropdown (site.js data-mention-suggest) */
.mention-sug {
  position: absolute;
  display: none;
  z-index: 1050;
  min-width: 11rem;
  padding: 0.25rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.6rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  max-height: 14rem;
  overflow-y: auto;
}
.mention-sug__item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.35rem 0.6rem;
  border: 0;
  border-radius: 0.45rem;
  background: transparent;
  color: var(--bs-body-color);
  font-size: 0.9rem;
  text-align: left;
}
.mention-sug__item:hover,
.mention-sug__item.active {
  background: rgba(var(--lg-accent-rgb), 0.12);
  color: var(--lg-accent);
}
.mention-sug__ava {
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--lg-bg);
  background: var(--cu, var(--lg-accent));
}
.fm-mdbar__hint i { margin-right: 0.25rem; color: var(--lg-accent); }

/* Post author card extras: role chip, stats, staff nick colors */
.fm-post__name--admin { color: #ffb454; }
.fm-post__name--admin:hover { color: #ffcd85; }
.fm-post__name--moderator { color: #6ea8ff; }
.fm-post__name--moderator:hover { color: #9cc3ff; }
.fm-role {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.68rem;
  padding: 0.1rem 0.5rem;
  border-radius: 2rem;
  color: var(--bs-secondary-color);
  border: 1px solid var(--bs-border-color-translucent);
}
.fm-role--admin {
  color: #ffb454;
  border-color: rgba(255, 180, 84, 0.35);
  background: rgba(255, 180, 84, 0.1);
}
.fm-role--moderator {
  color: #6ea8ff;
  border-color: rgba(110, 168, 255, 0.35);
  background: rgba(110, 168, 255, 0.1);
}
.fm-post__uinfo { font-size: 0.7rem; color: var(--bs-secondary-color); }

/* Game-server role chips in the post author card (site roles reuse
   .fm-role--admin/--moderator above) */
.fm-role--head {
  color: #ff8f8f;
  border-color: rgba(255, 143, 143, 0.35);
  background: rgba(255, 143, 143, 0.1);
}
.fm-role--srvadmin {
  color: var(--lg-accent);
  border-color: rgba(var(--lg-accent-rgb), 0.35);
  background: rgba(var(--lg-accent-rgb), 0.1);
}
.fm-role--vip {
  color: #a98bff;
  border-color: rgba(169, 139, 255, 0.35);
  background: rgba(169, 139, 255, 0.1);
}

/* Inline post images + lightbox */
.fm-post__imgs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.fm-post__imgs:empty { display: none; }
.fm-img {
  display: inline-flex;
  max-width: 100%;
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.5rem;
  overflow: hidden;
  cursor: zoom-in;
}
.fm-img:hover { border-color: var(--lg-accent); }
.fm-img img {
  display: block;
  max-height: 18rem;
  max-width: 100%;
  object-fit: contain;
}
.lg-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1080;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: rgba(0, 0, 0, 0.85);
  cursor: zoom-out;
}
.lg-lightbox img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 0.4rem;
}

/* [imgN] tokens: placed at that spot in the text, but always on their own
   line, flush left — mid-sentence tokens break the line rather than float
   the image inside the paragraph. fit-content keeps the border snug. */
.fm-md .fm-img--inline {
  display: block;
  width: fit-content;
  margin: 0.4rem 0;
}

/* Forum search: index search bar, search page form and result cards */
.fm-search { display: flex; gap: 0.4rem; align-items: center; }
.fm-search input { width: 15rem; }
.fm-searchform__row { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.fm-searchform__row input[name="q"] { flex: 1 1 14rem; }
.fm-searchform__author { flex: 0 1 12rem; }
.fm-search-h {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.95rem;
  font-weight: 700;
  margin: 1.2rem 0 0.7rem;
}
.fm-search-h i { color: var(--lg-accent); }
.fm-sres-list { display: flex; flex-direction: column; gap: 0.55rem; margin-bottom: 1rem; }
.fm-sres {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.7rem 0.95rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.7rem;
  text-decoration: none;
  color: var(--bs-body-color);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.fm-sres:hover { border-color: var(--lg-accent); transform: translateY(-1px); color: var(--bs-body-color); }
.fm-sres__head { display: flex; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }
.fm-sres__topic { font-weight: 600; }
.fm-sres__meta { font-size: 0.76rem; color: var(--bs-secondary-color); }
.fm-sres__snippet { font-size: 0.85rem; color: var(--bs-secondary-color); overflow-wrap: anywhere; }
@media (max-width: 575.98px) { .fm-search input { width: 100%; } .fm-search { width: 100%; } }

/* === News v2 (26-news-v2.md): hero + grid list, article typography, comments === */

/* List: covers keep a 16:9 box whether or not an image exists */
.nw-cover {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--lg-surface);
}
.nw-cover--empty {
  background: linear-gradient(135deg, rgba(var(--lg-accent-rgb), 0.16), var(--lg-surface) 70%);
  color: rgba(var(--lg-accent-rgb), 0.55);
  font-size: 2.6rem;
}
.nw-cover--hero { aspect-ratio: auto; height: 20rem; }
.nw-card__coverlink { display: block; line-height: 0; }
.nw-cover--empty i { line-height: 1; }

.nw-hero { overflow: hidden; }
.nw-hero__title { font-size: 1.5rem; font-weight: 700; margin: 0.15rem 0 0.4rem; }
.nw-card { overflow: hidden; transition: border-color 0.15s ease, transform 0.15s ease; }
.nw-card:hover { border-color: var(--lg-accent); transform: translateY(-2px); }
.nw-card__title { margin: 0.15rem 0 0.4rem; }
.nw-card .card-footer { background: transparent; }

.nw-teaser {
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
  margin-bottom: 0.5rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.nw-teaser--hero { -webkit-line-clamp: 2; font-size: 1rem; }

.nw-meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}
.nw-meta__comments {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-left: auto;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
a.nw-meta__comments:hover { color: var(--lg-accent); }
.nw-pin {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.1rem 0.55rem;
  border-radius: 2rem;
  color: var(--lg-accent);
  border: 1px solid rgba(var(--lg-accent-rgb), 0.35);
  background: rgba(var(--lg-accent-rgb), 0.1);
}

/* Detail: cover header + article typography (.news-body finally gets rules) */
.nw-detail-cover {
  width: 100%;
  max-height: 26rem;
  object-fit: cover;
  border-radius: 0.7rem;
}
.nw-admintools { display: flex; gap: 0.45rem; justify-content: flex-end; margin-bottom: 0.6rem; }
.news-body {
  font-size: 1.02rem;
  line-height: 1.7;
  overflow-wrap: anywhere;
}
.news-body h1, .news-body h2, .news-body h3, .news-body h4 {
  font-weight: 700;
  margin: 1.4em 0 0.5em;
}
.news-body h1 { font-size: 1.5rem; }
.news-body h2 { font-size: 1.3rem; }
.news-body h3 { font-size: 1.15rem; }
.news-body h4 { font-size: 1.02rem; }
.news-body > :first-child { margin-top: 0; }
.news-body blockquote {
  margin: 0.8rem 0;
  padding: 0.5rem 0.9rem;
  border-left: 3px solid var(--lg-accent);
  background: rgba(var(--lg-accent-rgb), 0.06);
  border-radius: 0 0.4rem 0.4rem 0;
  color: var(--bs-secondary-color);
}
.news-body pre {
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.45rem;
  padding: 0.6rem 0.8rem;
}
.news-body table { width: auto; margin-bottom: 1rem; }
.news-body th, .news-body td { border: 1px solid var(--bs-border-color-translucent); padding: 0.3rem 0.7rem; }
.news-body img {
  max-width: 100%;
  border-radius: 0.5rem;
  cursor: zoom-in; /* site.js opens these in the lightbox */
}
.news-body hr { margin: 1.4rem 0; }

/* Comments */
.nw-comments { margin-top: 2.2rem; }
.nw-comments__title { font-size: 1.15rem; font-weight: 700; margin-bottom: 1rem; }
.nw-comment {
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.7rem;
  padding: 0.7rem 1rem 0.8rem;
  margin-bottom: 0.8rem;
}
.nw-comment:target { border-color: var(--lg-accent); }
.nw-comment--deleted { opacity: 0.6; border-style: dashed; }
.nw-comment--mentioned {
  border-color: rgba(var(--lg-accent-rgb), 0.45);
  background: linear-gradient(90deg, rgba(var(--lg-accent-rgb), 0.06), var(--lg-surface) 45%);
}
.nw-comment__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.45rem;
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
}
.nw-comment__ava {
  width: 1.9rem;
  height: 1.9rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--lg-bg);
  background: var(--cu, var(--lg-accent));
  object-fit: cover;
}
.nw-comment .fm-post__name { font-size: 0.88rem; }
.nw-comment-form textarea { resize: vertical; }

/* Editor (post_form.html): tabs + preview pane */
.nw-editor-tabs .nav-link { color: var(--bs-secondary-color); }
.nw-editor-tabs .nav-link.active { color: var(--lg-accent); background: var(--lg-surface); }
.nw-editor-body {
  border: 1px solid var(--bs-border-color-translucent);
  border-top: 0;
  border-radius: 0 0 0.6rem 0.6rem;
  padding: 0.8rem;
  background: var(--lg-surface);
}
.nw-editor-body textarea { resize: vertical; }
.nw-preview { min-height: 10rem; }
.fm-mdbar__status { font-size: 0.75rem; color: var(--bs-secondary-color); margin-left: 0.4rem; }

/* Search bar, tag chips and author links (26-news-v2.md §9) */
.nw-search { display: flex; gap: 0.4rem; align-items: center; flex: 1 1 14rem; max-width: 22rem; }
.nw-tagrow, .nw-taglist { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }
.nw-taglist { margin-bottom: 0.35rem; }
.nw-taglist:empty { display: none; }
.nw-tag {
  display: inline-flex;
  align-items: center;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.12rem 0.6rem;
  border-radius: 2rem;
  color: var(--bs-secondary-color);
  border: 1px solid var(--bs-border-color-translucent);
  background: transparent;
  text-decoration: none;
}
.nw-tag:hover {
  color: var(--lg-accent);
  border-color: rgba(var(--lg-accent-rgb), 0.5);
  background: rgba(var(--lg-accent-rgb), 0.08);
}
.nw-tag--active {
  color: var(--lg-bg);
  border-color: var(--lg-accent);
  background: var(--lg-accent);
}
.nw-author { color: inherit; text-decoration: none; font-weight: 600; }
.nw-author:hover { color: var(--lg-accent); }

/* Tag picker in the editor: chip-styled checkboxes */
.nw-tagpick > div { display: flex; gap: 0.45rem; flex-wrap: wrap; }
.nw-tagpick div div { display: inline-flex; }
.nw-tagpick label {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.82rem;
  padding: 0.2rem 0.7rem;
  border-radius: 2rem;
  border: 1px solid var(--bs-border-color-translucent);
  cursor: pointer;
}
.nw-tagpick label:hover { border-color: rgba(var(--lg-accent-rgb), 0.5); }
.nw-tagpick input[type="checkbox"] { accent-color: var(--lg-accent); margin: 0; }
.nw-tagpick label:has(input:checked) {
  color: var(--lg-accent);
  border-color: var(--lg-accent);
  background: rgba(var(--lg-accent-rgb), 0.1);
}

/* === Reactions (docs/components/27-reactions.md): chips + emoji picker === */
.rx-bar {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.5rem;
}
/* The form is invisible plumbing: its children lay out as .rx-bar flex items. */
.rx-form { display: contents; }
.rx-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.6rem;
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--bs-body-color);
  font-size: 0.85rem;
  line-height: 1.4;
}
button.rx-chip:hover { border-color: rgba(var(--lg-accent-rgb), 0.5); }
.rx-chip--mine {
  border-color: rgba(var(--lg-accent-rgb), 0.6);
  background: rgba(var(--lg-accent-rgb), 0.14);
}
.rx-chip__n { font-weight: 600; font-variant-numeric: tabular-nums; }
.rx-chip--mine .rx-chip__n { color: var(--lg-accent); }
.rx-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  padding: 0.15rem 0.45rem;
  border: 1px dashed var(--bs-border-color-translucent);
  border-radius: 999px;
  background: transparent;
  color: var(--bs-secondary-color);
  font-size: 0.85rem;
  line-height: 1.4;
}
.rx-add:hover { color: var(--lg-accent); border-color: rgba(var(--lg-accent-rgb), 0.5); }
/* Picker panel: CSS-anchored to the bar, opens UPWARD so it never clips at
   the chat's bottom edge (site.js only flips the hidden attribute). */
.rx-picker {
  position: absolute;
  bottom: calc(100% + 0.35rem);
  left: 0;
  z-index: 1050;
  padding: 0.4rem 0.5rem;
  background: var(--lg-surface);
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.6rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.rx-picker__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  max-width: 15rem; /* 9 emojis wrap to 2 rows on narrow screens */
}
.rx-picker__btn {
  width: 2.25rem;  /* juveniles are on phones — generous tap targets */
  height: 2.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 0.45rem;
  background: transparent;
  font-size: 1.25rem;
  line-height: 1;
}
.rx-picker__btn:hover { background: rgba(var(--lg-accent-rgb), 0.12); }
.rx-picker__hint {
  margin-top: 0.25rem;
  color: var(--bs-secondary-color);
  font-size: 0.72rem;
  text-align: center;
}
/* Forum: the author card usually sets the post height, so a bar right under
   short text floats mid-card. Flex the main column and push the bar to the
   card's lower edge instead. */
.fm-post__main { display: flex; flex-direction: column; }
.fm-post__main .rx-bar { margin-top: auto; padding-top: 0.5rem; }

/* Chat variant: tighter geometry inside the message column */
.rx-bar--chat { margin-top: 0.15rem; gap: 0.25rem; }
.rx-bar--chat .rx-chip { padding: 0.05rem 0.45rem; font-size: 0.78rem; }
.rx-bar--chat .rx-add { min-width: 1.6rem; padding: 0.05rem 0.35rem; font-size: 0.78rem; }
/* Chat: the add button appears only on message hover (Telegram-style — a
   permanent ☺ under every row is noise). It LINGERS ~½s after hover-out:
   the pointer needs time to travel from the text down to the button
   (display:none would yank it away mid-flight), and hovering the button
   itself re-hovers the row, keeping it alive. */
.rx-bar--chat .rx-add {
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.15s ease 0.4s, visibility 0s linear 0.55s;
}
.chat-row:hover .rx-bar--chat .rx-add {
  visibility: visible;
  opacity: 1;
  transition-delay: 0s, 0s;
}
/* The row gap is widened so the hover button has a home (base gap: 0.7rem). */
.chat-scroll,
.dash-cbox { gap: 1.05rem; }
/* No reactions yet: the empty bar collapses; on hover the button shows up
   under the text — the same spot a chips bar occupies — overlaying the row
   gap, so the row height never jumps. With chips present the button rides
   inline after them as before. */
.chat-row__body { position: relative; }
.rx-bar--chat:not(:has(.rx-chip)) { position: static; margin-top: 0; }
.rx-bar--chat:not(:has(.rx-chip)) .rx-add {
  position: absolute;
  top: calc(100% + 0.1rem);
  left: 0;
  z-index: 5;
}

/* --- /privileges/ page (docs/components/31-privileges.md): two plan columns —
   VIP violet / Admin accent, colors matching the forum role chips
   .fm-role--vip / --srvadmin — then the purchase block. Perk screenshots
   open via the site lightbox (a[data-lightbox]). --- */
.pv-sub { margin: 0.15rem 0 0; color: var(--bs-secondary-color); font-size: 0.9rem; }
.pv-note i { margin-right: 0.4rem; }

/* Page-header gem: the dashboard card's shine animation (.priv-card__gem*) on
   a gold-tinted disc instead of the standard accent avatar circle. */
.pg-head__ava--gem {
  color: #e6c04d;
  background: linear-gradient(135deg, rgba(230, 192, 77, 0.22), rgba(202, 154, 45, 0.05));
  border: 1px solid rgba(230, 192, 77, 0.35);
}
.pg-head__ava--gem .priv-card__gemwrap {
  font-size: 1.7rem;
  /* Optical centering: the glyph box sits ~1.5px high in the disc, and the
     diamond's wide crown/pointed tip makes it read higher still — nudge down. */
  transform: translateY(0.07em);
}

/* Plan columns */
.pv-plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}
.pv-plan {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 1.3rem 1.3rem 1.1rem;
  border-radius: 1rem;
  border: 1px solid var(--bs-border-color-translucent);
  background: var(--lg-surface);
}
.pv-plan--vip {
  border-color: rgba(169, 139, 255, 0.4);
  background:
    radial-gradient(120% 70% at 100% 0%, rgba(169, 139, 255, 0.13), transparent 55%),
    var(--lg-surface);
}
.pv-plan--admin {
  border-color: rgba(var(--lg-accent-rgb), 0.4);
  background:
    radial-gradient(120% 70% at 100% 0%, rgba(var(--lg-accent-rgb), 0.11), transparent 55%),
    var(--lg-surface);
}
.pv-plan__head {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--bs-border-color-translucent);
}
.pv-plan--vip .pv-plan__head { border-bottom-color: rgba(169, 139, 255, 0.3); }
.pv-plan--admin .pv-plan__head { border-bottom-color: rgba(var(--lg-accent-rgb), 0.3); }
.pv-plan__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.8rem;
  font-size: 1.2rem;
}
.pv-plan--vip .pv-plan__icon { color: #a98bff; background: rgba(169, 139, 255, 0.14); }
.pv-plan--admin .pv-plan__icon { color: var(--lg-accent); background: rgba(var(--lg-accent-rgb), 0.12); }
.pv-plan__name { margin: 0; font-size: 1.4rem; font-weight: 800; }
.pv-plan__price { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; }
.pv-plan__rub { font-size: 1.5rem; font-weight: 800; line-height: 1.1; }
.pv-plan--vip .pv-plan__rub { color: #cdbaff; }
.pv-plan--admin .pv-plan__rub { color: #7ce8dc; }
.pv-plan__per { font-size: 0.75rem; color: var(--bs-secondary-color); }

/* Perk rows */
.pv-list { list-style: none; margin: 0; padding: 0; }
/* The chip centers against the title+description block — top-aligning it made
   every two-line row read as «icon sits high». */
.pv-item { display: flex; align-items: center; gap: 0.75rem; padding: 0.7rem 0; }
.pv-item + .pv-item { border-top: 1px dashed var(--bs-border-color-translucent); }
.pv-item__ic {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 0.6rem;
  font-size: 0.95rem;
  color: var(--bs-secondary-color);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--bs-border-color-translucent);
}
.pv-plan--vip .pv-item__ic { color: #cdbaff; }
.pv-plan--admin .pv-item__ic { color: #7ce8dc; }
.pv-item--all .pv-item__ic { color: #f2dc92; border-color: rgba(242, 220, 146, 0.4); background: rgba(242, 220, 146, 0.08); }
/* Bootstrap-icons glyphs are baseline-aligned inline boxes (-0.125em shift for
   running text), so inside these chips they never sit geometrically centered.
   Make the <i> fill its chip as a flex box and center the ::before glyph box
   itself; line-height 1 shrinks that box to the glyph's own em square, which
   bootstrap-icons draws centered — so the centering is geometric, not
   baseline arithmetic. */
.pv-plan__icon > .bi,
.pv-item__ic > .bi {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.pv-plan__icon > .bi::before,
.pv-item__ic > .bi::before {
  line-height: 1;
}
.pv-item__b { min-width: 0; }
.pv-item__b h3 { margin: 0 0 0.15rem; font-size: 0.95rem; font-weight: 700; }
.pv-item__b p { margin: 0; font-size: 0.84rem; color: var(--bs-secondary-color); }
.pv-item__b .fm-role { vertical-align: baseline; margin: 0 0.1rem; }
.pv-item--all h3 { color: #f2dc92; }

/* Small screenshot links inside perk titles */
.pv-zoom {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  margin-left: 0.35rem;
  padding: 0.05rem 0.45rem;
  border-radius: 2rem;
  border: 1px solid var(--bs-border-color-translucent);
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
  text-decoration: none;
  vertical-align: middle;
  cursor: zoom-in;
}
.pv-zoom:hover { color: var(--lg-accent); border-color: var(--lg-accent); }
.pv-plan--vip .pv-zoom:hover { color: #a98bff; border-color: #a98bff; }

/* Value pills in perk titles */
.pv-cd {
  display: inline-block;
  margin-left: 0.3rem;
  padding: 0.05rem 0.5rem;
  border-radius: 2rem;
  font-size: 0.68rem;
  font-weight: 800;
  vertical-align: middle;
  color: var(--bs-secondary-color);
  border: 1px solid var(--bs-border-color-translucent);
}

.pv-plan__req {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: auto 0 0; /* pins the note to the card bottom in the stretched grid */
  padding-top: 0.8rem;
  border-top: 1px dashed var(--bs-border-color-translucent);
  font-size: 0.82rem;
  color: var(--bs-secondary-color);
}

/* Title-pill toggle (Bootstrap collapse) + its fine print under a perk row */
button.pv-zoom { background: transparent; font: inherit; font-size: 0.68rem; font-weight: 600; cursor: pointer; }
.pv-item__fine {
  margin-top: 0.35rem !important;
  padding: 0.4rem 0.6rem;
  border-radius: 0.45rem;
  border: 1px dashed var(--bs-border-color-translucent);
  font-size: 0.8rem;
}

.pv-buy__state { font-size: 0.9rem; margin: 0 0 0.9rem; }
.pv-buy__state i { color: var(--lg-accent); margin-right: 0.25rem; }

/* Purchase block: consent checkboxes gate the VK button (site.js §6) */
.pv-buy__choices { margin: 0 0 0.9rem; }
.pv-buy__choices legend { float: none; width: auto; font-size: 0.85rem; margin-bottom: 0.5rem; }

/* Plan picker: the radios render as selectable cards. Inputs stay in the DOM
   (visually hidden, still focusable) so the native radio semantics and the
   change events site.js §6 listens for are untouched. */
.pv-pick { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.pv-pick__input {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.pv-pick__card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 14rem;
  padding: 0.8rem 2.6rem 0.8rem 1rem;
  border: 1px solid var(--bs-border-color-translucent);
  border-radius: 0.8rem;
  background: var(--lg-surface);
  cursor: pointer;
  transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.pv-pick__card:hover { transform: translateY(-2px); }
.pv-pick__ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.3rem; height: 2.3rem;
  border-radius: 0.7rem;
  font-size: 1.05rem;
}
.pv-pick__card--vip .pv-pick__ic { color: #a98bff; background: rgba(169, 139, 255, 0.14); }
.pv-pick__card--admin .pv-pick__ic { color: var(--lg-accent); background: rgba(var(--lg-accent-rgb), 0.12); }
.pv-pick__m { display: flex; flex-direction: column; gap: 0.05rem; }
.pv-pick__t { font-weight: 800; font-size: 1rem; line-height: 1.2; }
.pv-pick__p { font-weight: 800; font-size: 0.95rem; }
.pv-pick__p small { font-weight: 400; font-size: 0.72rem; color: var(--bs-secondary-color); }
.pv-pick__card--vip .pv-pick__p { color: #cdbaff; }
.pv-pick__card--admin .pv-pick__p { color: #7ce8dc; }
.pv-pick__sub {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.7rem;
  font-weight: 700;
  color: #f2dc92;
}
/* The check bubble: appears when the card's radio is selected */
.pv-pick__card::after {
  content: "\2713";
  position: absolute;
  top: 0.55rem; right: 0.55rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem; height: 1.15rem;
  border-radius: 50%;
  font-size: 0.7rem;
  font-weight: 800;
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.pv-pick__card--vip::after { background: #a98bff; color: #14101f; }
.pv-pick__card--admin::after { background: var(--lg-accent); color: #06231f; }
.pv-pick__input:checked + .pv-pick__card::after { opacity: 1; transform: scale(1); }
.pv-pick__input:checked + .pv-pick__card--vip {
  border-color: rgba(169, 139, 255, 0.65);
  box-shadow: 0 0 0 1px rgba(169, 139, 255, 0.55), 0 0.35rem 1.2rem rgba(169, 139, 255, 0.15);
  background: linear-gradient(160deg, rgba(169, 139, 255, 0.1), transparent 55%), var(--lg-surface);
}
.pv-pick__input:checked + .pv-pick__card--admin {
  border-color: rgba(var(--lg-accent-rgb), 0.65);
  box-shadow: 0 0 0 1px rgba(var(--lg-accent-rgb), 0.55), 0 0.35rem 1.2rem rgba(var(--lg-accent-rgb), 0.13);
  background: linear-gradient(160deg, rgba(var(--lg-accent-rgb), 0.09), transparent 55%), var(--lg-surface);
}
.pv-pick__input:focus-visible + .pv-pick__card {
  outline: 2px solid var(--lg-accent);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .pv-pick__card, .pv-pick__card::after { transition: none; }
  .pv-pick__card:hover { transform: none; }
}
.pv-buy__checks { margin-bottom: 1rem; }
.pv-buy__checks .form-check + .form-check { margin-top: 0.35rem; }
.pv-buy__note { margin: 0.6rem 0 0; font-size: 0.8rem; color: var(--bs-secondary-color); }

/* Pay page (/privileges/pay/): three numbered instruction cards */
.pv-pay { margin-bottom: 1rem; }
.pv-pay .mod__h h2 i { color: var(--lg-accent); }
.pv-pay__nick { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.pv-pay__nick code {
  font-size: 1.05rem;
  font-weight: 700;
  padding: 0.3rem 0.7rem;
  border-radius: 0.5rem;
  background: rgba(var(--lg-accent-rgb), 0.1);
  border: 1px solid rgba(var(--lg-accent-rgb), 0.35);
  color: #7ce8dc;
}
.pv-pay__note { margin: 0.6rem 0 0; font-size: 0.8rem; color: var(--bs-secondary-color); }
/* The «впишите ник» callout: must be read BEFORE the player leaves for the
   donate page, hence inside step 1, above its button. */
.pv-pay__important {
  display: flex;
  gap: 0.7rem;
  margin: 0.9rem 0 1rem;
  padding: 0.85rem 1rem;
  border-radius: 0.7rem;
  border: 1px solid rgba(255, 180, 84, 0.4);
  background: rgba(255, 180, 84, 0.07);
}
.pv-pay__important > i { flex: 0 0 auto; color: #ffb454; font-size: 1.05rem; margin-top: 0.1rem; }
.pv-pay__important p { margin: 0 0 0.45rem; }
.pv-pay__important p:last-child { margin-bottom: 0; }
/* Donate row: the primary button + the «не подходит способ оплаты?» disclosure
   (native <details> — no JS, CSP-friendly). */
.pv-pay__actions { display: flex; align-items: baseline; gap: 0.4rem 1.1rem; flex-wrap: wrap; }
.pv-pay__alt summary {
  cursor: pointer;
  list-style: none; /* the bi-question-circle icon replaces the triangle marker */
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
  text-decoration: underline dotted;
  text-underline-offset: 0.2em;
}
.pv-pay__alt summary::-webkit-details-marker { display: none; }
.pv-pay__alt summary:hover { color: var(--lg-accent); }
.pv-pay__alt p {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
  max-width: 36rem;
}
/* Auth-method picker: reuses the plan-picker card mechanics (.pv-pick) with a
   neutral accent skin — all three options are equal, teal marks the choice. */
.pv-pick--auth .pv-pick__card { min-width: 12.5rem; padding-right: 2.2rem; }
.pv-pick--auth .pv-pick__ic { color: var(--lg-accent); background: rgba(var(--lg-accent-rgb), 0.1); }
.pv-pick--auth .pv-pick__card::after { background: var(--lg-accent); color: #06231f; }
.pv-pick--auth .pv-pick__input:checked + .pv-pick__card {
  border-color: rgba(var(--lg-accent-rgb), 0.65);
  box-shadow: 0 0 0 1px rgba(var(--lg-accent-rgb), 0.55), 0 0.35rem 1.2rem rgba(var(--lg-accent-rgb), 0.13);
  background: linear-gradient(160deg, rgba(var(--lg-accent-rgb), 0.09), transparent 55%), var(--lg-surface);
}
.pv-auth__row {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 1rem 1.4rem;
  margin-top: 0.8rem;
  padding: 0.9rem 1rem;
  border: 1px dashed var(--bs-border-color-translucent);
  border-radius: 0.6rem;
  max-width: 56rem;
}
.pv-auth__row .form-label { font-size: 0.85rem; margin-bottom: 0.3rem; }
.pv-auth__field { flex: 1 1 16rem; max-width: 24rem; }
/* The method's explanation as a proper panel instead of squeezed form-text. */
.pv-auth__info {
  flex: 1 1 18rem;
  display: flex;
  gap: 0.65rem;
  padding: 0.7rem 0.85rem;
  border-radius: 0.55rem;
  border: 1px solid rgba(var(--lg-accent-rgb), 0.22);
  background: rgba(var(--lg-accent-rgb), 0.05);
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--bs-secondary-color);
}
.pv-auth__info > i { flex: 0 0 auto; color: var(--lg-accent); font-size: 1rem; margin-top: 0.05rem; }
.pv-auth__info p { margin: 0 0 0.45rem; }
.pv-auth__info p:last-child { margin-bottom: 0; }
/* The live «setinfo _pw …» command sample under the password input. */
.pv-auth__cmd { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin: 0.45rem 0 0; }
.pv-auth__cmd code {
  padding: 0.25rem 0.6rem;
  border-radius: 0.45rem;
  background: rgba(var(--lg-accent-rgb), 0.1);
  border: 1px solid rgba(var(--lg-accent-rgb), 0.35);
  color: #7ce8dc;
}
