/* =========================================================================
   CriticalTarkov — dark-first, military-inspired UI.

   Direction handling: this file uses CSS *logical* properties
   (margin-inline-start, padding-block, inset-inline-end, text-align: start …)
   almost everywhere, so the whole layout mirrors automatically under
   `dir="rtl"`. Only genuinely directional artwork — chevrons, arrows, progress
   fills — needs the explicit [dir="rtl"] rules near the bottom.
   ========================================================================= */

/* --- Theme tokens: dark is the default, light is opt-in ------------------ */
:root,
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:            #0d0f0d;
  --bg-elevated:   #141814;
  --bg-panel:      #171c17;
  --bg-inset:      #0a0c0a;
  --bg-hover:      #1e241d;

  --line:          #2a322a;
  --line-strong:   #3b453a;

  --text:          #dfe4dc;
  --text-strong:   #f2f5ef;
  --text-muted:    #8d978a;

  --accent:        #a8b545;   /* olive tracer */
  --accent-strong: #c3d152;
  --accent-ink:    #12160c;
  --accent-soft:   rgba(168, 181, 69, 0.14);

  /* The logo's crit marker. Close to --danger but deliberately its own token:
     the logo must not shift if the error red is ever retuned. */
  --brand-crit:    #e0624a;

  --danger:        #d9614b;
  --danger-soft:   rgba(217, 97, 75, 0.14);
  --warn:          #d9a441;
  --warn-soft:     rgba(217, 164, 65, 0.14);
  --ok:            #6fae6b;
  --ok-soft:       rgba(111, 174, 107, 0.14);
  --info:          #6f9dbd;
  --info-soft:     rgba(111, 157, 189, 0.14);

  --shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  --grain: rgba(255, 255, 255, 0.02);
}

:root[data-theme="light"] {
  color-scheme: light;

  --bg:            #eceee7;
  --bg-elevated:   #f7f8f4;
  --bg-panel:      #ffffff;
  --bg-inset:      #e3e6dd;
  --bg-hover:      #e6e9df;

  --line:          #cdd2c4;
  --line-strong:   #b2b9a6;

  --text:          #2c322a;
  --text-strong:   #171b16;
  --text-muted:    #626a5e;

  --accent:        #6b7a1f;
  --accent-strong: #56631a;
  --accent-ink:    #ffffff;
  --accent-soft:   rgba(107, 122, 31, 0.12);

  --brand-crit:    #b83c26;   /* the dark-theme red goes pink on a pale page */

  --danger:        #b23b26;
  --danger-soft:   rgba(178, 59, 38, 0.10);
  --warn:          #9a6d10;
  --warn-soft:     rgba(154, 109, 16, 0.12);
  --ok:            #3f7a3b;
  --ok-soft:       rgba(63, 122, 59, 0.12);
  --info:          #2f6280;
  --info-soft:     rgba(47, 98, 128, 0.12);

  --shadow: 0 8px 24px rgba(30, 36, 26, 0.10);
  --grain: rgba(0, 0, 0, 0.015);
}

/* --- Reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(180deg, var(--bg-elevated) 0%, var(--bg) 340px),
    var(--bg);
  color: var(--text);
  font-family: "Inter", "Segoe UI", system-ui, -apple-system, "Noto Sans Arabic",
               "Tahoma", "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  overflow-wrap: break-word;
}

:root[lang="ar"] body,
[dir="rtl"] body {
  font-family: "Noto Sans Arabic", "Segoe UI", "Tahoma", "Dubai", system-ui,
               "Arial", sans-serif;
  line-height: 1.85;   /* Arabic script needs more room between lines */
}

img, svg, video { max-width: 100%; height: auto; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent-strong); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 {
  color: var(--text-strong);
  line-height: 1.25;
  margin-block: 0 0.5em;
  font-weight: 650;
  letter-spacing: -0.01em;
}
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3, [dir="rtl"] h4 { letter-spacing: 0; }

h1 { font-size: clamp(1.7rem, 1.2rem + 2vw, 2.5rem); }
h2 { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.7rem); }
h3 { font-size: 1.15rem; }
p { margin-block: 0 1em; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Clipped rather than pushed off-canvas: a large negative inline offset lands
   outside the viewport on the wrong side under `dir="rtl"`. */
.skip-link {
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0;
  z-index: 100;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  padding: 0;
  background: var(--accent);
  color: var(--accent-ink);
  white-space: nowrap;
}
.skip-link:focus {
  width: auto;
  height: auto;
  padding: 0.6rem 1rem;
  clip-path: none;
}

/* --- Layout -------------------------------------------------------------- */
.wrap { width: min(1160px, 100% - 2rem); margin-inline: auto; }
.wrap-narrow { width: min(820px, 100% - 2rem); margin-inline: auto; }
main { flex: 1 0 auto; padding-block-end: 4rem; }

.section-block { padding-block: 2.5rem; }
.stack > * + * { margin-block-start: 1rem; }
.grid { display: grid; gap: 1.1rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }
/* Drips are portrait character shots, so they tile smaller and denser. */
.grid-4 { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.row { display: flex; gap: 0.6rem; flex-wrap: wrap; align-items: center; }
.row-between { display: flex; gap: 1rem; flex-wrap: wrap;
               align-items: center; justify-content: space-between; }
.push-end { margin-inline-start: auto; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.muted { color: var(--text-muted); }
.small { font-size: 0.86rem; }
.tiny  { font-size: 0.78rem; }
.mono  { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
         font-variant-numeric: tabular-nums; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }

/* --- Header -------------------------------------------------------------- */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg-elevated) 92%, transparent);
  backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--line);
}
/* Row one: identity on one side, account controls on the other. Never wraps —
   these are the two things that must stay findable at any width. */
.header-top {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 58px;
}

/* The bilingual lockup. The mark is the axis: Latin reads inward toward it
   from one side and Arabic inward from the other, so TARKOV and تاركوف always
   sit against the marker and the thing mirrors itself.

   `direction: ltr` is load-bearing, not a leftover. A flex row reverses its
   children under [dir="rtl"], which would swap the two halves and hand the
   Arabic pages a visibly different logo — the whole point here is that there
   is one lockup, identical in both directions. Only its position in the header
   flips, which the logical properties already handle. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  direction: ltr;
  color: var(--text-strong);
  min-width: 0;
  /* No `margin-inline-end: auto` here, deliberately. Logical properties resolve
     against the element's *own* direction, and this one is forced to ltr — so
     under [dir="rtl"] that auto margin lands on the leading side and drags the
     logo inward off the edge. `.nav-actions` already claims the free space with
     `margin-inline-start: auto`, and it inherits the page direction, so it
     resolves correctly both ways. */
}
.brand:hover { text-decoration: none; }
.brand-mark {
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  color: var(--brand-crit);
}
.brand-text,
.brand-ar { font-size: 1.02rem; line-height: 1; white-space: nowrap; }
.brand-text {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  /* Tracking is applied after every letter, including the last one. Left in,
     that trailing sliver makes the gap to the mark wider on the Latin side
     than on the Arabic side and the lockup stops looking centred. */
  margin-right: -0.13em;
}
.brand-ar {
  font-family: "Noto Sans Arabic", "Segoe UI", "Tahoma", "Dubai", system-ui, sans-serif;
  font-weight: 700;
}
.brand-text strong,
.brand-ar strong { color: var(--accent); font-weight: inherit; }
.brand-text .brand-word { margin-inline-end: 0.3em; }
.brand-ar .brand-word { margin-inline-end: 0.32em; }

.nav-toggle {
  display: none;
  width: 42px; height: 38px;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  cursor: pointer;
  padding: 9px 10px;
  flex-direction: column;
  justify-content: space-between;
}
.nav-toggle span { display: block; height: 2px; background: var(--text); border-radius: 2px; }

/* Row two: the sections, on a line of their own. */
.primary-nav { border-block-start: 1px solid var(--line); }

/* Scrolls sideways instead of wrapping. Wrapping was what broke the old header
   — the second line of links pushed the account chips down and the whole bar
   changed height depending on how many sections existed. */
.nav-scroll {
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: none;          /* the links are the affordance, not a bar */
}
.nav-scroll::-webkit-scrollbar { display: none; }

/* Edge fades, added by the script only while there is more to scroll to.
   `mask-image` rather than an overlay so the fade works on whatever the sticky
   header's translucent background happens to be sitting over. */
.nav-scroll.has-end {
  mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
}
.nav-scroll.has-start {
  mask-image: linear-gradient(to right, transparent, #000 2.5rem);
}
.nav-scroll.has-start.has-end {
  mask-image: linear-gradient(to right, transparent, #000 2.5rem,
                              #000 calc(100% - 2.5rem), transparent);
}

.nav-list {
  display: flex;
  gap: 0.15rem;
  list-style: none;
  margin: 0;
  padding: 0;
  flex-wrap: nowrap;
}
.nav-link {
  display: block;
  padding: 0.6rem 0.7rem;
  color: var(--text-muted);
  font-size: 0.92rem;
  white-space: nowrap;
  border-block-end: 2px solid transparent;
}
.nav-link:hover { color: var(--text-strong); text-decoration: none; }
/* Underline rather than a pill: it sits on the header's own bottom edge, so
   the current section reads as a tab without adding another boxed shape. */
.nav-link.is-active {
  color: var(--accent-strong);
  border-block-end-color: var(--accent);
}

.nav-actions { display: flex; align-items: center; gap: 0.45rem; margin-inline-start: auto; }

/* --- Chips & buttons ----------------------------------------------------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.65rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--bg-panel);
  color: var(--text);
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}
.chip:hover { background: var(--bg-hover); text-decoration: none; border-color: var(--accent); }
.chip-theme { padding-inline: 0.5rem; }

.icon { width: 1em; height: 1em; fill: none; stroke: currentColor;
        stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
        font-size: 1.05rem; flex: none; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: var(--bg-panel);
  color: var(--text-strong);
  font-weight: 550;
  font-size: 0.94rem;
  cursor: pointer;
  text-align: center;
}
.btn:hover { background: var(--bg-hover); text-decoration: none; border-color: var(--accent); }
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.btn-primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
.btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
.btn-danger:hover { background: var(--danger-soft); border-color: var(--danger); }
.btn-sm { padding: 0.38rem 0.7rem; font-size: 0.86rem; }
.btn-block { width: 100%; }
.btn[disabled], .btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-link {
  background: none; border: none; padding: 0;
  color: var(--accent-strong); cursor: pointer; text-decoration: underline;
}

/* --- Account menu -------------------------------------------------------- */
.account { position: relative; }
.account-name { max-width: 9rem; overflow: hidden; text-overflow: ellipsis; }
.menu {
  position: absolute;
  inset-block-start: calc(100% + 0.4rem);
  inset-inline-end: 0;
  min-width: 190px;
  background: var(--bg-panel);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 0.35rem;
  z-index: 50;
}
.menu a, .menu button {
  display: block;
  width: 100%;
  padding: 0.5rem 0.65rem;
  border: none;
  background: none;
  border-radius: 5px;
  color: var(--text);
  text-align: start;
  font-size: 0.9rem;
  cursor: pointer;
}
.menu a:hover, .menu button:hover { background: var(--bg-hover); text-decoration: none; }
.menu-admin { color: var(--accent-strong); }
.menu-signout { color: var(--danger); }

/* --- Avatars ------------------------------------------------------------- */
.avatar {
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-inset);
  border: 1px solid var(--line-strong);
  flex: none;
}
.avatar-xs { width: 24px; height: 24px; }
.avatar-sm { width: 36px; height: 36px; }
.avatar-md { width: 56px; height: 56px; }
.avatar-lg { width: 96px; height: 96px; }
.avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1;
}
.avatar-lg.avatar-fallback { font-size: 2.2rem; }
.avatar-md.avatar-fallback { font-size: 1.4rem; }

