/* Héraldique: classless. Look comes from elements, ARIA and structure. data-* names game facts only. */
:root {
  color-scheme: light;
  accent-color: var(--accent);
  --bg: #f6f0e4;
  --surface: #fffdf8;
  --surface-2: #efe2cb;
  --text: #22181a;
  --text-muted: #5e4d48;
  --accent: #035682;
  --accent-text: #ffffff;
  --gold: #7f5d0a;
  --border: #d8c4a2;
  --danger: #a8410c;
  --danger-text: #ffffff;
  --success: #2c6a34;
  --paper: #fbf4e2;
  --scrim: rgb(34 24 26 / .45);

  --font-display: "Cinzel", "Trajan Pro", Georgia, serif;
  --font-body: "Alegreya Sans", "Gill Sans", "Segoe UI", system-ui, sans-serif;

  --s1: .25rem; --s2: .5rem; --s3: .75rem; --s4: 1rem; --s5: 1.5rem; --s6: 2rem;
  --radius: 6px;
  --radius-lg: 12px;
  --tap: 44px;
  --lift: 0 1px 0 color-mix(in oklch, var(--border), transparent 20%), 0 10px 24px -18px color-mix(in oklch, var(--text) 70%, transparent);
  --lift-hover: 0 1px 0 color-mix(in oklch, var(--border), transparent 20%), 0 16px 28px -16px color-mix(in oklch, var(--text) 80%, transparent);
  --card: 20rem;
}

*, *::before, *::after { box-sizing: border-box }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 1.0625rem/1.5 var(--font-body);
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100% }
svg { display: block; flex: none; width: 1.375rem; height: 1.375rem }
h1, h2, h3 { font-family: var(--font-display); font-weight: 600; line-height: 1.2; letter-spacing: .03em; text-wrap: balance; margin: 0 }
h1 { font-size: 1.375rem }
h2 { font-size: 1.2rem }
h3 { font-size: 1.05rem }
h4 { margin: 0; font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted) }
p { margin: 0; text-wrap: pretty }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: .2em }
small { font-size: .875rem; color: var(--text-muted) }
strong { font-weight: 700 }
data, time, dd, output { font-variant-numeric: tabular-nums }
:focus-visible { outline: 3px solid color-mix(in oklch, var(--accent) 65%, transparent); outline-offset: 2px }

/* Buttons: filled = acts on the game. Outline = a second choice, a cancel, or opens a panel. The button after a cancel is the primary one. */
[hidden] { display: none !important }
form { display: grid; gap: var(--s3) }
form:has(> section) { gap: var(--s6) }
:is(main, section) > header:has(> h1) { display: grid; justify-content: start; gap: var(--s1); > small > svg { display: inline; width: 1.1em; height: 1.1em; vertical-align: -.2em; margin-inline: .15em } }
main > footer:last-child, main > form > footer:last-child, main > form:last-of-type > footer {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--s2);
  padding-block-start: var(--s4); border-block-start: 1px solid var(--border);
  > button { flex: 1 1 9rem }
  > button:first-child:not([value="cancel"]) { order: 1 }
}
@container main (width >= 44rem) { main > footer:last-child > button, main > form > footer:last-child > button { flex: none } }
:where(button) {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: var(--tap); padding: 0 1.15rem;
  font: 700 1rem/1 var(--font-body); letter-spacing: .02em;
  color: var(--accent-text); background: var(--accent);
  border: 1px solid var(--accent); border-radius: var(--radius);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .18), 0 1px 0 color-mix(in oklch, var(--accent), black 40%);
  cursor: pointer; touch-action: manipulation;
  transition: background-color .15s, border-color .15s, color .15s, translate .05s;
  &:hover { background: color-mix(in oklch, var(--accent), black 12%) }
}
button:active { translate: 0 1px }
:where(button ~ button:not(button[value="cancel"] ~ button, [formaction]), button[value="cancel"], button[commandfor]:not([command="close"], [command^="--"], footer > :last-child), fieldset > div > button) {
  color: var(--accent); background: transparent; border-color: var(--border); box-shadow: none;
  &:hover { background: var(--surface-2); border-color: var(--accent) }
}
button[data-danger] {
  color: var(--danger-text); background: var(--danger); border-color: var(--danger);
  &:hover { background: color-mix(in oklch, var(--danger), black 12%) }
}
button[data-link] {
  margin-inline-end: auto; padding-inline: var(--s2); background: none; border-color: transparent; box-shadow: none;
  &[data-danger] { color: var(--danger) }
  &:hover { background: none; text-decoration: underline }
}
button[aria-label] {
  min-width: var(--tap); padding: 0; position: relative;
  color: var(--text); background: transparent; border-color: transparent; box-shadow: none; font-size: 1.25rem;
  &:hover { background: var(--surface-2); border-color: transparent }
}
button:disabled, button:disabled:hover {
  color: var(--text-muted); background: var(--surface-2); border-color: var(--border); box-shadow: none; cursor: not-allowed; translate: none;
}
form > button:last-of-type {
  width: 100%; min-height: 52px; font-family: var(--font-display); font-size: 1.05rem; letter-spacing: .08em; text-transform: uppercase;
}
:where(form, main) > footer:has(> a) {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2);
  > a { margin-inline-end: auto; display: inline-flex; align-items: center; min-height: var(--tap); padding-inline: var(--s2); font-weight: 700; text-decoration: none }
  > button { flex: 1 1 9rem }
}

