/* Palette and artwork follow agemonia.com: the parchment ground, the blue
   wordmark banner and the purple filigree menu strip are that site's own
   assets, and the colours below were sampled from them.

   Agemonia's own typefaces are Landa (body) and Varna Bold (headings). Both are
   commercial and cannot ship here, so they lead the stack for anyone who has
   them installed and README.md documents how to self-host them. */
:root {
  --font-body: "Landa", "Iowan Old Style", "Palatino Linotype", Palatino,
    "Book Antiqua", Georgia, serif;
  --font-head: "Varna", "Varna Bold", "Landa", "Iowan Old Style", Georgia, serif;

  /* Sampled from the assets: banner frame, menu plum and filigree, wordmark
     gold, parchment highlight and shadow. */
  --banner-blue: #2d4b9b;
  --plum: #231923;
  --plum-lit: #5f4169;
  --gold: #d9a441;
  --gold-lit: #fff5c3;
  --parchment: #f5ebd7;
  --parchment-deep: #cdaf73;

  --bg: var(--parchment);
  --bg-image: url("assets/bg.jpg");
  --bg-texture-opacity: 1;
  --bg-texture-blend: normal;
  --bg-raised: #fdf8ec;
  --bg-veil: rgb(253 248 236 / 62%);
  --ink: #2a2318;
  --ink-soft: #6b5b45;
  --line: #c3b291;
  --line-strong: #8a7550;
  --accent: #96601a;
  --focus: #2d4b9b;

  --lane-a: rgb(205 175 115 / 13%);
  --lane-b: rgb(205 175 115 / 26%);

  /* The four primal forces, used for the orb pips. */
  --orb-aiun: #c98f18;
  --orb-aox: #6d4b8c;
  --orb-agur: #2f6b90;
  --orb-ferox: #44793f;

  /* Hourglass colours, matching the scenario cards. */
  --len-short: #4e8a4a;
  --len-medium: #2f6b90;
  --len-epic: #a83a2c;
  --star: #c8901f;

  --node-w: 208px;
  --bar-h: clamp(54px, 7.5vw, 82px);
  --shadow: 0 1px 2px rgb(42 35 24 / 22%), 0 6px 18px rgb(42 35 24 / 12%);

  color-scheme: light;
}

/* Dark mode has no counterpart on agemonia.com, so it is built from the two
   dark brand assets: the plum of the menu strip as the ground, the filigree
   mauve for rules, and the wordmark gold for accents. The parchment texture is
   kept as a faint overlay so both themes share a grain. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #191320;
    --bg-texture-opacity: 0.09;
    --bg-texture-blend: soft-light;
    --bg-raised: #251d30;
    --bg-veil: rgb(37 29 48 / 72%);
    --ink: #ece3d4;
    --ink-soft: #a08faa;
    --line: #3d3247;
    --line-strong: #8a7396;
    --accent: #e8b455;
    --focus: #8fb7e8;
    --lane-a: rgb(95 65 105 / 12%);
    --lane-b: rgb(95 65 105 / 24%);
    --orb-aiun: #e8b455;
    --orb-aox: #a37fc4;
    --orb-agur: #62a8cf;
    --orb-ferox: #74b96c;
    --len-short: #74b96c;
    --len-medium: #62a8cf;
    --len-epic: #e0705e;
    --star: #e8b455;
    --shadow: 0 1px 2px rgb(0 0 0 / 55%), 0 6px 18px rgb(0 0 0 / 38%);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #191320;
  --bg-texture-opacity: 0.09;
  --bg-texture-blend: soft-light;
  --bg-raised: #251d30;
  --bg-veil: rgb(37 29 48 / 72%);
  --ink: #ece3d4;
  --ink-soft: #a08faa;
  --line: #3d3247;
  --line-strong: #8a7396;
  --accent: #e8b455;
  --focus: #8fb7e8;
  --lane-a: rgb(95 65 105 / 12%);
  --lane-b: rgb(95 65 105 / 24%);
  --orb-aiun: #e8b455;
  --orb-aox: #a37fc4;
  --orb-agur: #62a8cf;
  --orb-ferox: #74b96c;
  --len-short: #74b96c;
  --len-medium: #62a8cf;
  --len-epic: #e0705e;
  --star: #e8b455;
  --shadow: 0 1px 2px rgb(0 0 0 / 55%), 0 6px 18px rgb(0 0 0 / 38%);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
  background-color: var(--bg);
}

/* The parchment sits behind everything as a fixed layer so the graph scrolls
   over it. In dark mode it drops to a faint grain over the plum ground. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--bg-image) center / cover no-repeat;
  opacity: var(--bg-texture-opacity);
  mix-blend-mode: var(--bg-texture-blend);
  pointer-events: none;
}

h1, h2, h3 {
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: 0.01em;
  margin: 0;
}

a { color: var(--accent); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---------- header ---------- */

