/* ═══ HELHEIMRS — pages: Valhalla, auth, 404, dust (the style guide has its own sheet, style.css) ═══ */

/* ───────────────────────── VALHALLA ─────────────────────────
   The page's head (the sealed wall, the record, first steps, the tabs) is
   valhalla.css, fetched with the valhalla module and put just before this
   sheet, so the rules keep the order they were written in. The rest stays
   here: the medals are also the admin's badge dialog's (.adm-badges, drawn
   even when valhalla.js does not arrive), what follows them must stay after
   them, and the separators are shared with Niflheim and the info pages. */

/* ── rune medallions ── earned: an emerald bevel round a basalt hex, the
   rune lit; locked: carved into the wall, a hairline ring and a muted rune
   (no opacity: the rune keeps ≥ 3 : 1). A counted badge's progress is an
   arc round the hex. */
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal { position: relative; isolation: isolate; flex: none; display: grid; place-items: center; width: 72px; height: 82px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal::before, :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal::after { content: ""; position: absolute; clip-path: var(--clip-hex); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal::before { inset: 0; z-index: -2; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal::after { z-index: -1; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal__rune { font-family: var(--font-rune); font-size: 30px; line-height: 1; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal__rune svg { width: 26px; height: 36px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-earned { filter: drop-shadow(0 0 10px rgba(47,211,154,.4)); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-earned::before { background: linear-gradient(160deg, #7BE6C0 0%, var(--emerald) 32%, var(--jade) 72%, var(--jade-deep) 100%); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-earned::after { inset: 5px; background: radial-gradient(circle at 50% 36%, #1E2C27 0%, #0C0F0E 78%); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-earned .vh-medal__rune { color: var(--emerald); text-shadow: 0 0 10px rgba(47,211,154,.7); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked::before { background: var(--line-strong); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked::after { inset: 1px; background: var(--bg-elev-3); box-shadow: inset 0 4px 10px rgba(0,0,0,.4); }
:root[data-theme="light"] :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked::after { box-shadow: inset 0 3px 8px rgba(20,24,22,.12); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-medal__rune { color: var(--fg-muted); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal__ring { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal__ring path { fill: none; stroke: var(--emerald); stroke-width: 3; vector-effect: non-scaling-stroke; }
:root[data-theme="light"] :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal__ring path { stroke: var(--jade); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--lg { width: 88px; height: 100px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--lg .vh-medal__rune { font-size: 36px; }
/* the admin's badge dialog (admin.js): the same seal a member receives, at a
   row's size, lit when the member holds it and grey when not */
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--sm { width: 40px; height: 46px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--sm.is-earned { filter: drop-shadow(0 0 6px rgba(47,211,154,.35)); }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--sm.is-earned::after { inset: 3px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--sm .vh-medal__rune { font-size: 18px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--sm .vh-medal__rune svg { width: 14px; height: 20px; }
/* the seal inside: drawn on a 48-unit grid (valhalla.js SEALS). Earned, a
   black silhouette rim-lit in emerald over a halo, its one light lit; locked,
   the same silhouette in grey with that light carved out of it, so the eight
   still part at a glance, in colour or not. */
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal { --seal-ink: #050506; --seal-lit: #9CF0D3; display: block; width: 48px; height: 48px; overflow: visible; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--lg .vh-seal { width: 58px; height: 58px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal--sm .vh-seal { width: 28px; height: 28px; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__body { fill: var(--seal-ink); stroke-width: 2; stroke-linejoin: round; paint-order: stroke; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__seam { fill: none; stroke: rgba(237,239,234,.22); stroke-width: 1; stroke-linecap: round; stroke-linejoin: round; }
:is(.pg-valhalla, .pg-profile, .adm-badges) :is(.vh-seal__lit, .vh-seal__gem) { fill: var(--seal-lit); stroke: var(--emerald); stroke-opacity: .45; stroke-width: 2.2; stroke-linejoin: round; paint-order: stroke; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__line { fill: none; stroke: var(--seal-lit); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__glow { fill: none; stroke: var(--emerald); stroke-opacity: .35; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__rays { fill: none; stroke: var(--seal-lit); stroke-opacity: .75; stroke-width: 1; stroke-linecap: round; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__ink { fill: none; stroke: var(--seal-ink); stroke-width: 1.3; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__bars { fill: none; stroke: var(--seal-ink); stroke-width: 1.1; }
/* the grey keeps ≥ 3 : 1 on the locked medal's face in both themes */
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal { --seal-ghost: #8F948E; --seal-bg: var(--bg-elev-3); }
:root[data-theme="light"] :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal { --seal-ghost: #858B85; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked :is(.vh-seal__halo, .vh-seal__rays, .vh-seal__glow) { display: none; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal__body { fill: var(--seal-ghost); stroke: none; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked :is(.vh-seal__seam, .vh-seal__line, .vh-seal__ink) { stroke: var(--seal-bg); stroke-opacity: 1; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal__lit { fill: var(--seal-bg); stroke: none; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal__gem { fill: var(--seal-ghost); stroke: none; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal__bars { stroke: var(--seal-ghost); }

:is(.pg-valhalla, .pg-profile) :is(.vh-badges, .pf-badges) { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-4); }
:is(.pg-valhalla, .pg-profile) .vh-badge { --bd: var(--line); --facet: 10px; display: grid; justify-items: center; align-content: start; gap: var(--s-1); padding: var(--s-5) var(--s-3) var(--s-4); text-align: center; border: 1px solid var(--bd); background: var(--facet-edges), var(--bg-elev); clip-path: var(--clip-facet); min-width: 0; }
:is(.pg-valhalla, .pg-profile) .vh-badge.is-earned { --bd: var(--line-glow); background: var(--facet-edges), linear-gradient(180deg, rgba(47,211,154,.09), transparent 64%), var(--bg-elev); }
/* a badge not yet earned is the one dashed (pending) slab: no stroke closes a dashed corner */
:is(.pg-valhalla, .pg-profile) .vh-badge.is-locked { --bd: var(--line-strong); background: transparent; border-style: dashed; }
:is(.pg-valhalla, .pg-profile, .adm-badges) .vh-badge .vh-medal { margin-bottom: var(--s-2); }
:is(.pg-valhalla, .pg-profile) .vh-badge__name { font-size: var(--fs-sm); color: var(--fg-strong); overflow-wrap: anywhere; }
:is(.pg-valhalla, .pg-profile) .vh-badge.is-locked .vh-badge__name { color: var(--fg); font-weight: 600; }
:is(.pg-valhalla, .pg-profile) .vh-badge__desc { font-size: var(--fs-xs); line-height: 1.7; color: var(--fg-muted); }
:is(.pg-valhalla, .pg-profile) .vh-badge__when { display: inline-flex; align-items: center; gap: 4px; margin-top: var(--s-1); font-size: var(--fs-2xs); font-weight: 700; color: var(--accent-text); }
:is(.pg-valhalla, .pg-profile) .vh-badge.is-locked .vh-badge__when { color: var(--fg-muted); font-weight: 600; }
@media (max-width: 900px) { :is(.pg-valhalla, .pg-profile) :is(.vh-badges, .pf-badges) { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 600px) { :is(.pg-valhalla, .pg-profile) :is(.vh-badges, .pf-badges) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); } }

/* the next badge within reach: the step a new member takes, not a wall of locks */
.pg-valhalla .vh-next { --bd: var(--line-glow); --facet: 12px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--s-4) var(--s-5); padding: var(--s-4) var(--s-5); margin-bottom: var(--s-6); background: var(--facet-edges), var(--bg-elev); border: 1px solid var(--bd); clip-path: var(--clip-facet); box-shadow: var(--glow-inset-soft); }
.pg-valhalla .vh-next__txt { display: grid; gap: 2px; min-width: 0; }
.pg-valhalla .vh-next__txt p { margin: 0; }
.pg-valhalla .vh-next__k { font-size: var(--fs-xs); font-weight: 700; color: var(--accent-text); }
.pg-valhalla .vh-next__txt b { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--fg-strong); }
@media (max-width: 600px) {
  .pg-valhalla .vh-next { grid-template-columns: auto minmax(0, 1fr); padding: var(--s-4); }
  .pg-valhalla .vh-next .btn { grid-column: 1 / -1; justify-self: stretch; }
}

/* ── characters ── */
.pg-valhalla .vh-chars { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); }
.pg-valhalla .vh-char { display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; align-items: center; gap: var(--s-3); padding: var(--s-4) var(--s-5); color: var(--fg); text-decoration: none; }
.pg-valhalla .vh-char[hidden] { display: none; }
.pg-valhalla .vh-char:hover { text-decoration: none; }
/* the character's own face, cut to the hex: the bust its sheet shows */
.pg-valhalla .vh-char__face { position: relative; width: 56px; height: 64px; clip-path: var(--clip-hex); display: grid; place-items: center; overflow: hidden; color: var(--accent-text); background: #0A0A0B; }
/* framed on the head and shoulders, as a medallion is: the portrait's own canvas keeps a lot of night round the bust */
.pg-valhalla .vh-char__face .hx-portrait { width: 64px; height: 64px; flex: none; transform: translateY(-9%) scale(1.36); }
/* a hairline of the hex drawn over the picture, the way the medals carry theirs */
.pg-valhalla .vh-char__face::after { content: ""; position: absolute; inset: 0; clip-path: var(--clip-hex); box-shadow: inset 0 0 0 1px var(--line-glow); pointer-events: none; }
.pg-valhalla .vh-char__meta { display: grid; gap: 2px; min-width: 0; }
.pg-valhalla .vh-char__meta b { color: var(--fg-strong); font-size: var(--fs-lg); font-family: var(--font-display); font-weight: 700; overflow-wrap: anywhere; }
.pg-valhalla .vh-char__meta span { font-size: var(--fs-sm); }
.pg-valhalla .vh-char__go { color: var(--fg-faint); transition: transform var(--t-ui) var(--ease-stone), color var(--t-ui) var(--ease-stone); }
.pg-valhalla .vh-char:hover .vh-char__go { color: var(--accent-text); transform: translateX(-4px); }
/* the glyph is the self-mirroring "forward" (.ico--dir); only the nudge changes side */
[dir="ltr"] .pg-valhalla .vh-char:hover .vh-char__go { transform: translateX(4px); }
.pg-valhalla .vh-char--new { grid-template-columns: auto minmax(0, 1fr); border: 1px dashed var(--line-strong); clip-path: var(--clip-facet); color: var(--fg-muted); min-height: 96px; }
.pg-valhalla .vh-char--new:hover { color: var(--accent-text); border-color: var(--line-glow); }
.pg-valhalla .vh-char--broken { grid-template-columns: 56px minmax(0, 1fr); border: 1px dashed rgba(234,122,102,.5); --facet: 14px; clip-path: var(--clip-facet); }
.pg-valhalla .vh-char--broken .vh-char__face { color: var(--danger); background: var(--bg); }
.pg-valhalla .vh-char--broken .vh-char__face::after { box-shadow: inset 0 0 0 1px rgba(234,122,102,.5); }
.pg-valhalla .vh-fate + .vh-fate, .pg-valhalla .vh-fate + .vh-chars { margin-top: var(--s-7); }
.pg-valhalla .vh-fate h3 { margin: 0 0 var(--s-1); display: flex; align-items: baseline; gap: var(--s-2); }
.pg-valhalla .vh-fate > p { margin: 0 0 var(--s-4); font-size: var(--fs-sm); }
.pg-valhalla .vh-char.is-valhalla { --bd: var(--line-glow); box-shadow: var(--glow-inset-soft); }
.pg-valhalla .vh-char.is-niflheim { --bd: rgba(var(--fog-color), .35); }
/* kept in Valhalla, the face keeps its light; lost in the mist, it greys and dims */
.pg-valhalla .vh-char.is-niflheim .vh-char__face .hx-portrait { filter: grayscale(1) brightness(.78) contrast(.9); }
.pg-valhalla .vh-char.is-niflheim .vh-char__face::after { box-shadow: inset 0 0 0 1px rgba(var(--fog-color), .45); }
.pg-valhalla .vh-char__epitaph { display: block; margin-top: 2px; color: var(--fg-muted); line-height: 1.8; }
/* how the story ended: a tag under the facts, as the public profile has it */
.pg-valhalla .vh-char__meta .vh-char__fate { justify-self: start; margin-top: var(--s-1); font-size: var(--fs-xs); white-space: normal; overflow-wrap: anywhere; }

/* ── sessions, what is owed, what was paid ── */
/* «پیش‌رو», «گذشته» and «پرداخت‌ها» read as one ledger, so they share one
   grid: each sized itself to its own rows, and the same header sat 90–125px
   apart from one table to the next. Fixed columns, the same in all three
   (a receipt's amount and date under the date and the DM, its state under
   the state); a long title wraps inside its own column. */
.pg-valhalla .vh-history { table-layout: fixed; }
.pg-valhalla .vh-history th:nth-child(1) { width: 38%; }
.pg-valhalla .vh-history th:nth-child(2) { width: 21%; }
.pg-valhalla .vh-history th:nth-child(3) { width: 19%; }
.pg-valhalla .vh-history th:nth-child(4) { width: 22%; }
/* narrower, the titles give the state room enough for «جایت محفوظ است» on one line */
@media (max-width: 900px) {
  .pg-valhalla .vh-history th:nth-child(1) { width: 33%; }
  .pg-valhalla .vh-history th:nth-child(4) { width: 27%; }
}
/* what a member typed (a title, a DM's name) may break anywhere; a date or a
   sum never breaks inside itself */
.pg-valhalla .vh-history td { overflow-wrap: normal; }
.pg-valhalla .vh-history td:first-child, .pg-valhalla .vh-history:not(.vh-payments) .vh-history__who { overflow-wrap: anywhere; }
/* a tag may take two lines inside its column rather than run out of it (the
   sittings passed over are named in a long one) */
.pg-valhalla .vh-history__tags .tag { white-space: normal; text-align: start; }
/* where the seat stands, and beside it a sitting passed over (skipped, or
   called off): two tags that wrap as a pair, never touching */
.pg-valhalla .vh-history__state { display: inline-flex; flex-wrap: wrap; gap: var(--s-1); }
/* a table called off before it met keeps its date as a plan, «قرار بود …»
   (UI-B-R11-1): the words say it was only planned, the date itself stays
   whole and in the row's own colour, so it still reads at a glance */
.pg-valhalla .vh-history__was { color: var(--fg-muted); }
.pg-valhalla .vh-history__day { color: var(--fg); white-space: nowrap; }
/* a DM's way to their earnings, a line of its own under the lists */
.pg-valhalla .vh-earn-link { margin: var(--s-5) 0 0; }
/* A cell holding only a member's words in the other script is given that
   script's direction (HX.enhance), and .tbl's text-align: start then sent it
   to the column's far edge: on the English page a Persian title and DM sat
   flush right under a header set flush left. The words keep their own order
   in their isolate; the cell lines up with its row. */
.pg-valhalla .vh-history td[data-iso] { direction: inherit; }
@media (max-width: 640px) {
  /* Four columns in 358px left each a quarter, and a name broke inside its
     word («کوهس / ار», «یک‌شنـ / به»); at 601px the shared grid gave a
     seat's tag 100px of its 110. Each row is told as a short card
     instead: the session, then when ◆ with whom (or how much ◆ when), then
     where the seat stands. The headers stay for a screen reader, and the
     table keeps its roles (valhalla.js), so it is still read as one. */
  .pg-valhalla .vh-history thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .pg-valhalla .vh-history, .pg-valhalla .vh-history tbody { display: block; }
  .pg-valhalla .vh-history tr { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: var(--s-1) 0; padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
  .pg-valhalla .vh-history tr[hidden] { display: none; }
  .pg-valhalla .vh-history td { display: block; padding: 0; border: 0; }
  .pg-valhalla .vh-history td:first-child, .pg-valhalla .vh-history .vh-history__tags { grid-column: 1 / -1; max-width: none; }
  .pg-valhalla .vh-history .vh-history__tags { margin-top: var(--s-1); }
  .pg-valhalla .vh-history :is(.vh-history__when, .vh-history__who) { color: var(--fg-muted); }
  .pg-valhalla .vh-history .vh-history__when { white-space: nowrap; }
  /* here every date is in the quiet colour, a planned one too */
  .pg-valhalla .vh-history .vh-history__day { color: inherit; }
  /* the lozenge leads the second fact and stays at its first line: a long
     name wraps under itself, never under the lozenge or after it */
  .pg-valhalla .vh-history .vh-history__who { position: relative; padding-inline-start: 21px; }
  .pg-valhalla .vh-history .vh-history__who::before { content: ""; position: absolute; inset-inline-start: 8px; top: .6em; top: calc((1lh - 5px) / 2); width: 5px; height: 5px; background: var(--ornament); transform: rotate(45deg); }
  /* a receipt's one tag ends its own line rather than taking another */
  .pg-valhalla .vh-payments tr { grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; }
  .pg-valhalla .vh-payments .vh-history__tags { grid-column: auto; margin-top: 0; }
}
/* the way to the member's own calendar: one quiet row above the tables */
.pg-valhalla .vh-calbar { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--s-2) var(--s-4); margin-bottom: var(--s-5); padding-block: var(--s-3); border-block: 1px solid var(--line); }
.pg-valhalla .vh-calbar__ico { display: grid; place-items: center; width: 36px; height: 40px; clip-path: var(--clip-hex); background: var(--bg-elev-2); color: var(--accent-text); }
.pg-valhalla .vh-calbar__txt { display: grid; gap: 2px; min-width: 0; }
.pg-valhalla .vh-calbar__txt b { color: var(--fg-strong); }
.pg-valhalla .vh-calbar__txt small { font-size: var(--fs-xs); line-height: 1.7; }
@media (max-width: 560px) {
  .pg-valhalla .vh-calbar { grid-template-columns: auto minmax(0, 1fr); }
  .pg-valhalla .vh-calbar .btn { grid-column: 1 / -1; justify-self: stretch; justify-content: center; }
}
.pg-valhalla .vh-owed { --bd: var(--line); --facet: 10px; margin-bottom: var(--s-6); padding: var(--s-4) var(--s-5); background: var(--facet-edges), var(--bg-elev); border: 1px solid var(--bd); clip-path: var(--clip-facet); }
.pg-valhalla .vh-panel .vh-owed h3 { margin: 0 0 var(--s-2); font-size: var(--fs-lg); }
.pg-valhalla .vh-owed__sum { margin: 0; }
/* the heading and the sum on one side, one «پرداخت همه» on the other: one trip to the bank */
.pg-valhalla .vh-owed__head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--s-3) var(--s-5); margin-bottom: var(--s-3); }
.pg-valhalla .vh-owed__title { min-width: 0; }
.pg-valhalla .vh-owed__all { flex: none; }
.pg-valhalla .vh-owed__note { margin: 0 0 var(--s-3); font-size: var(--fs-sm); }
.pg-valhalla .vh-owed__pay { color: var(--accent-text); }
.pg-valhalla .vh-owed__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.pg-valhalla .vh-due { display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; align-items: center; gap: var(--s-2) var(--s-4); padding: var(--s-3) 0; background: var(--bg-elev); }
.pg-valhalla .vh-due.is-overdue { padding-inline-start: var(--s-3); border-inline-start: 2px solid var(--danger); }
.pg-valhalla .vh-due__what { display: grid; min-width: 0; }
.pg-valhalla .vh-due__what a { overflow-wrap: anywhere; }
.pg-valhalla .vh-due__what small { font-size: var(--fs-xs); }
/* paid from the table's kept credit by itself: said under the sitting, with when */
.pg-valhalla .vh-due__auto { display: inline-flex; align-items: center; gap: 4px; margin-top: 2px; color: var(--accent-text); font-weight: 600; line-height: 1.7; }
.pg-valhalla .vh-due__auto .ico { flex: none; }
@media (max-width: 600px) {
  .pg-valhalla .vh-owed__all { flex: 1 1 100%; }
  .pg-valhalla .vh-due { grid-template-columns: minmax(0, 1fr) auto; }
  .pg-valhalla .vh-due__state { justify-self: start; }
}
/* What became of a payment (UX-2-R6-1): its «پرداخت‌شده», and hung from it by
   a short bracket, where the money went next — back to credit, and why. The
   receipt stays a receipt (the plain tag); what is true of the money now is
   the lit one. The bracket is drawn in logical borders, so it turns with
   the page: ┘ on the Persian page, └ on the English one. */
.pg-valhalla .vh-pay { display: inline-grid; justify-items: start; gap: 6px; }
.pg-valhalla .vh-pay__then { position: relative; display: block; padding-inline-start: 18px; }
.pg-valhalla .vh-pay__then::before { content: ""; position: absolute; inset-inline-start: 7px; top: -7px; width: 8px; height: calc(50% + 7px); border-inline-start: 1px solid var(--line-strong); border-bottom: 1px solid var(--line-strong); border-end-start-radius: 3px; }
@media (max-width: 640px) {
  /* told on its own line under the amount and the day: two tags would not end that line */
  .pg-valhalla .vh-payments .vh-pay__cell { grid-column: 1 / -1; margin-top: var(--s-1); }
}
/* The credit ledger, under the receipts: where the credit came from and
   where it went, one move a line, newest first — a statement, read like
   one: what moved and why at the start, the signed sum at the end, money
   in lit, money out in the text's own colour (paying a sitting is not a
   loss). The balance heads it. */
/* a statement is read across: at the panel's full width the sum sat 900px
   from the words it belongs to */
.pg-valhalla .vh-credit { max-width: 52rem; margin-top: var(--s-6); }
.pg-valhalla .vh-credit__head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: var(--s-1) var(--s-4); }
.pg-valhalla .vh-credit__sum { margin: 0; color: var(--fg-muted); }
.pg-valhalla .vh-credit__sum b { color: var(--fg-strong); }
.pg-valhalla .vh-credit__how { margin: 0 0 var(--s-3); max-width: 64ch; font-size: var(--fs-sm); line-height: 1.8; }
.pg-valhalla .vh-credit__list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.pg-valhalla .vh-credit__line { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: var(--s-1) var(--s-4); padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
.pg-valhalla .vh-credit__line[hidden] { display: none; }
.pg-valhalla .vh-credit__what { display: grid; gap: 2px; min-width: 0; color: var(--fg-strong); overflow-wrap: anywhere; }
.pg-valhalla .vh-credit__why { font-size: var(--fs-xs); color: var(--fg-muted); line-height: 1.8; }
.pg-valhalla .vh-credit__amt { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--fg-strong); }
.pg-valhalla .vh-credit__line.is-in .vh-credit__amt { color: var(--accent-text); }
.pg-valhalla .vh-saved { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); }
.pg-valhalla .vh-saved__card { display: block; color: var(--fg); text-decoration: none; min-width: 0; }
.pg-valhalla .vh-saved__card[hidden] { display: none; }
.pg-valhalla .vh-saved__card:hover { text-decoration: none; }
.pg-valhalla .vh-saved__cover { display: block; aspect-ratio: 16 / 9; overflow: hidden; }
.pg-valhalla .vh-saved__meta { display: grid; gap: 4px; padding: var(--s-3) var(--s-4) var(--s-4); }
.pg-valhalla .vh-saved__meta .tag { justify-self: start; }
.pg-valhalla .vh-saved__meta b { color: var(--fg-strong); overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.pg-valhalla .vh-treasure { display: grid; place-items: center; gap: var(--s-2); min-height: 160px; border: 1px dashed var(--line-strong); clip-path: var(--clip-facet); font-size: var(--fs-xs); }
@media (max-width: 900px) { .pg-valhalla .vh-saved { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .pg-valhalla .vh-chars, .pg-valhalla .vh-saved { grid-template-columns: minmax(0, 1fr); } }

/* HX.SEP between facts. Two things the bare ᛫ got wrong here: the runic
   letter is a strong left-to-right character, so beside Persian digits it
   pulled the number across it («تجربه۱٬۵۷۵ ᛫ تا»); isolated, it is neutral
   again. And Noto Sans Runic draws it as a round dot, the very shape of «۰»;
   it is shown as a carved lozenge, which no digit resembles. */
:is(.pg-valhalla, .pg-profile, .pg-settings, .pg-niflheim, .pg-info) .sep { display: inline-block; font-family: inherit; font-style: normal; unicode-bidi: isolate; width: 5px; height: 5px; margin-inline: 8px; vertical-align: middle; background: var(--ornament); transform: rotate(45deg); font-size: 0; line-height: 0; overflow: hidden; color: transparent; }
/* A row of facts that may wrap (metaLine in valhalla.js), drawn as the public
   profile's: each fact whole, the same lozenge before every one, and the row
   pulled back by one lozenge's room (5px + 2 × 8px) inside a holder that
   clips it, so the first fact of every line loses its lozenge with the
   line's start. No line ends on a separator or starts with one. */
:is(.pg-valhalla, .pg-settings) .meta-line { display: block; overflow: hidden; }
:is(.pg-valhalla, .pg-settings) .meta-line__in { display: flex; flex-wrap: wrap; align-items: baseline; margin-inline-start: -21px; }
/* a line of one fact in the other script is given that script's direction
   by HX.enhance, and a flex row with it flew to the far edge (a Persian
   title alone in the English experience log): the row keeps the page's
   direction, the words their own in their isolate */
:is(.pg-valhalla, .pg-settings) :is(.meta-line, .meta-line__in)[data-iso] { direction: inherit; }
:is(.pg-valhalla, .pg-settings) .meta-part { min-width: 0; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.pg-valhalla, .pg-settings) .meta-part::before { content: ""; display: inline-block; width: 5px; height: 5px; margin-inline: 8px; vertical-align: middle; background: var(--ornament); transform: rotate(45deg); }
/* a session's title may be longer than the line: it wraps inside its own
   fact, and what follows it starts the next line */
.pg-valhalla .vh-how__what .meta-part:first-child { white-space: normal; overflow-wrap: anywhere; }

/* ───────────────────────── SETTINGS ─────────────────────────
   The page's own rules (.pg-settings) are valhalla.css, fetched with the
   valhalla module that draws /settings. What it shares with Valhalla and
   the profile (the separators, the fact rows) stays above; its high-contrast
   states stay in the block below. */
.pg-valhalla .vh-id__trust { color: var(--fg-muted); font-weight: 600; }
/* a new DM's standing leads to what it means (the settings' DM section) */
.pg-valhalla .vh-id__trust a { color: inherit; text-decoration: underline dotted; text-underline-offset: 3px; }
.pg-valhalla .vh-id__trust a:hover { color: var(--accent-text); }
.vh-del { display: grid; gap: var(--s-3); }
.vh-del h2, .vh-del p { margin: 0; }
.vh-del__list { margin: 0; padding-inline-start: var(--s-5); display: grid; gap: var(--s-1); font-size: var(--fs-sm); }

/* High contrast: the states above are drawn with backgrounds and clip-paths,
   which forced colours erase; they are redrawn in system colours. */
@media (forced-colors: active) {
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal, :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-level, .pg-settings .vh-face__rune { forced-color-adjust: none; }
  /* the separator lozenge and the rune ornament's dots are drawn with a background */
  :is(.pg-valhalla, .pg-profile, .pg-settings, .pg-niflheim, .pg-info) .sep, :is(.pg-profile, .pg-niflheim) .meta-part::before { forced-color-adjust: none; background: CanvasText; }
  :is(.pg-valhalla, .pg-settings) .meta-part::before, .pg-valhalla .vh-history .vh-history__who::before { forced-color-adjust: none; background: CanvasText; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-earned::before, :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-level::before { background: Highlight; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal::after, :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-level::after { background: Canvas; box-shadow: none; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-earned .vh-medal__rune, :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-level b { color: Highlight; text-shadow: none; }
  :is(.pg-valhalla, .pg-profile) .vh-level small { color: CanvasText; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked::before { background: GrayText; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-medal__rune { color: GrayText; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal__ring path { stroke: Highlight; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) :is(.vh-seal__halo, .vh-seal__glow, .vh-seal__rays) { display: none; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__body { fill: CanvasText; stroke: none; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) :is(.vh-seal__lit, .vh-seal__gem) { fill: Highlight; stroke: none; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__line { stroke: Highlight; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) :is(.vh-seal__seam, .vh-seal__ink) { stroke: Canvas; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-seal__bars { stroke: CanvasText; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked :is(.vh-seal__body, .vh-seal__gem) { fill: GrayText; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked :is(.vh-seal__line, .vh-seal__seam, .vh-seal__ink) { stroke: Canvas; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal__lit { fill: Canvas; }
  :is(.pg-valhalla, .pg-profile, .adm-badges) .vh-medal.is-locked .vh-seal__bars { stroke: GrayText; }
  :is(.pg-valhalla, .pg-profile) .vh-badge.is-earned { border: 2px solid Highlight; }
  :is(.pg-valhalla, .pg-profile) .vh-xp__bar { border: 1px solid CanvasText; }
  :is(.pg-valhalla, .pg-profile) .vh-xp__bar i { forced-color-adjust: none; background: Highlight; }
  .pg-settings .vh-face__rune { background: GrayText; }
  .pg-settings .vh-face__in { background: Canvas; color: CanvasText; }
  .pg-settings .vh-face__rune[aria-checked="true"], .pg-settings .vh-face__rune:focus-visible { background: Highlight; }
  .pg-settings .st-index a[aria-current="true"] { border-color: Highlight; color: Highlight; }
  .pg-valhalla .vh-shield.is-yours .vh-shield__face { forced-color-adjust: none; background: Highlight; color: Canvas; }
}

/* ── a name or title in the other script ──
   HX.enhance (and HX.textAttrs) give the holder of a name or title people
   wrote its own direction, so its letters and its ellipsis are in order, and
   mark it data-iso. It must still line up with its row: a character's name
   beside its portrait, a post's title over its date, a role under a label.
   Aligned to its own start, a Persian name in an English card flew to the
   card's far edge, and the Valhalla names zig-zagged by script. A backstory's
   opening is reading text and keeps its own side. */
:is(.pg-valhalla, .pg-profile, .pg-settings, .pg-niflheim, .pg-info, .pg-auth) [data-iso] { text-align: match-parent; }
.pg-profile .pf-char__story[data-iso] { text-align: start; }

/* ── drawn rune ornaments (runes() in misc.js → HX.art.runes) ──
   Every stave full height (the font set ᚲ ᛃ ᛊ ᛜ at half height). A crown
   spelled as one word (ᛚᚨᚷ, ᚱᚨᚹᛖᚾ) is tracked about as the font was (.3em)
   instead of set solid; a spaced kicker keeps the drawing's own gaps. */
.pg-info .info-head .rune { --runes-gap: 6px; }

/* ───────────────────────── AUTH ───────────────────────── */
.pg-auth { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: calc(100vh - 68px); }
/* a grid item will not shrink below its content unless told: the ledger's own
   width once pushed /verify 2px past a 320px screen */
.pg-auth .auth-scene, .pg-auth .auth-ledger { min-width: 0; }
.pg-auth .auth-scene { position: relative; overflow: hidden; display: grid; place-items: center; align-content: center; gap: var(--s-5); padding: var(--gutter); background: radial-gradient(ellipse at 50% 60%, rgba(15,107,79,.35), transparent 55%), radial-gradient(ellipse at 50% 100%, rgba(47,211,154,.12), transparent 50%), var(--bg-elev); border-inline-start: 1px solid var(--line); }
.pg-auth .auth-scene::before, .pg-auth .auth-scene::after { content: ""; position: absolute; inset: -20%; background: radial-gradient(ellipse at 30% 70%, rgba(var(--fog-color), .12), transparent 55%), radial-gradient(ellipse at 70% 40%, rgba(var(--fog-color), .09), transparent 50%); animation: authFog 26s ease-in-out infinite alternate; pointer-events: none; }
.pg-auth .auth-scene::after { animation-duration: 38s; animation-direction: alternate-reverse; opacity: .7; }
@keyframes authFog { from { transform: translate(-3%, 1%) scale(1); } to { transform: translate(3%, -2%) scale(1.08); } }
/* The mark rests. It used to breathe ±15% forever beside the form, the loudest
   thing on a page whose only job is the form; the glow behind it is enough. */
.pg-auth .auth-scene__mark { position: relative; }
.pg-auth .auth-scene__mark::before { content: ""; position: absolute; left: 18%; right: 18%; top: 13%; bottom: 9%; z-index: -1; clip-path: var(--clip-hex); box-shadow: 0 0 60px 20px rgba(47,211,154,.3); }
.pg-auth .auth-scene__mark svg { width: min(380px, 60vw); height: auto; }
/* the kicker is read, not glanced at: full body colour, not the muted grey that
   fell to 4:1 on the lit scene */
.pg-auth .auth-scene__kicker { position: relative; margin: 0; color: var(--fg); text-align: center; max-width: 34ch; }
.pg-auth .auth-scene .rune-band { position: relative; margin: 0; }
.pg-auth .auth-ledger { display: grid; place-items: center; padding: var(--s-8) var(--gutter); }
/* No ruled lines behind the form any more: at a fixed 32px period they ran
   through labels and hints, because a form with hints has no single rhythm. */
/* a six-sided slab whose edge runs round the cut corners too (--facet-edges) */
.pg-auth .auth-ledger__in { --bd: var(--line-strong); width: min(100%, 460px); position: relative; padding: var(--s-6) var(--s-6) var(--s-5); background: var(--facet-edges), var(--stone-grad); border: 1px solid var(--bd); clip-path: var(--clip-facet); box-shadow: var(--shadow-stone); }
.pg-auth .auth-ledger__in > * { position: relative; }
.pg-auth .auth-ledger__in .rune { margin: 0 0 var(--s-2); font-size: .95rem; }
.pg-auth .auth-ledger__in h1 { font-size: var(--fs-2xl); margin-bottom: var(--s-1); }
.pg-auth .auth-ledger__in h1:focus { outline: none; }
.pg-auth .auth-form { display: grid; gap: var(--s-4); margin-top: var(--s-5); transition: opacity var(--t-slow) var(--ease-out); }
/* the card stepping back for the name is started by the reader's own press:
   it moves on the first frame (--ease-press), and a nod's is short */
.pg-auth .auth-ledger__in > * { transition: opacity var(--t-slow) var(--ease-press); }
/* the nod's state is a class on the card itself (signAndEnter), never read
   through :has(): a :has() in a non-final compound followed by `> *` cannot be
   scoped, and this stylesheet is loaded on every page, so it made every DOM
   insertion anywhere restyle the whole document */
.pg-auth .auth-ledger__in.is-signing.is-nodding > * { transition-duration: var(--t-fast); }
.pg-auth .auth-ledger__in.is-signing > :not(.auth-sign) { opacity: .08; pointer-events: none; }
.pg-auth .auth-row { font-size: var(--fs-sm); }
.pg-auth .auth-forgot { font-size: var(--fs-xs); color: var(--fg-muted); display: inline-flex; align-items: center; min-height: 44px; padding-inline: var(--s-2); }
.pg-auth .auth-actions { display: flex; gap: var(--s-3); flex-wrap: wrap; margin-top: var(--s-2); }
.pg-auth .auth-actions .btn--primary { flex: 1; }
.pg-auth .auth-nick { display: flex; gap: var(--s-2); }
.pg-auth .auth-nick .input { flex: 1; }
.pg-auth .auth-nick .btn { flex: none; }
.pg-auth .auth-alt { margin: var(--s-5) 0 0; font-size: var(--fs-sm); color: var(--fg-muted); }
.pg-auth .auth-alt a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: var(--s-1); }
/* a handle that is free says so in the hint's own place, in the accent */
.pg-auth .hint.is-ok { color: var(--accent-text); font-weight: 600; }

/* the password eye: a 44px target inside the field, on the side the page ends
   on. The input itself is left-to-right (passwords are Latin), so its padding
   is set physically from the page's direction, not its own. */
.pg-auth .auth-pass { position: relative; }
[dir="rtl"] .pg-auth .auth-pass .input { padding-left: 52px; }
[dir="ltr"] .pg-auth .auth-pass .input { padding-right: 52px; }
.pg-auth .auth-eye { position: absolute; inset-block: 1px; inset-inline-end: 1px; width: 44px; display: grid; place-items: center; padding: 0; background: none; border: 0; color: var(--fg-muted); cursor: pointer; transition: color var(--t-ui) var(--ease-stone); }
.pg-auth .auth-eye .ico { --n: 20; }
.pg-auth .auth-eye:hover { color: var(--fg-strong); }
.pg-auth .auth-eye:focus-visible { outline: 2px solid var(--accent); outline-offset: -5px; }
.pg-auth .auth-eye[aria-pressed="true"] { color: var(--accent-text); }
.pg-auth .auth-eye::after { content: ""; position: absolute; width: 22px; height: 2px; background: currentColor; transform: rotate(-45deg) scaleX(0); transition: transform var(--t-ui) var(--ease-press); }
.pg-auth .auth-eye[aria-pressed="true"]::after { transform: rotate(-45deg) scaleX(1); }

/* The consent sentence is one span beside its box, top-aligned to the first
   line, so English wraps as a sentence instead of three columns. */
.pg-auth .auth-oath .check { display: flex; align-items: flex-start; }
.pg-auth .auth-oath .check input { flex: none; margin-top: 6px; margin-top: calc((1lh - 18px) / 2); }
.pg-auth .auth-oath .check a { text-decoration: underline; text-underline-offset: 3px; }

/* ── continuing with Google ──
   Google's own dark button in Helheim (#131314 fill, #8E918F edge, #E3E3E3
   label) and its white one in Frost: the same height as the fields, with the
   standard rounded shape, so it reads as the third-party option it is — never
   brighter than the form's own emerald button. */
.auth-google { display: grid; gap: var(--s-4); margin-bottom: var(--s-4); }
.pg-auth .auth-google__btn { display: flex; align-items: center; justify-content: center; gap: var(--s-3); width: 100%; min-height: 46px; padding-inline: var(--s-5); font-size: var(--fs-sm); font-weight: 600;
  background: #131314; color: #E3E3E3; border: 1px solid #8E918F; border-radius: 4px; clip-path: none; box-shadow: none; }
.pg-auth .auth-google__btn:hover, .pg-auth .auth-google__btn:focus-visible { background: #1E1F20; color: #E3E3E3; border-color: #A8ABA9; text-decoration: none; }
:root[data-theme="light"] .pg-auth .auth-google__btn { background: #FFFFFF; color: #1F1F1F; border-color: #747775; }
:root[data-theme="light"] .pg-auth .auth-google__btn:hover, :root[data-theme="light"] .pg-auth .auth-google__btn:focus-visible { background: #F6F8F7; color: #1F1F1F; }
.auth-google__g { flex: none; }
.auth-google__note, .auth-google__reason { margin: calc(-1 * var(--s-2)) 0 0; }
.auth-or { display: flex; align-items: center; gap: var(--s-3); margin: 0; color: var(--fg-muted); font-size: var(--fs-sm); }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line-strong); }

/* ── the inbox state: a sign-up waiting on its emailed link ── */
.pg-auth .auth-inbox { display: grid; gap: var(--s-4); margin-top: var(--s-5); }
.pg-auth .auth-inbox__seal { --bd: var(--line); --facet: 8px; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s-4); align-items: center; padding: var(--s-4); background: var(--facet-edges), var(--bg); border: 1px solid var(--bd); clip-path: var(--clip-facet); }
.pg-auth .auth-inbox__hex { width: 52px; height: 58px; clip-path: var(--clip-hex); display: grid; place-items: center; background: var(--emerald-grad); color: var(--accent-fg); }
.pg-auth .auth-inbox__hex .ico { --n: 24; }
.pg-auth .auth-inbox__seal p { margin: 0; font-size: var(--fs-sm); line-height: var(--lh-ui, 1.6); }
/* the session this sign-up started from, named so its seat does not feel lost */
.pg-auth .auth-inbox__back { margin: 0; padding-inline-start: var(--s-3); border-inline-start: 2px solid var(--accent); font-size: var(--fs-sm); line-height: var(--lh-ui, 1.6); color: var(--fg); overflow-wrap: anywhere; }
.pg-auth .auth-inbox__back b { color: var(--fg-strong); }
.pg-auth .auth-inbox__sent { margin: 0; font-size: var(--fs-sm); color: var(--accent-text); }
.pg-auth .auth-inbox__sent:empty { display: none; }
.pg-auth .auth-inbox__addr { color: var(--fg-strong); font-weight: 700; overflow-wrap: anywhere; }
.pg-auth .auth-inbox .auth-actions .btn { flex: 1; }
.pg-auth .auth-inbox .auth-alt { margin-top: 0; }
.pg-auth .auth-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--s-1); background: none; border: 0; color: var(--accent-text); font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.pg-auth .auth-link:hover { color: var(--fg-strong); }

/* ── the name, carved into the ledger ──
   One text run under a mask that sweeps from where the name starts (the right
   edge of a Persian name, the left of a Latin one), with a soft edge rather
   than a hard clip line cutting stems in half. The cut glows emerald while the
   chisel works and cools to carved stone as it finishes. Without @property the
   sweep degrades to the name appearing at once, still whole and still shaped. */
@property --carve { syntax: '<percentage>'; inherits: true; initial-value: 0%; }
.pg-auth .auth-sign { position: absolute; inset-inline: var(--s-6); top: 50%; transform: translateY(-40%); display: grid; gap: var(--s-2); justify-items: center; text-align: center; pointer-events: none; --hot: var(--emerald); }
:root[data-theme="light"] .pg-auth .auth-sign { --hot: var(--jade); }
.pg-auth .auth-sign__label { font-size: var(--fs-xs); color: var(--fg-muted); }
.pg-auth .auth-sign__name { --carve-to: left; position: relative; padding-inline: .2em; font-family: var(--font-display); font-weight: 900; font-size: var(--fs-2xl); line-height: 1.3; color: var(--fg-strong); white-space: nowrap;
  -webkit-mask-image: linear-gradient(to var(--carve-to), #000 calc(var(--carve) - 8%), transparent var(--carve));
  mask-image: linear-gradient(to var(--carve-to), #000 calc(var(--carve) - 8%), transparent var(--carve));
  animation: signCarve var(--sign-ms, 1100ms) cubic-bezier(.45,.05,.35,1) both, signCool calc(var(--sign-ms, 1100ms) + 250ms) linear both; }
.pg-auth .auth-sign__name[dir="ltr"] { --carve-to: right; }
/* the chisel: a small lit hex riding just behind the cut */
.pg-auth .auth-sign__name::after { content: ""; position: absolute; top: 50%; inset-inline-start: calc(var(--carve) - 9%); width: 7px; height: 8px; margin-top: -4px; clip-path: var(--clip-hex); background: var(--hot); box-shadow: 0 0 10px var(--hot); filter: drop-shadow(0 0 4px var(--hot)); animation: signChisel var(--sign-ms, 1100ms) linear both; }
@keyframes signCarve { from { --carve: 0%; } to { --carve: 108%; } }
@keyframes signCool { 0%, 60% { color: var(--hot); text-shadow: 0 0 18px rgba(47,211,154,.55); } 100% { color: var(--fg-strong); text-shadow: 0 1px 0 rgba(255,255,255,.06), 0 -1px 0 rgba(0,0,0,.8); } }
@keyframes signChisel { 0%, 92% { opacity: 1; } 100% { opacity: 0; } }
:root[data-theme="light"] .pg-auth .auth-sign__name { animation-name: signCarve, signCoolLight; }
@keyframes signCoolLight { 0%, 60% { color: var(--hot); } 100% { color: var(--fg-strong); text-shadow: 0 1px 0 rgba(255,255,255,.8); } }
/* a returning member's nod: the name appears whole in a quarter second; the
   label and the chisel belong to the ceremony and would only flicker here */
.pg-auth .auth-sign.is-nod .auth-sign__label { visibility: hidden; }
.pg-auth .auth-sign.is-nod .auth-sign__name::after { content: none; }
.pg-auth .auth-sign__line { display: block; width: 0; height: 2px; background: linear-gradient(90deg, transparent, var(--emerald), transparent); box-shadow: var(--glow); animation: signLine var(--sign-ms, 1100ms) .1s var(--ease-out) forwards; }
@keyframes signLine { to { width: 80%; } }
@media (max-width: 900px) {
  .pg-auth { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .pg-auth .auth-scene { min-height: 260px; padding-block: var(--s-6); border-inline-start: 0; border-bottom: 1px solid var(--line); order: -1; }
  .pg-auth .auth-scene__mark svg { width: 200px; }
  .pg-auth .auth-scene__kicker { display: none; }
  .pg-auth .auth-ledger { padding-block: var(--s-6) var(--s-8); }
}
/* On a phone the page's job is the form: the portal shrinks to a 132px band
   with the seal at 96px, so the title, the Google button and the first fields
   are on the first screen, keyboard or not. The band is still the realm's —
   its glow and fog — but carries no words. */
@media (max-width: 600px) {
  .pg-auth .auth-scene { min-height: 0; height: 132px; padding-block: 18px; gap: 0; }
  .pg-auth .auth-scene__mark svg { width: 96px; }
  .pg-auth .auth-scene__mark::before { box-shadow: 0 0 34px 10px rgba(47,211,154,.26); }
  .pg-auth .auth-scene .rune-band { display: none; }
  .pg-auth .auth-ledger { padding-block: var(--s-4) var(--s-7); }
  .pg-auth .auth-ledger__in { padding: var(--s-5) var(--s-4) var(--s-4); }
  .pg-auth .auth-ledger__in h1 { font-size: var(--fs-xl); }
  .pg-auth .auth-form { margin-top: var(--s-4); gap: var(--s-3); }
}
@media (prefers-reduced-motion: reduce) { .pg-auth .auth-scene::before, .pg-auth .auth-scene::after { animation: none; } }

/* ───────────────────────── 404 · NIFLHEIM ─────────────────────────
   One picture behind the copy: the void-black shore at the bottom of the world,
   fog drifting across it, a dead tree with a raven on the left and a lost
   soul walking away on the right. A picture, not a sentence: it is not
   mirrored for English, so nothing has to be flipped. The figures stay in the margins
   (the text column is narrow enough to leave them room); on a phone they stand
   in their own band above the text. Nothing overlaps the heading. */
.pg-404 { --nf-col: 560px; position: relative; min-height: calc(100vh - 68px); overflow: hidden; display: grid; place-items: center; padding: var(--s-9) var(--gutter) calc(var(--s-9) + 40px); text-align: center; background: radial-gradient(ellipse at 50% 110%, rgba(15,107,79,.2), transparent 55%), var(--bg); }
.pg-404 .nf-scene { position: absolute; inset: 0; pointer-events: none; }
/* the realm's plate (HX.art.niflheim) is the ground: it fills the frame and is
   cropped, never stretched; its three fog banks are wider than the frame and
   drift, each at its own pace */
.pg-404 .nf-plate-art { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.pg-404 .nf-plate-art .nf-plate { animation: nfBank 64s ease-in-out infinite alternate; }
.pg-404 .nf-plate-art .nf-plate--2 { animation-duration: 88s; animation-direction: alternate-reverse; }
.pg-404 .nf-plate-art .nf-plate--3 { animation-duration: 72s; }
@keyframes nfBank { from { transform: translateX(-140px); } to { transform: translateX(140px); } }
/* the copy keeps a pool of plain ground under it, so the banks never run
   through a line of text or the outlined button */
.pg-404 .nf-scene::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse min(46vw, 420px) 58% at 50% 54%, color-mix(in srgb, var(--bg) 72%, transparent), transparent); }
/* one haze passes in front of the figures, low over the shore */
.pg-404 .nf-fog { position: absolute; pointer-events: none; }
.pg-404 .nf-fog--3 { inset: auto -30% 0; height: 42%; background: radial-gradient(ellipse at 30% 80%, rgba(var(--fog-color), .2), transparent 55%), radial-gradient(ellipse at 75% 90%, rgba(var(--fog-color), .16), transparent 50%); filter: blur(14px); animation: nfDrift 70s ease-in-out infinite alternate; }
@keyframes nfDrift { from { transform: translateX(-5%); } to { transform: translateX(5%); } }
/* the tree: a silhouette against a patch of lit fog, rimmed so it never sinks
   into the void; its long branch leans toward the text */
.pg-404 .nf-tree { position: absolute; bottom: 92px; left: max(2vw, 16px); width: clamp(120px, calc((100vw - var(--nf-col)) / 2 - 72px), 250px); color: #121514; filter: drop-shadow(0 0 1px rgba(200,225,215,.35)) drop-shadow(0 0 22px rgba(var(--fog-color), .28)); }
.pg-404 .nf-tree::before { content: ""; position: absolute; inset: -10% -25% 10%; z-index: -1; background: radial-gradient(ellipse at 50% 55%, rgba(var(--fog-color), .2), transparent 62%); }
.pg-404 .nf-tree__art { display: block; width: 100%; height: auto; }
:root[data-theme="light"] .pg-404 .nf-tree { color: #3B4340; filter: drop-shadow(0 0 18px rgba(255,255,255,.6)); }
/* the raven sits on the long branch, an emerald pinpoint of a watcher */
.pg-404 .nf-raven { position: absolute; top: 41%; right: 4%; width: 28%; transform: translateY(-82%); filter: drop-shadow(0 0 1px rgba(200,225,215,.5)) drop-shadow(0 0 10px rgba(47,211,154,.22)); animation: nfPerch 9s ease-in-out infinite; }
.pg-404 .nf-raven svg { width: 100%; height: auto; display: block; }
@keyframes nfPerch { 0%, 84%, 100% { rotate: 0deg; } 88% { rotate: -4deg; } 93% { rotate: 2deg; } }
/* the wanderer: frost at a third of its strength, walking off into the fog;
   it drifts outward and back in either language, never off the screen */
.pg-404 .nf-wanderer { --wander: 1; position: absolute; bottom: 96px; right: max(11vw, 24px); width: clamp(56px, 6vw, 84px); color: #EDEFEA; opacity: .35; filter: blur(.5px) drop-shadow(0 0 14px rgba(200,225,215,.45)); animation: nfWander 36s ease-in-out infinite alternate; }
:root[data-theme="light"] .pg-404 .nf-wanderer { color: #4E5A55; opacity: .4; filter: blur(.4px); }
.pg-404 .nf-wanderer svg { display: block; width: 100%; height: auto; overflow: visible; }
@keyframes nfWander { 0% { transform: translate(0, 0) scale(1); opacity: .38; } 50% { transform: translate(calc(var(--wander) * 2.5vw), -6px) scale(.94); opacity: .3; } 100% { transform: translate(calc(var(--wander) * 4.5vw), 4px) scale(.86); opacity: .22; } }

.pg-404 .nf-body { position: relative; z-index: 1; display: grid; justify-items: center; gap: var(--s-4); width: min(100%, var(--nf-col)); }
.pg-404 .nf-body p { margin: 0; }
/* the numerals and the title are one lockup: the outlined 404 stands behind,
   the title sits on its lower third, haloed in the ground colour so every
   letter stays clear */
.pg-404 .nf-lockup { display: grid; justify-items: center; }
.pg-404 .nf-code { position: relative; z-index: 0; margin: 0 0 -.34em; font-family: var(--font-latin); font-weight: 700; font-size: clamp(5rem, 15vw, 9.5rem); line-height: .85; letter-spacing: .1em; padding-inline-start: .1em; color: transparent; -webkit-text-stroke: 1px rgba(237,239,234,.32); text-shadow: 0 0 40px rgba(47,211,154,.14); opacity: .8; user-select: none; }
:root[data-theme="light"] .pg-404 .nf-code { -webkit-text-stroke: 1px rgba(14,16,15,.3); text-shadow: none; }
/* The title may run wider than the text column: on a wide screen it is one
   line under the numerals, not a phrase broken after «در» in a forced narrow
   measure. On a phone it wraps, balanced, and the no-break space in the copy
   keeps «در نیفلهایم» together. */
.pg-404 .nf-lockup { width: max-content; max-width: calc(100vw - 2 * var(--gutter)); }
.pg-404 h1 { position: relative; z-index: 1; margin: 0; max-width: 14em; margin-inline: auto; text-wrap: balance; text-shadow: 0 0 18px var(--bg), 0 0 36px var(--bg), 0 0 4px var(--bg); }
.pg-404 .nf-where { display: flex; justify-content: center; }
/* a path is code: set in the mono face in true case, never in Cinzel capitals */
.pg-404 .nf-path { --bd: var(--line-strong); --facet: 6px; display: inline-block; padding: var(--s-2) var(--s-4); font-family: var(--font-mono, ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace); font-size: .8125rem; letter-spacing: 0; text-transform: none; font-variant: normal; background: var(--facet-edges), var(--bg-elev); border: 1px solid var(--bd); color: var(--fg-muted); clip-path: var(--clip-facet); max-width: 100%; overflow-wrap: anywhere; unicode-bidi: isolate; }
.pg-404 .nf-actions { justify-content: center; margin-top: var(--s-2); }
.pg-404 .nf-links { list-style: none; padding: 0; margin: var(--s-5) 0 0; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2); }
.pg-404 .nf-links a { --bd: var(--line); --facet: 6px; display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 0 12px; font-size: var(--fs-xs); font-weight: 600; color: var(--fg-muted); border: 1px solid var(--bd); clip-path: var(--clip-facet); background: var(--facet-edges), var(--bg-elev); transition: color var(--t-fast) var(--ease-stone), border-color var(--t-fast) var(--ease-stone); }
.pg-404 .nf-links a:hover { --bd: var(--line-glow); color: var(--accent-text); text-decoration: none; }
.pg-404 .nf-links .ico { --n: 16; }
@media (pointer: coarse) { .pg-404 .nf-links a { min-height: 44px; } }
/* phone and narrow tablet: the figures move into a band above the text */
@media (max-width: 900px) {
  /* place-items aligns block children too in current engines: reset it, or the empty band collapses to nothing */
  .pg-404 { display: block; place-items: normal; padding: 0 0 var(--s-8); }
  .pg-404 .nf-scene { position: relative; inset: auto; height: 230px; overflow: hidden; -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent); mask-image: linear-gradient(180deg, #000 72%, transparent); }
  .pg-404 .nf-scene::after { content: none; }
  .pg-404 .nf-tree { bottom: 34px; width: 128px; left: var(--gutter); }
  /* small, at the gate's foot: in this band the plate's gate is a thumb high,
     and a figure taller than it would stand in front of the light, not walk to it */
  .pg-404 .nf-wanderer { bottom: 44px; width: 26px; right: calc(22% - 22px); }
  .pg-404 .nf-fog--3 { height: 60%; }
  .pg-404 .nf-body { width: auto; margin-inline: var(--gutter); }
  /* three lines and more of centred Persian start ragged on both sides: the
     paragraph keeps its centred block and reads from its start */
  .pg-404 .nf-body > p:not(.nf-where):not(.rune) { text-align: start; max-width: 56ch; text-wrap: pretty; }
}
@media (prefers-reduced-motion: reduce) { .pg-404 .nf-fog, .pg-404 .nf-wanderer, .pg-404 .nf-raven, .pg-404 .nf-plate-art .nf-plate { animation: none; } }
:root[data-motion="off"] :is(.pg-404 .nf-fog, .pg-404 .nf-wanderer, .pg-404 .nf-raven, .pg-404 .nf-plate-art .nf-plate) { animation: none; }

/* ───────────────────────── DUST · «دوست» ───────────────────────── */
.pg-dust { padding-block: var(--s-9); text-align: center; background: radial-gradient(ellipse at 50% 0%, rgba(47,211,154,.1), transparent 50%); }
.pg-dust .dust-in { display: grid; justify-items: center; gap: var(--s-4); }
.pg-dust .dust-in p { margin: 0; text-wrap: pretty; }
/* the lead is one line on a wide screen and stays centred under the title; the
   body is prose, read from its start in a centred block of its own */
.pg-dust .dust-in > p:not(.rune):not(.dust-lead):not(.dust-foot) { text-align: start; max-width: 56ch; justify-self: center; }
.pg-dust h1 { margin: 0; font-size: var(--fs-page); }
.pg-dust .dust-lead { font-size: var(--fs-lg); color: var(--fg-strong); }
.pg-dust .dust-keeper { filter: drop-shadow(0 0 26px rgba(47,211,154,.5)); }
/* a slow nod is all the keeper does here; the arms it used to wave were never
   in the drawing */
.pg-dust .dust-keeper .keeper-head { transform-box: fill-box; transform-origin: 50% 100%; animation: dustNod 5s ease-in-out infinite; }
@keyframes dustNod { 0%, 100% { transform: rotate(0) translateY(0); } 50% { transform: rotate(-2deg) translateY(2px); } }
.pg-dust .dust-founders { list-style: none; padding: 0; margin: var(--s-4) 0 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s-3); width: 100%; text-align: start; }
.pg-dust .dust-founders li { --bd: var(--line); --facet: 8px; display: flex; align-items: center; gap: var(--s-3); padding: var(--s-3) var(--s-4); border: 1px solid var(--bd); background: var(--facet-edges), var(--bg-elev); clip-path: var(--clip-facet); }
.pg-dust .dust-founders li > span:last-child { display: grid; }
.pg-dust .dust-founders b { color: var(--fg-strong); }
.pg-dust .dust-founders small { font-size: var(--fs-xs); }
.pg-dust .dust-poem { width: 100%; margin: var(--s-4) 0 0; padding: var(--s-5) var(--s-6); border-inline-start: 2px solid var(--emerald); background: var(--bg-elev); text-align: start; box-shadow: var(--glow-inset); }
.pg-dust .dust-poem p { margin: 0 0 .5em; display: flex; gap: var(--s-3); align-items: baseline; color: var(--fg-strong); }
.pg-dust .dust-poem p:last-child { margin-bottom: 0; }
.pg-dust .dust-poem .rune { font-size: 1.3rem; letter-spacing: 0; flex: none; }
.pg-dust .dust-foot { font-size: var(--fs-sm); }
@media (max-width: 600px) {
  .pg-dust .dust-founders { grid-template-columns: 1fr; }
  /* on a phone the lead is several lines too: it reads from its start like the rest */
  .pg-dust .dust-in > p:not(.rune):not(.dust-foot) { text-align: start; justify-self: stretch; }
}
@media (prefers-reduced-motion: reduce) { .pg-dust .dust-keeper .keeper-head { animation: none; } }


/* ── Niflheim: the hall of unfinished stories ── */
.pg-niflheim { position: relative; overflow: hidden; min-height: calc(100vh - 68px); padding-block: var(--s-9); background: radial-gradient(ellipse at 50% 0%, rgba(var(--fog-color), .12), transparent 60%); }
.pg-niflheim .nf-fog { position: absolute; inset: -30%; pointer-events: none; background: radial-gradient(ellipse at 20% 60%, rgba(var(--fog-color), .14), transparent 45%), radial-gradient(ellipse at 75% 35%, rgba(var(--fog-color), .1), transparent 45%); animation: nfDrift 46s ease-in-out infinite alternate; }
/* The banks are cut by the page box, and the cut was a hard seam above the
   footer. Each bank thins out downward instead and is gone by the page's foot:
   the layer starts 30% above the section and is 160% of its height, so its
   80% line is the section's last pixel. The drift is sideways only, so the
   mask never moves against the page. */
.pg-niflheim .nf-fog { -webkit-mask-image: linear-gradient(180deg, #000 40%, transparent 80%); mask-image: linear-gradient(180deg, #000 40%, transparent 80%); }
.pg-niflheim .nf-fog--2 { animation-duration: 64s; animation-direction: alternate-reverse; opacity: .7; }
.pg-niflheim .nif-in { position: relative; z-index: 1; }
.pg-niflheim .nif-head { text-align: center; display: grid; justify-items: center; gap: var(--s-3); margin-bottom: var(--s-8); }
.pg-niflheim .nif-head .rune { color: rgb(var(--fog-color)); margin: 0; }
/* Frost's fog is pale (188,200,206): as ink on the pale ground the rune
   measured 1.1 : 1 and vanished into it. It takes the ornament ink the other
   pages' crowns wear (4.7 : 1), so it is the same motif in both themes. */
:root[data-theme="light"] .pg-niflheim .nif-head .rune { color: var(--ornament); }
.pg-niflheim .nif-head h1 { margin: 0; }
.pg-niflheim .nif-head .lead { margin: 0; font-size: var(--fs-lg); }
/* the title and the one-line lead are centred; the paragraph is prose, read
   from its start in a centred block */
.pg-niflheim .nif-head .lead { text-wrap: pretty; }
.pg-niflheim .nif-head__p { margin: 0; max-width: 56ch; margin-inline: auto; line-height: 2; text-align: start; text-wrap: pretty; }
.pg-niflheim .nif-souls { display: grid; gap: var(--s-4); max-width: 880px; margin-inline: auto; }
.pg-niflheim .nf-soul { --bd: rgba(var(--fog-color), .28); display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--s-4); align-items: center; padding: var(--s-5); background: var(--facet-edges), linear-gradient(90deg, rgba(var(--fog-color), .07), transparent 70%), var(--bg-elev); }
.pg-niflheim .nf-soul__txt { display: grid; gap: 4px; }
.pg-niflheim .nf-soul__txt h2 { margin: 0; font-size: var(--fs-lg); }
.pg-niflheim .nf-soul__txt p { margin: 0; }
.pg-niflheim .nf-soul__epitaph { font-size: var(--fs-md); line-height: 1.9; color: var(--fg); }
.pg-niflheim .nf-soul__act { display: grid; gap: var(--s-2); }
@media (max-width: 640px) { .pg-niflheim .nf-soul { grid-template-columns: auto minmax(0, 1fr); } .pg-niflheim .nf-soul__act { grid-column: 1 / -1; grid-template-columns: 1fr 1fr; } }
@media (prefers-reduced-motion: reduce) { .pg-niflheim .nf-fog { animation: none; } }
:root[data-motion="off"] .pg-niflheim .nf-fog { animation: none; }

/* ───────────────────── REPORTING ─────────────────────
   One dialog for every kind of target. The reasons are a radio list rather than
   a select: on a phone the whole set has to be readable without opening a menu.
   Nothing is ticked for the reporter, and the send button says why it waits. */
.report { display: grid; gap: var(--s-4); }
.report h2 { margin: 0; }
.report > p { margin: 0; }
.report__reasons { --bd: var(--line); --facet: 8px; border: 1px solid var(--bd); padding: var(--s-3) var(--s-4); margin: 0; display: grid; gap: var(--s-1); clip-path: var(--clip-facet); background: var(--facet-edges), var(--bg); transition: border-color var(--t-ui) var(--ease-stone); }
.report__reasons.is-error { --bd: var(--danger); }
.report__reasons legend { padding: 0 var(--s-2); font-size: var(--fs-sm); color: var(--fg-muted); }
.report__reasons .check { display: flex; align-items: center; min-height: 40px; line-height: var(--lh-ui, 1.5); }
.report__actions { gap: var(--s-3); align-items: center; flex-wrap: wrap; }
.report__actions .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; box-shadow: none; }
.report__hint { font-size: var(--fs-xs); color: var(--fg-muted); }
.report--done { display: grid; gap: var(--s-3); text-align: start; }
.report--done h2 { margin: 0; color: var(--accent-text); }
.report--done p { margin: 0; }

/* ───────────────────── PUBLIC PROFILE ─────────────────────
   The same record as Valhalla seen from outside: the hero, level, stats and
   medallions are Valhalla's rules (`:is(.pg-valhalla, .pg-profile)` above).
   Below them, what a visitor came for: the tables this member sat at, their
   public characters with the opening of each backstory, what they earned and
   what they wrote. Section headings sit well below the name. */
.pg-profile .pf-body { display: grid; gap: var(--s-7); }
.pg-profile .pf-sec { min-width: 0; }
.pg-profile .pf-sec__h { display: flex; align-items: center; gap: var(--s-3); margin: 0 0 var(--s-4); font-size: var(--fs-xl); }
.pg-profile .pf-sec__h::after { content: ""; flex: 1; min-width: 40px; height: 1px; background: linear-gradient(to left, var(--line-glow), transparent 70%); }
[dir="ltr"] .pg-profile .pf-sec__h::after { background: linear-gradient(to right, var(--line-glow), transparent 70%); }
/* nothing here yet: one quiet line in a carved frame, not a missing section */
/* solid, not dashed: a dashed edge is the system's disabled or pending sign,
   and an empty section is neither — it is simply empty */
.pg-profile .pf-none { --bd: var(--line); --facet: 10px; display: flex; align-items: center; gap: var(--s-3); max-width: none; margin: 0; padding: var(--s-4) var(--s-5); color: var(--fg-muted); border: 1px solid var(--bd); background: var(--facet-edges), color-mix(in srgb, var(--bg-elev) 45%, transparent); clip-path: var(--clip-facet); }
.pg-profile .pf-none .ico { --n: 20; flex: none; color: var(--ornament); }
.pg-profile .pf-badges { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }

.pg-profile .pf-camps { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.pg-profile .pf-camp { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 2px var(--s-3); padding: var(--s-3) var(--s-2); background: var(--bg); }
.pg-profile .pf-camp__title { font-weight: 700; color: var(--fg-strong); overflow-wrap: anywhere; }
.pg-profile .pf-camp__title:hover { color: var(--accent-text); }
.pg-profile .pf-camp__meta { grid-column: 1 / -1; font-size: var(--fs-xs); }

/* three to a row at 1280, not four: at 286px a card wrapped the name and broke
   its facts after a lozenge */
.pg-profile .pf-chars { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 360px), 1fr)); gap: var(--s-3); }
.pg-profile .pf-char { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--s-2) var(--s-3); padding: var(--s-3) var(--s-4); text-decoration: none; color: var(--fg); }
.pg-profile .pf-char[hidden] { display: none; }
.pg-profile .pf-more { margin: var(--s-4) 0 0; text-align: center; }
.pg-profile .pf-char:hover, .pg-profile .pf-char:focus-visible { --bd: var(--line-glow); text-decoration: none; }
/* the character's own face cut to the hex, framed on the head and shoulders
   as in Valhalla; in the mist it greys and dims */
:is(.pg-profile, .pg-niflheim) .pf-face { --face: 44px; position: relative; flex: none; width: var(--face); height: calc(var(--face) * 1.14); clip-path: var(--clip-hex); display: grid; place-items: center; overflow: hidden; color: var(--accent-text); background: #0A0A0B; }
:is(.pg-profile, .pg-niflheim) .pf-face .hx-portrait { width: calc(var(--face) * 1.14); height: calc(var(--face) * 1.14); flex: none; transform: translateY(-9%) scale(1.36); }
:is(.pg-profile, .pg-niflheim) .pf-face .ico { --n: 24; }
:is(.pg-profile, .pg-niflheim) .pf-face::after { content: ""; position: absolute; inset: 0; clip-path: var(--clip-hex); box-shadow: inset 0 0 0 1px var(--line-glow); pointer-events: none; }
:is(.pg-profile .pf-char.is-niflheim, .pg-niflheim) .pf-face .hx-portrait { filter: grayscale(1) brightness(.78) contrast(.9); }
:is(.pg-profile .pf-char.is-niflheim, .pg-niflheim) .pf-face::after { box-shadow: inset 0 0 0 1px rgba(var(--fog-color), .45); }
.pg-niflheim .pf-face { --face: 56px; }
.pg-profile .pf-char__txt { display: grid; gap: 2px; min-width: 0; }
.pg-profile .pf-char__txt b { color: var(--fg-strong); font-family: var(--font-display); overflow-wrap: anywhere; }
.pg-profile .pf-char__txt small { font-size: var(--fs-xs); }
.pg-profile .pf-char__txt .tag { justify-self: start; margin-top: var(--s-1); }
/* a line of facts (metaLine in misc.js): each fact holds together («سطح ۱۴»
   never splits) and carries the lozenge before it. The row is pulled back by
   one lozenge's room (5px + 2 × 8px) and its holder clips that room, so the
   first fact of every line — the first, and any that wrapped — loses its
   lozenge with the line's start: no line begins or ends on a separator. A
   fact longer than the whole line (a 45-letter name) ends in an ellipsis
   rather than pushing the page sideways. */
:is(.pg-profile, .pg-niflheim) .meta-line { display: block; overflow: hidden; }
:is(.pg-profile, .pg-niflheim) .meta-line__in { display: flex; flex-wrap: wrap; align-items: center; margin-inline-start: -21px; }
:is(.pg-profile, .pg-niflheim) .meta-part { min-width: 0; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
:is(.pg-profile, .pg-niflheim) .meta-part::before { content: ""; display: inline-block; width: 5px; height: 5px; margin-inline: 8px; vertical-align: middle; background: var(--ornament); transform: rotate(45deg); }
.pg-profile .pf-char__story { grid-column: 1 / -1; padding-inline-start: var(--s-3); border-inline-start: 2px solid var(--line-strong); font-size: var(--fs-sm); line-height: 1.9; color: var(--fg-muted); overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

.pg-profile .pf-posts { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--s-4); }
.pg-profile .pf-post { --bd: var(--line); --facet: 12px; display: flex; flex-direction: column; min-width: 0; background: var(--facet-edges), var(--bg-elev); border: 1px solid var(--bd); clip-path: var(--clip-facet); transition: border-color var(--t-ui) var(--ease-stone); }
.pg-profile .pf-post:hover, .pg-profile .pf-post:focus-within { --bd: var(--line-glow); }
/* the cover runs up into the cut corner and would hide the drawn diagonal:
   the edge is drawn once more on a layer above it */
.pg-profile .pf-post { position: relative; }
.pg-profile .pf-post::after { content: ""; position: absolute; inset: -1px; z-index: 1; background: var(--facet-edges); pointer-events: none; }
:root[data-theme="light"] .pg-profile .pf-post { --bd: rgba(24,36,34,.16); }
.pg-profile .pf-post__cover { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--bg); }
.pg-profile .pf-post__cover :is(svg, img) { display: block; width: 100%; height: 100%; object-fit: cover; }
.pg-profile .pf-post__body { display: grid; gap: var(--s-2); padding: var(--s-3) var(--s-4) var(--s-4); }
.pg-profile .pf-post__meta { margin: 0; display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2); font-size: var(--fs-xs); color: var(--fg-muted); }
.pg-profile .pf-post__title { margin: 0; font-size: var(--fs-md); line-height: 1.6; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.pg-profile .pf-post__title a { color: var(--fg-strong); }
.pg-profile .pf-post__title a:hover { color: var(--accent-text); text-decoration: none; }
.pg-profile .pf-post__likes { margin: 0; display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-xs); color: var(--accent-text); }
.pg-profile .pf-post__likes .ico { --n: 16; }
@media (max-width: 600px) {
  .pg-profile .pf-chars, .pg-profile .pf-posts { grid-template-columns: minmax(0, 1fr); }
  .pg-profile .pf-sec__h { font-size: var(--fs-lg); }
}

/* ───────────────────── RULES, PRIVACY, ABOUT, CONTACT ─────────────────────
   Long-form reading in one column of about 68 characters, with the same
   cross-links at the foot of each so a reader never has to go back up. On a
   wide screen the far side carries the contents list (rules, privacy) or the
   page's one next step (about, contact) instead of standing empty. The head
   sits on a strip of the house runestone plate (HX.art.cover('runes')): the
   stone stands on the far side, where the contents list is, and the plate
   fades out before it reaches the title, so the head reads on plain night. */
.pg-info { position: relative; padding-block: var(--s-7) var(--s-8); }
.pg-info--doc .info-plate { --to-near: right; position: absolute; inset-inline: 0; top: 0; z-index: -1; height: 340px; overflow: hidden; pointer-events: none; }
[dir="ltr"] .pg-info--doc .info-plate { --to-near: left; }
/* the stone is the middle of the plate, so the plate's width sets where it
   stands: in the room the head's ~68ch leave free, never under the title */
.pg-info--doc .info-plate__art { position: absolute; top: 0; inset-inline-end: 0; width: min(66%, calc(100% - 680px)); height: 100%; opacity: .7;
  -webkit-mask-image: linear-gradient(to var(--to-near), #000 45%, transparent 92%), linear-gradient(180deg, #000 40%, transparent 92%);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to var(--to-near), #000 45%, transparent 92%), linear-gradient(180deg, #000 40%, transparent 92%);
  mask-composite: intersect; }
/* Frost: the plate washed to pale stone, as the realm skies are */
:root[data-theme="light"] .pg-info--doc .info-plate__art { opacity: .2; filter: saturate(.5); }
/* The phone has no free side: the stone stands at the far edge, half out of
   the frame where lines end ragged, faint, and gone before the body text. */
@media (max-width: 760px) {
  .pg-info--doc .info-plate { height: 280px; }
  .pg-info--doc .info-plate__art { width: 180%; inset-inline-end: -90%; opacity: .34;
    -webkit-mask-image: linear-gradient(to var(--to-near), #000 45%, transparent 85%), linear-gradient(180deg, #000 30%, transparent 100%);
    mask-image: linear-gradient(to var(--to-near), #000 45%, transparent 85%), linear-gradient(180deg, #000 30%, transparent 100%); }
  :root[data-theme="light"] .pg-info--doc .info-plate__art { opacity: .2; }
}
.pg-info .info-wrap { max-width: 1120px; }
.pg-info .info-head { max-width: 68ch; margin-bottom: var(--s-7); }
/* the rune crowns the title on its own side: an inline run, so it follows the
   page's direction instead of being pushed to the far edge as a block */
.pg-info .info-head .rune { display: inline-block; direction: ltr; unicode-bidi: isolate; font-family: var(--font-rune); font-size: var(--rune-md); color: var(--ornament); letter-spacing: .3em; margin-bottom: var(--s-2); }
.pg-info .info-head h1 { margin: 0 0 var(--s-2); }
.pg-info .info-head .lead { margin: 0; font-size: var(--fs-lg); color: var(--fg-muted); }
.pg-info .info-grid { display: grid; grid-template-columns: minmax(0, 68ch); gap: var(--s-7); align-items: start; }
.pg-info .info-body h2 { margin-top: var(--s-6); font-size: var(--fs-xl); scroll-margin-top: calc(var(--hdr-h, 68px) + var(--s-5)); }
.pg-info .info-body h2:first-child { margin-top: 0; }
.pg-info .info-body h2:focus { outline: none; }
.pg-info .info-body li { margin-bottom: var(--s-2); }
.pg-info .info-side { display: grid; gap: var(--s-5); align-content: start; }
.pg-info .info-toc { display: none; }
@media (min-width: 1100px) {
  .pg-info .info-grid.has-side { grid-template-columns: minmax(0, 68ch) minmax(240px, 280px); gap: clamp(var(--s-7), 6vw, 112px); }
  .pg-info .info-side { position: sticky; top: calc(var(--hdr-h, 68px) + var(--s-5)); max-height: calc(100vh - var(--hdr-h, 68px) - var(--s-7)); overflow-y: auto; scrollbar-width: thin; }
  .pg-info .info-toc { display: block; }
}
@media (max-width: 1099px) { .pg-info .info-side:has(.contact-mail) { order: -1; } }
.pg-info .info-toc__h { margin: 0 0 var(--s-2); font-size: .8125rem; font-weight: 700; color: var(--fg-muted); }
.pg-info .info-toc ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; border-inline-start: 1px solid var(--line); }
.pg-info .info-toc a { display: grid; grid-template-columns: 1.5em minmax(0, 1fr); gap: var(--s-2); padding: 6px var(--s-3); margin-inline-start: -1px; border-inline-start: 2px solid transparent; color: var(--fg-muted); font-size: .8125rem; line-height: 1.55; text-decoration: none; transition: color var(--t-ui) var(--ease-stone), border-color var(--t-ui) var(--ease-stone); }
.pg-info .info-toc a:hover { color: var(--fg-strong); text-decoration: none; }
.pg-info .info-toc a[aria-current="true"] { color: var(--accent-text); border-inline-start-color: var(--emerald); font-weight: 700; }
:root[data-theme="light"] .pg-info .info-toc a[aria-current="true"] { border-inline-start-color: var(--jade); }
.pg-info .info-toc__n { font-variant-numeric: tabular-nums; }
.pg-info .info-card { --bd: var(--line-strong); --facet: 10px; display: grid; gap: var(--s-3); padding: var(--s-5); background: var(--facet-edges), var(--stone-grad); border: 1px solid var(--bd); clip-path: var(--clip-facet); box-shadow: var(--shadow-stone); }
.pg-info .info-card p { margin: 0; font-size: var(--fs-sm); line-height: var(--lh-ui, 1.6); }
.pg-info .info-card .info-card__k { font-size: var(--fs-md); font-weight: 800; color: var(--fg-strong); }
.pg-info .info-card .btn { justify-self: start; }
.pg-info .info-card__mark { justify-self: center; filter: drop-shadow(0 0 18px rgba(47,211,154,.3)); }
.pg-info .info-card__mark svg { display: block; width: 96px; height: auto; }
.pg-info .info-facts { margin: 0; display: grid; gap: var(--s-2); }
.pg-info .info-facts div { display: grid; gap: 1px; padding-bottom: var(--s-2); border-bottom: 1px solid var(--line); line-height: var(--lh-ui, 1.5); }
.pg-info .info-facts dt { color: var(--fg-muted); font-size: var(--fs-xs); }
.pg-info .info-facts dd { margin: 0; color: var(--fg-strong); font-weight: 700; font-size: var(--fs-sm); }
.pg-info .info-nav { display: flex; flex-wrap: wrap; gap: var(--s-4); max-width: 68ch; margin-top: var(--s-7); padding-top: var(--s-4); border-top: 1px solid var(--line); font-size: var(--fs-sm); }
.pg-info .info-nav a { display: inline-flex; align-items: center; min-height: 44px; }

/* contact: the in-site routes as stone slabs, then the topics as one list of
   mail links, each opening the reader's mail app with its subject filled in */
.pg-info .info-body .contact-routes { list-style: none; padding: 0; margin: 0 0 var(--s-7); display: grid; gap: var(--s-3); max-width: none; }
.pg-info .info-body .contact-routes li { --bd: var(--line); --facet: 8px; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s-4); align-items: start; margin: 0; padding: var(--s-4) var(--s-5); background: var(--facet-edges), var(--bg-elev); border: 1px solid var(--bd); clip-path: var(--clip-facet); }
:root[data-theme="light"] .pg-info .info-body .contact-routes li { --bd: rgba(24,36,34,.16); }
.pg-info .contact-routes__ico, .pg-info .contact-topic__ico, .pg-info .contact-mail__seal { width: 40px; height: 46px; display: grid; place-items: center; flex: none; clip-path: var(--clip-hex); background: var(--bg-elev-2); color: var(--accent-text); }
:root[data-theme="light"] .pg-info .contact-routes__ico, :root[data-theme="light"] .pg-info .contact-topic__ico { background: #DADDD6; }
.pg-info .contact-routes__ico .ico, .pg-info .contact-topic__ico .ico { --n: 20; }
.pg-info .info-body .contact-routes h3 { margin: 0 0 var(--s-1); font-size: var(--fs-md); }
.pg-info .info-body .contact-routes p { margin: 0; }
.pg-info .info-body .contact-routes .contact-routes__go { display: flex; gap: 0 var(--s-5); flex-wrap: wrap; margin-top: var(--s-1); font-size: var(--fs-sm); font-weight: 700; }
.pg-info .contact-routes__go a { display: inline-flex; align-items: center; min-height: 44px; }
.pg-info .info-body .contact-topics { list-style: none; padding: 0; margin: var(--s-4) 0 0; display: grid; gap: 1px; background: var(--line); border-block: 1px solid var(--line); max-width: none; }
.pg-info .info-body .contact-topics li { margin: 0; }
.pg-info .info-body .contact-topic { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--s-4); align-items: center; padding: var(--s-4) var(--s-3); background: var(--bg); color: var(--fg); text-decoration: none; transition: background var(--t-ui) var(--ease-stone); }
.pg-info .info-body .contact-topic:hover, .pg-info .info-body .contact-topic:focus-visible { background: var(--bg-elev); text-decoration: none; }
.pg-info .contact-topic__txt { display: grid; gap: 2px; min-width: 0; line-height: var(--lh-ui, 1.55); }
.pg-info .contact-topic__txt b { color: var(--fg-strong); }
.pg-info .contact-topic__txt span { color: var(--fg-muted); font-size: var(--fs-sm); }
/* the topic a page sent the reader to: lit at its inline-start edge */
.pg-info .info-body .contact-topic.is-asked { background: linear-gradient(to left, rgba(47,211,154,.1), transparent 70%), var(--bg-elev); box-shadow: inset -3px 0 0 var(--accent-text); }
:root[dir="ltr"] .pg-info .info-body .contact-topic.is-asked { background: linear-gradient(to right, rgba(47,211,154,.1), transparent 70%), var(--bg-elev); box-shadow: inset 3px 0 0 var(--accent-text); }
.pg-info .contact-topic__note { font-style: normal; font-size: var(--fs-sm); font-weight: 700; color: var(--accent-text); }
.pg-info .contact-topic__go { color: var(--fg-muted); transition: color var(--t-ui) var(--ease-stone); }
.pg-info .contact-topic__go .ico { --n: 20; }
.pg-info .contact-topic:hover .contact-topic__go { color: var(--accent-text); }
.pg-info .contact-mail__seal { width: 48px; height: 54px; background: var(--emerald-grad); color: var(--accent-fg); }
.pg-info .contact-mail__seal .ico { --n: 24; }
.pg-info .info-card .contact-mail__addr { font-size: var(--fs-md); font-weight: 700; overflow-wrap: anywhere; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.pg-info .contact-mail__addr a { color: var(--accent-text); unicode-bidi: isolate; }
.pg-info .contact-mail__do { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.pg-info .contact-mail .hint:empty { display: none; }
@media (max-width: 600px) {
  .pg-info .info-body .contact-routes li { grid-template-columns: 1fr; gap: var(--s-2); padding: var(--s-4); }
  .pg-info .info-body .contact-topic { grid-template-columns: auto minmax(0, 1fr); }
  .pg-info .contact-topic__go { display: none; }
}