/* Inputs. A group is a row of controls; a group around a number is a stepper; a group of links is a filter. */
label { display: grid; gap: var(--s1); font-weight: 500 }
input:not([type="range"], [type="radio"], [type="checkbox"]), select {
  min-height: var(--tap); width: 100%; padding: 0 var(--s3);
  font: inherit; color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius);
}
input[type="range"] { width: 100%; margin: 0; accent-color: var(--accent) }
input:user-invalid { border-color: var(--danger) }
select { appearance: none; padding-inline-end: 2.25rem; background: var(--surface) no-repeat right .75rem center / .7rem; background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%), linear-gradient(-45deg, transparent 50%, var(--text-muted) 50%); background-size: .35rem .35rem; background-position: right 1.05rem center, right .7rem center }
[role="group"] {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2);
  &:has(> input[type="number"]) {
    justify-self: start; width: max-content;
    display: inline-grid; grid-template-columns: var(--tap) 4.5rem var(--tap); align-items: stretch;
    border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); overflow: hidden;
  }
  > input[type="number"] {
    border: 0; border-inline: 1px solid var(--border); border-radius: 0; text-align: center; font-weight: 700; appearance: textfield; padding: 0;
    &::-webkit-inner-spin-button { display: none }
  }
  > button[aria-label] { flex: none; border-radius: 0; color: var(--accent); font-weight: 700 }
}


/* A figure of several images shows them side by side, split by slanted gold seams. Straight in main, it is the hero being built. */
figure:has(> img + img) {
  display: flex; background: var(--gold);
  > img { flex: 1; min-width: 0; height: 100%; aspect-ratio: auto; object-fit: cover }
  > img:first-child { clip-path: polygon(0 0, calc(100% - 1.5px) 0, calc(100% - 1.5rem - 1.5px) 100%, 0 100%) }
  > img + img { margin-inline-start: -1.5rem; clip-path: polygon(calc(1.5rem + 1.5px) 0, calc(100% - 1.5px) 0, calc(100% - 1.5rem - 1.5px) 100%, 1.5px 100%) }
  > img:last-of-type { clip-path: polygon(calc(1.5rem + 1.5px) 0, 100% 0, 100% 100%, 1.5px 100%) }
}
:is(article > header ~ figure, dialog figure:not(dialog article > figure)) {
  margin: 0; aspect-ratio: 5; overflow: hidden; pointer-events: none; border: 1px solid var(--border); border-radius: var(--radius);
  > img { width: 100%; height: 100%; aspect-ratio: auto; max-height: none; object-fit: cover }
  &:has(> img + img) { aspect-ratio: 4; border-color: var(--gold) }
}
article > figure:has(> img + img) { aspect-ratio: 16 / 7; max-height: 14rem }