/* --- Flash --------------------------------------------------------------- */
.flash-stack { margin-block-start: 1rem; display: grid; gap: 0.5rem; }
.flash {
  padding: 0.7rem 1rem;
  border-radius: 6px;
  border-inline-start: 3px solid var(--info);
  background: var(--info-soft);
  font-size: 0.92rem;
}
.flash-success { border-color: var(--ok); background: var(--ok-soft); }
.flash-error   { border-color: var(--danger); background: var(--danger-soft); }
.flash-warning { border-color: var(--warn); background: var(--warn-soft); }

/* --- Cards / panels ------------------------------------------------------ */
.panel {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1.25rem;
}
.panel-tight { padding: 0.9rem 1rem; }

.card {
  display: flex;
  flex-direction: column;
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.card:hover { border-color: var(--line-strong); transform: translateY(-2px); }

/* --- Whole-card links -------------------------------------------------------
   One real anchor per card, stretched over the whole thing with a pseudo
   element. Not a click handler on the card: this way the card is a link in
   every sense a link is one — middle-click opens a tab, the status bar shows
   where it goes, ctrl-click works, a screen reader announces one link rather
   than a region full of them, and none of it needs JavaScript.

   Everything in the footer sits above the overlay, so upvoting, opening the
   comments and visiting the author's profile all still do their own thing.
   ------------------------------------------------------------------------- */
.card-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  /* No background: this is a hit area, not a scrim. */
}
/* On memes, drips and rat spots there is no title to stretch, so the picture is
   the link — and `.card-media` is normally `position: relative`, which would
   make the overlay stop at the bottom of the image. Dropping it back to static
   hands the job to `.card`, which is the element we actually want covered.
   `.card-flag` re-anchors to the card as a result and lands in the same place,
   because the media sits flush at the top of the card. */
.card-media.card-link { position: static; }
/* Above the overlay. `position` is what puts them in the same stacking
   context — z-index alone does nothing on a static element. */
.card-foot,
.card .card-pending { position: relative; z-index: 2; }

/* The title reacts to hovering anywhere on the card, because the whole card is
   now the thing you are about to click. */
.card:hover .card-title a { color: var(--accent-strong); }

/* The cost of a stretched link is that dragging across the card selects
   nothing. Card text is a truncated preview of the page it links to, so there
   is nothing here worth copying — but the footer, which holds a real username,
   stays selectable because it sits above the overlay. */
.card-body { padding: 1.05rem 1.15rem; display: flex; flex-direction: column; gap: 0.5rem; flex: 1; }
.card-title { margin: 0; font-size: 1.08rem; }
.card-title a { color: var(--text-strong); }
.card-title a:hover { color: var(--accent-strong); text-decoration: none; }
.card-media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--bg-inset);
  border-block-end: 1px solid var(--line);
  overflow: hidden;
}
/* A PMC is taller than they are wide. */
.card-media-tall { aspect-ratio: 3 / 4; }
.card-media-tall img { object-fit: cover; padding: 0; }
.card-flag {
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
}
/* `contain`, not `cover`: build previews are a mix of wide weapon art and
   16:9 screenshots, and cropping either one loses the point of the picture. */
.card-media img { width: 100%; height: 100%; object-fit: contain; padding: 0.4rem; }
.card-media-empty {
  display: grid;
  place-items: center;
  color: var(--line-strong);
  font-size: 2rem;
}
.card-foot {
  padding: 0.65rem 1.15rem;
  border-block-start: 1px solid var(--line);
  background: var(--bg-elevated);
  display: flex;
  gap: 0.6rem;
  align-items: center;
  font-size: 0.84rem;
}

/* --- Badges -------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  border: 1px solid transparent;
  white-space: nowrap;
}
[dir="rtl"] .badge { letter-spacing: 0; }
.badge-meta   { background: var(--accent-soft); color: var(--accent-strong);
                border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.badge-budget { background: var(--info-soft); color: var(--info);
                border-color: color-mix(in srgb, var(--info) 40%, transparent); }
.badge-neutral{ background: var(--bg-inset); color: var(--text-muted); border-color: var(--line); }
.badge-warn   { background: var(--warn-soft); color: var(--warn);
                border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.badge-ok     { background: var(--ok-soft); color: var(--ok);
                border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
.badge-danger { background: var(--danger-soft); color: var(--danger);
                border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.badge-map    { background: var(--info-soft); color: var(--info);
                border-color: color-mix(in srgb, var(--info) 35%, transparent);
                text-transform: none; letter-spacing: 0; }
.badge-featured { background: var(--warn-soft); color: var(--warn);
                  border-color: color-mix(in srgb, var(--warn) 40%, transparent); }

/* Confidence labels for cultist entries */
.badge-unconfirmed      { background: var(--danger-soft); color: var(--danger);
                          border-color: color-mix(in srgb, var(--danger) 35%, transparent); }
.badge-community_tested { background: var(--warn-soft); color: var(--warn);
                          border-color: color-mix(in srgb, var(--warn) 35%, transparent); }
.badge-high_confidence  { background: var(--ok-soft); color: var(--ok);
                          border-color: color-mix(in srgb, var(--ok) 35%, transparent); }

/* --- Hero ---------------------------------------------------------------- */
.hero {
  position: relative;
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  border-block-end: 1px solid var(--line);
  background-image:
    radial-gradient(1200px 400px at 50% -10%, var(--accent-soft), transparent 70%),
    repeating-linear-gradient(135deg, var(--grain) 0 2px, transparent 2px 9px);
  overflow: hidden;
}
.hero-inner { display: grid; gap: 1.5rem; }
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--accent);
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-block-end: 0.4rem;
}
[dir="rtl"] .eyebrow { letter-spacing: 0; }
.hero h1 { max-width: 20ch; }
.hero-lead { font-size: 1.08rem; color: var(--text-muted); max-width: 62ch; }

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 0.75rem;
  margin-block-start: 0.5rem;
}
.stat {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.8rem 1rem;
}
a.stat { color: inherit; }
a.stat:hover { text-decoration: none; border-color: var(--accent); background: var(--bg-hover); }
.stat-value { font-size: 1.5rem; font-weight: 700; color: var(--accent-strong); line-height: 1.2; }
.stat-label { font-size: 0.78rem; color: var(--text-muted); text-transform: uppercase;
              letter-spacing: 0.08em; }
[dir="rtl"] .stat-label { letter-spacing: 0; }

/* --- Page header --------------------------------------------------------- */
.page-head {
  padding-block: 2rem 1.25rem;
  border-block-end: 1px solid var(--line);
  margin-block-end: 1.75rem;
}
.breadcrumbs { font-size: 0.84rem; color: var(--text-muted); margin-block-end: 0.5rem; }
.breadcrumbs a { color: var(--text-muted); }
.breadcrumbs .sep { margin-inline: 0.4rem; }

/* --- Meta bar (last updated / patch) ------------------------------------- */
.meta-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: center;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.meta-bar .icon { font-size: 1rem; }
.meta-item { display: inline-flex; align-items: center; gap: 0.35rem; }

.stale-notice {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  padding: 0.75rem 1rem;
  border-radius: 8px;
  background: var(--warn-soft);
  border-inline-start: 3px solid var(--warn);
  font-size: 0.9rem;
  margin-block: 1rem;
}

.disclaimer {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 1rem 1.15rem;
  border-radius: 10px;
  background: var(--danger-soft);
  border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent);
  margin-block-end: 1.5rem;
}
.disclaimer .icon { font-size: 1.35rem; color: var(--danger); margin-block-start: 0.15rem; }
.disclaimer p:last-child { margin-block-end: 0; }

/* --- Prose (guide bodies) ------------------------------------------------ */
.prose { font-size: 1.02rem; }
.prose > :first-child { margin-block-start: 0; }
.prose h2 {
  margin-block: 2rem 0.75rem;
  padding-block-end: 0.4rem;
  border-block-end: 1px solid var(--line);
}
.prose h3 { margin-block: 1.5rem 0.5rem; color: var(--accent-strong); }
.prose h4 { margin-block: 1.2rem 0.4rem; }
.prose ul, .prose ol { padding-inline-start: 1.4rem; margin-block: 0 1.1rem; }
.prose li { margin-block-end: 0.4rem; }
.prose img { border-radius: 8px; border: 1px solid var(--line); margin-block: 1rem; }
.prose figure { margin: 1.5rem 0; }
.prose figcaption { font-size: 0.85rem; color: var(--text-muted); margin-block-start: 0.5rem;
                    text-align: center; }
.prose blockquote {
  margin: 1.25rem 0;
  padding: 0.75rem 1.1rem;
  border-inline-start: 3px solid var(--accent);
  background: var(--bg-elevated);
  border-radius: 0 8px 8px 0;
  color: var(--text-muted);
}
[dir="rtl"] .prose blockquote { border-radius: 8px 0 0 8px; }
.prose code {
  background: var(--bg-inset);
  padding: 0.12em 0.4em;
  border-radius: 4px;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.9em;
}
.prose pre {
  background: var(--bg-inset);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1rem;
  overflow-x: auto;
}
.prose hr { border: none; border-block-start: 1px solid var(--line); margin-block: 2rem; }

