/* Self-hosted (no external font CDN, so the dashboard renders correctly
   even if this server has no outbound internet). */
@font-face {
  font-family: "VT323";
  src: url("/static/fonts/vt323-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Press Start 2P";
  src: url("/static/fonts/press-start-2p-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #0c120b;
  --bg-panel: #182415;
  --bg-panel-2: #1e2c19;
  --border: #3d5a33;       /* mid green, used for card edges / dividers */
  --border-dark: #070a06;  /* near-black, used for the beveled/pixel edge */
  --border-light: #4c7040; /* lighter green, used for the "raised" bevel edge */
  --text: #dcefce;
  --text-dim: #84a373;
  --accent: #7fd858;       /* bright pixel green */
  --accent-dim: #5a9440;
  --accent-bg: #1c2a16;
  --invert: #0a0f08;       /* dark text painted on top of an accent-colored fill */
  --good: #7fd858;
  --warn: #e0b95a;
  --bad: #e0776a;
  --mono: "VT323", "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --pixel: "Press Start 2P", var(--mono);
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --notch: 8px;
  --notch-sm: 5px;
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  /* plain dark field: the bevels and dashed rules carry the old-web look */
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);
  font-size: 18px;
  text-transform: lowercase;
}

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

/* Skin A, "green terminal homepage", sidebar edition: the nav groups
   stack down the left like an old homepage's link column, and the page
   column next to it keeps the full width the dash had before (the shell
   grows by exactly the sidebar's width). On a phone the sidebar folds
   back into a wrapping row of buttons above the page, so nothing ever
   scrolls sideways. */
.shell {
  max-width: 1460px;
  margin: 0 auto;
  padding: 14px 20px 0;
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}

.sidebar {
  position: sticky;
  top: 0;
  max-height: 100vh;
  overflow-y: auto;
  padding: 0 14px 20px 0;
  border-right: 2px dashed var(--border);
}

.masthead {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--accent);
  text-decoration: none;
  width: fit-content;
}
.masthead:hover { text-decoration: none; }
/* Crown only (no wordmark): 44px link box so it's a full touch target. */
.masthead { min-width: 44px; min-height: 44px; justify-content: center; }
.masthead img { width: 40px; height: 40px; image-rendering: auto; }

.sidenav { display: flex; flex-direction: column; gap: 14px; margin-top: 16px; }

.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  color: var(--text);
  padding: 0 10px;
  border-radius: 0;
  font-size: 18px;
  white-space: nowrap;
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
}
.nav-link:hover { background: #243418; text-decoration: none; }
.nav-link.active {
  background: var(--accent);
  color: var(--invert);
  border-style: inset;
  border-color: var(--accent-dim);
}
.nav-link.muted { color: var(--text-dim); background: transparent; border-color: transparent; border-style: solid; }
.nav-link.muted:hover { background: var(--bg-panel-2); }

.content {
  padding: 0 0 60px;
  min-width: 0;
}

h1 { font-size: 24px; margin: 0 0 6px 0; color: var(--text); }
h2 {
  font-size: 17px;
  margin: 32px 0 14px 0;
  color: var(--accent);
  border-bottom: 2px dotted var(--border);
  padding-bottom: 8px;
}
h3 { font-size: 15px; margin: 0 0 8px 0; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; }
.page-sub { color: var(--text-dim); margin-bottom: 20px; font-size: 15px; }

.flash {
  background: var(--accent-bg);
  border: 2px solid var(--accent-dim);
  color: var(--text);
  padding: 10px 14px;
  border-radius: 0;
  margin-bottom: 16px;
  font-size: 15px;
}
.flash.error { border-color: var(--bad); }

.card {
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 18px 20px;
  margin-bottom: 18px;
}

.tile-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}
.tile {
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 14px 16px;
}
.tile .tile-value { font-size: 20px; font-family: var(--pixel); color: var(--text); }
.tile .tile-label { color: var(--text-dim); font-size: 13px; margin-top: 6px; }
.tile.accent .tile-value { color: var(--accent); }
.tile.good .tile-value { color: var(--good); }
.tile.warn .tile-value { color: var(--warn); }

.task-row, .list-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px dotted var(--border);
}
.task-row:last-child, .list-row:last-child { border-bottom: none; }
.cat {
  font-size: 12px;
  padding: 2px 9px;
  border-radius: 0;
  border: 1px solid var(--border-dark);
  background: var(--bg-panel-2);
  color: #fff;
  white-space: nowrap;
}
.task-title { flex: 1; }
.task-meta { color: var(--text-dim); font-size: 13.5px; }

input[type=checkbox] {
  width: 18px; height: 18px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* Custom checkbox used for todo/chore completion, with the undo-buffer
   interaction handled in app.js */
.check-wrap {
  position: relative;
  display: inline-flex;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  cursor: pointer;
}
.check-wrap input[type=checkbox] {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}
.check-wrap .checkmark {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border: 2px solid var(--border-light);
  border-radius: 0;
  background: var(--bg-panel-2);
  transition: background 0.15s, border-color 0.15s;
}
.check-wrap .checkmark::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 2px;
  width: 6px;
  height: 11px;
  border: solid var(--invert);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 0.15s ease;
}
.check-wrap input:checked ~ .checkmark {
  background: var(--accent);
  border-color: var(--accent);
}
.check-wrap input:checked ~ .checkmark::after {
  transform: rotate(45deg) scale(1);
}

[data-task-row] {
  transition: opacity 0.25s ease;
}
[data-task-row].checking .task-title {
  color: var(--text-dim);
  text-decoration: line-through;
}
[data-task-row].fading {
  opacity: 0;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}
th {
  text-align: left;
  color: var(--text-dim);
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 8px 10px;
  border-bottom: 2px solid var(--border);
}
td {
  padding: 9px 10px;
  border-bottom: 1px dotted var(--border);
  vertical-align: top;
}
tr:hover td { background: var(--bg-panel-2); }

.pill {
  display: inline-block;
  font-size: 12px;
  padding: 2px 9px;
  border-radius: 0;
  border: 1px solid var(--border-dark);
  background: var(--bg-panel-2);
  color: var(--text-dim);
}
.pill.status-in-progress { color: var(--warn); background: #2a2312; border-color: #2a2312; }
.pill.status-posted, .pill.status-done { color: var(--good); background: #12261c; border-color: #12261c; }
.pill.alert { color: var(--invert); background: var(--bad); border-color: var(--border-dark); font-weight: 700; }

form.inline { display: inline; }

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 6px;
}
.form-grid .full { grid-column: 1 / -1; }

label { display: block; font-size: 13px; color: var(--text-dim); margin-bottom: 4px; }

input, select, textarea {
  width: 100%;
  background: var(--bg-panel-2);
  border: 2px solid var(--border-dark);
  color: var(--text);
  border-radius: 0;
  padding: 8px 10px;
  font-size: 15px;
  font-family: inherit;
  text-transform: inherit;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--accent-dim);
  outline-offset: 1px;
  border-color: var(--accent);
}
textarea { min-height: 60px; resize: vertical; }