main > header:has(> h2) { display: grid; justify-items: center; gap: var(--s2); text-align: center; > h2 { font-size: 1.6rem } > p { color: var(--text-muted); > svg { display: inline; width: 1.2rem; height: 1.2rem; vertical-align: -.25em; margin-inline-end: .25em } } }
main > header:has(> svg:last-child) {
  position: relative; display: grid; justify-items: center; gap: var(--s3); width: 100%; max-width: 48rem; justify-self: center; margin-block-end: var(--s6);
  padding: var(--s6) var(--s6) 3.5rem; text-align: center; background: var(--paper); border: 1px solid #c9a24a; border-radius: 4px;
  box-shadow: inset 0 0 0 6px var(--paper), inset 0 0 0 7px #c9a24a, 0 14px 30px -20px rgb(34 24 26 / .8);
  > p:first-child { padding-block-end: var(--s3); border-block-end: 1px solid #c9a24a; font: 700 .8rem/1 var(--font-body); letter-spacing: .28em; text-transform: uppercase; color: var(--gold) }
  > h2 { font: italic 600 clamp(2rem, 6cqi, 2.9rem)/1.1 Georgia, serif; &::before { content: "❧ " } &::after { content: " ☙" } &::before, &::after { font-style: normal; color: #c9a24a } > :is(ins, del) { font-weight: inherit } }
  > time { font: italic .95rem/1.2 Georgia, serif; color: var(--text-muted) }
  > h2 + p { font: 1.1rem/1.4 Georgia, serif; color: var(--text-muted) }
  > svg { position: absolute; left: 50%; bottom: -1.3rem; translate: -50% 0; z-index: 1; width: 2.1rem; height: 2.1rem; filter: grayscale(1) brightness(2.2) sepia(.4) }
  &::after {
    content: ""; position: absolute; left: 50%; bottom: -2.6rem; translate: -50% 0; width: 5.25rem; height: 5.25rem; border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #c8394a, #9e1b2a 55%, #6d0f1b); box-shadow: 0 6px 12px -4px rgb(0 0 0 / .5), inset 0 0 0 5px rgb(0 0 0 / .12);
  }
}

/* Tags, badges, diffs, meters */
mark {
  display: inline-flex; align-items: center; gap: .3em; padding: .2em .6em; white-space: nowrap;
  font: 700 .75rem/1.1 var(--font-body); letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted); background: transparent; border: 1px solid currentColor; border-radius: 99px;
  &[data-affinity="bonus"] { color: var(--success) }
  &[data-affinity="malus"] { color: var(--danger) }
  > svg { width: 1.1em; height: 1.1em }
}
[data-resource] {
  white-space: nowrap;
  > svg { display: inline; width: 1.1em; height: 1.1em; vertical-align: -.2em }
}
ins { text-decoration: none; color: var(--success); font-weight: 700 }
del { text-decoration: none; color: var(--danger) }
article[data-empty] {
  justify-items: center; text-align: center; padding-block: var(--s5); color: var(--text-muted); box-shadow: none; background: color-mix(in oklch, var(--surface) 60%, transparent);
  > svg { width: 2rem; height: 2rem; opacity: .6 }
  > p { max-width: 40ch }
}

dl {
  margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 6rem), 1fr)); gap: var(--s3);
  > div { display: grid; gap: 2px; min-width: 0 }
  > div:has(> dd > :is(a, mark) ~ :is(a, mark), > dd > p) { grid-column: 1 / -1 }
}
dialog dl { grid-template-columns: repeat(auto-fit, minmax(min(100%, 7.5rem), 1fr)) }
p[data-chips] {
  display: flex; flex-wrap: wrap; gap: var(--s2); max-width: none;
  > :is(span, a) { display: inline-flex; align-items: center; gap: var(--s1); padding: var(--s1) var(--s3) var(--s1) var(--s2); border-radius: 999px; background: var(--surface-2); font-weight: 700; font-variant-numeric: tabular-nums; > svg { width: 1.15rem; height: 1.15rem } }
}
:is(dialog, article) section:has(> :is(dl[data-ledger], p[data-chips])) { display: grid; gap: var(--s1); > h4 { margin: 0 } }
dl[data-ledger] {
  display: block;
  > div[data-missing] > :is(dt, dd) { color: var(--danger); font-weight: 700 }
  > div {
    display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); padding-block: var(--s2);
    border-block-end: 1px solid color-mix(in oklch, var(--border) 55%, transparent);
    &:last-child { border-block-end: 0 }
    > dt { flex: none; max-width: 60%; font-size: 1rem; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--text-muted); &:only-child { color: var(--text) } }
    > dd { min-width: 0; margin: 0; text-align: end; font-weight: 400; > p { margin: 0 } }
    &:has(> dt:only-child) > dt > p { margin: 0 }
  }
}
fieldset {
  display: grid; gap: var(--s2); margin: 0; padding: 0; border: 0;
  > legend { margin-block-end: var(--s1); padding: 0; font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted) }
  > div {
    display: flex; align-items: center; gap: var(--s3); padding: var(--s1) var(--s1) var(--s1) var(--s3); border: 1px solid var(--border); border-radius: var(--radius);
    > span { margin-inline-start: auto; color: var(--text-muted) }
  }
}
dt {
  font-size: .72rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted);
  &:has(> svg) { display: flex; align-items: center; gap: var(--s1) }
  > svg { width: 1rem; height: 1rem }
}
dd {
  margin: 0; font-weight: 700; font-size: 1.05rem;
  > small { font-weight: 400 }
}

/* Status messages (after Post/Redirect/Get) */
[role="alert"], p[data-notice] {
  display: flex; gap: var(--s2); align-items: baseline; padding: var(--s3) var(--s4);
  border-radius: var(--radius); border: 1px solid; font-weight: 500;
}
[role="alert"], p[data-notice="error"] { color: var(--danger); background: color-mix(in oklch, var(--danger) 9%, var(--surface)); border-color: color-mix(in oklch, var(--danger) 35%, transparent) }

