/* Clarity Planner - one stylesheet, no inline styles anywhere (strict CSP). */

:root {
  --paper: #F7F8F6;
  --surface: #FFFFFF;
  --ink: #16202B;
  --ink-soft: #4E5B69;
  --ink-faint: #7A8591;
  --rule: #CBD3DC;
  --rule-soft: #E1E6EC;
  /* ---- CHROME: the page itself. Lifted from PC Site Manager, because this
     product is sold on its own AND folded into both Site Managers later, and
     a fold-in should be a lift rather than a rebuild.

     Its rule comes with it, and it is the important part: CHROME CARRIES NO
     MEANING. Everything here is slate, so every colour left on a screen is
     saying something. Clarity broke that rule from the start - the buttons,
     links, focus rings and badges were all #2F5D85, which is ALSO the default
     colour of an ordinary task bar and is a colour the customer can change.
     A button and a task were the same blue, and a company that set its bars
     green would have had chrome that no longer matched anything. */
  --chrome: #2E3438;            /* the top bar */
  --chrome-light: #4A5257;      /* a primary button */
  --chrome-rule: #6B7A82;
  --accent: #2C4A63;            /* PC Site Manager's navigation blue: links,
                                   focus, the active state of a toggle */
  --accent-soft: #9DB1C4;
  --accent-wash: #E8EDF2;

  /* ---- STATUS: reserved, exactly as the suite reserves them. Green means
     done or all-clear and nothing else; never use one for chrome. */
  --ok: #17612B;
  --ok-wash: #DCEBD6;
  --warn: #B85F0A;
  --warn-wash: #F7EEDC;
  --sel: #FFF6D6;

  /* ---- THE CHART: the one place colour is the answer rather than the
     decoration. These are defaults only - a company sets its own in Settings,
     and chart.js writes them onto the bars as attributes. Nothing in this
     file may use them for chrome. */
  --bar: #2F5D85;
  --crit: #A63626;
  --crit-wash: #F6E6E3;
  --mile: #A9781F;
  /* APTOS FIRST, with a close fallback chain. Paul asked for it, 2026-09-13.
     It is Microsoft's newer default and a good humanist sans - but it ships
     with Office and recent Windows rather than being a web font: it is not on
     Google Fonts and is not licensed for general web embedding, so a customer
     on a Mac, a phone, or an older PC gets the fallback. The chain is chosen
     so that fallback still looks like the same design rather than a different
     one: Segoe UI Variable and Segoe UI are its closest relatives, then
     whatever the system calls its UI face.

     The numbers keep their own variable only so that TABULAR FIGURES can be
     forced on everywhere they are used - in a column of dates, digits that do
     not line up are worse than any choice of typeface. */
  --sans: Aptos, "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: Aptos, "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
}

/* Everything that shows a number, a date or a reference: same face as the
   rest, figures the same width so columns align. */
.mono, .grid td.c-ref, .grid td.c-date, .grid td.c-float, .grid td.c-slip,
.cell.c-dur-in, .cell.c-pct-in, .cell.c-date-in, .cell.c-snet-in, .cell.c-pred-in,
.props-facts dd, .pred-lag input, .pred-pick-ref, .colophon, .foot,
.flow-n, .step-no, .eyebrow, .tb-key {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

* { box-sizing: border-box; }
html { font-size: 15px; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.45;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
a { color: var(--accent); }
b, strong { font-weight: 600; }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-faint); }
.num { text-align: right; }
.hint { font-weight: 400; color: var(--ink-faint); font-size: 0.85em; }
[hidden] { display: none !important; }

/* ---- chrome ---- */
.progbar { display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap; padding: 0.55rem 1.5rem;
  background: var(--surface); border-bottom: 1px solid var(--rule); }
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; list-style: none; margin: 0; padding: 0; font-size: 0.92rem; color: var(--ink-soft); }
.crumbs li + li::before { content: "\203A"; margin-right: 0.35rem; color: var(--ink-faint); }
.crumbs a { color: var(--accent); }
.crumbs [aria-current="page"] { color: var(--ink); font-weight: 600; }
.progbar .progbar-reports { margin-left: auto; }
.progbar .progbar-reports .view-panel { right: 0; left: auto; }
.export-list a.is-here { background: var(--accent-wash); }
/* A page inside a programme already says which programme in its bar. */
.has-progbar .prog-head .eyebrow:has(> a:only-child) { display: none; }
/* A PDF in the app (v0.91.0). */
.pdf-view-actions { display: flex; gap: 0.6rem; align-items: center; }
.pdf-view-actions .button { display: inline-block; text-decoration: none; }
.pdf-frame { display: block; width: 100%; height: calc(100vh - 15rem); min-height: 28rem; border: 1px solid var(--rule); background: #fff; }
.foot { margin-top: auto; padding: 1rem 1.25rem; font-family: var(--mono); font-size: 0.72rem; color: var(--ink-faint); }
/* On the planner the chart is measured down to the top of this bar, so every
   pixel of it is a pixel of programme nobody can see. Same words, half the
   height - it is a version number, not a section of the page.

   AND NO `margin-top: auto` HERE. That is what pins the footer to the bottom
   of a short page everywhere else, and on the planner it caused a loop: the
   auto margin swallows the free space, so the gap between the chart and the
   footer GROWS as the chart shrinks - and the chart is measured from that
   gap. Each pass made the chart smaller and the empty band below it bigger,
   settling with half the window blank. The footer sits directly under the
   chart here, which is where it belongs on a page that always fills the
   screen. */
main.page-wide + .foot { padding: 0.3rem 1.25rem; }
/* THE AUTO MARGIN IS BACK, ON PURPOSE. It was taken off on 2026-09-15 to stop
   a loop: the footer's `margin-top: auto` swallowed the free space, the gap
   below the chart grew as the chart shrank, and the chart was measured from
   the gap. Taking it off stopped the loop and left a new fault - on a short
   page the footer stops in the middle of the screen with dead page beneath
   it, which is what Paul was looking at when he said "the footer is still not
   correct".
   The loop is no longer possible: fitPane clamps the gap it measures, so an
   auto margin cannot inflate it whatever the stylesheet says. With the loop
   closed at the other end, the footer can go back to sitting where a footer
   should - at the bottom. */

.page { width: min(64rem, 100% - 2.5rem); margin: 1.5rem auto 2rem; }
/* The planner fills whatever screen it is on - a laptop or a 32" desk
   monitor - because every extra inch is more programme you can see at once. */
.page-wide { width: calc(100% - 2rem); max-width: none; margin: 1.1rem auto 1.2rem; }
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.page-head h1 { margin: 0; font-size: 1.55rem; font-weight: 700; letter-spacing: -0.01em; }
.head-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: flex-end; }
@media (max-width: 600px) { .page-head:has(.head-actions) { flex-wrap: wrap; } .head-actions { justify-content: flex-start; } }
.eyebrow { margin: 0 0 0.1rem; font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
.lede-text { max-width: 50rem; color: var(--ink-soft); margin: 0 0 1.2rem; }
.empty { color: var(--ink-soft); padding: 2rem 0; }

.card { background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 1rem 1.2rem; margin-bottom: 1.2rem; }
.card h2 { margin: 0 0 0.35rem; font-size: 1.1rem; }
.new-card > summary { cursor: pointer; font-weight: 600; color: var(--accent); list-style: none; }
.new-card > summary::-webkit-details-marker { display: none; }
.new-card[open] > summary { margin-bottom: 0.8rem; }

/* ---- forms ---- */
label { display: block; font-size: 0.86rem; font-weight: 600; color: var(--ink-soft); }
label input, label select, label textarea {
  display: block; width: 100%; margin-top: 0.25rem;
  font: inherit; font-weight: 400; color: var(--ink);
  padding: 0.42rem 0.55rem; border: 1px solid var(--rule); border-radius: 3px; background: #fff;
}
label input:focus, label select:focus, .cell:focus, button:focus-visible, a:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem 1rem; max-width: 40rem; }
.span-2 { grid-column: span 2; }
.form-actions { display: flex; gap: 0.6rem; align-items: center; }
.form-row { display: flex; gap: 0.8rem; align-items: flex-end; flex-wrap: wrap; margin-top: 0.8rem; }
.form-row .grow { flex: 1 1 14rem; }
.inline-form { display: inline; }
.weekdays { border: 1px solid var(--rule-soft); border-radius: 3px; padding: 0.5rem 0.8rem; display: flex; gap: 0.9rem; flex-wrap: wrap; }
.weekdays legend { font-size: 0.86rem; font-weight: 600; color: var(--ink-soft); }
.check { display: inline-flex; align-items: center; gap: 0.3rem; font-weight: 400; }
.check input { width: auto; margin: 0; }

