/* ============================================================
   RULES (rules.html) — the rulebook, read by the light
   Header: the crest portal opens on the standing stones (laws set in
   stone); the stego walks away from the viewer's side, into the frame
   and toward the stones (it never breaks out, unlike the other pages'
   creatures). Fog carries the band down into the page.
   Rulebook: each category is a faceted chapter plate on the spine (its
   number is the rule ids' prefix; a window onto the night opens on its
   right). Every rule row branches off the trace into its id chip, so
   the light connects to each rule as it reaches it. Outcome chips carry
   the words; violet pips repeat the heaviest outcome (no red). The
   codex beside it is the rulebook in miniature: one tick per rule, a
   via per chapter, the trace filling as you read (sticky >= 1100px;
   an index strip above the rulebook below that).
   ============================================================ */

/* ---------- header band ---------- */

.rules-band-env { z-index: 0; }
.rules-band-fog { top: auto; height: 62%; -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 45%, #000 70%, transparent 100%); mask-image: linear-gradient(180deg, transparent 0%, #000 45%, #000 70%, transparent 100%); }
.rules-band-fog > img { object-position: 50% 100%; opacity: 0.32; }
.rules-stage { --cast-x: 4%; --cast-y: 7%; --cast-w: 76%; aspect-ratio: 1.16; width: min(100%, 600px); }
/* the stego faces into the scene, toward the stones (each registered layer flips about the same centre) */
.rules-cast > img { transform: scaleX(-1); }
.rules-band .lede { max-width: 38ch; }
.rules-stones > img { object-position: 82% 46%; }
.rules-stage .portal-veil { background: linear-gradient(180deg, rgba(3, 6, 26, 0.12) 0%, rgba(3, 6, 26, 0) 30%, rgba(3, 6, 26, 0.2) 58%, rgba(3, 6, 26, 0.86) 100%); }
@media (max-width: 959.98px) {
  .rules-stage { --cast-x: 4%; --cast-y: 6%; --cast-w: 80%; width: min(84%, 460px); margin-top: 0; }
}

/* ---------- the rulebook: head + legend, codex beside the reading column ---------- */

.rules-body { padding-top: var(--s-9); overflow-x: clip; } /* the full-bleed chapter scenes never widen the page */
.rules-key > p { margin: 0 0 var(--s-3); color: var(--silver); }
.rules-key .rule-result { margin: 0; }
.rules-key-list { display: flex; flex-wrap: wrap; gap: 8px 10px; margin: 0; padding: 0; list-style: none; }

.rules-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-7) clamp(40px, 4vw, 64px); align-items: start; }
.rules-read { min-width: 0; }
@media (min-width: 1100px) {
  .rules-layout { grid-template-columns: minmax(0, 1fr) minmax(244px, 284px); }
  .rules-aside { grid-column: 2; grid-row: 1; position: sticky; z-index: 5; top: calc(var(--nav-h) + var(--s-6)); }
  .rules-read { grid-column: 1; grid-row: 1; }
}

/* ---------- the codex ---------- */