/* Tables scroll inside their own box rather than the page */
.prose table, .data-table {
  width: 100%;
  border-collapse: collapse;
  margin-block: 1.25rem;
  font-size: 0.94rem;
}
.prose th, .prose td, .data-table th, .data-table td {
  border: 1px solid var(--line);
  padding: 0.55rem 0.75rem;
  text-align: start;
  vertical-align: top;
}
.prose th, .data-table th {
  background: var(--bg-elevated);
  color: var(--text-strong);
  font-weight: 600;
}
.prose tbody tr:nth-child(even), .data-table tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--bg-elevated) 55%, transparent);
}
.table-wrap, .table-scroll { overflow-x: auto; margin-block: 1.25rem; }
.table-wrap table, .table-scroll table { margin-block: 0; }

/* Callouts available to admin-authored content */
.prose .note, .prose .tip, .prose .warning, .prose .danger, .prose .callout {
  padding: 0.85rem 1.1rem;
  border-radius: 8px;
  margin-block: 1.25rem;
  border-inline-start: 3px solid var(--info);
  background: var(--info-soft);
}
.prose .tip     { border-color: var(--ok);     background: var(--ok-soft); }
.prose .warning { border-color: var(--warn);   background: var(--warn-soft); }
.prose .danger  { border-color: var(--danger); background: var(--danger-soft); }
.prose .note > :last-child, .prose .tip > :last-child,
.prose .warning > :last-child, .prose .danger > :last-child,
.prose .callout > :last-child { margin-block-end: 0; }

/* Numbered walkthroughs */
.prose ol.steps { list-style: none; counter-reset: step; padding-inline-start: 0; }
.prose ol.steps > li {
  counter-increment: step;
  position: relative;
  padding-inline-start: 2.75rem;
  margin-block-end: 1.1rem;
  min-height: 2rem;
}
.prose ol.steps > li::before {
  content: counter(step);
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0;
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent-strong);
  font-weight: 700;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

/* Interactive checklists — JS turns these into persisted checkboxes */
.prose ul.checklist { list-style: none; padding-inline-start: 0; }
.prose ul.checklist > li {
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-block-end: 0.5rem;
  background: var(--bg-elevated);
}
.checklist-item { display: flex; gap: 0.7rem; align-items: flex-start;
                  padding: 0.65rem 0.9rem; cursor: pointer; }
.checklist-item input { margin-block-start: 0.28rem; accent-color: var(--accent);
                        width: 1.05rem; height: 1.05rem; flex: none; cursor: pointer; }
.prose ul.checklist > li:has(input:checked) { opacity: 0.6; background: var(--ok-soft);
                                              border-color: color-mix(in srgb, var(--ok) 30%, var(--line)); }
.prose ul.checklist > li:has(input:checked) .checklist-text { text-decoration: line-through; }
.checklist-progress {
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  padding: 0.7rem 0.9rem; margin-block: 1rem;
  background: var(--bg-elevated); border: 1px solid var(--line); border-radius: 8px;
  font-size: 0.88rem;
  position: sticky; inset-block-start: 70px; z-index: 5;
}
.checklist-bar { flex: 1; min-width: 6rem; height: 7px; border-radius: 99px;
                 background: var(--bg-inset); overflow: hidden; }
.checklist-bar > span { display: block; height: 100%; background: var(--accent);
                        border-radius: 99px; transition: width 0.2s ease; }
.checklist-status:empty { display: none; }
.checklist-saved { color: var(--ok); }
.checklist-failed { color: var(--danger); }

/* Item artwork under a checklist entry */
.prose .checklist-text .item-icon {
  display: block;
  width: auto;
  max-width: 96px;
  max-height: 72px;
  margin-block: 0.4rem 0.1rem;
  margin-inline: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-inset);
  padding: 0.2rem;
  object-fit: contain;
  image-rendering: -webkit-optimize-contrast;
}
.prose ul.checklist > li:has(input:checked) .item-icon { filter: grayscale(1); }

/* "Sign in to save your progress" prompt above an anonymous reader's checklist */
.checklist-signin {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
  padding: 0.85rem 1rem;
  margin-block: 1.25rem 0.75rem;
  border-radius: 8px;
  background: var(--info-soft);
  border: 1px solid color-mix(in srgb, var(--info) 35%, transparent);
  border-inline-start: 3px solid var(--info);
}
.checklist-signin > .icon { font-size: 1.3rem; color: var(--info); flex: none; }
.checklist-signin > div { flex: 1; min-width: 12rem; }
.checklist-signin p { margin: 0.15rem 0 0; color: var(--text-muted); }
.checklist-signin .btn { flex: none; }

/* --- Task chains ---------------------------------------------------------
   A numbered sequence of quests, each linking out to the wiki. The connector
   line uses inset-inline-start so it moves to the right-hand side under RTL.
   ------------------------------------------------------------------------- */
.prose ol.task-chain {
  list-style: none;
  counter-reset: task;
  padding-inline-start: 0;
  margin-block: 1.5rem;
  position: relative;
}
.prose ol.task-chain > li {
  counter-increment: task;
  position: relative;
  padding-inline-start: 3rem;
  padding-block: 0.35rem 1.1rem;
  margin: 0;
}
/* connector running between the node markers */
.prose ol.task-chain > li::after {
  content: "";
  position: absolute;
  inset-inline-start: 1.03rem;
  inset-block-start: 2.3rem;
  bottom: -0.35rem;
  width: 2px;
  background: linear-gradient(180deg, var(--accent) 0%, var(--line-strong) 100%);
  opacity: 0.55;
}
.prose ol.task-chain > li:last-child::after { display: none; }
.prose ol.task-chain > li::before {
  content: counter(task);
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.15rem;
  width: 2.1rem;
  height: 2.1rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--bg-panel);
  border: 2px solid var(--accent);
  color: var(--accent-strong);
  font-weight: 700;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  z-index: 1;
}
.prose ol.task-chain > li > a:first-child {
  display: inline-block;
  font-weight: 650;
  font-size: 1.02rem;
  color: var(--text-strong);
  border-block-end: 1px dashed color-mix(in srgb, var(--accent) 55%, transparent);
}
.prose ol.task-chain > li > a:first-child:hover {
  color: var(--accent-strong);
  text-decoration: none;
  border-block-end-style: solid;
}
.prose ol.task-chain > li > a:first-child::after {
  content: "↗";
  font-size: 0.75em;
  margin-inline-start: 0.3rem;
  opacity: 0.65;
}
[dir="rtl"] .prose ol.task-chain > li > a:first-child::after { content: "↖"; }

.task-meta {
  display: block;
  font-size: 0.86rem;
  color: var(--text-muted);
  margin-block-start: 0.15rem;
}
.task-note {
  display: block;
  font-size: 0.86rem;
  margin-block-start: 0.3rem;
  padding: 0.4rem 0.7rem;
  border-radius: 6px;
  background: var(--bg-inset);
  border-inline-start: 2px solid var(--line-strong);
}
/* A hard prerequisite between two steps. */
.prose .task-gate {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-block: 1.25rem;
  padding: 0.55rem 0.9rem;
  border-radius: 6px;
  background: var(--warn-soft);
  border: 1px dashed color-mix(in srgb, var(--warn) 50%, transparent);
  font-size: 0.9rem;
}
.prose .task-gate::before { content: "⚑"; color: var(--warn); }

/* --- Branching flow chart (the endings decision tree) --------------------- */
.prose .flow { margin-block: 1.75rem; }
.prose .flow-node {
  position: relative;
  padding: 0.75rem 1rem;
  margin-block-end: 1.9rem;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--bg-panel);
}
/* the arrow joining one node to the next */
.prose .flow-node::after {
  content: "▼";
  position: absolute;
  inset-block-end: -1.5rem;
  inset-inline-start: 1.4rem;
  color: var(--accent);
  font-size: 0.8rem;
  opacity: 0.8;
}
.prose .flow-node:last-child::after { display: none; }
.prose .flow-node > :last-child { margin-block-end: 0; }

.prose .flow-start {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.prose .flow-decision {
  border-style: dashed;
  border-color: var(--warn);
  background: var(--warn-soft);
}
.prose .flow-decision > strong { color: var(--warn); }
.prose .flow-end { border-color: var(--ok); background: var(--ok-soft); }

.prose .flow-branches {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin-block-end: 1.5rem;
}
.prose .flow-branch {
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  padding: 0.9rem 1rem;
  background: var(--bg-elevated);
  border-block-start: 3px solid var(--line-strong);
}
.prose .flow-branch-head {
  font-weight: 700;
  font-size: 1.02rem;
  margin-block-end: 0.4rem;
  color: var(--text-strong);
}
.prose ol.flow-steps, .prose ul.flow-steps {
  padding-inline-start: 1.15rem;
  margin-block-end: 0;
  font-size: 0.92rem;
}
.prose .flow-steps > li { margin-block-end: 0.35rem; }

/* Ending emblems: inline with the branch label, larger beside the section heading. */
.prose .ending-logo {
  display: inline-block;
  width: 2.6rem;
  height: 2.6rem;
  margin: 0;
  margin-inline-end: 0.55rem;
  vertical-align: -0.8rem;
  object-fit: contain;
  border: none;
  border-radius: 0;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
}
.prose .flow-branch-head {
  display: flex;
  align-items: center;
  gap: 0;
}
.prose .flow-branch-head .ending-logo { vertical-align: middle; flex: none; }

.prose h3.ending-heading {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  margin-block-start: 2.25rem;
}
.prose h3.ending-heading .ending-logo {
  width: 3.4rem;
  height: 3.4rem;
  vertical-align: middle;
  flex: none;
}

/* Each ending gets its own accent so the four routes are tellable apart. */
.prose .outcome-savior   { border-block-start-color: var(--ok); }
.prose .outcome-savior   .flow-branch-head { color: var(--ok); }
.prose .outcome-survivor { border-block-start-color: var(--info); }
.prose .outcome-survivor .flow-branch-head { color: var(--info); }
.prose .outcome-debtor   { border-block-start-color: var(--warn); }
.prose .outcome-debtor   .flow-branch-head { color: var(--warn); }
.prose .outcome-fallen   { border-block-start-color: var(--danger); }
.prose .outcome-fallen   .flow-branch-head { color: var(--danger); }

/* Responsive video embeds */
.prose iframe, .video-embed iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-block: 1.25rem;
  background: var(--bg-inset);
}

/* --- Table of contents / side rail --------------------------------------- */
.guide-layout { display: grid; gap: 2rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1000px) {
  .guide-layout { grid-template-columns: minmax(0, 1fr) 250px; align-items: start; }
  .guide-rail { position: sticky; inset-block-start: 82px; }
}
.rail-title { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.1em;
              color: var(--text-muted); margin-block-end: 0.6rem; }