.topbar { z-index: 2; }

.menu {
  display: flex;
  align-items: stretch;
  /* No padding on the top, left or bottom: the banner bleeds into all three. */
  padding: 0 1.1rem 0 0;
  min-height: var(--bar-h);
  color: var(--parchment);
  background: var(--plum) url("assets/Menu-BG.jpg") center / auto 100% repeat-x;
  border-bottom: 2px solid var(--gold);
  box-shadow: var(--shadow);
}

/* Only this wraps, so the banner keeps spanning the bar however tall it gets. */
.menu-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0 1rem;
  align-items: center;
  justify-content: space-between;
}

/* Width comes from the artwork's own ratio at the nominal bar height, and the
   height stretches to whatever the bar actually is, so the plate stays flush
   top, left and bottom even when the controls wrap onto a second row.
   `aspect-ratio` cannot do this: a stretched cross size gives the flex item no
   main size to derive from, and it collapses to zero width. */
.banner {
  flex: none;
  align-self: stretch;
  width: calc(var(--bar-h) * 1920 / 463);
  margin-right: 0.95rem;
  background: var(--banner-blue) url("assets/Agemonia_top_5-scaled.jpg")
    center / cover no-repeat;
  border-right: 1px solid var(--gold);
  box-shadow: 4px 0 10px rgb(0 0 0 / 40%);
}

.deck { display: flex; flex-direction: column; margin: 0; padding: 0.35rem 0; }

.deck-title {
  font-family: var(--font-head);
  font-size: clamp(1.05rem, 2.2vw, 1.35rem);
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1.2;
  color: var(--gold-lit);
  text-shadow: 0 1px 3px rgb(0 0 0 / 75%);
}

.deck-sub {
  font-size: 0.82rem;
  color: #d9cbdd;
  text-shadow: 0 1px 3px rgb(0 0 0 / 75%);
}
.deck-sub strong { color: var(--gold); }

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.8rem;
  align-items: center;
  /* Matches the bar's right padding for when the header wraps onto two rows. */
  padding: 0.4rem 0 0.4rem 1.1rem;
}

/* Controls sit on the plum strip in both themes, so they carry their own dark
   palette rather than the theme tokens. */
input[type="search"], .levels label, .levels .toggle-all, .buttons button {
  color: var(--parchment);
  background: rgb(0 0 0 / 32%);
  border: 1px solid var(--plum-lit);
}