.rules-aside:has(#rules-index:empty) { display: none; } /* no JS: nothing to index */
.codex-title { margin: 0 0 var(--s-4); font-size: var(--fs-small); font-weight: 600; color: var(--steel); }
.codex-rail { position: relative; }
.rule-index { margin: 0; padding: 0; list-style: none; }
.rule-index a { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "num name" "num count"; align-items: baseline; column-gap: 12px; color: var(--silver); text-decoration: none; }
.rule-index-num { grid-area: num; font: 800 1.5rem/1 var(--font-display); font-stretch: 86%; color: var(--steel); }
.rule-index-name { grid-area: name; font: 700 1.25rem/1.15 var(--font-display); font-stretch: 92%; color: var(--silver); }
.rule-index-count { grid-area: count; font-size: var(--fs-fine); line-height: 1.4; color: var(--steel); }
.rule-index a:hover .rule-index-name, .rule-index a[aria-current] .rule-index-name { color: var(--chrome); }
.rule-index a[aria-current] .rule-index-num { color: var(--trace); }

/* wide: a tablet with the crest's chamfers; the index is a rail, each chapter as tall as its rules */
@media (min-width: 1100px) {
  .codex { --cut: var(--cut-l); position: relative; isolation: isolate; padding: 24px 22px 26px; }
  .codex::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--plate);
    clip-path: polygon(var(--cut) 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  }
  .rule-index { position: relative; display: flex; flex-direction: column; height: clamp(300px, 46vh, 420px); padding-left: 28px; }
  /* the rail, then one tick per rule (a chapter's ticks span its share of the rail) */
  .rule-index::before { content: ""; position: absolute; left: 6px; top: 6px; bottom: 0; width: 1px; background: var(--facet); }
  .rule-index > li { position: relative; flex: var(--n, 1) 1 0; min-height: 58px; }
  .rule-index > li::before {
    content: "";
    position: absolute;
    left: -26px; top: 6px; bottom: -6px;
    width: 9px;
    background: linear-gradient(180deg, transparent calc(100% - 1px), var(--rule-strong) 0) 0 0 / 9px calc(100% / var(--n, 1)) repeat-y;
  }
  .rule-index > li:last-child::before { bottom: 0; }
  .rule-index a { padding: 0 0 10px; }
  .rule-index a > .pad { --pad: 12px; left: calc(-28px + 6.5px - var(--pad) / 2); top: 6px; }
  .rule-index a[aria-current] > .pad::after { opacity: 1; }
  .codex-fill {
    position: absolute;
    left: 6px; top: 6px; bottom: 0;
    width: 1.5px;
    background: var(--trace);
    transform: scaleY(0);
    transform-origin: 50% 0;
    pointer-events: none;
  }
}
/* narrower: an index strip above the rulebook */
@media (max-width: 1099.98px) {
  .codex-fill, .rule-index .pad { display: none; }
  .rule-index { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); gap: 8px; }
  .rule-index a { --cut: var(--cut-s); isolation: isolate; min-height: 64px; padding: 12px 14px; }
  .rule-index a::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--plate);
    clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  }
  .rule-index a[aria-current]::before { background: linear-gradient(0deg, var(--trace) 0 2px, transparent 2px), var(--plate-2); }
}
@media (max-width: 479.98px) {
  .rule-index { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .rule-index a { grid-template-areas: "num" "name" "count"; grid-template-columns: minmax(0, 1fr); row-gap: 4px; padding: 10px 10px 12px; }
  .rule-index-num { font-size: 1.25rem; }
  .rule-index-name { font-size: 1.0625rem; overflow-wrap: anywhere; }
}

/* ---------- chapters ---------- */

.rulebook { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(72px, 8vw, 120px); }

/* a chapter's scene: the night plate full-bleed (out of the reading column to both viewport edges),
   fading into the page above and below; the spine runs over it, the chapter plate lands on its lower edge */
.rule-cat-scene {
  position: relative;
  width: 100vw;
  height: clamp(250px, 27vw, 420px);
  margin: calc(-1 * clamp(24px, 3vw, 48px)) 0 0 calc(-1 * (var(--gut) + var(--lane) + max(0px, (100vw - var(--container-max)) / 2)));
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 24%, #000 64%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 24%, #000 64%, transparent 100%);
}
.rule-cat-scene::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(3, 6, 26, 0.5) 0%, rgba(3, 6, 26, 0) 42%); }
.scene-veil { position: absolute; inset: 0; z-index: 1; background: var(--void); opacity: 0; }
.scene-header-canyon { right: -70%; } /* zoomed onto the river canyon, cliffs on both sides */
.scene-header-canyon > img { object-position: 0% 72%; }
.scene-crystal > img { object-position: 50% 62%; }
.scene-header-stones > img { object-position: 50% 52%; }
.rule-cat-scene + .rule-cat-bar { margin-top: calc(-1 * clamp(84px, 9vw, 136px)); }
@media (max-width: 719.98px) {
  .rules-body { padding-top: var(--s-7); }
  .rule-cat-scene { height: clamp(240px, 74vw, 340px); }
  .rule-cat-scene + .rule-cat-bar { margin-top: -56px; }
  .scene-header-canyon { right: 0; }
  .scene-header-canyon > img { object-position: 30% 70%; }
  .scene-crystal > img { object-position: 60% 62%; }
}

.rule-cat-bar {
  --cut: var(--cut-xl);
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "num title" "num count";
  align-items: end;
  column-gap: clamp(16px, 2vw, 26px);
  width: min(100%, 620px);
  margin-bottom: var(--s-3);
  padding: 26px clamp(22px, 3vw, 34px) 24px clamp(20px, 2.6vw, 30px);
}
.rule-cat-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--plate);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}
/* the chapter's light: one line along the lower bevel in its accent (data.js rules[].color) */
.rule-cat-bar::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 72%;
  height: 2px;
  background: linear-gradient(90deg, var(--cat, var(--steel)), transparent);
  opacity: 0.85;
}
.rule-cat-bar > .pad { left: calc(var(--lane) * -0.5 - var(--pad) / 2); top: calc(50% - var(--pad) / 2); }
.rule-cat-num {
  grid-area: num;
  align-self: center;
  font: 800 clamp(3.75rem, 2.9rem + 2.6vw, 5.5rem)/0.82 var(--font-display);
  font-stretch: 82%;
  color: var(--steel);
}
.rule-cat-title.h2 { grid-area: title; font-size: clamp(2.125rem, 1.6rem + 1.6vw, 3.125rem); line-height: 1; }
.rule-cat-count { grid-area: count; justify-self: start; margin-top: 12px; }
@media (max-width: 719.98px) { .rule-cat-bar { padding: 22px 20px 20px 18px; } }

/* ---------- one rule: the trace's stub lands on its id chip ---------- */

.rule-card {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "id name" "text text" "out out";
  align-items: start;
  column-gap: 14px;
  padding: 22px 0 26px;
  box-shadow: inset 0 -1px var(--rule);
}
.rule-card:last-child { box-shadow: none; }
.rule-card > .pad { --pad: 12px; left: calc(var(--lane) * -0.5 - var(--pad) / 2); top: calc(22px + 16px - var(--pad) / 2); }
.rule-card > .stub { top: 38px; }
.rule-card > p:only-child { grid-column: 1 / -1; } /* a plain-text rule (a string in data.js) */

