/* KoinBooks — only what this workspace needs that the frame does not give it.
 *
 * shared/koin-frame.css dresses the whole chrome: .frame, .aside, .brand, .org,
 * .nav, .group, .items, .foot, .main, .top, .crumb, .tools, .content, .card,
 * .lead, .boot. None of that is repeated here.
 *
 * The first version of this file invented .shell, .rail and .navlink and styled
 * them from nothing, which is why the workspace looked like a different product
 * standing next to KoinVoice. It also redefined .card, .group and .boot, so it
 * was fighting the frame for the same names. This file now adds and never
 * overrides.
 */

/* ── Figures ───────────────────────────────────────────────────────────── */

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 13px; margin-bottom: 20px; }
.kpi {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 15px 17px; display: flex; flex-direction: column; gap: 5px;
}
.kpi span { font-size: var(--t-small); color: var(--ink-soft); font-weight: 600; }
.kpi strong { font-size: 22px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.kpi small { font-size: var(--t-small); color: var(--ink-soft); }

/* Which book these figures belong to. One book per legal entity, so this reads
   rather than chooses until a workspace keeps more than one. */
.scope {
  display: flex; flex-wrap: wrap; gap: 10px 28px; margin-bottom: 18px; padding: 11px 15px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
}
.scope div { display: flex; flex-direction: column; gap: 2px; }
.scope span { font-size: var(--t-small); color: var(--ink-soft); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.scope b { font-size: var(--t-emph); color: var(--ink); font-weight: 800; }

/* The selector sits where the name was, so the bar does not change shape when
   a workspace opens its second book. Weighted like the <b> it replaces. */
.scope select {
  min-height: 34px; padding: 0 8px; max-width: 34ch;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: var(--t-emph); font-weight: 800;
}

/* ── Money ─────────────────────────────────────────────────────────────── */

/* Right-aligned and tabular, the way figures are read: a column lines up on the
   decimal and a long number cannot be mistaken for a short one. */
table.rows { width: 100%; border-collapse: collapse; font-size: var(--t-emph); }
table.rows th, table.rows td { padding: 8px 10px; border-bottom: 1px solid var(--line-soft); text-align: left; }
table.rows th { font-size: var(--t-small); color: var(--ink-soft); font-weight: 700; white-space: nowrap; }
table.rows td.num, table.rows th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.rows tr:last-child td { border-bottom: 0; }
table.rows tfoot td { font-weight: 800; border-top: 1px solid var(--line); border-bottom: 0; }
/* A CODE IN A TABLE IS TEXT, NOT A BADGE.
   The shared frame defines `.code` as the 34px square that holds an
   organisation's initials: display grid, fixed width and height, a border and
   a background. These cells carry the same class for a different reason, and
   inherited all of it: every invoice number, entry number and account code in
   a books table was squeezed into a 34px tile, so a receipt form drew the
   invoice and its due date stacked in one column and every figure after them
   under the wrong heading. Nothing overflowed, so no sweep looking for
   overflow saw it. Every property the badge sets is put back here. */
table.rows td.code {
  display: table-cell; width: auto; height: auto; place-items: initial; flex-shrink: initial;
  border: 0; border-radius: 0; background: none;
  font-size: inherit; font-weight: inherit; text-transform: none;
  font-variant-numeric: tabular-nums; color: var(--ink-soft); white-space: nowrap;
}

/* An account nothing has ever been posted to. A dash, not nought: the two are
   different facts and a column of 0.00 hides which is which. */
.none { color: var(--ink-soft); }

.pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; border-radius: 20px;
  font-size: var(--t-small); font-weight: 700;
}
.pill.ok { background: var(--sel); color: var(--pos); }
.pill.warn { background: var(--sel-warn, #fdf2df); color: var(--warn, #8a5a00); }

.notice { border-radius: 11px; padding: 12px 14px; font-size: var(--t-emph); line-height: 1.55; }
.notice.warn { background: var(--sel-warn, #fdf2df); color: var(--ink); border: 1px solid var(--line); }
.notice.bad { background: var(--sel-neg, #fdecec); color: var(--ink); border: 1px solid var(--line); }

/* ── Writing: approvals, people, opening a book ───────────────────────── */

button.act {
  min-height: 40px; padding: 0 15px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); font: inherit; font-weight: 700; cursor: pointer;
}
button.act:hover { background: var(--surface-2); }
button.act[disabled] { opacity: .5; cursor: not-allowed; }

/* A button that reads as a link, inside a table. A real button, because it does
   something and a screen reader should say so. */
button.linklike {
  border: 0; background: none; padding: 0; font: inherit; color: var(--pos);
  font-weight: 700; cursor: pointer; text-align: left;
}
button.linklike:hover { text-decoration: underline; }

/* ── The ten classes that styled nothing ───────────────────────────────
 *
 * Found by rendering a screen and looking at it. Every one of these was in the
 * markup of between one and eleven registers, and none was defined anywhere:
 * the refusal paragraph on nine screens, the confirmation beside it, the small
 * buttons inside table rows, the totals row of seven tables. They rendered as
 * plain unstyled flow and every structural test passed, because as TEXT the
 * markup is perfectly correct.
 *
 * A test now refuses a class this stylesheet does not define.
 */

/* A refusal, and the confirmation that replaces it. Both are a sentence rather
   than a banner: they appear under the action that caused them, where somebody
   is already looking. */
.refuse {
  margin: 0 0 14px; padding: 11px 14px; border-radius: 11px;
  background: var(--sel-neg); border: 1px solid var(--line);
  color: var(--neg); font-size: var(--t-emph); line-height: 1.55; font-weight: 600;
}
.said {
  margin: 0 0 14px; padding: 11px 14px; border-radius: 11px;
  background: var(--sel); border: 1px solid var(--line);
  color: var(--pos); font-size: var(--t-emph); line-height: 1.55; font-weight: 600;
}

/* A button inside a table row, which must not be the height of the row. */
.btn.small { min-height: 30px; padding: 0 11px; font-size: var(--t-small); }

/**
 * The buttons at the end of a row, side by side.
 *
 * NEVER WRAPPING. An asset with three actions needed 265px of a column sized at
 * 80, so the buttons stacked and every row of the register stood 135px tall;
 * payroll was worse at 327. The last track of each grid above is sized to its
 * CONTENT for the same reason: an action column is as wide as its actions, and
 * the table scrolls if that makes it wider than the page.
 */
.rowacts { display: flex; flex-wrap: nowrap; gap: 8px; align-items: center; justify-content: flex-end; }

/* The line a table adds up to. Heavier, and divided from the rows above it. */
.rrow.total {
  font-weight: 800; color: var(--ink);
  background: var(--surface-2); border-top: 2px solid var(--line); border-bottom: 0;
}

/* A rendered document, shown as it will be sent. Monospaced because every
   character in it is significant, and scrollable because it is long. */
pre.xml {
  margin: 0; padding: 14px 16px; border-radius: 11px; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.5; max-height: 460px; overflow: auto; white-space: pre;
}

.fields { display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: flex-end; }
.fields label { display: flex; flex-direction: column; gap: 4px; font-size: var(--t-small); color: var(--ink-soft); font-weight: 700; }
/* A field that takes the whole row: a reason, a note, a series of dates. In a
   wrapping row of short inputs these would otherwise be a 12ch box for a
   sentence. */
.fields label.wide { flex: 1 0 100%; }
.fields label.wide input, .fields label.wide textarea { width: 100%; }

table.rows input, table.rows select, .fields input, .fields select {
  min-height: 38px; padding: 0 9px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface); color: var(--ink); font: inherit; max-width: 100%;
}
table.rows td.num input { text-align: right; font-variant-numeric: tabular-nums; width: 11ch; }
/* A line's description takes the room its row has. It was drawn at the
   input's default width, so "Annual hall hire: 2025-01-01 to 2025-01-31" read
   as "Annual hall hire: 2025-01-0" on the credit note form with half the row
   empty beside it, and the invoice and bill forms did the same. */
table.rows input[data-f="description"] { width: 100%; min-width: 22ch; }
table.rows select { min-width: 12ch; }

/* ── What is not built ─────────────────────────────────────────────────
 * Deliberately plain. A convincing empty state for a screen that does not
 * exist is how a demo becomes a promise, so this looks like a note rather
 * than a product. */
.pending { border: 1px dashed var(--line); border-radius: 14px; padding: 20px 22px; background: transparent; }
.pending h2 { margin: 0 0 8px; font-size: var(--t-card); font-weight: 800; color: var(--ink); }
.pending p { margin: 0 0 10px; color: var(--ink-soft); font-size: var(--t-emph); line-height: 1.55; max-width: 64ch; }
.pending dt { font-size: var(--t-small); font-weight: 700; color: var(--ink-soft); margin-top: 10px; }
.pending dd { margin: 3px 0 0; font-size: var(--t-emph); color: var(--ink); line-height: 1.5; max-width: 64ch; }

/* ── The dashboard ──────────────────────────────────────────────────────
 * Composed the way the project pack composes it. The sizes are the pack's:
 * a 52px title tile, a 190px card track, a 300px panel track and a 180px
 * action track. The panel track is the one that matters, because it is what
 * sets the two panels side by side; at 300px each they drop to one column on
 * a narrow screen, which is the behaviour the pack has too.
 */

.pagehead { display: flex; align-items: center; gap: 16px; margin-bottom: 22px; }
.pageicon {
  width: 52px; height: 52px; border-radius: 14px; flex-shrink: 0;
  background: var(--sel); color: var(--pos); display: grid; place-items: center;
}
.pageicon svg { width: 26px; height: 26px; }
.pagehead h1 { margin: 0; font-size: var(--t-page); font-weight: 800; color: var(--ink); letter-spacing: -.02em; }
.pagehead p { margin: 5px 0 0; font-size: 14px; color: var(--ink-soft); line-height: 1.5; max-width: 640px; }

/* Dark, and drawn only when the book has something to say. A standing amber
   banner on a healthy book teaches a reader to ignore the one that matters. */
.banner {
  display: flex; align-items: center; gap: 14px; margin-bottom: 24px;
  background: linear-gradient(135deg, #0d3024, #0b2119);
  color: #fff; border-radius: 16px; padding: 18px 22px;
}
.bicon {
  width: 40px; height: 40px; border-radius: 11px; flex-shrink: 0;
  background: rgba(213, 174, 91, .16); color: #d5ae5b; display: grid; place-items: center;
}
.bicon svg { width: 20px; height: 20px; }
.banner b { display: block; font-size: var(--t-emph); font-weight: 800; margin-bottom: 3px; }
.banner p { margin: 0; font-size: 13px; color: #c7d5cc; line-height: 1.5; }

/* The two panels. Priority Action Queue first, Book Health beside it. */
.panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 18px; margin-bottom: 24px; }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 20px; }
.phead { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.phead h2 { margin: 0; min-width: 0; font-size: var(--t-card); font-weight: 800; color: var(--ink); }
.plink { font-size: 12.5px; font-weight: 700; color: var(--pos); text-decoration: none; }
.plink:hover { text-decoration: underline; }

.prow { display: flex; align-items: center; gap: 12px; padding: 10px 4px; border-top: 1px solid var(--line-soft); }
.ptile {
  width: 32px; height: 32px; border-radius: 9px; flex-shrink: 0;
  background: var(--surface-2); color: var(--ink-soft); display: grid; place-items: center;
}
.ptile svg { width: 16px; height: 16px; }
.ptext { flex: 1; min-width: 0; }
.ptext b { display: block; font-size: 13.5px; font-weight: 700; color: var(--ink); }
/* One line, truncated. The book reference lives here and is a pair of
   uuids: wrapped, it pushes every row of the panel apart. */
.ptext small { font-size: var(--t-small); color: var(--ink-soft);
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prow .pill { flex-shrink: 0; }

/* Only actions that lead somewhere built. A tile that opens a placeholder is
   how a demo becomes a promise. */
.quick { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; }
.qa {
  display: flex; flex-direction: column; gap: 8px; padding: 16px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  text-decoration: none; color: inherit;
}
.qa:hover { border-color: #a8bcae; }
.qa svg { width: 20px; height: 20px; color: var(--pos); }
.qa b { font-size: 13px; font-weight: 800; color: var(--ink); }
.qa small { font-size: 11.5px; color: var(--ink-soft); line-height: 1.4; }

/* ── A register, the way the pack draws one ─────────────────────────────
 * One table whose columns each carry two facts, a status pill in the second
 * to last, and the row's action in the last. The pack's own rows open a
 * detail screen; there is none here, so the action is inline.
 *
 * A grid rather than a <table>, as the pack has it: the column template is one
 * declaration and the row is a flex-free line that cannot be knocked out of
 * alignment by a long customer name.
 */

.actionbar { display: flex; gap: 10px; margin-bottom: 16px; align-items: center; flex-wrap: wrap; }
.actionbar select {
  min-height: 38px; padding: 0 12px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface); color: var(--ink); font: inherit; font-size: var(--t-emph); cursor: pointer;
}

.rtable {
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  overflow-x: auto; overflow-y: hidden; margin-bottom: 20px;
}
.rhead, .rrow {
  display: grid;
  grid-template-columns: minmax(152px, 1fr) minmax(110px, 1.4fr)
                         minmax(190px, max-content) minmax(170px, max-content)
                         minmax(170px, max-content) minmax(140px, max-content)
                         minmax(90px, max-content);
  /* The minimums are measured, not guessed: a pair of dates is 187px and a pair
     of amounts in the thousands is 167px, so those tracks start there and grow
     to their content. The gap is 16 rather than 22 because seven columns spend
     132px of a row on nothing at 22. */
  /* 12 rather than 16: six gaps at 16 spend 96px of the row on nothing, and
     the 42px that buys is exactly what the identifier column needed. */
  min-width: 1094px; gap: 12px; align-items: center;
}
/*
 * THE FIRST TRACK HOLDS AN IDENTIFIER, SO IT IS MEASURED LIKE ONE.
 *
 * It was 110px, which is less than the things that go in it. The payables
 * register showed "INV-202501-1000" in 110px of the 127px it needs, and two
 * bills whose numbers differ in the last character became the same bill on
 * screen. The audit trail showed "2026-10-06 16:37:15" in 110 of 147 and lost
 * the time, which is most of what an audit entry is for.
 *
 * THE NAME COLUMN PAYS FOR IT, from 130px to 110px, along with 4px off each
 * of the six gaps. A name in that column is ellipsised at any of those widths,
 * so the 20px bought nothing that was readable; the identifier beside it is
 * now whole. Measured after: nothing in the first column of any register is
 * cut, and no table scrolls sideways.
 *
 * A name may be cut short; it is still recognisable, and another column
 * usually identifies the row. A document number and a timestamp are not
 * recognisable when cut, which is the same rule the paragraph below states
 * about amounts. 152px is the widest of those measured, not a guess.
 */
/*
 * ONLY THE FIRST TWO TRACKS FLEX. They hold a code and a name, which are the
 * only things in a row long enough to be worth cutting short: everything after
 * them is a date, a pair of dates, an amount or a pair of amounts, and each of
 * those is meaningless when it is cut. "2025-01-01 / 2025-02-15" ellipsised in
 * the middle of the due date is the shape this found.
 *
 * So the trailing tracks size to their CONTENT rather than to a guess, because a
 * cell there often holds two figures rather than one: "EUR 5,124.00 /
 * EUR 5,124.00" is what has been settled against what is owed. At a fixed
 * 140px that reads as a truncated amount with an ellipsis where the cents
 * should be, and a clipped figure is the one thing a ledger must never show.
 * The table scrolls if the row ends up wider than the page, which is what the
 * scroller on .rtable has always been for.
 */

/**
 * A WIDER TABLE SAYS SO.
 *
 * The grid above declares seven tracks. A header with eight or nine spans does
 * not widen it: the extra cells WRAP onto a second line, under the first
 * column, on every row. Four registers shipped like that and nobody saw it,
 * because nobody had looked at them rendered.
 *
 * Fewer than seven is harmless, which is why most screens say nothing: the
 * unused tracks simply stay empty. More than seven has to be declared, and a
 * test counts the spans and refuses a table that does not.
 */
.rtable.wide8 .rhead, .rtable.wide8 .rrow {
  grid-template-columns: minmax(100px, 1fr) minmax(120px, 1.3fr)
                         minmax(200px, max-content) minmax(150px, max-content)
                         minmax(140px, max-content) minmax(120px, max-content)
                         minmax(110px, max-content) minmax(85px, max-content);
  min-width: 970px; gap: 12px;
}
/* Nine columns in the width a sidebar leaves on an ordinary laptop, which
   measured 1126px: at a 1180px minimum the asset register scrolled sideways on
   a 1440px screen, which is most screens. The gap narrows with it, because
   22px nine times is 198px of the row spent on nothing. */
.rtable.wide9 .rhead, .rtable.wide9 .rrow {
  grid-template-columns: minmax(110px, 1fr) minmax(130px, 1.3fr) minmax(100px, .8fr)
                         minmax(110px, .9fr) minmax(100px, .9fr) minmax(95px, .7fr)
                         minmax(95px, .7fr) minmax(95px, .7fr) minmax(80px, max-content);
  min-width: 1040px; gap: 14px;
  /* Rows can be two lines deep now, so cells sit at the top of one rather
     than floating in the middle of it. */
  align-items: start;
}
/*
 * NINE TRACKS LEAVE NO SLACK, so the two that hold WORDS wrap.
 *
 * Measured on both tables that use this rule, every track was pinned at its
 * minimum: there is nothing left to give anybody. The payroll register's State
 * column needed 168px and had 95, so "Waiting to be checked" read "Waiting to
 * b...", and a state you cannot read is the only thing that column is for. The
 * asset register lost its asset names the same way, 190px into 110.
 *
 * Widening a track would only starve another one. Wrapping costs a line of
 * height and loses nothing, and it is the right answer for these two
 * specifically: an asset's name and a state are phrases, read rather than
 * scanned. Every other track here is a date, a count or an amount, and those
 * stay on one line, because a wrapped figure is a misread figure.
 */
.rtable.wide9 .rrow > span:nth-child(1),
.rtable.wide9 .rrow > span:nth-child(8) {
  overflow: visible; text-overflow: clip; white-space: normal; line-height: 1.4;
}
/**
 * A BOX NUMBER AND A STATUTORY SENTENCE, which is the inverse of the shape
 * the grid above is built for.
 *
 * The default tracks assume "a code and a name" and let everything after them
 * size to its content. On the VAT return the first cell is "1" or "2^1" and
 * the second is the law's own wording, up to about 1,270px of it. The
 * max-content tracks take the width first, the flexible ones collapse to
 * their minimums, and the description cell gets 130px.
 *
 * Rendered, that was seven different boxes every one of which read
 * "Acts and transacti..." - a return where you cannot tell which box a figure
 * belongs to, which is the only thing the column is for.
 *
 * So the number track shrinks to what a number needs, the description gets
 * the slack, AND IT WRAPS. Wrapping is the part that actually fixes it: a
 * statutory label is a sentence, it is read rather than scanned, and no column
 * width makes 1,270px of it fit on one line. Nothing else in the row wraps,
 * because everything else is a figure.
 */
.rtable.boxes .rhead, .rtable.boxes .rrow {
  grid-template-columns: minmax(44px, max-content) minmax(240px, 2.6fr)
                         minmax(110px, max-content) minmax(110px, max-content)
                         minmax(170px, 1.4fr) minmax(100px, max-content);
  min-width: 860px; gap: 16px;
  align-items: start;
}
/* The description AND the reason. Both are sentences: "Import VAT is assessed
   by customs, not by a purchase invoice" is why a box is left unanswered, and
   half of it answers nothing. The figures between them do not wrap, because a
   wrapped amount is a misread one. */
.rtable.boxes .rrow > span:nth-child(2),
.rtable.boxes .rrow > span:nth-child(5) {
  overflow: visible; text-overflow: clip; white-space: normal; line-height: 1.45;
}

.rhead {
  padding: 12px 18px; background: var(--surface-2); border-bottom: 1px solid var(--line);
  font-size: var(--t-small); font-weight: 800; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-soft);
}
.rrow { padding: 14px 18px; border-bottom: 1px solid var(--line-soft); font-size: var(--t-emph); }
.rrow:last-child { border-bottom: 0; }
.rrow > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/*
 * A SECOND VALUE IN A CELL IS SPACED FROM THE FIRST, HERE RATHER THAN IN
 * EVERY CALLER.
 *
 * A row cell often carries a label and a quieter second value: a code and a
 * name, a method and a life. Most callers happen to leave a newline between
 * them in the markup, which HTML collapses to a space, and read correctly by
 * accident. The asset register's method cell puts the newline INSIDE the
 * template expression instead, so nothing reached the output and twelve rows
 * read "Straight line60 months".
 *
 * Depending on where a caller happens to break its lines is not a rule. The
 * space belongs to the pair, so it is set on the pair.
 */
.rrow > span > small { margin-left: 6px; }
/*
 * A CELL THAT HOLDS TWO VALUES SAYS SO, and is allowed the second line.
 *
 * By POSITION is not good enough for this one. In the asset register the
 * fourth column is "Straight line, 60 months", two values and 139px of them in
 * a 110px track. In the payroll register, which uses the same nine track rule,
 * the fourth column is Gross. Wrapping by position would wrap an amount, and a
 * wrapped amount is a misread amount.
 *
 * So the cell declares itself rather than being inferred from where it sits.
 */
.rrow > span.stack {
  overflow: visible; text-overflow: clip; white-space: normal; line-height: 1.4;
}
.rrow .num, .rhead .num { text-align: right; font-variant-numeric: tabular-nums; }
/* A figure is never ellipsised. Its track is sized to its content above, so
   there is nothing to hide, and hiding four pixels of it turns 15,250.00 into
   15,250.0 with a dot after it. */
.rrow > .num { overflow: visible; text-overflow: clip; }
.rrow .pill { justify-self: start; }
/* The second fact on a line, quieter than the first: a payment term beside a
   customer, never competing with the name. */
.rrow i.none { font-style: normal; font-size: var(--t-small); }

.rempty { padding: 50px 20px; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; }
.rempty b { font-size: var(--t-card); font-weight: 800; color: var(--ink); }
.rempty p { margin: 0; font-size: var(--t-emph); color: var(--ink-soft); max-width: 42ch; }

/* The register's own pill tones, matching the pack's: a settled document is
   green, one still owed is amber, a draft is informational and a void is spent. */
.pill.info { background: var(--sel-info, #e8eef7); color: var(--info, #1f4f80); }
.pill.closed { background: #eef1ee; color: var(--ink-soft); }

/* Two-factor setup: the QR code sits on white whatever the theme, because a
   phone camera reads dark modules on a light ground and not the reverse. */
.qr { display: inline-block; background: #fff; border-radius: 10px; padding: 6px; line-height: 0; margin: 4px 0 10px; }

/* Help Center guides: one closed row each, opened in place. */
details.guide { border: 1px solid var(--line-soft, var(--line)); border-radius: 12px; padding: 12px 14px; margin: 0 0 10px; }
details.guide summary { cursor: pointer; }
details.guide ol { margin: 10px 0; padding-left: 20px; display: grid; gap: 6px; }

/* Setting up a book: three steps, the current one marked, the done ones ticked. */
ol.setup-steps { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 0 0 16px; padding: 0; list-style: none; counter-reset: step; }
ol.setup-steps li { counter-increment: step; color: var(--ink-soft); font-weight: 600; }
ol.setup-steps li::before { content: counter(step) ". "; }
ol.setup-steps li.now { color: var(--ink); font-weight: 800; }
ol.setup-steps li.done { color: var(--pos, var(--ink)); }
ol.setup-steps li.done::before { content: "\2713  "; }

/* ── The project pack's own rules, copied from its stylesheet ─────────────── */
[data-scope-bar] { position: relative; display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; padding: 16px 18px 16px 22px; margin: 0 0 18px; border: 1px solid var(--line); border-radius: 16px; background: linear-gradient(180deg, var(--surface), var(--surface-2)); box-shadow: rgba(12, 38, 29, 0.05) 0 1px 2px, rgba(12, 38, 29, 0.35) 0 16px 30px -24px; overflow: hidden; }
[data-scope-bar]::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: linear-gradient(180deg, var(--pos), #4aa87a); }
[data-scope-bar] .field { display: grid; gap: 6px; font-size: 10.5px; font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-soft); position: relative; }
[data-scope-bar] .field .chev { position: absolute; right: 1px; bottom: 1px; width: 42px; height: 42px; display: grid; place-items: center; pointer-events: none; color: var(--ink-soft); }
[data-scope-bar] .field select { background-image: none; height: 44px; min-width: 0; width: 100%; padding: 0 38px 0 13px; border: 1px solid rgb(107, 127, 116); border-radius: 11px; background-color: var(--surface); color: var(--ink); font-size: 13.5px; font-weight: 750; cursor: pointer; appearance: none; transition: border-color 0.15s, box-shadow 0.15s; }
[data-scope-bar] .field select:hover { border-color: rgb(77, 107, 94); }
[data-scope-bar] .field select:focus { outline: none; border-color: var(--pos); box-shadow: rgba(31, 107, 70, 0.14) 0 0 0 3px; }
[data-scope-bar] .field select:disabled { cursor: default; opacity: 1; }
.kpi-value { display: block; min-width: 0; max-width: 100%; font-size: clamp(16px, 1.55vw, 24px); white-space: nowrap; overflow: visible; line-height: 1.2; font-variant-numeric: tabular-nums; }
.scp7:hover { background: var(--surface-2, #f3f5f0) !important; }
.scp5:hover { border-color: var(--pos, #1f6b46) !important; }
.scp7[aria-selected="true"] { background: var(--sel, #e5f2e9) !important; }


/* ── Theme: controls in the product's green ────────────────────────────────
   Every button, dropdown and date field takes the book's green, so a control
   looks the same on every screen whichever module drew it. */
:root { accent-color: var(--pos); }

.pk-btn {
  min-height: 44px; padding: 9px 14px; border-radius: 9px; font: inherit; font-size: 12.5px;
  font-weight: 800; cursor: pointer; border: 1px solid rgba(31, 107, 70, .28);
  transition: background-color .15s, border-color .15s, box-shadow .15s;
}
.pk-act { background: var(--sel); color: var(--pos); }
.pk-act:hover { border-color: var(--pos); box-shadow: inset 0 0 0 1px var(--pos); }
.pk-quiet { background: var(--surface-2); color: var(--pos); border-color: var(--line); font-weight: 700; }
.pk-quiet:hover { background: var(--sel); border-color: rgba(31, 107, 70, .28); }
.pk-primary { background: var(--pos); color: var(--on-pos); border-color: var(--pos); }
.pk-primary:hover { background: var(--pos-deep, #18563a); border-color: var(--pos-deep, #18563a); }
.pk-btn:focus-visible { outline: 2px solid var(--pos); outline-offset: 2px; }
.pk-btn[disabled] { opacity: .5; cursor: not-allowed; box-shadow: none; }
/* A link to another screen (pack.js goLink): text and an arrow, never button
   chrome, so it cannot be mistaken for an action on this screen. */
.pk-link { color: var(--pos); font-size: 12.5px; font-weight: 800; text-decoration: none; cursor: pointer; white-space: nowrap; }
.pk-link:hover { text-decoration: underline; }
.pk-link:focus-visible { outline: 2px solid var(--pos); outline-offset: 2px; border-radius: 4px; }
.pk-related { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; margin: -10px 0 18px; font-size: 12.5px; }
.pk-related-label { color: var(--ink-soft); font-weight: 700; }
button.act { background: var(--sel); color: var(--pos); border-color: rgba(31, 107, 70, .28); }
button.act:hover { background: var(--sel); border-color: var(--pos); }

select {
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%231f6b46' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 12px;
  padding-right: 32px !important; border-color: var(--ctl-line);
}
[data-theme="dark"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236cc196' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
select:hover, input[type="date"]:hover, input[type="month"]:hover, input[type="datetime-local"]:hover { border-color: var(--pos) !important; }
select:focus, input:focus, textarea:focus {
  outline: none; border-color: var(--pos) !important; box-shadow: 0 0 0 3px rgba(31, 107, 70, .14);
}
input[type="date"], input[type="month"], input[type="datetime-local"], input[type="time"] {
  color: var(--ink); accent-color: var(--pos); cursor: pointer;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
  cursor: pointer; border-radius: 6px; padding: 3px;
  /* The browser draws this icon in black; this filter turns it the book's green. */
  filter: invert(29%) sepia(52%) saturate(640%) hue-rotate(102deg) brightness(92%) contrast(90%);
}
input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="month"]::-webkit-calendar-picker-indicator:hover { background-color: rgba(31, 107, 70, .12); }
[data-theme="dark"] input::-webkit-calendar-picker-indicator {
  filter: invert(72%) sepia(23%) saturate(640%) hue-rotate(95deg) brightness(95%);
}
input[type="checkbox"], input[type="radio"] { accent-color: var(--pos); }

/* ── The month calendar (controls.js); dropdowns and dates use the shared scripts ── */
.pk-off { opacity: .55; cursor: not-allowed; }
  display: inline-flex; align-items: center; min-height: 38px; padding: 8px 32px 8px 13px; text-align: left;
  border: 1px solid var(--ctl-line); border-radius: 9px; background-color: var(--surface); color: var(--ink);
  font: inherit; font-size: 13px; cursor: pointer; max-width: 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%231f6b46' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 12px;
}
.pk-pop {
  position: fixed; z-index: 1000; background: var(--surface); color: var(--ink);
  border: 1px solid rgba(31, 107, 70, .35); border-radius: 12px;
  box-shadow: 0 14px 36px rgba(18, 53, 42, .18); padding: 6px;
}
.pk-date-wrap { position: relative; display: inline-flex; align-items: center; max-width: 100%; }
.fields label.wide .pk-date-wrap, .pk-date-wrap:has(> input[style*="width: 100%"]) { width: 100%; }
.pk-date-wrap > input.pk-date { padding-right: 38px !important; width: 100%; }
input.pk-date::-webkit-calendar-picker-indicator { display: none; }
.pk-date-btn {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 28px; height: 28px;
  display: grid; place-items: center; border: 0; border-radius: 7px; background: transparent; color: var(--pos); cursor: pointer;
}
.pk-date-btn:hover { background: var(--sel); }
.pk-cal { width: 286px; padding: 12px; }
.pk-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.pk-cal-head b { font-size: 14px; text-transform: capitalize; }
.pk-cal-nav { width: 32px; height: 32px; border: 0; border-radius: 8px; background: var(--sel); color: var(--pos); font-size: 18px; font-weight: 800; cursor: pointer; }
.pk-cal-nav:hover { background: var(--pos); color: var(--on-pos); }
.pk-cal-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.pk-cal-months { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.pk-cal-wd { text-align: center; font-size: 11px; font-weight: 800; color: var(--ink-soft); text-transform: uppercase; padding: 4px 0; }
.pk-cal-cell { height: 34px; border: 0; border-radius: 8px; background: transparent; color: var(--ink); font: inherit; font-size: 13px; cursor: pointer; text-transform: capitalize; }
.pk-cal-cell:hover { background: var(--sel); color: var(--pos); }
.pk-cal-cell.pk-today { box-shadow: inset 0 0 0 1.5px var(--pos); color: var(--pos); font-weight: 800; }
.pk-cal-cell.pk-on { background: var(--pos); color: var(--on-pos); font-weight: 800; }
.pk-cal-cell[disabled] { opacity: .35; cursor: default; }
.pk-cal-foot { display: flex; justify-content: space-between; margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.pk-cal-link { border: 0; background: transparent; color: var(--pos); font: inherit; font-size: 13px; font-weight: 800; cursor: pointer; padding: 4px 6px; border-radius: 6px; }
.pk-cal-link:hover { background: var(--sel); }

/* pack.js about(): a collapsed explainer, Show/Hide and chevron by [open]. */
.pk-about > summary { list-style: none; }
.pk-about > summary::-webkit-details-marker { display: none; }
.pk-about .pk-about-hide { display: none; }
.pk-about[open] .pk-about-hide { display: inline; }
.pk-about[open] .pk-about-show { display: none; }
.pk-about .pk-about-chev { transition: transform .15s; }
.pk-about[open] .pk-about-chev { transform: rotate(180deg); }
.pk-about > summary:focus-visible { outline: 2px solid var(--pos,#1f6b46); outline-offset: 2px; border-radius: 10px; }