input[type="search"] {
  font: inherit;
  font-size: 0.9rem;
  padding: 0.35rem 0.6rem;
  min-width: 11.5rem;
  border-radius: 3px;
}
input[type="search"]::placeholder { color: #b09cb6; }

.levels {
  display: flex;
  gap: 0;
  margin: 0; padding: 0; border: 0;
}

.levels label {
  font-size: 0.8rem;
  padding: 0.3rem 0.55rem;
  cursor: pointer;
  border-right-width: 0;
  user-select: none;
}
.levels label:first-of-type { border-radius: 3px 0 0 3px; }
.levels label:last-of-type { border-radius: 0 3px 3px 0; border-right-width: 1px; }
.levels label:has(:checked) {
  background: var(--gold);
  border-color: var(--gold);
  color: #2a2318;
  font-weight: 700;
}
.levels label:focus-within { outline: 2px solid var(--gold-lit); outline-offset: 1px; }
.levels input { position: absolute; opacity: 0; pointer-events: none; }

.levels .toggle-all {
  font: inherit;
  font-size: 0.8rem;
  padding: 0.3rem 0.55rem;
  margin-left: 0.4rem;
  border-radius: 3px;
  cursor: pointer;
}
.levels .toggle-all:hover { background: var(--plum-lit); }

.buttons { display: flex; gap: 0.4rem; }

.buttons button {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.35rem 0.75rem;
  border-radius: 3px;
  cursor: pointer;
}
.buttons button:hover { background: var(--plum-lit); }

/* ---------- layout ---------- */

main {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

.canvas {
  flex: 1 1 auto;
  min-width: 0;
  position: relative;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
}
.canvas.dragging { cursor: grabbing; }
.canvas:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }

#graph { width: 100%; height: 100%; display: block; }

.status {
  position: absolute;
  inset: auto 0 auto 0;
  top: 45%;
  text-align: center;
  color: var(--ink-soft);
}
.status[hidden] { display: none !important; }

/* ---------- graph pieces ---------- */

.lane-band { fill: var(--lane-a); }
.lane-band.alt { fill: var(--lane-b); }

.lane-label {
  font-family: var(--font-head);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  fill: var(--ink-soft);
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 3px;
  stroke-linejoin: round;
}

.edge {
  fill: none;
  stroke: var(--line-strong);
  stroke-width: 1.6;
}
.edge.forced { stroke: var(--accent); stroke-width: 2.6; }
.edge.exclusive { stroke-dasharray: 7 5; }

.edge-label {
  font-size: 10.5px;
  fill: var(--ink-soft);
  text-anchor: middle;
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 4px;
  stroke-linejoin: round;
}

.node { cursor: pointer; }

.node-box {
  fill: var(--bg-raised);
  stroke: var(--line-strong);
  stroke-width: 1.4;
  rx: 5;
}
.node.arena .node-box { stroke-dasharray: 5 3; }
.node.selected .node-box { stroke: var(--focus); stroke-width: 3; }

.node-id {
  font-family: var(--font-head);
  font-size: 15px;
  font-weight: 700;
  fill: var(--accent);
}
.node-title { font-size: 12.5px; fill: var(--ink); }
.node-meta { font-size: 10.5px; fill: var(--ink-soft); }

.orb { fill: var(--pip); stroke: var(--bg-raised); stroke-width: 1; }
.orb.held { fill: none; stroke: var(--pip); stroke-width: 1.8; }

.sym path { stroke-width: 0.7; stroke-linejoin: round; }

/* Dimming for search and filters. */
.node.dimmed, .edge.dimmed, .edge-label.dimmed { opacity: 0.13; }
.node.hidden, .edge.hidden, .edge-label.hidden,
.lane-band.hidden, .lane-label.hidden { display: none; }

/* ---------- legend ---------- */

.legend {
  position: absolute;
  left: 0.9rem;
  bottom: 0.9rem;
  max-width: 15rem;
  font-size: 0.75rem;
  color: var(--ink);
  background: var(--bg-veil);
  backdrop-filter: blur(3px);
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  box-shadow: var(--shadow);
}

.legend summary {
  padding: 0.3rem 0.6rem;
  font-family: var(--font-head);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
}
.legend[open] summary { border-bottom: 1px solid var(--line); }

.legend-body {
  display: grid;
  grid-template-columns: 1.4rem 1fr;
  gap: 0.2rem 0.4rem;
  align-items: center;
  padding: 0.45rem 0.6rem 0.55rem;
}
.legend-body svg { display: block; justify-self: center; overflow: visible; }
.legend-body span { line-height: 1.25; }
.legend-body hr {
  grid-column: 1 / -1;
  width: 100%;
  margin: 0.25rem 0;
  border: 0;
  border-top: 1px solid var(--line);
}

/* ---------- detail panel ---------- */

.panel {
  position: relative;
  flex: 0 0 21rem;
  max-width: 90vw;
  overflow-y: auto;
  padding: 1.1rem 1.2rem 2rem;
  background: var(--bg-veil);
  backdrop-filter: blur(3px);
  border-left: 1px solid var(--line-strong);
  box-shadow: var(--shadow);
}
.panel[hidden] { display: none; }

.panel-close {
  position: absolute;
  top: 0.5rem; right: 0.6rem;
  padding: 0 0.4rem;
  font: inherit;
  font-size: 1.3rem;
  line-height: 1.4;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: pointer;
}
.panel-close:hover { border-color: var(--line); }

.panel h2 { font-size: 1.15rem; }
.panel .eyebrow {
  font-family: var(--font-head);
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.15rem;
}
.panel .subtitle { margin: 0.15rem 0 0; color: var(--ink-soft); font-style: italic; }

.panel h3 {
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 1.3rem 0 0.35rem;
  padding-bottom: 0.2rem;
  border-bottom: 1px solid var(--line);
}

.panel ul { margin: 0.3rem 0; padding-left: 1.1rem; }
.panel li { margin: 0.25rem 0; }
.panel p { margin: 0.3rem 0; }

.tags { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.6rem; }
.tag {
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.15rem 0.45rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--ink-soft);
}
.tag.len-short { border-color: var(--len-short); color: var(--len-short); }
.tag.len-medium { border-color: var(--len-medium); color: var(--len-medium); }
.tag.len-epic { border-color: var(--len-epic); color: var(--len-epic); }