.button, .button-secondary {
  font: inherit; font-weight: 600; font-size: 0.9rem;
  padding: 0.45rem 0.9rem; border-radius: 3px; cursor: pointer;
  border: 1px solid var(--chrome-light); background: var(--chrome-light); color: #fff;
}
.button-secondary { background: #fff; color: var(--accent); border-color: var(--accent-soft); }
.button-secondary:hover { background: var(--accent-wash); }
.button-secondary.danger { color: var(--crit); border-color: #E2B8B1; }
.button-secondary.danger:hover { background: var(--crit-wash); }
.link-button { font: inherit; background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; text-decoration: underline; }
/* The programmes list (v0.91.0): an Open button on every row, the name the
   way in, the whole row clickable, archive kept quiet at the side. */
.prog-list .prog-row { cursor: pointer; }
.prog-list .prog-row:hover td { background: var(--accent-wash); }
/* The programme's name is the button that opens it (v0.92.0). */
.prog-name-btn { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.42rem 0.85rem; border: 1px solid var(--accent-soft);
  border-radius: 4px; background: var(--accent-wash); color: var(--accent); font-weight: 600; font-size: 1rem; line-height: 1.3;
  text-decoration: none; }
.prog-name-btn .prog-go { font-weight: 700; transition: transform 0.12s ease; }
.prog-name-btn:hover, .prog-name-btn:focus, .prog-list .prog-row:hover .prog-name-btn { background: var(--accent); border-color: var(--accent); color: #fff; }
.prog-name-btn:hover .prog-go, .prog-list .prog-row:hover .prog-name-btn .prog-go { transform: translateX(2px); }
.prog-name-btn.small { padding: 0.2rem 0.6rem; font-size: 0.92rem; }
@media (prefers-reduced-motion: reduce) { .prog-name-btn .prog-go { transition: none; } }
.link-button.quiet-link { color: var(--ink-faint); font-size: 0.85rem; }
.link-button.quiet-link:hover { color: var(--crit); }
.link-button.danger { color: var(--crit); }
.error { color: var(--crit); background: var(--crit-wash); border-left: 3px solid var(--crit); padding: 0.5rem 0.8rem; border-radius: 2px; }

.badge { display: inline-block; font-size: 0.72rem; font-weight: 600; padding: 0.08rem 0.45rem; border-radius: 2px; background: var(--accent-wash); color: var(--accent); vertical-align: middle; }
.badge-ok { background: var(--ok-wash); color: var(--ok); }
.badge-off { background: var(--rule-soft); color: var(--ink-soft); }
.badge-warn { background: var(--warn-wash); color: #7A5410; }

/* ---- list tables ---- */
.list-table { width: 100%; border-collapse: collapse; background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; }
.list-table th, .list-table td { text-align: left; padding: 0.55rem 0.8rem; border-bottom: 1px solid var(--rule-soft); }
.list-table th { font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; }
/* A table wider than a phone scrolls INSIDE itself, not the page. The
   programmes list alone pushed the page 176px past the edge at 375px. Scoped
   to narrow screens only: on a desktop these tables fit, and `display: block`
   on a table changes how its border sits, so it is not applied where it is
   not needed. */
@media (max-width: 600px) {
  .list-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}
.list-table tbody tr:last-child td { border-bottom: 0; }
.list-table.compact th, .list-table.compact td { padding: 0.35rem 0.6rem; }
/* Offline, waiting progress and the update prompt (v0.89.0) */
.netbar { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; padding: 0.5rem 1rem; font-size: 0.9rem; border-bottom: 1px solid var(--rule); background: var(--surface); color: var(--ink); }
.netbar[hidden] { display: none; }
.netbar .button { padding: 0.2rem 0.8rem; }
.netbar-off { background: #FFF4D6; color: #5A4300; border-bottom-color: #E8C766; }
.netbar-new { background: var(--accent-wash); }
.netbar-ok { background: #E6F4EA; color: #1F5130; border-bottom-color: #A9D5B5; }
tr.row-waiting td.c-pct, tr.row-waiting td.c-date.actual { box-shadow: inset 0 -2px 0 #E0A800; }
.offline-card { max-width: 38rem; }
/* Pictures in the help (v0.93.0): kept at twice their shown size, never
   stretched, shrinking only to fit a narrow window. */
.help-shot { margin: 0.6rem 0 1rem; }
.help-shot img { display: block; max-width: 100%; height: auto; border: 1px solid var(--rule); border-radius: 4px; }
.help-shot figcaption { margin-top: 0.3rem; }
/* Use it as an app (v0.92.0) - the same card as PC Site Manager's. */
.pin-edge { display: none; }
.app-edge .pin-edge { display: block; }
.app-edge .pin-chrome { display: none; }
.install-pin-tip { display: flex; gap: 12px; align-items: center; justify-content: space-between; border-left: 4px solid #2E8B4F;
  margin: 0.75rem 1.5rem 0; }
.install-pin-tip p { margin: 0; }
/* THE PROGRAMME PAGE GIVES ITS ROOM TO THE CHART (v0.93.0) ------------------- */
.ico { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vertical-align: middle; flex: none; }
.icon-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem; min-width: 2.1rem; padding: 0.32rem 0.45rem; }
.icon-btn .icon-word { font-size: 0.85rem; }
.icon-btn .ico-count { font-size: 0.78rem; font-weight: 700; }
.letter-btn { min-width: 1.9rem; padding: 0.32rem 0.4rem; font-weight: 700; text-align: center; }
.toolbar-spacer { flex: 1 1 0; min-width: 0.5rem; }
.toolbar-help { align-self: center; }
.find-box.find-slim { width: 7.5rem; }
.lookahead-bar .lookahead-lbl { font-size: 0.68rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); }
.programme-page .grid-toolbar { gap: 0.4rem 0.7rem; margin-bottom: 0.4rem; flex-wrap: wrap; }
.programme-page .toolbar-group { gap: 0.25rem; }
/* menus at the right-hand end drop down leftwards, inside the window */
.programme-page .grid-toolbar .view-menu .view-panel, .programme-page .grid-toolbar .print-panel,
.programme-page .grid-toolbar .issues-list > table, .programme-page .grid-toolbar .issue-form { right: 0; left: auto; }
/* THE KEY, ALL ON ONE SCREEN (v0.99.0). Paul, 2026-10-03: "when you click on
   the key button ... I don't think you should need to use your screen bars to
   drag ... Everything should fit onto one page". .view-panel (later in this
   file) held it to 25rem with a scroll box, and the key's lines do not wrap,
   so the long ones ran off the right edge behind a sideways scroll bar. Now
   it is wide, laid out in columns, every line wraps, and it never scrolls. */
.view-panel.legend-panel { width: min(48rem, calc(100vw - 2rem)); max-height: none; overflow: visible; }
.legend-panel .legend-list { margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr)); gap: 0.4rem 1.2rem; }
.legend-panel .legend-list li { white-space: normal; align-items: flex-start; line-height: 1.3; }
.legend-panel .legend-list li > :first-child { flex: none; margin-top: 0.15rem; }
.legend-panel .legend-list li.is-long { grid-column: 1 / -1; }
.baseline-row { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin: 0 0 0.6rem; padding-bottom: 0.6rem; border-bottom: 1px solid var(--rule); }

/* the title line: name and revision | the two chips | logo and Settings */
.programme-page .prog-head { align-items: center; gap: 0.6rem 1.2rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.programme-page .prog-head .prog-title { display: flex; align-items: baseline; gap: 0.3rem 0.8rem; flex-wrap: wrap; flex: 0 1 auto; }
.programme-page .prog-head .eyebrow { margin: 0; }
.programme-page .prog-head h1 { font-size: 1.25rem; }
.programme-page .prog-head .rev-line { margin: 0; }
.programme-page .prog-head .prog-side { flex-direction: row; align-items: center; gap: 0.8rem; }
.prog-facts { color: var(--ink-soft); font-size: 0.82rem; margin: 0 0 0.3rem; }
.prog-status { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; flex: 1 1 auto; }
.prog-status > details { position: relative; margin: 0; padding: 0; border: 0; background: none; }
.prog-status > details > summary.chip-sum { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.85rem; font-weight: 600; padding: 0.22rem 0.65rem; border: 1px solid var(--rule); border-radius: 999px; background: var(--surface); white-space: nowrap; }
.prog-status > details > summary.chip-sum::-webkit-details-marker { display: none; }
.prog-status > details > summary.chip-sum .week-sum { margin: 0; font-size: 0.85rem; }
.prog-status > details > summary.chip-sum .step-badge { font-size: 0.8rem; padding: 0.05rem 0.45rem; }
.prog-status > details[open] > summary.chip-sum { border-color: var(--accent-soft); background: var(--accent-wash); }
.prog-status > details.chip-alert > summary.chip-sum { border-color: var(--crit); box-shadow: 0 0 0 2px #F6D5D0; }
.prog-status .chip-panel { position: absolute; top: calc(100% + 0.35rem); left: 0; z-index: 30; width: min(46rem, 92vw); max-height: 70vh; overflow: auto;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 0.8rem 1rem; box-shadow: 0 8px 24px rgba(20, 30, 40, 0.14); }
.chip-panel-head { margin: 0 0 0.6rem; display: flex; gap: 0.5rem; align-items: baseline; flex-wrap: wrap; }
.chip-close { margin-left: auto; font: inherit; font-size: 1.25rem; line-height: 1; border: 0; background: none; color: var(--ink-soft); cursor: pointer; padding: 0 0.25rem; }
.chip-close:hover, .chip-close:focus-visible { color: var(--ink); }

/* the chart, the whole window */
html.chart-focus body.programme-page .cbar, html.chart-focus body.programme-page .prog-head,
html.chart-focus body.programme-page .foot { display: none; }
[data-act="chart-focus"][aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #fff; }

/* a short screen: tighter still */
@media (max-height: 820px) {
  .programme-page .page { padding-top: 0.5rem; }
  .programme-page .cbar { height: 48px; }
  .programme-page .grid-toolbar .button, .programme-page .grid-toolbar .button-secondary { padding-top: 0.25rem; padding-bottom: 0.25rem; }
}
/* Saved documents, type by type (v0.88.0) */
.docs-by-type .docs-type-head th { background: var(--accent-wash); text-align: left; font-size: 0.85rem; padding-top: 0.5rem; }
.docs-type-code { font-family: ui-monospace, Consolas, monospace; font-weight: 600; margin-left: 0.35rem; }
.docs-ref { white-space: nowrap; font-weight: 600; }
.list-table tr.muted td { color: var(--ink-faint); }

/* ---- login ---- */
/* the sign-in pages in the Clarity bar's dark, with the app's own icon (v1.1.01) */
.login-body { background: var(--cbar-bg, #17231C); }
.login-main { margin: 12vh auto 0; width: min(24rem, 100% - 2rem); }
.login-card { background: var(--surface); border-radius: 6px; padding: 1.6rem 1.7rem 1.8rem; display: grid; gap: 0.9rem; }
.login-brand { margin: 0 0 0.2rem; font-size: 1.25rem; color: var(--ink); display: flex; align-items: center; gap: 0.6rem; }
.login-brand img { display: block; border-radius: 9px; }
.login-brand strong { font-weight: 700; }
.login-card h1 { margin: 0; font-size: 1.4rem; }
.login-card .button { margin-top: 0.3rem; }
/* The quiet line under a sign-in card: "Forgotten your password?", "Back to
   sign in". Deliberately smaller and softer than the button above it - it is
   the way out for the one person in twenty who needs it, not a second thing
   to weigh up against signing in. */
.login-aside { margin: 0.2rem 0 0; font-size: 0.86rem; color: var(--ink-soft); }
.login-aside a { color: var(--ink-soft); }
.login-aside a:hover { color: var(--accent); }
/* The remove control on a long editable list: an x that is quiet until the
   row is hovered. Forty rows each ending in the word "remove" read as a
   column of removes, louder than the names beside them. */
.first-time { margin: 0.2rem 0 1rem; font-size: 1.02rem; }
.remove-x { font-size: 1.05rem; line-height: 1; padding: 0 0.3rem; opacity: 0.45; }
.type-item:hover .remove-x, .remove-x:focus-visible { opacity: 1; }

/* A cell that must stay on one line - the record page's timestamps.
   The class was on the markup from the start; the rule was not. */
.nowrap { white-space: nowrap; }

/* ---- two-factor sign-in ---- */
/* The QR is inline SVG, so it is sized here rather than by an attribute.
   A fixed max-width keeps it scannable on a phone without swallowing the
   card on a laptop. */
.qr { display: flex; justify-content: center; padding: 0.4rem 0; }
.qr svg { width: 100%; max-width: 15rem; height: auto; }
.qr-manual { font-size: 0.86rem; color: var(--ink-soft); }
.qr-manual > summary { cursor: pointer; color: var(--accent); }
.secret { font-size: 0.95rem; letter-spacing: 0.06em; word-break: break-all; margin: 0.4rem 0 0; }
/* The recovery codes. Two columns so eight of them read as a block somebody
   can photograph or copy in one go, and tabular figures so they line up. */
.codes {
  list-style: none; margin: 0.3rem 0 0; padding: 0.8rem 1rem;
  background: var(--surface-sunk, rgba(0, 0, 0, 0.04)); border-radius: 5px;
  /* Columns sized to a CODE, not to the container. repeat(2, 1fr) looked
     right inside the narrow sign-in card and stretched to a 437px column on
     the wider account page, with a fourteen-character code adrift in each.
     Counted rather than auto-fit: eight codes want to land as 4 + 4, and
     auto-fit kept choosing 3 or 5 depending on where the rounding fell. */
  display: grid; grid-template-columns: repeat(4, 9.5rem);
  justify-content: start; gap: 0.35rem 1.4rem;
  font-family: var(--mono); font-size: 0.95rem; letter-spacing: 0.06em;
  /* Figures the same width, so eight codes line up as a block rather than
     ragging. The house --mono is not actually monospaced - what stops a code
     being misread is the ALPHABET it is drawn from, which has no 0/O and no
     1/I/L in it (app/mfa.py). */
  font-variant-numeric: tabular-nums;
}
@media (max-width: 52rem) { .codes { grid-template-columns: repeat(2, 9.5rem); } }
@media (max-width: 26rem) { .codes { grid-template-columns: 1fr; } }

/* ---- programme page ---- */
.prog-head { align-items: flex-start; }
.prog-meta { display: flex; gap: 1.2rem; align-items: center; font-size: 0.82rem; color: var(--ink-soft); flex-wrap: wrap; }
.settings-menu { position: relative; }
.settings-menu > summary { cursor: pointer; color: var(--accent); font-family: var(--sans); font-weight: 600; list-style: none; }
.settings-menu > summary::-webkit-details-marker { display: none; }
/* The panel floats; everything inside it is in flow, so nothing can land on
   anything else however the form grows (v0.95.01). Taller than the window? It
   scrolls inside itself. */
.settings-panel { position: absolute; right: 0; top: 1.6rem; z-index: 5; background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 1rem; width: 34rem; max-width: 88vw; max-height: calc(100vh - 7rem); overflow-y: auto; box-shadow: 0 8px 24px rgba(22, 32, 43, 0.12); font-family: var(--sans); box-sizing: border-box; }
.settings-panel .copy-block { margin-top: 0.9rem; padding-top: 0.7rem; border-top: 1px solid var(--rule); }
.settings-panel .copy-block > .settings-form { margin-top: 0.6rem; }
.settings-archive { margin-top: 0.9rem; padding-top: 0.7rem; border-top: 1px solid var(--rule); text-align: right; font-family: var(--sans); }

.notice { margin: 0 0 0.8rem; padding: 0.55rem 0.9rem; border-radius: 3px; border-left: 3px solid var(--crit); background: var(--crit-wash); color: var(--crit); font-size: 0.92rem; }
.notice.ok { border-left-color: var(--ok); background: var(--ok-wash); color: var(--ok); }
/* Somebody else holds the programme. Amber, not red: nothing is wrong, it is
   simply somebody else's turn. */
.notice.hold { border-left-color: var(--warn); background: var(--warn-wash); color: #5C4712; display: flex; gap: 0.9rem; align-items: center; flex-wrap: wrap; }
.notice.hold b { color: #3F3110; }
.hold-actions { margin-left: auto; }
.seats-form input[type="number"] { width: 4rem; font: inherit; padding: 0.15rem 0.3rem; border: 1px solid var(--rule); border-radius: 3px; text-align: right; }

.grid-toolbar { display: flex; gap: 0.5rem 1.2rem; align-items: center; margin-bottom: 0.6rem; flex-wrap: wrap; }
.toolbar-group { display: inline-flex; gap: 0.4rem; align-items: center; }
/* SHRINKS, NEVER WRAPS. The hint shares one row with the buttons now, and a
   hint that wrapped to its own line would hand back the 60px the merge was
   done to save. It takes what room is left and ellipsises. */
.toolbar-hint {
  margin-left: auto; font-size: 0.8rem; color: var(--ink-faint);
  flex: 1 1 8rem; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.toolbar-hint .mono { font-size: 0.78rem; }
.zoom-bar .zoom.active { background: var(--accent); color: #fff; border-color: var(--accent); }
/* A menu entry that is not available yet, with its reason in the small line
   under it. Never hidden: a control that vanishes is a control nobody learns. */
.export-list .is-off { display: block; padding: 0.3rem 0.4rem; font-size: 0.88rem; font-weight: 600; color: var(--ink-faint); cursor: not-allowed; }
.export-list .is-off span { display: block; font-weight: 400; font-size: 0.78rem; color: var(--ink-faint); }
/* The merged Print & export panel carries a form AND three lists, so it is a
   little wider than the old print-only one. */
.print-panel.wide { width: 24rem; }
.print-form { display: grid; gap: 0.4rem; margin-bottom: 0.5rem; }

/* ---- the properties panel, to the left of the table ---- */
/* The properties panel lives inside the row menu now - see grid.js. The
   sidebar it used to be cost about 300px of window whether anything was
   selected or not, which on a laptop was most of the chart. */
.props-panel {
  border: 0; border-top: 1px solid var(--rule-soft);
  margin: 0.25rem -0.25rem -0.25rem; padding: 0.45rem 0.6rem 0.5rem;
  display: flex; flex-direction: column;
}
.props-head {
  display: flex; align-items: center; gap: 0.4rem;
  padding: 0.5rem 0.6rem 0.5rem 0.85rem; border-bottom: 1px solid var(--rule-soft);
  position: sticky; top: 0; background: var(--surface); z-index: 2;
}
.props-head h2 { margin: 0; font-size: 0.95rem; flex: 1; min-width: 0; }
.props-collapse {
  flex: none; width: 1.5rem; height: 1.5rem; padding: 0; line-height: 1;
  border: 1px solid var(--rule); background: #fff; color: var(--ink-soft);
  border-radius: 3px; cursor: pointer; font-size: 0.85rem;
}
.props-collapse:hover { background: var(--accent-wash); color: var(--accent); }
#props-body { padding: 0.7rem 0.85rem 1rem; display: flex; flex-direction: column; gap: 0.75rem; }
.props-names { margin: 0; font-size: 0.85rem; color: var(--ink-soft); max-width: none; }
.props-field { display: flex; flex-direction: column; gap: 0.2rem; }
.props-label { font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); }
.props-field input, .props-field textarea {
  width: 100%; font: inherit; font-size: 0.88rem; color: var(--ink);
  padding: 0.32rem 0.45rem; border: 1px solid var(--rule); border-radius: 3px; background: #fff;
}
.props-field textarea { resize: vertical; }
.props-row { display: flex; gap: 0.6rem; }
.props-row .props-field { flex: 1; }

.props-patterns { border: 1px solid var(--rule-soft); border-radius: 3px; padding: 0.45rem 0.6rem 0.6rem; margin: 0; display: grid; gap: 0.35rem; }
.props-patterns legend { font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); padding: 0 0.25rem; }
.pattern-opt {
  display: grid; grid-template-columns: 1.1rem 1fr; gap: 0 0.4rem;
  font-weight: 400; cursor: pointer; padding: 0.25rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.props-patterns .pattern-opt:last-of-type { border-bottom: 0; }
.pattern-opt input { grid-row: span 2; margin: 0.2rem 0 0; width: auto; }
.pattern-name { font-size: 0.85rem; font-weight: 600; color: var(--ink); }
.pattern-blurb { font-size: 0.76rem; color: var(--ink-faint); line-height: 1.35; }

.props-facts { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 0.15rem 0.6rem; font-size: 0.82rem; }
.props-facts dt { color: var(--ink-faint); }
.props-facts dd { margin: 0; font-family: var(--mono); font-size: 0.78rem; color: var(--ink); }

/* type of activity, in the grid and in the panel */
.grid th.c-type, .grid td.c-type { width: 8.6rem; }
.grid td.c-type { padding: 0; }
/* Who is doing the work, beside what kind of work it is. Wider than the
   trade column because a firm's name is longer than a trade's - "Groundforce
   Foundations Ltd" against "Piling". Same control in every other way. */
.grid th.c-firm, .grid td.c-firm { width: 8.6rem; }   /* 128px - keep in step with DEFAULTS in columns.js */
.grid td.c-firm { padding: 0; }
.cell.c-type-in, .cell.c-firm-in {
  width: 100%; height: 2rem; border: 0; background: transparent;
  font: inherit; font-size: 0.82rem; color: var(--ink-soft); padding: 0 0.35rem;
  appearance: none; -webkit-appearance: none; cursor: pointer;
}
.cell.c-type-in:focus, .cell.c-firm-in:focus { outline: 2px solid var(--accent); outline-offset: -2px; background: #fff; }
/* The trade and contractor cells until they are used (v0.90.0): a button that
   reads exactly like the drop-down it becomes on a click. */
.cell.list-cell { display: block; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cell.c-type-in:disabled, .cell.c-firm-in:disabled { color: var(--ink-faint); cursor: default; }
.inline-select { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
.inline-select select { width: auto; margin: 0; padding: 0.3rem 0.4rem; font-size: 0.84rem; font-weight: 400; border: 1px solid var(--rule); border-radius: 3px; background: #fff; color: var(--ink); }

/* the length + unit pair, and the colour row, in the properties panel */
.props-unit { display: flex; gap: 0.3rem; align-items: center; }
.props-unit input[type="number"] { flex: 1; min-width: 0; }
.props-unit input[type="color"] { width: 2.4rem; height: 1.9rem; padding: 1px; border: 1px solid var(--rule); border-radius: 3px; background: #fff; cursor: pointer; }
.props-unit-sel { flex: 0 0 5rem; font-size: 0.82rem; padding: 0.3rem 0.2rem; border: 1px solid var(--rule); border-radius: 3px; background: #fff; }
.props-field select { width: 100%; font: inherit; font-size: 0.86rem; padding: 0.3rem 0.4rem; border: 1px solid var(--rule); border-radius: 3px; background: #fff; color: var(--ink); }
.props-inert { color: var(--crit); }

/* the predecessor editor */
.props-preds { border: 1px solid var(--rule-soft); border-radius: 3px; padding: 0.45rem 0.6rem 0.6rem; margin: 0; display: grid; gap: 0.5rem; }
.props-preds legend { font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); padding: 0 0.25rem; }
.pred-row { display: grid; gap: 0.25rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--rule-soft); }
.props-preds .pred-row:last-of-type { border-bottom: 0; padding-bottom: 0; }
.pred-row select, .pred-row input { width: 100%; font: inherit; font-size: 0.82rem; padding: 0.25rem 0.35rem; border: 1px solid var(--rule); border-radius: 3px; background: #fff; color: var(--ink); }
.pred-task { font-family: var(--mono); }
.pred-how { color: var(--accent); }
.pred-lag { display: flex; gap: 0.25rem; }
.pred-lag input { flex: 0 0 3.6rem; font-family: var(--mono); text-align: right; }
.pred-lag select { flex: 1; }
.pred-drop { justify-self: end; font-size: 0.78rem; }
.pred-add { width: 100%; font-size: 0.82rem; padding: 0.3rem 0.35rem; border: 1px dashed var(--accent-soft); border-radius: 3px; background: var(--accent-wash); color: var(--accent); }

/* settings: types and colours */
.type-list { list-style: none; margin: 0.8rem 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 0.3rem 0.9rem; }
.type-item { display: flex; align-items: center; gap: 0.4rem; border-bottom: 1px solid var(--rule-soft); padding: 0.15rem 0; }
.type-rename { flex: 1; min-width: 0; }
/* contractors carry an email too: give each its room (v1.1.01) */
.type-list.contractor-list { grid-template-columns: repeat(auto-fill, minmax(27rem, 1fr)); }
.contractor-list .type-rename { flex: 0 0 42%; }
.contractor-list .type-email { flex: 1; min-width: 0; }
.contractor-list .type-email input { width: 100%; box-sizing: border-box; font: inherit; font-size: 0.86rem; padding: 0.2rem 0.3rem; border: 1px solid var(--rule-soft); border-radius: 3px; }
.brand-colour-row input[type="color"] { width: 3rem; height: 2rem; padding: 2px; border: 1px solid var(--rule); border-radius: 4px; background: #fff; cursor: pointer; flex: none; }
.type-rename input { width: 100%; font: inherit; font-size: 0.86rem; border: 1px solid transparent; background: transparent; padding: 0.2rem 0.3rem; border-radius: 3px; color: var(--ink); }
.type-rename input { border-color: var(--rule-soft); }
.type-rename input:hover { border-color: var(--rule); background: #fff; }
.rename-hint { margin: 0.4rem 0 0; }
.type-rename input:focus { border-color: var(--accent); background: #fff; outline: none; }
.type-item .link-button { font-size: 0.76rem; opacity: 0; }
/* The x is quietly THERE at rest - the older rule above faded the whole
   control to nothing until hover, which is not what was agreed: a small x
   on each row, the word only on hover (its title). */
.type-item .link-button.remove-x { opacity: 0.45; }
/* The bank-holiday table: one column per calendar, headed by its name. */
.bh-cal { max-width: 8rem; white-space: normal; }
.bh-tick { white-space: nowrap; }
.bh-line { display: flex; gap: 0.6rem; align-items: baseline; flex-wrap: wrap; }
.tbl { overflow-x: auto; }
.type-item:hover .link-button, .type-item .link-button:focus-visible { opacity: 1; }
.archive-card > summary { cursor: pointer; font-weight: 600; color: var(--ink-soft); list-style: none; }
.archive-card > summary::-webkit-details-marker { display: none; }
.archive-card[open] > summary { margin-bottom: 0.6rem; }
.archive-actions { display: flex; gap: 0.8rem; justify-content: flex-end; align-items: baseline; }
.delete-menu { position: relative; }
.delete-menu > summary { cursor: pointer; list-style: none; }
.delete-menu > summary::-webkit-details-marker { display: none; }
.delete-form {
  position: absolute; right: 0; top: 1.5rem; z-index: 20; width: 24rem; max-width: 88vw; text-align: left;
  background: var(--surface); border: 1px solid var(--crit); border-radius: 4px;
  padding: 0.8rem 0.9rem; box-shadow: 0 8px 24px rgba(22, 32, 43, 0.18);
}
.delete-form label { margin-top: 0.6rem; }
.retired-types { margin-top: 0.8rem; font-size: 0.88rem; }
.retired-types summary { cursor: pointer; color: var(--ink-soft); }
.colour-form { display: grid; gap: 0.5rem; max-width: 54rem; }
.colour-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 0.9rem; font-weight: 400; padding: 0.55rem 0; border-bottom: 1px solid var(--rule-soft); }
.colour-pick { display: flex; align-items: center; gap: 0.5rem; }
.colour-row input[type="color"] { width: 2.4rem; height: 1.9rem; padding: 1px; border: 1px solid var(--rule); border-radius: 3px; background: #fff; cursor: pointer; margin: 0; }
.colour-what { display: flex; flex-direction: column; }
.colour-name { font-weight: 600; color: var(--ink); font-size: 0.9rem; }
.colour-blurb { font-size: 0.84rem; color: var(--ink-soft); }
.colour-hatch select { font: inherit; font-size: 0.84rem; padding: 0.25rem 0.35rem; border: 1px solid var(--rule); border-radius: 3px; background: #fff; width: auto; margin: 0; }
.hatch-label { display: flex; align-items: center; gap: 0.35rem; font-size: 0.8rem; }
/* Three columns - swatches, name, hatch - need about 34rem. On a phone they
   stack; measured at 375px the rows ran 135px past the edge otherwise. */
@media (max-width: 600px) {
  .colour-row { grid-template-columns: 1fr; gap: 0.4rem; }
}

/* the swatch grid - the "standard" picker, with the native one beside it */
.swatches { display: grid; grid-template-columns: repeat(10, 1.05rem); gap: 2px; }
.props-field .swatches { grid-template-columns: repeat(10, 1fr); gap: 3px; margin-bottom: 0.35rem; }
.swatch {
  width: 100%; aspect-ratio: 1; min-height: 1.05rem; padding: 0;
  border: 1px solid rgba(0, 0, 0, 0.18); border-radius: 2px; cursor: pointer;
}
.swatch:hover { transform: scale(1.25); position: relative; z-index: 2; }
.swatch.chosen { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3.5px var(--ink); z-index: 1; }
.swatch:disabled { cursor: default; }
.swatch:disabled:hover { transform: none; }

/* folds in the properties panel */
.props-fold { border: 1px solid var(--rule-soft); border-radius: 3px; }
.props-fold > summary {
  cursor: pointer; list-style: none; padding: 0.4rem 0.55rem;
  display: flex; align-items: baseline; gap: 0.4rem;
}
.props-fold > summary::-webkit-details-marker { display: none; }
.props-fold > summary::before { content: "▸"; color: var(--ink-faint); font-size: 0.7rem; }
.props-fold[open] > summary::before { content: "▾"; }
.props-fold[open] > summary { border-bottom: 1px solid var(--rule-soft); }
.fold-title { font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); }
.fold-now { font-size: 0.78rem; color: var(--ink-faint); margin-left: auto; text-align: right; }
.props-fold .props-patterns, .props-fold > .props-field { border: 0; margin: 0; padding: 0.5rem 0.6rem; }
.props-fold > .props-field { padding-top: 0; }
.props-ownweek { border-top: 1px solid var(--rule-soft); padding-top: 0.5rem; margin-top: 0.2rem; }
.own-toggle { font-weight: 600; font-size: 0.84rem; }
.own-days { display: flex; flex-wrap: wrap; gap: 0.1rem 0.5rem; margin: 0.35rem 0 0.2rem; }
.day-check { font-size: 0.78rem; }

/* the predecessor sentence, and picking several at once */
.pred-says { margin: 0.2rem 0 0; font-size: 0.78rem; color: var(--ink-soft); line-height: 1.35; font-style: italic; }
.pred-adder { border: 1px dashed var(--accent-soft); border-radius: 3px; background: var(--accent-wash); }
.pred-adder > summary { cursor: pointer; list-style: none; padding: 0.3rem 0.5rem; font-size: 0.82rem; color: var(--accent); font-weight: 600; }
.pred-adder > summary::-webkit-details-marker { display: none; }
.pred-picker { background: var(--surface); padding: 0.4rem 0.5rem 0.5rem; display: grid; gap: 0.3rem; max-height: 15rem; overflow: auto; }
.pred-pick { display: grid; grid-template-columns: 1.1rem 2rem 1fr; gap: 0.3rem; align-items: baseline; font-size: 0.8rem; font-weight: 400; }
.pred-pick input { margin: 0; width: auto; }
.pred-pick-ref { font-family: var(--mono); font-size: 0.74rem; color: var(--ink-faint); text-align: right; }
.pred-go { margin-top: 0.3rem; font-size: 0.82rem; padding: 0.3rem 0.6rem; }

/* the panel's own stretch handle */
.props-panel { position: relative; }
/* The width grip belonged to the sidebar. The panel is a popover now and
   sizes itself to the window, so there is nothing left to drag. */
.props-grip { display: none; }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* the presentation view */
.present-sheet { background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 1.4rem 1.6rem 1.8rem; }
.present-title { margin-bottom: 1.1rem; }
.present-title h2 { margin: 0 0 0.2rem; font-size: 1.4rem; }
.present-title p { margin: 0; color: var(--ink-faint); font-size: 0.85rem; }
.present-wrap { display: flex; align-items: flex-start; overflow-x: auto; }
.present-grid { border-collapse: separate; border-spacing: 0; flex: none; width: 20rem; }
.present-grid th { height: 2.6rem; border-bottom: 1px solid var(--rule); }
.present-grid td { height: 2.3rem; padding: 0 0.7rem 0 0.2rem; border-bottom: 1px solid var(--rule-soft); vertical-align: middle; }
.present-name { font-size: 0.95rem; color: var(--ink); }
.present-section .present-name { font-weight: 700; }
.present-milestone .present-name { font-style: italic; color: var(--mile); }
.present-chart { flex: none; }
.present-head-wrap { border-bottom: 1px solid var(--rule); }
@media print {
  .no-print, .cbar, .foot { display: none !important; }
  .present-sheet { border: 0; padding: 0; }
  body { background: #fff; }
}

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.settings-page .setting { padding-bottom: 1rem; margin-bottom: 1rem; border-bottom: 1px solid var(--rule-soft); }
.settings-page .setting:last-of-type { border-bottom: 0; }
.settings-page h2 { font-size: 1.05rem; margin: 0 0 0.3rem; }
.settings-page .weekdays { margin-top: 0.6rem; }
label.narrow { max-width: 16rem; }

/* One scroller for both panes. The grid sticks to the left, both headers
   stick to the top, and the chart simply sits to the right at its full
   width - so vertical scroll is shared by construction. */
.planner { overflow: auto; border: 1px solid var(--rule); background: var(--surface); border-radius: 4px; max-height: calc(100vh - 16rem); position: relative;  }
.planner-inner { display: flex; align-items: flex-start; width: max-content; min-width: 100%; position: relative; }
/* table-layout: fixed so a column width is an instruction, not a suggestion -
   columns.js sets each one and the table's width is their sum. */
/* The grid column is what sticks to the left now, so the overview band's
   label sits above the table and scrolls with it. */
.grid-col { flex: none; position: sticky; left: 0; z-index: 3; background: var(--surface); box-shadow: 1px 0 0 var(--rule); }
.grid { border-collapse: separate; border-spacing: 0; table-layout: fixed; width: 56rem; background: var(--surface); }
.planner.chart-hidden .grid-col { width: 100%; box-shadow: none; }
.planner.chart-hidden .grid { width: 100%; }
.band-label {
  /* The height is set by chart.js to match the band exactly - it grows with
     the number of lines on it, because each lane now carries a task name. */
  height: 58px; box-sizing: border-box; display: flex; align-items: center;
  padding: 0 0.6rem; border-bottom: 1px solid var(--rule);
  background: #F4F6F8; font-size: 0.72rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-faint); font-weight: 600;
  position: sticky; top: 0; z-index: 5;
}
.present-band { display: block; position: sticky; top: 0; z-index: 1; border-bottom: 1px solid var(--rule); }
.band-bg { fill: #FAFBFC; }
.band-tick { stroke: var(--rule-soft); stroke-width: 1; }
.band-bar { }
.band-lbl { font-size: 10px; fill: var(--ink-soft); dominant-baseline: middle; pointer-events: none; }
/* The joins between critical bars are the links themselves, so they are drawn
   a shade lighter than the bars they connect - the work is the point, the
   dependency is how you got there. */
.ch-critjoin { stroke-width: 1.6; opacity: 0.75; }

/* the critical path, turned up by turning everything else down */
.ch-tie { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 2 2; }
.ch-span { pointer-events: none; }
.ch-link.critical { stroke: var(--crit); stroke-width: 1.8; }
.ch-critline { fill: none; stroke: #16A34A; stroke-width: 2.4; stroke-linejoin: round; stroke-linecap: round; pointer-events: none; }
.ch-critdot { fill: #16A34A; pointer-events: none; }
/* The path of works: the sequence, as one line - amber, so it is never mistaken for the critical path's green. */
.ch-pathline { fill: none; stroke: #D97706; stroke-width: 2.6; stroke-linejoin: round; stroke-linecap: round; pointer-events: none; }
.ch-pathdot { fill: #D97706; pointer-events: none; }
.ch-pathpivot { fill: none; stroke: #D97706; stroke-width: 2; pointer-events: none; }
.button-secondary.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* The column ticks. They live inside the View panel now, so they need no
   panel of their own - the two rules that used to give them one went with
   the Columns menu they belonged to. */
.cols-list { display: grid; gap: 0.15rem; }
.cols-item { font-size: 0.85rem; padding: 0.15rem 0; }

/* ONE VIEW MENU - the timescale, what the chart shows, which columns are on,
   and the key. Eleven controls that used to sit on the toolbar and push the
   programme itself below the fold. */
.view-menu { position: relative; }
.view-menu > summary { cursor: pointer; list-style: none; display: inline-block; }
.view-menu > summary::-webkit-details-marker { display: none; }
.view-menu[open] > summary { background: var(--accent-wash); border-color: var(--accent-soft); color: var(--accent); }
.view-panel {
  position: absolute; right: 0; top: 2.3rem; z-index: 30; width: 25rem; max-width: 88vw;
  max-height: 64vh; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 4px;
  padding: 0.75rem 0.85rem 0.9rem; box-shadow: 0 10px 30px rgba(22, 32, 43, 0.18);
}
.view-lbl {
  font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 600;
  color: var(--ink-faint); margin: 1rem 0 0.4rem; display: flex; gap: 0.5rem; align-items: baseline;
}
.view-panel > .view-lbl:first-child { margin-top: 0.15rem; }
.key-fold > summary { cursor: pointer; list-style: none; }
.key-fold > summary::-webkit-details-marker { display: none; }
.key-fold > summary::after { content: "show"; font-size: 0.66rem; letter-spacing: 0.08em; border: 1px solid var(--rule); border-radius: 2px; padding: 0.04rem 0.3rem; }
.key-fold[open] > summary::after { content: "hide"; }
.key-fold > summary:hover { color: var(--ink); }
.view-hint { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 0.72rem; }
.view-row { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.view-panel .cols-list { grid-template-columns: 1fr 1fr; gap: 0.1rem 0.6rem; }
.chart-key { display: grid; grid-template-columns: 1.6rem 1fr; gap: 0.45rem 0.2rem; margin: 0; }
.key-note { margin: 0.6rem 0 0; }
.chart-key dt { display: flex; align-items: center; justify-content: center; height: 1.05rem; }
.chart-key dd { margin: 0; font-size: 0.8rem; line-height: 1.35; color: var(--ink-soft); }
.chart-key dd b { color: var(--ink); }
.key-mark { display: block; width: 1.15rem; }
.key-baseline { height: 3px; background: var(--ink-faint); opacity: 0.55; }
.key-done { height: 0.62rem; border-radius: 2px; background: #2E8B4F; }
.key-sumdone { height: 0.38rem; border-radius: 1px; background: #71B087; }
.key-tie { height: 0; border-top: 1px dashed var(--ink-faint); }
.key-crit { height: 0; border-top: 2.4px solid #16A34A; }
.key-path { height: 0; border-top: 2.6px solid #D97706; }
.key-prog { height: 0; border-top: 1.6px solid #7C3AED; }
.key-today { height: 0; border-top: 1.2px dashed var(--crit); }

/* The little up/down buttons on a number cell. */
.stepper { display: flex; flex-direction: column; justify-content: center; flex: none; margin-left: 1px; }
.step-btn {
  font: inherit; font-size: 7px; line-height: 1; width: 0.95rem; height: 0.72rem;
  padding: 0; border: 1px solid var(--rule); background: var(--surface);
  color: var(--ink-faint); cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.step-btn:first-child { border-radius: 3px 3px 0 0; border-bottom: 0; }
.step-btn:last-child { border-radius: 0 0 3px 3px; }
.step-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent-soft); background: var(--accent-wash); }
.step-btn:disabled { opacity: 0.35; cursor: default; }
.cols-item input:disabled + span { color: var(--ink-faint); }
.cols-all { margin-top: 0.3rem; font-size: 0.8rem; text-align: left; }
/* The Columns menu beside the grid (v0.81.0): the button, or a right-click on a heading. */
/* The vertical dots at the end of the Task heading, clear of the resize grip (v0.81.02). */
.grid th.c-name { padding-right: 1.5rem; }
.cols-dots { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 0.95rem; height: 1.5rem; padding: 0; border: 0; border-radius: 3px; background: transparent; color: var(--ink-soft); font-size: 1rem; line-height: 1; cursor: pointer; }
.cols-dots:hover, .cols-dots[aria-expanded="true"] { background: var(--accent-wash); color: var(--accent); }
.cols-dots:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cols-pop { position: fixed; z-index: 60; width: 17rem; max-height: 70vh; overflow-y: auto; background: var(--surface); border: 1px solid var(--rule); border-radius: 6px; box-shadow: 0 8px 24px rgba(20, 30, 40, 0.16); padding: 0.6rem 0.75rem; }
.cols-pop .cols-list { grid-template-columns: 1fr 1fr; gap: 0.1rem 0.6rem; }
.cols-pop-hide { margin: 0 0 0.4rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--rule); font-size: 0.85rem; }
.planner.chart-hidden .chart-pane { display: none; }
.grid th {
  position: sticky; top: 0; z-index: 4;
  background: #F4F6F8; border-bottom: 1px solid var(--rule);
  font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint);
  text-align: left; padding: 0.45rem 0.6rem; font-weight: 600; height: 2rem; box-sizing: border-box;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* the line between two headings: drag it, or double-click it to fit */
.col-grip {
  position: absolute; top: 0; right: -3px; width: 7px; height: 100%;
  cursor: col-resize; z-index: 5; touch-action: none;
}
.col-grip::after {
  content: ""; position: absolute; left: 3px; top: 4px; bottom: 4px; width: 1px;
  background: var(--rule);
}
.col-grip:hover::after, body.resizing-col .col-grip:active::after { background: var(--accent); width: 2px; left: 2.5px; }
body.resizing-col, body.resizing-col * { cursor: col-resize !important; user-select: none; }
/* Text that does not fit says so, so you know to widen the column. */
.cell.c-name-in { text-overflow: ellipsis; }
.grid td { border-bottom: 1px solid var(--rule-soft); padding: 0; vertical-align: middle; height: 2rem; }
/* The outline number. Same face and weight as the ID so the two read as one
   pair of references, but softer, because the ID is the one that is stable. */
.grid td.c-wbs {
  padding: 0 0.45rem; font-family: var(--mono); font-size: 0.78rem;
  color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.grid tr.summary td.c-wbs { font-weight: 600; color: var(--ink-soft); }

.grid td.c-ref {
  padding: 0 0.35rem 0 0.5rem; font-family: var(--mono); font-size: 0.82rem; color: var(--ink-faint);
  cursor: grab; user-select: none; width: 4.1rem; text-align: right;
  touch-action: none;   /* the row drag owns this cell */
  display: flex; align-items: center; justify-content: flex-end; gap: 0.15rem; height: 2rem;
}
.grid td.c-ref:active { cursor: grabbing; }
.ref-no { flex: 1; text-align: right; }
/* Always there, and a real target - it used to appear only on hover, in a
   cell that is itself a drag handle, which made it a game of chance. */
.row-menu-btn {
  flex: none; width: 1.5rem; height: 1.75rem; padding: 0; line-height: 1;
  border: 1px solid transparent; background: none; color: var(--ink-faint); cursor: pointer;
  font-size: 1.05rem; border-radius: 3px; opacity: 0.55;
  touch-action: none;
}
.grid tbody tr:hover .row-menu-btn, .grid tr.selected .row-menu-btn, .row-menu-btn:focus-visible {
  opacity: 1; border-color: var(--rule);
}
.row-menu-btn:hover { background: var(--accent-wash); border-color: var(--accent-soft); color: var(--accent); }
.grid td.c-float { padding: 0 0.6rem; font-family: var(--mono); font-size: 0.85rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.grid td.c-date { padding: 0; }
.cell.c-date-in { font-family: var(--mono); font-size: 0.8rem; font-variant-numeric: tabular-nums; }
/* ONE TEXT SIZE ACROSS THE DATA COLUMNS. Paul, 2026-09-16: "the days of the
   week letters ... should be the same text height as the dates themselves ...
   Likewise, the length should be the same height as the dates. They're too
   big. Can we make all the text heights in these columns the same height?"
   The dates were 0.8rem and everything beside them inherited 0.92rem, so a
   row read at two sizes and the smaller one was the date - the thing being
   looked for. */
.cell.c-dur-in, .cell.c-pct-in, .cell.c-snet-in, .cell.c-pred-in,
.dur-both, .day-letter { font-size: 0.8rem; }
.grid td.c-date.pinned { box-shadow: inset 2px 0 0 var(--mile); }

/* dragging a row */
.grid tr.row-dragging td { opacity: 0.45; }
body.dragging-row, body.dragging-row * { cursor: grabbing !important; }
body.dragging-row .cell { pointer-events: none; }
.drop-line {
  position: absolute; left: 0; right: 0; height: 0; z-index: 6; pointer-events: none;
  border-top: 2px solid var(--accent);
}
.drop-line::before {
  content: ""; position: absolute; left: 0; top: -4px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
}

/* THE ROW MENU - now everything a row can have done to it, the task's own
   properties included, so it is a panel rather than a short list. It scrolls
   itself instead of running off the bottom of the screen. */
.row-menu {
  position: fixed; z-index: 40; min-width: 21rem; max-width: min(29rem, 92vw);
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 4px;
  box-shadow: 0 10px 30px rgba(22, 32, 43, 0.2); padding: 0.25rem;
  display: flex; flex-direction: column;
}
.row-menu hr { border: 0; border-top: 1px solid var(--rule-soft); margin: 0.25rem 0; }
.row-menu-item {
  font: inherit; font-size: 0.88rem; text-align: left;
  padding: 0.4rem 0.6rem; border: 0; background: none; border-radius: 3px;
  color: var(--ink); cursor: pointer; white-space: nowrap;
  display: flex; align-items: center; gap: 1.5rem; justify-content: space-between;
}
.row-menu-item:hover:not(:disabled) { background: var(--accent-wash); }
.row-menu-item:disabled { color: var(--ink-faint); cursor: default; }
.row-menu-item.danger { color: var(--crit); }
.row-menu-item.danger:hover { background: var(--crit-wash); }
/* The keyboard shortcut, quiet and on the right - findable without competing
   with the words that say what the thing does. */
.row-menu-key { font-family: var(--mono); font-size: 0.72rem; color: var(--ink-faint); }
.row-menu-item:disabled .row-menu-key { opacity: 0.5; }
.grid td.c-float { text-align: right; width: 3.6rem; color: var(--ink-soft); }
.grid th.c-float { text-align: right; }
/* Wider than it was, because a section now says both units on one line and
   "50.6w - 253d" must not wrap - a wrapped cell is a taller row, and a
   taller row puts the grid out of step with the chart beside it. */
.grid th.c-dur, .grid td.c-dur { width: 6.4rem; }   /* 96px - keep in step with DEFAULTS[4] in columns.js */
.dur-wrap { display: flex; align-items: center; height: 2rem; }
.dur-wrap .cell { flex: 1; min-width: 0; padding-right: 0.1rem; }
.dur-unit {
  flex: none; width: 1.05rem; height: 1.5rem; padding: 0; margin-right: 0.15rem;
  border: 1px solid transparent; border-radius: 3px; background: none; cursor: pointer;
  font: inherit; font-size: 0.72rem; font-weight: 700; color: var(--ink-faint);
  font-family: var(--mono); touch-action: none;
}
.dur-unit.weeks { color: var(--accent); background: var(--accent-wash); border-color: var(--accent-soft); }
.dur-unit:hover:not(:disabled) { border-color: var(--accent-soft); color: var(--accent); }
.dur-unit:disabled { opacity: 0.4; cursor: default; }
.grid th.c-name { width: 15rem; }
.grid th.c-date { width: 7.8rem; }   /* 116px - keep in step with DEFAULTS in columns.js */
.grid th.c-pred { width: 8rem; }
.grid th.c-snet, .grid td.c-snet { width: 7.4rem; }
.grid th.c-snet { white-space: normal; line-height: 1.15; }
.cell.c-snet-in { font-family: var(--mono); font-size: 0.78rem; }
.cell.c-snet-in.empty:not(:focus) { color: transparent; }
.cell.c-snet-in.empty:not(:focus)::-webkit-calendar-picker-indicator { opacity: 0.3; }
/* A date the links are overriding: shown, struck through, and explained in
   the tooltip - the Check panel says the same thing in full. */
.cell.c-snet-in.inert { color: var(--ink-faint); text-decoration: line-through; }
.grid th.c-pct, .grid td.c-pct { width: 4.2rem; }
.grid th.c-slip, .grid td.c-slip { width: 3.4rem; text-align: right; }
.grid td.c-slip { padding: 0 0.6rem; font-family: var(--mono); font-size: 0.85rem; font-variant-numeric: tabular-nums; color: var(--ink-faint); }
.slip-late { color: var(--crit) !important; font-weight: 600; }
.slip-early { color: var(--ok) !important; font-weight: 600; }
.cell.c-pct-in { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.cell.c-pct-in::-webkit-outer-spin-button, .cell.c-pct-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cell.c-pct-in.empty:not(:focus) { color: var(--rule); }

/* ---- the step path ---- */
.flow-wrap { margin: 0 0 0.9rem; }
/* Folded, the path is one line you can click to open. Open, the summary gets
   out of the way entirely - the strip below it already says where you are. */
.flow-summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.6rem;
  padding: 0.4rem 0.1rem; font-size: 0.9rem; color: var(--ink-soft);
}
.flow-summary::-webkit-details-marker { display: none; }
.flow-summary:hover { color: var(--ink); }
.flow-more {
  font-size: 0.68rem; letter-spacing: 0.09em; text-transform: uppercase; font-weight: 600;
  color: var(--ink-faint); border: 1px solid var(--rule); border-radius: 2px; padding: 0.08rem 0.36rem;
}
.flow-wrap[open] > .flow-summary { display: none; }
.flow-strip {
  display: flex; flex-wrap: wrap; gap: 0.3rem;
  list-style: none; margin: 0; padding: 0;
  counter-reset: none;
}
.flow-strip li { flex: 1 1 8rem; }
.flow-strip a {
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--rule); border-radius: 3px;
  background: var(--surface); color: var(--ink-soft);
  font-size: 0.85rem; font-weight: 600; text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.flow-strip a:hover { border-color: var(--accent-soft); }
.flow-n {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.25rem; height: 1.25rem; border-radius: 50%;
  background: var(--rule-soft); color: var(--ink-faint);
  font-family: var(--mono); font-size: 0.68rem; font-weight: 500;
}
.flow-done a { background: var(--ok-wash); border-color: #BBD6C3; color: var(--ok); }
.flow-done .flow-n { background: var(--ok); color: #fff; }
.flow-current a { background: var(--accent-wash); border-color: var(--accent); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.flow-current .flow-n { background: var(--accent); color: #fff; }
.flow-partial a { background: var(--warn-wash); border-color: #E0C48A; color: #7A5410; }
.flow-partial .flow-n { background: #A8781F; color: #fff; }
.flow-todo a { color: var(--ink-faint); }

.flow-hint { margin: 0.55rem 0 0; font-size: 0.92rem; color: var(--ink-soft); max-width: 62rem; }
.flow-hint strong { color: var(--ink); }
.flow-next { font-size: 0.85rem; color: var(--ink-soft); }
.flow-next-done { color: var(--ok); font-weight: 600; }

.step-badge {
  display: inline-block; margin-left: 0.45rem;
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.01em;
  padding: 0.1rem 0.45rem; border-radius: 2px; vertical-align: middle;
}
.step-done { background: var(--ok-wash); color: var(--ok); }
.step-current { background: var(--accent-wash); color: var(--accent); }
.step-partial { background: var(--warn-wash); color: #7A5410; }
.step-todo { background: var(--rule-soft); color: var(--ink-soft); }
.step-no { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); margin-right: 0.4rem; }

/* ---- the check ---- */
.check-card { padding: 0.75rem 1.1rem; }
.check-card > summary { cursor: pointer; font-weight: 700; font-size: 1.02rem; list-style: none; }
.check-card > summary::-webkit-details-marker { display: none; }
.check-card[open] > summary { margin-bottom: 0.7rem; }
.findings { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
.finding { border-left: 3px solid var(--rule); padding: 0.1rem 0 0.1rem 0.8rem; max-width: 58rem; }
.finding-serious { border-left-color: var(--crit); }
.finding-check { border-left-color: #C8952E; }
.finding-note { border-left-color: var(--accent-soft); }
.finding-head { margin: 0 0 0.15rem; font-size: 0.95rem; max-width: none; }
.finding-label {
  font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.08rem 0.35rem; border-radius: 2px; margin-right: 0.45rem;
}
.finding-serious .finding-label { background: var(--crit-wash); color: var(--crit); }
.finding-check .finding-label { background: var(--warn-wash); color: #7A5410; }
.finding-note .finding-label { background: var(--rule-soft); color: var(--ink-soft); }
.finding-detail { margin: 0; font-size: 0.9rem; color: var(--ink-soft); max-width: none; }
.finding-fix { margin: 0.25rem 0 0; font-size: 0.9rem; color: var(--ink); max-width: none; }
.finding-fix::before { content: "Fix: "; font-weight: 600; color: var(--accent); }
.finding-act { margin: 0.5rem 0 0.2rem; }
/* The two tick lists under Views - Show only. */
/* One above the other - Paul, 2026-09-18: side by side "is very difficult to pick". */
.pick-lists { display: grid; grid-template-columns: 1fr; gap: 0.6rem; margin: 0.2rem 0 0.4rem; }
.pick-lbl { margin: 0 0 0.2rem; font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; }
.pick-list .cols-list { max-height: 11rem; overflow-y: auto; }
/* The line that says the grid is narrowed. */
.filter-note { margin: 0.4rem 0 0.2rem; padding: 0.45rem 0.7rem; background: var(--accent-wash); border: 1px solid var(--accent-soft); border-radius: 4px; font-size: 0.86rem; color: var(--ink-soft); }
.props-many-hint { margin: 0 0 0.6rem; }
.props-chain { margin: 0 0 0.8rem; }
/* "Saved", quietly, after each change; louder when one did not get through. */
.saved-mark { font-size: 0.8rem; color: var(--ink-faint); opacity: 0; transition: opacity 0.25s; align-self: center; white-space: nowrap; }
.saved-mark.show { opacity: 1; }
.saved-mark.bad { color: var(--crit, #A63626); font-weight: 600; }
.find-box { font: inherit; font-size: 0.86rem; padding: 0.35rem 0.55rem; border: 1px solid var(--rule); border-radius: 4px; width: 11rem; background: var(--surface); }
.progress-form { display: inline-flex; align-items: center; gap: 0.4rem; }
.progress-form .inline-date { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; color: var(--ink-soft); }
.progress-form input[type="date"] { font: inherit; font-size: 0.84rem; padding: 0.3rem 0.4rem; border: 1px solid var(--rule); border-radius: 4px; }
.flow-note { font-size: 0.8rem; }
/* The weekly report. */
.report { background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 1.1rem 1.2rem 1.3rem; }
.report-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; border-bottom: 2px solid var(--ink); padding-bottom: 0.6rem; margin-bottom: 0.8rem; }
.report-head h2 { margin: 0; font-size: 1.25rem; }
.report-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.6rem; margin: 0.6rem 0 1rem; }
.report-tiles .tile { border: 1px solid var(--rule); border-radius: 4px; padding: 0.6rem 0.7rem; display: flex; flex-direction: column; gap: 0.1rem; }
.report-tiles .tile b { font-size: 1.3rem; font-variant-numeric: tabular-nums; }
.report-tiles .tile span { font-size: 0.76rem; color: var(--ink-faint); }
.report-tiles .tile.bad b { color: var(--crit, #A63626); }
.report h3 { font-size: 1.02rem; margin: 1.1rem 0 0.4rem; }
.report h4 { font-size: 0.8rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-faint); margin: 0.7rem 0 0.25rem; }
.report-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 2rem; }
@media (max-width: 900px) { .report-cols { grid-template-columns: 1fr; } }
.report-table { font-size: 0.86rem; }
.report-chart { margin: 0.4rem 0 0.6rem; }
.report-risks { margin-top: 0.4rem; }
.send-card { display: flex; align-items: flex-end; gap: 0.8rem; flex-wrap: wrap; margin-bottom: 1rem; }
.send-card .grow { flex: 1; min-width: 16rem; }
.send-actions { display: flex; gap: 0.4rem; }
.look-flag { font-size: 0.68rem; color: var(--ink-faint); white-space: nowrap; }
@media print { .report { border: 0; padding: 0; } .report-cols { grid-template-columns: 1fr 1fr; } .report-table tr { page-break-inside: avoid; } }
/* The fill handle: a spreadsheet's corner square, on the cells whose value
   makes sense copied down - contractor, type, length, % done. */
.grid td.c-type, .grid td.c-firm, .grid td.c-dur, .grid td.c-pct { position: relative; }
.fill-grip { position: absolute; right: 1px; bottom: 1px; width: 9px; height: 9px; background: var(--accent); border: 1.5px solid #fff; border-radius: 2px; cursor: ns-resize; opacity: 0; z-index: 2; }
.grid tr:hover .fill-grip, .grid tr.selected .fill-grip { opacity: 1; }
body.filling, body.filling * { cursor: ns-resize !important; user-select: none; }
.grid tr.fill-target td { background: var(--accent-wash) !important; }
.finding-act-top { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; margin: 0 0 0.9rem; padding: 0.7rem 0.8rem; background: var(--accent-wash); border: 1px solid var(--accent-soft); border-radius: 4px; }
.finding-act-top .hint { color: var(--ink-soft); }

/* ---- starter programmes ---- */
.starters { border: 1px solid var(--rule-soft); border-radius: 3px; padding: 0.6rem 0.9rem 0.8rem; display: grid; gap: 0.1rem; }
.starters legend { font-size: 0.86rem; font-weight: 600; color: var(--ink-soft); }
.starter { display: grid; grid-template-columns: 1.2rem 1fr; gap: 0.1rem 0.4rem; padding: 0.4rem 0; font-weight: 400; cursor: pointer; border-bottom: 1px solid var(--rule-soft); }
.starter:last-of-type { border-bottom: 0; }
.starter input { width: auto; margin: 0.2rem 0 0; grid-row: span 2; }
.starter-name { font-weight: 600; color: var(--ink); font-size: 0.92rem; }
.starter-lines { font-family: var(--mono); font-size: 0.72rem; font-weight: 400; color: var(--ink-faint); margin-left: 0.35rem; }
.starter-blurb { font-size: 0.85rem; color: var(--ink-soft); line-height: 1.4; }
.starter-note { margin: 0.5rem 0 0; grid-column: 1 / -1; }

.progress-toolbar { margin-bottom: 0.4rem; }
.linkish { text-decoration: none; display: inline-block; }
.issue-menu, .issues-list { position: relative; }
.issue-menu > summary, .issues-list > summary { cursor: pointer; list-style: none; display: inline-block; }
.issue-menu > summary::-webkit-details-marker, .issues-list > summary::-webkit-details-marker { display: none; }
/* CAPPED, BUT NOT RE-ANCHORED. Opening this at a 1009px window used to put
   its right edge at 1191px - 182px off the screen - and gave the PAGE a
   horizontal scroll bar of its own, which is the same complaint Paul reported
   from a different cause an hour earlier.

   Flipping it to `right: 0` fixed that width and broke 900px, where the
   toolbar has wrapped and the button sits near the left: the panel then ran
   267px off the OTHER edge. No fixed anchor is right for a toolbar that moves,
   so the anchor stays as it was and `keepPanelOnScreen` in app.js nudges it
   when it would fall off either side. If that script never runs, this behaves
   exactly as it always has - the cap is the only unconditional change. */
.issue-form, .issues-table { position: absolute; left: 0; top: 2.3rem; z-index: 6; background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 0.9rem 1rem; width: 30rem; max-width: 88vw; box-shadow: 0 8px 24px rgba(22, 32, 43, 0.12); }
.issues-table { width: auto; min-width: 40rem; max-width: 92vw; padding: 0; }
/* The reference, date, seal and buttons each on one line (v1.2.0): the reference made the old 40rem wrap every cell. */
.issues-table td.mono, .issues-table td.issue-actions { white-space: nowrap; }
.issue-form label { margin-top: 0.6rem; }
.issue-form .form-actions { margin-top: 0.8rem; }
.hint-p { margin: 0; font-size: 0.86rem; color: var(--ink-soft); }
.section-h { font-size: 1.05rem; margin: 1.6rem 0 0.6rem; }

/* No `fill` here: chart.js sets it from the company's Progress colour
   (green by default). A CSS fill would silently beat the attribute. */
.ch-done { pointer-events: none; }
/* Same rule as .ch-done: NO `fill` here. chart.js sets it from the company's
   progress colour, lightened, and a CSS fill would silently beat it. */
.ch-summary-done { pointer-events: none; }
.ch-baseline { fill: var(--ink-faint); opacity: 0.55; pointer-events: none; }
/* The PROGRESS LINE - where the job has actually got to, measured against the
   status date. It used to be dark green, which put TWO unexplained green
   lines on the same chart alongside the critical path; Paul asked what the
   green line was, and the honest answer was "one of two different things".
   Violet is its own colour here: nothing else on the chart uses it. */
.ch-progress { fill: none; stroke: #7C3AED; stroke-width: 1.6; stroke-linejoin: round; pointer-events: none; }
.ch-progress.quiet { stroke-width: 1; opacity: 0.55; }
/* THE TRAFFIC LIGHT ON THE PROGRESS LINE. Paul, 2026-09-15: "if it's behind
   progress, it turns red. If it's on progress, it's amber, and if it's in
   front of progress, then it's green."
   The green is DELIBERATELY NOT the critical path's #16A34A. That line is
   green and this one was too, once, and Paul could not tell them apart -
   which is why the spine of this one is violet and only its kinks take a
   colour. A kink is always attached to violet, so it can never be mistaken
   for the critical path running along the bars.
   Thicker than the spine as well as coloured: a verdict nobody can see at a
   glance is not a verdict, and thickness reads where colour does not. */
.ch-progress.behind { stroke: #B42318; stroke-width: 2.4; opacity: 1; }
/* Not finished yet, started or not. Spine weight, not kink weight: this runs
   the whole length of the work still to come, and at 2.4 it drowns the one
   thing on this line that is actually urgent. */
.ch-progress.on { stroke: var(--warn); stroke-width: 1.8; opacity: 1; }
.ch-progress.ahead { stroke: var(--ok); stroke-width: 2.4; opacity: 1; }
/* Finished, and behind the date. The same green as 'ahead' because it says
   the same thing - this work is not a worry - but its own class so the
   label can count what is genuinely AHEAD of programme separately from
   what is simply done. Thinner than a kink: the spine is the quiet part of
   the line, and a green spine running the length of the finished work
   should not shout as loudly as a task that is late. */
.ch-progress.done { stroke: var(--ok); stroke-width: 1.8; opacity: 1; }
.ch-progress-lbl { font-family: var(--mono); font-size: 9.5px; fill: #7C3AED; letter-spacing: 0.06em; pointer-events: none; }
.ch-progress-lbl.behind { fill: #B42318; }
.ch-progress-lbl.ahead { fill: var(--ok); }

/* ---- the chart ---- */
.chart-pane { flex: none; position: relative; }
.chart-head-wrap { position: sticky; top: 0; z-index: 2; background: #F4F6F8; border-bottom: 1px solid var(--rule); box-sizing: border-box; }
.chart-head, .chart-body { display: block; }
.ch-bg { fill: #F4F6F8; }
.ch-rule { stroke: var(--rule); stroke-width: 1; }
.ch-div { stroke: var(--rule-soft); stroke-width: 1; }
.ch-div-top { stroke: var(--rule); stroke-width: 1; }
.ch-off { fill: rgba(22, 32, 43, 0.045); }
.ch-lbl, .ch-lbl-top, .ch-drag-lbl, .ch-today-lbl { font-variant-numeric: tabular-nums lining-nums; }
.ch-lbl { font-family: var(--mono); font-size: 10.5px; fill: var(--ink-soft); }
.ch-lbl.off { fill: var(--ink-faint); }
.ch-lbl-top { font-family: var(--sans); font-size: 11px; font-weight: 600; fill: var(--ink-soft); }
.ch-today-lbl { font-family: var(--mono); font-size: 9.5px; fill: var(--crit); letter-spacing: 0.06em; }
.ch-nw { fill: rgba(22, 32, 43, 0.05); }
.ch-grid { stroke: var(--rule-soft); stroke-width: 1; }
/* NO `fill` HERE. A CSS fill beats a fill ATTRIBUTE, and the row tint is set
   as an attribute from chart.js - exactly the trap that made per-bar colours
   silently do nothing until every `fill` was taken out of `.ch-bar` and
   friends. chart.js always sets one, "transparent" when there is no tint. */
.ch-row { cursor: pointer; }
.ch-row:hover { fill: rgba(47, 93, 133, 0.05); }
.ch-row.selected { fill: rgba(255, 214, 102, 0.28); }
.ch-rowline { stroke: var(--rule-soft); stroke-width: 1; }
/* Fills come from the payload, set as attributes by chart.js - the
   company's colours, or the bar's own override. Nothing here may declare
   `fill`, or the override never lands. */
.ch-bar { cursor: pointer; }
.ch-summary { cursor: pointer; }
.ch-mile { cursor: pointer; }
.ch-lbl-task { font-family: var(--sans); font-size: 12px; fill: var(--ink-soft); pointer-events: none; }
.ch-lbl-task.summary { font-weight: 700; fill: var(--ink); }
.ch-link { fill: none; stroke: var(--ink-faint); stroke-width: 1.2; }
.ch-arrow { fill: var(--ink-faint); }
.ch-today { stroke: var(--crit); stroke-width: 1.2; stroke-dasharray: 3 3; }
.ch-deadline { stroke: var(--crit); stroke-width: 1.5; }

/* dragging */
.ch-bar, .ch-mile, .ch-handle, .ch-grip, .ch-hit { touch-action: none; }
.ch-hit { fill: transparent; cursor: grab; }
.ch-bar { cursor: grab; }
.ch-mile { cursor: grab; }
.ch-summary { cursor: default; }
.ch-grip { fill: var(--ink); opacity: 0; cursor: ew-resize; }
.ch-task:hover .ch-grip { opacity: 0.5; }
.ch-grip:hover, .ch-task.dragging .ch-grip { opacity: 0.85 !important; }
.ch-handle { fill: #fff; stroke: var(--bar); stroke-width: 1.5; opacity: 0.4; cursor: crosshair; transition: opacity 0.12s; }  /* faintly there on every bar - a ring nobody can see is a feature nobody finds (2026-09-19) */
.ch-task:hover .ch-handle, .ch-task.linking .ch-handle { opacity: 1; }
.ch-task.dragging .ch-bar, .ch-task.dragging .ch-mile { opacity: 0.75; cursor: grabbing; }
.ch-task.dragging .ch-hit { cursor: grabbing; }
.ch-link-ghost { stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 4 3; fill: none; pointer-events: none; }
.ch-row.drop-target { fill: rgba(47, 93, 133, 0.16); }
.ch-drag-lbl { font-family: var(--mono); font-size: 11px; fill: var(--ink); pointer-events: none; }
.ch-drag-lbl-bg { fill: #fff; stroke: var(--rule); pointer-events: none; }
.toolbar-sep { display: inline-block; width: 1px; height: 1.4rem; background: var(--rule); margin: 0 0.3rem; }
button:disabled { opacity: 0.45; cursor: default; }
.button-secondary:disabled:hover { background: #fff; }
.grid tr.selected td { background: var(--sel); }
.grid tr.summary td.c-name .cell { font-weight: 700; }
.grid tr.summary td.c-date { font-weight: 600; }
/* Critical is a way of LOOKING, not a state a row is in - these appear only
   while the Critical path button is pressed (chart.js puts `crit-on` on the
   body). Otherwise a fully linked programme, which is one long chain, reads
   as red from top to bottom and the colour stops meaning anything. */
.crit-on .grid tr.critical td.c-float { color: var(--crit); font-weight: 600; }
.crit-on .grid tr.critical td.c-ref { border-left: 3px solid var(--crit); }
.grid tr.milestone td.c-name .cell { font-style: italic; }
.grid td.c-name { position: relative; }
.grid td.c-name .mark { position: absolute; left: 0.35rem; top: 50%; transform: translateY(-50%); font-size: 0.7rem; color: var(--mile); pointer-events: none; }

.cell {
  width: 100%; height: 2rem; border: 0; background: transparent;
  font: inherit; font-size: 0.92rem; color: var(--ink); padding: 0 0.6rem;
}
.cell:focus { outline: 2px solid var(--accent); outline-offset: -2px; background: #fff; }
.cell:disabled { color: var(--ink-faint); background: transparent; }
.cell.c-dur-in { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.cell.c-dur-in::-webkit-outer-spin-button, .cell.c-dur-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cell.c-pred-in { font-family: var(--mono); font-size: 0.85rem; }
.cell.c-snet-in { font-family: var(--mono); font-size: 0.82rem; }
.cell.c-snet-in.empty:not(:focus) { color: transparent; }
.cell.c-snet-in.empty:not(:focus)::-webkit-calendar-picker-indicator { opacity: 0.35; }
.cell.dirty { background: var(--sel); }
.grid-empty { color: var(--ink-soft); padding: 1rem 0.2rem; }

/* ---------------------------------------------------------------------------
   The slippage chart - planned against actual, with the slip between them.

   Same construction as the planner: one horizontal scroller, the names
   sticky on the left, the timescale sticky on top, so the two halves cannot
   disagree about which row you are looking at. Read-only: nothing here drags.
   --------------------------------------------------------------------------- */
.slip-wrap { margin: 0.9rem 0 1.4rem; border: 1px solid var(--rule); border-radius: 5px; background: var(--surface); }
.slip-bar {
  display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap;
  padding: 0.5rem 0.7rem; border-bottom: 1px solid var(--rule-soft);
}
.slip-legend { display: flex; gap: 0.9rem; flex-wrap: wrap; font-size: 0.78rem; color: var(--ink-soft); }
.slip-legend .lg { display: inline-flex; align-items: center; gap: 0.3rem; }
.slip-legend i { display: inline-block; width: 1.1rem; height: 0.55rem; border-radius: 2px; }
.lg-plan { background: #9AA5B1; }
.lg-late { background: #A63626; }
.lg-early { background: #2E8B4F; }
.lg-same { background: #4E5B69; }
.slip-zoom { margin-left: auto; display: flex; gap: 0.25rem; }

.slip-scroll { overflow-x: auto; overflow-y: hidden; }
.slip-inner { display: flex; align-items: flex-start; min-width: min-content; }
.slip-col {
  position: sticky; left: 0; z-index: 3; flex: none; width: 17rem;
  background: var(--surface); box-shadow: 1px 0 0 var(--rule-soft);
}
.slip-col-head {
  height: 34px; box-sizing: border-box; display: flex; align-items: center;
  padding: 0 0.5rem; font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 600; background: #F4F6F8;
  border-bottom: 1px solid var(--rule-soft); position: sticky; top: 0; z-index: 4;
}
.slip-name {
  height: 36px; box-sizing: border-box; display: flex; align-items: center; gap: 0.4rem;
  padding: 0 0.5rem; font-size: 0.82rem; border-bottom: 1px solid var(--rule-soft);
  white-space: nowrap; overflow: hidden;
}
.slip-name.summary { font-weight: 600; }
.slip-name.milestone .slip-nm { font-style: italic; }
.slip-no { font-family: var(--mono); font-size: 0.72rem; color: var(--ink-faint); flex: none; min-width: 2.2rem; }
.slip-nm { overflow: hidden; text-overflow: ellipsis; }
.slip-days { margin-left: auto; font-family: var(--mono); font-size: 0.74rem; color: var(--ink-faint); flex: none; }
.slip-days.late { color: var(--crit); font-weight: 600; }
.slip-days.early { color: #2E8B4F; font-weight: 600; }

.slip-pane { flex: none; }
.slip-head { display: block; position: sticky; top: 0; z-index: 2; border-bottom: 1px solid var(--rule-soft); }
.slip-body { display: block; }
.slip-headbg { fill: #F4F6F8; }
.slip-month { font-family: var(--mono); font-size: 10px; fill: var(--ink-soft); font-weight: 600; }
.slip-week { font-family: var(--mono); font-size: 8.5px; fill: var(--ink-faint); }
.slip-tick { stroke: var(--rule); stroke-width: 1; }
.slip-tick.soft { stroke: var(--rule-soft); }
.slip-grid { stroke: var(--rule-soft); stroke-width: 1; }
.slip-band { fill: #FAFBFC; }
.slip-today { stroke: var(--crit); stroke-width: 1.2; stroke-dasharray: 3 3; }

/* Fills are set here rather than as attributes because slip.js never
   overrides them per task - there is no company colour on this chart, the
   colour IS the answer: grey was the plan, red is late, green is early. */
.slip-plan { fill: #9AA5B1; }
.slip-now { fill: #4E5B69; }
.slip-now.late { fill: #A63626; }
.slip-now.early { fill: #2E8B4F; }
.slip-arrow { fill: none; stroke-width: 1.2; stroke-dasharray: 3 2; }
.slip-arrow.late { stroke: #A63626; }
.slip-arrow.early { stroke: #2E8B4F; }
.slip-lbl { font-family: var(--mono); font-size: 9px; font-weight: 600; }
.slip-lbl.late { fill: #A63626; }
.slip-lbl.early { fill: #2E8B4F; }
.slip-note { font-family: var(--mono); font-size: 9px; fill: var(--ink-faint); }

/* ---------------------------------------------------------------------------
   Settings, as one place with four sections rather than four menu items.
   --------------------------------------------------------------------------- */
.settings-nav {
  display: flex; gap: 0.25rem; flex-wrap: wrap;
  border-bottom: 1px solid var(--rule); margin: -0.4rem 0 1.2rem;
}
.settings-nav a {
  padding: 0.45rem 0.8rem; font-size: 0.9rem; text-decoration: none;
  color: var(--ink-soft); border: 1px solid transparent; border-bottom: 0;
  border-radius: 4px 4px 0 0; margin-bottom: -1px;
}
.settings-nav a:hover { color: var(--ink); background: var(--accent-wash); }
.settings-nav a.on {
  color: var(--ink); font-weight: 600; background: var(--surface);
  border-color: var(--rule); border-bottom-color: var(--surface);
}
.settings-h { margin: 0 0 0.9rem; font-size: 1.15rem; }
/* Which baseline the programme is measured against (v0.80.0). */
.compare-pick { align-items: flex-end; gap: 0.6rem; margin: 0 0 0.8rem; flex-wrap: wrap; }
.compare-pick .hint { flex-basis: 100%; }
/* "On this page" on the long company Settings page (v0.77.01). */
.on-page { display: flex; flex-wrap: wrap; gap: 0.2rem 0.9rem; align-items: baseline; margin: -0.3rem 0 1rem; font-size: 0.88rem; }
.on-page-lbl { font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; }
.on-page a { text-decoration: none; }
.on-page a:hover { text-decoration: underline; }
.settings-page, .card[id] { scroll-margin-top: 0.8rem; }

/* THE SETTINGS TABS (v1.4.0). Paul, 2026-10-04: five short pages
   instead of one long one. Pills, so they read as a choice WITHIN "This
   company" and not as a second row of the folder tabs above them. */
.settings-tabs { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 1.1rem; }
.settings-tabs a { padding: 0.38rem 0.95rem; border: 1px solid var(--rule); border-radius: 999px; font-size: 0.9rem;
  color: var(--ink-soft); text-decoration: none; background: var(--surface); }
.settings-tabs a:hover { color: var(--ink); border-color: var(--accent); }
.settings-tabs a.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.settings-pane[hidden] { display: none; }

/* ONE LINE, THEN "?" (v1.4.0). Paul's mantra, simple is best: a section says
   what it is in one sentence; the rest is a click away, opened in place, and
   nothing that was said before has gone. The sentence and the ? are one
   button (a <summary>), so either opens it. */
.hint-more { margin: 0 0 0.75rem; font-size: 0.86rem; color: var(--ink-soft); max-width: 52rem; }
.hint-more > summary { list-style: none; cursor: pointer; display: block; }
.hint-more > summary::-webkit-details-marker { display: none; }
.hint-more > summary:hover { color: var(--ink); }
.more-q { display: inline-flex; align-items: center; justify-content: center; width: 1.1rem; height: 1.1rem; border-radius: 50%;
  border: 1px solid var(--rule); color: var(--ink-faint); font-size: 0.7rem; font-weight: 700; line-height: 1; margin-left: 0.3rem;
  vertical-align: 0.05rem; background: var(--surface); }
.hint-more > summary:hover .more-q, .hint-more > summary:focus-visible .more-q { color: var(--accent); border-color: var(--accent); }
.hint-more[open] .more-q { background: var(--accent); border-color: var(--accent); color: #fff; }
.hint-more-body { margin: 0.45rem 0 0.2rem; padding: 0.5rem 0.8rem; border-left: 3px solid var(--accent); background: var(--accent-wash); border-radius: 0 4px 4px 0; }
.hint-more-body p { margin: 0 0 0.45rem; }
.hint-more-body p:last-child { margin-bottom: 0; }
@media print { .settings-tabs, .more-q { display: none; } .settings-pane[hidden] { display: block; } }

/* ---------------------------------------------------------------------------
   THE LOOK-AHEAD. The sheet that goes to the Monday meeting, so it is built to
   be printed and read on a wall, not to be admired on a screen: no colour that
   a mono printer would lose, wide rules, and a column left empty to write in.
   --------------------------------------------------------------------------- */
.look-bar { display: flex; align-items: flex-end; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 1rem; }
.look-weeks { display: flex; gap: 0.25rem; }
.look-weeks .active { background: var(--accent); color: #fff; border-color: var(--accent); }
.look-date { font-size: 0.8rem; }
.look-date input { width: 9.5rem; }

.look-sheet { background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 1.1rem 1.2rem 1.3rem; }
.look-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; border-bottom: 2px solid var(--ink); padding-bottom: 0.6rem; margin-bottom: 0.8rem; }
.look-head h2 { margin: 0; font-size: 1.25rem; }
.look-sub { margin: 0.1rem 0 0; color: var(--ink-soft); font-size: 0.85rem; }
.look-window { text-align: right; font-size: 0.85rem; line-height: 1.5; }

.look-foot { margin: 0.9rem 0 0; font-size: 0.8rem; color: var(--ink-faint); }
.markup-bar { margin-bottom: 0.7rem; }
.since-line { margin: 0.2rem 0 1rem; font-size: 0.92rem; color: var(--ink-soft); }
.load-wrap { overflow-x: auto; }
.load-table tr.load-bars td { vertical-align: bottom; border-bottom: 2px solid var(--rule); padding-bottom: 0.2rem; }
.load-table td.load-bar-cell { height: 5.2rem; text-align: center; }
.load-table td.load-bar-cell .hist-n { display: block; }
.load-table td.load-bar-cell .hist-bar { height: 3.6rem; width: 70%; margin: 0 auto; display: flex; align-items: flex-end; }
.load-table td.load-bar-cell .hist-bar i { display: block; width: 100%; background: var(--accent); border-radius: 2px 2px 0 0; }
.load-table td.load-bar-cell.load-now .hist-bar i { background: var(--warn); }
.load-table th.load-col { min-width: 3.2rem; font-weight: 500; line-height: 1.15; }
.load-table .load-now { background: var(--warn-wash); }
.load-table td.load-cell { min-width: 3.2rem; }
.load-table .load-1 { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.load-table .load-2 { background: color-mix(in srgb, var(--accent) 26%, transparent); }
.load-table .load-3 { background: color-mix(in srgb, var(--accent) 42%, transparent); font-weight: 600; }
.load-table tr.load-none td:first-child { color: var(--crit); font-style: italic; }
.load-table tfoot td { border-top: 2px solid var(--rule); }
.copy-block { margin-top: 0.6rem; }
.week-card > summary { cursor: pointer; font-weight: 600; }
.week-card .week-sum { font-weight: 400; color: var(--ink-soft); font-size: 0.9rem; margin-left: 0.5rem; }
.week-steps { margin: 0.6rem 0 0; padding-left: 1.4rem; display: grid; gap: 0.55rem; }
.week-steps li { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.8rem; }
.week-steps li > b { min-width: 14rem; }
.week-steps .hint { flex-basis: 100%; order: 3; margin: -0.2rem 0 0; }
.week-last { font-size: 0.82rem; color: var(--ink-faint); }
.week-auto { margin-top: 0.9rem; padding-top: 0.7rem; border-top: 1px solid var(--rule); display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 1rem; }
.week-auto p { margin: 0; flex: 1; min-width: 18rem; font-size: 0.92rem; }
.notice-row { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
.share-link-sm { font-size: 0.78rem; width: 100%; min-width: 14rem; }
/* ---- the project reports ---- */
/* ---- preview, saved documents, the two-week board ---- */
.preview-acts { flex-wrap: wrap; gap: 0.5rem; }
.preview-acts .hint { margin-left: 0.3rem; }
.preview-pages { display: grid; gap: 1rem; justify-items: start; }
.preview-page { max-width: 100%; height: auto; border: 1px solid var(--rule); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); background: #fff; }
@media print { .preview-page { box-shadow: none; border: 0; page-break-after: always; max-width: 100%; } .preview-pages { gap: 0; } }
.board-week { margin-bottom: 1.4rem; }
.board-week-head { margin: 0 0 0.6rem; padding: 0.35rem 0.6rem; background: var(--ink); color: #fff; border-radius: 3px; font-size: 1.1rem; display: flex; gap: 0.8rem; align-items: baseline; flex-wrap: wrap; }
.board-week-head .board-week-dates { font-family: var(--mono); font-size: 0.95rem; }
.board-week-head .muted { color: rgba(255, 255, 255, 0.7); }
.board-group h4 { margin: 0 0 0.4rem; font-size: 1.05rem; border-bottom: 2px solid var(--ink); padding-bottom: 0.2rem; }
.board-none h4 { color: var(--crit); border-bottom-color: var(--crit); }
/* ---- the lead-in schedule ---- */
.needs-card { margin-bottom: 0.8rem; }
.needs-list { margin: 0.3rem 0 0; padding-left: 1.1rem; display: grid; gap: 0.3rem; }
.needs-list li.is-late { color: var(--crit); }
.leadin-add { margin-bottom: 1rem; }
.leadin-add-one { margin-top: 0.6rem; }
.set-add { margin-top: 0.8rem; }
.set-pick { display: grid; gap: 0.15rem; }
.set-pick .pick-lbl { margin: 0 0 0.2rem; }
.leadin-one { margin-top: 0.6rem; }
.leadin-one > summary { cursor: pointer; }
.leadin-table td.leadin-acts { white-space: nowrap; }
.leadin-table td.leadin-acts form { display: inline-flex; gap: 0.3rem; align-items: center; margin-right: 0.4rem; }
.leadin-table td.leadin-acts input[type=date] { width: 9rem; }
.leadin-sets .leadin-set { display: flex; justify-content: space-between; gap: 0.6rem; align-items: baseline; }
.status-row.status-due-soon td:first-child { border-left-color: var(--warn); }
.status-chip.status-due-soon { background: var(--warn-wash); color: #5C4712; }
.status-chip.status-planned { background: var(--rule); color: var(--ink-soft); }
.view-check { display: inline-flex; gap: 0.4rem; align-items: baseline; }
.ch-leadin { fill: #2F5D85; opacity: 0.9; }
.ch-leadin.is-done { fill: #9AA3AD; }
.ch-leadin.is-late { fill: var(--crit); }
.props-leadin { margin: 0.6rem 0 0; font-size: 0.88rem; display: grid; gap: 0.25rem; }
.props-leadin-item { font-size: 0.82rem; color: var(--ink-soft); }
.props-leadin-item.is-late { color: var(--crit); }
.props-leadin-item.is-done { color: var(--ink-faint); text-decoration: line-through; }
.props-leadin-add { display: flex; gap: 0.35rem; align-items: center; flex-wrap: wrap; margin-top: 0.3rem; }
.props-leadin-add select { max-width: 11rem; }
.props-leadin-add input { width: 4rem; }
.props-leadin.is-late a { color: var(--crit); font-weight: 600; }
.setup-card > summary { cursor: pointer; font-weight: 600; }
.setup-list { margin: 0.6rem 0 0; padding: 0; list-style: none; display: grid; gap: 0.45rem; }
.setup-list li { display: grid; grid-template-columns: 1.4rem auto; gap: 0 0.5rem; align-items: baseline; }
.setup-list .hint { grid-column: 2; }
.setup-tick { display: inline-flex; width: 1.1rem; height: 1.1rem; border-radius: 50%; border: 1px solid var(--rule); align-items: center; justify-content: center; font-size: 0.7rem; color: var(--ok); }
.setup-list li.is-done .setup-tick { background: var(--ok-wash); border-color: var(--ok); }
.setup-list li.is-done .setup-label { color: var(--ink-faint); text-decoration: line-through; }
.changes-table td.changes-time { white-space: nowrap; width: 8rem; }
.changes-table td.changes-who { white-space: nowrap; font-weight: 600; width: 12rem; }
.note-mark { position: absolute; right: 0.35rem; top: 50%; transform: translateY(-50%); font-size: 0.62rem; letter-spacing: 0.04em; text-transform: uppercase; padding: 0.05rem 0.35rem; border-radius: 3px; background: var(--warn-wash); color: #5C4712; pointer-events: auto; cursor: help; }
.assume-form { margin: -0.4rem 0 0.9rem; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.week-pack { margin: 0.8rem 0 0; display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.basis-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: 1rem 2rem; margin-bottom: 1rem; }
.basis-grid h3 { margin-top: 0; }
.basis-facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.3rem 1rem; margin: 0; font-size: 0.92rem; }
.basis-facts dt { color: var(--ink-soft); font-weight: 600; }
.basis-facts dd { margin: 0; }
.basis-list { list-style: none; margin: 0.5rem 0 0; padding: 0; columns: 2; font-size: 0.85rem; }
.basis-list li { break-inside: avoid; }
.hist-wrap { overflow-x: auto; padding-bottom: 0.4rem; }
.hist { display: flex; align-items: flex-end; gap: 2px; height: 16rem; min-width: 100%; border-bottom: 1px solid var(--rule); padding: 1.2rem 0 1.4rem; position: relative; }
.hist-col { flex: 1 0 1.4rem; display: flex; flex-direction: column; align-items: center; height: 100%; justify-content: flex-end; position: relative; }
.hist-n { font-size: 0.7rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; height: 1rem; }
.hist-bar { width: 70%; height: 100%; display: flex; align-items: flex-end; }
.hist-bar i { display: block; width: 100%; background: var(--accent); border-radius: 2px 2px 0 0; min-height: 0; }
.hist-col.is-now .hist-bar i { background: var(--warn); }
.hist-lbl { position: absolute; bottom: -1.3rem; font-size: 0.68rem; color: var(--ink-faint); white-space: nowrap; }
.hist-bar[data-h="0"] i { height: 0%; }
.hist-bar[data-h="1"] i { height: 1%; }
.hist-bar[data-h="2"] i { height: 2%; }
.hist-bar[data-h="3"] i { height: 3%; }
.hist-bar[data-h="4"] i { height: 4%; }
.hist-bar[data-h="5"] i { height: 5%; }
.hist-bar[data-h="6"] i { height: 6%; }
.hist-bar[data-h="7"] i { height: 7%; }
.hist-bar[data-h="8"] i { height: 8%; }
.hist-bar[data-h="9"] i { height: 9%; }
.hist-bar[data-h="10"] i { height: 10%; }
.hist-bar[data-h="11"] i { height: 11%; }
.hist-bar[data-h="12"] i { height: 12%; }
.hist-bar[data-h="13"] i { height: 13%; }
.hist-bar[data-h="14"] i { height: 14%; }
.hist-bar[data-h="15"] i { height: 15%; }
.hist-bar[data-h="16"] i { height: 16%; }
.hist-bar[data-h="17"] i { height: 17%; }
.hist-bar[data-h="18"] i { height: 18%; }
.hist-bar[data-h="19"] i { height: 19%; }
.hist-bar[data-h="20"] i { height: 20%; }
.hist-bar[data-h="21"] i { height: 21%; }
.hist-bar[data-h="22"] i { height: 22%; }
.hist-bar[data-h="23"] i { height: 23%; }
.hist-bar[data-h="24"] i { height: 24%; }
.hist-bar[data-h="25"] i { height: 25%; }
.hist-bar[data-h="26"] i { height: 26%; }
.hist-bar[data-h="27"] i { height: 27%; }
.hist-bar[data-h="28"] i { height: 28%; }
.hist-bar[data-h="29"] i { height: 29%; }
.hist-bar[data-h="30"] i { height: 30%; }
.hist-bar[data-h="31"] i { height: 31%; }
.hist-bar[data-h="32"] i { height: 32%; }
.hist-bar[data-h="33"] i { height: 33%; }
.hist-bar[data-h="34"] i { height: 34%; }
.hist-bar[data-h="35"] i { height: 35%; }
.hist-bar[data-h="36"] i { height: 36%; }
.hist-bar[data-h="37"] i { height: 37%; }
.hist-bar[data-h="38"] i { height: 38%; }
.hist-bar[data-h="39"] i { height: 39%; }
.hist-bar[data-h="40"] i { height: 40%; }
.hist-bar[data-h="41"] i { height: 41%; }
.hist-bar[data-h="42"] i { height: 42%; }
.hist-bar[data-h="43"] i { height: 43%; }
.hist-bar[data-h="44"] i { height: 44%; }
.hist-bar[data-h="45"] i { height: 45%; }
.hist-bar[data-h="46"] i { height: 46%; }
.hist-bar[data-h="47"] i { height: 47%; }
.hist-bar[data-h="48"] i { height: 48%; }
.hist-bar[data-h="49"] i { height: 49%; }
.hist-bar[data-h="50"] i { height: 50%; }
.hist-bar[data-h="51"] i { height: 51%; }
.hist-bar[data-h="52"] i { height: 52%; }
.hist-bar[data-h="53"] i { height: 53%; }
.hist-bar[data-h="54"] i { height: 54%; }
.hist-bar[data-h="55"] i { height: 55%; }
.hist-bar[data-h="56"] i { height: 56%; }
.hist-bar[data-h="57"] i { height: 57%; }
.hist-bar[data-h="58"] i { height: 58%; }
.hist-bar[data-h="59"] i { height: 59%; }
.hist-bar[data-h="60"] i { height: 60%; }
.hist-bar[data-h="61"] i { height: 61%; }
.hist-bar[data-h="62"] i { height: 62%; }
.hist-bar[data-h="63"] i { height: 63%; }
.hist-bar[data-h="64"] i { height: 64%; }
.hist-bar[data-h="65"] i { height: 65%; }
.hist-bar[data-h="66"] i { height: 66%; }
.hist-bar[data-h="67"] i { height: 67%; }
.hist-bar[data-h="68"] i { height: 68%; }
.hist-bar[data-h="69"] i { height: 69%; }
.hist-bar[data-h="70"] i { height: 70%; }
.hist-bar[data-h="71"] i { height: 71%; }
.hist-bar[data-h="72"] i { height: 72%; }
.hist-bar[data-h="73"] i { height: 73%; }
.hist-bar[data-h="74"] i { height: 74%; }
.hist-bar[data-h="75"] i { height: 75%; }
.hist-bar[data-h="76"] i { height: 76%; }
.hist-bar[data-h="77"] i { height: 77%; }
.hist-bar[data-h="78"] i { height: 78%; }
.hist-bar[data-h="79"] i { height: 79%; }
.hist-bar[data-h="80"] i { height: 80%; }
.hist-bar[data-h="81"] i { height: 81%; }
.hist-bar[data-h="82"] i { height: 82%; }
.hist-bar[data-h="83"] i { height: 83%; }
.hist-bar[data-h="84"] i { height: 84%; }
.hist-bar[data-h="85"] i { height: 85%; }
.hist-bar[data-h="86"] i { height: 86%; }
.hist-bar[data-h="87"] i { height: 87%; }
.hist-bar[data-h="88"] i { height: 88%; }
.hist-bar[data-h="89"] i { height: 89%; }
.hist-bar[data-h="90"] i { height: 90%; }
.hist-bar[data-h="91"] i { height: 91%; }
.hist-bar[data-h="92"] i { height: 92%; }
.hist-bar[data-h="93"] i { height: 93%; }
.hist-bar[data-h="94"] i { height: 94%; }
.hist-bar[data-h="95"] i { height: 95%; }
.hist-bar[data-h="96"] i { height: 96%; }
.hist-bar[data-h="97"] i { height: 97%; }
.hist-bar[data-h="98"] i { height: 98%; }
.hist-bar[data-h="99"] i { height: 99%; }
.hist-bar[data-h="100"] i { height: 100%; }
.status-row td:first-child { border-left: 3px solid transparent; }
.status-row.status-done td:first-child, .status-row.status-early td:first-child, .status-row.status-on-track td:first-child { border-left-color: var(--ok); }
.status-row.status-late td:first-child, .status-row.status-critical td:first-child { border-left-color: var(--crit); }
.status-row.status-moved td:first-child, .status-row.status-risk td:first-child { border-left-color: var(--warn); }
.status-chip { display: inline-block; padding: 0.05rem 0.5rem; border-radius: 999px; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; background: var(--rule); color: var(--ink-soft); }
.status-chip.status-done, .status-chip.status-early, .status-chip.status-on-track { background: var(--ok-wash); color: var(--ok); }
.status-chip.status-late { background: var(--crit-wash); color: var(--crit); }
.status-chip.status-moved { background: var(--warn-wash); color: #5C4712; }
.status-chip.status-no-baseline { background: var(--rule); color: var(--ink-faint); }
.curve-svg { width: 100%; max-width: 60rem; height: auto; display: block; margin: 0.4rem 0; }
.curve-grid { stroke: var(--rule); stroke-width: 1; }
.curve-lbl { font-size: 10px; fill: var(--ink-faint); font-family: var(--mono); }
.curve-planned { fill: none; stroke: var(--ink-soft); stroke-width: 2; stroke-dasharray: 5 3; }
.curve-actual { fill: none; stroke: var(--ok); stroke-width: 2.6; stroke-linejoin: round; }
.curve-dot { fill: var(--ok); }
.curve-today { stroke: var(--crit); stroke-width: 1.2; stroke-dasharray: 3 3; }
.curve-key { display: inline-block; width: 1.6rem; height: 0; border-top: 3px solid var(--ink-soft); vertical-align: middle; margin-right: 0.3rem; }
.curve-key-planned { border-top-style: dashed; }
.curve-key-actual { border-top-color: var(--ok); }
.curve-key-today { border-top-color: var(--crit); border-top-style: dotted; }
.curve-table { max-width: 32rem; }
.board { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1rem; }
.board-group h3 { margin: 0 0 0.4rem; font-size: 1.15rem; border-bottom: 2px solid var(--ink); padding-bottom: 0.2rem; }
.board-none h3 { color: var(--crit); border-bottom-color: var(--crit); }
.board-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.board-row { border-left: 4px solid var(--rule); padding: 0.3rem 0.6rem; display: grid; }
.board-row.is-critical { border-left-color: var(--crit); }
.board-row.is-done { opacity: 0.55; }
.board-name { font-weight: 600; font-size: 1.05rem; }
.board-meta { font-size: 0.85rem; color: var(--ink-faint); }
@media print { .board { grid-template-columns: 1fr 1fr; } .board-name { font-size: 1.3rem; } }
.starter-group { grid-column: 1 / -1; margin: 0.5rem 0 0; font-size: 0.8rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint); }
.continue-line { margin: 0 0 0.8rem; font-size: 0.95rem; }
.prog-search-row { margin: 0 0 0.6rem; display: flex; align-items: center; gap: 0.6rem; }
.prog-search-row .find-box { min-width: 16rem; }
.props-more { margin-top: 0.8rem; border-top: 1px solid var(--rule); padding-top: 0.5rem; }
.props-more > summary .fold-now { text-transform: none; }
.legend { margin: 0 0 0.4rem; font-size: 0.82rem; color: var(--ink-soft); }
.legend > summary { cursor: pointer; display: inline-block; padding: 0.1rem 0.5rem; border: 1px solid var(--rule); border-radius: 3px; }
.legend-list { list-style: none; margin: 0.4rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.3rem 1.1rem; }
.legend-list li { display: inline-flex; align-items: center; gap: 0.3rem; white-space: nowrap; }
/* THE "?" BESIDE A PANEL: the manual, opened at that section. Small, quiet,
   always in the same place - never a tooltip that has to be hovered for. */
.help-q { display: inline-flex; align-items: center; justify-content: center; width: 1.15rem; height: 1.15rem; border-radius: 50%; border: 1px solid var(--rule); color: var(--ink-faint); font-size: 0.72rem; font-weight: 700; text-decoration: none; vertical-align: middle; margin-left: 0.25rem; line-height: 1; }
.help-q:hover, .help-q:focus { color: var(--accent); border-color: var(--accent); background: var(--surface); }
.props-head .help-q { margin-left: auto; margin-right: 0.4rem; }
@media print { .help-q { display: none; } }
.link-row { margin-top: 0.6rem; flex-wrap: wrap; gap: 0.6rem 1rem; align-items: center; }
/* ---- the walk-round mark-up page: thumbs, not mice ---- */
.markup-page { max-width: 44rem; }
.markup-window { margin: 0 0 0.6rem; color: var(--ink-soft); }
.markup-date { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.8rem; font-weight: 600; }
.markup-date input { font-size: 1.05rem; padding: 0.45rem 0.6rem; }
.markup-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.markup-row { border: 1px solid var(--rule); border-radius: 6px; padding: 0.7rem 0.8rem; background: var(--surface); display: grid; gap: 0.5rem; }
.markup-row.is-done { background: var(--ok-wash); border-color: var(--ok); }
.markup-row.is-changed { border-left: 4px solid var(--accent); }
.markup-text { min-width: 0; }
.markup-name { font-weight: 600; display: block; }
.markup-meta { display: block; font-size: 0.85rem; color: var(--ink-faint); margin-top: 0.15rem; }
.markup-ctl { display: flex; align-items: stretch; gap: 0.4rem; }
.markup-btn { min-width: 3rem; min-height: 2.8rem; font-size: 1.3rem; border: 1px solid var(--rule); border-radius: 6px; background: var(--surface); color: var(--ink); cursor: pointer; }
.markup-btn:active { background: var(--rule); }
.markup-btn.markup-done { font-size: 0.95rem; font-weight: 600; margin-left: auto; padding: 0 0.9rem; }
.markup-pct { width: 4.6rem; min-height: 2.8rem; font-size: 1.25rem; text-align: center; font-variant-numeric: tabular-nums; border: 1px solid var(--rule); border-radius: 6px; }
.markup-save { position: sticky; bottom: 0; background: var(--bg, #fff); padding: 0.8rem 0 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; border-top: 1px solid var(--rule); margin-top: 0.8rem; }
.markup-save .button { min-height: 3rem; font-size: 1.05rem; padding: 0 1.4rem; }
@media (max-width: 600px) { .markup-page .prog-head { flex-direction: column; align-items: flex-start; } .markup-btn.markup-done { padding: 0 0.6rem; } }
.badge-warn { background: var(--warn-wash); color: #5C4712; }
.badge-ok { background: var(--ok-wash); color: var(--ok); }
.copy-block > summary { cursor: pointer; }
.overview-table td.ov-name a { font-weight: 600; }
.overview-table .ov-bar { width: 5rem; height: 0.5rem; vertical-align: middle; margin-right: 0.35rem; accent-color: var(--ok); }
.bad-text { color: var(--crit); font-weight: 600; }
.ok-text { color: var(--ok); }
.plain-list { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.9rem; }
.grid .pct-box { width: 4.2rem; padding: 0.15rem 0.3rem; font: inherit; font-variant-numeric: tabular-nums; text-align: right; border: 1px solid var(--rule); border-radius: 3px; background: var(--surface); color: var(--ink); }
.grid .pct-box:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
@media print { .grid .pct-box { border: 0; background: none; } }
/* A section heading carried into the window for the rows under it. */
.grid tr.carried td { color: var(--ink-soft); }

@media print {
  .look-sheet { border: 0; padding: 0; }
}

/* ---- bringing a programme in --------------------------------------------- */
.import-ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1.2rem; align-items: start; }
.import-way h2 { margin-top: 0; }
.import-way textarea { font-family: var(--mono); font-size: 0.85rem; resize: vertical; }
.import-problems { margin: 0.5rem 0 0; padding-left: 1.1rem; font-size: 0.88rem; }
.import-table { margin-top: 1.2rem; }
.import-indent { display: inline-block; }
.import-table tr.lvl-1 td:nth-child(2) { font-weight: 600; }

/* ---- printing the wall chart --------------------------------------------- */
.print-menu { position: relative; }
.print-menu > summary { cursor: pointer; list-style: none; display: inline-block; }
.print-menu > summary::-webkit-details-marker { display: none; }
.print-menu[open] > summary { background: var(--accent-wash); border-color: var(--accent-soft); color: var(--accent); }
.print-panel {
  position: absolute; left: 0; top: 2.3rem; z-index: 30; width: 20rem; max-width: 88vw;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 4px;
  padding: 0.75rem 0.85rem 0.85rem; box-shadow: 0 10px 30px rgba(22, 32, 43, 0.18);
  display: grid; gap: 0.6rem;
}
.print-panel .hint-p { margin: 0; }

/* The shared, read-only view. */
.shared-badge {
  background: var(--accent-wash); color: var(--accent); border: 1px solid var(--accent-soft);
  border-radius: 2px; padding: 0.1rem 0.45rem; font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.shared .grid td { padding: 0 0.45rem; height: 2rem; font-size: 0.86rem; }
.export-list { display: grid; gap: 0.1rem; margin-bottom: 0.2rem; }
.export-list a { text-decoration: none; padding: 0.3rem 0.4rem; border-radius: 3px; font-size: 0.88rem; font-weight: 600; }
.export-list a:hover { background: var(--accent-wash); }
.export-list span { display: block; font-weight: 400; font-size: 0.78rem; color: var(--ink-faint); }
.share-link { width: 100%; font-family: var(--mono); font-size: 0.74rem; padding: 0.35rem 0.4rem; border: 1px solid var(--rule); border-radius: 3px; }

/* A promise that has been broken, said the same way everywhere it appears. */
.props-late { color: var(--crit) !important; font-weight: 600; }
input.props-late { border-color: var(--crit); }
.grid tr.late td.c-name .cell { color: var(--crit); }
.ch-latemark { fill: var(--crit); }

/* What this company has paid for. One line, at the top, never mid-task. */
.licence-bar {
  padding: 0.5rem 1.25rem; font-size: 0.88rem; font-weight: 600;
  background: var(--warn-wash); color: #7A4406; border-bottom: 1px solid #E7D3B0;
}
.licence-bar.lapsed { background: var(--crit-wash); color: var(--crit); border-bottom-color: #E4C4BE; }
.help { max-width: 46rem; }
.help h2 { font-size: 1.15rem; margin: 2rem 0 0.4rem; padding-top: 0.6rem; border-top: 1px solid var(--rule-soft); }
.help p, .help li { line-height: 1.6; }
.manual { max-width: 52rem; }
.manual h2 { scroll-margin-top: 4rem; }
.manual-toc { columns: 2; column-gap: 2rem; margin: 1rem 0 1.5rem; padding: 0.8rem 1rem; background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; }
.manual-toc ol { margin: 0; padding-left: 1.4rem; }
.manual-toc li { break-inside: avoid; line-height: 1.7; }
@media (max-width: 600px) { .manual-toc { columns: 1; } }
@media print { .manual { max-width: none; } .manual h2 { break-after: avoid; } }
.help-dl { display: grid; grid-template-columns: 10rem 1fr; gap: 0.3rem 1rem; margin: 0.6rem 0; }
.help-dl dt { font-weight: 600; }
.help-dl dd { margin: 0; color: var(--ink-soft); }
.help-steps li { margin-bottom: 0.4rem; }
.help-keys td:first-child { width: 11rem; white-space: nowrap; }
@media (max-width: 34rem) { .help-dl { grid-template-columns: 1fr; gap: 0.1rem; } }

/* --- The record, and the revision register ------------------------------
   A failed seal is the one message on this site that has to stop somebody,
   so it is the only notice that is allowed to shout. */
.notice.bad { border-left-width: 5px; font-weight: 600; }

.record-table td { vertical-align: top; }
.record-table td:first-child { white-space: nowrap; color: var(--ink-soft); }
.record-table td:nth-child(3) { max-width: 16rem; }
.empty-note { color: var(--ink-soft); font-style: italic; }
.tag { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em;
       background: var(--crit-wash); color: var(--crit); padding: 0 0.3rem; border-radius: 2px; }

.filter-bar { display: flex; gap: 1rem; align-items: flex-end; margin: 0 0 1rem; flex-wrap: wrap; }
.filter-bar label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.85rem; color: var(--ink-soft); }

/* Three actions in one cell, and they must not wrap into a stack of one-word
   lines on a narrow screen. */
.issue-actions { display: flex; gap: 0.7rem; align-items: baseline; white-space: nowrap; }
.issue-actions .inline-form { display: inline; }

/* --- Dropping a file on the import cards -------------------------------- */
.import-way { transition: background 0.12s, border-color 0.12s; }
.import-way.dropping { border-color: var(--accent); background: var(--accent-wash); }
/* The card is the target, so nothing inside it may swallow the drop. */
.import-way.dropping * { pointer-events: none; }
.dropzone { display: block; border: 1px dashed var(--rule); border-radius: 4px;
            padding: 0.7rem 0.9rem; cursor: pointer; color: var(--ink-soft); }
.dropzone input[type="file"] { display: block; margin-top: 0.45rem; }
.drop-name { display: block; margin-top: 0.35rem; font-size: 0.85rem; color: var(--ok); }
.drop-name.bad { color: var(--crit); }

/* --- A blank row -------------------------------------------------------
   Paul, 2026-09-15: "insert a blank row to separate tasks out, but it has no
   effect on the programme." So it reads as a gap, not as an empty task: no
   cell edges, no hover, nothing to click into. */
/* NO HEIGHT HERE. The chart draws every row at ONE height and stacks them,
   so a grid row of a different height puts the two panes out of step - and
   the error COMPOUNDS: nine short blank rows on Res - NorthFleet drifted the
   bottom of a 228-row programme six pixels away from its own bars. A blank
   row is a full row that happens to be empty. */
/* TRANSPARENT, NOT ABSENT. `border: 0` here took a real pixel off the row -
   a normal row is its 30px input plus a 1px border - and the chart, which
   stacks every row at one height, then drifted a pixel per blank row. Nine
   of them on Res - NorthFleet and the bars were 4px out of line with their
   own names by the middle of the programme. The border still has to occupy
   its pixel; it just must not be seen. */
/* THE SAME HEIGHT AS EVERY OTHER ROW, and both halves of that matter.
   A normal row is a 2rem input plus a 1px border. This cell has no input, so
   it needs the height stated (the same `2rem` the inputs use, so they move
   together if the scale ever changes) AND the border's pixel kept, invisible.
   The chart stacks every row at ONE height, so a grid row of a different
   height puts the two panes out of step and the error COMPOUNDS - nine short
   blank rows had the bars 4px away from their own names by the middle of a
   228-row programme, and worse the further down you looked. */
tr.spacer td.c-gap { border: 0; border-bottom: 1px solid transparent;
                     background: transparent; }
/* The height goes on the CONTENT, not the cell. Cells are `border-box`, so a
   height of 2rem on the cell INCLUDES the border and comes out a pixel short
   - which is the whole bug again. A normal cell gets its height from the 2rem
   input inside it plus its own border; this gives the empty one exactly the
   same, by the same 2rem, so the two cannot drift apart. */
tr.spacer td.c-gap::before { content: ""; display: block; height: 2rem; }
tr.spacer:hover td { background: transparent; }
tr.spacer td.c-ref { opacity: 0.35; }
tr.spacer:hover td.c-ref { opacity: 1; }
tr.spacer .ref-no { font-style: italic; }

/* --- Which revision am I looking at ------------------------------------- */
.rev-line { margin: 0.3rem 0 0; display: flex; gap: 0.6rem; align-items: baseline;
            font-size: 0.88rem; flex-wrap: wrap; }
.rev-badge { display: inline-block; padding: 0.1rem 0.5rem; border-radius: 3px;
             background: var(--ok-wash); color: var(--ok); font-weight: 600;
             text-decoration: none; border: 1px solid transparent; }
.rev-badge:hover { border-color: currentColor; }
/* Issued, then edited. Not the same programme as the one on site. */
.rev-badge.stale { background: var(--crit-wash); color: var(--crit); }
.rev-badge.draft { background: var(--accent-wash); color: var(--accent); font-weight: 500; }
.stale-note { color: var(--crit); }

/* --- Key Dates ----------------------------------------------------------
   NEC clause 31.2: a date the contract attaches consequences to. It is a
   mark on a task, not a colour scheme - one diamond in the ID cell, so it
   reads down the column without repainting the row. */
tr.key-date .ref-no::after { content: " ◆"; color: var(--warn, #A9781F); font-size: 0.85em; }
tr.key-date td.c-name { font-weight: 600; }
.ch-key-date { stroke: #A9781F; stroke-width: 1.6; fill: none; }

/* --- Folding a section away ---------------------------------------------
   The control sits in the section's own row, in front of its name, where its
   contents visibly begin. Absolute so it does not push the name cell about
   as sections fold and unfold. */
.fold-btn { position: absolute; top: 50%; transform: translateY(-50%);
            width: 1rem; height: 1rem; line-height: 1; padding: 0; border: 0;
            background: none; cursor: pointer; color: var(--ink-soft);
            font-size: 0.72rem; border-radius: 2px; }
.fold-btn:hover { color: var(--ink); background: var(--accent-wash); }
.fold-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* At the RIGHT-HAND end of the name cell, not after the name: the name is an
   input that fills its cell, so anything following it wrapped onto a line of
   its own and made every folded section two rows tall. */
.fold-count { position: absolute; right: 0.4rem; top: 50%; transform: translateY(-50%);
              font-size: 0.72rem; color: var(--ink-soft); font-style: italic;
              pointer-events: none; background: var(--paper, #fff); padding-left: 0.3rem; }

/* --- A colour per outline level -----------------------------------------
   Paul, 2026-09-15: the rows that have work under them get a pastel by how
   deep they are, so a long programme shows its shape without being read.

   :not(.selected) so selecting a row still reads as selected - same
   specificity would otherwise be settled by whichever rule came last in the
   file, which is not a thing to leave to chance. */
/* THE ID AND THE NAME, and nothing else. Paul, 2026-09-15: "I only want it
   to apply to ID number and task. The rest can stay as they are." Right: the
   colour is there to show the shape of the programme, and the columns that
   carry the shape are the number and the name. Running it under the dates
   and the percentages tinted the figures people actually read. */
.grid tr.tinted:not(.selected) td.c-ref,
.grid tr.tinted:not(.selected) td.c-wbs,
.grid tr.tinted:not(.selected) td.c-name { background: var(--row-tint); }
.grid tr.tinted:not(.selected):hover td.c-ref,
.grid tr.tinted:not(.selected):hover td.c-wbs,
.grid tr.tinted:not(.selected):hover td.c-name { filter: brightness(0.97); }
/* The name still has to carry: these are headings. */
.grid tr.tinted td.c-name .c-name-in { font-weight: 600; }

.row-menu-swatch { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.8rem;
                   font-size: 0.85rem; }
.row-menu-swatch input[type="color"] { width: 2.2rem; height: 1.4rem; padding: 0; border: 1px solid var(--rule);
                                       border-radius: 3px; background: none; cursor: pointer; }
.row-menu-swatch.muted { color: var(--ink-soft); font-style: italic; font-size: 0.78rem; }

.colour-subhead { margin: 1.4rem 0 0.2rem; font-size: 0.95rem; }
.level-colours { display: flex; gap: 1.2rem; flex-wrap: wrap; margin: 0.6rem 0 0.2rem; }
.level-colour { display: flex; align-items: center; gap: 0.45rem; font-size: 0.85rem; }
.level-colour input[type="color"] { width: 2.6rem; height: 1.6rem; padding: 0; border: 1px solid var(--rule);
                                    border-radius: 3px; background: none; cursor: pointer; }

/* A section's length, said once and said whole: weeks then days, ONE SIZE.
   Paul, 2026-09-15: "it should read 10.2w - 51d, same text height." No box
   and no unit button out here - a section's length is worked out from the
   tasks inside it, so there is nothing to type and nothing to swap, and a
   cell that looks like a control it is not invites a click that does
   nothing. Same right edge as every other number in the column. */
.dur-both {
  flex: 1; min-width: 0; text-align: right; padding-right: 0.15rem;
  font-family: var(--mono); font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ---- A COMPANY'S OWN MARK ------------------------------------------------
   Paul, 2026-09-15: "I want the ability, within a company's programmes, to
   brand it for that company." The top bar stays Clarity Planner; the
   programme is theirs. A logo is CONTAINED, never stretched - somebody will
   upload a 2000px wide banner and somebody else a square, and both have to
   sit on the same line without pushing the title about. */
.brand-mark { max-height: 2.6rem; max-width: 11rem; width: auto; object-fit: contain; align-self: center; margin-right: 0.9rem; }
.prog-head { display: flex; align-items: flex-start; gap: 0; }
/* The name on the left; the company's mark on the right with the dates and
   Settings under it (v0.91.0). */
.prog-head .prog-title { flex: 1 1 auto; min-width: 0; }
.prog-head .prog-side { display: flex; flex-direction: column; align-items: flex-end; gap: 0.5rem; margin-left: auto; }
.prog-head .prog-side .brand-mark { align-self: flex-end; margin-right: 0; }
.prog-head .prog-side .prog-meta { justify-content: flex-end; }
.brand-logo-preview { max-height: 3.5rem; max-width: 12rem; object-fit: contain; display: block; margin-bottom: 0.4rem; }
.brand-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 14rem); gap: 1.2rem; align-items: start; }
.brand-field { display: block; margin-top: 0.9rem; font-weight: 600; }
.brand-field input[type="text"] { display: block; width: 100%; margin-top: 0.3rem; font-weight: 400; }
.brand-colour-row { display: flex; align-items: center; gap: 0.7rem; margin-top: 0.3rem; font-weight: 400; }
.brand-now { text-align: right; }
.dropzone.disabled { opacity: 0.55; cursor: default; }
@media (max-width: 720px) { .brand-grid { grid-template-columns: minmax(0, 1fr); } .brand-now { text-align: left; } }

/* ---- WHICH DAY OF THE WEEK -----------------------------------------------
   Paul, 2026-09-15: "just have a letter that signifies the day of the week."
   A date input shows dd/mm/yyyy and there is no telling a Tuesday from a
   Saturday in that - which is the question a planner asks of every date on a
   programme.

   Its OWN COLUMN inside the cell, fixed width, so a run of them lines up down
   the page and the eye can scan for the weekend without reading a single
   date. Same size as the date, never shrunken: a second figure in small grey
   type was exactly the thing that read wrong in the length column. */
.date-wrap { display: flex; align-items: center; gap: 0.3rem; height: 2rem; }
.date-wrap .cell { flex: 1; min-width: 0; }
/* IN FRONT OF THE DATE, not after it. Paul: "should precede the date, not come
   at the end." Right-aligned in its own fixed column, so M, T and TH all
   finish at the same point and the dates start level whatever day it is. */
.day-letter {
  flex: none; width: 1.55rem; text-align: right; font-family: var(--mono);
  font-variant-numeric: tabular-nums; color: var(--ink-soft); white-space: nowrap;
}
/* In the properties panel the field is full width, so the letter sits after
   it on its own line rather than stealing width from the picker. */
.day-letter.props-day { display: inline-block; width: auto; margin-left: 0.4rem; text-align: left; }

/* ---- THE PLUS BETWEEN TWO ROWS -------------------------------------------
   Paul, 2026-09-15: "as you hover over a task, a little button comes up in
   between the lines where you can click a plus ... similar to tables in Word."

   Sits ON the line between this row and the next, half over each, so what you
   click is where the row appears. Hidden until the row is hovered: a plus on
   every line of a 228-row programme is 228 buttons.

   `position: relative` on the cell, absolute on the button - it is drawn
   OUTSIDE the row's own box without taking part in the layout, so it cannot
   change the row height. The chart stacks every row at one height and a row
   half a pixel taller walks the two panes apart all the way down. */
.grid td.c-ref { position: relative; }
.row-plus {
  position: absolute; left: 0.15rem; bottom: -0.55rem; z-index: 3;
  width: 1.1rem; height: 1.1rem; padding: 0; line-height: 1;
  border: 1px solid var(--rule); border-radius: 50%; background: var(--surface);
  color: var(--ink-soft); font-size: 0.78rem; font-weight: 700; cursor: pointer;
  display: none;
}
.grid tbody tr:hover .row-plus,
.row-plus:focus-visible { display: block; }
.row-plus:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
/* The blank-line button sits just to the right of the round one, and is
   SQUARE so the two read as different things at a glance. */
.row-plus.row-blank { left: 1.45rem; border-radius: 2px; }
/* The minus sits third, and goes red on hover so it can never be mistaken
   for either plus. */
.row-plus.row-minus { left: 2.75rem; }
.row-plus.row-minus:hover { background: var(--crit, #A63626); border-color: var(--crit, #A63626); color: #fff; }
/* The rows that would go, while the pointer rests on a minus. */
.grid tbody tr.doomed td { background: rgba(166, 54, 38, 0.13) !important; }
.grid tbody tr.doomed td.c-ref { box-shadow: inset 3px 0 0 var(--crit, #A63626); }
/* Touch has no hover, so on a tablet it is simply always there. */
@media (hover: none) { .grid tbody tr .row-plus { display: block; opacity: 0.45; } }

/* ---- PICKING THE LINES TO EXPORT ----------------------------------------
   A long table of tick boxes. The indent is set from JS - a style attribute
   in the template is dropped by the Content-Security-Policy without a word. */
.pick-table { width: 100%; }
.pick-table th.pick-tick, .pick-table td.pick-tick { width: 2.4rem; text-align: center; }
.pick-table tbody tr.is-summary { font-weight: 600; background: var(--paper); }
.pick-table tbody tr.is-spacer td { height: 1.2rem; }
.pick-table td.pick-name { max-width: 40rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-box { width: 1rem; height: 1rem; cursor: pointer; }
.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;
}

/* A date that RECORDS rather than plans. Quieter than the planned dates beside
   it: what was promised is the programme, what happened is the note against
   it, and the two should not read with the same weight. */
.grid td.c-date.actual .cell { color: var(--ink-soft); }

/* ---- THE NEEDS BAND (v0.70.0). Paul, 2026-09-21: a collapsible chart above the
   chart of what the tasks need - information released by, approvals by. The
   label side is HTML in the grid column; chart.js keeps both the same height. */
.needs-label {
  box-sizing: border-box; border-bottom: 1px solid var(--rule); background: #F4F6F8;
  position: sticky; top: 0; z-index: 6; overflow: hidden; font-size: 0.78rem;
}
.needs-sched { margin-left: auto; font-size: 0.75rem; color: var(--accent); white-space: nowrap; }
.needs-head { height: 24px; box-sizing: border-box; display: flex; align-items: center; gap: 0.5rem; padding: 0 0.4rem; border-bottom: 1px solid var(--rule-soft); }
.needs-fold { border: 0; background: none; padding: 0; cursor: pointer; font: inherit; font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); font-weight: 600; }
.needs-fold:hover { color: var(--accent); }
.needs-count { font-size: 0.72rem; color: var(--ink-faint); white-space: nowrap; }
.needs-lines { padding: 3px 0; }
.needs-line { height: 18px; line-height: 18px; box-sizing: border-box; display: flex; gap: 0.5rem; align-items: center; padding: 0 0.4rem 0 1rem; white-space: nowrap; overflow: hidden; cursor: pointer; }
.needs-line:hover { background: var(--accent-wash); }
.needs-line.is-head { padding-left: 0.4rem; font-size: 0.68rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; cursor: default; }
.needs-line.is-head:hover { background: none; }
.needs-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.needs-who { color: var(--ink-faint); max-width: 6rem; overflow: hidden; text-overflow: ellipsis; }
.needs-when { font-family: var(--mono, ui-monospace, monospace); font-size: 0.72rem; color: var(--ink-soft); }
.needs-line.is-late .needs-when, .needs-line.is-late .needs-name { color: var(--crit); font-weight: 600; }
.needs-line.is-due .needs-when { color: #A9781F; font-weight: 600; }
.needs-line.is-done { color: var(--ink-faint); text-decoration: line-through; }
.needs-line.is-focus { background: var(--accent-wash); }
.needs-band { display: block; position: sticky; top: 0; z-index: 2; border-bottom: 1px solid var(--rule); }
.needs-bg { fill: #FAFBFC; }
.needs-rowline { stroke: var(--rule-soft); stroke-width: 1; }
.needs-bar { cursor: pointer; }
.needs-span { fill: #5B7A99; opacity: 0.55; }
.needs-diamond { fill: #5B7A99; }
.needs-ghost { fill: none; stroke: #9AA5B1; stroke-width: 1; }
.needs-bar.is-due .needs-span, .needs-bar.is-due .needs-diamond { fill: #A9781F; }
.needs-bar.is-late .needs-span, .needs-bar.is-late .needs-diamond { fill: var(--crit); }
.needs-bar.is-done .needs-span, .needs-bar.is-done .needs-diamond { fill: #2E8B4F; }
.needs-bar.is-focus .needs-diamond { stroke: var(--ink); stroke-width: 1.5; }
.needs-lbl { font-size: 10px; fill: var(--ink-soft); dominant-baseline: middle; pointer-events: none; }
.ch-need-drop { stroke: var(--ink-soft); stroke-width: 1; stroke-dasharray: 3 3; fill: none; pointer-events: none; }

/* the Needs column and its tick list */
.grid td.c-needs { width: 8.25rem; padding: 0 0.3rem; }
.grid th.c-needs { width: 8.25rem; }
.needs-btn { border: 0; background: none; padding: 0.1rem 0.3rem; font: inherit; font-size: 0.8rem; color: var(--ink-faint); cursor: pointer; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; border-radius: 3px; }
.needs-btn.is-some { color: var(--ink); }
.needs-btn.is-late { color: var(--crit); font-weight: 600; }
.needs-btn:hover { background: var(--accent-wash); color: var(--accent); }
.needs-pick, .pick-pop {
  position: absolute; z-index: 60; background: var(--surface); border: 1px solid var(--rule); border-radius: 6px;
  box-shadow: 0 6px 20px rgba(22, 32, 43, 0.14); padding: 0.5rem 0.7rem; min-width: 15rem; max-width: 22rem; display: grid; gap: 0.2rem;
}
.needs-pick-lbl { margin: 0 0 0.25rem; font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; }
.needs-pick-item { font-size: 0.85rem; display: grid; grid-template-columns: auto 1fr; gap: 0 0.4rem; align-items: baseline; }
.needs-pick-item .needs-pick-hint { grid-column: 2; font-size: 0.72rem; color: var(--ink-faint); }
.needs-pick-own { font-size: 0.8rem; color: var(--ink-soft); }
.needs-pick-own.is-late { color: var(--crit); }
.needs-pick-own.is-done { color: var(--ink-faint); text-decoration: line-through; }
.needs-pick-more { font-size: 0.8rem; margin-top: 0.2rem; }
.props-needs { display: grid; gap: 0.2rem; margin-top: 0.2rem; }
.pick-pop-clear { justify-self: start; margin-top: 0.2rem; font-size: 0.8rem; }

/* a filter dropped from the heading itself */
.th-filter { border: 0; background: none; padding: 0 0.2rem; margin-left: 0.2rem; font-size: 0.7rem; color: var(--ink-faint); cursor: pointer; border-radius: 3px; vertical-align: middle; }
.th-filter:hover { color: var(--accent); background: var(--accent-wash); }
.th-filter.is-on { color: var(--accent); background: var(--accent-wash); }

/* Settings: the on-site tick and the Needs list */
.type-site-pick { font-size: 0.78rem; color: var(--ink-soft); white-space: nowrap; }
.need-list { grid-template-columns: 1fr; }
.need-item { flex-wrap: wrap; }
.need-name { min-width: 11rem; }
.need-edit { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; font-size: 0.8rem; color: var(--ink-soft); }
.need-edit select { font-size: 0.8rem; max-width: 12rem; }
.need-num { white-space: nowrap; }
.need-num input { width: 3.6rem; }
.need-who { width: 8rem; }
.need-add { flex-wrap: wrap; }
.leadin-from { font-size: 0.72rem; }
.leadin-unissued { font-size: 0.75rem; }

/* v0.71.0 - the period where the need is ticked, on the band, on the schedule; the notes log */
.needs-pick-period { grid-column: 2; display: inline-flex; gap: 0.25rem; align-items: center; font-size: 0.72rem; color: var(--ink-faint); }
.needs-pick-period input { width: 3.2rem; font-size: 0.75rem; padding: 0.05rem 0.2rem; }
.needs-when-edit { cursor: pointer; border-bottom: 1px dotted var(--ink-faint); }
.needs-when-edit:hover { color: var(--accent); border-bottom-color: var(--accent); }
.needs-line.is-editing { cursor: default; }
.needs-edit-box { display: inline-flex; gap: 0.25rem; align-items: center; font-size: 0.72rem; color: var(--ink-faint); }
.needs-edit-box input { width: 3.2rem; font-size: 0.75rem; padding: 0.05rem 0.2rem; height: 15px; }
.needs-edit-ok, .needs-edit-no { border: 0; background: none; cursor: pointer; font-size: 0.8rem; padding: 0 0.2rem; color: var(--ink-soft); }
.needs-edit-ok:hover { color: var(--ok); }
.needs-edit-no:hover { color: var(--crit); }
.leadin-period { display: flex; gap: 0.4rem; align-items: center; font-size: 0.75rem; color: var(--ink-faint); margin-top: 0.15rem; }
.leadin-period input { width: 3.4rem; font-size: 0.78rem; padding: 0.05rem 0.2rem; }
.leadin-period input[type=date] { width: 8.6rem; }
.leadin-period label { white-space: nowrap; }
.needs-pick-period input[type=date], .needs-edit-box input[type=date] { width: 7.6rem; }
.needs-pick-period { flex-wrap: wrap; }
.leadin-notes { margin-top: 0.2rem; font-size: 0.8rem; }
.leadin-notes > summary { cursor: pointer; color: var(--ink-faint); font-size: 0.75rem; }
.leadin-note { margin: 0.15rem 0 0; }
.leadin-note-add { display: flex; gap: 0.3rem; align-items: center; margin-top: 0.25rem; }
.leadin-note-add input { flex: 1 1 auto; min-width: 8rem; font-size: 0.8rem; }

/* v0.73.0 - the needs schedule as a chart, server-drawn SVG */
.needs-chart-wrap { overflow-x: auto; margin: 0.4rem 0 1rem; border: 1px solid var(--rule); border-radius: 4px; }
.needs-chart { display: block; font-family: var(--sans); }
.nc-bg { fill: #FAFBFC; }
.nc-week { stroke: var(--rule-soft); stroke-width: 1; }
.nc-week.is-month { stroke: var(--rule); }
.nc-week-lbl { font-size: 8px; fill: var(--ink-faint); font-family: var(--mono, ui-monospace, monospace); letter-spacing: 0; }
.nc-rule { stroke: var(--rule-soft); stroke-width: 1; }
.nc-head { font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; fill: var(--ink-faint); font-weight: 600; }
.nc-what { font-size: 11px; fill: var(--ink); }
.nc-what .nc-task { fill: var(--ink-soft); }
.nc-what.is-late { fill: var(--crit); font-weight: 600; }
.nc-what.is-done { fill: var(--ink-faint); }
.nc-who { font-size: 10px; fill: var(--ink-faint); }
.nc-date { font-size: 10px; fill: var(--ink-soft); font-family: var(--mono, ui-monospace, monospace); }
.nc-date.is-late { fill: var(--crit); font-weight: 600; }
.nc-date.is-due-soon { fill: #A9781F; font-weight: 600; }
.nc-span { fill: #5B7A99; opacity: 0.55; }
.nc-diamond { fill: #5B7A99; }
.nc-ghost { fill: none; stroke: #9AA5B1; stroke-width: 1; }
.nc-bar.is-due-soon .nc-span, .nc-bar.is-due-soon .nc-diamond { fill: #A9781F; }
.nc-bar.is-late .nc-span, .nc-bar.is-late .nc-diamond { fill: var(--crit); }
.nc-bar.is-done .nc-span, .nc-bar.is-done .nc-diamond { fill: #2E8B4F; }
.nc-today { stroke: var(--crit); stroke-width: 1; stroke-dasharray: 4 3; }
@media print { .needs-chart-wrap { overflow: visible; border: 0; } .needs-chart { max-width: 100%; height: auto; } }

/* v0.73.01 - the timeline runs alongside the rows */
.leadin-table th.nc-th, .leadin-table td.nc-td { padding: 0 0 0 0.4rem; vertical-align: middle; width: 60%; }
.leadin-table th.nc-th { vertical-align: bottom; }
/* The header scales proportionally so its month labels are not stretched; the
   row strip is a FIXED height and stretches in x only. Both scale x by the
   same factor, so the weeks line up. */
.nc-head-svg { display: block; width: 100%; height: 16px; }
.nc-row { display: block; width: 100%; height: 18px; overflow: visible; }
.leadin-table tr.leadin-family td { padding: 0.3rem 0.4rem 0.05rem; font-size: 0.7rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; border-bottom: 1px solid var(--rule); background: none; }
.leadin-sheet-scroll { overflow-x: auto; }
.release-btn { white-space: nowrap; }
.leadin-sheet-scroll .leadin-table { table-layout: fixed; width: 100%; min-width: 60rem; }
.leadin-table th.c-lead-task, .leadin-table td.c-lead-task { width: 13%; }
.leadin-table th.c-lead-date, .leadin-table td.c-lead-date { width: 9%; }
.leadin-table th.c-lead-what, .leadin-table td.c-lead-what { width: 18%; position: relative; }
.leadin-line { display: flex; gap: 0.35rem; align-items: baseline; min-width: 0; overflow: hidden; }
.leadin-line > * { flex: none; }
.leadin-line .leadin-what { flex: 0 1 auto; min-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leadin-edit { font-size: 0.72rem; }
.leadin-edit:not([open]) { display: inline-block; }
/* OPEN, IT IS A PANEL over the chart, so the row stays one line (Paul, 2026-09-21). */
.leadin-edit[open] { position: absolute; left: 0.4rem; top: 1.7rem; z-index: 6; width: 36rem; max-width: 80vw; background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; padding: 0.5rem 0.8rem 0.7rem; box-shadow: 0 8px 24px rgba(22, 32, 43, 0.14); white-space: normal; }
.leadin-edit[open] > summary { color: var(--ink-soft); }
.leadin-edit > summary { cursor: pointer; color: var(--accent); font-size: 0.75rem; }
.leadin-edit-lbl { margin: 0.45rem 0 0.15rem; font-size: 0.68rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; }
.leadin-edit .leadin-acts { display: flex; flex-wrap: wrap; gap: 0.3rem 0.6rem; align-items: center; }
.leadin-edit .leadin-acts form { display: inline-flex; gap: 0.3rem; align-items: center; }
.leadin-edit .leadin-acts input[type=date] { width: 9rem; }
.leadin-meta { display: inline-flex; gap: 0.3rem; align-items: baseline; font-size: 0.68rem; white-space: nowrap; min-width: 0; overflow: hidden; }
.leadin-line .leadin-meta { flex: 0 1 auto; }
.leadin-meta .leadin-meta-who, .leadin-meta .look-flag { overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; }
.leadin-meta .status-chip { flex: none; }
.leadin-table td.c-lead-task, .leadin-table td.c-lead-date, .leadin-table td.c-lead-what { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.leadin-table td.c-lead-what { overflow: visible; }
.leadin-what { font-weight: 600; }
.leadin-fixed-dot { color: var(--ink-soft); }
/* A SPREADSHEET, NOT A LIST. Paul, 2026-09-21: "a lot thinner ... a lot
   tighter" - the row is one line of small type with no padding to spare. */
.leadin-table.compact tbody { font-size: 0.82rem; line-height: 1.2; }
.leadin-table.compact tbody td { padding: 0.02rem 0.4rem; vertical-align: middle; }
.leadin-table.compact thead th { padding-top: 0.2rem; padding-bottom: 0.2rem; }
.leadin-table tbody .status-chip { font-size: 0.64rem; padding: 0 0.3rem; line-height: 1.35; }
.leadin-table tbody .look-flag { font-size: 0.64rem; padding: 0 0.3rem; }
.leadin-meta-who { color: var(--ink-soft); }

/* v0.75.0 - the timescale and the look-ahead, squeezed onto the bar */
.zoom-bar { gap: 0.25rem; }
/* Narrower sides only: the height is the bar's own, so every button's top sits
   on one line (Paul, 2026-09-23). The group has its OWN class - "look-bar" is
   the Look-ahead page's picker, and sharing it lifted this group 8px. */
.zoom-bar .button-secondary, .lookahead-bar .button-secondary { padding-left: 0.5rem; padding-right: 0.5rem; }
.lookahead-bar { gap: 0.25rem; }
.lookahead-lbl { font-size: 0.68rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; margin-right: 0.1rem; white-space: nowrap; }
.lookahead-bar .look-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.look-btn { white-space: nowrap; }

/* the site board: who gets it, and what is missing */
.board-dist { font-size: 0.85rem; color: var(--ink-soft); margin: 0 0 0.8rem; }
.board-untyped { color: var(--ink-soft); }
.board-none-hint { font-size: 0.72rem; font-weight: 400; color: var(--crit); margin-left: 0.3rem; }

/* Settings > Who gets reports */
.dist-scroll { overflow-x: auto; }
.dist-table { width: 100%; }
.dist-table th.dist-rep { text-align: center; vertical-align: bottom; min-width: 8rem; }
.dist-rep-name { display: block; font-weight: 600; }
.dist-rep-what { display: block; font-size: 0.68rem; color: var(--ink-faint); font-weight: 400; text-transform: none; letter-spacing: 0; white-space: normal; margin-top: 0.15rem; }
.dist-table td.dist-tick { text-align: center; }
.dist-tick input[type=checkbox] { width: 1.05rem; height: 1.05rem; }
.dist-when td { background: var(--accent-wash); vertical-align: top; }
.dist-when select { font-size: 0.75rem; max-width: 8.5rem; margin: 0 0 0.2rem; }
.dist-send { font-size: 0.72rem; }
/* The timing panel (v0.78.0): opens in its cell, which widens while it is open. */
.when-pick { display: block; margin: 0 0 0.25rem; text-align: left; }
.when-pick > summary { list-style: none; cursor: pointer; display: block; padding: 0.25rem 0.4rem; border: 1px solid var(--rule); border-radius: 4px; background: var(--surface); font-size: 0.74rem; line-height: 1.3; }
.when-pick > summary::-webkit-details-marker { display: none; }
.when-pick > summary:hover, .when-pick[open] > summary { border-color: var(--accent); }
.when-text { display: block; color: var(--ink); }
.when-next { display: block; color: var(--ink-faint); font-size: 0.7rem; }
.when-change { display: block; color: var(--accent); text-decoration: underline; font-size: 0.7rem; }
.when-pick[open] .when-change { display: none; }
/* THE PANEL FILLS ITS CELL, and nothing in it is wider than it (v0.81.03,
   Paul's screenshot: a 13.5rem panel under a wider box, its drop-downs and
   the Thu box running out past its edge). A grid item's minimum is its
   content unless told otherwise, so the labels, the drop-downs and the day
   grid are all told they may shrink to the panel. */
.when-form { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.45rem; width: 100%; min-width: 15rem; margin-top: 0.35rem; padding: 0.6rem 0.7rem; border: 1px solid var(--rule); border-radius: 4px; background: var(--surface); font-size: 0.8rem; }
.when-form label { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.15rem; min-width: 0; font-size: 0.74rem; color: var(--ink-soft); }
.dist-when .when-form select { max-width: 100%; width: 100%; min-width: 0; font-size: 0.8rem; margin: 0; }
.when-days { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.25rem 0.4rem; }
.when-days legend { font-size: 0.74rem; color: var(--ink-soft); padding: 0; margin-bottom: 0.15rem; }
.when-form .when-day { display: inline-flex; align-items: center; gap: 0.2rem; font-size: 0.78rem; color: var(--ink); }
.when-now { min-height: 1.4rem; }
.when-month select { min-width: 0; }
.when-actions { display: flex; justify-content: flex-start; }
.dist-auto { display: inline; }
.dist-name input, .dist-email input { width: 100%; min-width: 8rem; font-size: 0.85rem; }
.dist-jobs > summary { cursor: pointer; font-size: 0.8rem; color: var(--accent); white-space: nowrap; }
.dist-jobs-list { display: grid; gap: 0.15rem; margin-top: 0.3rem; font-size: 0.8rem; min-width: 12rem; }
.dist-add { margin-top: 0.8rem; flex-wrap: wrap; }
.dist-job { margin-right: 0.25rem; }
/* v0.76.0 - the rest of what goes by itself, under the grid */
.dist-sub { margin-top: 1.4rem; font-size: 1rem; }
.dist-extra { max-width: 60rem; }
.dist-extra-what { text-align: left; }
.dist-extra-what .hint { display: block; max-width: 42rem; white-space: normal; }
/* v0.77.0 - per job */
.dist-add-wrap { display: grid; gap: 0.2rem; }
.dist-book select { max-width: 28rem; }
.dist-book-table { max-width: 52rem; }
.dist-overview td { vertical-align: top; }
.dist-ov-cell { font-size: 0.78rem; white-space: nowrap; }

/* ==== THE CLARITY BAR (v0.96.0) ==========================================
   Shared by Clarity Planner, Clarity Resource and Clarity PC Site Manager -
   copy this block, do not redraw it (0000-Software/CLARITY BANNER AND HELP.md).
   One dark for every product and every customer; Green 2 marks where you are
   and that a new version is ready. */
:root {
  --cbar-bg: #17231C; --cbar-ink: #FFFFFF; --cbar-ink-soft: rgba(255, 255, 255, 0.74);
  --cbar-accent: #49A91D; --cbar-deep: #096126; --crow-rule: #D7DED9;
}
.cbar { display: flex; align-items: center; gap: 1.4rem; height: 56px; padding: 0 1.1rem; background: var(--cbar-bg); color: var(--cbar-ink);
  font-family: var(--sans); position: relative; z-index: 20; }
.cbar-prod { display: inline-flex; align-items: center; gap: 0.6rem; flex: none; color: var(--cbar-ink); text-decoration: none; }
.cbar-prod img { width: 30px; height: 30px; display: block; }
.cbar-prod span { font-size: 17px; font-weight: 400; letter-spacing: 0.01em; white-space: nowrap; }
.cbar-prod b { font-weight: 700; }
.cbar-tabs { display: flex; gap: 0.15rem; align-self: stretch; }
.cbar-tabs a, .cbar-menu nav a { display: inline-flex; align-items: center; padding: 0 0.75rem; color: var(--cbar-ink-soft); font-size: 14.5px; font-weight: 600;
  text-decoration: none; border-top: 3px solid transparent; border-bottom: 3px solid transparent; }
.cbar-tabs a:hover, .cbar-tabs a:focus-visible { color: var(--cbar-ink); }
.cbar-tabs a[aria-current="page"] { color: var(--cbar-ink); border-bottom-color: var(--cbar-accent); }
.cbar-menu { display: none; position: relative; }
.cbar-menu > summary { list-style: none; cursor: pointer; color: var(--cbar-ink); font-weight: 600; border: 1px solid rgba(255, 255, 255, 0.4); border-radius: 6px; padding: 0.3rem 0.7rem; }
.cbar-menu > summary::-webkit-details-marker { display: none; }
.cbar-menu nav { position: absolute; left: 0; top: calc(100% + 0.5rem); min-width: 12rem; background: #fff; border: 1px solid var(--crow-rule); border-radius: 6px;
  box-shadow: 0 8px 24px rgba(22, 32, 43, 0.16); display: flex; flex-direction: column; padding: 0.3rem 0; }
.cbar-menu nav a { color: var(--ink); padding: 0.5rem 0.9rem; border: 0; border-left: 3px solid transparent; }
.cbar-menu nav a[aria-current="page"] { border-left-color: var(--cbar-accent); color: var(--cbar-deep); }
.cbar-side { margin-left: auto; display: flex; align-items: center; gap: 1rem; white-space: nowrap; min-width: 0; }
.cbar-chip { background: #fff; border-radius: 6px; padding: 4px 9px; display: inline-flex; align-items: center; height: 32px; box-sizing: border-box; flex: none; }
.cbar-chip img { max-height: 24px; max-width: 140px; display: block; }
.cbar-chip-name { color: var(--cbar-bg); font-size: 13px; font-weight: 700; max-width: 14rem; overflow: hidden; text-overflow: ellipsis; display: inline-block; line-height: 24px; }
.cbar-help { color: var(--cbar-ink); font-weight: 600; text-decoration: none; }
.cbar-help:hover, .cbar-help:focus-visible { text-decoration: underline; }
.cbar-who { color: var(--cbar-ink-soft); font-size: 14px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.cbar-out { font: inherit; font-weight: 600; font-size: 14px; color: var(--cbar-ink); background: transparent; border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 6px; padding: 0.3rem 0.7rem; cursor: pointer; }
.cbar-out:hover, .cbar-out:focus-visible { background: rgba(255, 255, 255, 0.12); }
.cbar a:focus-visible, .cbar button:focus-visible, .cbar summary:focus-visible { outline: 2px solid var(--cbar-accent); outline-offset: 2px; }
/* WHERE IT FOLDS - measured, and the same on every Clarity product
   (v0.96.01). The bar wants ~900px with four tabs, the chip, Help, the name
   and Sign out; at 700-780 it ran off the edge. So the name goes under
   1000px, the tabs fold into Menu under 820px, the chip and the product's
   name under 520px - the numbers Clarity Resource measured too. */
@media (max-width: 999px) { .cbar-who { display: none; } }
@media (max-width: 819px) {
  .cbar { height: 52px; gap: 0.8rem; padding: 0 0.75rem; }
  .cbar-tabs { display: none; }
  .cbar-menu { display: block; }
  .cbar-prod span { font-size: 15px; }
  .cbar-side { gap: 0.7rem; }
}
@media (max-width: 519px) { .cbar-chip, .cbar-prod span { display: none; } }
/* The row under the bar: Back first, in the shared button shape. */
.crow { min-height: 48px; box-sizing: border-box; }
.crow-back { font: inherit; font-size: 0.9rem; font-weight: 600; color: var(--ink); background: #fff; border: 1px solid var(--crow-rule);
  border-radius: 6px; padding: 0.3rem 0.75rem; cursor: pointer; text-decoration: none; display: inline-block; white-space: nowrap; }
.crow-back:hover, .crow-back:focus-visible { border-color: var(--cbar-deep); color: var(--cbar-deep); }
/* The update strip: the same green and words on every product. */
.netbar-new { background: var(--cbar-accent); color: #fff; font-weight: 600; justify-content: center; border-bottom-color: var(--cbar-accent); }
.netbar-reload { font: inherit; font-weight: 600; background: #fff; color: var(--cbar-deep); border: 0; border-radius: 6px; padding: 0.2rem 0.8rem; cursor: pointer; }
/* ==== end of the Clarity bar ============================================= */

/* ==== THE CLARITY HELP (v0.97.0) =========================================
   The shared manual layout, the same as Clarity Resource's: an index of topic
   cards with a search box, then a topic page with the contents down the side
   (200px) and the article (up to 760px). 0000-Software/CLARITY BANNER AND HELP.md. */
.helpmain { display: block; padding: 0 1rem; }
.helpidx { max-width: 1000px; margin: 24px auto; padding: 22px 26px; background: #fff; border-radius: 10px; box-shadow: 0 1px 3px rgba(23, 35, 28, 0.08); }
.helpmast { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }
.helpmast img { flex: none; display: block; border-radius: 11px; }
.helpmast h1 { margin: 2px 0 0; font-size: 26px; }
.helpmast .eyebrow { font-family: var(--sans); font-size: 11px; letter-spacing: 0.12em; color: #8a93a0; margin: 0; }
.helpsearch { margin: 16px 0 6px; }
.helpsearch input { width: 100%; box-sizing: border-box; padding: 9px 12px; font: inherit; font-size: 14.5px; border: 1px solid #b8c0ca; border-radius: 8px; }
.helpsearch input:focus { outline: 2px solid var(--cbar-accent); outline-offset: 1px; }
.helpsearch p { margin: 6px 0 0; font-size: 12.5px; min-height: 1em; }
.helpnone { margin: 10px 0 0; }
.helpgroup { margin-top: 26px; }
.helpgroup > h2 { margin: 0; font-family: var(--sans); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: #8a93a0; font-weight: 600; }
.helpgrid { display: grid; gap: 12px; margin-top: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 699px) { .helpgrid { grid-template-columns: minmax(0, 1fr); } }
.helpcard { display: block; text-decoration: none; color: inherit; background: #fff; border: 1px solid var(--crow-rule); border-radius: 8px; padding: 12px 16px; }
.helpcard:hover, .helpcard:focus-visible { border-color: var(--cbar-accent); background: #FBFDFB; }
.helpcard strong { display: block; color: var(--cbar-deep); font-weight: 700; font-size: 15px; }
.helpcard span { display: block; color: #5a6672; font-size: 13.5px; margin-top: 2px; }
.helpmore { margin-top: 22px; font-size: 13.5px; color: #5a6672; }
.helpback { margin: 18px 0 0; font-weight: 600; }
.helpback a, .helpmore a { color: var(--cbar-deep); }
.helpwrap { display: grid; grid-template-columns: 200px minmax(0, 760px); gap: 28px; max-width: 1040px; margin: 24px auto; align-items: start; }
.helpcontents { position: sticky; top: 14px; font-size: 14px; }
.helpcontents > summary { display: none; }
.helpcontents-title { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: #8a93a0; margin: 0 0 6px 10px; font-weight: 600; }
.helpcontents nav a { display: block; padding: 5px 10px; border-radius: 6px; color: #1c2430; text-decoration: none; }
.helpcontents nav a:hover { background: #F2F5F3; }
.helpcontents nav a[aria-current="page"] { background: #EEF2EF; color: var(--cbar-deep); font-weight: 700; }
.helparticle { background: #fff; border-radius: 10px; padding: 20px 26px; box-shadow: 0 1px 3px rgba(23, 35, 28, 0.08); min-width: 0; }
@media (max-width: 899px) {
  .helpwrap { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .helpcontents { position: static; background: #fff; border-radius: 10px; padding: 8px 14px; }
  .helpcontents > summary { display: list-item; cursor: pointer; font-weight: 700; color: var(--cbar-deep); }
  .helpcontents-title { display: none; }
}
.crumb { margin: 0 0 8px; font-size: 12.5px; color: #66707d; }
.crumb a { color: inherit; }
.inshort { background: #EEF2EF; border-left: 4px solid var(--cbar-accent); border-radius: 0 6px 6px 0; padding: 10px 14px; margin: 12px 0 6px; font-size: 14.5px; max-width: 760px; }
.inshort strong { color: var(--cbar-deep); margin-right: 6px; }
.helpbody { margin-top: 14px; }
.related { margin-top: 26px; padding-top: 12px; border-top: 1px solid #e2e7ed; font-size: 14px; color: #5a6672; }
.related a { color: var(--cbar-deep); font-weight: 600; }
.helpall-actions { display: flex; gap: 1rem; align-items: center; margin: 12px 0; }
.helpall .manual > h2 { margin-top: 2rem; padding-bottom: 5px; border-bottom: 1px solid #e2e7ed; }
@media print { .helpidx, .helparticle { box-shadow: none; padding: 0; } .helpcontents { display: none; } }
/* ==== end of the Clarity help ============================================ */

/* ---- An item's details, from the Information and approvals band (v0.98.0) ---- */
.need-card { position: absolute; z-index: 60; width: 30rem; max-width: calc(100vw - 16px); box-sizing: border-box; background: #fff; border: 1px solid var(--rule);
  border-radius: 8px; box-shadow: 0 10px 30px rgba(22, 32, 43, 0.18); padding: 0.9rem 1rem 0.8rem; font-family: var(--sans); font-size: 0.9rem; }
.need-card-head { display: flex; align-items: flex-start; gap: 0.6rem; }
.need-card-title { flex: 1; min-width: 0; }
.need-card-title b { display: block; font-size: 1rem; }
.need-card-task { display: block; color: var(--ink-soft); font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.need-card-pill { flex: none; font-size: 0.75rem; font-weight: 600; border-radius: 999px; padding: 0.15rem 0.6rem; background: var(--accent-wash); color: var(--ink-soft); }
.need-card-pill.is-late { background: var(--crit-wash); color: var(--crit); }
.need-card-pill.is-due { background: #FFF4D6; color: #7A5A12; }
.need-card-pill.is-done { background: #E6F4EA; color: #1F5130; }
.need-card-x { flex: none; font: inherit; font-size: 1.2rem; line-height: 1; background: none; border: 0; color: var(--ink-soft); cursor: pointer; padding: 0 0.2rem; }
.need-card-facts { margin: 0.5rem 0 0.6rem; color: var(--ink-soft); font-size: 0.85rem; }
.need-card-say { margin: 0 0 0.5rem; padding: 0.35rem 0.6rem; border-radius: 4px; background: #E6F4EA; color: #1F5130; font-size: 0.85rem; }
.need-card-say.is-bad { background: var(--crit-wash); color: var(--crit); }
.need-card-row { display: grid; grid-template-columns: 5.5rem 1fr; align-items: center; gap: 0.2rem 0.6rem; margin: 0.35rem 0; }
.need-card-lbl { font-weight: 600; font-size: 0.85rem; margin: 0; }
.need-card-in { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; }
.need-card-in input { font: inherit; font-size: 0.88rem; padding: 0.2rem 0.35rem; border: 1px solid var(--rule); border-radius: 4px; }
.need-card-in input[type="number"] { width: 4.2rem; }
.need-card-in input[type="text"], .need-card-in input[type="email"] { flex: 1 1 8rem; min-width: 0; }
.need-card-hint { grid-column: 2; font-size: 0.75rem; color: var(--ink-faint); }
.need-card-acts { display: flex; gap: 0.8rem; align-items: center; margin: 0.6rem 0 0.2rem; }
.need-card-notes { margin-top: 0.7rem; padding-top: 0.6rem; border-top: 1px solid var(--rule); }
.need-card-log { list-style: none; margin: 0.3rem 0; padding: 0; max-height: 8.5rem; overflow-y: auto; }
.need-card-log li { padding: 0.2rem 0; border-bottom: 1px solid #EEF1F4; font-size: 0.85rem; display: flex; flex-direction: column; }
.need-card-when { font-size: 0.72rem; color: var(--ink-faint); }
.need-card-none { color: var(--ink-faint); border-bottom: 0 !important; }
.need-card-add { display: flex; gap: 0.4rem; margin-top: 0.3rem; }
.need-card-add input { flex: 1; min-width: 0; font: inherit; font-size: 0.88rem; padding: 0.25rem 0.4rem; border: 1px solid var(--rule); border-radius: 4px; }
.need-card-foot { display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; align-items: center; margin-top: 0.7rem; padding-top: 0.5rem; border-top: 1px solid var(--rule); font-size: 0.85rem; }
.need-card-foot .danger { margin-left: auto; }
.needs-bar { cursor: pointer; }

/* Copied from PC Site Manager v4.102.0 (Paul approved the banner for every Clarity product). */
/* ---------------------------------------------------------------------------
   Install as an app - the BANNER (v4.102.0). Paul, 2026-10-01: "a lot more
   visible, so it's clear what we're asking them to do and not part of the
   tables and badges". Full width above the page title, the strong Clarity
   green, white text, one big white button. Nothing else in the app looks like
   this, which is the point.
   --------------------------------------------------------------------------- */
.install-banner {
  position: relative;
  margin: 0 0 22px;
  padding: 20px 24px;
  border-radius: 14px;
  color: #fff;
  background: #1E8C2E;
  background: linear-gradient(100deg, #096126 0%, #1E8C2E 55%, #49A91D 100%);
  box-shadow: 0 6px 18px rgba(9, 97, 38, 0.28);
}
.install-banner-row {
  display: flex;
  gap: 22px;
  align-items: center;
  padding-right: 26px;
}
.install-banner-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 84px;
  padding: 5px;
  border-radius: 19px;
  background: #fff;
  color: #096126;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.25);
}
.install-banner-icon img { display: block; width: 74px; height: 74px; }
.install-banner-icon .ui-icon { width: 40px; height: 40px; margin: 0; }
.install-banner-icon-done { border-radius: 50%; }
.install-banner-body { flex: 1; min-width: 0; }
.install-banner .install-banner-kicker {
  margin: 0 0 2px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.9;
}
.install-banner .install-banner-title {
  margin: 0 0 4px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  font-size: 1.55rem;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: 0;
  text-transform: none;
}
.install-banner .install-banner-why { margin: 0; font-size: 1rem; opacity: 0.95; }
.install-banner a { color: #fff; }
.install-banner-actions {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.install-banner .install-banner-cta {
  display: inline-flex;
  gap: 10px;
  align-items: center;
  justify-content: center;
  padding: 14px 26px;
  border: none;
  border-radius: 10px;
  background: #fff;
  color: #096126;
  font-size: 1.12rem;
  font-weight: 800;
  text-decoration: none;
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.18);
}
.install-banner .install-banner-cta:hover { background: #F0F8F2; }
.install-banner .install-banner-cta:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
.install-banner-cta svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.install-banner-links {
  display: flex;
  justify-content: center;
  gap: 18px;
  font-size: 0.92rem;
}
.install-banner .install-banner-links a,
.install-banner .install-banner-links .link-button {
  padding: 0;
  border: none;
  background: none;
  color: #fff;
  font: inherit;
  text-decoration: underline;
}
.install-banner-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 30px;
  margin: 16px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.35);
  list-style: none;
  font-size: 0.95rem;
}
.install-banner-steps li { display: flex; gap: 9px; align-items: center; }
.install-banner-steps b {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: #fff;
  color: #096126;
  font-size: 0.85rem;
}
.install-banner .install-banner-close {
  position: absolute;
  top: 8px;
  right: 10px;
  padding: 2px 8px;
  border: none;
  background: none;
  color: #fff;
  font-size: 1.4rem;
  line-height: 1;
  opacity: 0.85;
}
.install-banner .install-banner-close:hover { opacity: 1; background: none; }
@media (max-width: 860px) {
  .install-banner-row { flex-wrap: wrap; padding-right: 0; }
  .install-banner-actions { width: 100%; }
}
/* The Planner's one addition: a tick in the done tile (it has no icon set with a check). */
.install-banner-tick { font-size: 40px; font-weight: 800; line-height: 1; color: #096126; }
.install-banner .link-button { cursor: pointer; }

/* ==== THE REPORTS SCREEN (v0.99.0) =======================================
   Every report down the left, the one picked on the right, the list staying
   put as you go from one to the next. Under 900px the list becomes a strip
   across the top that scrolls sideways in itself. */
.reports-shell { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 1.2rem; align-items: start; padding: 0 1rem 0 0.9rem; }
.reports-nav { position: sticky; top: 0.8rem; margin-top: 1.1rem; background: #fff; border: 1px solid var(--rule); border-radius: 8px; padding: 0.5rem 0.4rem 0.7rem;
  display: flex; flex-direction: column; max-height: calc(100vh - 1.6rem); overflow-y: auto; box-sizing: border-box; }
.reports-nav-home { display: block; padding: 0.45rem 0.6rem; margin-bottom: 0.2rem; border-radius: 6px; font-weight: 700; color: var(--cbar-deep); text-decoration: none; }
.reports-nav-group { margin: 0.7rem 0.6rem 0.25rem; font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 600; color: var(--ink-faint); }
.reports-nav-item { display: block; padding: 0.38rem 0.6rem; border-radius: 6px; color: var(--ink); text-decoration: none; font-size: 0.92rem; line-height: 1.25; border-left: 3px solid transparent; }
a.reports-nav-item:hover, .reports-nav-home:hover { background: #F2F5F3; }
.reports-nav-item.is-here, .reports-nav-home.is-here { background: #EEF2EF; color: var(--cbar-deep); font-weight: 700; border-left-color: var(--cbar-accent); }
.reports-nav-item.is-off { color: var(--ink-faint); cursor: not-allowed; }
.reports-nav-item small { display: block; font-size: 0.72rem; }
/* the report has the whole width beside the list - a look-ahead chart is a chart */
.reports-main.page { width: auto; margin: 1.1rem 0 2rem; max-width: none; }
.reports-main.page-wide { width: auto; margin: 1.1rem 0 1.2rem; }
.reports-group { margin-top: 1.4rem; }
.reports-group > h2 { margin: 0 0 0.5rem; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); font-weight: 600; }
.reports-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 0.7rem; }
.reports-card { display: block; background: #fff; border: 1px solid var(--crow-rule); border-radius: 8px; padding: 0.7rem 0.9rem; text-decoration: none; color: inherit; }
a.reports-card:hover, a.reports-card:focus-visible { border-color: var(--cbar-accent); background: #FBFDFB; }
.reports-card strong { display: block; color: var(--cbar-deep); }
.reports-card span { display: block; font-size: 0.85rem; color: var(--ink-soft); margin-top: 0.15rem; }
.reports-card.is-off strong { color: var(--ink-faint); }
@media (max-width: 899px) {
  .reports-shell { grid-template-columns: minmax(0, 1fr); padding: 0 0.6rem; gap: 0; }
  .reports-nav { position: static; flex-direction: row; overflow-x: auto; overflow-y: hidden; max-height: none; white-space: nowrap; gap: 0.2rem; padding: 0.35rem; margin-top: 0.8rem; }
  .reports-nav-group { display: none; }
  .reports-nav-item, .reports-nav-home { flex: none; margin: 0; border-left: 0; border-bottom: 3px solid transparent; }
  .reports-nav-item.is-here, .reports-nav-home.is-here { border-bottom-color: var(--cbar-accent); }
  .reports-nav-item small { display: none; }
}
@media print { .reports-shell { display: block; padding: 0; } .reports-main.page, .reports-main.page-wide { margin: 0; } }
/* ==== end of the Reports screen ========================================== */

/* ==== THE RIBBON (v1.0.0) ================================================
   Paul, 2026-10-03: MS Project / Asta Easy Plan's way of setting out the
   buttons - "lets go folded, i like that option, but an option to pin open".
   Folded: the tab row only; a tab drops its buttons OVER the chart. Pinned
   (html.rb-pinned, the default since v1.1.02): the buttons sit under the
   tabs, in the page. */
.programme-page .grid-toolbar.rb { display: block; position: relative; z-index: 25; margin: 0 0 0.45rem; gap: 0; flex-wrap: nowrap;
  background: #fff; border: 1px solid #D5DCD8; border-radius: 6px; }
.rb-tabs { display: flex; align-items: stretch; height: 34px; padding-left: 0; border-bottom: 1px solid transparent; }
.rb.rb-open .rb-tabs { border-bottom-color: #D5DCD8; }
.rb-file, .rb-tab { font: inherit; font-size: 0.9rem; border: 0; background: none; cursor: pointer; padding: 0 0.95rem; color: #2B3440; }
.rb-file { background: var(--cbar-deep); color: #fff; font-weight: 600; border-radius: 5px 0 0 0; margin-right: 0.3rem; }
.rb-file:hover, .rb-file.on { background: #0B7A30; }
.rb-tab { border-bottom: 3px solid transparent; margin-bottom: -1px; }
.rb-tab:hover { background: #F2F5F3; }
.rb-tab.on { color: var(--cbar-deep); font-weight: 700; border-bottom-color: var(--cbar-accent); background: #F7F9F8; }
.rb-file:focus-visible, .rb-tab:focus-visible, .rb-qat-btn:focus-visible, .rb-pin:focus-visible, .rb-big:focus-visible, .rb-small:focus-visible { outline: 2px solid var(--cbar-accent); outline-offset: -2px; }
.rb-spacer { flex: 1; }
.rb-qat { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0 0.4rem 0 0.6rem; border-left: 1px solid #E1E6E3; }
.rb-qat-btn, .rb-pin { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 28px; padding: 0; border: 1px solid transparent; border-radius: 4px; background: none; cursor: pointer; color: var(--ink); }
.rb-qat-btn:hover:not(:disabled), .rb-pin:hover { background: #F2F5F3; border-color: #D5DCD8; }
.rb-qat-btn:disabled { opacity: 0.4; cursor: default; }
.rb-qat-btn .ricon { width: 18px; height: 18px; }
.rb-qat-btn .ico { width: 18px; height: 18px; }
.rb-qat-btn[aria-pressed="true"] { background: var(--accent); color: #fff; }
.rb-find { display: inline-flex; margin: 0 0.25rem; }
.rb-find .find-box.find-slim { width: 10rem; height: 26px; }
.rb-pin svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.rb-pin[aria-pressed="true"] { background: #DCEBDF; border-color: #9CC8A8; color: var(--cbar-deep); }
.rb-pin[aria-pressed="true"] svg { fill: currentColor; }
.rb-qat .toolbar-help { margin: 0 0.15rem; }
/* the buttons */
.rb-body { position: absolute; left: -1px; right: -1px; top: 100%; background: #F7F9F8; border: 1px solid #D5DCD8; border-top: 0; border-radius: 0 0 6px 6px;
  box-shadow: 0 12px 26px rgba(22, 32, 43, 0.18); display: none; }
.rb.rb-open .rb-body { display: block; }
html.rb-pinned .rb-body { position: static; box-shadow: none; border: 0; border-radius: 0 0 6px 6px; }
.rb-panel { display: flex; align-items: stretch; min-height: 92px; padding: 4px 4px 0; overflow-x: auto; }
.rb-panel[hidden] { display: none; }
.rb-group { display: flex; flex-direction: column; padding: 0 0.4rem; border-right: 1px solid #DCE2DE; flex: none; }
.rb-items { flex: 1; display: flex; align-items: flex-start; gap: 2px; }
.rb-label { text-align: center; font-size: 0.72rem; color: #5E6A64; padding: 3px 0 4px; white-space: nowrap; }
.ricon { display: block; flex: none; }
.rb-big { display: inline-flex; flex-direction: column; align-items: center; gap: 3px; min-width: 54px; padding: 4px 6px 3px; border: 1px solid transparent; border-radius: 4px;
  background: none; font: inherit; font-size: 0.78rem; color: #2B3440; line-height: 1.15; text-align: center; cursor: pointer; text-decoration: none; list-style: none; }
.rb-big > span { white-space: nowrap; }
.rb-big .ricon { width: 32px; height: 32px; }
.rb-small { display: inline-flex; align-items: center; gap: 6px; height: 23px; padding: 1px 7px; border: 1px solid transparent; border-radius: 3px; background: none;
  font: inherit; font-size: 0.8rem; color: #2B3440; white-space: nowrap; cursor: pointer; text-decoration: none; list-style: none; }
.rb-small .ricon { width: 16px; height: 16px; }
.rb-big:hover, .rb-small:hover, details[open] > .rb-big, details[open] > .rb-small { background: #E8F1EA; border-color: #B7D6BF; }
.rb-big[aria-pressed="true"], .rb-small[aria-pressed="true"] { background: #DCEBDF; border-color: #9CC8A8; }
.rb-big.is-off, .rb-small.is-off { color: var(--ink-faint); cursor: not-allowed; opacity: 0.55; }
.rb-big:disabled, .rb-small:disabled { opacity: 0.45; cursor: default; }
summary.rb-big::-webkit-details-marker, summary.rb-small::-webkit-details-marker { display: none; }
.rb-stack { display: flex; flex-direction: column; gap: 1px; padding-top: 1px; }
.rb-note { max-width: 22rem; font-size: 0.8rem; color: var(--ink-soft); padding: 0.6rem 0.4rem; white-space: normal; }
.rb .ico-count { font-weight: 700; }
/* the old bar's groups, inside a ribbon group: the timescale and look-ahead letters */
.rb .zoom-bar, .rb .lookahead-bar { display: inline-flex; align-items: center; padding-top: 1.2rem; }
.rb .lookahead-bar .lookahead-lbl { display: none; }
/* the ribbon's drop-downs open under their button, inside the window */
.rb .rb-group > .rb-items > details, .rb .rb-stack > details { position: relative; }
.programme-page .grid-toolbar.rb .view-menu .view-panel, .programme-page .grid-toolbar.rb .print-panel,
.programme-page .grid-toolbar.rb .issues-list > table, .programme-page .grid-toolbar.rb .issue-form { left: 0; right: auto; top: calc(100% + 4px); }
.programme-page .grid-toolbar.rb .legend .view-panel { left: auto; right: -12rem; }
.rb-panel { overflow: visible; }
/* full screen keeps the tab row, so there is always a way back */
html.chart-focus body.programme-page .grid-toolbar.rb { margin-top: 0.4rem; }
@media print { .grid-toolbar.rb { display: none !important; } }
/* the Key and other old drop-downs, drawn as ribbon buttons */
.rb .legend { margin: 0; font-size: inherit; color: inherit; }
.rb .legend > summary.rb-small { display: inline-flex; border: 1px solid transparent; padding: 1px 7px; border-radius: 3px; }
.rb .legend > summary.rb-small .icon-word { font-size: 0.8rem; }
/* the editing groups travel together: hidden for a viewer, as #step-tasks always was */
.rb-edit { display: contents; }
/* ==== end of the ribbon ================================================== */
/* which of the two needs schedules this is (v1.1.0) */
.schedule-kind { margin: 0; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cbar-deep); font-weight: 700; }
.both-link { font-size: 0.85rem; align-self: center; }
.both-link.active { font-weight: 700; }

/* ---- the programme's ribbon tabs on its reports and presentation view (v1.1.0) ---- */
.rb-away { margin: 0.55rem 1rem 0; background: #fff; border: 1px solid #D5DCD8; border-radius: 6px; }
.rb-away .rb-tabs a { display: inline-flex; align-items: center; text-decoration: none; }
.rb-away .rb-tab { border-bottom: 3px solid transparent; }
.rb-home { align-self: center; margin-right: 0.8rem; font-weight: 600; font-size: 0.88rem; color: var(--cbar-deep); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40%; }
.rb-home:hover, .rb-home:focus-visible { text-decoration: underline; }
.present-weeks { display: inline-flex; gap: 0.25rem; }
.present-weeks .look-btn { text-decoration: none; }
.present-weeks .look-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