/* Cards: an article. Header = name and tag. Figure = art. dl = numbers. Footer = actions. A form inside a card ends with the card footer. */
article {
  overflow-wrap: break-word;
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s3); align-content: start; min-width: 0;
  padding: var(--s4); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--lift);
  > figure {
    margin: calc(-1 * var(--s4)) calc(-1 * var(--s4)) 0; overflow: hidden; border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0; border-block-end: 1px solid var(--border);
    > img { width: 100%; aspect-ratio: 16 / 7; max-height: 14rem; object-fit: cover }
  }
  > header + figure { margin: 0 calc(-1 * var(--s4)); aspect-ratio: 16 / 7; max-height: 14rem; border: 0; border-block: 1px solid var(--border); border-radius: 0 }
  > header + figure:has(> img + img) { aspect-ratio: 16 / 7; border-color: var(--border) }
  > [data-pills] { position: absolute; top: -.6rem; right: -.6rem; z-index: 2; display: flex; gap: var(--s1); pointer-events: none }
  > data, > [data-pills] > data {
    position: absolute; top: -.6rem; right: -.6rem; z-index: 2; pointer-events: none;
    min-width: 2rem; padding: .2rem .7rem; text-align: center;
    border: 1px solid color-mix(in oklch, var(--gold) 45%, var(--border)); border-radius: 999px;
    background: color-mix(in oklch, var(--gold) 6%, var(--surface)); color: var(--text);
    font: 400 1rem/1.3 var(--font-body); font-variant-numeric: tabular-nums; box-shadow: var(--lift);
  }
  > [data-pills] > data { position: static }
  > button[aria-label][data-danger] {
    position: absolute; top: -.6rem; left: -.6rem; z-index: 2; min-width: 0; min-height: 0; padding: .3rem .6rem;
    border: 1px solid color-mix(in oklch, var(--gold) 45%, var(--border)); border-radius: 999px;
    background: color-mix(in oklch, var(--gold) 6%, var(--surface)); box-shadow: var(--lift);
    &:hover { border-color: var(--danger); background: color-mix(in oklch, var(--danger) 10%, var(--surface)) }
    > svg { width: 1.2rem; height: 1.2rem }
  }
  &:has(> header input:is([type="checkbox"], [type="radio"])) {
    > header label { display: flex; align-items: center }
    &:has(input:checked) { border-color: var(--accent); background: color-mix(in oklch, var(--accent) 6%, var(--surface)) }
    &:has(input:not(:checked)) { opacity: .5; box-shadow: none }
    &:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px }
  }
  > data > svg, > [data-pills] > data > svg { display: inline; width: 1em; height: 1em; vertical-align: -.15em; margin-inline-end: .25em }
  > data[data-missing] { color: var(--danger); border-color: color-mix(in oklch, var(--danger) 45%, var(--border)); background: color-mix(in oklch, var(--danger) 8%, var(--surface)) }
  > :is(figure, header, data, [data-pills]) + p[data-chips] { gap: var(--s1); font-size: .85rem; > span { padding: 2px var(--s2) 2px var(--s1); > svg { width: 1rem; height: 1rem } } > mark { padding: 2px var(--s2); border: 0; background: var(--surface-2); font-size: inherit; line-height: inherit; letter-spacing: normal; text-transform: none; > svg { width: 1rem; height: 1rem } } }
  > header {
    display: flex; align-items: center; justify-content: space-between; gap: var(--s2); flex-wrap: wrap;
    > :is(h2, h3) {
      display: flex; align-items: baseline; gap: var(--s2); font-size: 1.05rem; font-weight: 400;
      > svg { align-self: start }
      &:has(> small), > button:has(> small) { flex-wrap: wrap }
      small { display: flex; gap: 2px; align-self: center; > svg { width: 1rem; height: 1rem } }
    }
    > mark { white-space: normal }
    > h3:has(> button[commandfor]) { flex: 1; min-width: 0; > button { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; > svg { display: inline; vertical-align: -.2em; margin-inline-end: var(--s2) } } }
    data { font-family: var(--font-body); font-weight: 700; color: var(--text-muted) }
    :is(a, button[commandfor], button[form], label) {
      color: inherit; text-decoration: none;
      &::after { content: ""; position: absolute; inset: 0; border-radius: inherit }
    }
    label { min-height: 0; gap: var(--s2); font-weight: inherit; cursor: pointer; > input { position: absolute; opacity: 0; pointer-events: none } }
    :is(button[commandfor], button[form]) { min-height: 0; padding: 0; gap: inherit; font: inherit; letter-spacing: inherit; text-align: start; justify-content: start; align-items: start; background: none; border: 0; box-shadow: none; translate: none }
  }
  &:has(> header :is(a, button[commandfor], button[form], label)) {
    transition: translate .15s, box-shadow .15s, border-color .15s, opacity .15s, filter .15s;
    &:hover { border-color: var(--accent); translate: 0 -2px; box-shadow: var(--lift-hover) }
  }
  > :is(footer, form) { position: relative; z-index: 1 }
  > :is(footer, form > footer) {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--s2);
    > small:first-child { margin-inline-end: auto }
  }
  > p { color: var(--text-muted) }
  & article { box-shadow: none; background: var(--bg) }
  &[data-state="success"] { border-color: color-mix(in oklch, var(--success) 55%, var(--border)); background: color-mix(in oklch, var(--success) 7%, var(--surface)) }
  &[data-state="warning"] { border-color: color-mix(in oklch, var(--danger) 55%, var(--border)); background: color-mix(in oklch, var(--danger) 7%, var(--surface)) }
  &[role="status"] { grid-template-columns: auto 1fr; align-items: center; gap: var(--s4); border-inline-start: 4px solid var(--success); > svg { width: 2.5rem; height: 2.5rem } > p { margin: 0; color: var(--text); font-weight: 500 } }
  &[data-slot] { border-style: dashed; box-shadow: none; background: transparent; color: var(--text-muted); > figure { display: grid; place-items: center; aspect-ratio: 16 / 7; max-height: 14rem; border-block-end-style: dashed; font-size: 2rem } }
  &[data-state="unavailable"] { box-shadow: none; > :not(data, dialog, button, [data-pills]) { opacity: .6 } > figure { filter: grayscale(1) } }
}
article > footer > a, main > a, section > a:last-child {
  display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 700; text-decoration: none;
  &::after { content: "\203A"; margin-inline-start: .35em; font-size: 1.2em; line-height: 1 }
}
dialog > footer > a {
  display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap); padding: 0 1.15rem;
  font: 700 1rem/1 var(--font-body); letter-spacing: .02em; text-decoration: none;
  color: var(--accent-text); background: var(--accent); border: 1px solid var(--accent); border-radius: var(--radius);
  &:hover { background: color-mix(in oklch, var(--accent), black 12%) }
}
:has(> article + article):not(main) {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); gap: var(--s3);
  > :not(article) { grid-column: 1 / -1 }
}
section {
  display: grid; gap: var(--s3); min-width: 0;
  &:has(> section) { gap: var(--s5) }
  > header { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); > h3 { margin: 0; font-size: 1rem; color: var(--text-muted) } > h2 { display: flex; align-items: center; gap: var(--s2); > svg { width: 1.2em; height: 1.2em } } }
  > header + article:has(> figure) {
    padding-inline-start: calc(8rem + var(--s4));
    > figure { position: absolute; inset: 0 auto 0 0; width: 8rem; margin: 0; border-block-end: 0; border-inline-end: 1px solid var(--border); border-radius: calc(var(--radius-lg) - 1px) 0 0 calc(var(--radius-lg) - 1px); > img { height: 100%; aspect-ratio: auto; max-height: none } }
  }
}
aside { display: grid; gap: var(--s5); align-content: start; min-width: 0 }

