/* First Light Farm billing — desktop client.
   The palette is the barn sign, same as the iOS app: navy ground, silver
   lettering, the rising sun as the one warm accent. Chrome is navy; the working
   area stays light, because this screen is for reading tables of numbers. */

:root {
  --stack: 18px;   /* the one vertical gap between blocks on a page */
  --navy:      #111A33;
  --navy-deep: #0B1227;
  --silver:    #CBD1D8;
  --sun:       #F2D06E;
  --sky:       #A9C6E4;

  --ink:       #16181d;
  --ink-soft:  #5c6270;
  --line:      #e2e5ea;
  --ground:    #f6f7f9;
  --card:      #ffffff;
  --ok:        #1d7a45;
  --warn:      #9a6700;
  --bad:       #b3261e;
  --busy:      #1a4f9c;   /* waiting on something: .working */

  --radius: 10px;
  --pad: 16px;
  color-scheme: light;
}

* { box-sizing: border-box; }

/* The hidden attribute must actually hide.
   .boot and .login set `display: grid`, and an author display rule beats the UA
   stylesheet's `[hidden] { display: none }`. So `el.hidden = true` set the
   property, the element stayed on screen, and its `height: 100vh` covered the
   app rendering underneath it — the page looked stuck on "Loading…" while
   working perfectly. Any DOM-level test passes straight through this. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
  color: var(--ink);
  background: var(--ground);
}

button, input, select, textarea { font: inherit; color: inherit; }

/* ---------------------------------------------------------------- booting */
.boot {
  display: grid; place-items: center; height: 100vh;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------- sign-in */
.login {
  display: grid; place-items: center; min-height: 100vh;
  background: linear-gradient(170deg, var(--navy) 0%, var(--navy-deep) 100%);
  padding: 24px;
}
.login-card {
  width: min(360px, 100%);
  display: flex; flex-direction: column; gap: 14px;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(203,209,216,.18);
  border-radius: 14px;
  padding: 30px 26px 26px;
  color: var(--silver);
}
.login-card .mark { display: grid; place-items: center; }
.login-card h1 {
  margin: 0 0 6px; text-align: center;
  font-size: 19px; font-weight: 600; letter-spacing: .01em; color: #fff;
}
.login-card label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; }
.login-card input {
  background: rgba(0,0,0,.28);
  border: 1px solid rgba(203,209,216,.28);
  border-radius: 8px; padding: 10px 11px; color: #fff;
}
.login-card input:focus { outline: 2px solid var(--sun); outline-offset: -1px; }

/* ---------------------------------------------------------------- chrome */
.topbar {
  display: flex; align-items: center; gap: 22px;
  background: var(--navy); color: var(--silver);
  padding: 0 18px; height: 52px;
  position: sticky; top: 0; z-index: 20;
}
.brand { display: flex; align-items: center; gap: 9px; font-weight: 600; color: #fff; white-space: nowrap; }
.topbar nav { display: flex; gap: 2px; margin-right: auto; flex-wrap: wrap; }
.topbar nav a {
  color: var(--silver); text-decoration: none;
  padding: 7px 12px; border-radius: 7px; font-size: 13px;
}
.topbar nav a:hover { background: rgba(255,255,255,.08); color: #fff; }
.topbar nav a.on { background: rgba(242,208,110,.16); color: var(--sun); font-weight: 600; }
.who { display: flex; align-items: center; gap: 12px; font-size: 12px; white-space: nowrap; }
.link {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--sky); text-decoration: underline; font-size: 12px;
}

.view { padding: 22px; max-width: 1180px; margin: 0 auto; }

/* ---------------------------------------------------------------- blocks */
h2.title { margin: 0; font-size: 19px; font-weight: 650; }
.sub { color: var(--ink-soft); font-size: 13px; margin: 3px 0 0; }
.head { display: flex; align-items: flex-end; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; }
.head .grow { margin-right: auto; }

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: var(--pad);
}
.card + .card { margin-top: 14px; }
.card h3 { margin: 0 0 12px; font-size: 14px; font-weight: 650; }

.grid { display: grid; gap: 14px; }
/* Two across, never three: a table of money needs its columns, and `1fr`
   refuses to shrink below min-content, so a third track silently clips the
   right-hand columns instead of wrapping. min() keeps it honest when narrow. */