[dir="rtl"] .rail-title { letter-spacing: 0; }
.rail-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.15rem; }
.rail-list a { display: block; padding: 0.35rem 0.6rem; border-radius: 5px;
               font-size: 0.88rem; color: var(--text); border-inline-start: 2px solid transparent; }
.rail-list a:hover { background: var(--bg-hover); text-decoration: none; }
.rail-list a.is-active { color: var(--accent-strong); border-inline-start-color: var(--accent);
                         background: var(--accent-soft); }

/* --- Forms --------------------------------------------------------------- */
.form-grid { display: grid; gap: 1.1rem; }
.form-row { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.field { display: grid; gap: 0.35rem; }
.field > label, .field-label { font-size: 0.88rem; font-weight: 600; color: var(--text-strong); }
.field .hint { font-size: 0.8rem; color: var(--text-muted); }
.req { color: var(--danger); }
.opt { color: var(--text-muted); font-weight: 400; font-size: 0.82em; }

input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="date"], input[type="search"], select, textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  background: var(--bg-inset);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  color: var(--text);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  outline: 2px solid var(--accent-soft);
  outline-offset: 0;
}
textarea { min-height: 120px; resize: vertical; line-height: 1.6; }
textarea.code { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
                font-size: 0.9rem; min-height: 300px; }
input[type="file"] { padding: 0.45rem; background: var(--bg-inset);
                     border: 1px dashed var(--line-strong); border-radius: 6px; width: 100%; }
select { appearance: none; background-image: none; }

.check { display: flex; gap: 0.55rem; align-items: center; font-size: 0.92rem; cursor: pointer; }
.check input { accent-color: var(--accent); width: 1.05rem; height: 1.05rem; cursor: pointer; }

.radio-cards { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.radio-card {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--bg-inset);
  cursor: pointer;
}
.radio-card input { accent-color: var(--accent); }
.radio-card:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--text-strong);
}

.errors {
  padding: 0.8rem 1rem 0.8rem 1rem;
  border-radius: 8px;
  background: var(--danger-soft);
  border-inline-start: 3px solid var(--danger);
  margin-block-end: 1.25rem;
}
.errors ul { margin: 0; padding-inline-start: 1.1rem; }
.form-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; align-items: center;
                padding-block-start: 0.5rem; }

/* Bilingual editor: EN and AR fields side by side */
.bilingual { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.lang-field { border: 1px solid var(--line); border-radius: 8px; padding: 0.85rem; background: var(--bg-elevated); }
.lang-field > .field-label { display: flex; align-items: center; gap: 0.45rem; margin-block-end: 0.4rem; }
.lang-tag { font-size: 0.7rem; padding: 0.1rem 0.4rem; border-radius: 4px;
            background: var(--accent-soft); color: var(--accent-strong); font-weight: 700; }
.lang-field[data-lang="ar"] textarea, .lang-field[data-lang="ar"] input { direction: rtl; text-align: right; }
.lang-field[data-lang="ar"] textarea.code { direction: ltr; text-align: left; }
.lang-field[data-lang="en"] textarea, .lang-field[data-lang="en"] input { direction: ltr; text-align: left; }

/* --- Toolbar for the rich-content editor --------------------------------- */
.editor-toolbar { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-block-end: 0.4rem; }
.editor-toolbar button {
  padding: 0.25rem 0.55rem;
  font-size: 0.78rem;
  border: 1px solid var(--line-strong);
  border-radius: 5px;
  background: var(--bg-panel);
  cursor: pointer;
}
.editor-toolbar button:hover { background: var(--bg-hover); border-color: var(--accent); }

/* --- Toolbar / filters --------------------------------------------------- */
.toolbar {
  display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center;
  padding: 0.75rem 1rem;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-block-end: 1.5rem;
}
.filter-group { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.filter {
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 0.85rem;
  color: var(--text);
  background: var(--bg-panel);
}
.filter:hover { border-color: var(--accent); text-decoration: none; }
.filter.is-active { background: var(--accent); border-color: var(--accent);
                    color: var(--accent-ink); font-weight: 600; }

/* --- Vote button --------------------------------------------------------- */
.vote {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  min-width: 3.1rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--bg-inset);
  color: var(--text);
  cursor: pointer;
  line-height: 1.15;
}
.vote:hover { border-color: var(--accent); background: var(--bg-hover); text-decoration: none; }
.vote .icon { font-size: 1.1rem; }
.vote-count { font-weight: 700; font-variant-numeric: tabular-nums; font-size: 0.95rem; }
.vote.is-voted { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong); }
.vote[disabled] { cursor: default; opacity: 0.75; }
/* Own build: the count still shows, but nothing here is clickable. */
.vote.is-disabled { cursor: default; opacity: 0.6; }
.vote.is-disabled:hover { border-color: var(--line-strong); background: var(--bg-inset); }

/* --- Build specifics ----------------------------------------------------- */
.build-head { display: flex; gap: 1rem; align-items: flex-start; flex-wrap: wrap; }
.spec-grid { display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.spec {
  background: var(--bg-inset);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
}
.spec-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.07em;
              color: var(--text-muted); }
[dir="rtl"] .spec-label { letter-spacing: 0; }
.spec-value { font-size: 1.15rem; font-weight: 700; color: var(--text-strong);
              font-variant-numeric: tabular-nums; }

/* --- Zoomable build screenshot ------------------------------------------- */
.zoomable {
  display: block;
  position: relative;
  border-radius: 10px;
  border: 1px solid var(--line);
  overflow: hidden;
  cursor: zoom-in;
}
.zoomable:hover { border-color: var(--accent); text-decoration: none; }
.zoomable img { width: 100%; display: block; }
.zoom-cue {
  position: absolute;
  inset-block-end: 0.6rem;
  inset-inline-end: 0.6rem;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  border: 1px solid var(--line-strong);
  color: var(--text);
  font-size: 0.78rem;
  backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity 0.15s ease;
}
.zoomable:hover .zoom-cue,
.zoomable:focus-visible .zoom-cue { opacity: 1; }
/* Touch devices have no hover, so keep the hint permanently visible there. */
@media (hover: none) {
  .zoom-cue { opacity: 1; }
}

/* --- Lightbox ------------------------------------------------------------ */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(0, 0, 0, 0.88);
  backdrop-filter: blur(3px);
  overflow: auto;
  overscroll-behavior: contain;
}
.lightbox img {
  max-width: 100%;
  max-height: calc(100vh - 3rem);
  width: auto;
  border-radius: 6px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
  cursor: zoom-in;
}
/* Actual-size mode: let the image overflow so it can be scrolled and read. */
.lightbox.is-actual-size { align-items: flex-start; justify-content: flex-start; }
.lightbox.is-actual-size img {
  max-width: none;
  max-height: none;
  width: auto;
  cursor: zoom-out;
  margin: auto;
}
.lightbox-close {
  position: fixed;
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--bg-panel);
  color: var(--text-strong);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  z-index: 1;
}
.lightbox-close:hover { border-color: var(--accent); color: var(--accent-strong); }
.lightbox-hint {
  position: fixed;
  inset-block-end: 1rem;
  inset-inline: 0;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.8rem;
  pointer-events: none;
}
body.lightbox-open { overflow: hidden; }

/* Mini profile card shown next to user content */
.mini-profile {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  padding: 0.8rem 1rem;
  background: var(--bg-inset);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.mini-profile .name { font-weight: 600; color: var(--text-strong); }
.mini-profile .meta { font-size: 0.8rem; color: var(--text-muted); }

/* --- Cultist helper ------------------------------------------------------ */
.combobox { position: relative; }
.combobox-list {
  position: absolute;
  inset-block-start: calc(100% + 4px);
  inset-inline: 0;
  z-index: 30;
  max-height: 260px;
  overflow-y: auto;
  background: var(--bg-panel);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  box-shadow: var(--shadow);
  list-style: none;
  margin: 0;
  padding: 0.25rem;
}
.combobox-list li { border-radius: 5px; }
.combobox-list button {
  display: flex; justify-content: space-between; gap: 0.75rem; width: 100%;
  padding: 0.5rem 0.6rem; background: none; border: none; border-radius: 5px;
  text-align: start; cursor: pointer; font-size: 0.9rem;
}
.combobox-list button:hover, .combobox-list li.is-highlighted button {
  background: var(--accent-soft); color: var(--accent-strong);
}
.combobox-empty { padding: 0.6rem; color: var(--text-muted); font-size: 0.88rem; }

.entry {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-panel);
  padding: 1.1rem 1.2rem;
}
.entry + .entry { margin-block-start: 0.9rem; }
.entry-head { display: flex; gap: 0.75rem; align-items: flex-start;
              justify-content: space-between; flex-wrap: wrap; }
.item-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-block: 0.6rem; }
.item-tag {
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--bg-inset);
  font-size: 0.82rem;
  color: var(--text);
}
.item-tag:hover { border-color: var(--accent); color: var(--accent-strong); text-decoration: none; }
.entry-outcome {
  padding: 0.6rem 0.85rem;
  border-radius: 6px;
  background: var(--accent-soft);
  border-inline-start: 3px solid var(--accent);
  margin-block: 0.6rem;
}
.source-note { font-size: 0.82rem; color: var(--text-muted); }

/* --- Empty state --------------------------------------------------------- */
.empty {
  text-align: center;
  padding: 3rem 1.5rem;
  border: 1px dashed var(--line-strong);
  border-radius: 10px;
  color: var(--text-muted);
  background: var(--bg-elevated);
}
.empty .icon { font-size: 2.25rem; margin-block-end: 0.5rem; color: var(--line-strong); }

/* --- Admin --------------------------------------------------------------- */
.admin-layout { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) {
  .admin-layout { grid-template-columns: 210px minmax(0, 1fr); align-items: start; }
  .admin-nav { position: sticky; inset-block-start: 82px; }
}
.admin-nav { display: grid; gap: 0.2rem; }
.admin-nav a {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 0.75rem; border-radius: 6px;
  color: var(--text); font-size: 0.92rem;
  border-inline-start: 2px solid transparent;
}
.admin-nav a:hover { background: var(--bg-hover); text-decoration: none; }
.admin-nav a.is-active { background: var(--accent-soft); color: var(--accent-strong);
                         border-inline-start-color: var(--accent); }