.rule-id {
  --cut: 6px;
  grid-area: id;
  position: relative;
  isolation: isolate;
  justify-self: start;
  display: inline-grid;
  place-items: center;
  min-width: 52px;
  height: 32px;
  padding: 0 10px;
  color: var(--chrome);
  font: 700 1.0625rem/1 var(--font-display);
  font-stretch: 90%;
  white-space: nowrap;
}
.rule-id::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--hull-2);
  box-shadow: inset 0 0 0 1px rgba(126, 152, 172, 0.42);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition: box-shadow var(--dur-ui) var(--ease);
}
/* lit: the light reached the rule (always lit without motion) */
.rule-card:has(> .pad.lit) > .rule-id::before, html:not(.motion) .rule-id::before { box-shadow: inset 0 0 0 1px rgba(70, 210, 245, 0.75); }

.rule-card h4 { grid-area: name; margin: 4px 0 0; font: 600 1.1875rem/1.35 var(--font-text); color: var(--chrome); text-wrap: pretty; }
.rule-card p { grid-area: text; max-width: 62ch; margin: 10px 0 0; font-size: 1.0625rem; line-height: 1.6; color: var(--silver); }

/* a rule linked from Discord (#rule-2-3): a plate rises under it */
.rule-card::before {
  content: "";
  position: absolute;
  inset: 0 -14px;
  z-index: -1;
  background: linear-gradient(90deg, var(--trace) 0 2px, transparent 2px), var(--hull);
  opacity: 0;
}
.rule-card:target::before { opacity: 1; }

/* ---------- outcome: the words, then pips for the heaviest outcome named ---------- */

.rule-result { grid-area: out; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 16px; --tone: var(--hull); --edge: var(--rule-strong); --chip-ink: var(--silver); --pip: var(--steel); }
.rule-result.sev-mid { --tone: var(--hull-2); --edge: rgba(155, 133, 255, 0.5); --chip-ink: var(--chrome); --pip: var(--violet); }
.rule-result.sev-high { --tone: linear-gradient(180deg, rgba(201, 188, 255, 0.4) 0 1px, transparent 1px), linear-gradient(180deg, #5C48A3, #4A3A8A); --edge: rgba(201, 188, 255, 0.45); --chip-ink: var(--chrome); --pip: #DCD3FF; }
.rule-result-k { font-size: var(--fs-fine); font-weight: 500; color: var(--steel); }
.rule-result-v {
  --cut: 6px;
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
  min-height: 32px;
  padding: 5px 13px 5px 11px;
  color: var(--chip-ink);
  font: 600 var(--fs-small)/1.25 var(--font-text);
}
.rule-result-v::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--tone);
  box-shadow: inset 0 0 0 1px var(--edge);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}
.pips { display: inline-flex; flex: none; gap: 4px; }
.pips i { width: 7px; height: 7px; transform: rotate(45deg); box-shadow: inset 0 0 0 1.25px var(--pip); opacity: 0.55; }
.pips i:first-child, .sev-mid .pips i:nth-child(2), .sev-high .pips i { background: var(--pip); opacity: 1; }

/* two columns: the id hangs in its own column */
@media (min-width: 600px) {
  .rule-card { grid-template-columns: 4.5rem minmax(0, 1fr); grid-template-areas: "id name" "id text" "id out"; column-gap: 18px; }
}
/* three columns: outcomes hang down the right edge, read top to bottom like a referee's sheet */
@media (min-width: 1000px) and (max-width: 1099.98px), (min-width: 1360px) {
  .rule-card { grid-template-columns: 4.5rem minmax(0, 1fr) 17rem; grid-template-areas: "id name out" "id text out"; column-gap: 24px; }
  .rule-result { flex-direction: column; align-items: flex-start; gap: 6px; margin-top: 2px; }
}

/* ---------- the closing word on appeals, on the trace ---------- */

.rules-close { position: relative; margin-top: clamp(72px, 8vw, 112px); }
.rules-close:has(> .rules-footer-note[hidden]) { display: none; }
.rules-close > .pad { --pad: 12px; left: calc(var(--lane) * -0.5 - var(--pad) / 2); top: calc(50% - var(--pad) / 2); }
.rules-footer-note {
  --cut: var(--cut-l);
  position: relative;
  isolation: isolate;
  max-width: 54rem;
  margin: 0;
  padding: 28px clamp(24px, 3vw, 40px) 28px clamp(22px, 2.6vw, 34px);
  color: var(--chrome);
  font: 500 var(--fs-lede)/1.45 var(--font-text);
}
.rules-footer-note::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, var(--violet) 0 2px, transparent 2px), var(--plate);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%);
}
@media (max-width: 719.98px) {
  .rules-close { margin-top: var(--s-8); }
  .rules-footer-note { font-size: 1.1875rem; }
}

/* ---------- motion-only overscan: the chapter scenes drift by depth ---------- */

html.motion .rule-cat-scene > .env-layer { top: -12%; bottom: -12%; }
