/*
  How the site is put together.

  One idea holds it up: there are exactly three weights on any page. The bar across the top, the
  rail beside the work, and the work itself - which is made of panels. A panel is the only surface
  there is. Everything that used to be its own kind of box, and there were four, is now a panel
  with a heading or a panel with a table in it.

  Every colour comes from tokens.css and none is written out here.
*/

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 inherit;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0; font-weight: 600; line-height: 1.25; }
h1 { font-size: 1.375rem; }
h2 { font-size: 1rem; }
h3 { font-size: .9rem; }

p { margin: 0 0 .75rem; }
p:last-child { margin-bottom: 0; }

.muted { color: var(--dim); }
.lead { font-size: 1.0625rem; color: var(--dim); max-width: 46rem; }

/* ── the bar across the top ─────────────────────────────────────────────────────────────── */

.topbar {
  display: grid;
  /* Equal outer columns are what actually centres the middle one, whatever is in the corners. */
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  height: 52px;
  padding: 0 1.25rem;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 10;
}

.topbar .mark {
  justify-self: start;
  font-weight: 650;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
  color: var(--text);
}

.topbar .mark:hover { text-decoration: none; color: var(--accent); }

.topbar .primary { display: flex; gap: .25rem; }

.topbar .primary a {
  color: var(--dim);
  padding: .35rem .7rem;
  border-radius: var(--radius);
  font-weight: 500;
  white-space: nowrap;
}

.topbar .primary a:hover { color: var(--text); background: var(--bg); text-decoration: none; }

.topbar .primary a.active { color: var(--text); background: var(--bg); }

.topbar .account {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: .6rem;
}

.topbar .who { color: var(--dim); font-size: .9rem; }

/* ── a page ─────────────────────────────────────────────────────────────────────────────── */

.page {
  max-width: var(--page);
  margin: 0 auto;
  padding: 1.75rem 1.25rem 4rem;
}

/* A section: the rail, then the work. */
.workspace {
  display: grid;
  grid-template-columns: 208px minmax(0, 1fr);
  gap: 2rem;
  max-width: var(--page);
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
  align-items: start;
}

.rail nav { display: flex; flex-direction: column; gap: 1px; position: sticky; top: 68px; }

.rail a {
  display: flex;
  align-items: center;
  gap: .5rem;
  color: var(--dim);
  padding: .4rem .65rem;
  border-radius: var(--radius);
  font-size: .9rem;
}

.rail a > span:first-child { flex: 1 1 auto; min-width: 0; }

/* How many are waiting behind a link. Carries the count rather than only saying "something",
   because "eleven unclaimed" and "one unclaimed" are not the same morning. */
.pip {
  flex: 0 0 auto;
  min-width: 1.25rem;
  padding: 0 .35rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: .7rem;
  font-weight: 600;
  line-height: 1.25rem;
  text-align: center;
}

.rail a:hover { color: var(--text); background: var(--panel); text-decoration: none; }

.rail a.active {
  color: var(--text);
  background: var(--panel);
  box-shadow: inset 2px 0 0 var(--accent);
  font-weight: 500;
}

.work { min-width: 0; }

.work-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
  padding-bottom: .9rem;
  border-bottom: 1px solid var(--line);
}

.work-head h1 { flex: 1; }

/* ── the only surface ───────────────────────────────────────────────────────────────────── */

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 1rem;
}

.panel > * { padding: 1rem 1.1rem; }
.panel > * + * { border-top: 1px solid var(--line); }

/* A panel's own heading row, so a form and the thing it belongs to read as one object. */
.panel-head {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  background: color-mix(in srgb, var(--bg) 45%, transparent);
  border-radius: var(--radius) var(--radius) 0 0;
}

.panel-head h2 { flex: 1; }

.panel.narrow { max-width: 34rem; }

.cards { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.cards .panel { margin: 0; }

/* ── the landing page ───────────────────────────────────────────────────────────────────── */

.hero { padding: 4rem 0 1.5rem; max-width: 44rem; }
.hero h1 { font-size: 2.5rem; letter-spacing: -0.02em; margin-bottom: 1rem; }
.hero .lead { margin-bottom: 1.75rem; }
.hero .panel { margin-top: 2rem; }

/* ── tables ─────────────────────────────────────────────────────────────────────────────── */

.panel > .table { padding: 0; overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: .9rem; }

th, td { text-align: left; padding: .6rem .9rem; border-bottom: 1px solid var(--line); }

th {
  color: var(--dim);
  font-weight: 500;
  font-size: .8rem;
  letter-spacing: .02em;
  background: color-mix(in srgb, var(--bg) 45%, transparent);
  white-space: nowrap;
}

tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: color-mix(in srgb, var(--bg) 35%, transparent); }