/* Details */
details {
  > summary {
    cursor: pointer; list-style: none; display: flex; align-items: center; gap: var(--s2); min-height: var(--tap); font-weight: 700;
    &::-webkit-details-marker { display: none }
    &::after { content: ""; width: .45rem; height: .45rem; margin-inline-start: auto; border: solid var(--text-muted); border-width: 0 2px 2px 0; rotate: 45deg; translate: 0 -2px; transition: rotate .15s }
  }
  &[open] > summary::after { rotate: 225deg; translate: 0 2px }
}

/* Dialogs: bottom sheet on a phone, centred above 640px. */
dialog {
  width: 100%; max-width: 100%; max-height: 88dvh; margin: auto 0 0; padding: 0; gap: 0;
  color: var(--text); background: var(--surface); border: 1px solid var(--border); border-block-end: 0;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0; box-shadow: 0 -12px 40px -20px rgb(0 0 0 / .5);
  overscroll-behavior: contain;
  transition: translate .25s ease-out, opacity .25s, display .25s allow-discrete, overlay .25s allow-discrete;
  &[open] {
    display: flex; flex-direction: column; translate: 0 0; opacity: 1;
    @starting-style { translate: 0 100% }
  }
  &:not([open]) { translate: 0 100% }
  &::backdrop { background: var(--scrim); transition: opacity .25s, display .25s allow-discrete, overlay .25s allow-discrete; opacity: 0 }
  &[open]::backdrop {
    opacity: 1;
    @starting-style { opacity: 0 }
  }
  > header {
    position: sticky; top: 0; z-index: 1; display: flex; align-items: center; gap: var(--s2);
    padding: var(--s2) var(--s2) var(--s2) var(--s4); background: var(--surface); border-block-end: 1px solid var(--border);
    > :is(h2, h3) { flex: 1; display: flex; align-items: center; gap: var(--s2) }
    &::before { content: ""; position: absolute; top: 6px; left: 50%; translate: -50% 0; width: 2.5rem; height: 4px; border-radius: 99px; background: var(--border) }
  }
  > :not(header, footer) { padding: var(--s4); overflow-y: auto; display: grid; gap: var(--s4); align-content: start }
  > footer, > form > footer {
    display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s2);
    padding: var(--s3) var(--s4) calc(var(--s3) + env(safe-area-inset-bottom, 0px)); border-block-start: 1px solid var(--border); background: var(--surface);
  }
  > form {
    padding: 0; gap: 0;
    > div { padding: var(--s4); display: grid; gap: var(--s4) }
  }
  @media (width >= 640px) {
    & {
      max-width: 30rem; margin: auto; border-radius: var(--radius-lg); border-block-end: 1px solid var(--border);
      > header::before { display: none }
    }
  }
}

