/* One small stylesheet, no build step and no external requests — the page has to
   work from a fresh container with nothing but the bot's own dependencies. */

:root {
  --bg: #0f1216;
  --panel: #171b21;
  --panel-2: #1e242c;
  --line: #2a323c;
  --text: #e6eaf0;
  --muted: #9aa6b5;
  --accent: #5865f2;
  --accent-2: #4451d6;
  --ok: #3ba55d;
  --warn: #d9a441;
  --err: #e05260;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #f5f7fa;
    --panel: #ffffff;
    --panel-2: #eef1f6;
    --line: #d8dee7;
    --text: #1b2027;
    --muted: #5d6874;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.55 system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

a { color: inherit; }

main {
  max-width: 900px;
  margin: 0 auto;
  padding: 24px 20px 64px;
}

/* -- top bar ------------------------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 20px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-decoration: none;
}

/* Logos are square-ish but not guaranteed to be — contain keeps any aspect
   ratio intact instead of squashing it into the box. */
.brandlogo, .herologo { object-fit: contain; }
.brandlogo { width: 32px; height: 32px; }
.herologo { width: 96px; height: 96px; margin-bottom: 10px; }

/* Brand, then which server you are looking at — the guild name used to be an
   `<h1>` repeated on every page. `min-width: 0` lets a long guild name be
   truncated rather than squeezing the sign-out control off the bar. */
.topbarstart { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topsep { color: var(--muted); }
.guildname {
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.guildname:hover { color: var(--accent); }

.user { display: flex; align-items: center; gap: 10px; }
.avatar { border-radius: 50%; }
.user .name { color: var(--muted); }

.foot {
  max-width: 900px;
  margin: 0 auto;
  padding: 0 20px 32px;
  color: var(--muted);
  font-size: 13px;
}

/* -- type ---------------------------------------------------------------- */

h1 { font-size: 26px; margin: 0 0 6px; }
h2 { font-size: 18px; margin: 32px 0 12px; }
h3 { font-size: 15px; margin: 0 0 8px; }

.muted, .hint, .fineprint { color: var(--muted); }
.hint, .fineprint { font-size: 13px; }
.lead { font-size: 18px; color: var(--muted); max-width: 60ch; }
.crumbs { color: var(--muted); font-size: 13px; margin: 0 0 12px; }
.description { white-space: pre-wrap; }
.empty { color: var(--muted); padding: 18px 0; }

.pagehead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}

/* A page's name, under the tabs. The `h2` after it opens a section of that
   page rather than a new subject, so it does not need its usual 32px of air. */
.pagehead h1 { margin-bottom: 0; }
.pagehead + h2 { margin-top: 20px; }
.pagehead + p, .pagehead + .hint, .pagehead + .crumbs { margin-top: 10px; }

.hero { padding: 48px 0; }
.hero .button { margin-top: 12px; }

/* -- buttons ------------------------------------------------------------- */

.button {
  display: inline-block;
  padding: 9px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 15px;
  text-decoration: none;
  cursor: pointer;
}

.button:hover { border-color: var(--muted); }
.button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.button.primary:hover { background: var(--accent-2); }
.button.danger { border-color: var(--err); color: var(--err); background: transparent; }
.button.danger:hover { background: rgba(224, 82, 96, 0.12); }
.button.big { padding: 12px 22px; font-size: 17px; }

.linkish {
  background: none;
  border: 0;
  padding: 0;
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
}

.actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.managebar { display: flex; gap: 10px; flex-wrap: wrap; }
.inlineform { margin-top: 40px; }

/* -- flashes ------------------------------------------------------------- */

.flash {
  padding: 11px 14px;
  border-radius: 8px;
  border-left: 3px solid var(--ok);
  background: var(--panel);
  margin-bottom: 18px;
}

.flash.warn { border-left-color: var(--warn); }
.flash.err { border-left-color: var(--err); }

/* -- cards / lists ------------------------------------------------------- */

.cards, .eventlist, .people { list-style: none; margin: 0; padding: 0; }
.cards { display: grid; gap: 12px; }

.card, .event {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.cardlink {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  text-decoration: none;
}

.cardbody { display: flex; flex-direction: column; }
.guildicon { border-radius: 12px; }

.guildicon.placeholder {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: var(--panel-2);
  font-weight: 700;
}

.eventlist { display: grid; gap: 10px; }

.event {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 16px;
  flex-wrap: wrap;
}

.eventmain {
  display: grid;
  gap: 2px;
  text-decoration: none;
  flex: 1 1 320px;
  min-width: 0;
}

.eventmain .title { font-size: 17px; font-weight: 600; }
.eventmain .when { display: flex; gap: 10px; font-size: 13px; }
.eventmain .meta { color: var(--muted); font-size: 13px; }
.eventlist.quiet .event { opacity: 0.72; }

.counts { display: flex; gap: 6px; flex-wrap: wrap; }

.chip {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  font-size: 13px;
}

.status {
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.08em;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid var(--line);
}

.status.scheduled { color: var(--ok); border-color: var(--ok); }
.status.cancelled { color: var(--err); border-color: var(--err); }
.status.completed { color: var(--muted); }

/* -- tabs ---------------------------------------------------------------- */

.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  /* Little air above: the tabs are the first thing in the page now, where the
     guild's name used to sit. */
  margin: 2px 0 8px;
  border-bottom: 1px solid var(--line);
}

.tab {
  padding: 8px 11px;
  text-decoration: none;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  /* A flex row breaks the labels themselves rather than wrapping, so this
     keeps each label on one line and lets the row wrap instead. It should not
     have to: the row is meant to fit 860px — see web/nav.py. */
  white-space: nowrap;
}

.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }

/* The second row, for the pages inside one group. Quieter than the row above
   it — it is a sibling list, not another set of destinations to weigh up. */
.subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 0 16px;
}
.subtab {
  padding: 5px 11px;
  font-size: 13px;
  text-decoration: none;
  color: var(--muted);
  border: 1px solid transparent;
  border-radius: 999px;
  white-space: nowrap;
}
.subtab:hover { border-color: var(--line); }
.subtab.active {
  color: var(--text);
  font-weight: 600;
  border-color: var(--line);
  background: var(--panel);
}

/* -- game roles ---------------------------------------------------------- */

.rolegrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
}

.rolecard {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 13px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
}