button, .btn {
  background: var(--accent);
  color: var(--invert);
  border-top: 2px solid #b6f2a0;
  border-left: 2px solid #b6f2a0;
  border-bottom: 2px solid var(--border-dark);
  border-right: 2px solid var(--border-dark);
  border-radius: 0;
  padding: 8px 16px;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  text-transform: inherit;
  cursor: pointer;
  display: inline-block;
}
button:hover, .btn:hover { background: var(--accent-dim); color: #fff; text-decoration: none; }
button:active, .btn:active {
  border-top-color: var(--border-dark);
  border-left-color: var(--border-dark);
  border-bottom-color: #b6f2a0;
  border-right-color: #b6f2a0;
}
button.secondary, .btn.secondary {
  background: var(--bg-panel-2);
  color: var(--text);
  border-top-color: var(--border-light);
  border-left-color: var(--border-light);
  border-bottom-color: var(--border-dark);
  border-right-color: var(--border-dark);
}
button.secondary:hover, .btn.secondary:hover { background: var(--bg-panel); color: var(--text); }
button.small, .btn.small { padding: 5px 10px; font-size: 13px; }
button.danger { background: var(--bg-panel-2); color: var(--bad); border-color: var(--border-dark); }
button.danger:hover { background: #2a1613; color: var(--bad); }

.filters { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; align-items: end; }
.filters .field { min-width: 140px; }

.csv-io { position: relative; }
.csv-io summary {
  list-style: none;
  cursor: pointer;
}
.csv-io summary::-webkit-details-marker { display: none; }
.csv-io-panel {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 6px;
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 220px;
  z-index: 5;
}
.csv-io-panel input[type=file] { width: 100%; }

/* Collapsible side-by-side blocks (e.g. mutual aid add/import) */
.collapsible-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 18px;
}
@media (max-width: 760px) {
  .collapsible-row { grid-template-columns: 1fr; }
}
.collapsible-row > details {
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 14px 18px;
}
.collapsible-row > details > summary {
  cursor: pointer;
  font-size: 15px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
}
.collapsible-row > details[open] > summary { margin-bottom: 12px; }

.empty-state { color: var(--text-dim); padding: 20px 4px; font-size: 15px; }

/* Quick-add: a single-line title input + button, with any extra fields
   tucked into a collapsed-by-default <details> beneath. */
.quick-add-row { display: flex; gap: 8px; }
.quick-add-row input[type=text] { flex: 1; }
details.inline-details { margin-top: 2px; }
details.inline-details > summary {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 13px;
  padding: 4px 0;
}
details.inline-details[open] > summary { margin-bottom: 8px; }

/* A whole card that collapses (e.g. "add an event"). */
details.card > summary {
  cursor: pointer;
  font-size: 15px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  list-style: none;
}
details.card > summary::-webkit-details-marker { display: none; }
details.card > summary::before { content: "▸ "; color: var(--accent-dim); }
details.card[open] > summary::before { content: "▾ "; }
details.card[open] > summary { margin-bottom: 12px; }

/* Two-column dash: todo list on the left, calendar on the right. Stacks
   a bit earlier than it used to, since the sidebar now takes 220px of
   the width on desktop. */
.split-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 20px;
  align-items: start;
}
@media (max-width: 1100px) {
  .split-grid { grid-template-columns: 1fr; }
}

/* Dense task rows: tickbox, priority, click-to-edit title, category,
   due date, all on one line. */
.task-row {
  padding: 5px 4px;
  flex-wrap: wrap;
  row-gap: 4px;
}
.task-title-wrap { flex: 1; min-width: 90px; }
.task-title-wrap .task-title {
  cursor: pointer;
}
.task-title-wrap .task-title:hover { text-decoration: underline dotted; }
.title-edit-form { display: inline-flex; width: 100%; }
.title-edit-form input[type=text] { padding: 3px 6px; font-size: 15px; }

/* Task-row fields (priority/category/cadence/due date): bare selects
   and a date input, no <form> wrapper -- each saves itself via a
   background fetch (app.js's initFieldSave) rather than a page POST. */
.task-row > select, .task-row > input[type=date] {
  width: auto;
  padding: 2px 7px;
  font-size: 12px;
  border-radius: 0;
  color: #fff;
  border: 1px solid var(--border-dark);
}
.task-row > select.cat-select { min-width: 0; }
.task-row > select.priority-select {
  background: var(--bg-panel-2);
  color: var(--text-dim);
  min-width: 32px;
  text-align: center;
  font-weight: 700;
}
.task-row > select.priority-select.set {
  background: var(--accent-bg);
  color: var(--accent);
  border-color: var(--accent-dim);
}
.task-row > input[type=date] {
  background: var(--bg-panel-2);
  color: var(--text-dim);
  font-size: 13px;
}

/* Right-click menu for a task row (currently just "delete"), positioned
   at the click point in initRowContextMenu (app.js). */
.row-context-menu {
  position: absolute;
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 4px;
  min-width: 120px;
  z-index: 50;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.6);
}
.row-context-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  color: var(--bad);
  padding: 8px 12px;
  font-size: 14px;
  font-family: inherit;
  text-transform: inherit;
  border-radius: 0;
  cursor: pointer;
}
.row-context-menu-item:hover { background: var(--bg-panel-2); }

/* Scraps: a Google-Keep-style grid of cards. */
.scrap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  /* Cards size to their own content instead of stretching to the
     tallest card in the row; app.js's masonry pass then packs them
     (Keep-style) by giving each card a row span matching its height. */
  align-items: start;
}
.scrap-grid.masonry { grid-auto-rows: 4px; row-gap: 0; }
/* hidden until app.js has packed it (see revealScrapGrids) */
html.js .scrap-grid[data-scrap-grid]:not(.masonry-ready) { visibility: hidden; }