.admin-nav-label {
  margin: 0.7rem 0 0.15rem; padding-inline: 0.75rem;
  color: var(--text-muted); font-size: 0.7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.09em;
}
/* Arabic has no upper case, and letter-spacing pulls a joined script apart. */
[dir="rtl"] .admin-nav-label { text-transform: none; letter-spacing: 0; font-size: 0.76rem; }

.admin-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.admin-table th, .admin-table td {
  padding: 0.6rem 0.7rem;
  border-block-end: 1px solid var(--line);
  text-align: start;
  vertical-align: middle;
}
.admin-table th { color: var(--text-muted); font-size: 0.76rem; text-transform: uppercase;
                  letter-spacing: 0.07em; font-weight: 600; }
[dir="rtl"] .admin-table th { letter-spacing: 0; }
.admin-table tbody tr:hover { background: var(--bg-hover); }
.admin-table .actions { display: flex; gap: 0.3rem; flex-wrap: wrap; justify-content: flex-end; }
.inline-form { display: inline; }

.dash-grid { display: grid; gap: 0.9rem; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* The restore panel. A red edge because it is the one control on the site that
   cannot be undone by clicking it again — it should not look like the panel
   above it, which only downloads a file. */
.danger-panel { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
.danger-panel h2 { color: var(--danger); }

/* --- Footer ---------------------------------------------------------------
   Just the brand line now: the language switcher and section links both live in
   the header, and duplicating them down here earned nothing.
   ------------------------------------------------------------------------- */
.site-footer {
  margin-block-start: auto;
  padding-block: 1.75rem;
  border-block-start: 1px solid var(--line);
  background: var(--bg-elevated);
}
.footer-inner {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 0.5rem 1.5rem;
}
.footer-meta { display: flex; align-items: center; gap: 0.6rem; margin: 0; }
.footer-brand { display: flex; align-items: center; gap: 0.75rem; }
.footer-brand .brand-mark { width: 1.9rem; height: 1.9rem; }
.footer-title {
  margin: 0;
  color: var(--text-strong);
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
[dir="rtl"] .footer-title { letter-spacing: 0; }
.footer-brand .muted { margin: 0.1rem 0 0; }

@media (max-width: 480px) {
  .footer-brand { flex-direction: column; text-align: center; gap: 0.5rem; }
}

/* Sits above a post written in the other language. Quiet on purpose — it is a
   note about the text, not a warning about it. */
.lang-note {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-block: 0 0.75rem;
  padding: 0.5rem 0.7rem;
  border: 1px dashed var(--line-strong);
  border-radius: 8px;
  color: var(--text-muted);
}
.lang-note .icon { flex: none; inline-size: 1rem; block-size: 1rem; }

/* --- Comments on a profile ------------------------------------------------
   A list, not a grid of cards: a comment is a line of text, and giving each one
   a card would say it carries the same weight as a build with a screenshot.
   ------------------------------------------------------------------------- */
.profile-comments { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.profile-comment {
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--line-strong);
  border-radius: 8px;
  background: var(--bg-panel);
}
.profile-comment:hover { border-inline-start-color: var(--accent); }
.profile-comment .eyebrow { margin: 0 0 0.3rem; }
.profile-comment-body {
  display: block;
  color: var(--text);
  font-size: 0.94rem;
  /* The whole quote is the link to the comment in context. */
  text-decoration: none;
}
.profile-comment-body:hover { color: var(--text-strong); text-decoration: none; }

/* --- My submissions -------------------------------------------------------
   The page a rejection needs, and the mark that tells you to come to it.
   ------------------------------------------------------------------------- */
.submission-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.submission {
  display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-elevated);
}
.submission-main { flex: 1; min-width: 0; }
.submission-title { margin: 0; font-size: 1rem; }
.submission-title a { color: var(--text-strong); }
.submission-actions { flex: none; }
.profile-own-note { margin-block: 0.75rem 0; }

/* A dot on the account chip. Deliberately not a number: the count is one click
   away in the menu, and a badge with a digit in the header reads as urgent in a
   way that "an admin has a note for you" is not. */
.attention-dot {
  inline-size: 0.5rem; block-size: 0.5rem;
  border-radius: 50%;
  background: var(--danger);
  flex: none;
  /* A ring so it stays visible against the chip in either theme. */
  box-shadow: 0 0 0 2px var(--bg-panel);
}
.menu-attention { color: var(--danger); font-weight: 600; }

/* --- About --------------------------------------------------------------- */
.about-card + .about-card { margin-block-start: 1.25rem; }
.about-card h2 { font-size: 1.1rem; margin-block: 0 0.75rem; }
.about-list { display: grid; gap: 0.6rem; margin: 0; }
.about-list > div {
  display: grid; grid-template-columns: 8rem 1fr; gap: 0.5rem 1rem; align-items: baseline;
}
.about-list dt { color: var(--text-muted); font-size: 0.86rem; }
.about-list dd { margin: 0; }
@media (max-width: 30rem) {
  .about-list > div { grid-template-columns: 1fr; gap: 0.1rem; }
}

/* --- Pagination ---------------------------------------------------------- */
.pagination { display: flex; gap: 0.5rem; justify-content: center; align-items: center;
              margin-block-start: 2rem; }

/* =========================================================================
   Directional corrections — everything else mirrors via logical properties.
   ========================================================================= */
[dir="rtl"] .icon-flip,
[dir="rtl"] .pagination .icon,
[dir="rtl"] .breadcrumbs .icon { transform: scaleX(-1); }

[dir="rtl"] .admin-table .actions { justify-content: flex-start; }

/* Numbers stay LTR inside RTL text so "1,250,000 ₽" reads correctly. */
[dir="rtl"] .mono,
[dir="rtl"] .spec-value,
[dir="rtl"] .stat-value,
[dir="rtl"] .vote-count { direction: ltr; unicode-bidi: isolate; }

/* --- Landing-page section directory --------------------------------------
   Every section in one glance. Deliberately compact — the previews below it
   are where the actual content lives. */
.section-grid {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
}

.section-tile {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-panel);
  color: inherit;
}
.section-tile:hover {
  border-color: var(--accent);
  background: var(--bg-elevated);
  text-decoration: none;
}

.section-tile-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent-strong);
}
.section-tile-icon .icon { width: 1.25rem; height: 1.25rem; }

.section-tile-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.section-tile-title { font-weight: 600; color: var(--text-strong); }
.section-tile-desc {
  font-size: 0.82rem;
  color: var(--text-muted);
  /* Two lines then ellipsis, so tiles in a row stay the same height. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.section-tile-count {
  margin-inline-start: auto;
  flex: none;
  align-self: flex-start;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  background: var(--bg-inset);
  border: 1px solid var(--line);
  color: var(--text-muted);
  font-size: 0.78rem;
}

/* --- /post chooser -------------------------------------------------------
   Taller than the landing-page directory tiles, because each one carries the
   list of what its form will ask for. */
.post-grid { display: grid; gap: 0.75rem; }

.post-tile {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-panel);
  color: inherit;
}
.post-tile:hover {
  border-color: var(--accent);
  background: var(--bg-elevated);
  text-decoration: none;
}
.post-tile-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--accent-strong);
}
.post-tile-icon .icon { width: 1.4rem; height: 1.4rem; }
.post-tile-body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.post-tile-title { font-weight: 600; font-size: 1.05rem; color: var(--text-strong); }
.post-tile-needs { font-size: 0.85rem; color: var(--text-muted); }
/* `icon-flip` already mirrors the chevron in RTL; this only parks it at the end. */
.post-tile-go { margin-inline-start: auto; flex: none; color: var(--text-muted); }
.post-tile:hover .post-tile-go { color: var(--accent-strong); }

/* --- Landing-page code strip --------------------------------------------- */
.code-strip { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.code-chip {
  padding: 0.25rem 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--line-strong);
  background: var(--bg-inset);
  color: var(--accent-strong);
  font-weight: 700;
  letter-spacing: 0.05em;
  font-size: 0.88rem;
}
.code-chip:hover { border-color: var(--accent); text-decoration: none; }

.join-panel { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }

/* --- Scav's Eye ----------------------------------------------------------
   The whole game is two submit buttons, so the card *is* the button. */
.streak { text-align: center; flex: none; }
.streak-value { display: block; font-size: 2.4rem; font-weight: 700; color: var(--accent-strong); line-height: 1; }
.streak-label {
  font-size: 0.72rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.pick-grid {
  display: grid;
  gap: 0.9rem;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  margin-block-start: 1.5rem;
}
.pick { margin: 0; }
.pick-versus {
  font-size: 0.8rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.pick-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  padding: 1.4rem 1rem;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--bg-panel);
  color: var(--text);
  cursor: pointer;
  text-align: center;
}
.pick-card:hover { border-color: var(--accent); background: var(--bg-elevated); }
.pick-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pick-media { display: grid; place-items: center; height: 120px; }
.pick-media img { max-height: 120px; max-width: 100%; object-fit: contain; }
.pick-name { font-weight: 600; font-size: 1.02rem; color: var(--text-strong); }
.pick-cta {
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.pick-card:hover .pick-cta { color: var(--accent-strong); }

.shared-player {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-block-end: 0.5rem;
  font-weight: 600;
  color: var(--text-strong);
}
.shared-player:hover { color: var(--accent-strong); text-decoration: none; }

/* --- Landing-page game panel --------------------------------------------- */
.game-promo {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  align-items: center;
}
.game-promo-copy { min-width: 0; }
.game-promo-board { min-width: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.game-promo-board .podium-list { border-color: var(--line-strong); }
.game-promo-board .podium-row { background: var(--bg-inset); }

@media (max-width: 720px) {
  .game-promo { grid-template-columns: 1fr; }
}

/* --- Top players, shown under the game ----------------------------------- */
.podium { margin-block-start: 2.5rem; }
.podium-title { font-size: 1.05rem; margin: 0; }
.podium-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}
.podium-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.85rem;
  background: var(--bg-panel);
  border-block-start: 1px solid var(--line);
  font-size: 0.9rem;
}
.podium-row:first-child { border-block-start: none; }
.podium-row.is-me { background: var(--accent-soft); }
.podium-place {
  width: 1.6rem;
  flex: none;
  color: var(--text-muted);
  font-size: 0.82rem;
}
/* The three that actually get awarded. */
.podium-row:nth-child(1) .podium-place { color: var(--accent-strong); font-weight: 700; }
.podium-row:nth-child(2) .podium-place,
.podium-row:nth-child(3) .podium-place { color: var(--text); font-weight: 600; }