.grid.two { grid-template-columns: repeat(auto-fit, minmax(min(440px, 100%), 1fr)); }
.grid.two > * { min-width: 0; }

/* ---------------------------------------------------------------- tables */
.tablewrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: 13px; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
th {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-soft); font-weight: 600; white-space: nowrap;
  background: var(--card);
}
/* No sticky header. `.tablewrap` sets `overflow-x: auto`, which makes it a
   scroll container on both axes, so `position: sticky; top: 52px` offset the
   header 52px from the WRAPPER's top rather than the viewport's — parking it on
   top of the first row and hiding it. These tables are short enough that a
   sticky header buys nothing worth that. */
tbody tr:hover { background: #fafbfc; }

/* ---------------------------------------------------------------- flags */
/* Something is missing and someone should act: a rider with no release, a
   horse with no agreement. Red, and it says what on hover. */
.flag {
  display: inline-grid; place-items: center;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--bad); color: #fff;
  font-weight: 700; font-size: 13px; line-height: 1;
  cursor: help;
}
.problems {
  margin: 10px 0 0; padding-left: 18px;
  color: var(--bad); font-size: 13px;
}
.problems li { margin: 2px 0; }

/* ------------------------------------------------------- rows that open */
tr.clickable { cursor: pointer; }
tr.clickable > td:first-child { position: relative; padding-left: 22px; }
/* A flag column sits ahead of the name, so the caret belongs to it instead. */
td.flagcol, th.flagcol { width: 1px; padding-right: 0; }
/* A caret rather than a button: the whole row is the target. */
tr.clickable > td:first-child::before {
  content: '›';
  position: absolute; left: 8px; top: 50%;
  transform: translateY(-50%) rotate(0deg);
  transition: transform .15s ease;
  color: var(--ink-soft); font-size: 15px; line-height: 1;
}
tr.clickable.open > td:first-child::before { transform: translateY(-50%) rotate(90deg); }
tr.clickable.open { background: #f2f5f9; }
tr.clickable.open > td { border-bottom-color: transparent; font-weight: 550; }

tr.detailrow > td.panel { padding: 0 10px 16px 22px; background: #f7f9fb; }
.detail { display: flex; flex-direction: column; gap: 14px; }

.factgrid {
  display: grid; grid-template-columns: max-content 1fr;
  gap: 4px 16px; align-items: baseline; font-size: 13px;
  padding: 12px 0 2px;
}

.panel-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding-top: 6px; border-top: 1px solid var(--line);
}
.panel-head .grow { margin-left: auto; }

/* A form opened inside a panel: set apart from the row it belongs to without
   looking like another card floating on the page. */
.subform {
  display: flex; flex-direction: column; gap: 10px;
  background: #fff; border: 1px solid var(--line);
  border-radius: 8px; padding: 12px;
}
.subform h3 { margin: 0; font-size: 13px; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
td.actions { text-align: right; white-space: nowrap; }
tr.void td { color: var(--ink-soft); text-decoration: line-through; }
.empty { padding: 26px; text-align: center; color: var(--ink-soft); }

/* ---------------------------------------------------------------- forms */
label.f, div.f { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--ink-soft); }
div.f > .caption { font-size: 12px; color: var(--ink-soft); }
label.f > input, label.f > select, label.f > textarea,
.stack > input, .stack > select,
div.f > input, div.f > select, div.f > textarea {
  border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; background: #fff; color: var(--ink); font-size: 14px;
}
label.f > input:focus, label.f > select:focus, label.f > textarea:focus,
.stack > input:focus, .stack > select:focus,
div.f > input:focus, div.f > select:focus, div.f > textarea:focus {
  outline: 2px solid var(--sky); outline-offset: -1px; border-color: transparent;
}
input[readonly] { background: var(--ground); color: var(--ink-soft); }
.row { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.check { flex-direction: row; align-items: center; gap: 8px; color: var(--ink); }
.check input { width: 16px; height: 16px; }
.hint { font-size: 12px; color: var(--ink-soft); }
/* Billing is waiting on something (loading, checking, sending): blue, with a turning
   ring, so it isn't taken for a static hint (grey) or for the answer. Each color has
   one meaning: grey static, blue working, green done, amber attention, red problem.
   Goes with .hint, .empty or plain text; an empty one shows nothing. */
.working { color: var(--busy); }
.working:empty { display: none; }
.working::before {
  content: ''; display: inline-block; box-sizing: border-box;
  width: .9em; height: .9em; margin-right: .45em; vertical-align: -.1em;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: working-turn .8s linear infinite;
}
@keyframes working-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .working::before { animation-duration: 3s; } }

/* ---------------------------------------------------------------- buttons */
button.primary, button.ghost, button.danger {
  border-radius: 8px; padding: 8px 14px; cursor: pointer; font-size: 13px;
  font-weight: 550; border: 1px solid transparent;
}
button.primary { background: var(--navy); color: #fff; }
button.primary:hover:not(:disabled) { background: var(--navy-deep); }
button.ghost { background: #fff; border-color: var(--line); color: var(--ink); }
button.ghost:hover:not(:disabled) { border-color: var(--ink-soft); }
button.danger { background: #fff; border-color: #e6c7c4; color: var(--bad); }
button.danger:hover:not(:disabled) { background: #fdf3f2; }
button:disabled { opacity: .5; cursor: not-allowed; }
.actions-bar { display: flex; gap: 8px; align-items: center; }

/* ---------------------------------------------------------------- pills */
.tag {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
.tag.grey  { background: #eceef1; color: #5c6270; }
.tag.green { background: #e4f4ea; color: var(--ok); }
.tag.blue  { background: #e5eefb; color: #1a4f9c; }
.tag.gold  { background: #fbf1d8; color: var(--warn); }
.tag.red   { background: #fbe9e7; color: var(--bad); }

.pillset { display: inline-flex; gap: 5px; }
.pillset button {
  border: 1px solid var(--line); background: #fff; color: var(--ink-soft);
  border-radius: 999px; padding: 5px 12px; font-size: 12px; cursor: pointer;
}
.pillset button.on { background: var(--navy); border-color: var(--navy); color: #fff; font-weight: 600; }

/* ---------------------------------------------------------------- dialog */
dialog {
  border: 0; border-radius: 12px; padding: 0; width: min(760px, 94vw);
  max-height: 88vh; overflow: auto;
  box-shadow: 0 18px 50px rgba(10,16,30,.28);
}
/* Provenance notes are reference, not headline: let them wrap small rather
   than forcing the columns that matter into a sliver. */
dialog td { font-size: 12.5px; }
dialog .note-cell { color: var(--ink-soft); font-size: 11.5px; max-width: 30ch; white-space: normal; }
dialog::backdrop { background: rgba(11,18,39,.45); }
dialog .dhead { padding: 16px 18px 0; font-weight: 650; font-size: 15px; }
dialog form { display: flex; flex-direction: column; gap: 12px; padding: 14px 18px 18px; }
dialog .dfoot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }

/* ---------------------------------------------------------------- toast */
.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  background: var(--navy); color: #fff; padding: 11px 18px;
  border-radius: 999px; font-size: 13px; z-index: 60;
  box-shadow: 0 8px 26px rgba(10,16,30,.3);
  max-width: min(600px, 92vw);
}
.toast.bad { background: var(--bad); }
.error { color: #ffb4ad; font-size: 12px; margin: 0; }

@media (max-width: 720px) {
  .topbar { height: auto; padding: 10px 12px; flex-wrap: wrap; }
  th { position: static; }
  .view { padding: 14px; }
}


/* ---------------------------------------------------------------- charts */
.chart svg { display: block; overflow: visible; }
.legend { display: flex; gap: 16px; font-size: 12px; color: var(--ink-soft); margin-bottom: 10px; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.charttip {
  position: fixed; z-index: 80; pointer-events: none;
  background: var(--navy); color: #fff; font-size: 12px;
  padding: 5px 9px; border-radius: 6px; white-space: nowrap;
  box-shadow: 0 4px 14px rgba(10,16,30,.28);
}

/* ------------------------------------------------------------ the sheet */
.tiles { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.figure { font-size: 26px; font-weight: 650; letter-spacing: -.01em; }
.figure.good { color: var(--ok); }
.figure.bad  { color: var(--bad); }
.sheet-head { margin-bottom: 14px; }
.sheet > * + * { margin-top: 14px; }

table.pnl td { padding: 6px 10px; }
table.pnl tr.group td {
  font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-soft); font-weight: 700; padding-top: 16px;
  border-bottom: 1px solid var(--line);
}
table.pnl tr.subgroup td {
  font-size: 11px; color: var(--ink-soft); font-weight: 600;
  padding-top: 10px; border-bottom: 0;
}
table.pnl tr.subtotal td { font-weight: 600; color: var(--ink-soft); }
table.pnl tr.total td { font-weight: 700; border-top: 2px solid var(--ink); border-bottom: 0; }
table.pnl tr.net td { font-size: 15px; }
/* Net after a partner's draw (045): a footnote to Net, not a second total. */
table.pnl tr.aftershare td { font-size: 12px; color: var(--ink-soft); border-bottom: 0; }
table.pnl tr.bad td { color: var(--bad); }
table.pnl td:first-child { padding-left: 18px; }
table.pnl tr.group td:first-child, table.pnl tr.total td:first-child { padding-left: 10px; }

/* ---------------------------------------------------------------- print */
/* The P&L prints as its own document (.printdoc, built in views/pnl.js), not
   as the screen: a statement on page one, forecast workings and the split on
   page two, the charts last and each kept whole. Anything else that prints
   (a table on another screen) still just loses the chrome. */
.printdoc, .printonly { display: none; }

@media print {
  .topbar, .noprint, .charttip, .screenonly { display: none !important; }
  body { background: #fff; font-size: 10pt; }
  .view { padding: 0; max-width: none; }
  .card { border: 0; padding: 0 0 12px; break-inside: avoid; }
  .grid.two { grid-template-columns: 1fr 1fr; }
  h3 { margin-top: 10px; }
  /* Bars are the data; a printer that drops colour prints a blank chart. */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  /* Two sheets of 11x17 landscape, never more (Mike, 11 Oct 2026): the
     statement, then the charts and notes. Each sheet is scaled to fill its
     page by fitPage1 in views/pnl.js. Safari ignores @page size and prints
     whatever its dialog says, so a scale is worked out for both orientations
     and the paper picks. */
  @page { size: 17in 11in; margin: 0.5in; }
  .pd-first, .pd-sheet2 { zoom: var(--fit-landscape, 1); }
  /* Only where @page size is ignored, which is Safari. Chrome honours the
     landscape @page but still answers (orientation: portrait) while printing,
     so it must never read this. Support for the page property tells them
     apart: Chrome and Firefox have it, WebKit does not. */
  @supports not (page: auto) {
    @media (orientation: portrait) { .pd-first, .pd-sheet2 { zoom: var(--fit-portrait, 1); } }
  }
  .printdoc { display: block; }
  .pd-first, .pd-sheet2 { break-inside: avoid; }
  .pd-sheet2 { break-before: page; }
  /* Page breaks inside a flex column are unreliable; plain blocks paginate. */
  .sheet.pagestack { display: block; }
}

.pd-head {
  display: flex; justify-content: space-between; align-items: flex-end; gap: 24px;
  border-bottom: 2px solid var(--ink); padding-bottom: 8px; margin-bottom: 10px;
}
.pd-farm { font-size: 9pt; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); font-weight: 600; }
.pd-head h1 { margin: 2px 0 2px; font-size: 18pt; font-weight: 700; letter-spacing: -.01em; }
.pd-period { font-size: 10.5pt; }
.pd-meta { text-align: right; font-size: 8.5pt; color: var(--ink-soft); line-height: 1.5; }

.pd-statement { width: 100%; border-collapse: collapse; font-size: 10pt; line-height: 1.3; }
.pd-statement th, .pd-statement td { border: 0; padding: 2px 8px; background: none; }
.pd-statement th, .pd-plain th {
  font-size: 8pt; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-soft); font-weight: 600;
}
.pd-statement thead tr.period th { color: var(--ink); font-size: 9pt; padding-bottom: 0; }
.pd-statement thead tr:last-child th { border-bottom: 1px solid var(--ink); padding-bottom: 5px; }
.pd-statement td.num, .pd-statement th.num { width: 0.95in; }
/* Page one holds a year of columns and every line on one landscape sheet, so
   its rows sit closer than the rest of the printout's. */
.pd-first .pd-statement { line-height: 1.15; }
.pd-first .pd-statement td { padding-top: 1px; padding-bottom: 1px; }
.pd-first .pd-statement td:first-child { white-space: nowrap; }
.pd-first .pd-statement tr.group td { padding-top: 6px; }
.pd-first .pd-statement tr.subgroup td { padding-top: 3px; }
.pd-first .pd-statement tr.net td { padding-top: 6px; }
/* Revenue and expenses as two sections, not one block (Mike, 10 Oct 2026). */
.pd-statement tr.group.section-break td { border-top: 1.5px solid var(--ink); }
.pd-first .pd-statement tr.group.section-break td { padding-top: 12px; }
.pd-statement tr.group.section-break td { padding-top: 12px; }
/* The forecast column is set apart: a rule to its left and a tint, so nobody
   reads a guess as a takings figure. */
.pd-statement .fc { border-left: 1px solid var(--line); background: #f6f7f9; font-style: italic; }
.pd-statement tr.group td {
  padding-top: 9px; font-weight: 700; font-size: 9pt;
  text-transform: uppercase; letter-spacing: .06em;
}
.pd-statement tr.group td.fc, .pd-statement tr.subgroup td.fc { font-style: normal; }
.pd-statement tr.subgroup td { padding-top: 5px; padding-left: 16px; font-weight: 600; }
.pd-statement tr.line td:first-child { padding-left: 28px; }
.pd-statement tr.subtotal td { font-weight: 600; }
.pd-statement tr.subtotal td:first-child { padding-left: 16px; }
/* Revenue's Other heading sits level with the main revenue lines and its
   lines one step in, as an expense section's do under its heading. */
.pd-statement tr.subgroup.nested td:first-child,
.pd-statement tr.subtotal.nested td:first-child { padding-left: 28px; }
.pd-statement tr.line.nested td:first-child { padding-left: 40px; }
.pd-statement tr.subtotal td.num { border-top: 1px solid #9aa1ad; }
.pd-statement tr.total td { font-weight: 700; padding-top: 5px; }
.pd-statement tr.total td.num { border-top: 1px solid var(--ink); }
.pd-statement tr.net td { font-weight: 800; font-size: 11pt; padding-top: 9px; padding-bottom: 3px; }
.pd-statement tr.net td.num { border-bottom: 3px double var(--ink); }
.pd-statement tr.margin td { color: var(--ink-soft); font-size: 9pt; padding-top: 6px; }
.pd-statement sup, .pd-plain sup { font-size: 7pt; margin-left: 1px; }
.pd-statement td.num, .pd-plain td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

.pd-notes { margin-top: 12px; font-size: 8pt; color: var(--ink-soft); break-inside: avoid; }
.pd-label { font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: 8pt; color: var(--ink); }
.pd-notes ol { margin: 4px 0 0; padding-left: 16px; }
.pd-notes li { margin: 1px 0; }

.printdoc h2 { font-size: 12pt; margin: 0 0 8px; }
.pd-page h2 + table { margin-bottom: 8px; }
.pd-plain { width: 100%; border-collapse: collapse; font-size: 9.5pt; margin-bottom: 22px; }
.pd-plain th, .pd-plain td { padding: 3px 8px; border: 0; border-bottom: 1px solid var(--line); background: none; }
.pd-plain thead th { border-bottom: 1px solid var(--ink); }
.pd-plain tr.group td { font-weight: 700; font-size: 8.5pt; text-transform: uppercase; letter-spacing: .05em; padding-top: 10px; border-bottom: 0; }
.pd-plain tr.total td { font-weight: 700; border-bottom: 0; border-top: 1px solid var(--ink); }
.pd-basis { color: var(--ink-soft); font-size: 8.5pt; }
.pd-small { font-size: 8.5pt; color: var(--ink-soft); margin: -8px 0 22px; }
/* Sheet two: the screen's charts, laid out for paper. Not inside @media print,
   so the fit measures the sheet as it will print. */
.pd-sheet2 .card { border: 0; padding: 0; margin: 0; background: none; box-shadow: none; }
.pd-sheet2 details, .pd-sheet2 .hint { display: none; }
.pd-sheet2 h3 { margin: 0 0 6px; font-size: 11pt; }
.pd-sheet2 .legend { margin-bottom: 4px; }
.pd-sheet2 .chart svg { height: auto; max-height: 3.6in; }
.pd-sheet2 .grid.two { display: grid; grid-template-columns: 1fr 1fr; gap: 36px; margin-top: 18px; }
.pd-sheet2 .grid.two .chart svg { max-height: 3in; }
.pd-sheet2 .pd-notes { margin-top: 18px; font-size: 9pt; }

.memo {
  margin-top: 12px; padding: 10px 12px;
  border-left: 3px solid var(--sun); background: #fdfaf1;
  font-size: 12.5px; color: var(--ink);
}

/* ------------------------------------------------------------- receipts */
.drop {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border: 1.5px dashed var(--line); border-radius: 10px;
  padding: 14px 16px; background: #fff; cursor: pointer;
  color: var(--ink-soft); font-size: 13px; transition: border-color .12s, background .12s;
}
.drop:hover, .drop:focus-visible { border-color: var(--sky); outline: none; }
.drop.over { border-color: var(--navy); background: #f2f5f9; border-style: solid; }
.drop.has { border-style: solid; }
.drop strong { color: var(--ink); font-weight: 600; }
.drop .hint { margin-left: 8px; }
.drop img.thumb {
  width: 52px; height: 52px; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--line);
}
.drop button { margin-left: auto; }

/* --------------------------------------------------------- icon buttons */
.iconbtn, .iconbtn.danger {
  /* Both selectors on purpose: the text-button .danger rule carries padding,
   * and without the doubled specificity it wins and the trash icon sits
   * 8px down and 14px right of every other mark in the row. */
  display: inline-grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  border: 1px solid var(--line); border-radius: 8px;
  background: #fff; color: var(--ink-soft); cursor: pointer;
}
.iconbtn svg { width: 16px; height: 16px; fill: none;
  stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.iconbtn:hover { border-color: var(--ink-soft); color: var(--ink); background: #fbfcfd; }
.iconbtn.danger { border-color: #e6c7c4; color: var(--bad); }
.iconbtn.danger:hover { background: #fdf3f2; }
.iconbtn:focus-visible { outline: 2px solid var(--sky); outline-offset: 1px; }
/* Something is already filed here — the mark reads as done, not as an invitation. */
.iconbtn.on { color: var(--ink); border-color: #cdd7e2; background: #f2f6fb; }
.actions-bar.end { justify-content: flex-end; gap: 6px; }

/* P&L lines that open to show what is in them. */
table.pnl tr.openable { cursor: pointer; }
table.pnl tr.openable td:first-child::before { content: '▸ '; color: var(--ink-soft); font-size: 11px; }
table.pnl tr.openable.open td:first-child::before { content: '▾ '; }
table.pnl tr.openable:hover td { background: #f7f9fb; }
table.pnl tr.detail > td { padding: 4px 0 12px 22px; }
table.pnl tr.detail table { font-size: 13px; }
@media print { table.pnl tr.openable td:first-child::before { content: ''; } }
/* Expense sections: one line each, opening to their categories. */
table.pnl tr.child td:first-child { padding-left: 36px; }
table.pnl tr.hidden { display: none; }
.statement-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.statement-head h3 { margin: 0; }
.statement-head span { display: flex; gap: 6px; }
button.ghost.small { padding: 3px 10px; font-size: 12px; }

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

/* ‹ Month › */
.monthpick { display: inline-flex; align-items: center; height: 38px;
  border: 1px solid var(--line); border-radius: 8px; background: #fff; overflow: hidden; }
.monthpick button { width: 34px; height: 100%; border: 0; background: transparent;
  color: var(--ink-soft); font-size: 18px; cursor: pointer; }
.monthpick button:hover:not(:disabled) { background: #f3f6f9; color: var(--ink); }
.monthpick button:disabled { opacity: .3; cursor: default; }
.monthpick .mp-label { min-width: 132px; text-align: center; font-size: 14px; color: var(--ink);
  font-weight: 500; padding: 0 4px; }

/* The filter bar: every control on one baseline, captions level, the
 * checkbox sitting beside its words rather than floating above them. */
.head { align-items: flex-end; }
.head > .f { justify-content: flex-end; }
.head > label.f.check { flex-direction: row; align-items: center; gap: 8px; height: 38px;
  font-size: 14px; color: var(--ink); }
.head > label.f.check input { width: auto; margin: 0; }
.stack { display: flex; flex-direction: column; gap: 6px; }
.stack > input, .stack > select { width: 100%; }

/* Selects render a pixel shorter than inputs; the bar shows it. */
.head > .f > select, .head > .f > input:not([type=checkbox]) { height: 38px; box-sizing: border-box; }

.dropzone { border: 1.5px dashed var(--line); border-radius: 10px; padding: 14px;
  text-align: center; font-size: 13px; color: var(--ink-soft); margin-top: 10px; }
.dropzone.over { border-color: var(--sky); background: #f2f7fd; color: var(--ink); }
.dropzone input[type=file] { display: none; }
.receipts .grid.two { gap: 10px; }

.packrow { padding: 12px 0; border-top: 1px solid var(--line); }
.packrow:first-child { border-top: 0; }
.packhead { display: flex; align-items: center; gap: 22px; margin-bottom: 8px; }
.packstat { font-size: 15px; white-space: nowrap; }
.packstat strong { font-size: 20px; }
.packhead > .grow { flex: 1; }
.tag.amber { background: #fdf1e3; color: #9a5b12; }

.packbanner { border: 1px solid #cbe3d2; background: #eef8f1; color: #1d5c34;
  border-radius: 10px; padding: 10px 14px; margin: 12px 0; font-size: 14px; }
.packbanner span { color: #2f6b45; }

/* A pair shown side by side is two halves of one thing, so they are the same
 * size: same top, same bottom. Card-to-card spacing is for a stack — inside a
 * grid it pushed the second card of every row 14px down the page, which is why
 * two charts beside each other never lined up.
 * (A LIST of cards of differing heights is a different problem and uses
 * .masonry, which flows them in columns with no dead space.) */
.grid.two { align-items: stretch; }
.grid > .card + .card, .masonry > .card + .card { margin-top: 0; }

/* ONE vertical rhythm per page.
 *
 * Spacing used to come from `.card + .card`, which only works while every
 * block on the page happens to be a card. Put a wrapper between two of them —
 * a grid of a pair, a column flow of five — and the rule stops matching and
 * that join loses its gap, which is exactly what kept happening. A page is a
 * flex column with one gap; nothing inside it contributes margins of its own. */
.pagestack { display: flex; flex-direction: column; gap: var(--stack); }
.pagestack > * { margin-top: 0 !important; margin-bottom: 0 !important; }
.masonry { column-gap: var(--stack); }
.masonry > * { margin: 0 0 var(--stack) !important; }
.grid { gap: var(--stack); }
/* Work given away: present, but not read as money in the bank. */
.given { color: var(--ink-soft); }
/* "split delivery, Sep–Oct" beside a line that carries a share of a spread. */
.spreadnote { color: var(--ink-soft); font-size: .88em; font-style: italic; }

/* Signed forms arriving: a notification, not a destination. */
.formsbtn { display: inline-flex; align-items: center; gap: 6px; margin-right: 14px;
  padding: 4px 8px; border-radius: 8px; color: #aab4c4; text-decoration: none; }
.formsbtn svg { width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.formsbtn:hover { background: rgba(255,255,255,.08); color: #fff; }
.formsbtn.waiting { color: #fff; }
.formsbtn .count { display: none; }
.formsbtn.waiting .count { display: inline-grid; place-items: center; min-width: 18px;
  height: 18px; padding: 0 5px; border-radius: 9px; background: var(--bad);
  color: #fff; font-size: 11px; font-weight: 600; }
h3.section { font-size: 15px; margin: 22px 0 10px; }
h3.section:first-child { margin-top: 0; }
.card.intake .factgrid { grid-template-columns: 1fr 1fr; gap: 6px 24px; margin-top: 10px; }
.card.intake + .card.intake { margin-top: 14px; }

/* Cards of their own heights, stacked. A grid puts these in rows, so a short
 * card leaves a hole beneath it until the tall one beside it finishes — which
 * is the empty half-page under "Charges by service". Columns flow instead:
 * each card sits directly under the one above it. */
.masonry { columns: 2; column-gap: 18px; }
.masonry > * { break-inside: avoid; margin: 0 0 18px !important; display: inline-block; width: 100%; }
@media (max-width: 900px) { .masonry { columns: 1; } }

/* What a forecast is made of: open it and argue with the lines. */
details.forecast { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
details.forecast summary { cursor: pointer; font-size: 13px; color: var(--ink-soft); }
details.forecast summary:hover { color: var(--ink); }
details.forecast table { width: 100%; font-size: 13px; margin-top: 10px; }
details.forecast td { padding: 5px 8px; border-bottom: 1px solid var(--line); }
details.forecast tr.group td { font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-soft); border-bottom: 0; padding-top: 12px; }
details.forecast tr.guessed td:first-child::after { content: ' ~'; color: var(--ink-soft); }

/* A picker with its "+ New" beside it. The pair used to sit in .actions-bar,
 * which the field rules above never reach (they style a select that is the
 * label's own child), so the select fell back to the grey native control and
 * sized itself to its longest name — crushing "+ New" onto two lines and
 * pushing it into the next column. The select takes the room; the button
 * keeps its one line. */
.withadd { display: flex; gap: 8px; align-items: stretch; }
.withadd > select {
  flex: 1 1 auto; min-width: 0; width: 100%;
  border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; background: #fff; color: var(--ink); font-size: 14px;
}
.withadd > select:focus { outline: 2px solid var(--sky); outline-offset: -1px; border-color: transparent; }
.withadd > button { flex: none; white-space: nowrap; }

/* Something owed and not paid (053): a red "!" on the tab that holds it. */
.alert { display: inline-grid; place-items: center; width: 16px; height: 16px;
  margin-left: 6px; border-radius: 50%; background: var(--bad); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1; vertical-align: 1px; }

/* -------------------------------------------- shows: connections, show cards */
/* The external sites billing signs in to, side by side at the top of the Shows tab
   and each show's roster: signed in or not, and what the sign-in is for. */
.connections { display: grid; gap: 12px; margin-bottom: var(--stack);
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.conn { background: var(--card); border: 1px solid var(--line); border-left: 4px solid var(--warn);
  border-radius: var(--radius); padding: 12px 14px; min-width: 0; }
.conn.on { border-left-color: var(--ok); }
.conn-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-weight: 650; }
.conn .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--warn); flex: none; }
.conn.on .dot { background: var(--ok); }
.conn .state { font-weight: 400; color: var(--ink-soft); font-size: 13px; }
.conn-head button { margin-left: 4px; }
.conn.compact { padding: 8px 12px; display: inline-block; max-width: 100%; }
.conn.compact .actions-bar { display: inline-flex; }
.conn .why { color: var(--ink-soft); font-size: 13px; margin: 4px 0 8px; }
.conn .actions-bar { margin: 0; }
.conn input { max-width: 100%; }

.show-cards { display: grid; gap: 12px; margin-bottom: var(--stack);
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); }
.show-card { display: block; color: inherit; text-decoration: none; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.show-card:hover { border-color: var(--sky); box-shadow: 0 1px 4px rgba(17, 26, 51, .08); }
/* A show you have entries at on horseshowing.com, offered to add: not a link, dashed. */
.show-card.offered { border-style: dashed; }
.show-card.offered:hover { border-color: var(--line); box-shadow: none; }
.show-card .name { font-weight: 650; }
.show-card .meta { color: var(--ink-soft); font-size: 13px; margin-top: 2px; }
.show-card .counts { margin-top: 8px; font-size: 13px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

details.riders { margin-top: 6px; }
details.riders > summary { cursor: pointer; font-weight: 650; font-size: 15px; padding: 6px 0; }
details.riders > summary .hint { font-weight: 400; margin-left: 6px; }

/* A text box with a list of our own under it, wider than the box (the Shows tab's
   "Add a show"): the browser's own suggestion list can't be made wider. Anchored to
   the box's right edge, since the box sits at the right of its row. */
.combo { position: relative; display: inline-block; max-width: 100%; }
.combo-list { position: absolute; top: calc(100% + 4px); right: 0; z-index: 30;
  width: 36em; max-width: calc(100vw - 32px); max-height: 340px; overflow-y: auto;
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 6px 18px rgba(17, 26, 51, .12); padding: 4px; }
.combo-item { padding: 6px 10px; border-radius: 6px; cursor: pointer; }
.combo-item:hover, .combo-item.active { background: var(--ground); }
.combo-item .meta, .combo-item.meta { color: var(--ink-soft); font-size: 12px; }