.scrap-card {
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 90px;
}
.scrap-card { min-width: 0; min-height: 0; }
.scrap-card .scrap-text {
  flex: 1;
  font-size: 15px;
  white-space: pre-wrap;
  /* long URLs / unbroken strings wrap inside the card instead of
     running out past its edge */
  overflow-wrap: anywhere;
  word-break: break-word;
  min-width: 0;
}
.scrap-card.pinned { border-color: var(--accent-dim); background: var(--accent-bg); }
.scrap-card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.scrap-card-footer > form { flex: 1; min-width: 0; }
.scrap-card-footer select, .scrap-card-footer input[type=text] {
  width: 100%;
  font-size: 12px;
  padding: 4px 6px;
  color: #fff;
  border: 1px solid var(--border-dark);
  border-radius: 0;
}
.scrap-card-actions { display: flex; align-items: center; gap: 2px; flex: 0 0 auto !important; }
.icon-btn.pinned { color: var(--accent); }

/* Small money-log block, pinned to the top right of a faction page. */
.faction-top {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 18px;
}
.money-box {
  width: 280px;
  max-width: 100%;
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 12px 16px;
  font-size: 14px;
}
.money-box-header {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin-bottom: 8px;
}
.money-box-totals { display: flex; flex-direction: column; gap: 3px; margin-bottom: 8px; }
.money-box-totals .net { color: var(--good); font-weight: 700; }
.money-box-totals .net.negative { color: var(--bad); }
.money-box details summary { cursor: pointer; color: var(--accent); font-size: 13px; }
.money-box .form-grid { grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px; }
.money-box table { font-size: 13px; margin-top: 8px; }
.money-box td, .money-box th { padding: 5px 4px; }

/* Full ledger page: the summary box goes full-width with its stat
   lines in a row instead of the faction page's narrow stacked box. */
.money-box-wide { width: 100%; }
.money-box-totals-row { flex-direction: row; flex-wrap: wrap; gap: 18px; font-size: 15px; }

/* Finance ledger table: a lot of columns, so it scrolls horizontally
   on narrower screens rather than trying to squeeze. */
.table-scroll { overflow-x: auto; }
.finance-table { min-width: 760px; }
.finance-table td.positive { color: var(--good); }
.finance-table td.negative { color: var(--bad); }
.finance-table .row-actions { white-space: nowrap; }

.faction-tag {
  display: inline-block;
  white-space: nowrap;
  font-size: 12px;
  padding: 2px 9px;
  border-radius: 0;
  border: 1px solid var(--accent-dim);
  color: var(--accent);
}

/* Login page */
.login-body {
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  margin: 0;
}
.login-card {
  background: var(--bg-panel);
  border: 2px outset var(--border-light);
  border-radius: 0;
  padding: 32px;
  width: 280px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.login-card .brand { padding: 0 0 12px 0; }
.login-card button { margin-top: 8px; }

@media (max-width: 760px) {
  .shell { padding: 10px 16px 0; }
  /* 44px touch targets on phones */
  .nav-link { min-height: 44px; padding: 0 8px; font-size: 17px; }
  .content { padding: 0 0 70px; }
  table, thead, tbody, th, td, tr { display: block; }
  thead { display: none; }
  td { border-bottom: none; padding: 4px 0; }
  tr { border-bottom: 1px dotted var(--border); padding: 10px 0; }
  td::before { content: attr(data-label); color: var(--text-dim); font-size: 12px; display: block; text-transform: uppercase; }

  /* Events: several fields per line instead of one-per-line, so a
     glance shows date + faction + status together, then the title,
     then the lower-priority details. */
  .events-table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3px 10px;
  }
  .events-table td {
    display: inline-block;
    width: auto;
    padding: 2px 0;
  }
  .events-table td::before { display: none; }
  .events-table td[data-label="date"] { order: 0; font-size: 13px; color: var(--text-dim); }
  .events-table td[data-label="faction"] { order: 1; }
  .events-table td[data-label="status"] { order: 2; margin-left: auto; }
  .events-table td[data-label="title"] { order: 3; flex-basis: 100%; font-weight: 700; }
  .events-table td[data-label="location"] { order: 4; flex-basis: 100%; font-size: 13px; color: var(--text-dim); }
  .events-table td[data-label="notes"] { order: 5; flex-basis: 100%; font-size: 13px; color: var(--text-dim); }
  .events-table td[data-label=""] { order: 6; margin-left: auto; }

  .cal-grid { font-size: 11px; }
  .cal-cell { min-height: 46px; padding: 2px; }
  .cal-event { font-size: 9px; }

  /* Let the finance ledger table drop into the same stacked-card
     layout as every other table on mobile, instead of forcing the
     desktop-width horizontal scroll. */
  .finance-table { min-width: 0; }
  .money-box-totals-row { flex-direction: column; gap: 3px; }
}

/* ---- date switcher (dash, next to the sort dropdown) ---- */
.date-switcher {
  outline: none;
}
.date-switcher:focus .ds-control {
  outline: 2px solid var(--accent-dim);
  outline-offset: 1px;
}
.ds-control {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--bg-panel-2);
  border: 2px solid var(--border-dark);
  padding: 6px 10px;
  white-space: nowrap;
}
.ds-arrow {
  color: var(--accent);
  font-weight: 700;
  font-size: 17px;
  line-height: 1;
  padding: 0 2px;
}
.ds-arrow:hover { text-decoration: none; color: var(--text); }
.ds-date {
  color: var(--text);
  font-size: 15px;
}
.ds-date:hover { text-decoration: none; color: var(--accent); }
.ds-all { color: var(--warn); font-weight: 700; }

/* ---- calendar module (dash + events page) ---- */
.cal-module { padding: 14px 16px; }
.cal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.cal-label { font-size: 15px; color: var(--accent); font-weight: 700; }
.cal-nav {
  font-size: 18px;
  font-weight: 700;
  padding: 0 8px;
  color: var(--text);
}
.cal-nav:hover { color: var(--accent); text-decoration: none; }
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.cal-dow {
  text-align: center;
  font-size: 12px;
  color: var(--text-dim);
  text-transform: uppercase;
  padding: 2px 0 4px;
}
.cal-cell {
  background: var(--bg-panel-2);
  border: 1px solid var(--border-dark);
  min-height: 60px;
  padding: 3px 4px;
  overflow: hidden;
}
.cal-cell.out { opacity: 0.35; }
.cal-cell.today { border-color: var(--accent); background: var(--accent-bg); }
/* Only the dash's calendar cells are links (jump to that day's todos);
   the events page's calendar view reuses .cal-cell as plain divs. */