.podium-player { display: inline-flex; align-items: center; gap: 0.45rem; color: inherit; min-width: 0; }
.podium-player span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.podium-streak {
  margin-inline-start: auto;
  font-weight: 700;
  color: var(--accent-strong);
}
.podium-time { flex: none; width: 3.2rem; text-align: end; color: var(--text-muted); font-size: 0.82rem; }

.claim-panel {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
  margin-block-start: 1.25rem;
  border-color: var(--accent);
}
.claim-panel h2 { font-size: 1.15rem; }
.claim-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-inline-start: auto; }

.result-rank { margin-block-start: 0.75rem; font-weight: 600; color: var(--accent-strong); }
.result-rank.muted { color: var(--text-muted); font-weight: 400; font-size: 0.9rem; }

.lb-table td, .lb-table th { vertical-align: middle; }
.lb-table .rank { width: 3rem; color: var(--text-muted); }
.lb-table .lb-streak { font-size: 1.05rem; font-weight: 700; color: var(--accent-strong); }
.lb-player { display: inline-flex; align-items: center; gap: 0.5rem; }
.lb-table tr.is-me { background: var(--accent-soft); }

.result-panel { padding-block: 2rem; }
.result-score { font-size: 4rem; font-weight: 700; line-height: 1; color: var(--accent-strong); }
.result-label { color: var(--text-muted); margin-block-start: 0.35rem; }

.answer-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.answer {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-panel);
  text-align: center;
}
.answer img { max-height: 90px; object-fit: contain; }
.answer-name { font-weight: 600; margin-block: 0.5rem 0.25rem; }
.answer-price { font-size: 1.2rem; color: var(--text-strong); }
/* Green for the right answer, red outline for what they actually chose. */
.answer.is-dearer { border-color: var(--ok); background: var(--ok-soft); }
.answer.is-picked:not(.is-dearer) { border-color: var(--danger); background: var(--danger-soft); }

@media (max-width: 640px) {
  .pick-grid { grid-template-columns: 1fr; }
  .pick-versus { justify-self: center; }
  .pick-media { height: 90px; }
  .pick-media img { max-height: 90px; }
}

/* --- Share bar ----------------------------------------------------------- */
.share {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding-block-start: 1.25rem;
  margin-block-start: 1.25rem;
  border-block-start: 1px solid var(--line);
}
.share-label {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-inline-end: 0.15rem;
}
.share-link {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  background: var(--bg-inset);
  color: var(--text-muted);
}
.share-link:hover {
  border-color: var(--accent);
  color: var(--accent-strong);
  text-decoration: none;
}
.share-link .icon { width: 1.05rem; height: 1.05rem; }

/* --- Memes ---------------------------------------------------------------
   Memes come in every aspect ratio, so the tile is a fixed 4:3 window and the
   image is `contain`ed inside it — cropping a meme can cut off the punchline. */
.card-media-meme { aspect-ratio: 4 / 3; }
.card-media-meme img { object-fit: contain; padding: 0.3rem; }
.credit-line { font-style: italic; }

/* --- Comments ------------------------------------------------------------ */
.comments { margin-block-start: 2.5rem; }
.comment-list { list-style: none; margin: 0 0 1.5rem; padding: 0; }
.comment {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding-block: 1rem;
  border-block-start: 1px solid var(--line);
}
.comment:first-child { border-block-start: none; }
.comment-body { flex: 1; min-width: 0; }
.comment-head {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
  margin: 0 0 0.35rem;
}
.comment-head .name { font-weight: 600; color: var(--text-strong); }
.comment .prose { font-size: 0.94rem; }
.comment .prose p { margin-block: 0 0.5rem; }
.comment .prose p:last-child { margin-block-end: 0; }
/* Hidden comments are only rendered for moderators; make that obvious. */
.comment.is-removed { opacity: 0.6; }
.comment.is-removed .prose { text-decoration: line-through; }

.comment-form { display: flex; flex-direction: column; gap: 0.6rem; }
.comment-form textarea { width: 100%; }

/* Reply and Delete used to sit at opposite ends of the row via `push-end`.
   Now they are one group under the comment, because they belong to it rather
   than to the layout. */
.comment-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
                   margin-block-start: 0.5rem; }
.comment-actions:empty { display: none; }

/* --- Post formatting editor ------------------------------------------------
   The bar sits on top of the textarea and shares its border, so the two read as
   one control rather than a strip of buttons that happens to be nearby.
   ------------------------------------------------------------------------- */
.editor { display: flex; flex-direction: column; }
.editor-bar {
  display: flex; align-items: center; gap: 0.15rem; flex-wrap: wrap;
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--line); border-block-end: none;
  border-start-start-radius: 8px; border-start-end-radius: 8px;
  background: var(--bg-elevated);
}
/* Nothing claimed by script yet: the bar would be an empty grey strip, so it
   collapses instead of announcing a feature that is not there. */
.editor-bar:not(:has(.editor-btn:not([hidden]))) { display: none; }
.editor-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.9rem; height: 1.9rem; padding: 0 0.4rem;
  border: 1px solid transparent; border-radius: 5px;
  background: transparent; color: var(--text-muted);
  font: inherit; font-size: 0.86rem; line-height: 1; cursor: pointer;
}
.editor-btn:hover { background: var(--bg-hover); color: var(--text-strong); }
.editor-btn .icon { width: 1.05rem; height: 1.05rem; }
.editor-sep {
  width: 1px; height: 1.1rem; margin-inline: 0.25rem; background: var(--line);
}
.editor-preview-toggle { font-size: 0.8rem; font-weight: 600; }
/* The bar is glued to the top of whatever the caller put inside. */
.editor > textarea,
.editor .editor-preview {
  border-start-start-radius: 0; border-start-end-radius: 0;
  margin-block-start: -1px;
}
.editor-preview {
  border: 1px solid var(--line); border-radius: 0 0 8px 8px;
  padding: 0.7rem 0.85rem; min-height: 6rem; background: var(--bg);
}
.editor-preview > :first-child { margin-block-start: 0; }
.editor-preview > :last-child { margin-block-end: 0; }
.editor-help { margin-block-start: 0.4rem; }

/* Character countdown. Sits under its field, aligned to the end so it reads as
   a gauge rather than as another line of copy — and mirrors in RTL for free. */
.char-count {
  margin: 0.2rem 0 0;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;   /* stops the width jittering per keystroke */
  color: var(--text-muted);
  text-align: end;
}
.char-count.is-close { color: var(--warn); }
.char-count.is-out { color: var(--danger); font-weight: 600; }

.comment-sort-note { margin-block: -0.4rem 0.8rem; }

/* The header is sticky, so an anchored comment would otherwise land underneath
   it. Only matters on the no-script path — posting a reply, or upvoting without
   JavaScript, both come back to `#c<id>` — but landing half-hidden under the
   header is exactly the kind of "the page moved oddly" this was reported as. */
.comment, .comments { scroll-margin-block-start: 5.5rem; }
/* Mid-vote. Not `pointer-events: none` — the cursor should still say button. */
.comment-vote:disabled { opacity: 0.6; cursor: default; }
.edited-mark { font-style: italic; }

/* Upvote on a comment. Deliberately smaller and quieter than the post vote
   button: it ranks a remark, not the thing the page is about. */
.comment-vote {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.22rem 0.5rem; border-radius: 999px;
  border: 1px solid var(--line); background: transparent;
  color: var(--text-muted); font: inherit; font-size: 0.82rem; font-weight: 600;
  cursor: pointer; line-height: 1;
}
.comment-vote .icon { width: 0.95rem; height: 0.95rem; }
.comment-vote:hover { border-color: var(--accent); color: var(--accent-strong); text-decoration: none; }
.comment-vote.is-voted {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong);
}
/* Signed out, or unconfirmed: the count still reads, the control still leads
   somewhere useful, and it does not pretend to be pressable. */
.comment-vote.is-locked { cursor: pointer; opacity: 0.75; }
/* Your own comment: the count still reads, nothing invites a press. */
.comment-vote.is-own { cursor: default; opacity: 0.55; border-style: dashed; }

/* The reply and edit forms live inside a `details`, so this styles the toggle
   to look like the quiet text button it is standing in for. */
.reply-box > summary,
.edit-box > summary {
  display: inline-flex; align-items: center; gap: 0.35rem;
  cursor: pointer; list-style: none;
  font-size: 0.85rem; font-weight: 600; color: var(--text-muted);
  padding: 0.25rem 0.5rem; border-radius: 6px;
}
.reply-box > summary::-webkit-details-marker,
.edit-box > summary::-webkit-details-marker { display: none; }
.reply-box > summary::marker,
.edit-box > summary::marker { content: ""; }
.reply-box > summary:hover,
.edit-box > summary:hover { color: var(--accent-strong); background: var(--bg-hover); }
.reply-box > summary .icon,
.edit-box > summary .icon { width: 1rem; height: 1rem; }
.reply-box[open] > summary,
.edit-box[open] > summary { color: var(--accent-strong); }
.comment-form-reply, .comment-form-edit { margin-block-start: 0.6rem; }
/* The edit box replaces what you are reading, so it gets the margin the action
   row would otherwise sit in. */
.edit-box { margin-block-start: 0.5rem; }

/* Replies: indented, and joined to the comment they answer by a rule down the
   side. `margin-inline-start` and `border-inline-start` rather than left, so
   Arabic indents the other way without a second rule. */
.comment-replies-row { list-style: none; }
.comment-replies {
  margin: 0 0 0 0; padding: 0;
  margin-inline-start: 2.6rem;
  border-inline-start: 2px solid var(--line);
  padding-inline-start: 0.9rem;
}
.comment-replies > .comment:first-child { border-block-start: none; padding-block-start: 0.25rem; }
@media (max-width: 34rem) {
  .comment-replies { margin-inline-start: 1rem; padding-inline-start: 0.7rem; }
}

/* --- Ratting spots ------------------------------------------------------- */
.map-filter { flex-wrap: wrap; margin-block-end: 1.5rem; }
/* Still clickable — it is honest about being empty, not disabled. */
.map-filter .filter.is-empty { opacity: 0.5; }
.map-filter .filter .mono { color: var(--text-muted); }

.shot-stack { display: flex; flex-direction: column; gap: 1rem; }
.shot-stack img { width: 100%; border-radius: 10px; border: 1px solid var(--line); }

.shot-picker {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.85rem;
  margin-block-start: 0.75rem;
}
.shot-grid {
  display: grid;
  gap: 0.6rem;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
}
.shot-thumb { display: flex; flex-direction: column; gap: 0.3rem; }
.shot-thumb img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--line);
}
.shot-thumb .check { font-size: 0.78rem; }