/* App shell: body > header (top bar + resources), body > aside (menu), main. */
body > header {
  position: sticky; top: env(safe-area-inset-top, 0px); z-index: 20;
  display: grid; grid-template-columns: var(--tap) 1fr var(--tap); align-items: center;
  padding: var(--s1) max(var(--s2), env(safe-area-inset-right, 0px)) 0 max(var(--s2), env(safe-area-inset-left, 0px));
  background: color-mix(in oklch, var(--surface) 92%, transparent); backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--border);
  > p {
    margin: 0; max-width: none; text-align: center; font: 600 1.15rem/1.2 var(--font-display); letter-spacing: .03em;
    > a { color: var(--text); text-decoration: none }
  }
  > a[aria-label] { display: grid; place-items: center; min-height: var(--tap); color: var(--text); border-radius: var(--radius); &:hover { background: var(--surface-2) } }
  > button[popovertarget] { grid-column: -2 }
  > nav[popover] {
    margin: 0; inset: calc(var(--tap) + var(--s2)) max(var(--s2), env(safe-area-inset-right, 0px)) auto auto; min-width: 14rem; padding: var(--s2);
    color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: 0 12px 40px -20px rgb(0 0 0 / .5);
    &:popover-open { display: grid; gap: 2px }
    > form { display: grid; justify-content: stretch }
    > a, > form > button {
      display: flex; align-items: center; justify-content: space-between; gap: var(--s2); width: 100%; min-width: 0; min-height: var(--tap); padding: 0 var(--s3);
      font: 600 1rem/1.2 var(--font-body); letter-spacing: normal; text-transform: none; text-decoration: none;
      color: var(--text); background: none; border: 0; border-radius: var(--radius); box-shadow: none;
      &:hover { background: var(--surface-2) }
      > svg { width: 1.1em; height: 1.1em; color: var(--text-muted) }
    }
  }
  > dl {
    grid-column: 1 / -1; min-height: 40px; padding: 0 var(--s1); align-items: center;
    grid-template-columns: repeat(4, auto); justify-content: space-between; gap: 2px;
    > div { display: flex; align-items: center; gap: 3px }
    dt { font-size: .62rem; letter-spacing: .08em }
    dt > svg { width: 1rem; height: 1rem }
    dd { font-size: .85rem; white-space: nowrap }
    dd > small { display: none }
  }
}
main {
  container: main / inline-size;
  display: grid; gap: var(--s6); align-content: start; width: 100%; max-width: 70rem; margin: 0 auto;
  padding: var(--s4) max(16px, env(safe-area-inset-right, 0px)) calc(var(--s6) + env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px));
}
section > ol {
  > li[data-side] { border-inline-start: 3px solid var(--success) }
  > li[data-side="enemy"] { border-inline-start-color: var(--danger); background: color-mix(in oklch, var(--danger) 5%, var(--surface)) }
  > li > span { grid-column: 1 / -1; padding: var(--s3) var(--s4); > svg { display: inline; width: 1.1em; height: 1.1em; vertical-align: -.2em; margin-inline-end: .2em } }
  display: grid; grid-template-columns: 1fr auto auto auto; list-style: none; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); overflow: hidden;
  > li { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid }
  > li + li { border-block-start: 1px solid var(--border) }
  > li > a {
    display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; gap: var(--s1) var(--s4); padding: var(--s3) var(--s4); color: var(--text); text-decoration: none;
    &:hover { background: color-mix(in oklch, var(--gold) 8%, var(--surface)) }
    > span { display: flex; align-items: center; gap: var(--s2); > svg { width: 1.6rem; height: 1.6rem; flex: none } }
    > time { color: var(--text-muted); font-size: .9rem }
    > :is(ins, del) { justify-self: end; font-variant-numeric: tabular-nums; white-space: nowrap }
  }
}
@media (max-width: 40rem) {
  section > ol { grid-template-columns: 1fr auto }
  section > ol > li > a { > time { grid-row: 2; font-size: .85rem } > del { grid-row: 2; grid-column: 2 } }
}
article:is([data-stat], [data-gain], [data-cost]) {
  justify-items: center; align-content: center; gap: var(--s2); text-align: center;
  > svg { width: 2.75rem; height: 2.75rem }
  > small > svg { display: inline; width: 1.1em; height: 1.1em; vertical-align: -.2em }
  > strong { font: 600 1.75rem/1 var(--font-display) }
  > p { font-weight: 700; line-height: 1.3 }
}
section > article:not([data-empty]) {
  gap: var(--s4); max-width: 40rem; margin-block-end: var(--s4); padding: var(--s6) var(--s6) calc(var(--s6) + var(--s2));
  background: var(--paper); border-color: color-mix(in oklch, var(--gold) 30%, var(--border)); border-radius: 4px;
  box-shadow: 0 1px 2px rgb(0 0 0 / .08), 0 22px 34px -24px rgb(0 0 0 / .55);
  font: 1.1rem/1.65 Georgia, "Times New Roman", serif;
  > p { color: var(--text) }
  > p:first-child { justify-self: end; font-size: .95rem; font-style: italic; color: var(--text-muted) }
  > p:last-child { justify-self: end; font-style: italic }
  &::after {
    content: ""; position: absolute; inset-inline-end: var(--s6); bottom: -22px; width: 48px; height: 48px; border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #c4404f, #9e1b2a 55%, #6b0f1b); box-shadow: 0 3px 6px rgb(0 0 0 / .35), inset 0 0 0 4px rgb(0 0 0 / .12);
  }
}
article:is(:has(> progress), [data-tiles] > *) {
  gap: var(--s2); grid-column: span 2;
  &:first-child { grid-column: 1 / -1 }
  > header {
    display: flex; align-items: center; justify-content: start; gap: var(--s2);
    > svg { width: 1.75rem; height: 1.75rem }
    > h3 { font: 700 .78rem/1 var(--font-body); letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted) }
    > :is(ins, del, small) { margin-inline-start: auto; padding: .3rem .65rem; border-radius: 99px; font-weight: 700; font-size: .85rem; white-space: nowrap; color: var(--text-muted); background: var(--surface-2) }
    > ins { color: var(--success); background: color-mix(in oklch, var(--success) 12%, var(--surface)) }
    > del { color: var(--danger); background: color-mix(in oklch, var(--danger) 12%, var(--surface)) }
  }
  > p:has(> strong) { color: var(--text-muted); > strong { font: 600 2.75rem/1 var(--font-display); color: var(--text) } }
  > progress {
    appearance: none; width: 100%; height: .75rem; border: 1px solid var(--border); border-radius: 99px; overflow: hidden; background: var(--surface-2); color: var(--gold);
    &::-webkit-progress-bar { background: var(--surface-2) }
    &::-webkit-progress-value { background: currentColor }
    &::-moz-progress-bar { background: currentColor }
  }
}
[data-tiles] > article { grid-column: span 1; &:first-child { grid-column: span 2 } &:nth-child(2):last-child { grid-column: span 2 } }
[data-tiles="even"] > article:is(:first-child, :nth-child(2):last-child) { grid-column: span 1 }
@container main (width >= 44rem) { [data-tiles="wide"] > article { &:first-child { grid-column: span 3 } &:nth-child(2):last-child { grid-column: span 1 } } }
article[data-gain] > :is(strong, p) { color: var(--success) }
article[data-cost] > :is(strong, p) { color: var(--danger) }