a.cal-cell { display: block; color: inherit; text-decoration: none; cursor: pointer; }
a.cal-cell:hover { border-color: var(--accent-dim); text-decoration: none; }
.cal-daynum { font-size: 12px; color: var(--text-dim); }
.cal-cell.today .cal-daynum { color: var(--accent); font-weight: 700; }
.cal-event {
  font-size: 10.5px;
  color: var(--invert);
  padding: 1px 4px;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cal-more { font-size: 10px; color: var(--text-dim); margin-top: 2px; }
.cal-module-large .cal-cell { min-height: 90px; }
.cal-module-large .cal-event { font-size: 11.5px; padding: 2px 5px; }

/* ---- small icon buttons: copy-link, edit toggle ---- */
.icon-btn {
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 14px;
  padding: 2px 4px;
  cursor: pointer;
  line-height: 1;
}
.icon-btn:hover { color: var(--accent); }
.icon-btn.copied { color: var(--good); }
.event-title-row { display: inline-flex; align-items: center; gap: 6px; }
.row-actions { display: flex; align-items: center; gap: 4px; }

/* ---- events: past events grey out the day after their date ---- */
.events-table tr.past td { color: var(--text-dim); opacity: 0.6; }
.events-table tr.past .faction-tag { border-color: var(--border); color: var(--text-dim); }

/* ---- inline event edit row ---- */
tr.edit-row td { background: var(--bg-panel-2); padding: 12px 10px; }
tr.edit-row .form-grid { margin-bottom: 0; }

/* ---- scraps tag <select> (replaces the old free-text + datalist) ---- */
.tag-select { width: auto; min-width: 140px; max-width: 100%; }
.scrap-card-footer .tag-select { min-width: 0; text-overflow: ellipsis; }
#new-tag-add, [id^="new-tag-"] { margin-top: 6px; }

/* ---- page header row: title + a link/action top-right ---- */
.page-header-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
.page-header-row .page-title { margin-bottom: 0; }

/* ---- scraps: click-to-edit text block ---- */
.scrap-text-wrap { flex: 1; }
.scrap-text-wrap .scrap-text { cursor: text; }
.scrap-text-input {
  width: 100%;
  min-height: 64px;
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--bg-panel-2);
  border: 1px solid var(--accent-dim);
  border-radius: 6px;
  padding: 8px 10px;
  resize: vertical;
}
.scrap-text-input:focus { outline: none; border-color: var(--accent); }

/* ---- text-label icon button (archive/restore) ---- */
.icon-btn.text-icon-btn {
  font-size: 12.5px;
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 3px 8px;
}
.icon-btn.text-icon-btn:hover { border-color: var(--accent-dim); }

/* ---- toast: brief bottom-right "saved" confirmation ---- */
.app-toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  background: var(--accent);
  color: #fff;
  font-size: 13.5px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.18s ease, transform 0.18s ease;
  pointer-events: none;
  z-index: 500;
}
.app-toast.show { opacity: 1; transform: translateY(0); }

/* ---- generic editable flex table (day job, tangle sale inventory,
   tkla glossary) ---- */
.flex-table-toolbar {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}
.flex-table { min-width: 100%; }
.flex-table th, .flex-table td { vertical-align: top; padding: 6px; }
.flex-header-cell {
  display: flex;
  align-items: center;
  gap: 4px;
}
.flex-header-input {
  font-weight: 700;
  font-size: 13px;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 5px 6px;
  color: var(--text);
  width: 100%;
  min-width: 110px;
}
.flex-header-input:focus { outline: none; border-color: var(--accent-dim); }
.flex-col-remove {
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
  flex: 0 0 auto;
}
.flex-col-remove:hover { color: var(--bad); }
.flex-cell-input {
  width: 100%;
  min-width: 110px;
  min-height: 32px;
  font: inherit;
  font-size: 13.5px;
  color: var(--text);
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 5px 6px;
  resize: vertical;
}
.flex-cell-input:focus { outline: none; border-color: var(--accent-dim); }
.flex-actions-col { width: 28px; padding: 6px 2px !important; }
.scrap-tag-form { display: flex; flex-direction: column; flex: 1; min-width: 0; }

.journal-entry { margin: 8px 0 8px 14px; border-left: 2px solid var(--border); padding-left: 10px; }
.journal-entry summary { cursor: pointer; }
.journal-entry-body { white-space: pre-wrap; margin: 8px 0; line-height: 1.5; }