.rolecard:hover { border-color: var(--muted); }
.rolecard.held { border-color: var(--accent); }
.rolecard input { width: auto; margin-top: 3px; }
.rolebody { display: grid; gap: 2px; font-size: 14px; min-width: 0; }

.rolelist { width: 100%; border-collapse: collapse; margin-top: 8px; }

.rolelist td {
  padding: 12px 0;
  border-top: 1px solid var(--line);
  vertical-align: top;
  font-size: 14px;
}

.rowactions {
  text-align: right;
  white-space: nowrap;
}

.rowactions form {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
}

.rowactions .check { font-size: 13px; color: var(--muted); }

/* Link names: one card per player, its other names listed under it. */
.namegroups { display: grid; gap: 10px; margin-top: 8px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.namegroup { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; min-width: 0; }
.namegroup strong { overflow-wrap: anywhere; }
.namegroup ul { list-style: none; margin: 6px 0 0; padding: 0; }
.namegroup li { display: flex; gap: 10px; align-items: baseline; padding: 3px 0; font-size: 13px; }
.namegroup li span { flex: 1; min-width: 0; overflow-wrap: anywhere; color: var(--muted); }
.namegroup li form { margin: 0; }
.mapped { color: var(--text, inherit); font-weight: 600; margin-right: 8px; }
.rolefilter { margin: 10px 0; font-size: 14px; }
.rolefilter summary { cursor: pointer; }
.rolechips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px; font-size: 13px; cursor: pointer; }
.chip input { width: auto; margin: 0; }
.linkbutton { background: none; border: 0; padding: 0; font: inherit; font-size: 12px; color: var(--accent); cursor: pointer; text-decoration: underline; }
.linkbutton.danger { color: var(--danger, #e5534b); }

/* A section heading inside a form, for grouping fields without a new <form>. */
.form h3 { margin: 10px 0 0; padding-top: 14px; border-top: 1px solid var(--line); }

/* -- voice leaderboard --------------------------------------------------- */

.periods { display: flex; gap: 4px; flex-wrap: wrap; border: 0; }

.ranks { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }

.rank {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}

/* The bar sits behind the text rather than next to it, so long names never
   squeeze it out of the row. */
.rankbar {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--accent);
  opacity: 0.14;
}

.rank.me { border-color: var(--accent); }
.ranknum { position: relative; width: 2ch; color: var(--muted); font-variant-numeric: tabular-nums; }
.rankname { position: relative; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.ranktime { position: relative; font-variant-numeric: tabular-nums; font-weight: 600; }

/* -- embed builder ------------------------------------------------------- */

.epcontent { white-space: pre-wrap; margin: 0 0 8px; }

.embedpreview {
  position: relative;
  display: grid;
  gap: 8px;
  max-width: 540px;
  padding: 13px 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: 6px;
}

.epauthor, .epfooter { display: flex; align-items: center; gap: 8px; }
.epauthor { font-size: 14px; font-weight: 600; }
.epauthor img, .epfooter img { width: 20px; height: 20px; border-radius: 50%; }
.eptitle { font-weight: 700; }
.epdesc, .epfieldvalue { white-space: pre-wrap; font-size: 14px; }
.epfooter { font-size: 12px; color: var(--muted); }

.epfields { display: flex; flex-wrap: wrap; gap: 10px; }
.epfield { flex: 1 1 100%; }
.epfield.inline { flex: 1 1 28%; min-width: 130px; }
.epfieldname { font-weight: 600; font-size: 14px; margin-bottom: 2px; }

.epimage { max-width: 100%; border-radius: 6px; }

.epthumb {
  position: absolute;
  top: 13px;
  right: 16px;
  width: 60px;
  height: 60px;
  object-fit: contain;
  border-radius: 6px;
}

.fieldrow {
  display: grid;
  grid-template-columns: 1fr 2fr auto;
  gap: 8px;
  align-items: start;
  margin-bottom: 8px;
}

@media (max-width: 620px) {
  .fieldrow { grid-template-columns: 1fr; }
}

/* -- facts / columns ----------------------------------------------------- */

.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 18px;
  margin: 18px 0;
}

.facts dt { color: var(--muted); font-size: 14px; }
.facts dd { margin: 0; }

.columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
}

.column {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px 16px;
}

.people { display: grid; gap: 4px; font-size: 14px; }