/* Menu: a list of places with icons, the current one tinted; a place with sections folds them, and the current one starts open. Folded into a button on a phone, a side column on desktop. */
body > aside {
  padding: var(--s4) max(16px, env(safe-area-inset-right, 0px)) 0 max(16px, env(safe-area-inset-left, 0px));
  > details {
    > summary {
      display: flex; align-items: center; gap: var(--s2); min-height: var(--tap); padding: 0 var(--s3); cursor: pointer; list-style: none;
      font-weight: 700; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
      &::-webkit-details-marker { display: none }
      &::before { content: "☰"; font-size: 1.2em; color: var(--accent) }
      &::after { display: none }
      > svg { width: 1.25rem; height: 1.25rem }
    }
    &[open] > summary { margin-block-end: var(--s2) }
    > nav {
      display: grid; gap: 2px;
      a, summary {
        display: flex; align-items: center; gap: var(--s2); min-height: var(--tap); padding: 0 var(--s3); border-radius: var(--radius);
        color: var(--text); font-weight: 600; text-decoration: none; white-space: nowrap;
        &:hover { background: var(--surface-2) }
        &[aria-current] { color: var(--accent) }
        &[aria-current="page"] { background: color-mix(in oklch, var(--accent) 14%, transparent) }
        &[data-state="unavailable"] { opacity: .6; cursor: default; background: none; > svg { filter: grayscale(1) } }
        > svg { width: 1.25rem; height: 1.25rem }
      }
      summary { cursor: pointer; list-style: none; &::-webkit-details-marker { display: none } }
      details > div {
        display: grid; gap: 2px; padding-inline-start: calc(var(--s3) + 1.25rem);
        > a { min-height: 2.25rem; font-size: .95rem }
      }
    }
  }
}