/* ── things to press ────────────────────────────────────────────────────────────────────── */

.button, button {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  background: var(--accent);
  color: var(--on-accent);
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: .4rem .85rem;
  font: inherit;
  font-size: .9rem;
  font-weight: 500;
  line-height: 1.4;
  cursor: pointer;
  white-space: nowrap;
}

.button:hover, button:hover { background: var(--accent-strong); text-decoration: none; }

.button.quiet, button.quiet {
  background: transparent;
  color: var(--text);
  border-color: var(--line);
}

.button.quiet:hover, button.quiet:hover { background: var(--bg); border-color: var(--dim); }

button.danger { background: transparent; color: var(--danger); border-color: var(--line); }
button.danger:hover { background: var(--danger); color: #fff; border-color: var(--danger); }

button:disabled { opacity: .55; cursor: default; }

.actions { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }

/* ── forms ──────────────────────────────────────────────────────────────────────────────── */

.field { margin-bottom: .85rem; }
.field:last-child { margin-bottom: 0; }

label {
  display: block;
  color: var(--dim);
  font-size: .8rem;
  font-weight: 500;
  margin-bottom: .3rem;
}

input, select, textarea {
  width: 100%;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .45rem .6rem;
  font: inherit;
  font-size: .9rem;
}

input:hover, select:hover, textarea:hover { border-color: var(--dim); }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

textarea { resize: vertical; min-height: 4.5rem; }

label.inline {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  margin: 0;
  color: var(--text);
  font-size: .875rem;
  font-weight: 400;
  white-space: nowrap;
}

label.inline input { width: auto; }
label.inline input[type="number"] { width: 5rem; }

.grid { display: grid; gap: .85rem; margin-bottom: .85rem; }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* ── small pieces of state ──────────────────────────────────────────────────────────────── */

.badge {
  display: inline-block;
  font-size: .75rem;
  font-weight: 500;
  padding: .1rem .5rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--dim);
  white-space: nowrap;
}

.badge-new { border-color: var(--accent); color: var(--accent); }
.badge-awaiting-reply { border-color: var(--waiting); color: var(--waiting); }
.badge-awaiting-evidence { border-color: var(--evidence); color: var(--evidence); }
.badge-resolved { border-color: var(--ok); color: var(--ok); }
.badge-held, .badge-note { border-color: var(--danger); color: var(--danger); }

/* Closed for good. Filled rather than outlined, because it is the one state that says the
   conversation is over rather than where it got to. */
.badge-locked {
  border-color: var(--dim);
  background: var(--dim);
  color: var(--panel);
}

.tag {
  font-size: .75rem;
  color: var(--dim);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: .05rem .35rem;
  white-space: nowrap;
}

/* Something waiting on the reader, where a whole badge would be too loud. */
.dot {
  display: inline-block;
  width: .45rem;
  height: .45rem;
  margin-left: .4rem;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
}

.empty { color: var(--dim); font-style: italic; }

/* A refusal, in the words of the rule that refused it. */
.refusal {
  border: 1px solid var(--danger);
  border-left-width: 3px;
  border-radius: var(--radius);
  padding: .6rem .85rem;
  margin-bottom: 1rem;
  background: color-mix(in srgb, var(--danger) 8%, transparent);
}

/* ── a ticket ───────────────────────────────────────────────────────────────────────────── */

.ticket-head { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }

.answer { margin-bottom: .9rem; }
.answer:last-child { margin-bottom: 0; }
.answer label { margin-bottom: .15rem; }

.message {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .7rem .85rem;
  margin-bottom: .6rem;
  background: var(--bg);
}

/* An internal note must never be mistaken for something the player was sent. */
.message.note { border-left: 3px solid var(--danger); }
.message.system { background: transparent; border-style: dashed; }

.message-head {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .35rem;
  font-size: .85rem;
}

.message-body, .prose { white-space: pre-wrap; overflow-wrap: anywhere; }

.reply { margin-top: 1rem; }
.reply-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .9rem; margin-top: .6rem; }

/* ── disclosures ────────────────────────────────────────────────────────────────────────── */

details.panel > summary {
  display: flex;
  gap: .75rem;
  align-items: center;
  flex-wrap: wrap;
  cursor: pointer;
  padding: .8rem 1.1rem;
  list-style: none;
  font-weight: 500;
}

details.panel > summary::-webkit-details-marker { display: none; }
details.panel > summary::before { content: "▸"; color: var(--dim); font-size: .8rem; }
details.panel[open] > summary::before { content: "▾"; }
details.panel > summary:hover { background: color-mix(in srgb, var(--bg) 45%, transparent); }
details.panel > summary .spacer { flex: 1; }
details.panel > .body { border-top: 1px solid var(--line); }