.rsvp { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.rsvpbtn.chosen { border-color: var(--accent); background: var(--accent); color: #fff; }

/* -- forms --------------------------------------------------------------- */

.form { display: grid; gap: 16px; margin-top: 18px; max-width: 720px; }
.cancelform { margin-top: 24px; }

/* align-content keeps each row at its natural height — without it, a field
   sitting next to a taller one stretches its input to match. */
.field { display: grid; gap: 6px; align-content: start; border: 0; padding: 0; margin: 0; }
.field > span, .field > legend { font-size: 14px; color: var(--muted); }

input[type='text'], input:not([type]), input[type='number'],
input[type='datetime-local'], input[type='time'], input[type='url'],
input[type='date'], input[type='search'], textarea, select {
  width: 100%;
  padding: 9px 11px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font: inherit;
}

textarea { resize: vertical; }
input:focus, textarea:focus, select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.checkgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 6px;
  max-height: 240px;
  overflow-y: auto;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
}

.check { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.check input { width: auto; }

.note {
  color: var(--muted);
  font-size: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
}

code {
  background: var(--panel-2);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 13px;
}

@media (max-width: 620px) {
  .row { grid-template-columns: 1fr; }
}

/* -- ORBATs -------------------------------------------------------------- */

.pad { padding: 16px 18px; }
.card h3 { margin-top: 0; }
.card h3.bad, .bad { color: var(--err); }
.card h3.warnish { color: var(--warn); }
.nospace { margin-top: 0; }

/* The editor and its preview need more room than the 900px main column. The
   whole page steps outside it rather than just the two columns, so the headings
   stay lined up with them. */
.widepage {
  width: min(1500px, 100vw - 32px);
  margin-left: 50%;
  transform: translateX(-50%);
}
.orbatsplit {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  align-items: start;
}
@media (max-width: 940px) { .orbatsplit { grid-template-columns: 1fr; } }

.orbateditor textarea {
  min-height: 520px;
  font: 14px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  tab-size: 2;
}
.orbatside { display: grid; gap: 14px; align-content: start; }
.formathelp { padding: 12px 16px; }
.formathelp pre {
  margin: 10px 0 0;
  white-space: pre-wrap;
  font: 13px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--muted);
}
.confirmlead { margin: 10px 0 4px; }
.confirmform { display: flex; align-items: center; gap: 10px; margin-top: 12px; }

/* The board, rendered the way the Discord embed is. */
.orbatboard {
  background: var(--panel-2);
  border-left: 4px solid var(--accent);
  border-radius: 6px;
  padding: 14px 16px;
}
.orbatboard h3 { margin: 0 0 6px; font-size: 16px; }
.orbatboard .counts { color: var(--muted); font-size: 14px; margin: 0 0 12px; }
.orbatfields { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 18px; }
@media (max-width: 560px) { .orbatfields { grid-template-columns: 1fr; } }
.squadname { font-size: 13px; font-weight: 600; margin-bottom: 3px; }
.squadradio {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 2px;
  font-variant-numeric: tabular-nums;
}
.squadslots { font-size: 13.5px; line-height: 1.65; white-space: pre-wrap; }
.squadslots .off { color: var(--muted); }
.nocount { color: var(--muted); font-weight: 400; font-size: 12px; }
.squadunit {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 4px;
  margin-left: 4px;
  vertical-align: 1px;
}

/* The shared net list, laid out like the table people already keep by hand. */
.netsblock { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
table.nets { border-collapse: collapse; font-size: 13px; margin-top: 4px; }
table.nets td { padding: 2px 14px 2px 0; }
table.nets td:last-child {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
tr.netoff td { text-decoration: line-through; opacity: .55; }

.netsfield {
  min-height: 0 !important;
  font: 13px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

.issues { margin: 0; padding-left: 18px; }
.issues li { margin: 3px 0; }
.lineno {
  font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 5px;
}

.difflist { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.difflist li { padding: 4px 0; border-bottom: 1px solid var(--line); }
.difflist li:last-child { border-bottom: 0; }
.tag { display: inline-block; min-width: 88px; font-size: 12px; font-weight: 600; }
.tag.added { color: var(--ok); }
.tag.removed { color: var(--err); }
.tag.renamed { color: var(--warn); }
.tag.kept { color: var(--muted); }

/* -- slot approvals ------------------------------------------------------ */

.chip.contested { border-color: var(--warn); color: var(--warn); }

/* The ORBAT backing the operation running right now. */
.chip.live { border-color: var(--err); color: var(--err); }
.denyrow { display: flex; gap: 8px; margin-top: 10px; }
.denyrow input { flex: 1; }

/* -- the operation page -------------------------------------------------- */

/* An action folded away until it is wanted. Native <details>, so it works with
   scripting off, which is the rule for everything else on this site too. */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-top: 10px;
}
.panel > summary {
  padding: 12px 16px;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  display: flex;
  gap: 10px;
  align-items: baseline;
}
.panel > summary::-webkit-details-marker { display: none; }
.panel > summary::before { content: '▸'; color: var(--muted); }
.panel[open] > summary::before { content: '▾'; }
.panel > summary .note { font-weight: 400; font-size: 13px; color: var(--muted); }
.panel > summary:hover { color: var(--accent); }
.panelbody { padding: 0 16px 16px; }
.panelbody .form { margin-top: 0; }

/* The running operation, above the fold: what it is, then its numbers. */
.opstatus { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: baseline; }
.opstatus .counts { color: var(--muted); font-size: 14px; }

/* The raw slot dump can be wider than the column; it scrolls on its own rather
   than making the whole page scroll sideways. */
.tablewrap { overflow-x: auto; margin-top: 10px; }

table.rawslots { border-collapse: collapse; font-size: 13px; width: 100%; }
table.rawslots th, table.rawslots td {
  padding: 5px 14px 5px 0;
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--line);
}
table.rawslots th { color: var(--muted); font-weight: 600; }
table.rawslots tr:last-child td { border-bottom: 0; }

/* One booked slot, with its Release button pushed to the far edge. */
.slotrow {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}
.slotrow:last-of-type { border-bottom: 0; }

/* The Assign form: who, which slot, go — on one line where there is room. */
.assignrow { display: flex; gap: 10px; align-items: end; flex-wrap: wrap; }
.assignrow .field { flex: 1 1 220px; }

/* -- the tactical map ----------------------------------------------------- *
   The editor is the one page with scripting behind it, so it is also the one
   place with a toolbar. Everything here degrades to "an SVG on a page", which
   is exactly what somebody with scripting off gets. */

.tmapp {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  overflow: hidden;
  margin-bottom: 20px;
}

.tmbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: var(--panel-2);
  border-bottom: 1px solid var(--line);
}

.tmtools, .tmpick, .tmdo { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.tmpick { gap: 12px; }
.tmpick label { font-size: 13px; color: var(--muted); display: flex; gap: 6px; align-items: center; }
.tmpick select { padding: 5px 8px; }

.tmtool {
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
.tmtool:hover { border-color: var(--muted); }
.tmtool.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.tmtool { position: relative; }
.tmtool.locked::after { content: '🔒'; position: absolute; top: 1px; right: 2px; font-size: 10px; }

.tmstatus { font-size: 13px; color: var(--muted); min-width: 120px; }
/* One line, always: a hint that wraps when it changes moves the whole map
   down under the pointer between two clicks of a line being plotted. The
   full text is in the title. A refusal may wrap — it carries buttons, and
   nobody is mid-click when it appears. */
.tmstatus { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 52ch; }
.tmstatus.err { white-space: normal; }
.tmstatus.ok { color: var(--ok); }
.tmstatus.warn { color: var(--warn); }
.tmstatus.err { color: var(--err); }

.tmstage { display: grid; grid-template-columns: 1fr 250px; gap: 0; }
.tmcanvas { background: #10141a; min-width: 0; position: relative; }

/* A square terrain is limited by height, not width, so the sheet gets as much
   of the window as the page chrome leaves — and the full-screen button gets
   the rest of it when that is still not enough. */
svg.tacmap {
  display: block;
  width: 100%;
  height: auto;
  max-height: max(420px, calc(100vh - 210px));
  /* The wheel zooms and a drag pans, so the browser must not also scroll. */
  touch-action: none;
}

.tmfull {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(16, 20, 26, 0.82);
  color: #e6eaf0;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.tmfull:hover { border-color: var(--muted); }
/* The grid reference under the pointer, and lengths while drawing. */
.tmreadout {
  position: absolute; left: 10px; top: 10px; z-index: 2;
  padding: 3px 8px; border-radius: 6px;
  background: rgba(16, 20, 26, 0.78); color: #e6edf3;
  font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  pointer-events: none; white-space: nowrap;
}
.tmreadout:empty { display: none; }
.tmreport { margin: 0 0 14px; padding: 10px 14px; border: 1px solid var(--line); border-radius: 8px; }
.tmreport p { margin: 0 0 4px; }
.tmreport ul { margin: 4px 0 0; padding-left: 18px; font-size: 14px; }
.tmmeasure { margin: 0 0 8px; font-size: 13px; color: var(--muted); }
/* A line's corners, once it is selected. */
.tacmap .tm-vertex { fill: #ffffff; stroke: #1f6feb; stroke-width: 2; vector-effect: non-scaling-stroke; cursor: move; }
.tacmap .tm-mid { fill: #1f6feb; fill-opacity: 0.55; stroke: #ffffff; stroke-width: 1; vector-effect: non-scaling-stroke; cursor: copy; }
.tacmap .tm-marquee { fill: #1f6feb; fill-opacity: 0.12; stroke: #58a6ff; stroke-width: 1; stroke-dasharray: 4 3; vector-effect: non-scaling-stroke; }
.tacmap .tm-snapmark { fill: none; stroke: #ffd166; stroke-width: 2; vector-effect: non-scaling-stroke; }

/* Full screen, and the fallback for a browser that refuses it. */
.tmapp:fullscreen { background: #10141a; display: flex; flex-direction: column; }
.tmapp:fullscreen .tmstage { flex: 1; min-height: 0; }
.tmapp:fullscreen svg.tacmap { max-height: 100vh; }
.tmapp:fullscreen .tmside { max-height: 100vh; }
.tmapp.tm-tall svg.tacmap { max-height: 94vh; }
svg.tacmap.tm-drawing { cursor: crosshair; }
.tm-item { cursor: move; }
.tm-ring {
  fill: none;
  stroke: #ffffff;
  stroke-width: 2;
  stroke-dasharray: 7 5;
  pointer-events: none;
}
/* A selected shape's handles: corners resize, the round one turns it. */
.tm-handle {
  fill: #ffffff;
  stroke: #11161c;
  stroke-width: 1.5;
  cursor: nwse-resize;
  pointer-events: all;
}
.tm-handle.tm-turn { cursor: grab; fill: #f2c832; }
.tm-stalk {
  stroke: #ffffff;
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
  pointer-events: none;
}

.tmside {
  border-left: 1px solid var(--line);
  padding: 12px;
  display: grid;
  gap: 12px;
  align-content: start;
  max-height: max(420px, calc(100vh - 210px));
  overflow-y: auto;
}
.tmpanel {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  background: var(--panel-2);
  display: grid;
  gap: 10px;
}
.tmpanel h3 { margin: 0; font-size: 15px; }
.tmpanel summary { cursor: pointer; font-size: 14px; }
.tmpanel .field > span { font-size: 13px; }
.tmpanel .row { grid-template-columns: 1fr 1fr; gap: 10px; }
.tmcheck { display: flex; gap: 8px; align-items: center; }
/* A row of colour buttons. Small, square and wrapping, so ten of them fit on
   the tool row without pushing anything off it. */
.tmswatches { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.tmswatches .tmswatch {
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 5px;
  cursor: pointer;
}
/* The first one hands the item back to its side's colour, so it shows the
   absence of a choice rather than a colour: a diagonal through an empty box. */
.tmswatches .tmswatch-side {
  background:
    linear-gradient(to top right, transparent 45%, var(--muted) 45%,
                    var(--muted) 55%, transparent 55%),
    var(--panel);
}
.tmswatches .tmswatch.active {
  outline: 2px solid var(--accent, #6b8afd);
  outline-offset: 1px;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.tmhelp { font-size: 13px; color: var(--muted); }
.tmhelp ul { margin: 0; padding-left: 18px; display: grid; gap: 6px; }
/* Sits under the tool row rather than in the side panel: it names the one
   gesture that is not a button, so it has to be where the buttons are. */
.tmhint {
  margin: 0;
  flex-basis: 100%;
  font-size: 12px;
  color: var(--muted);
}
.tmhint kbd,
.tmhelp kbd {
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0 4px;
  background: var(--panel);
  font-size: 12px;
}

/* The two Arma exports, side by side rather than one hidden behind the other:
   which to use is the question, so both have to be on screen to be compared. */
.tmexport {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  margin-top: 14px;
}
.tmexport h3 { margin: 0 0 8px; font-size: 15px; }
.tmexport h3 .note { font-weight: 400; }

.tmsection { margin-bottom: 14px; }
.tmsection summary { cursor: pointer; font-weight: 600; }
.tmsection h3 { margin: 18px 0 6px; font-size: 15px; }

@media (max-width: 900px) {
  .tmstage { grid-template-columns: 1fr; }
  .tmside { border-left: 0; border-top: 1px solid var(--line); max-height: none; }
}

/* The export script: monospaced, and tall enough to see a plan's worth of it
   without the panel growing past the fold. */
.sqfbox {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.45;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
}

/* One switch per layer, for whoever is looking at the map — the editor also
   gets the name and a way to remove one. */
.tmlayerlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.tmlayer { display: flex; align-items: center; gap: 8px; font-size: 14px; }
/* A layer the campaign planner names: read here, renamed there. */
.tmlayer .tmlayerfixed { flex: 1; min-width: 0; padding: 4px 6px; cursor: help; }
.tmlayer .tmlayerfixed::before { content: '🔗 '; opacity: 0.7; }
.tmlayer .tmlayername {
  flex: 1;
  min-width: 0;
  padding: 4px 6px;
  font-size: 13px;
}
.tmaddlayer { display: flex; gap: 6px; }
.tmaddlayer input { flex: 1; min-width: 0; padding: 5px 8px; font-size: 13px; }

/* A line's own colour, and the way back to its side's. */
.tmcolour { display: flex; align-items: center; gap: 10px; }
.tmcolour input[type="color"] {
  width: 46px;
  height: 30px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel);
}

/* The editor hides whatever doesn't apply to the current tool or selection.
   Every panel and field here sets `display`, which would otherwise beat the
   browser's own rule for [hidden] and leave them all on screen at once. */
.tmapp [hidden] { display: none; }

/* A second, quieter script inside the Arma panel — the variant whose markers
   can be picked up in game. It is folded away because it is the exception. */
.subpanel { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 12px; }
.subpanel > summary { cursor: pointer; font-weight: 600; color: var(--muted); }
.subpanel[open] > summary { margin-bottom: 10px; color: var(--text); }

/* A one-line form inside a panel — the channel picker beside its button. */
.form.inline { display: flex; align-items: flex-end; gap: 10px; margin: 12px 0; }
.form.inline .field { margin: 0; }

/* --- Help ---------------------------------------------------------------
   The how-tos, served from utils/help.py. Two entry points: the round `?` in
   the header, which goes to the index, and the `?` at the end of the tab row,
   which goes to the current page's own how-to. */

.topbarend { display: flex; align-items: center; gap: 16px; }

.helpbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--muted);
  font-weight: 700;
  text-decoration: none;
  flex: none;
}

.helpbtn:hover { color: var(--text); border-color: var(--accent); }

/* Pushed to the far end of the tab row, so it reads as "about this page"
   rather than as one more tab. */
.tab.helptab {
  margin-left: auto;
  font-weight: 700;
  padding: 8px 12px;
}

.tab.helptab:hover { color: var(--text); }

.helpsearch {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0 8px;
  flex-wrap: wrap;
}

.helpsearch input {
  flex: 1 1 260px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font: inherit;
}

.helpshelf { margin-top: 30px; }
.helpshelf h2 { margin-bottom: 4px; }
.helpshelf .muted { margin-top: 0; }

.helpgrid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  margin-top: 14px;
}

.helpcard {
  display: grid;
  gap: 6px;
  align-content: start;
  padding: 14px 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  text-decoration: none;
}

.helpcard:hover { border-color: var(--accent); }
.helpcardtitle { font-weight: 600; }
.helpcard .chip { justify-self: start; font-size: 12px; color: var(--muted); }
.helpcardsummary { color: var(--muted); font-size: 14px; }

.helpmeta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.helpsteps, .helpnotes { margin-top: 16px; }
.helpsteps h2, .helpnotes h2 { margin: 0 0 10px; font-size: 17px; }
.helpsteps ol, .helpnotes ul { margin: 0; padding-left: 22px; }
.helpsteps li, .helpnotes li { margin-bottom: 8px; }
.helpsteps li:last-child, .helpnotes li:last-child { margin-bottom: 0; }
.helpnotes li { color: var(--muted); }

.helpsteps code, .helpnotes code, .helpmeta code {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 1px 5px;
  font-size: 0.92em;
}

.helpsteps .cardbody, .helpnotes .cardbody { padding: 16px; }

/* The terrain's own place names: the paste box on the terrain list, and the
   group filter in the map editor. */
.placebox { margin-top: 10px; width: 100%; }
.placebox textarea { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
                     font-size: 13px; }
.chip.warn { border-color: var(--warn); color: var(--warn); }
#tmf-placebox { margin: 4px 0 10px; }
#tmf-placegroups { display: grid; gap: 2px; margin: 6px 0; }
#tmf-placegroups .field { margin: 0; }

/* Kill Tracker admin: a scrollable list of checkboxes (missions to pick for a campaign). */
.ktpick {
  display: grid; gap: 4px; max-height: 420px; overflow: auto;
  border: 1px solid var(--line); border-radius: 6px; padding: 8px 10px; background: var(--panel-2);
}
.ktpick label { display: flex; gap: 8px; align-items: baseline; }

/* -- campaign planner ------------------------------------------------------ */

.okchip { border-color: var(--ok); color: var(--ok); }
.cpcard .cardbody { padding: 14px 16px; }
.cpcardhead { display: flex; gap: 10px; align-items: center; justify-content: space-between; }
.cpcardtitle { font-weight: 600; font-size: 18px; text-decoration: none; }
.cpcardtitle:hover { text-decoration: underline; }
.cpmissions { margin: 10px 0 0; padding-left: 22px; display: grid; gap: 6px; }
.cpmissions li { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.cpmissions li.past, .cprow.past { opacity: .7; }
.cpopen { font-style: italic; }
.cpnext { font-size: 13px; color: var(--muted); }
.cpnext.warn, .cpstatus.warn { color: var(--warn); }
.cpnext.crit, .cpstatus.crit { color: var(--err); }
.cpstatus.ok { color: var(--ok); }
.cpstatus.acc { color: var(--accent); }
.cpsummary { white-space: pre-wrap; padding: 14px 16px; }

.cplist { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.cplist .cprow {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px;
}
.cplist .cprow.cpopen { border-style: dashed; background: transparent; }
.cpnum {
  width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  background: var(--panel-2); border: 1px solid var(--line); font-weight: 600; flex: none;
}
.cprowmain { flex: 1; min-width: 180px; display: flex; flex-direction: column; }
.cprowtitle { font-weight: 600; text-decoration: none; }
.cprowtitle:hover { text-decoration: underline; }
.cpaos { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.cpao {
  display: flex; gap: 8px; align-items: center; padding: 8px 10px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
}
.cpao form { margin: 0; }
.cpao .inlineform { flex: 1; display: flex; gap: 8px; align-items: center; }

.cptable { width: 100%; border-collapse: collapse; font-size: 14px; }
.cptable th, .cptable td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.cptable th { color: var(--muted); font-weight: 500; }
.cpschedule tr.cpk-op td { font-weight: 600; }
.cpjump { display: flex; flex-wrap: wrap; gap: 6px; }
.cpjump .chip { text-decoration: none; }

.cpchecks { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 6px; font-size: 14px; }
.cpchecks li.crit { color: var(--err); }
textarea.cppost { font: 13px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace; margin-bottom: 10px; }
.cpthumbs { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.cpthumbs img { max-height: 110px; max-width: 180px; border-radius: 6px; border: 1px solid var(--line); display: block; }

/* the wizard */
.cpheadactions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.cpsave { font-size: 14px; color: var(--muted); }
.cpsave.ok { color: var(--ok); }
.cpsave.err { color: var(--err); }
.cpsteps { display: flex; gap: 6px; flex-wrap: wrap; margin: 6px 0 16px; }
.cpstep {
  display: grid; grid-template-columns: auto 1fr auto; text-align: left;
  align-items: baseline; column-gap: 8px; row-gap: 2px;
  padding: 7px 12px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel); color: var(--text); cursor: pointer; font: inherit;
}
.cpstep:hover { border-color: var(--accent); }
.cpstep.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.cpstep.complete:not(.active) { border-color: var(--ok); }
.cpstepnum { font-weight: 700; }
.cpstepcount { font-size: 12px; opacity: .85; }
/* The second line of a step tab: its lock date and how long is left. */
.cpstepdue { grid-column: 1 / -1; font-size: 11.5px; opacity: .8; text-align: left; }
.cpstepdue:empty { display: none; }
.cpstepdue.warn { color: var(--warn); opacity: 1; font-weight: 600; }
.cpstepdue.crit { color: var(--err); opacity: 1; font-weight: 600; }
.cpstep.active .cpstepdue.warn, .cpstep.active .cpstepdue.crit { color: #fff; }
.cpwork { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 20px; align-items: start; }
@media (max-width: 980px) { .cpwork { grid-template-columns: 1fr; } }
.cpside { display: grid; gap: 12px; position: sticky; top: 12px; max-height: calc(100vh - 24px); overflow-y: auto; }
.cpside .cardbody { padding: 12px 14px; }
.cptips { margin: 6px 0 0; padding-left: 18px; font-size: 14px; color: var(--muted); }
.cpstephead { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.cpstephead h2 { margin: 0; }
.cpgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 18px; }
@media (max-width: 700px) { .cpgrid { grid-template-columns: 1fr; } }
.cpfield { display: grid; gap: 6px; align-content: start; }
.cpfield.wide { grid-column: 1 / -1; }
.cpfield.private { background: var(--panel-2); border: 1px dashed var(--warn); border-radius: 10px; padding: 10px; }
.cplabel { font-size: 14px; color: var(--muted); display: flex; gap: 8px; align-items: center; }
.cpreq { color: var(--accent); font-weight: 700; }
.cpfield input[type='date'], .cpfield input[type='time'] {
  padding: 8px 10px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text); font: inherit;
}
.cprows { display: grid; gap: 6px; }
.cprows .cprow { display: grid; grid-template-columns: auto 1fr auto; gap: 6px; align-items: start; }
.cprows .cprow.cols2 { grid-template-columns: auto 1fr 1fr auto; }
.cprowtools { display: flex; gap: 2px; white-space: nowrap; }
.cprowtools .linkish { padding: 4px 6px; }
.cprowtools .linkish[disabled] { opacity: .3; cursor: default; }
.cpremove { color: var(--err); }
.cpdrag { cursor: grab; color: var(--muted); padding: 8px 2px; user-select: none; }
.dragging { opacity: .45; }
.dropover { outline: 2px dashed var(--accent); outline-offset: 2px; }
.cpadd { justify-self: start; }
.cpgroups { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; }
.cpgroupsextra { flex: 1; min-width: 200px; }
.cpimages { border: 1px dashed var(--line); border-radius: 10px; padding: 10px; }
.cpimages:focus { outline: 2px solid var(--accent); }
.cpimagebar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.cpthumb { margin: 0; display: grid; gap: 4px; }
.cpthumb figcaption { display: flex; gap: 6px; align-items: center; font-size: 12px; }
.cpthumb figcaption .muted { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cppart { position: relative; margin-top: 8px; }
.cppre {
  white-space: pre-wrap; word-break: break-word; margin: 0; padding: 10px; border-radius: 8px;
  background: var(--panel-2); border: 1px solid var(--line); font: 12.5px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace;
  max-height: 420px; overflow-y: auto;
}

.cpphases { display: grid; gap: 12px; margin-bottom: 8px; }
.cpphase { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 12px; display: grid; gap: 8px; }
.cpphasehead { display: grid; grid-template-columns: auto auto 1fr 200px auto; gap: 8px; align-items: center; }
@media (max-width: 700px) { .cpphasehead { grid-template-columns: auto auto 1fr auto; } .cpphasehead select { grid-column: 3 / 4; } }
.cpphasenum {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent); color: #fff; font-weight: 700; font-size: 14px;
}
.cpobjectives { display: grid; gap: 8px; }
.cpobjective { border-left: 4px solid var(--accent); background: var(--panel-2); border-radius: 8px; padding: 8px; display: grid; gap: 6px; }
.cpobjective.role-secondary { border-left-color: var(--ok); }
.cpobjective.role-complication { border-left-color: var(--warn); }
.cpobjhead { display: grid; grid-template-columns: auto 150px 1fr auto; gap: 6px; align-items: center; }
.cpphaseactions { display: flex; gap: 8px; }
.cppicker { border: 1px solid var(--accent); border-radius: 10px; padding: 10px; background: var(--panel-2); }
.cppickbar { display: flex; gap: 10px; align-items: center; }
.cppickbar input { flex: 1; }
.cppicklist { max-height: 340px; overflow-y: auto; margin-top: 8px; display: grid; gap: 2px; }
.cppickcat { margin: 10px 0 4px; font-size: 13px; color: var(--muted); font-weight: 600; }
.cppick {
  text-align: left; background: transparent; border: 1px solid transparent; border-radius: 6px;
  padding: 6px 8px; color: var(--text); font: inherit; font-size: 14px; cursor: pointer;
}
.cppick:hover { border-color: var(--accent); background: var(--panel); }
.cppick.suggested { border-color: var(--ok); }
.cpfielderr { color: var(--err); font-size: 14px; margin: 6px 0 0; }
.cpaddao { display: flex; gap: 8px; margin-top: 10px; }
.cpaddao button, .cpao button { white-space: nowrap; }

.testchip { border-color: var(--warn); color: var(--warn); }
.cptestbar, .cptestbanner {
  display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap;
}
.cptestbar { background: var(--panel); border: 1px dashed var(--warn); border-radius: 10px; padding: 10px 14px; margin-bottom: 12px; }
.cptestactions { display: flex; gap: 8px; }
.cptestactions form { margin: 0; }

.cptools { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; margin-bottom: 18px; }
.cptool .cardbody { padding: 12px 14px; display: grid; gap: 8px; }
.cptoolrow { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.cptoolrow form { margin: 0; }
.cporbat { display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; }
.cporbatform { display: grid; gap: 8px; margin-top: 8px; }
.cpsub > summary { cursor: pointer; color: var(--muted); font-size: 14px; }
.cppacks { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.cppacks li { display: grid; grid-template-columns: 1fr auto; gap: 2px 8px; align-items: center; }
.cppacklinks { display: flex; gap: 6px; }
.cppacklinks .button { padding: 4px 10px; font-size: 14px; }
.cppackdesc { grid-column: 1 / -1; font-size: 13px; }

/* The overview tab. Its body is `_cp_schedule_body.html`, which the schedule
   page styles already cover; only the tab marker and the stale note are its
   own. */
.cpstep.cpstepover .cpstepnum { font-weight: 400; opacity: .8; }
.cpover .cpstephead { margin-bottom: 10px; }
#cp-overstale { margin: 0 0 14px; }

/* Drops and approvals (campaign planner, milestone 4) */
.button.small { padding: 5px 11px; font-size: 13px; }
form.inline { display: inline; margin: 0; }
.cpdropbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 10px; }
.cpdropbar > .muted { flex: 1 1 220px; }
details.panel > summary .cpstatus { margin-left: 8px; font-size: 13px; font-weight: 600; }
.cpsignups { margin: 6px 0 14px; }
.cpsignups .inlineform { margin-top: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.cpdropstate { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 6px 0 10px; }

/* Maps (campaign planner, milestone 5) */
.cpmapbox { display: flex; flex-direction: column; gap: 10px; margin: 8px 0 14px; align-items: flex-start; }
.cpmapframe { width: 100%; max-width: 440px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: #20262e; }
.cpmapframe svg { display: block; width: 100%; height: auto; }
.cpmaprow { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start; width: 100%; }
.cpmaprow .cpmapframe { flex: 1 1 280px; }
.cpmapkey { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; min-width: 140px; }
.cpmapkey li { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.cpmapswatch { flex: none; width: 22px; height: 14px; border-radius: 3px; border: 2px solid #11161c; box-shadow: 0 0 0 1px #f5f5f5; }
.cpmaplist { list-style: none; padding: 0; margin: 8px 0; }
.cpmaplist li { margin: 4px 0; }
.cpmaplist form { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0; }
.cpstatsline { font-size: 14px; margin: 6px 0 8px; }

/* -- A drop as Discord shows it (utils/discordmd.py) -------------------------
   Discord's own dark theme, whatever the site's theme is: the point is to see
   the post the way the unit will. */
.cpprevhead { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dcdialog { width: min(760px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0;
  border: 0; border-radius: 10px; background: #313338; color: #dbdee1; box-shadow: 0 12px 48px rgba(0,0,0,.55); }
.dcdialog[open] { display: flex; flex-direction: column; }
.dcdialog::backdrop { background: rgba(0,0,0,.6); }
.dcbar { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid #1f2023; }
.dcchannel { font-weight: 600; color: #f2f3f5; font-size: 15px; }
.dcclose { background: none; border: 0; color: #b5bac1; font-size: 18px; cursor: pointer; padding: 2px 6px; border-radius: 4px; }
.dcclose:hover { color: #fff; background: #3f4147; }
.dcfoot { margin: 0; padding: 10px 16px 14px; font-size: 12px; color: #949ba4; border-top: 1px solid #1f2023; }
.dcscroll { overflow-y: auto; padding: 14px 0 10px; background: #313338; color: #dbdee1;
  font-family: "gg sans", "Noto Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 15px; line-height: 1.375; }
.dcinline { margin: 6px 0 10px; }
.dcinline > summary { cursor: pointer; font-weight: 600; }
.dcinline .dcscroll { border-radius: 8px; margin-top: 8px; max-height: 70vh; }
.dcmsg { position: relative; padding: 2px 16px 2px 72px; min-height: 44px; }
.dcmsg.dcfollow { min-height: 0; padding-top: 4px; }
.dcmsg:hover { background: #2e3035; }
.dcavatar { position: absolute; left: 16px; top: 4px; width: 40px; height: 40px; border-radius: 50%; object-fit: cover; }
.dcinitial { display: flex; align-items: center; justify-content: center; background: #5865f2; color: #fff; font-weight: 700; }
.dchead { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.dcname { color: #f2f3f5; font-weight: 600; }
.dctag { background: #5865f2; color: #fff; font-size: 10px; font-weight: 600; padding: 1px 4px; border-radius: 3px; line-height: 15px; }
.dcwhen { color: #949ba4; font-size: 12px; }
.dcbody { overflow-wrap: anywhere; }
.dc-content { white-space: normal; }
.dc-h1 { font-size: 24px; font-weight: 700; line-height: 1.375; margin: 8px 0 4px; color: #f2f3f5; }
.dc-h2 { font-size: 20px; font-weight: 700; margin: 8px 0 4px; color: #f2f3f5; }
.dc-h3 { font-size: 16px; font-weight: 700; margin: 8px 0 4px; color: #f2f3f5; }
.dc-content > :first-child { margin-top: 0; }
.dc-sub { font-size: 13px; color: #949ba4; }
.dc-gap { height: 1.375em; }
.dc-quote { margin: 0; padding: 0 0 0 12px; border-left: 4px solid #4e5058; }
.dc-list { margin: 2px 0; padding-left: 26px; }
.dc-list li { margin: 1px 0; }
.dc-list li.dc-deep { margin-left: 18px; list-style-type: circle; }
.dc-code { background: #2b2d31; border: 1px solid #1e1f22; border-radius: 4px; padding: 0 3px;
  font-family: Consolas, "Andale Mono WT", Monaco, monospace; font-size: 85%; }
.dc-pre { background: #2b2d31; border: 1px solid #1e1f22; border-radius: 4px; padding: 7px; margin: 4px 0;
  white-space: pre-wrap; font-family: Consolas, "Andale Mono WT", Monaco, monospace; font-size: 13px; color: #dbdee1; }
.dc-link { color: #00a8fc; text-decoration: none; }
.dc-link:hover { text-decoration: underline; }
.dc-mention { background: rgba(88,101,242,.3); color: #c9cdfb; border-radius: 3px; padding: 0 2px; font-weight: 500; }
.dc-role { --dc-role: #c9cdfb; color: var(--dc-role); background: color-mix(in srgb, var(--dc-role) 18%, transparent); }
.dc-ts { background: rgba(255,255,255,.06); border-radius: 3px; padding: 0 2px; }
.dc-spoiler { background: #1e1f22; color: transparent; border-radius: 3px; cursor: pointer; }
.dc-spoiler.shown { background: rgba(255,255,255,.1); color: inherit; }
.dc-spoiler * { visibility: hidden; }
.dc-spoiler.shown * { visibility: visible; }
.dcimages { display: grid; grid-template-columns: repeat(2, minmax(0, 220px)); gap: 4px; margin-top: 6px; }
.dcimages.one { grid-template-columns: minmax(0, 420px); }
.dcimages img { width: 100%; height: auto; max-height: 300px; object-fit: cover; border-radius: 8px; display: block; }
@media (max-width: 600px) { .dcmsg { padding-left: 60px; } .dcavatar { left: 10px; width: 36px; height: 36px; } }
.dcinline .dc-spoiler:hover { background: rgba(255,255,255,.1); color: inherit; }
.dcinline .dc-spoiler:hover * { visibility: visible; }

/* -- the map editor's layout ------------------------------------------------ *
   One bar (the page's menus, then saving), a rail of tools down the left, the
   map filling the middle, and a side panel that shows what the tool in hand
   will draw or what is selected. The map takes the height of the window, and
   "Whole window" hands it the rest. */
.tmeditor { overflow: visible; }
.tmeditor .tmbar {
  position: relative; flex-wrap: nowrap; padding: 8px 10px; gap: 10px;
  border-radius: 12px 12px 0 0;
}
.tmmenus { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; min-width: 0; }
.tmmenu > summary {
  list-style: none; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); cursor: pointer; font-size: 14px; white-space: nowrap; user-select: none;
}
.tmmenu > summary::-webkit-details-marker { display: none; }
.tmmenu > summary:hover { border-color: var(--muted); }
.tmmenu[open] > summary { background: var(--accent); border-color: var(--accent); color: #fff; }
.tmmenupanel {
  position: absolute; top: calc(100% + 4px); left: 10px; z-index: 30;
  width: min(580px, calc(100vw - 40px)); max-height: min(72vh, 760px); overflow: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.38); padding: 14px 16px;
}
.tmmenutitle { margin: 0 0 10px; font-size: 16px; }
.tmmenutitle .note { font-weight: 400; }
.tmeditor .tmdo { flex-wrap: nowrap; min-width: 0; }
.tmeditor .tmdo .button { white-space: nowrap; }
.tmeditor .tmdo .tmstatus { min-width: 0; flex: 1 1 auto; }
.tmauto { font-size: 13px; color: var(--muted); display: flex; gap: 5px; align-items: center; white-space: nowrap; }

.tmeditor .tmstage {
  grid-template-columns: 76px minmax(0, 1fr) 292px;
  height: max(520px, calc(100vh - 150px));
}
.tmrail {
  display: flex; flex-direction: column; gap: 4px; padding: 8px 6px; overflow-y: auto;
  border-right: 1px solid var(--line); background: var(--panel-2);
}
.tmrail .tmtool {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 2px 6px; font-size: 11px; line-height: 1.1;
}
.tmrail .tmicon { font-size: 18px; line-height: 1; }
.tmeditor .tmcanvas { overflow: hidden; }
.tmeditor svg.tacmap { height: 100%; max-height: none; }
.tmeditor .tmside { max-height: none; height: 100%; box-sizing: border-box; }

.tmzoom {
  position: absolute; right: 10px; bottom: 10px; z-index: 2;
  display: flex; flex-direction: column; gap: 4px;
}
.tmzoom button {
  width: 32px; height: 32px; border-radius: 8px; border: 1px solid var(--line);
  background: rgba(16, 20, 26, 0.82); color: #e6eaf0; font-size: 17px; line-height: 1; cursor: pointer;
}
.tmzoom button:hover { border-color: var(--muted); }

/* The tool's options, stacked in the side panel. */
.tmside .tmpick { display: grid; gap: 8px; }
.tmside .tmpick h3 { margin: 0; }
.tmside .tmpick label {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  font-size: 13px; color: var(--muted);
}
.tmside .tmpick label.tmcheck { justify-content: flex-start; }
.tmside .tmpick select { max-width: 172px; min-width: 0; }
.tmside .tmpick [hidden], .tmside .tmpick[hidden] { display: none; }
.tmrail.tmtools { align-items: stretch; flex-wrap: nowrap; }
.tmmenutitle .note { border: 0; background: none; padding: 0; font-size: 13px; font-weight: 400;
  color: var(--muted); }
.tmtoolhint { margin: 0; font-size: 12.5px; color: var(--muted); }
.tmtoolhint:empty { display: none; }
.tmhelp > summary { cursor: pointer; font-weight: 600; color: var(--text); }

/* Whole window: the editor over everything else on the page. */
.tmapp.tm-focus {
  position: fixed; inset: 0; z-index: 100; margin: 0; border-radius: 0; border: 0;
  display: flex; flex-direction: column;
}
.tmapp.tm-focus .tmbar { border-radius: 0; }
.tmapp.tm-focus .tmstage { flex: 1; height: auto; min-height: 0; }
body.tm-focused { overflow: hidden; }

/* Layers: order and lock. */
.tmlayerctl { display: inline-flex; gap: 1px; }
.tmlayer .tmlayerbtn:disabled { opacity: .3; cursor: default; }
.tmlayer .tmlayerbtn {
  border: 0; background: none; color: var(--muted); cursor: pointer; padding: 0 2px; font-size: 13px;
}
.tmlayer .tmlayerbtn:hover { color: var(--text); }
.tmlayer .tmlayerbtn.on { color: var(--warn); }

@media (max-width: 900px) {
  .tmeditor .tmbar, .tmeditor .tmdo { flex-wrap: wrap; }
  .tmeditor .tmstage { grid-template-columns: 1fr; height: auto; }
  .tmrail { flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .tmrail .tmtool { min-width: 58px; }
  .tmeditor .tmcanvas { height: 70vh; }
  .tmeditor .tmside { height: auto; border-left: 0; border-top: 1px solid var(--line); }
}

/* The mods inside a whole-list choice on the public selector: listed, not pickable. */
.modlist { margin: 4px 0 12px 26px; padding: 0; list-style: none; font-size: 13px; color: var(--muted); columns: 2 260px; }
.modlist li { padding: 1px 0; break-inside: avoid; }

.publicpages { padding-bottom: 32px; }
.publicpages h2 { margin-top: 0; }

.count-progress { margin: 12px 0; }
.count-progress progress { width: 100%; height: 12px; accent-color: var(--accent, #5865f2); }