/* Desktop: one centred frame (rail + content, about 1 100 px of content). Header, rail and main share its edges. */
@media (width >= 900px) {
  :root { --rail: 12rem; --content: 68rem; --frame: calc(var(--rail) + var(--s5) + var(--content)); --bar-h: 3.75rem }
  body:not(:has(> aside)) > main { max-width: calc(var(--frame) + 2 * var(--s5)); padding-inline: var(--s5) }
  body:has(> aside) {
    display: grid; column-gap: var(--s5); grid-template-rows: auto 1fr; min-height: 100dvh;
    grid-template-columns: [full-start] minmax(0, 1fr) [rail-start] var(--rail) [rail-end main-start] minmax(0, var(--content)) [main-end] minmax(0, 1fr) [full-end];
    > main { grid-column: main; grid-row: 2; max-width: none; margin: 0; padding: var(--s4) 0 var(--s6) }
  }
  body > header {
    grid-column: full; top: 0; min-height: var(--bar-h);
    grid-template-columns: var(--tap) calc(var(--rail) + var(--s5) - var(--tap)) minmax(0, 1fr) var(--tap);
    padding: var(--s1) max(var(--s5), (100% - var(--frame)) / 2);
    > p { text-align: start; padding-inline-start: var(--s2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
    > nav[popover] { top: calc(var(--bar-h) + var(--s1)); right: max(var(--s5), (100vw - var(--frame)) / 2) }
    > dl {
      grid-column: 3; grid-row: 1; min-height: var(--tap); gap: var(--s3);
      > div { align-items: baseline }
      dt { align-self: center }
      dd > small { display: inline; font-size: .78rem; font-weight: 700 }
      dd > small > small { font-weight: 400 }
    }
  }
  body > aside {
    grid-column: rail; grid-row: 2; align-self: start; position: sticky; top: calc(var(--bar-h) + var(--s2)); padding: var(--s4) 0 0;
    > details {
      > summary { display: none }
      &::details-content { content-visibility: visible; height: auto }
    }
  }

  :has(> article + article):not(main), div:has(> article) { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: var(--s4) }
  dl { grid-template-columns: repeat(auto-fill, minmax(min(100%, 6rem), 1fr)) }

  main > article:not([role="status"]) {
    &:has(> figure) { padding-inline-start: calc(17rem + var(--s4)); min-height: 9rem }
    > figure {
      position: absolute; inset: 0 auto 0 0; width: 17rem; aspect-ratio: auto; max-height: none; margin: 0; border-block-end: 0; border-inline-end: 1px solid var(--border); border-radius: calc(var(--radius-lg) - 1px) 0 0 calc(var(--radius-lg) - 1px);
      > img { height: 100%; aspect-ratio: auto; max-height: none }
    }
  }

  form {
    > button:last-of-type { width: auto; min-width: 18rem; justify-self: end }
    &:not(:has(> :not(button))) {
      display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s2);
      > button:is(:first-of-type, :last-of-type) { flex: 0 0 14rem; min-height: var(--tap); font: 700 1rem/1 var(--font-body); letter-spacing: .02em; text-transform: none; min-width: 0 }
    }
    > footer { display: flex; justify-content: flex-end; > button { flex: none } }
  }
  section > footer { display: flex; justify-content: flex-end; > button { flex: none } }
  :is(main, aside, form) > article > dl {
    display: flex; flex-wrap: wrap; gap: var(--s3) var(--s6);
    > div { min-width: 6rem }
  }
  label:has(> :is(select, input:not([type="radio"]))) { max-width: 26rem }
}

:is(h1, h2, h3) > a:has(> svg) { display: inline-flex; align-items: center; gap: var(--s2) }
:is(p, dd, dt) > a > svg:first-child { display: inline; width: 1.1em; height: 1.1em; vertical-align: -.2em; margin-inline-end: .25em }
[data-terrains] > article > header > mark { margin-inline-start: auto; white-space: nowrap }


/* A card grid has 4 columns on a wide screen and 2 on a narrow one. */
main :is(div:has(> article:only-child), :has(> article + article):not(:has(> :not(article)))):not(dialog *) {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  @container main (width >= 44rem) { grid-template-columns: repeat(4, minmax(0, 1fr)) }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after, ::backdrop { transition: none !important; animation: none !important }
  article:hover { translate: none }
}
:is(p, dd) > svg { display: inline; width: 1.1em; height: 1.1em; vertical-align: -.2em; margin-inline-end: .25em }
dialog div:has(> article) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); > article > data { top: var(--s2); right: var(--s2) } }

form[data-filters] {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  > select { flex: 1 1 10rem; max-width: 16rem }
}