/* ── narrower ───────────────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .workspace { grid-template-columns: 1fr; gap: 1rem; }
  .rail nav { position: static; flex-direction: row; flex-wrap: wrap; }
  .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .topbar { grid-template-columns: auto 1fr; height: auto; padding: .6rem 1rem; gap: .5rem; }
  .topbar .primary { grid-column: 1 / -1; order: 3; }
  .g2, .g4 { grid-template-columns: 1fr; }
  .hero { padding-top: 2.5rem; }
  .hero h1 { font-size: 2rem; }
}

/* The light-and-dark toggle: a symbol, so it wants square padding rather than a button's. */
button.theme { padding: .35rem .5rem; line-height: 1; font-size: .95rem; }

/* ── the item editor ────────────────────────────────────────────────────────────────────── */

/* The item on the left, the lists that explain its numbers on the right. */
.editor { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: 1.25rem; }
.editor-item { min-width: 0; }

.hint { font-size: .8rem; color: var(--dim); margin: .25rem 0 0; }

/* One attribute. Reads as 6 = 38, because that is what it is. */
.attribute {
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .2rem .35rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
}

.attribute:hover, .attribute.pointed {
  border-color: var(--line);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

.attribute-index { width: 4.5rem; flex: none; text-align: right; font-variant-numeric: tabular-nums; }
.attribute-is { color: var(--dim); }
.attribute-value { width: 7rem; flex: none; font-variant-numeric: tabular-nums; }

.attribute-name {
  flex: 1;
  min-width: 0;
  color: var(--dim);
  font-size: .8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

button.tiny { padding: .15rem .4rem; font-size: .85rem; line-height: 1; }

/* ── the catalogue ──────────────────────────────────────────────────────────────────────── */

.editor-catalogue {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  min-width: 0;
  border-left: 1px solid var(--line);
  padding-left: 1.25rem;
}

.catalogue-tabs { display: flex; gap: .25rem; }
.catalogue-tabs button { flex: 1; justify-content: center; padding: .3rem .5rem; font-size: .85rem; }
.catalogue-search { font-size: .85rem; }

.catalogue {
  max-height: 26rem;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
}

.catalogue .empty { padding: .6rem .7rem; font-size: .85rem; }

.catalogue-entry {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  padding: .3rem .6rem;
  cursor: pointer;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  font-size: .85rem;
}

.catalogue-entry:last-child { border-bottom: 0; }
.catalogue-entry:hover { background: var(--panel); }

/* What the row being pointed at means. */
.catalogue-entry.lit {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  box-shadow: inset 2px 0 0 var(--accent);
}

.catalogue-index {
  flex: none;
  width: 3.5rem;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.catalogue-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.catalogue-detail {
  flex: none;
  color: var(--dim);
  font-size: .75rem;
  max-width: 8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 1100px) {
  .editor { grid-template-columns: 1fr; }
  .editor-catalogue { border-left: 0; padding-left: 0; border-top: 1px solid var(--line); padding-top: 1rem; }
}

/* ── raising a ticket ───────────────────────────────────────────────────────────────────── */

/* Who will be able to read this, said before it is written. */
.notice {
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--radius);
  padding: .6rem .85rem;
  margin-bottom: 1rem;
  background: var(--bg);
  color: var(--dim);
}

/* One held back above somebody's head is not the ordinary case and must not read like it. */
.notice.held {
  border-color: var(--accent);
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.entry { margin-bottom: .4rem; }

.entry-line { display: flex; align-items: flex-start; gap: .4rem; }

.entry-line button.narrow { flex: 0 0 auto; padding: .4rem .6rem; line-height: 1; }

/* The account behind seventeen digits, put in front of the person who typed them. */
.who {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin-top: .4rem;
  padding: .55rem .7rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}

.who.yes { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, transparent); }

.who img { flex: 0 0 auto; border-radius: var(--radius); }

.who-said { flex: 1 1 auto; min-width: 0; }
.who-said p { margin: 0; }

.who-buttons { display: flex; gap: .4rem; margin-top: .45rem !important; }

/* The stock replies, under the box they go into. */
.canned { margin-top: .5rem; max-width: 26rem; }
.canned label { margin-bottom: .2rem; }

button.narrow { padding: .3rem .6rem; line-height: 1.1; font-size: .8rem; }

/* A setting that is one short choice, not a whole row of the form. */
.narrow-field { max-width: 22rem; margin-top: .8rem; }

/* Two things to do to a row, side by side rather than stacked.
   Inline-flex and not flex: a flex cell fills the row's height and pushes its buttons off the
   line every other cell sits on. */
.row-actions { white-space: nowrap; }
.row-actions > * { display: inline-flex; vertical-align: middle; margin-right: .35rem; }
.row-actions > *:last-child { margin-right: 0; }

/* Every cell on the same line as the text beside it. */
table td { vertical-align: middle; }

/* One number, said large, because that is the whole of what the panel is for. */
.figure { display: flex; flex-direction: column; gap: .15rem; padding: 1rem 1.1rem; }
.figure > * { padding: 0; }
.figure-number { font-size: 1.9rem; font-weight: 600; line-height: 1.1; }

/* ── the update log ─────────────────────────────────────────────────────────────────────── */

.section-heading { margin: 1.6rem 0 .8rem; }

.post h3 { margin-bottom: .2rem; }
.post .post-by { margin: 0 0 .6rem; font-size: .8rem; }
.post > * { padding: 0; }
.post { padding: 1rem 1.1rem; }

/* ── the forms a ticket can be raised from ──────────────────────────────────────────────── */

/* A stripe rather than a tinted panel: the cards sit in a row and a wash of colour behind the
   text costs more contrast than it buys. */
.form-card { border-left: 3px solid transparent; }

.form-card.accent-red { border-left-color: var(--mark-red); }
.form-card.accent-amber { border-left-color: var(--mark-amber); }
.form-card.accent-green { border-left-color: var(--mark-green); }
.form-card.accent-blue { border-left-color: var(--mark-blue); }
.form-card.accent-purple { border-left-color: var(--mark-purple); }

/* The one thing to do on the card, in the middle and at the bottom of it. */
.form-choose { display: flex; justify-content: center; margin-top: auto; }

.cards .form-card { display: flex; flex-direction: column; }

/* ── what somebody wrote, as they wrote it ──────────────────────────────────────────────── */

/* Overrides the pre-wrap the plain .prose carries: once the paragraphs are real paragraphs,
   keeping the newlines as well doubles every gap. */
.prose h2, .prose h3, .prose h4 { margin: .9rem 0 .35rem; }
.prose h2:first-child, .prose h3:first-child, .prose h4:first-child { margin-top: 0; }
.prose h2 { font-size: 1.15rem; }
.prose h3 { font-size: 1rem; }
.prose h4 { font-size: .9rem; }

.prose p { margin: 0 0 .6rem; white-space: normal; }
.prose p:last-child { margin-bottom: 0; }

.prose ul { margin: 0 0 .6rem; padding-left: 1.2rem; }
.prose li { margin-bottom: .2rem; }

.prose code {
  padding: .05rem .3rem;
  border-radius: 4px;
  background: var(--bg);
  font-size: .9em;
}

/* ── the change log ─────────────────────────────────────────────────────────────────────── */

/* Title, then when, then what it says. Nothing between the pieces: an entry reads as one thing. */
.post-title { margin: 0 0 .15rem; font-size: 1.45rem; }
.post-when { margin: 0 0 .9rem !important; font-size: .8rem; }

.post-shot {
  display: block;
  max-width: 100%;
  height: auto;
  margin: .8rem 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

/* ── writing one ────────────────────────────────────────────────────────────────────────── */

.block {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .7rem .8rem;
  margin-bottom: .6rem;
  background: var(--bg);
}

.block-head { display: flex; align-items: center; gap: .35rem; margin-bottom: .5rem; }
.block-head .grow { flex: 1; }

.block-shot {
  display: block;
  max-width: 100%;
  max-height: 18rem;
  height: auto;
  margin-bottom: .6rem;
  border-radius: var(--radius);
}

/* ── the connection notice ─────────────────────────────────────────────────────────────────
   App.razor's reconnect and error notices. Pinned to the bottom of the screen and not blocking
   anything, so somebody whose page lost its connection can still select and copy what they typed
   before reloading. The framework moves the reconnect notice between states by class and shows
   the error one by setting its display. */

.connection {
  display: none;
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 1000;
  max-width: 44rem;
  margin: 0 auto;
  padding: .75rem 1rem;
  border: 1px solid var(--accent);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 6px 24px rgb(0 0 0 / .35);
}

.connection p { margin: 0; }
.connection button { margin-left: .5rem; }
.connection-broken { border-color: var(--danger); }

.connection > p { display: none; }

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-paused,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected,
#components-reconnect-modal.components-reconnect-resume-failed { display: block; }

.components-reconnect-show > .connection-down,
.components-reconnect-retrying > .connection-down,
.components-reconnect-paused > .connection-paused,
.components-reconnect-failed > .connection-failed,
.components-reconnect-rejected > .connection-gone,
.components-reconnect-resume-failed > .connection-gone { display: block; }

.components-reconnect-rejected,
.components-reconnect-resume-failed { border-color: var(--danger); }

#blazor-error-ui > p { display: block; }