.jump {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

.cond { color: var(--ink-soft); font-style: italic; }

.orb-chip { display: inline-flex; align-items: center; gap: 0.35rem; }
.orb-chip::before {
  content: "";
  width: 0.7em; height: 0.7em;
  border-radius: 50%;
  background: var(--chip, var(--ink-soft));
  box-shadow: 0 0 0 1px rgb(0 0 0 / 25%);
}

/* Reads as one of the panel's section headings, but folded until asked for.
   The marker is drawn by hand because `display: flex` drops the native one. */
.spoiler summary {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  justify-content: space-between;
  margin: 1.3rem 0 0.35rem;
  padding-bottom: 0.2rem;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  user-select: none;
  list-style: none;
}
.spoiler summary::-webkit-details-marker { display: none; }
.spoiler summary:hover { color: var(--ink); }

.spoiler .heading::before {
  content: "\25B8";
  display: inline-block;
  margin-right: 0.4rem;
  transition: transform 120ms ease;
}
.spoiler[open] .heading::before { transform: rotate(90deg); }

.spoiler-note {
  flex: none;
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  padding: 0.05rem 0.4rem;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
}

.todo {
  margin-top: 1rem;
  padding: 0.5rem 0.7rem;
  font-size: 0.85rem;
  background: rgb(217 164 65 / 18%);
  border-left: 3px solid var(--gold);
}

/* ---------- footer ---------- */

.footer {
  padding: 0.7rem 1.1rem;
  font-size: 0.78rem;
  color: #cbbcd0;
  background: var(--plum);
  border-top: 2px solid var(--gold);
}
.footer p { margin: 0.15rem 0; }
.footer a { color: var(--gold); }
.footer code { color: var(--parchment); }

/* Narrow screens: the banner keeps a fixed height rather than stretching to a
   tall wrapped bar, and `display: contents` lifts the deck and controls out of
   .menu-body so the controls can claim a full-width row of their own instead of
   being squeezed into what is left beside the banner. */
@media (max-width: 720px) {
  .menu { flex-wrap: wrap; align-items: center; padding: 0 0.8rem 0 0; }
  .menu-body { display: contents; }
  .banner { align-self: flex-start; height: var(--bar-h); }
  .deck { flex: 1 1 0; min-width: 0; }
  .controls { flex: 1 1 100%; padding: 0.1rem 0 0.5rem 0.8rem; }
  input[type="search"] { flex: 1 1 100%; min-width: 0; }
  .deck-sub { display: none; }

  main { flex-direction: column; }
  .panel { flex: 0 0 auto; max-height: 45%; border-left: 0; border-top: 1px solid var(--line-strong); }
  .legend { left: 0.5rem; bottom: 0.5rem; max-width: 11rem; font-size: 0.7rem; }
}