.training-card { margin-top: 16px; }
.training-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.training-nav { display: flex; align-items: center; gap: 6px; }
.training-table th:first-child, .training-table td:first-child { width: 110px; }
.training-table td { vertical-align: top; }
.training-table tr.today td { background: var(--bg-panel-2); }
.training-table tr.today .training-day-label { color: var(--accent); }
.training-day-label { font-weight: 600; white-space: nowrap; }
.training-block { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.training-block:empty { display: none; }
.training-add-form { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.training-add-form select, .training-add-form input[type="text"] { padding: 4px 6px; font-size: 13px; }
.training-num { width: 52px; padding: 4px 6px; font-size: 13px; }
.training-add-form [data-strength-fields], .training-add-form [data-cardio-fields] { display: contents; }
.training-add-form [data-strength-fields][hidden], .training-add-form [data-cardio-fields][hidden] { display: none; }
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--bg-panel-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 4px 2px 10px; font-size: 13px;
}
.chip-remove { background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 0 6px; font-size: 13px; }
.chip-remove:hover { color: var(--bad); background: none; }

.add-defaults { color: var(--accent-dim); margin-left: 4px; }

/* Action cells (edit ✎ / delete ×) in tables: .row-actions is a flex
   row, but putting display:flex on a <td> itself pulls it out of the
   table layout, which is what made the events page's edit button sit
   offset from its row. Keep the cell a real table cell and lay the
   buttons out inline inside it instead. */
@media (min-width: 761px) {
  td.row-actions { display: table-cell; white-space: nowrap; vertical-align: top; text-align: right; width: 1%; padding-top: 5px; }
}
td.row-actions > *, td.row-actions form.inline { display: inline-flex; vertical-align: top; align-items: center; }
td.row-actions .icon-btn,
td.row-actions button.small { height: 26px; min-width: 26px; padding: 0 6px; justify-content: center; line-height: 1; }
td.row-actions .icon-btn { display: inline-flex; align-items: center; font-size: 16px; }

/* Mutual aid: search/category/search-button form plus csv buttons all on
   one filter row. */
.filters-inline { display: flex; gap: 10px; flex-wrap: wrap; align-items: end; }
.filters .field.field-btn { min-width: unset; }
.csv-buttons { display: flex; gap: 8px; align-items: end; margin-left: auto; }
.scrap-card { transition: opacity 0.25s; }
.scrap-card.fading { opacity: 0; }

/* ---- posts queue: date · account · post · event · status · actions,
   with a small header row naming the columns ---- */
.post-add-row { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; align-items: center; }
.post-add-row .post-content-input { flex: 1 1 260px; min-width: 0; }
.post-date-input { width: 118px; flex: 0 0 auto; padding-left: 4px; padding-right: 2px; }
.post-account-select { width: 128px; }
.post-event-select { width: 150px; text-overflow: ellipsis; }
.posts-table { width: 100%; }
.posts-table thead th { font-size: 14px; font-weight: normal; color: #a9c59a; text-align: left; padding: 0 4px 2px; border-bottom: 1px solid var(--border); text-transform: lowercase; letter-spacing: 0; }
.posts-table td { vertical-align: middle; padding: 3px 4px; }
.posts-table input[type=text], .posts-table input[type=date], .posts-table select { padding-top: 4px; padding-bottom: 4px; }
.posts-table .post-date-cell, .posts-table .post-account-cell, .posts-table .post-event-cell,
.posts-table .post-status-cell, .posts-table .post-actions-cell { width: 1%; white-space: nowrap; }
.posts-table .post-content-input { width: 100%; min-width: 180px; }
.posts-table .post-date-cell .best-time { display: block; margin: 1px 0 0 2px; font-size: 13px; line-height: 1.1; }
.post-check { display: flex; gap: 5px; align-items: center; font-size: 15px; line-height: 1.1; white-space: nowrap; margin: 0; }
.post-check input { width: 16px; height: 16px; }
.post-leaving { display: block; font-size: 13px; color: var(--warn); white-space: nowrap; }
.post-leaving:empty { display: none; }
.post-actions { display: flex; gap: 4px; align-items: center; justify-content: flex-end; }
.move-btn { font-size: 13px; padding: 4px 6px; border: 1px solid var(--border); }
.post-row { transition: opacity 0.25s; }
.post-row.fading { opacity: 0; }
.post-row.posted .post-content-input { color: var(--text-dim); }
/* scheduled rows: a quiet accent edge so you can see what's queued up in Meta */
.posts-table tr.post-row.scheduled td:first-child { box-shadow: inset 3px 0 0 var(--accent-dim); }
.posts-table tr.post-row.leaving td { background: rgba(224, 185, 90, 0.10); }
@keyframes post-moved { from { background: var(--accent-bg); } to { background: transparent; } }
.post-row.just-moved td { animation: post-moved 0.8s ease-out; }
.posts-archive-link { margin-top: 12px; }
.posts-filters { align-items: center; }
.posts-title { margin: 0 12px 0 0; font-size: 26px; font-weight: normal; color: var(--accent); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* one visible keyboard focus ring for every link, button and toggle */
a:focus-visible, button:focus-visible, summary:focus-visible, [tabindex]:focus-visible,
input[type=checkbox]:focus-visible, input[type=radio]:focus-visible { outline: 2px solid #ffd35c; outline-offset: 2px; }

/* synced-calendar entries on the month grids */
.cal-event.cal-ext { opacity: 0.92; border-left: 3px solid rgba(255,255,255,0.55); }

/* ---- dash calendar: linked outside calendars ---- */
.cal-feeds { margin-top: 10px; font-size: 14px; }
.cal-feed-row { display: flex; align-items: center; gap: 8px; }
.cal-feed-swatch { width: 10px; height: 10px; display: inline-block; }
.cal-feed-error { color: var(--bad); }
.cal-feed-actions { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; margin-top: 6px; }
.cal-feed-manage { flex: 1 1 auto; }
.cal-feed-add { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
.cal-feed-add input[type=url] { flex: 1 1 220px; }
.cal-feed-remove { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.cal-feed-events-link { margin-left: auto; }
/* keep the glossary inside the page: fixed column widths (description
   widest), long links wrap instead of pushing the table off-screen */
@media (min-width: 761px) {
  .resources-table { table-layout: fixed; }
}
.resources-table td { overflow-wrap: anywhere; }
.scrap-card.scrap-stub { opacity: 0.55; justify-content: center; align-items: center; background: transparent; border-style: dashed; }
.scrap-stub-note { color: var(--text-dim); font-size: 14px; display: flex; align-items: center; gap: 4px; }
@media (max-width: 760px) {
  /* phone: each post is a small block. date + account + status on top,
     the post text full width, then event + actions */
  .posts-table thead { display: none; }
  .posts-table tr.post-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 10px 6px; }
  .posts-table tr.post-row.late, .posts-table tr.post-row.leaving { background: rgba(224, 72, 72, 0.16); }
  .posts-table tr.post-row.leaving { background: rgba(224, 185, 90, 0.10); }
  .posts-table tr.post-row.late td, .posts-table tr.post-row.leaving td { background: transparent; box-shadow: none; }
  .posts-table tr.post-row.late { box-shadow: inset 3px 0 0 var(--bad); }
  .posts-table td { display: block; width: auto !important; padding: 0; }
  .posts-table td::before { display: none; }
  .posts-table .post-content-cell { order: 5; flex: 1 1 100%; }
  .posts-table .post-content-input { min-width: 0; }
  .posts-table .post-event-cell { order: 6; flex: 1 1 auto; }
  .posts-table .post-event-select { width: 100%; }
  .posts-table .post-actions-cell { order: 7; }
  .posts-table .post-status-cell { display: flex; gap: 10px; }
  .post-check { min-height: 44px; }
  .post-add-row > * { min-width: 0; max-width: 100%; }
  .post-add-row .post-account-select, .post-add-row .post-event-select { flex: 1 1 140px; width: auto; }
}

/* ---- dash calendar: view switcher + day/week/schedule views ---- */
a.cal-label:hover { text-decoration: none; filter: brightness(1.2); }
.cal-views { display: flex; gap: 4px; margin: -4px 0 10px; justify-content: center; }
.cal-view-btn {
  font-size: 14px; padding: 1px 10px; border: 1px solid var(--border);
  color: var(--text-dim); background: var(--bg-panel-2);
}
.cal-view-btn:hover { color: var(--accent); text-decoration: none; }
.cal-view-btn.active { color: var(--invert); background: var(--accent); border-color: var(--accent); }

.cal-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.cal-week-col {
  background: var(--bg-panel-2); border: 1px solid var(--border-dark);
  min-height: 160px; padding: 3px 4px; min-width: 0;
}
.cal-week-col.today { border-color: var(--accent); background: var(--accent-bg); }
.cal-week-head { display: block; color: var(--text-dim); font-size: 13px; margin-bottom: 2px; }
.cal-week-head:hover { color: var(--accent); text-decoration: none; }
.cal-week-col.today .cal-week-head { color: var(--accent); font-weight: 700; }
/* week columns are narrow: let chips wrap instead of truncating */
.cal-week .cal-event { white-space: normal; overflow-wrap: anywhere; line-height: 1.15; padding: 2px 4px; }
.cal-empty { color: var(--text-dim); opacity: 0.4; font-size: 12px; }

.cal-row { display: flex; align-items: baseline; gap: 8px; padding: 3px 0; font-size: 15px; border-bottom: 1px dashed rgba(127,216,88,0.12); }
.cal-row-swatch { flex: 0 0 10px; width: 10px; height: 10px; align-self: center; background: var(--border); }
.cal-row-time { flex: 0 0 64px; color: var(--text-dim); font-size: 14px; }
.cal-row-title { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.cal-row-loc { color: var(--text-dim); font-size: 13px; }
.cal-row-src { flex: 0 0 auto; color: var(--text-dim); font-size: 12px; max-width: 30%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-day { min-height: 120px; }
.cal-day-todos { display: inline-block; margin-top: 8px; font-size: 14px; }

.cal-schedule { max-height: 560px; overflow-y: auto; }
.cal-sched-day { display: flex; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border-dark); }
/* just wide enough for "wed 12/31" */
.cal-sched-date { flex: 0 0 62px; color: var(--text-dim); font-size: 13px; padding-top: 3px; white-space: nowrap; }
.cal-sched-day.today .cal-sched-date { color: var(--accent); font-weight: 700; }
.cal-sched-items { flex: 1 1 auto; min-width: 0; }
.cal-sched-items .cal-row:last-child { border-bottom: 0; }

/* per-calendar color picker + show/hide */
.cal-feed-color {
  width: 18px; height: 18px; padding: 0; border: 1px solid var(--border);
  background: none; cursor: pointer; flex: 0 0 auto;
}
.cal-feed-color::-webkit-color-swatch-wrapper { padding: 0; }
.cal-feed-color::-webkit-color-swatch { border: 0; }
.cal-feed-color::-moz-color-swatch { border: 0; }
.cal-feed-vis { margin-left: auto; }
.cal-feed-vis button { padding: 0 8px; font-size: 13px; }
.cal-feed-row { margin: 2px 0; }
.cal-feed-row.hidden-feed > span { opacity: 0.45; text-decoration: line-through; }

@media (max-width: 760px) {
  .cal-week { grid-template-columns: 1fr; }
  .cal-week-col { min-height: 0; }
  .cal-sched-date { flex-basis: 58px; }
  .cal-row-src { display: none; }
}

/* ---- journal: history entries edit in the left-hand editor ---- */
.journal-editor-status { color: var(--warn); font-size: 15px; margin-bottom: 8px; }
.journal-editor-actions { display: flex; gap: 8px; margin-top: 10px; }
.journal-entry.journal-editing { border-left-color: var(--warn); }
.journal-entry.journal-editing > summary { color: var(--warn); }

/* ---- posts: best-time-to-post note next to each date ---- */
.best-time { position: relative; display: inline-block; margin-left: 6px; font-size: 13px; color: var(--text-dim); cursor: help; vertical-align: middle; }
.best-time-label { white-space: nowrap; }
.best-time:empty, .best-time-label:empty { display: none; }
.best-time-pop {
  display: none; position: absolute; z-index: 30; left: 0; top: calc(100% + 4px);
  width: 260px; white-space: normal; font-size: 14px; line-height: 1.3;
  background: var(--bg-panel); color: var(--text); border: 2px solid var(--accent-dim);
  padding: 8px 10px; box-shadow: 3px 3px 0 var(--border-dark);
}
.best-time-pop:empty { display: none !important; }
.best-time-sub { color: var(--text-dim); }
.best-time:hover .best-time-pop, .best-time:focus .best-time-pop, .best-time:focus-within .best-time-pop,
.post-date-input:focus + .best-time .best-time-pop { display: block; }
.post-row.posted .best-time { display: none; }

/* Week view needs more room: the calendar column grows and the todo
   column gives some up while the week view is showing. */
.split-grid.cal-wide { grid-template-columns: 1fr 1.3fr; }
.split-grid.cal-wide .cal-module { padding: 12px 10px; }
.cal-week-col { padding: 3px 5px; }
@media (max-width: 1100px) {
  .split-grid.cal-wide { grid-template-columns: 1fr; }
}

/* Schedule view: today's date row gets the accent instead of a " · today" suffix. */
.cal-sched-day.today .cal-sched-date { text-decoration: underline; text-underline-offset: 3px; }


/* ---- journal: one column, editor on top, history in a closeable box ---- */
.journal-editor-head { display: flex; gap: 12px; flex-wrap: wrap; }
.journal-date-field { flex: 0 0 auto; }
.journal-title-field { flex: 1 1 260px; }
.journal-title-field input { width: 100%; }
.journal-editor-head label { display: block; }
.journal-history > summary { font-size: 18px; }
.journal-search { display: flex; align-items: center; gap: 10px; margin: 4px 0 10px; }
.journal-search input { flex: 1 1 auto; max-width: 520px; }
.journal-entry > summary { display: flex; align-items: center; gap: 10px; list-style: none; }
.journal-entry > summary::-webkit-details-marker { display: none; }
.journal-entry > summary::before { content: "▸"; color: var(--accent-dim); }
.journal-entry[open] > summary::before { content: "▾"; }
.journal-entry-head { display: flex; gap: 10px; align-items: baseline; min-width: 0; }
.journal-entry-date { color: var(--text-dim); white-space: nowrap; }
.journal-entry-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.journal-entry-actions { display: inline-flex; gap: 4px; align-items: center; }
.journal-entry-actions .icon-btn, .journal-entry-actions .small { padding: 0 6px; line-height: 1.3; }

/* late = date has passed and it's not scheduled or posted: the whole row goes red */
.posts-table tr.post-row.late td { background: rgba(224, 72, 72, 0.16); }
.posts-table tr.post-row.late td:first-child { box-shadow: inset 3px 0 0 var(--bad); }
.posts-table tr.post-row.is-today .post-date-input { border-color: var(--accent); }

/* ---- sidebar nav groups: label on top, its buttons stacked full width
   underneath, so each group reads as one block down the left side ---- */
.nav-group { display: flex; flex-direction: column; align-items: stretch; gap: 4px; }
.nav-group-label { color: #a9c59a; font-size: 15px; padding-left: 2px; }
.sidenav .nav-link { min-height: 44px; white-space: normal; line-height: 1.05; padding: 4px 10px; }
.nav-dot { display: inline-block; flex: 0 0 8px; width: 8px; height: 8px; margin-right: 7px; border: 1px solid var(--border-dark); }
.nav-group.nav-util { border-top: 2px dotted var(--border); padding-top: 10px; }
/* tablets and phones: no room for a side column next to wide tables, so
   the sidebar folds into a wrapping row of buttons above the page */
@media (max-width: 999px) {
  .shell { display: block; }
  .sidebar {
    position: static; max-height: none; overflow: visible;
    padding: 0 0 10px; border-right: 0; border-bottom: 2px dashed var(--border); margin-bottom: 14px;
  }
  .sidenav { flex-direction: row; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
  .nav-group { display: contents; }
  .nav-group-label { display: none; }
  .sidenav .nav-link { white-space: nowrap; padding: 0 8px; }
  .nav-group.nav-util { border-top: 0; padding-top: 0; }
}

/* ---- dash: status strip, read like an old hit counter ---- */
.status-strip { width: 100%; border-collapse: collapse; margin: 0 0 16px; background: var(--border-dark); border: 2px inset var(--border); table-layout: fixed; }
.status-strip td { text-align: center; padding: 6px 4px; border-right: 1px dashed var(--border); border-bottom: 0; vertical-align: middle; }
.status-strip td:last-child { border-right: 0; }
.status-strip a { display: block; color: inherit; }
.status-strip a:hover { text-decoration: none; background: var(--bg-panel); }
.status-n { display: block; font-size: 30px; line-height: 1; color: var(--accent); }
.status-n.bad { color: #f09385; }
.status-l { display: block; font-size: 15px; color: #a9c59a; }
@media (max-width: 760px) {
  .status-strip, .status-strip tbody, .status-strip tr { display: block; }
  .status-strip tr { display: flex; flex-wrap: wrap; padding: 0; border: 0; }
  .status-strip td { display: block; flex: 1 1 33%; padding: 6px 2px; border-bottom: 1px dashed var(--border); }
  .status-strip td::before { display: none; }
  .status-n { font-size: 26px; }
}

/* ---- quick-add from any page ---- */
.qa-fab {
  position: fixed; right: 20px; bottom: 20px; z-index: 60; width: 46px; height: 46px; padding: 0;
  font-size: 26px; line-height: 1; border-radius: 0; box-shadow: 3px 3px 0 var(--border-dark);
}
.qa-fab.open { background: var(--accent-dim); }
.qa-pop {
  position: fixed; right: 20px; bottom: 76px; z-index: 60; width: min(420px, calc(100vw - 32px));
  background: var(--bg-panel); border: 2px solid var(--accent-dim); padding: 12px; box-shadow: 4px 4px 0 var(--border-dark);
}
.qa-pop-head { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 8px; color: var(--accent); flex-wrap: wrap; }
.qa-pop .quick-add-row input { flex: 1 1 auto; min-width: 0; }
@media (max-width: 760px) { .qa-fab { right: 14px; bottom: 14px; } .qa-pop { right: 16px; bottom: 70px; } }

/* dash filter bar: sort · priority · category · cadence · date · view all,
   compact enough to sit on one line next to the calendar */
.split-grid .filters { gap: 6px; flex-wrap: wrap; }
.split-grid .filters .field { min-width: 0; }
.split-grid .filters select { width: auto; max-width: 128px; }

/* ---- skin A boxes: raised panel with a solid title bar (the identity
   motif: every block reads like an old homepage window) ---- */
.box { background: var(--bg-panel); border: 2px outset var(--border-light); margin-bottom: 16px; min-width: 0; }
.box-title { background: var(--border); color: #eaf7de; padding: 3px 10px; font-size: 18px; }
.box-in { padding: 10px 12px; }
.box-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 10px; }

/* fold: a box whose title bar is the toggle. The arrow sits inline in the
   bar, and the whole bar is the click/keyboard target. */
details.fold { background: var(--bg-panel); border: 2px outset var(--border-light); margin-bottom: 12px; }
details.fold > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 4px 10px; background: var(--border); color: #eaf7de; font-size: 18px;
}
details.fold > summary::-webkit-details-marker { display: none; }
details.fold > summary::before { content: "▸"; color: var(--accent); }
details.fold[open] > summary::before { content: "▾"; }
details.fold > summary:hover { background: #466a3a; }
details.fold > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.fold-count { margin-left: auto; color: #cfe6c1; font-size: 15px; }
.fold-in { padding: 10px 12px; }

/* ---- faction pages ---- */
.faction-head { align-items: center; margin-bottom: 12px; }
.faction-head .page-title { font-size: 30px; font-weight: normal; color: var(--accent); }
.faction-links { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.faction-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.faction-side .list-row { padding: 5px 2px; flex-wrap: wrap; gap: 4px 10px; }
.faction-side .money-box-totals { font-size: 17px; }
.inventory-add { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.inventory-add input { flex: 1 1 140px; min-width: 0; }
.inventory-add input[type=number] { flex: 0 1 100px; }
.compact-table td, .compact-table th { padding: 4px 6px; }
.attendee-input { width: 70px; padding: 4px 6px; }
@media (max-width: 1100px) {
  .faction-grid { grid-template-columns: 1fr; }
}
/* ---- neocities publish button + its status line ---- */
.neocities-publish { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
/* no lowercasing here: env var names and file names must read exactly */
.neocities-status { font-size: 15px; color: var(--text-dim); text-transform: none; }
.neocities-status:empty { display: none; }
.neocities-status.ok { color: var(--accent); }
.neocities-status.bad { color: #f09385; }

/* ---- pop-out tool panels (events csv tools) ---- */
details.pop-tool { position: relative; }
details.pop-tool > summary { list-style: none; cursor: pointer; }
details.pop-tool > summary::-webkit-details-marker { display: none; }
.pop-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20;
  width: min(620px, calc(100vw - 32px)); padding: 12px;
  background: var(--bg-panel); border: 2px outset var(--border-light); box-shadow: 4px 4px 0 var(--border-dark);
}
@media (max-width: 760px) {
  details.pop-tool { position: static; }
  .pop-panel { left: 0; right: 0; width: auto; }
}
.cycle-pick { border: 1px dashed var(--border); padding: 6px 10px 8px; margin: 0; display: flex; flex-wrap: wrap; gap: 4px 20px; }
.cycle-pick legend { color: var(--text-dim); font-size: 15px; padding: 0 4px; }
.cycle-option { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; color: var(--text); cursor: pointer; }
.cycle-option input { width: 18px; height: 18px; accent-color: var(--accent); }

/* the custom tickboxes hide the real input, so show its keyboard focus
   on the drawn box instead */
.check-wrap:focus-within .checkmark { outline: 2px solid #ffd35c; outline-offset: 2px; }

/* ---- dash: recurring routines (under the calendar) ----
   Same window-with-title-bar box as everything else. A routine is marked
   by a dashed outline plus a solid left edge in its category color, both
   here and as a calendar chip, so it reads as "the same thing" in both
   places and never as a hosted event. */
details.routines > summary { list-style: none; cursor: pointer; }
details.routines > summary::-webkit-details-marker { display: none; }
.routines-summary { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 44px; }
.routines-summary > span:first-child::before { content: "▸ "; }
details.routines[open] .routines-summary > span:first-child::before { content: "▾ "; }
.routines-count { font-size: 16px; }
.routines-due { color: #ffe08a; }
.routine-add-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.routine-add-row input, .routine-add-row select, .routine-add-row button { min-height: 44px; }
.routine-add-row input[type=text] { flex: 1 1 180px; min-width: 0; }
.routine-add-row select, .routine-add-row input[type=date] { flex: 0 1 auto; width: auto; max-width: 100%; }
.routine-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px;
  padding: 2px 4px 2px 6px; border-bottom: 1px dotted var(--border);
  border-left: 3px solid var(--border-light);
}
.routine-row:last-child { border-bottom: none; }
.routine-row .check-wrap { width: 44px; height: 44px; }
.routine-row .check-wrap .checkmark { inset: 11px; }
.routine-row .task-title-wrap { flex: 1 1 140px; min-width: 0; }
.routine-title {
  background: none; border: 0; padding: 0; min-height: 44px; width: 100%;
  color: var(--text); font-weight: 400; font-size: 17px; text-align: left; overflow-wrap: anywhere;
}
.routine-title:hover { background: none; color: var(--text); text-decoration: underline dotted; }
.routine-row select, .routine-row input[type=date] {
  width: auto; min-height: 44px; padding: 2px 6px; font-size: 14px;
  background: var(--bg-panel-2); color: var(--text-dim); border: 1px solid var(--border-dark);
}
.routine-row input[type=date].pill.alert { color: #f09385; border-color: var(--bad); }
.routine-state { min-width: 3.2em; font-size: 15px; }
.routine-row.late .routine-state { color: #f09385; }
.routine-row.due-now .routine-state { color: var(--accent); }
.routines-help { margin: 8px 0 0; }

.cal-event.cal-routine {
  background: transparent; color: var(--text);
  border: 1px dashed var(--border-light); border-left: 3px solid var(--border-light);
}
.cal-event.cal-routine.late { color: #f09385; border-color: var(--bad); }
.cal-row-swatch.cal-routine { background: transparent; border: 2px dashed var(--border-light); }

/* ---- events: posters, dismiss, calendar sync ---- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.events-panels { display: flex; flex-direction: column; gap: 12px; margin-bottom: 16px; }
.events-panels > details.card { margin-bottom: 0; }
.undo-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.undo-bar button { min-height: 44px; }

/* Every control on the events page is a full 44px touch target. */
.events-table td.row-actions .icon-btn,
.events-table td.row-actions button.small { height: 44px; min-width: 44px; }
.events-table .copy-link-btn { min-width: 44px; min-height: 44px; justify-content: center; display: inline-flex; align-items: center; }

/* Dismissed rows read like past rows: done, out of the way. */
.events-table tr.is-dismissed td { color: var(--text-dim); }
.cal-event.dismissed { opacity: 0.55; }

/* "from calendar": a real-source note, dashed like the other
   automatic things on the dash (routines on the calendar). */
.from-cal {
  display: inline-block; margin-top: 3px; font-size: 13px; font-weight: normal;
  color: var(--text-dim); border: 1px dashed var(--border-light); padding: 0 6px;
}

/* Posters: square thumbs with the same pixel bevel as buttons, so they
   read as the event's own artwork sitting in the row. */
.poster-cell { min-width: 120px; }
.poster-strip { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.poster-thumb {
  display: inline-flex; width: 44px; height: 44px; align-items: center; justify-content: center;
  border-top: 2px solid var(--border-light); border-left: 2px solid var(--border-light);
  border-bottom: 2px solid var(--border-dark); border-right: 2px solid var(--border-dark);
  background: var(--bg); overflow: hidden; box-sizing: content-box;
}
.poster-thumb img { width: 44px; height: 44px; object-fit: cover; display: block; }
.poster-thumb:hover, .poster-thumb:focus-visible { border-color: var(--accent); text-decoration: none; }
.poster-pdf { font-size: 15px; color: var(--text); text-transform: uppercase; }
.poster-upload { display: inline-flex; gap: 6px; align-items: center; margin: 0; }
.poster-add { position: relative; min-height: 44px; display: inline-flex; align-items: center; cursor: pointer; white-space: nowrap; }
/* the real file input sits invisibly over the label: clicks and the
   keyboard both reach it, and the label shows its focus ring */
.poster-file { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }
.poster-add:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
html.js .poster-submit { display: none; }
.poster-upload.is-uploading .poster-add { opacity: 0.7; cursor: progress; }
.poster-manage, .promo-add { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.poster-remove { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.poster-remove button, .promo-add button { min-height: 44px; }

/* Calendar sync panel */
.sync-head { font-size: 18px; margin: 14px 0 6px; }
.sync-panel .sync-head:first-of-type { margin-top: 0; }
.sync-row {
  display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center;
  padding: 10px 0; border-top: 1px dotted var(--border);
}
.sync-toggle { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; cursor: pointer; }
.sync-toggle input { width: 20px; height: 20px; }
.sync-faction { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sync-faction span { color: var(--text-dim); font-size: 14px; }
.sync-faction select { min-height: 44px; width: auto; max-width: 100%; }
.sync-row button { min-height: 44px; }
.sync-note { flex-basis: 100%; margin: 0; color: var(--text-dim); font-size: 14px; }
.sync-note.warn { color: var(--warn); }
.sync-link { display: flex; gap: 8px; align-items: center; }
.sync-link input { flex: 1 1 auto; min-width: 0; min-height: 44px; }
.sync-link button { min-height: 44px; }

/* tablet widths: the table keeps its columns, so the row buttons stack
   instead of pushing the table wider than the screen */
@media (min-width: 761px) and (max-width: 1100px) {
  .events-table td.row-actions { white-space: normal; width: 60px; }
  .events-table td.row-actions > * { display: flex; margin-bottom: 4px; }
  .poster-cell { min-width: 0; }
}
@media (max-width: 760px) {
  .events-table td[data-label="posters"] { order: 6; flex-basis: 100%; }
  .events-table td[data-label=""] { order: 7; }
}