/* --- Redeem codes -------------------------------------------------------- */
.redeem-how { margin-block-start: 1.5rem; }
.redeem-columns {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin-block: 1rem;
}

.code-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  margin-block-start: 1rem;
}

.code-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-panel);
  overflow: hidden;
}
.code-card.is-expired { opacity: 0.72; }

.code-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.75rem 1rem;
  background: var(--bg-inset);
  border-block-end: 1px solid var(--line);
}
.code-value {
  font-family: ui-monospace, "SFMono-Regular", "Consolas", monospace;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--accent-strong);
  /* Selectable in one gesture: double-clicking grabs the whole code. */
  user-select: all;
}
.code-card.is-expired .code-value { color: var(--text-muted); text-decoration: line-through; }
.code-copy { margin-inline-start: auto; }
.code-copy.is-copied { border-color: var(--ok); color: var(--ok); }

.code-body { padding: 1rem; display: flex; flex-direction: column; gap: 0.6rem; flex: 1; }
.code-title { margin: 0; font-size: 1rem; }
.code-body .prose { font-size: 0.92rem; }
.code-body .prose p { margin-block: 0 0.4rem; }
.code-figure { margin: 0; }
.code-figure img { width: 100%; border-radius: 8px; border: 1px solid var(--line); }

.code-foot {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.6rem 1rem;
  border-block-start: 1px solid var(--line);
}

/* --- Twitch box ----------------------------------------------------------
   Fixed to the trailing corner, which `inset-inline-end` mirrors to the left
   on the Arabic pages without a second rule. Deliberately small: it is a
   presence on the page, not the page. */
.twitch-box {
  position: fixed;
  inset-block-end: 1rem;
  inset-inline-end: 1rem;
  z-index: 60;
  width: 288px;
  max-width: calc(100vw - 2rem);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--bg-panel);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.twitch-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  background: var(--bg-elevated);
  border-block-end: 1px solid var(--line);
  font-size: 0.82rem;
}
.twitch-dot {
  width: 0.5rem;
  height: 0.5rem;
  flex: none;
  border-radius: 50%;
  background: #e91916;
  box-shadow: 0 0 0 0 rgba(233, 25, 22, 0.55);
  animation: twitch-pulse 2.4s ease-out infinite;
}
@keyframes twitch-pulse {
  70%  { box-shadow: 0 0 0 6px rgba(233, 25, 22, 0); }
  100% { box-shadow: 0 0 0 0 rgba(233, 25, 22, 0); }
}
/* The global prefers-reduced-motion rule below already stops this pulsing. */

.twitch-name {
  font-weight: 600;
  color: var(--text-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.twitch-toggle {
  margin-inline-start: auto;
  padding: 0.15rem 0.45rem;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: var(--bg-inset);
  color: var(--text-muted);
  font-size: 0.75rem;
  cursor: pointer;
}
.twitch-toggle:hover { color: var(--text-strong); border-color: var(--accent); }

.twitch-frame { aspect-ratio: 16 / 9; background: #000; }
.twitch-frame iframe { display: block; width: 100%; height: 100%; border: 0; }

/* Collapsed: the bar stays as a handle, the player is unloaded by the script. */
.twitch-box.is-collapsed .twitch-frame { display: none; }

/* --- Responsive ---------------------------------------------------------- */
@media (max-width: 900px) {
  /* The section row collapses behind the toggle; the account controls stay in
     row one, so language, theme and sign-in never go behind a tap. */
  .nav-toggle { display: flex; }
  .primary-nav { display: none; padding-block-end: 0.5rem; }
  .primary-nav.is-open { display: block; }
  .nav-scroll { overflow-x: visible; }
  .nav-list { flex-direction: column; gap: 0.1rem; }
  .nav-link {
    padding: 0.65rem 0.75rem;
    border-block-end: none;
    border-inline-start: 2px solid transparent;
    border-radius: 0 6px 6px 0;
  }
  .nav-link.is-active {
    border-inline-start-color: var(--accent);
    background: var(--accent-soft);
  }
  .account-name { display: none; }   /* the avatar is enough at this width */
  .chip-lang span { display: none; }
}

/* Below this the top row runs out of room, so it sheds weight in order of what
   matters least: first the brand's first word, then the second auth button —
   registration is still one tap away from the sign-in page.

   Dropping "Critical" and "كريتيكال" together keeps the lockup bilingual on
   the way down — TARKOV ✕ تاركوف still reads as both languages. Cutting one
   script to save room would quietly demote it. */
@media (max-width: 640px) {
  .header-top { gap: 0.5rem; }
  .brand-text,
  .brand-ar { font-size: 0.95rem; }
  .brand-mark { width: 1.45rem; height: 1.45rem; }
  .brand-word { display: none; }
  .nav-actions { gap: 0.35rem; }
  .chip { padding: 0.3rem 0.5rem; }
}

@media (max-width: 430px) {
  .btn-join { display: none; }
}

/* Last resort: the mark alone. It carries no script, so this is still the same
   logo rather than a language having been picked for the visitor. */
@media (max-width: 380px) {
  .brand-text,
  .brand-ar { display: none; }
  .brand-mark { width: 1.7rem; height: 1.7rem; }
}

@media (max-width: 640px) {
  body { font-size: 15.5px; }
  .wrap, .wrap-narrow { width: calc(100% - 1.5rem); }
  .panel { padding: 1rem; }
  .card-foot { padding-inline: 1rem; }
  .toolbar { padding: 0.65rem 0.75rem; }
  .admin-table { font-size: 0.84rem; }
  .admin-table th, .admin-table td { padding: 0.5rem 0.4rem; }
  .admin-table .actions { justify-content: flex-start; }
  .form-actions .btn { flex: 1 1 auto; }
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  /* Smaller and tucked into the corner so it never covers a form control. */
  .twitch-box { width: 208px; inset-block-end: 0.6rem; inset-inline-end: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .card:hover { transform: none; }
}

@media print {
  .site-header, .site-footer, .toolbar, .guide-rail, .flash-stack,
  .twitch-box { display: none; }
  body { background: #fff; color: #000; }
}

/* --------------------------------------------------------------------------
   Role insignia
   Everyone holds exactly one role, so a name carries one mark. The shapes are
   distinguishable at 14px on their own; colour is a second signal, never the
   only one.
   -------------------------------------------------------------------------- */
.utag {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  margin-inline-start: 0.4em;
  padding: 0.1em 0.5em 0.1em 0.35em;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 0.68em;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
  line-height: 1.5;
}
.role-mark {
  inline-size: 1.15em;
  block-size: 1.15em;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* The founder star and the PMC tags read better filled than outlined. */
.utag-founder .role-mark path { fill: currentColor; stroke-width: 1.2; }
.utag-pmc .role-mark path { fill: color-mix(in srgb, currentColor 22%, transparent); }

.utag-admin {
  background: var(--warn-soft);
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 40%, transparent);
}
.utag-founder {
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
.utag-streamer {
  background: var(--info-soft);
  color: var(--info);
  border-color: color-mix(in srgb, var(--info) 40%, transparent);
}
/* The default role is the quiet one — most people have it, so it must not
   shout on every card. */
.utag-pmc {
  background: transparent;
  color: var(--text-muted);
  border-color: var(--line-strong);
}

/* On a card byline the label is noise; the mark alone carries it. */
.card-foot .utag,
.comment-head .utag { padding-inline: 0.3em; }
.card-foot .utag-pmc,
.comment-head .utag-pmc { display: none; }
@media (max-width: 30rem) {
  .utag-text { display: none; }
  .utag { padding-inline: 0.3em; }
}

/* A bigger version for the profile header, where the role is the point. */
.role-hero {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.role-hero .role-mark { inline-size: 1.3rem; block-size: 1.3rem; }

/* The current role in the admin users table. Between the tiny inline `utag`
   and the profile's `role-hero`: it has to out-weigh the row of change buttons
   under it, which it did not when it was the same size as them. */
.role-current {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-block-end: 0.5rem;
  padding: 0.28rem 0.65rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
[dir="rtl"] .role-current { letter-spacing: 0; }
.role-current .role-mark { inline-size: 1.1rem; block-size: 1.1rem; }
/* `utag-pmc` is hidden in card footers, where a PMC badge on every byline is
   noise. Here it is the answer to the column, so it stays. */
.role-current.utag-pmc { display: inline-flex; }

/* The admin picker. */
.role-choices { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }
.role-choice { display: inline-flex; }
.role-choice .btn { gap: 0.3rem; }
.role-choice .role-mark { inline-size: 1rem; block-size: 1rem; }

/* --------------------------------------------------------------------------
   Streamer card on a profile
   -------------------------------------------------------------------------- */
.streamer-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  text-decoration: none;
  color: inherit;
  border-inline-start: 3px solid var(--info);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.streamer-card:hover { background: var(--bg-elevated); border-inline-start-color: var(--accent); }
.streamer-glyph {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 10px;
  background: var(--info-soft);
  color: var(--info);
}
.streamer-glyph .icon { width: 1.5rem; height: 1.5rem; }
.streamer-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.streamer-name { font-size: 1.05rem; word-break: break-all; }

@media (max-width: 34rem) {
  .streamer-card { flex-wrap: wrap; }
  .streamer-card .btn { inline-size: 100%; }
}

/* --------------------------------------------------------------------------
   Stats bar chart
   Pure CSS: one number per day, has to work without JavaScript, and the site
   ships no third-party scripts. Bars are sized with an inline height so the
   markup carries the data rather than a canvas hiding it.
   -------------------------------------------------------------------------- */
.bar-chart {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  block-size: 160px;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
}
.bar-col {
  flex: 1 1 0;
  min-inline-size: 4px;
  block-size: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.bar-stack {
  position: relative;
  inline-size: 100%;
  block-size: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.bar {
  position: absolute;
  inset-block-end: 0;
  inline-size: 100%;
  border-radius: 2px 2px 0 0;
  min-block-size: 1px;
}
/* Views sit behind visitors, so the pair reads as one bar with a darker core
   rather than two competing series. */
.bar-views    { background: color-mix(in srgb, var(--accent) 35%, transparent); }
.bar-visitors { background: var(--accent); inline-size: 55%; inset-inline-start: 22.5%; }
.bar-stack:hover .bar-views { background: color-mix(in srgb, var(--accent) 55%, transparent); }

.legend-key {
  display: inline-block;
  inline-size: 0.7rem;
  block-size: 0.7rem;
  border-radius: 2px;
  vertical-align: middle;
  margin-inline-end: 0.3rem;
}
.legend-views    { background: color-mix(in srgb, var(--accent) 35%, transparent); }
.legend-visitors { background: var(--accent); }

ul.plain { list-style: none; }

/* --------------------------------------------------------------------------
   Review queue and the "waiting for review" notice
   -------------------------------------------------------------------------- */
/* A rejection is a different message than "we have not looked yet", so it does
   not wear the same amber. */
.review-notice-rejected {
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
  border-inline-start-color: var(--danger);
  align-items: center;
}
.review-notice-rejected .icon { color: var(--danger); }
.rejection-reason {
  padding: 0.5rem 0.7rem;
  border-radius: 6px;
  background: var(--bg-inset);
}
@media (max-width: 40rem) {
  .review-notice-rejected { flex-wrap: wrap; }
}

.review-notice {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.85rem 1rem;
  margin-block-end: 1.25rem;
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  border-inline-start: 3px solid var(--warn);
  border-radius: 10px;
  background: var(--warn-soft);
}
.review-notice .icon {
  flex: 0 0 auto;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  color: var(--warn);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

.review-list { display: grid; gap: 1rem; }
.review-item {
  display: grid;
  grid-template-columns: 12rem 1fr 11rem;
  gap: 1.25rem;
  align-items: start;
}
.review-media img {
  inline-size: 100%;
  block-size: 8rem;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--bg-inset);
}
.review-nomedia {
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 8rem;
  border: 1px dashed var(--line-strong);
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 0.8rem;
}
.review-body { min-width: 0; }
/* Scrolls rather than clamping to three lines. The queue is where you decide
   whether something publishes, and a decision made on the first three lines of
   a write-up is not really a decision — the part worth catching is as likely to
   be at the bottom. Capped so one long post cannot push the Approve button off
   the screen. */
.review-blurb {
  max-block-size: 16rem;
  overflow-y: auto;
  font-size: 0.9rem;
  padding-inline-end: 0.4rem;
}
.review-blurb > :first-child { margin-block-start: 0; }
.review-blurb > :last-child { margin-block-end: 0; }
.review-blurb h2, .review-blurb h3 { font-size: 1rem; margin-block: 0.6rem 0.3rem; }
.review-actions { display: grid; gap: 0.5rem; }

@media (max-width: 52rem) {
  .review-item { grid-template-columns: 1fr; }
  .review-media img, .review-nomedia { block-size: 11rem; }
}

/* The one nav item with work waiting on it. */
.nav-count {
  display: inline-block;
  min-inline-size: 1.4em;
  margin-inline-start: 0.4em;
  padding: 0.05em 0.4em;
  border-radius: 999px;
  background: var(--warn);
  color: var(--accent-ink);
  font-size: 0.72em;
  font-weight: 700;
  text-align: center;
}

/* --------------------------------------------------------------------------
   Role picker on the create-user form
   Radio buttons rather than a <select>, because the choice carries a mark and
   a sentence of consequence — neither of which fits in a dropdown.
   -------------------------------------------------------------------------- */
.role-picker { display: grid; gap: 0.5rem; }
.role-option {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.role-option:hover { background: var(--bg-elevated); }
.role-option:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.role-option:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.role-option .utag { margin-inline-start: 0; }
.role-option-blurb { color: var(--text-muted); font-size: 0.85rem; }

@media (max-width: 36rem) {
  .role-option { grid-template-columns: auto 1fr; }
  .role-option-blurb { grid-column: 1 / -1; }
}

/* --------------------------------------------------------------------------
   Profile: posts by section
   Every section is listed whether or not the person has posted in it, so a
   profile reads as "here is everything they do" rather than as a builds page
   with occasional extras. Sections with something in them are links to the
   heading below; empty ones are inert and dimmed.
   -------------------------------------------------------------------------- */
.post-tally {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-block: 1.5rem 1.75rem;
}
.tally {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  background: var(--bg-panel);
}
.tally-count { font-size: 1.15rem; font-weight: 700; line-height: 1; }
.tally-label { font-size: 0.85rem; color: var(--text-muted); }

.tally-has { border-color: var(--line-strong); }
.tally-has .tally-count { color: var(--accent-strong); }
.tally-has:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
/* Dimmed rather than hidden: a zero is information too. */
.tally-empty { opacity: 0.5; background: transparent; }

@media (max-width: 30rem) {
  .post-tally { gap: 0.35rem; }
  .tally { padding: 0.4rem 0.6rem; }
  .tally-label { font-size: 0.78rem; }
}

/* --------------------------------------------------------------------------
   "Awaiting review" ribbon on a card
   Only ever rendered for a post the viewer is entitled to see — their own, or
   an admin opening it from the queue — so it marks rather than reveals.
   -------------------------------------------------------------------------- */
.card { position: relative; }
.card-pending {
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.55rem;
  border: 1px solid color-mix(in srgb, var(--warn) 55%, transparent);
  border-radius: 999px;
  background: var(--bg);
  color: var(--warn);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
}
.card-pending .icon {
  inline-size: 0.85rem;
  block-size: 0.85rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}
/* A card waiting on somebody is dimmed, so a listing reads at a glance as
   "these are live, that one is not". */
.card:has(.card-pending) .card-media { opacity: 0.55; }

/* --------------------------------------------------------------------------
   Grouped navigation
   Nine sections became four entries: two links and two menus. Built on
   <details>, so it opens with no JavaScript at all — the script only closes it
   on an outside click or Escape, which <details> cannot do alone.
   -------------------------------------------------------------------------- */
.nav-menu { position: relative; }

/* The arrow that says "this opens", and no default triangle. */
.nav-summary {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.nav-summary::-webkit-details-marker { display: none; }
.nav-summary::marker { content: ""; }

.nav-caret {
  inline-size: 0.9rem;
  block-size: 0.9rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.15s ease;
}
.nav-menu[open] .nav-caret { transform: rotate(180deg); }

.nav-submenu {
  position: absolute;
  inset-block-start: calc(100% + 0.4rem);
  /* Logical, so the panel hangs from the correct edge under RTL. */
  inset-inline-start: 0;
  z-index: 60;
  min-inline-size: 14rem;
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  background: var(--bg-elevated);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
}
.nav-submenu a {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.6rem;
  border-radius: 7px;
  color: var(--text);
  text-decoration: none;
  font-size: 0.92rem;
  white-space: nowrap;
}
.nav-submenu a:hover,
.nav-submenu a:focus-visible { background: var(--bg-panel); color: var(--text-strong); }
.nav-submenu a.is-active { color: var(--accent-strong); background: var(--accent-soft); }
.nav-submenu .icon {
  inline-size: 1.05rem;
  block-size: 1.05rem;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--text-muted);
}
.nav-submenu a:hover .icon,
.nav-submenu a.is-active .icon { color: inherit; }

/* The nav row scrolls sideways on narrow screens, and `overflow` on the
   scroller would clip an absolutely-positioned panel. Once a menu is open the
   row stops clipping, so the panel can hang below it. */
.nav-scroll:has(.nav-menu[open]) { overflow: visible; }

@media (max-width: 40rem) {
  /* No room to hang a panel beside a scrolling row — open it inline instead,
     which also removes any chance of it running off the edge. */
  .nav-submenu {
    position: static;
    min-inline-size: 0;
    box-shadow: none;
    border: 0;
    padding-inline: 0;
    background: transparent;
  }
  .nav-menu[open] { inline-size: 100%; }
}

/* --------------------------------------------------------------------------
   Google sign-in
   -------------------------------------------------------------------------- */
.oauth-split {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-block: 1.1rem;
  color: var(--text-muted);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.oauth-split::before,
.oauth-split::after {
  content: "";
  flex: 1;
  block-size: 1px;
  background: var(--line);
}

.btn-google {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
}
/* Google's own mark, so it stays recognisable rather than following the site
   palette — the whole value of the button is that people spot it instantly. */
.btn-google .icon {
  inline-size: 1.1rem;
  block-size: 1.1rem;
  fill: currentColor;
  stroke: none;
  flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   Development-only hint
   Rendered only when CT_ENV is not production. Styled to read as scaffolding
   rather than as site content, so it is never mistaken for a real message.
   -------------------------------------------------------------------------- */
.dev-hint {
  padding: 0.8rem 1rem;
  border: 1px dashed var(--line-strong);
  border-radius: 10px;
  background: var(--bg-inset);
  color: var(--text-muted);
  font-size: 0.85rem;
  line-height: 1.7;
}
.dev-hint strong { color: var(--text); }
.dev-hint .mono { color: var(--accent-strong); }
.dev-hint .tiny { font-size: 0.75rem; opacity: 0.75; }

/* A recipe's item list. Plain bullets inside a panel — the sacrifice is a list
   of things, and anything more decorative competes with the screenshots. */
.plain-list          { margin: 0; padding-inline-start: 1.1rem; font-size: 0.92rem; }
.plain-list li       { margin-block-end: 0.2rem; }
.plain-list li:last-child { margin-block-end: 0; }

/* ---------------------------------------------------------------------------
   A community run inside the reference list.

   Same shell as an editorial entry so the page reads as one list, with three
   additions an entry has no use for: a byline, the before/after evidence, and
   a footer carrying the upvote and the comment count.

   The whole block is a link. `position: relative` is what the stretched
   `.card-link::after` resolves against — without it the overlay would size
   itself to the page. The byline and the footer are lifted above that overlay
   so upvoting, opening the thread and visiting the author still do their own
   thing.
   --------------------------------------------------------------------------- */
.entry-recipe                 { position: relative; }
.entry-recipe .entry-head h3 a { color: inherit; text-decoration: none; }
.entry-recipe:hover .entry-head h3 a { color: var(--accent-strong); }
.entry-by,
.entry-foot                   { position: relative; z-index: 2; }
.entry-by {
  display: flex; align-items: center; gap: 0.4rem;
  margin-block: 0.5rem 0.2rem;
}
.entry-foot {
  display: flex; align-items: center; gap: 0.9rem;
  margin-block-start: 0.8rem; padding-block-start: 0.7rem;
  border-block-start: 1px solid var(--line);
}

/* Two shots side by side, cropped to a strip. The pair is the evidence, so
   neither is allowed to dominate the row it sits in. */
.recipe-thumbs        { display: flex; gap: 0.5rem; margin-block: 0.7rem; }
.recipe-thumbs img {
  flex: 1 1 0; min-width: 0; height: 120px; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--line);
}
@media (max-width: 30rem) {
  .recipe-thumbs img  { height: 88px; }
}
