/* ==========================================================================
   Things to look out for
   ==========================================================================
   A findings list, not an alert banner. It sits under the Overview cards and
   is meant to be read top-down: the ones that cost money first.

   Severity is carried by a left rail rather than a filled background — a page
   of red boxes stops being read after the second wedding.
   ========================================================================== */

/* Air underneath as well as above. The checklist card used to start eight
   pixels below the last job row, so the panel and the cards read as one block.
   Gee: "they are too close to each other. It's very hard to see." */
.checks { margin-top: 34px; margin-bottom: 34px; }

.checks-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 14px;
}

.checks-head h3 {
  font-family: var(--display);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -.025em;
  color: var(--ink);
}

.checks-counts { display: flex; gap: 7px; }

/* These are buttons now, and they filter the panel. They always looked like
   controls; pressing one used to do nothing, which is its own small betrayal.
   Gee: "if I was to press 6 to chase, 11 to fill out, 18 to check, can I press
   that button that takes me right there?" */
.checks-pill {
  padding: 3px 11px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .01em;
  cursor: pointer;
}
.checks-pill:hover { filter: brightness(.95); }
.checks-pill:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

/* The one in force is outlined rather than recoloured — recolouring would
   fight the three job colours, which already mean something. */
.checks-pill.is-on { border-color: currentColor; }

/* THE COLOURS ARE THE ORIGINALS. I changed them and I should not have.

   Gee, 31 Aug: "Why have the colors change? The color shouldn't have changed.
   It was fine the way it was. It was more the layout below, and it should have
   been larger buttons."

   She asked for BIGGER and I delivered a recolour she never wanted. So the
   three hues are back exactly as they were, and the only thing that changes is
   the size — which is what "that has to change" meant. */
.checks-pill.is-chase { background: #fdeaf3; color: #b3145e; }
.checks-pill.is-fill  { background: #e7f6f7; color: #007c85; }
.checks-pill.is-check { background: #ffe3e4; color: #d4121f; }

/* Larger. These are the filter for the whole panel and they were 11px of
   text in a 3px-tall chip. */
.checks-pill {
  padding: 7px 15px;
  font-size: .82rem;
}

.checks-pill b, .checks-pill strong { font-weight: 800; font-size: .92rem; }

/* Kept: the digest and any older markup still emit these. */
.checks-pill.is-high { background: #ffe0e3; color: #b3001b; }
.checks-pill.is-med  { background: #ffe3e4; color: #d4121f; }
.checks-pill.is-low  { background: var(--surface-soft); color: var(--ink-soft); }


/* ---------- grouped by the job, not by how bad it is ----------------------

   The panel used to be one severity-ordered list under the pills "3 to sort ·
   5 to check · 2 minor". That ranks findings without ever saying what the work
   is, which is what left Gee unsure what the panel wanted from her.

   Now there are three headings — Chase someone, Fill something in, Check two
   numbers — and the heading is the instruction. Severity did not go away: it
   still orders rows inside a group and still colours the stripe, so the worst
   thing in a group is still the first thing in it.
   ------------------------------------------------------------------------- */

.checks-jobs { display: grid; gap: 22px; }

/* gap:0 now the rows carry their own hairline. Leaving 8px between them would
   put a gap either side of every divider and undo the point of a list. */
/* Plain block, not grid. It is a <details> now, and forcing a display on one
   is how you break the browser's own open/closed behaviour. gap:0 was the only
   thing grid was buying here anyway — the rows carry their own hairline. */
.check-job { display: block; }

/* The head is a <summary> now, so the group folds away. Closed, the panel is
   three counted lines instead of forty rows. */
.check-job-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  cursor: pointer;
  list-style: none;                 /* Firefox */
  padding: 6px 0;
  border-radius: 8px;
}

.check-job-head::-webkit-details-marker { display: none; }

/* EACH ROW WEARS ITS OWN PILL'S COLOUR.

   Gee, 31 Aug: "I feel like this area, the chase someone on the left and the
   fill something in, and the checklist progress are too close to each other.
   It's very hard to see. I think that they should be in the same colors as the
   buttons."

   Three grey rows under three coloured buttons, and nothing said which button
   belonged to which row. Now the pill and the group it filters are visibly the
   same thing. These three hues appear nowhere else on the Overview, so they do
   not collide with the budget or run sheet tags where pink and amber already
   mean something. */
.check-job > .check-job-head {
  padding: 11px 14px;
  border-radius: 11px;
  margin-bottom: 8px;
}

.check-job.is-chase > .check-job-head { background: #fdeaf3; }
.check-job.is-fill  > .check-job-head { background: #e7f6f7; }
.check-job.is-check > .check-job-head { background: #ffe3e4; }

.check-job.is-chase > .check-job-head .check-job-name,
.check-job.is-chase > .check-job-head .check-job-hint { color: #b3145e; }
.check-job.is-fill  > .check-job-head .check-job-name,
.check-job.is-fill  > .check-job-head .check-job-hint { color: #007c85; }
.check-job.is-check > .check-job-head .check-job-name,
.check-job.is-check > .check-job-head .check-job-hint { color: #d4121f; }

.check-job.is-chase > .check-job-head .check-job-n { background: #b3145e; color: #fff; }
.check-job.is-fill  > .check-job-head .check-job-n { background: #007c85; color: #fff; }
.check-job.is-check > .check-job-head .check-job-n { background: #d4121f; color: #fff; }

/* Show/Hide sits on white inside the tint, or it disappears into it. */
.check-job > .check-job-head::after {
  background: rgba(255, 255, 255, .78);
  border-color: transparent;
}

.check-job.is-chase > .check-job-head::after { color: #b3145e; }
.check-job.is-fill  > .check-job-head::after { color: #007c85; }
.check-job.is-check > .check-job-head::after { color: #d4121f; }

.check-job-head:hover::after { background: #fff; }

.check-job-head:hover { filter: brightness(.97); }

/* A BUTTON WITH A WORD ON IT, not a 7px chevron.

   Gee, 31 Aug: "that button needs to be larger. It's way too small, and it's
   very hard to be able to tell that button to collapse everything."

   She was right twice over. It was seven pixels of borrowed border, and it did
   not say what it did — you had to already know the group folded to guess that
   the shape meant fold. The whole heading has always been the click target,
   which nothing on screen ever mentioned.

   So: a real chip that says Show or Hide, big enough to hit, with the arrow
   kept beside it for the shape of the thing. */
.check-job-head::after {
  content: "Show";
  margin-left: auto;
  align-self: center;
  padding: 4px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink-soft);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.check-job[open] > .check-job-head::after { content: "Hide"; }

.check-job-head:hover::after {
  border-color: var(--ink-faint);
  color: var(--ink);
  background: var(--surface);
}

/* A closed group must still read as "there is something in here". */
.check-job:not([open]) > .check-job-head { opacity: .92; }

/* Every group open on paper — a printed panel cannot be clicked. */
@media print {
  .check-job-head::after { display: none; }
  .check-job > *:not(.check-job-head) { display: block !important; }
}

/* The count sits in the heading rather than in a pill up top, because "two
   people to chase" is a fact about this group and belongs on it. */
.check-job-n {
  flex: 0 0 auto;
  min-width: 22px;
  height: 22px;
  padding: 0 7px;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--surface);
  font-size: .72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: center;
}

.check-job-name {
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* One line saying what the heading means. Quiet, and it wraps to its own line
   on a narrow screen rather than squeezing the heading. */
.check-job-hint {
  color: var(--ink-soft);
  font-size: .8rem;
  flex: 1 1 22ch;
}


/* ---------- one finding --------------------------------------------------- */

/* Tighter than it was. Gee: "I don't need the full '11 tasks are overdue' with
   all of that. I would much rather it be more compressed so I can see it
   visually on the screen." Thirty-five findings at the old height was four
   screens of scrolling, and a list you scroll for four screens is a list you
   stop reading. Nothing is removed — the detail is clamped to one line and the
   padding is halved, so roughly twice as many fit in a glance. */
/* A LIST, not thirty-nine boxes. Gee, 30 Aug: "I do not think I love the way
   this looks."

   What was wrong was furniture, not information. Every finding carried a
   filled panel, a 3px stripe and a solid blue button — and the button repeated
   what the row already did, since the whole row has opened the finding since
   it was built. Thirty-nine of those stacked up reads as a wall rather than a
   list you work down.

   Now: no fill, a hairline between rows, a severity dot, and an arrow that
   arrives on hover. Same information, about twice as much of it on a screen. */
.check {
  display: grid;
  /* Two columns. It was three, with an 8px severity dot in the first — and
     when that dot was removed the body slid into the 8px slot and printed one
     word per line down the whole panel. */
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 12px;
  padding: 9px 6px;
  border-radius: var(--radius-sm);
  border-bottom: 1px solid var(--line-soft);
  background: transparent;
}

/* The last row in a group has the group heading below it doing the same job. */
.check:last-child { border-bottom: none; }

.check.is-openable { cursor: pointer; }
.check.is-openable:hover { background: var(--line-soft); }

/* THE DOT IS GONE.

   Gee, 31 Aug: "severity dots. I don't know what that means."

   Fair, and unanswerable at 8px. It carried three meanings — red serious,
   amber worth a look, grey minor — in a circle too small to tell three colours
   apart, which is exactly why she read a column of them as all-red and asked
   whether they disappear when they go red.

   A thing nobody can read is not information. The one distinction worth making
   says itself in a word, below, and only on the rows that need it. */
/* The serious ones, and nothing else. Two thirds of a panel wearing a badge is
   a panel with no badges. Inline in the title, never its own column. */
.check-flag {
  display: inline-block;
  vertical-align: 1px;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: #ffe0e3;
  color: #b3001b;
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
}

.check-body { min-width: 0; }

/* The area tag reuses the budget's category hues, so "Budget" is the same
   colour here as the section it points at. It now sits under the detail
   rather than beside the title: with a heading already telling you what kind
   of work this is, which part of the app it came from is the smaller fact. */
/* Back beside the title rather than on a line of its own. On its own line it
   cost every finding an extra row of height for two words. */
.check-area {
  display: inline-block;
  margin: 0 0 0 8px;
  vertical-align: 1px;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  background: var(--cat-tint, var(--line-soft));
  color: var(--cat, var(--ink-soft));
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  white-space: nowrap;
}

.check-title {
  font-size: .92rem;
  font-weight: 600;
  letter-spacing: -.01em;
  text-wrap: pretty;
}

/* One line, then stop. "11 tasks are overdue" listing three task names and an
   ellipsis was three lines of a card whose first line already said the thing.
   The full text is still in the title attribute, and "Open it" goes to the
   real list — nothing here is the last word on anything. */
.check-detail {
  margin-top: 1px;
  color: var(--ink-soft);
  font-size: .82rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ⚠️ A FINDING'S DETAIL IS PLAIN TEXT, NOT MARKUP. checks.js renders it
   through esc(), so a <span> or a <strong> written into a detail reaches the
   screen as literal tags. A `.check-said` class was written here on
   16 September to quote a supplier's own wording under a finding, and removed
   the same hour once that was checked — the quote goes in the detail string
   instead, where the row's `title` carries it on hover.
   If a finding ever genuinely needs markup, the RENDERER has to change, and
   every detail in the file becomes unsafe at that moment. */

/* An arrow, not a button. Still the same link and still the keyboard route —
   only its weight changed. Faint at rest so thirty-nine of them do not read as
   thirty-nine buttons, and it colours as the row lights up.

   Never display:none and never opacity:0. It has to stay in the layout or the
   rows would shift sideways on hover, and it has to stay reachable for anyone
   navigating by keyboard, who gets no hover at all. */
.check-goto {
  flex: 0 0 auto;
  align-self: center;
  padding: 2px 4px;
  color: var(--ink-faint);
  font-size: 1rem;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  transition: color .12s ease, transform .12s ease;
}

.check.is-openable:hover .check-goto {
  color: var(--pink, #e8197a);
  transform: translateX(2px);
}

.check-goto:focus-visible {
  outline: 2px solid var(--pink, #e8197a);
  outline-offset: 3px;
  border-radius: 4px;
  color: var(--pink, #e8197a);
}


/* ---------- the good outcome ---------------------------------------------- */

.checks-clear {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  padding: 18px 20px;
  border-radius: var(--radius);
  background: var(--c-sage-tint);
  color: var(--c-sage);
  font-size: .9rem;
}

.checks-clear strong { font-weight: 700; }
.checks-clear span   { color: var(--ink-soft); }


@media (max-width: 560px) {
  /* The stripe becomes a rule across the top and "Open it" drops to its own
     line at full width, which is easier to hit with a thumb than a small pill
     wedged against the right edge. */
  .check {
    grid-template-columns: 1fr;
    gap: 9px;
    padding-top: 14px;
  }
  .check-stripe { height: 3px; align-self: auto; }
  .check-goto   { justify-self: stretch; text-align: center; padding: 9px 14px; }
  .check-job-hint { flex-basis: 100%; }
}


/* ==========================================================================
   Supplier coverage cell
   ==========================================================================
   Missing coverage is amber, not red. Nothing is wrong yet — something simply
   is not filled in. Red stays reserved for a real problem (overdue payment, a
   clash), so that red keeps meaning "act now" rather than "look at me".
   ========================================================================== */

.sup-cover { white-space: nowrap; }

.cover-time {
  display: block;
  font-variant-numeric: tabular-nums;
  font-size: .85rem;
  font-weight: 600;
}

/* Hours nobody has vouched for. Amber, the same amber "Add hours" uses, for the
   same reason: nothing is wrong, nobody has said where the number came from
   yet. Once "Where these hours came from" is filled it settles to normal ink
   and the date rides underneath — so later, when the supplier has changed
   their hours and you are trying to work out when you last checked, the answer
   is on the screen rather than in an email. */
.cover-time.is-unvouched {
  color: var(--pay-part);
  text-decoration: underline dotted var(--pay-part);
  text-underline-offset: 3px;
  cursor: help;
}

.cover-len {
  display: block;
  color: var(--ink-faint);
  font-size: .74rem;
}

/* A supplier split across crews gets one line per crew — place and window —
   instead of a single figure that would have to span both. Legato is at the
   bride's house at 8:45 and at Metropolis at 20:25; there is no honest way to
   write that as one number. */
.cover-teams { display: grid; gap: 2px; }

.cover-team {
  display: block;
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
}

/* Amber, the same amber Coverage already uses for a missing length: nothing is
   wrong, something simply is not filled in yet. */
.cover-team.is-missing { color: var(--pay-part); font-style: italic; }

/* A time the CARD does not have, taken from the run sheet and said so.
   Gee writes the day first and fills the cards later, so four crews on Solin &
   Rony sat blank while the sheet already knew when they start.

   ⚠️ Nothing is stored — it is borrowed, which is why it has to LOOK borrowed.
   A time that reads as typed would be indistinguishable from one she checked,
   and the next person would have no way to tell what has actually been agreed.
   The label is the point; the colour only carries it. */
.cover-team.is-borrowed small {
  display: block;
  font-size: .72rem;
  color: var(--ink-faint);
}

.cover-team.is-borrowed em {
  font-style: normal;
  font-size: .69rem;
  font-weight: 700;
  color: var(--c-indigo, #5b3fa8);
  background: var(--c-indigo-tint, #f1e9f8);
  border-radius: 4px;
  padding: 1px 5px;
  margin-left: 4px;
  white-space: nowrap;
}

.cover-missing {
  padding: 4px 11px;
  border: 1px solid #ffb74d;
  border-radius: var(--radius-pill);
  background: #ffe3e4;
  color: #d4121f;
  font-family: inherit;
  font-size: .73rem;
  font-weight: 700;
  cursor: pointer;
  transition: background .14s ease, border-color .14s ease;
}

.cover-missing:hover { background: #ffe3e4; border-color: #ffb74d; }

/* ⚠️ THE ANSWERED CASE, AND IT IS DELIBERATELY QUIET — migration 92.
   .cover-missing above is a call to action: amber, bordered, a button you are
   meant to press. This is its opposite. A supplier ticked "not required on the
   wedding day" has no hours to book, so the cell states a fact instead of
   asking a question. Gee, 10 Sept: "that way we don't have to keep looking at
   that and thinking, oh, do I have to fill this in for the ones that aren't
   present on the day?"

   Same weight and colour as "not on the day" in the venue column, so the two
   read as one answer across the row rather than two different states. */
.cover-none {
  color: var(--ink-faint);
  font-size: .78rem;
  font-style: italic;
}

/* The half-filled case is quieter — one of the two is already in. */
.cover-missing.is-part {
  margin-top: 3px;
  border-style: dashed;
  background: none;
}

/* "optional" beside a label — quieter than the label, not a second label. */
.hint-inline {
  margin-left: 6px;
  color: var(--ink-faint);
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}


/* ==========================================================================
   Sideways scroll, made visible
   ==========================================================================
   The supplier table is wider than the screen. It always scrolled — there was
   just nothing to say so, which is indistinguishable from the contact details
   having been cut off. A soft fade on the right edge is the whole fix.
   ========================================================================== */

/* No `scrollbar-width` here any more — see "ONE MOVING LINE" below. */
.table-scroll {
  position: relative;
}

.table-scroll::after {
  content: "";
  position: sticky;
  top: 0;
  right: 0;
  float: right;
  width: 34px;
  height: 100%;
  margin-left: -34px;
  pointer-events: none;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), var(--surface));
}

/* Once it has been scrolled to the end there is nothing left to hint at. */
.table-scroll.is-end::after { opacity: 0; transition: opacity .2s ease; }


/* ---- the same scrollbar, at the top ---------------------------------------
   Gee, 7 Sep: the budget's only way across sat below every row, so the control
   that reveals Status and Balance was past the thing it controls. Built by
   attachTopScroll() in ui.js, which mirrors the real box and keeps the two in
   step.

   A REAL overflow box, not a drawn bar: it inherits the platform's scrollbar,
   its keyboard handling and its touch inertia for nothing. The child is a 1px
   spacer set to the table's full width — that is the whole trick.

   `hidden` is set by the JS when the table fits, and [hidden] is enforced
   globally, so a table that does not scroll shows no bar. */
/* "Swipe across for more →", above a table that has somewhere to go.
   Built by attachTopScroll in ui.js, which also retires it on first scroll.

   Gee, 11 Sept, on her phone: "there's nothing that explains that you can move
   on the sides of the budgets… yes, there's a line there, but if they don't
   know, they're just not going to understand."

   Deliberately quiet — it is a label, not a warning, and it goes away the
   moment it has done its job. Right-aligned because that is the direction it
   is pointing. */
/* LEFT, not right — 27 September. Gee: "the swipe across for more should be
   on top of where the supplier is… Instead of being on the right-hand side,
   it should be on the left-hand side." It sits over the Supplier column,
   where a couple's eye starts reading the table. */
.scroll-hint {
  font-size: .74rem;
  font-weight: 600;
  color: var(--ink-faint);
  text-align: left;
  padding: 0 2px 3px;
  letter-spacing: .01em;
  user-select: none;
}

/* On a mouse it is mostly noise: the bar is permanently visible and the table
   is usually wide enough not to need one. The problem is a phone, where the
   scrollbar hides until you are already scrolling. */
@media (min-width: 781px) { .scroll-hint { display: none; } }

.table-scroll-top {
  overflow-x: auto;
  overflow-y: hidden;
  /* Sits directly on the table below it. */
  margin-bottom: 4px;
}

.table-scroll-top > div { height: 1px; }

/* ===========================================================================
   🛑 ONE MOVING LINE, EVERYWHERE — ROYAL BLUE #2b59c3, 16px. 27 September.

   ⚠️ IT WAS SOFT PLUM FOR AN HOUR AND SHE CHANGED IT: "that color is way too
   similar to all of the colors above. It's too lost here with all the pinks."
   The budget's subtotal rows are pink, so a plum line vanished among them.
   Royal blue is a TRUE blue, kept clear of her teal buttons, the run sheet's
   sky-blue arrivals bar (#0067a3) and the category-heading navy (#1e3f7d).
   The history below says "plum" — it is kept for the reasoning.

   Gee, first: "See the gray line above there that moves… This section is very
   hard to view." Then, after the TOP bar alone went teal: "See how the bottom
   … has the gray line again? … It's meant to be systematic everywhere, so
   anywhere that had that moving line should be the same. I don't think it
   should be blue. It's too similar to all of the blue up on top." She chose
   SOFT PLUM from deep-plum shades — teal/blue are her buttons, orange/amber
   mean warning and TBC, red means overdue.

   ⚠️ EVERY SIDEWAYS SCROLLER IS IN THIS ONE LIST, AND A NEW ONE GOES HERE TOO,
   or it will be the odd grey line out again. Measured 27 Sept: the top mirror
   and the table's own bar (Budget, Suppliers, Payment schedule, the couple's
   payments), the Contacts table, the tab row, and a crew's times on a phone.

   ⚠️ `scrollbar-width` / `scrollbar-color` ARE RESET TO `auto` ON PURPOSE.
   In current Chrome either standard property, if set anywhere, takes over and
   every -webkit-scrollbar rule is ignored — which is why the old 10px "thin"
   bar never drew its height. Firefox has no -webkit- scrollbar, so it gets
   the standard colour inside the @supports.

   `-webkit-appearance: none` keeps the bar visible on a phone, where the
   browser otherwise hides it until you are already scrolling (11 Sept).
   =========================================================================== */
.table-scroll-top,
.table-scroll,
.contact-table-wrap,
.subnav,
.team-row > .team-times {
  scrollbar-width: auto;
  scrollbar-color: auto;
}

.table-scroll-top::-webkit-scrollbar,
.table-scroll::-webkit-scrollbar,
.contact-table-wrap::-webkit-scrollbar,
.subnav::-webkit-scrollbar,
.team-row > .team-times::-webkit-scrollbar {
  height: 16px;
  -webkit-appearance: none;
}

.table-scroll-top::-webkit-scrollbar-track,
.table-scroll::-webkit-scrollbar-track,
.contact-table-wrap::-webkit-scrollbar-track,
.subnav::-webkit-scrollbar-track,
.team-row > .team-times::-webkit-scrollbar-track {
  background: #e5ecfa;
  border-radius: 10px;
}

.table-scroll-top::-webkit-scrollbar-thumb,
.table-scroll::-webkit-scrollbar-thumb,
.contact-table-wrap::-webkit-scrollbar-thumb,
.subnav::-webkit-scrollbar-thumb,
.team-row > .team-times::-webkit-scrollbar-thumb {
  background: #2b59c3;
  border: 3px solid #e5ecfa;
  border-radius: 10px;
}

.table-scroll-top::-webkit-scrollbar-thumb:hover,
.table-scroll::-webkit-scrollbar-thumb:hover,
.contact-table-wrap::-webkit-scrollbar-thumb:hover,
.subnav::-webkit-scrollbar-thumb:hover,
.team-row > .team-times::-webkit-scrollbar-thumb:hover { background: #234aa6; }

@supports not selector(::-webkit-scrollbar) {
  .table-scroll-top,
  .table-scroll,
  .contact-table-wrap,
  .subnav,
  .team-row > .team-times { scrollbar-color: #2b59c3 #e5ecfa; }
}


/* ==========================================================================
   The assignments view, tidied
   ==========================================================================
   Built to match the Aisle Planner layout Gee works from: a lane per person,
   and one clean line per task — tick, title, date. Nothing else.

   The notes still exist; they are simply not shown here. A note is context
   for doing the job, and this screen is for seeing what the jobs ARE. It
   turned a scannable column into a wall of grey text. The full checklist and
   the Details panel both still show them.
   ========================================================================== */

.lane-grid .task-notes,
.lane-grid .task-meta { display: none; }

/* The lane header already says whose column this is. Repeating it on every
   row was a chip per line saying what the heading said once. */
.lane-grid .who-name { display: none; }

.lane-grid .task-row { align-items: center; padding: 9px 0; }

/* One line, and room to be one line. */
.lane-grid .task-title {
  display: block;
  font-size: .9rem;
  line-height: 1.35;
}

/* A rule before the date, the way the original has it — it turns the dates
   into a column you can run your eye down. */
.lane-grid .task-due {
  padding-left: 14px;
  border-left: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.lane-grid .task-due.is-overdue { color: var(--pay-late, #b3001b); font-weight: 600; }


/* ---------- the lane header ---------------------------------------------- */

.lane-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line-soft);
}

.lane-name {
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.lane-sub { color: var(--ink-faint); font-size: .78rem; }
.lane-sub.has-overdue { color: var(--pay-late, #b3001b); }


/* ==========================================================================
   The tick box
   ==========================================================================
   The browser's own checkbox only takes a colour once it is already ticked,
   so an unticked list was a column of grey squares. Drawn by hand instead.

   The box carries urgency — plain, amber inside a week, red once late — and
   fills with the brand pink when you tick it. So the list tells you what
   needs doing, and finishing something feels like finishing something.

   Scoped to input.task-check on purpose: in the couple's portal .task-check
   is a <label> wrapping the input, and this would take that apart.
   ========================================================================== */

input.task-check,
#portal-view .task-check > input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 19px;
  height: 19px;
  margin-top: 1px;
  /* 🛑 THE EMPTY BORDER WAS #ece5e8, WHICH IS 1.15:1 ON WHITE — a tick box you
     have to know is there. Gee, 18 September: "I can't see it. It's all lost
     with all of the things that we've got going on." `--teal-deep` is 4.98:1.
     ⚠️ The PINK fill on :checked below is untouched and must stay: it is the
     documented reason this control was drawn in the first place — finishing
     something should feel like finishing something. Only the empty state
     changed. */
  border: 2px solid var(--teal-deep);
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, transform .1s ease;
}

input.task-check:hover,
#portal-view .task-check > input:hover { transform: scale(1.08); }

input.task-check:focus-visible,
#portal-view .task-check > input:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 2px;
}

/* Due inside a week, and already late. Same traffic light as the budget, so
   amber and red keep meaning the one thing wherever they appear.

   🛑 THE MIDDLE LIGHT WAS RED FOR ITS WHOLE LIFE, AND TWO COMMENTS SAID IT
   SHOULD NOT BE. The header of this block says "amber inside a week, red once
   late"; `taskRowHtml` in checklists.js says "pink once it's late, yellow when
   it's close". Both describe a three-stage light. What shipped was
   `#d4121f` here and `#b3001b` for late — two reds a shade apart, so "due this
   week" and "already late" were the same signal.

   Gee, 21 September: *"there's too much red going on on the thing, so you
   can't tell."* She was reading a traffic light with two red bulbs.

   ⚠️ `--warn` IS NOT THE FIX. styles.css:234 sets `--warn: #d4121f` under a
   comment calling it "tangerine — due soon" — the token is labelled
   tangerine and defined as red — but 64 rules across the app read it, so
   changing it there would restyle the budget, the findings panel, the pay
   chips and the portal in one go. This is the two rules she actually named.

   ⚠️ #ff6f00, the app's own `--btn-tangerine`, was measured FIRST and
   rejected: 2.79:1 on white, below the 3:1 floor and worse than the red it
   replaced. #a85700 is 5.21:1 on white and 4.59:1 on #ffeeda, which puts it in
   the same company as the empty box (--teal-deep, 6.61:1) and late (7.16:1).
   `a-control-must-be-visible-and-hittable` — measure the colour, never reach
   for the obvious token. */
input.task-check.is-soon,
#portal-view .task-check > input.is-soon {
  border-color: #a85700;
  background: #ffeeda;
  box-shadow: none;
}

input.task-check.is-late,
#portal-view .task-check > input.is-late {
  border-color: #b3001b;
  background: #ffe0e3;
  box-shadow: none;
}

/* Ticked: filled in the brand colour, whatever it was before. */
input.task-check:checked,
#portal-view .task-check > input:checked {
  border-color: var(--pink);
  background: var(--pink);
}

input.task-check:checked::after,
#portal-view .task-check > input:checked::after {
  content: "";
  position: absolute;
  left: 5.5px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(43deg);
}

/* The couple's list wraps its input in a <label>, because the printed version
   draws its tick box off that label. Kept, and simply told to size itself to
   whatever the box now is rather than the 17px the old control was. */
#portal-view .task-check {
  display: inline-flex;
  width: auto;
  height: auto;
  margin-top: 0;
}


/* ==========================================================================
   Role picker
   ==========================================================================
   Tick what a supplier does rather than typing it. The wedding where photo
   and video are two different companies has to be sayable, and one free-text
   box could never say it.
   ========================================================================== */

/* A dropdown, not a flat grid.

   Thirty-five pills laid out took five lines of the longest form in the
   platform. Gee, 29 Aug: "are we able to actually make this a dropdown
   instead so it doesn't take up so much space on the screen?" Shut it is one
   control naming what is ticked; open it is the same tick list, scrolling. */

.role-picker { position: relative; }

.role-drop {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: .88rem;
  text-align: left;
  cursor: pointer;
}

.role-drop:hover { border-color: var(--pink); }
.role-drop[aria-expanded="true"] { border-color: var(--pink); }

/* The roles themselves, on one line. "3 selected" would make you open it to
   find out which, which is the thing being avoided. */
.role-drop-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.role-drop-text.is-empty { color: var(--ink-faint); }

.role-drop-count:not(:empty) {
  flex: 0 0 auto;
  min-width: 20px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--pink);
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  text-align: center;
}

.role-drop-arrow { flex: 0 0 auto; color: var(--ink-faint); font-size: .7rem; }

.role-menu {
  position: absolute;
  z-index: 5;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}

/* The supplier roles list, in Settings. */
.role-rows { display: grid; gap: 1px; background: var(--line); border-radius: 8px; overflow: hidden; margin-bottom: 14px; }
.role-rows:empty { display: none; }
.role-row {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  gap: 10px;
  align-items: center;
  padding: 8px 13px;
  background: var(--surface);
}
.role-row .role-name { font-size: .9rem; font-weight: 600; }
.role-row .role-used { font-size: .76rem; color: var(--ink-faint); }

@media (max-width: 620px) {
  .role-row { grid-template-columns: 1fr auto; row-gap: 4px; }
  .role-row .role-used { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------------------------
   Oversight — what changed, and what was deleted.
   Rows rather than cards: both lists are scanned for one line, not read.
   --------------------------------------------------------------------------- */

.chg-rows, .bin-rows { display: grid; gap: 1px; background: var(--line); border-radius: 8px; overflow: hidden; }
.chg-rows:empty, .bin-rows:empty { display: none; }

.chg-row {
  display: grid;
  grid-template-columns: minmax(90px, auto) 1fr auto;
  gap: 12px;
  align-items: baseline;
  padding: 9px 13px;
  background: var(--surface);
  font-size: .86rem;
}
.chg-who { font-weight: 700; }
/* A couple's edit is the one you look for, so it is the one that is marked. */
.chg-row.is-client .chg-who { color: var(--pink, #e8197a); }
.chg-what b { font-weight: 600; }
.chg-where { color: var(--ink-faint); }
.chg-when { color: var(--ink-faint); font-size: .78rem; white-space: nowrap; }

.bin-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 11px 13px;
  background: var(--surface);
}
.bin-what { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bin-label { font-size: .9rem; font-weight: 600; }
.bin-meta { font-size: .76rem; color: var(--ink-faint); }
.bin-row.is-restored .bin-label { text-decoration: line-through; opacity: .6; }
.bin-done { font-size: .78rem; font-weight: 700; color: var(--ok, #00733d); }

@media (max-width: 620px) {
  .chg-row { grid-template-columns: 1fr; gap: 3px; }
  .chg-when { font-size: .74rem; }
}

/* A contact card opens on click, so it has to look like it does. Matches the
   wedding cards, which have lifted on hover since they were built. */
.card.is-openable { cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
.card.is-openable:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.card.is-openable:focus-visible { outline: 2px solid var(--pink, #e8197a); outline-offset: 2px; }
/* The controls inside it keep their own cursor — they are not the card. */
.card.is-openable .btn, .card.is-openable a { cursor: pointer; }

/* Type to narrow a long picker — 48 categories, or twenty roles.
   Sticky, so it stays reachable once the list below it starts scrolling. */
.role-filter {
  position: sticky;
  top: -6px;
  z-index: 1;
  display: block;
  width: 100%;
  margin: -6px -6px 6px;
  padding: 8px 10px;
  width: calc(100% + 12px);
  border: none;
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: var(--surface);
  font: inherit;
  font-size: .86rem;
  color: var(--ink);
}
.role-filter:focus { outline: none; border-bottom-color: var(--pink, #e8197a); }
.role-filter::placeholder { color: var(--ink-faint); }

.role-none {
  margin: 0;
  padding: 10px 12px;
  font-size: .82rem;
  color: var(--ink-soft);
}

.role-opt {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--ink-soft);
  font-family: inherit;
  font-size: .84rem;
  text-align: left;
  cursor: pointer;
}

.role-opt:hover { background: var(--pink-tint); color: var(--pink-deep); }

.role-tick {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--surface);
}

.role-opt.is-on { color: var(--pink-deep); font-weight: 600; }
.role-opt.is-on .role-tick {
  border-color: var(--pink);
  background: var(--pink);
  /* A tick drawn with a border rather than a glyph, so it never falls back to
     a missing character in a font that has not loaded. */
  background-image: linear-gradient(45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%),
                    linear-gradient(-45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%);
}

/* ---------- a fold ---------------------------------------------------------

   For the pair of boxes that are blank on almost every supplier. Gee, 29 Aug,
   on the driver: "I want to have a driver and then driver's mobile to be
   released closer to the wedding. Just say Show or Hide." */

.fold-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 11px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
  background: none;
  color: var(--teal);
  font-family: inherit;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
}

.fold-toggle:hover { border-color: var(--teal); background: var(--teal-tint); }
.fold-arrow { font-size: .68rem; }

.fold-note {
  margin-left: auto;
  color: var(--ink-faint);
  font-size: .72rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

/* Something is actually in there — say so, so a filled-in driver is never
   hidden behind a fold that looks empty. */
.fold-note.has-value { color: var(--ink); font-weight: 600; }

/* ---------------------------------------------------------------------------
   Supplier arrivals — the block above the run sheet.

   Read down the times, not across the names: the only use for this list is
   standing at a door on the morning working out who is next.
   --------------------------------------------------------------------------- */

.arrivals {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}

.arrivals li {
  display: grid;
  grid-template-columns: 86px 1fr auto;
  gap: 10px;
  align-items: baseline;
  padding: 9px 2px;
  border-bottom: 1px solid var(--line);
}

.arr-time {
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.arr-name { color: var(--ink); }

/* Not pinned down yet. Red, because a supplier with no arrival time used to be
   left off the list entirely, which looked exactly like a supplier who wasn't
   coming — and the one thing worse than not knowing is not noticing. */
.arrivals li.is-tbc .arr-time { color: #b3001b; font-weight: 700; }
.arrivals li.is-tbc .arr-name { color: var(--muted); }

/* ---------------------------------------------------------------------------
   Run sheet change requests.

   A couple suggests; Gee decides. Amber throughout, because a request is
   neither a warning (red) nor a settled fact (teal) — it is a decision
   waiting to be made, and it should look like one.
   --------------------------------------------------------------------------- */

/* LOUD. A couple is sitting at the other end of this one waiting for an
   answer, and it was a pale cream bar you could scroll past.

   Gee, 30 Aug: "I actually wanted the whole thing in orange and red text so I
   can really see it, because this is not very visible. I don't know why we
   didn't fix it before."

   Red text HERE and amber on the supplier coverage panel is not a
   contradiction. Red means "somebody is waiting on you" — overdue payments,
   overdue tasks, and this. Coverage is a gap in your own preparation, which is
   loud but nobody is waiting. */
/* Key details keeps a colour of its own — see the swap note further down. It
   gives tangerine to the findings panel and takes burnt in return. */
.tl-header-requests {
  background: #d4121f !important;
  border-left-color: #d4121f !important;
  border: 2px solid #d4121f !important;
  border-bottom: none !important;
}

/* White, and bold. Dark red on orange measured fine and read badly — Gee, on
   seeing it: "make this font bold white because i cant read it properly."
   She is looking at it on a real screen; that is the measurement that counts. */
.tl-header-requests h3 {
  color: #fff !important;
  font-weight: 800 !important;
  letter-spacing: .02em;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .25);
}

/* The card's fill, its radius and its padding are set in the OPTION A block
   below — one definition, not two. This rule kept only what is still true. */
.rsr-card .rsr-line { color: #b3001b; font-weight: 800; }
.rsr-card .rsr-body { color: #2a2126; font-weight: 600; }

/* Blue, not the teal that Key details wears. Gee, 28 Aug: "the supplier
   arrival times box, which is that green teal box, is the same as the key
   details. We don't want that to be that color. We want that to be blue."
   Two filled teal bars stacked read as one long block; they are two different
   things and one of them dictates the day. */
.tl-header-arrivals { background: var(--blue); }

.rsr-queue {
  border: 2px solid #d4121f;
  border-top: none;
  padding: 10px 12px;
  background: #ffe3e4;
}

/* ---------------------------------------------------------------------------
   OPTION A — EVERY FINDING IS ITS OWN WHITE CARD. 12 September.

   Gee, looking at ten findings running together: "I can't tell that they're
   separate individual lines… I like that it's got a border around it."

   She chose this out of five drawn layouts. A white card on a tint cannot be
   misread as one block of text, which numbering and hairlines both failed to
   fix — the divider was one pixel of #ffe3e4 on #ffe3e4, which is to say no
   divider at all. That is the actual bug in the old rule below, and it had
   been there since the panel was built.

   The gap does the separating now, so the top border and the padding trick
   are gone with it.
   -------------------------------------------------------------------------- */
.rsr-queue { display: grid; gap: 9px; }

.rsr-card {
  background: #fff;
  border: 1px solid rgba(179, 78, 0, .22);
  border-radius: 10px;
  padding: 11px 13px;
}

/* It is a link (11 Sept), so it says so on hover — and the border is what
   moves, because the fill is already white and has nowhere to go. */
a.rsr-card:hover { background: #fffaf4; border-color: #ff6f00; }

/* ---------------------------------------------------------------------------
   THE CARD IS A LINK NOW. 11 September.

   Gee: "when we press that button, it takes us exactly to the areas where that
   problem is throughout the whole website."

   Both panels — Key details and the on-page findings — emit <a class="rsr-card">
   instead of a div. The class is unchanged on purpose (§38.10: this panel must
   stay Key details' markup), so everything above still applies; these four
   lines only stop an anchor looking like an anchor, and say it can be pressed.

   ⚠️ display:block is load-bearing. An inline <a> wrapping three block children
   collapses its own padding and the cards run into each other.
   -------------------------------------------------------------------------- */
a.rsr-card {
  display: block;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

/* The hover lives in the OPTION A block above now. A white wash was right when
   the card was tinted; on a white card it does nothing at all. */

a.rsr-card:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 2px;
}

/* Which line they are asking about, said first — the request is meaningless
   floating free of the moment it concerns. */
.rsr-line {
  font-weight: 700;
  font-size: .86rem;
  color: var(--ink);
}

.rsr-head { font-size: .76rem; color: var(--muted); margin-top: 2px; }
.rsr-when { margin-left: 4px; }

.rsr-body {
  margin: 6px 0 8px;
  font-size: .92rem;
  line-height: 1.5;
  color: var(--ink);
}

.rsr-acts { display: flex; gap: 8px; flex-wrap: wrap; }

/* --- the couple's side ------------------------------------------------- */

.rsr {
  margin: 6px 0;
  padding: 7px 10px;
  border-left: 3px solid #d4121f;
  background: #ffe3e4;
  font-size: .85rem;
}

.rsr-approved { border-left-color: #00733d; background: #d6f7e2; }
.rsr-declined { border-left-color: var(--muted); background: #faf7f9; }

.rsr-pill {
  margin-left: 6px;
  padding: 0 7px;
  border-radius: 999px;
  background: #ffb74d;
  color: #d4121f;
  font-size: .68rem;
  font-weight: 700;
}

.rsr-approved .rsr-pill { background: #d6f7e2; color: #00733d; }
.rsr-declined .rsr-pill { background: #f2f0f1; color: var(--ink-faint); }

.rsr-reply { margin-top: 5px; color: var(--ink); }

/* ---------------------------------------------------------------------------
   ANSWERED CHANGE REQUESTS, ON GEE'S SIDE. 18 September.

   Her panel drew only the PENDING ones, so the moment she answered a request
   it left her screen — while it stayed on the couple's run sheet, her reply
   with it, with no way to take it down. Nine of them were sitting on Tiffany
   & Liam, most of them her own testing.

   ⚠️ CLOSED BY DEFAULT AND QUIET. This is a record, not a job. The panel above
   it is the one that means "you owe somebody an answer"; this must never
   compete with it or push the run sheet down the page.
   -------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   THE CONVERSATION CHIP ON A RUN SHEET LINE. 18 September.

   Gee, on her 8:45: "there's nothing on my view to show that it is there as a
   conversation." The COUPLE saw the exchange pinned to the line; her own sheet
   said nothing. Seven of her lines carried one.

   ⚠️ TWO STATES, DELIBERATELY. "Waiting on you" is a job and is allowed to be
   loud; an answered one is a record and must not be — a single style would
   have made a thing she has dealt with shout as loudly as one she has not.
   -------------------------------------------------------------------------- */
.tl-req {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 6px;
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  font-family: inherit;
  font-size: .68rem;
  font-weight: 700;
  /* --ink-soft on the row's white, measured: 6.1:1. */
  color: var(--ink-soft);
  cursor: pointer;
  vertical-align: middle;
  white-space: nowrap;
}
.tl-req:hover { background: var(--surface-soft, #f7f4f2); border-color: var(--ink-faint); }
.tl-req:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

/* Waiting on her. --warn on --warn-tint is 4.45:1 and this is 11px, so it uses
   --danger at 5.9:1 instead — the same call as the payments Hide. */
.tl-req.is-waiting {
  background: var(--warn-tint);
  border-color: var(--warn-mid);
  color: var(--danger);
}

@media print { .tl-req { display: none !important; } }

/* The card the chip just scrolled to. Scrolling to one of several identical
   cards does not say WHICH. */
@keyframes rsr-found {
  from { box-shadow: 0 0 0 3px rgba(0, 124, 133, .55); }
  to   { box-shadow: 0 0 0 3px rgba(0, 124, 133, 0); }
}
.rsr-card.is-found { animation: rsr-found 1.6s ease-out 1; }

@media (prefers-reduced-motion: reduce) {
  .rsr-card.is-found { animation: none; box-shadow: 0 0 0 3px rgba(0, 124, 133, .45); }
}

/* ---------------------------------------------------------------------------
   TICK THEM AND CLEAR THE LOT. 18 September.

   Gee, having taken one off and watched it leave the couple's sheet: "There
   should be a tick to mark all of it and then disregard all of it in one go."

   The FIFTH card of this shape she has had to ask for. CHECK 27 exists for it.
   -------------------------------------------------------------------------- */
.rsr-pickbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0 4px;
  padding: 6px 2px;
}

.rsr-picked-n { font-size: .8rem; font-weight: 700; color: var(--ink-soft); }

/* The action, and it is the loud thing on this bar because it is the point. */
.rsr-go {
  margin-left: auto;
  background: var(--teal-deep);
  border-color: var(--teal-deep);
  color: #fff;
  font-weight: 700;
}
.rsr-go:hover { filter: brightness(1.08); }

/* The tick sits on the same line as the title, so the card keeps its height. */
.rsr-pick {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  cursor: pointer;
}
.rsr-pick input {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin-top: 2px;
  accent-color: var(--teal-deep);
  cursor: pointer;
}
.rsr-pick .rsr-line { flex: 1 1 auto; }

/* ⚠️ AN EDGE, NOT A FILL. These cards are already tinted by status — approved
   is green, declined is grey — and a background on top would fight the pill
   that says which. */
.rsr-card.is-picked { box-shadow: inset 3px 0 0 0 var(--teal-deep); }

@media (hover: none) { .rsr-pick input { width: 22px; height: 22px; } }

@media print { .rsr-pickbar, .rsr-pick input { display: none !important; } }

.rsr-answered { margin-top: 10px; }

.rsr-answered > summary {
  cursor: pointer;
  padding: 7px 11px;
  border-radius: 8px;
  background: var(--surface-soft, #f7f4f2);
  font-size: .78rem;
  font-weight: 700;
  color: var(--ink-soft);
  list-style: none;
}
.rsr-answered > summary::-webkit-details-marker { display: none; }
.rsr-answered > summary::before { content: "▸ "; color: var(--ink-faint); }
.rsr-answered[open] > summary::before { content: "▾ "; }
.rsr-answered > summary:hover { background: #efe9e2; }
.rsr-answered > summary:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

.rsr-answered .rsr-queue { margin-top: 8px; }

/* The ask control stays shut until wanted — fifty open boxes down a run sheet
   would be a form, not a document. */
.rsr-ask { margin-top: 6px; }
.rsr-ask summary {
  cursor: pointer;
  font-size: .8rem;
  color: var(--teal-deep, #007c85);
}
.rsr-ask textarea { width: 100%; margin: 6px 0; }

.rsr-closed { margin-top: 6px; font-size: .78rem; color: var(--muted); }

/* ---------------------------------------------------------------------------
   Arrival cards — one venue's arrivals, sitting inside the run sheet.

   Copied from how Gee already writes these by hand: a pink block headed
   "Reception Supplier arrival times", dropped in where that venue starts to
   matter, listing everyone due there whenever they are due. Deliberately out
   of step with the times around it — the card answers "who is coming to this
   building", not "what happens next".
   --------------------------------------------------------------------------- */

/* REVERTED 27 Aug to exactly how it was. It was restyled to teal, with an
   uppercase ruled heading, off the back of a conversation about making the
   BRIDE'S HOUSE and GROOM'S arrivals look like these two. Gee: "the supplier
   arrival times at Metropolis and at the church were all fine before. There
   was no problem with that. I don't know why you changed it."
   The job was to give the other two venues this treatment, not to change
   this. Nothing here gets touched again without being asked for. */
.arr-card {
  margin: 6px 0 2px;
  padding: 9px 12px;
  border: 1px solid var(--pink-line, #f0c3d7);
  border-left: 3px solid var(--pink);
  background: #fff;
}

.arr-card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 5px;
  color: var(--ink);
  font-size: .88rem;
  font-weight: 700;
}

/* Hide / Show for one door's card. Same shape and size as the one on the phone
   list, so the two read as the same control rather than two inventions. */
/* 🛑 IT HAS TO BE VISIBLE. Gee, 17 September: "can you make that a different
   colour so I can actually see that, because it's just so hard to see that
   button?" It was a grey outline with grey text on white — technically there,
   and invisible on a card that is already busy with pink names and teal times.
   Teal, filled, is the app's own secondary action and reads at a glance
   without competing with the red, which means something else entirely. */
.arr-card-hide {
  margin-left: auto;
  padding: 4px 12px;
  border: 1.5px solid var(--teal, #009faa);
  border-radius: 999px;
  background: var(--teal-tint, #e7f6f7);
  color: var(--teal-deep, #007c85);
  font-family: inherit;
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  cursor: pointer;
}

.arr-card-hide:hover {
  background: var(--teal, #009faa);
  color: #fff;
}

/* Folded: the heading stays, so she can count the arrivals without opening it. */
.arr-card.is-shut .arr-card-list { display: none; }
.arr-card.is-shut .arr-card-head { margin-bottom: 0; }

.arr-card-list { list-style: none; margin: 0; padding: 0; }

/* Not the three-column grid the top block uses — a card is read as a list. */
.arr-card-list li {
  display: block;
  padding: 2px 0;
  border: none;
  color: var(--pink-deep, #c31465);
  font-size: .84rem;
  font-weight: 600;
}

/* A colour per door, so four cards side by side are told apart without
   reading their headings. The hue lives on the card as two custom properties
   and everything inside takes it from there, which is what keeps the head,
   the rule and the time chips from drifting apart.
   Cards inside the run sheet carry no tone class and keep the original pink —
   they are read one at a time, in place, and never need telling apart. */
/* 🛑 PINK CHANGED HERE ON 17 SEPTEMBER, AND THE REASON IS THE WHOLE POINT.
   Gee: "we do have to make sure the colours are still in alignment with the
   supplier arrival times."

   They were not. Measured on her sheet: this block's pink was `--pink`
   (#e8197a) while the run sheet's tag for the same place, `.tl-door.door-pink`,
   was `--pink-deep` (#c31465). Blue, green and plum already matched — pink
   alone did not, so the Bride's house card and the Bride's tag were two
   different pinks a screen apart.

   `--pink-deep` wins: it is the darker of the two, and the whole evening has
   been about reading things at a glance.

   🛑 `tone-coral` EXISTS NOW, AND THIS PARAGRAPH USED TO SAY IT NEVER WOULD.
   It read: "a coral rule would be CSS nothing can ever emit… fixing it means
   teaching suppliers.js about a fifth place, and that is a separate job."

   That job was done later the same day. Gee: "I think it should show one more
   block for the photography and videography locations." groupArrivals() now
   draws a Photography & videography card, so the block CAN emit coral — and
   the National Gallery of Victoria, which was the example in the paragraph
   above, is exactly what lands in it.

   ⚠️ IT TAKES `--c-peach`, NOT `--c-coral`, AND THAT IS NOT A TYPO. The run
   sheet's own `.tl-door.door-coral` in styles.css has always painted peach —
   the class is named coral and the colour is peach. Matching the NAME instead
   of the VALUE would have put a red tag against a peach card and satisfied
   every check while looking wrong, which is the whole failure this block of
   rules exists to prevent. Check 19 covers coral now too.

   ⚠️ THESE RULES LIVE IN checks.css AND MUST STAY HERE. checks.css loads AFTER
   styles.css, so an "override" written over there at the same specificity would
   silently lose. That ordering has bitten three times tonight. */
.arr-card.tone-pink  { --tone: var(--pink-deep); --tone-tint: var(--pink-tint); }
.arr-card.tone-blue  { --tone: var(--blue);     --tone-tint: var(--blue-soft); }
.arr-card.tone-green { --tone: var(--c-sage);   --tone-tint: var(--c-sage-tint); }
.arr-card.tone-plum  { --tone: var(--c-plum);   --tone-tint: var(--c-plum-tint); }
.arr-card.tone-coral { --tone: var(--c-peach);  --tone-tint: var(--c-peach-tint); }
.arr-card.tone-grey  { --tone: var(--ink-soft); --tone-tint: var(--line-soft); }

/* 🛑 THE ORDER OF THESE TWO IS THE WHOLE RULE, AND IT WAS THE WRONG WAY ROUND.
   `border-color` is the SHORTHAND — it sets all four sides, including the left.
   With `border-left-color` written first, the shorthand immediately overwrote
   it, so the coloured left edge never painted on ANY card. Measured on all five
   on 17 September: every one had the pale tint where the strong colour should
   be, which is why the cards read as one flat block.

     pink  #fdeaf3 where #c31465 belongs   ·  blue  #eef2fa where #1e3f7d belongs
     green #d6f7e2 where #00733d belongs   ·  plum  #ffe3ef where #b3145e belongs
     coral #ffeeda where #b34e00 belongs

   Nothing was broken and nothing said anything — the CSS declared a colour the
   browser threw away one declaration later. `a-field-nothing-reads-is-not-a-
   guard`, in a stylesheet. */
.arr-card[class*="tone-"] { border-color: var(--tone-tint); border-left-color: var(--tone); }

/* The heading wears the tint full-bleed, the way the section bands down the
   sheet do — that is the look Gee pointed at: "a color similar to the morning
   bride's house heading". */
.arr-card[class*="tone-"] .arr-card-head {
  margin: -9px -12px 8px;
  padding: 7px 12px;
  background: var(--tone-tint);
  color: var(--tone);
}

/* The name goes black. Gee, 28 Aug: "I don't want the text in there with the
   Gucci paints, Michelle, big letter code JLS... in that pinky color. I want
   that to be black text. I like that the colors and the start times are a
   different color."
   Only in this block — the cards down the sheet are untouched. */
.arrivals-groups .arr-card-list li { color: var(--ink); }

/* The time gets a box of its own, in the card's own colour.
   Nine names down a card all in one pink was a paragraph; the time is what
   you scan for, and a filled chip is what the eye lands on. */
.arr-card-list .arr-time {
  flex: 0 0 auto;
  min-width: 66px;
  margin-right: 8px;
  padding: 1px 6px;
  border-radius: 5px;
  background: var(--tone-tint, var(--teal-tint));
  color: var(--tone, var(--teal-deep));
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* A row, so a long name indents into its own column instead of wrapping back
   under the chip — "The Big Letter Co - JLS / Event Hire" was breaking the
   line of times you read the card by.

   NOT scoped to .arrivals-groups any more. The block at the top of the run
   sheet is inside that wrapper; the cards placed down IN the run sheet are
   not, so their rows were never laid out as rows. It only showed when a line
   carried the "next day" badge, which is a block: 12:30am, then NEXT DAY
   centred on its own line, then Signature Chauffeurs on a third. Gee sent a
   screenshot of exactly that on 30 Aug. The chip already says flex: 0 0 auto —
   it was waiting for a flex parent that half the cards never had. */
.arr-card-list li {
  display: flex;
  align-items: baseline;
  gap: 0;
}

.arr-card-list .arr-name { flex: 1 1 auto; min-width: 0; }

.arr-card-list .arr-name { color: inherit; }
.arr-card-list li.is-tbc { color: #b3001b; }

/* A time that is not settled keeps saying so — the box changes colour with it
   rather than dressing an unknown up as a fact. Red beats the door's colour
   here on purpose: unknown is more urgent than which building. */
.arr-card-list li.is-tbc .arr-time {
  background: var(--danger-tint);
  color: var(--danger);
}

/* A KNOWN TIME THAT IS NOT SIGNED OFF — migration 133, 22 September.
   Gee: "I need a TBC for me and the supplier to have that option, time span
   wise, or just time itself as a TBC, or else it doesn't look correct."

   Amber, NOT the red above, and the distinction is the whole point. Red means
   "no time at all, you still have to ring them". This means "9:15, but nobody
   has signed it off" — a real answer, just not a settled one. Painting it red
   would put HD's four crews in alarm colours on a card Gee reads at a door,
   and she had already said that morning there was too much red to decipher.

   The same amber as the due-soon tick box: 5.21 to 1 on white, so it passes
   at small sizes where the tangerine it replaced did not. */
.arr-card-list li.has-tbc .arr-time {
  background: #ffeeda;
  color: #a85700;
}

/* Rides inside the time box like "next day", so the flex row keeps its shape
   and a long supplier name still indents into its own column. */
.arr-tbc {
  display: block;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* On the run sheet chip there is no box to ride inside, so it sits beside the
   time instead. The chip is small and grey already; the tag carries the
   meaning without a second colour on the row. */
.tl-arr .arr-tbc {
  display: inline;
  margin-left: 4px;
  color: #a85700;
}

/* "next day" rides inside the box, not beside it. */
/* "Next Day", normal letters — Gee, 21 Oct: "should not be in capital
   letters and should be normal Next Day." (CHECK 233) */
.arr-card-list .arr-time .arr-next {
  display: block;
  font-size: 9px;
  letter-spacing: 0;
  text-transform: none;
}

/* The driver and their mobile. Only transport carries one, and it is usually
   blank until the day before — so a missing one says TBC in red rather than
   leaving a gap you would not notice. */
.arr-driver {
  display: block;
  font-size: 12px;
  color: var(--ink);
  font-weight: 600;
}

.arr-driver.is-tbc { color: #b3001b; background: #ffe0e3; border-radius: 3px; padding: 0 4px; }

/* "booked start" and the team name — what a time is, when it isn't an arrival. */
.arr-note {
  font-size: 11px;
  color: var(--muted);
  font-weight: 400;
}

.arr-role {
  font-size: 12px;
  color: var(--muted);
  text-align: right;
}

@media (max-width: 560px) {
  .arrivals li { grid-template-columns: 74px 1fr; }
  .arr-role { grid-column: 2; text-align: left; }
}

/* ---------------------------------------------------------------------------
   A file said along with a comment.

   This is the ONLY place these classes are styled. checks.css loads after
   styles.css, so a second definition over there would lose silently — which is
   exactly what happened on 29 Aug when I wrote one without looking here first.
   If you are changing how an attachment looks, change it here.

   It used to be teal underlined text, which read as a link in a sentence
   rather than as a thing that arrived. Gee, 29 Aug: "there's no way that you
   can see easily that the running sheet has been attached to that. I think
   that has to be like a colour."

   So: a filled chip, indigo, sized to its own content. Indigo because teal is
   already every link and every conversation in the platform — a file needs to
   be a different kind of thing, not a louder version of the same one.

   Thumbnails stay small on purpose: the thread is a conversation, not a
   gallery, and tapping opens the real thing.
   --------------------------------------------------------------------------- */

.comment-file {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;   /* so the chip is as wide as its words, not the row */
  gap: 5px;
  max-width: 100%;
  margin-top: 6px;
  text-decoration: none;
}

/* "📎 Invoice added — LO-4320.pdf". The label carries the meaning; the
   filename is the footnote, because a camera filename means nothing. */
.comment-file-label {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  max-width: 100%;
  padding: 5px 12px;
  border: 1px solid var(--c-indigo, #4a00b0);
  border-radius: 999px;
  background: var(--c-indigo-tint, #eae0ff);
  color: var(--c-indigo, #4a00b0);
  font-size: .78rem;
  font-weight: 700;
  line-height: 1.35;
}

.comment-file-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: inherit;
  font-weight: 500;
  font-size: .74rem;
  opacity: .8;
}

a.comment-file:hover .comment-file-label {
  background: var(--c-indigo, #4a00b0);
  color: #fff;
}

.comment-file img {
  display: block;
  max-width: 180px;
  max-height: 180px;
  border: 1px solid var(--line);
  border-radius: 8px;
}

.comment-file.is-doc { text-decoration: none; }

/* "📎 IMG_2041.png" under the compose box — did that attach? now never asked. */
.compose-file-name {
  display: block;
  margin-top: 3px;
  font-size: .75rem;
  color: var(--muted);
}

/* The person under the business name — supplier table, contact card, portal. */
.sup-person,
.card-person,
.portal-supplier-person {
  display: block;
  font-size: 12px;
  color: var(--muted);
  font-weight: 400;
}

.sup-person { margin-top: 2px; }
.card-person { margin: 2px 0 0; }
.portal-supplier-person { margin-top: 1px; }

/* ---------------------------------------------------------------------------
   Teams — crews within one booking.

   Boxed rather than listed, because two crews at two addresses read as two
   things. A flat list of six time fields reads as one confusing supplier.
   --------------------------------------------------------------------------- */

.team-row {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface, #fff);
}

.team-head { display: flex; gap: 8px; align-items: center; }
.team-head .team-name { flex: 1; font-weight: 600; }

.team-del {
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.team-del:hover { color: var(--pink, #e8197a); }

.team-times { display: flex; gap: 10px; flex-wrap: wrap; }

.team-times label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--teal, #009faa);
  font-weight: 700;
}

.team-times input { min-width: 116px; }

/* ---------------------------------------------------------------------------
   A TBC TICK UNDER EVERY TIME BOX — migration 134, 22 September.

   Gee, on what 133 gave her: "No, it's not one tick. I want one tick per box,
   but I also want a better box and a better tick because you can't tell. It's
   visually very hard to see."

   🛑 SHE WAS RIGHT, AND THE MEASUREMENT IS BRUTAL. 133's tick was a bare
   <input type="checkbox"> with NO RULE OF ITS OWN anywhere in this file, so it
   inherited `.team-times label` above — column direction, uppercase, bold,
   heading colour — and rendered 4px wide × 16px tall under words that read
   exactly like ARRIVES and FINISHES. Measured in her live browser. It was
   ticked on 0 of 32 crews and 0 of 49 bookings across every wedding, because
   there was nothing there to press.

   ⚠️ AND COLOUR ALONE COULD NOT HAVE FIXED IT. `accent-color` only paints a
   box that is ALREADY ticked — the empty state stays browser-grey however many
   ways you set it. That is in memory as `accent-color only paints a ticked
   box`, and the empty state is precisely the one she could not see. So the
   real input is taken out of the layout and `.tbc-mark` is drawn in its place,
   with a deliberate look for BOTH states.

   ⚠️ AMBER (#a85700), THE SAME ONE `.arr-card-list li.has-tbc` uses above.
   Red means "no time at all, ring them"; this means "8:30, but nobody has
   signed it off". One idea, one colour, wherever it appears.
   --------------------------------------------------------------------------- */

/* The time box and its tick travel together. This is the flex child of
   `.team-times` now — the caption label sits inside it and keeps every rule it
   already had, so the three columns look exactly as they did. */
.team-times .tm-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

/* Sentence case, on one line, ordinary weight — everything `.team-times label`
   is not. Scoped as `label.tbc-tick` so it outranks that rule on specificity
   rather than on file order, which has bitten this project before. */
.team-times label.tbc-tick {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  user-select: none;
  align-self: flex-start;
  padding: 2px 2px 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: none;
  color: var(--muted, #6c6067);
}

/* Out of the layout, not display:none — a hidden control is not focusable and
   this one has to stay reachable from the keyboard. */
.team-times label.tbc-tick input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  min-width: 0;
}

.team-times .tbc-mark {
  width: 22px;
  height: 22px;
  flex: none;
  border: 2px solid #b9b2ab;
  border-radius: 5px;
  background: #fff;
  display: grid;
  place-items: center;
  box-sizing: border-box;
}

/* The check itself, drawn: two borders of an empty box, rotated. Nothing to
   load and nothing to go missing. */
.team-times .tbc-mark::after {
  content: "";
  width: 11px;
  height: 6px;
  border-left: 2.5px solid #fff;
  border-bottom: 2.5px solid #fff;
  transform: rotate(-45deg) translateY(-1px);
  opacity: 0;
}

.team-times label.tbc-tick input:checked + .tbc-mark {
  background: #a85700;
  border-color: #a85700;
}

.team-times label.tbc-tick input:checked + .tbc-mark::after { opacity: 1; }

.team-times label.tbc-tick input:checked ~ .tbc-txt { color: #a85700; }

/* Keyboard users get the same ring they would have had on the real box. */
.team-times label.tbc-tick input:focus-visible + .tbc-mark {
  outline: 2px solid #a85700;
  outline-offset: 2px;
}

/* ⚠️ THE TICK IS NOT THE ONLY SIGNAL. A ticked box tints the TIME as well, so
   the state reads from a glance at the row rather than from finding a 22px
   control — which is the complaint that started this. Live, via :has(), so it
   follows the tick without a re-render and can never sit stale.

   🛑 NOT `input[type="time"]`, AND THIS IS THE MEMORY RULE `time-inputs-are-
   not-time-inputs`. Every time box in this app is converted to type="text" at
   boot so the AM/PM typing works — `<input type="time">` exists in the source
   and never in the DOM. The first version of this rule selected on the type
   and matched NOTHING: the tick worked, the tint silently did not, and only
   reading the rendered element back showed it.

   `:not(.tbc-tick)` because the tick's own label is a direct child too, and
   without it the checkbox would tint itself. */
.team-times .tm-field:has(.tbc-tick input:checked) > label:not(.tbc-tick) input {
  background: #fdf6ea;
  color: #a85700;
  font-weight: 600;
  /* ⚠️ NO EDGE ON THIS BOX, AND THAT IS A DECISION RATHER THAN AN OVERSIGHT.
     Two ways of drawing one were tried on the live page and BOTH were
     overwritten by the base sheet — `border-color` by its `border` shorthand
     (`a-shorthand-wipes-the-longhand`), and an inset `box-shadow` by a later
     rule that resets it to transparent. Each was measured, not assumed.

     The remaining three declarations carry the state on their own: an amber
     ground, amber text and 600 weight, against a white box in near-black at
     400. Leaving a fourth declaration in that quietly does nothing is the
     exact fault this whole feature came from. */
}

/* ---------------------------------------------------------------------------
   Section movers.

   Always visible, and sat right beside the count rather than flung to the far
   edge of the row. They were hover-only and pinned right, which on a wide
   screen put them fourteen hundred pixels from the name they belonged to —
   invisible until you happened to sweep the mouse across the right thing.
   --------------------------------------------------------------------------- */

.sec-move {
  display: inline-flex;
  gap: 3px;
  vertical-align: middle;
}

/* ⚠️ THE FOLD IS A TRIANGLE, NOT A BUTTON, and it is at the opposite end of
   the heading from the × that DELETES the section. Hiding and deleting must not
   look alike or sit together — the whole reason this exists is that the only
   control which made a section go away was the destructive one.

   No border and no box: a disclosure triangle is a piece of the heading, not a
   control competing with the five on the right. */
.task-group-head .sec-fold {
  border: 0;
  background: none;
  width: 18px;
  padding: 0;
  margin-right: 2px;
  color: var(--muted);
  font-size: 11px;
  cursor: pointer;
}
.task-group-head .sec-fold:hover,
.task-group-head .sec-fold:focus-visible { color: var(--pink, #e8197a); }

/* The tasks go, the heading and its count stay — a folded section still has to
   say "0/1" rather than becoming a blank line you cannot identify. */
.task-group.is-folded .task-list { display: none; }
.task-group.is-folded { margin-bottom: 6px; }

.sec-btn {
  border: 1px solid var(--line);
  background: var(--surface, #fff);
  color: var(--muted);
  border-radius: 6px;
  width: 22px;
  height: 20px;
  line-height: 1;
  font-size: 12px;
  cursor: pointer;
  padding: 0;
}

/* ✓ Complete / Not yet under a tick (CHECK 251): its own line, RIGHT UNDER THE
   CIRCLE (CHECK 271) — the last child of the row, wrapped onto a line of its
   own, with alignTickAsk() setting the left edge to the circle's. */
.task-row:has(> .tick-ask) { flex-wrap: wrap; }
.task-row > .tick-ask { display: flex; gap: 8px; align-items: center; flex: 0 0 100%; box-sizing: border-box; order: 99; margin: 4px 0 2px; }
#task-picked-bar .picked-done,
.task-row .tick-ask .tick-yes { background: #00796b; border-color: #00796b; color: #fff; font-weight: 700; }

/* Select one section (CHECK 247): a word, so it is wider than the icon buttons. */
.sec-btn.sec-pick { width: auto; padding: 0 7px; font-size: 11px; font-weight: 700; color: var(--teal-deep, #00796b); }

.sec-btn:hover {
  color: var(--pink, #e8197a);
  border-color: var(--pink, #e8197a);
}

.sec-btn:focus-visible {
  outline: 2px solid var(--pink, #e8197a);
  outline-offset: 1px;
}

@media print { .sec-move { display: none; } }

/* ---------------------------------------------------------------------------
   The Notion pull review.

   Everything arrives ticked, so the work is unticking — which means a row has
   to be scannable in about a second. Heading bold, the sentence underneath in
   grey, and a duplicate warning that is impossible to read past.
   --------------------------------------------------------------------------- */

.pull-meet { margin-top: 16px; }

.pull-meet h4 {
  margin: 0 0 8px;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--teal, #009faa);
  font-weight: 700;
  border-bottom: 1px solid var(--line);
  padding-bottom: 5px;
}

.pull-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 8px 10px;
  border-radius: 8px;
}

/* The tick and the words. The owner buttons sit outside this, so pressing one
   cannot toggle the tick on the way past. */
.pull-pick {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  cursor: pointer;
  min-width: 0;
}

.pull-row:hover { background: var(--sunk, #f5f0f2); }

.pull-row input {
  margin-top: 4px;
  flex: none;
  width: 16px;
  height: 16px;
  accent-color: var(--pink, #e8197a);
}

.pull-title { font-weight: 600; }

/* The Notion status, shown because it is what decides whose job this is.
   Without it a row sitting on "the couple" looks like a decision the platform
   made on its own. */
.pull-status {
  margin-left: 7px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--line-soft, #f5f0f2);
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Who the task is for, on every row rather than only when Notion says Couple.
   A row with no marking used to mean both "mine" and "nobody has said". */
.pull-owner {
  display: flex;
  flex: none;
  gap: 0;
  align-self: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.pull-owner button {
  padding: 3px 11px;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.pull-owner button:hover { background: var(--sunk, #f5f0f2); color: var(--ink); }

.pull-owner button.is-on {
  background: var(--teal-deep);
  color: #fff;
}

/* The couple's half of the split is the half worth reading — it is the only
   part of this batch that leaves Gee's screen. */
.pull-count { margin-top: -4px; }
.pull-count strong { color: var(--teal-deep); }

.pull-detail,
.pull-dup { display: block; font-size: 13px; }

.pull-detail { color: var(--muted); }

.pull-dup {
  color: var(--amber, #d4121f);
  font-weight: 600;
  margin-top: 3px;
}

.pull-row.is-dup { background: var(--amber-bg, #ffe3e4); }

/* ---------------------------------------------------------------------------
   Pull from Notion, REDESIGNED 19 Oct (her yes: "Happy for you to redesign it
   and make it even better. It's just really shit the way it's designed").

   The same morning had grown a tick box that only selected, a tag, two row
   buttons, four meeting buttons that renamed themselves, four more at the top
   and one Save for everything. Now: meetings down the LEFT, ONE meeting's
   items on the right, ONE four-way switch per item, the same switch as
   "Set all" for the meeting, and Save PER MEETING. Sky = complete, violet =
   hidden, mint = checklist, pink = do not pull — the mock-up she said yes to.
   --------------------------------------------------------------------------- */

#notion-pull-modal .modal-box { max-width: min(1100px, 96vw); width: 1100px; }

.pull-wrap {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 0;
  margin-top: 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: clip;
}

/* The meetings. Sticky, so the list of meetings stays put while she scrolls
   one meeting's items. */
.pull-rail {
  position: sticky;
  top: 0;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px;
  background: #fff8fb;
  border-right: 1px solid var(--line);
  min-height: 100%;
}

.pull-rail-lbl {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 2px 6px 4px;
}

.pull-mt {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  padding: 8px 10px;
  border: 1.5px solid transparent;
  border-radius: 10px;
  background: none;
  font: inherit;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
}
.pull-mt:hover { background: #fff; }
.pull-mt.is-on { background: #fff; border-color: var(--pink, #e8197a); }
.pull-mt:focus-visible { outline: 2px solid var(--pink, #e8197a); outline-offset: 1px; }
.pull-mt.is-saved { cursor: default; opacity: .85; }
.pull-mt.is-saved:hover { background: none; }

.pull-mt-name { font-weight: 800; font-size: 13.5px; line-height: 1.25; }
.pull-mt-date { font-size: 12px; color: var(--muted); }
.pull-mt-bar { height: 5px; border-radius: 9px; background: #f3e3ea; overflow: hidden; }
.pull-mt-bar i { display: block; height: 100%; background: var(--teal-deep, #1f7a7a); }
.pull-mt-state { font-size: 12px; font-weight: 700; color: var(--teal-deep, #1f7a7a); }
.pull-mt.is-saved .pull-mt-state { color: #0f6b45; }

/* One meeting. */
.pull-main { min-width: 0; display: flex; flex-direction: column; }

.pull-mhead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 12px 16px 10px;
  border-bottom: 1px solid var(--line);
  background: #e3f6f5;
}
.pull-mtitle { margin-right: auto; font-weight: 800; font-size: 16px; }
.pull-mtitle small { display: block; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.pull-setall { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--muted); }

.pull-list { padding: 2px 16px 8px; }

.pull-list .pull-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 12px;
  align-items: center;
  padding: 10px 6px;
  margin: 0;
  border-radius: 0;
  border-bottom: 1px solid var(--line);
}
.pull-list .pull-row:last-child { border-bottom: 0; }
.pull-list .pull-row:hover { background: #fffafc; }
/* Not sorted yet: a faint pink edge, so what is left to do is visible. */
.pull-list .pull-row.is-unsorted { box-shadow: inset 3px 0 0 #f7b9d1; }
.pull-list .pull-row.is-dup { background: var(--amber-bg, #ffe3e4); }

.pull-what { min-width: 0; }

/* The one control: four segments. */
.pull-seg {
  display: inline-flex;
  flex: none;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
  background: #fff;
}
.pull-seg button {
  padding: 5px 11px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
  cursor: pointer;
}
.pull-seg button + button { border-left: 1.5px solid var(--line); }
.pull-seg button:hover { background: #fff3f8; color: var(--ink); }
.pull-seg button:focus-visible { outline: 2px solid var(--pink, #e8197a); outline-offset: -2px; }
.pull-seg button.is-on.is-add  { background: #c9f5df; color: #0f6b45; }
.pull-seg button.is-on.is-done { background: #d6ecff; color: #1d5d99; }
.pull-seg button.is-on.is-hide { background: #ece0ff; color: #5b2fa8; }
.pull-seg button.is-on.is-off  { background: #ffe3ee; color: #c2185b; }

/* Whose job it is — a small dropdown now, not three buttons on every row. */
.pull-who {
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--teal-deep, #1f7a7a);
  border: 1.5px solid var(--line);
  border-radius: 999px;
  padding: 4px 8px;
  background: #fff;
}

.pull-alldone { padding: 30px 16px; text-align: center; color: var(--muted); }
.pull-alldone strong { display: block; color: var(--ink); font-size: 16px; margin-bottom: 4px; }

/* The footer line beside Save — what THIS meeting's save will do. */
.pull-foot-sum { font-size: 13.5px; color: var(--ink); }
.pull-foot-sum b { color: var(--pink-deep, #c2185b); }

@media (max-width: 760px) {
  .pull-wrap { grid-template-columns: 1fr; }
  .pull-rail { position: static; flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); min-height: 0; }
  .pull-rail-lbl { display: none; }
  .pull-mt { min-width: 170px; }
  .pull-list .pull-row { grid-template-columns: 1fr; }
  /* The four choices share the width, so "Do not pull" is never cut off. */
  .pull-seg { display: flex; width: 100%; }
  .pull-seg button { flex: 1 1 0; padding: 7px 4px; text-align: center; font-size: 12px; }
  .pull-setall { width: 100%; flex-wrap: wrap; gap: 4px; }
  .pull-who { justify-self: start; }
}


/* "next day" beside an after-midnight arrival, so 12:30am at the bottom of the
   list reads as the end of the night rather than a mistake. */
.arr-next {
  display: block;
  font-size: 10px;
  letter-spacing: 0;
  text-transform: none;   /* "Next Day", her capitals (CHECK 233) */
  font-weight: 700;
  color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Sign in.

   The link is the way in; the password is the exception. Gee uses the second
   one daily and a couple never sees it, so it hides behind a text button
   rather than sitting there as a second empty field to worry about.
   --------------------------------------------------------------------------- */

.login-alt { margin: 10px 0 0; text-align: center; }

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

.linkish:hover { color: var(--pink, #e8197a); }

.login-sent {
  margin: 14px 0 0;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--good-bg, #d6f7e2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--good, #00733d);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
}

#login-password-row { margin-top: 14px; }

/* ---------------------------------------------------------------------------
   Install bar.

   Sits above the portal rather than floating over it — a couple reads this
   once and acts on it, and a dismissable overlay on a phone is a thing you
   swipe away without reading.
   --------------------------------------------------------------------------- */

.install-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 13px 18px;
  background: var(--pink, #e8197a);
  color: #fff;
  font-size: 14px;
  line-height: 1.45;
}

.install-words { display: flex; flex-direction: column; gap: 2px; flex: 1 1 260px; }
.install-words strong { font-weight: 700; }
.install-words span { opacity: .92; font-size: 13px; }

/* The iOS share glyph, so "tap Share" points at something they can see. */
.ios-share::before {
  content: "";
  display: inline-block;
  width: .72em;
  height: .92em;
  margin-right: .18em;
  vertical-align: -.12em;
  background: currentColor;
  -webkit-mask: no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l4 4h-3v9h-2V6H8l4-4zM5 10h3v2H6v8h12v-8h-2v-2h3a1 1 0 011 1v10a1 1 0 01-1 1H5a1 1 0 01-1-1V11a1 1 0 011-1z'/%3E%3C/svg%3E");
  mask: no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l4 4h-3v9h-2V6H8l4-4zM5 10h3v2H6v8h12v-8h-2v-2h3a1 1 0 011 1v10a1 1 0 01-1 1H5a1 1 0 01-1-1V11a1 1 0 011-1z'/%3E%3C/svg%3E");
}

.install-acts { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.install-acts .linkish { color: #fff; opacity: .85; }
.install-acts .linkish:hover { color: #fff; opacity: 1; }
.install-acts .btn-primary { background: #fff; color: var(--btn-pink, #d1176e); border-color: #fff; }


/* ---------------------------------------------------------------------------
   The preview bar — Gee looking at a couple's portal.

   Deliberately charcoal rather than pink. The pink bar above it is something
   a COUPLE reads; this one says "you are in a mode", and the two must never
   be mistaken for each other at a glance. It also carries the only way back:
   the other button on this screen is Sign out, which would sign her out of
   the planner entirely.
   --------------------------------------------------------------------------- */

.preview-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  background: #2a2126;
  color: #fff;
  font-size: 14px;
  line-height: 1.45;
}

/* Delete, pushed away from the actions you actually use and quiet until you
   mean it. It sat in the run as a solid red button, which made the one
   irreversible control the most prominent thing in the box. */
.file-row-actions .bf-del { margin-left: auto; opacity: .62; }
.file-row-actions .bf-del:hover,
.file-row-actions .bf-del:focus-visible {
  opacity: 1;
  color: var(--red, #b3001b);
  border-color: currentColor;
}

/* Remove a whole budget category, from its heading row.

   Faint but never invisible. Hiding it until hover would put it out of reach
   on a touch screen entirely, and 13.1 already cost a round on a control Gee
   could not find — "I don't actually even know how to click out of it". Quiet
   is the goal, not hidden. */
.bg-table tr.bg-cat th { position: relative; }

.bg-cat-del {
  margin-left: 8px;
  padding: 0 4px;
  border: none;
  background: none;
  color: inherit;
  font-size: .92em;
  line-height: 1;
  cursor: pointer;
  opacity: .38;
  transition: opacity .12s ease;
}

.bg-cat:hover .bg-cat-del,
.bg-cat-del:focus-visible { opacity: .8; }
.bg-cat-del:hover { opacity: 1; }

/* Is this line's supplier on the team, and the offer to put them there. */
.b-team-hint { margin-top: 6px; font-size: .78rem; }
.b-team-hint .team-on { color: var(--teal-deep, #007c85); }

/* How they are paid, on the supplier card. 12 September.

   Gee looked for the cash option here and it was only on the budget line:
   "Did you add the cash option for the suppliers, because I can't see it
   here?" Told that two controls on one column is the fault this codebase has
   hit before, she chose both anyway — so this writes the SAME column on the
   SAME row and nothing is cached. See syncBudgetHint() in suppliers.js.

   Inline in the hint row beside "On the budget — Cake", because it is one more
   fact about the same budget line rather than a field of its own. Sized down
   to sit on a hint's baseline without dragging the row taller. */
.b-team-hint .s-pay {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 10px;
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink-soft, #4a4046);
  white-space: nowrap;
}

.b-team-hint .s-pay select {
  font: inherit;
  font-size: .78rem;
  padding: 1px 6px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}

.b-team-hint .s-pay select:hover { border-color: var(--teal-deep); }
.b-team-hint .linkish { font-size: inherit; }

/* ON THE BUDGET, AS A MINT PANEL — one row per fact. 1 October.

   Gee, on La Belle Venues: "it's very hard to see that and read that." It was
   11px grey text running on in a 286px column. She picked option A of three:
   the payments panel's own mint and green edge (.hb-pay, CHECK 99), a label
   per row, her pink for anything she can press. No grey anywhere. CHECK 117. */
#s-budget-hint .sbh-panel {
  display: grid;
  gap: 7px;
  margin-top: 4px;
  padding: 10px 12px;
  border: 1.5px solid #16a36a;
  border-radius: 10px;
  background: #e6f7ef;
  font-size: .92rem;
  color: var(--ink);
}
#s-budget-hint .sbh-row {
  display: grid;
  grid-template-columns: 74px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
}
#s-budget-hint .sbh-k {
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: #0d7a4f;
}
#s-budget-hint .sbh-panel .linkish {
  justify-self: start;
  font-size: inherit;
  font-weight: 700;
  color: var(--pink-deep);
}
#s-budget-hint .sbh-row select {
  justify-self: start;
  font: inherit;
  font-weight: 700;
  padding: 2px 8px;
  border: 1.5px solid var(--pink);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}

/* Search, sized so it does not crowd the ticks beside it. */
.bg-search-field { min-width: 190px; }

.preview-words { flex: 1 1 260px; opacity: .94; }
.preview-words b { font-weight: 700; opacity: 1; }
.preview-bar .btn-primary {
  margin-left: auto;
  background: #fff;
  color: #2a2126;
  border-color: #fff;
}

/* Spaced so it reads as a code rather than a phone number. Sized for the
   8 digits Supabase issues, with slack — the box must never be the thing
   that decides how long a code is allowed to be. */
.code-input {
  font-size: 22px;
  letter-spacing: .22em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

#login-code-row { margin-top: 14px; }

/* Arrival phases — the morning, the church, the reception. Twenty names in
   one column is a list you read; four short lists is something you glance at. */

/* Side by side, the way they already print. Gee, 28 Aug, pointing at the
   empty half of the page beside a 350px card: "I would love for there to be
   room on the running sheet to be able to have them both on the same line...
   see how there's so much room."
   Stacked, the bride's morning and the groom's morning are a scroll apart and
   the 9am that happens in both places gets missed. */
.arrivals-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px 26px;
  align-items: start;
}

/* 🛑 THE HEADER WAS A LID ON NOTHING. Gee, 18 September: *"The supplier
   arrival time needs a proper box to be in. It's not in it. See how the key
   details are like that, as in, you can tell that the photography and
   videography, and two locations, are a part of that."*

   She is right, and it is one missing rule. Measured on her page, the three
   blocks on this tab that carry a `.tl-header` bar:

       Nothing to look at  → .rsr-queue-onpage   border ✓  radius 0 0 14 14 ✓
       Key details         → .tl-details         border ✓  radius 0 0 14 14 ✓
       Supplier arrivals   → .arrivals-groups    border ✗  radius 0          ✗

   So the bar had its top corners rounded onto a body that was never closed
   underneath it, and the five cards read as loose furniture sitting below a
   heading rather than contents of it.

   ⚠️ THE SAME SHAPE AS `.tl-details`, IN ITS OWN COLOUR. Key details is teal
   because its bar is teal; this bar is `--blue`, so the box is blue. Copying
   the teal would have made one card out of two different headings.
   `make-it-look-like-that-means-reuse-those-classes`.

   ⚠️ SCREEN ONLY. The printed sheet lays this block out itself and she was
   pointing at the app, so print.css is left exactly as it was. */
@media screen {
  .arrivals-groups {
    padding: 16px 17px;
    border: 1.5px solid var(--blue);
    border-top: 0;
    border-radius: 0 0 var(--radius) var(--radius);
  }
}

/* Elsewhere is the catch-all — a family drop at a hotel across town. It runs
   the full width under the doors rather than pretending to be one of them. */
.arrivals-group.is-wide { grid-column: 1 / -1; }

/* ⚠️ THREE DOORS: TWO COLUMNS, NOT auto-fit. A wedding with no ceremony has
   three doors, and the builder widens the last of them. Left on auto-fit the
   container would still open five 260px tracks at full width — the widened
   card would span all five while the two mornings sat in the first two, narrow,
   with three empty tracks beside them. Pinning to two puts the mornings side by
   side at half the page each, which is the layout that was approved.
   Screen only; print.css is already two columns. */
.arrivals-groups.is-paired { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* The long card reads down one column and continues in the next, so the times
   stay in order — 12:00 to 5:00 on the left, 5:30 to the end on the right.
   `break-inside` because a row is a flex line and would otherwise be split
   across the column boundary, putting a time at the foot of one column and its
   supplier at the head of the next. */
.arrivals-group.is-split .arr-card-list {
  columns: 2;
  column-gap: 26px;
}
.arrivals-group.is-split .arr-card-list li {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}

.arrivals-group h4 {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--pink, #e8197a);
}

/* ---------------------------------------------------------------------------
   Bank details read off an invoice.

   Gee, 30 Aug: "why can't you attach it to their actual supplier card?"

   Set apart from the money facts above it, because this block is about WHERE
   the money goes rather than how much. The three states are colour-coded on
   purpose — a row that differs from the account already held has to be
   impossible to skim past.
   --------------------------------------------------------------------------- */

.bf-bank {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #faf7f9;
}

.bf-bank-head {
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 9px;
}

.bf-bank-rows { margin: 0; display: grid; gap: 6px; }

.bf-bank-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: .87rem;
}

.bf-bank-row dt {
  min-width: 118px;
  color: var(--muted);
  font-size: .8rem;
}

.bf-bank-row dd {
  margin: 0;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.bf-bank-tag {
  font-size: .68rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--line-soft);
  color: var(--muted);
}

/* WHETHER SHE HAS CHECKED THESE BANK DETAILS. Migration 115, on the contact
   card, directly under the four boxes.

   Amber and not red: an unverified account is not a WRONG account, it is one
   nobody has rung them about. Red is reserved for .bf-bank-row.is-differs
   below, which is the document disagreeing with her card — the actual fraud
   case — and having two reds would flatten the difference between "unchecked"
   and "this changed". */
.bank-trust {
  margin: 8px 0 0;
  padding: 8px 11px;
  border-radius: var(--radius-sm);
  font-size: .82rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
}
.bank-trust.is-unverified {
  background: var(--warn-tint, #ffe3e4);
  border: 1px solid var(--warn, #d4121f);
  color: var(--warn, #d4121f);
}
.bank-trust.is-unverified b { font-weight: 800; }
.bank-trust.is-unverified span { color: var(--ink-soft); }
.bank-trust.is-unverified .btn { margin-left: auto; }
.bank-trust.is-ok {
  background: #d6f7e2;
  border: 1px solid #00733d;
  color: #00733d;
  font-weight: 600;
}

.bf-bank-tag.is-new    { background: #daf0ff; color: #1e3f7d; }
.bf-bank-tag.is-same   { background: #d6f7e2; color: #00733d; }
.bf-bank-tag.is-differs{ background: #ffe0e3; color: #b3001b; font-weight: 800; }

/* A row whose account disagrees with the one already held. This is the fraud
   case and it gets the loudest thing on the panel. */
.bf-bank-row.is-differs {
  background: #ffe0e3;
  border-radius: 6px;
  padding: 5px 8px;
  margin: 0 -8px;
}

.bf-bank-row.is-differs dd { color: #b3001b; }

.bf-bank-warn {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: #ffe0e3;
  border-left: 4px solid #b3001b;
  font-size: .86rem;
  line-height: 1.5;
  color: #2a2126;
}

.bf-bank-warn strong { color: #b3001b; }

/* ⚠️ .rsr-fix IS DELETED — 12 September. It printed "Fix in Edit details" under
   every Key details finding. Gee: "I don't like how it's got the fix and stuff
   down there." It was right on 31 August, when the card was text and you did
   have to work out where to go; the card is a link now, so it was directions
   to a button printed under the button. Nothing emits the class. */

/* ---------------------------------------------------------------------------
   The line under a finding was too faint to read.

   Gee, on "Charcoald Catering — still an estimate": "I actually can't see that
   there's a comment there or any of them. It's too in the background."

   It carried --ink-soft, which is right for a caption and wrong for the half
   of the finding that tells you what is actually wrong — the title names the
   thing, this line is the evidence. Same weight as body text now.
   --------------------------------------------------------------------------- */
.check-detail { color: var(--ink); opacity: .82; }

/* ---------------------------------------------------------------------------
   "Not now" — migration 71.

   Gee, 31 Aug: a finding can be true, known, and not actionable yet.
   "Charcoald Catering — still an estimate" is correct, and it will be correct
   every time she opens that wedding for 54 days.

   A <details> rather than a popup on purpose: nothing to anchor, it closes
   itself, and it works from a keyboard without any code. It sits quiet until
   the row is hovered, like the row's own controls, so a panel of ten findings
   is not also a panel of ten buttons.
   --------------------------------------------------------------------------- */

.check-later { position: relative; flex: none; }

/* 🛑 IT WAS A MENU THAT LOOKED LIKE A CAPTION, AND THIS IS THE SECOND TIME.
   Gee, 16 September: "I thought you were going to give me a button to say
   dismiss. There's no button here. Why not? I thought you said it was done."

   It WAS done — "Settled — don't ask again" was in the DOM on all 125 of her
   findings. It was inside a closed <details> whose summary was 11px text in
   --ink-faint with no border, no background, and `opacity: 0` until the card
   was hovered. Measured off her live page before changing anything.

   ⚠️ `a-hover-reveal-she-has-to-be-told-about` IS ABOUT THIS EXACT ELEMENT —
   "Not now" sat on all 65 findings cards at opacity 0 because its reveal
   needed a `.check` ancestor the panel never had. That was fixed by giving it
   the ancestor. The hover-reveal itself was left in place, so the control
   stayed invisible-until-touched and merely became reachable. A control you
   have to hover to discover is a control you have to be told about.

   So the reveal is gone. It carries a hairline and a caret now — quiet enough
   not to compete with the finding it sits on, loud enough to read as
   something you press. */
.check-later > summary {
  list-style: none;
  cursor: pointer;
  padding: 2px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill, 999px);
  font-size: .72rem;
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: color .12s ease, background .12s ease, border-color .12s ease;
}

/* The caret is what says "there is more behind this". Without it the pill
   reads as a label that happens to have an outline. */
.check-later > summary::after {
  content: " ▾";
  font-size: .9em;
  opacity: .75;
}
.check-later[open] > summary::after { content: " ▴"; }

.check-later > summary::-webkit-details-marker { display: none; }

.check-later > summary:hover,
.check-later[open] > summary {
  color: var(--ink);
  background: var(--line-soft);
  border-color: var(--ink-faint);
}

.check-later-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 132px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 10px);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}

.check-later-menu button {
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: .8rem;
  text-align: left;
  cursor: pointer;
}

.check-later-menu button:hover { background: var(--line-soft); }

/* Coming back is not a hover-only action: if a finding is being shown BECAUSE
   it was put down, the way to undo that has to be visible without a mouse. */
.check-back {
  flex: none;
  padding: 2px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill, 999px);
  background: var(--surface);
  color: var(--ink-soft);
  font: inherit;
  font-size: .72rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.check-back:hover { color: var(--ink); border-color: var(--ink-faint); }

/* The count of what is hidden. Never silent — a panel that says "nothing to
   flag" while holding four findings back would be lying. */
.checks-put {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 2px 0;
  font-size: .78rem;
  color: var(--ink-soft);
}

.checks-put button {
  padding: 2px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill, 999px);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .74rem;
  font-weight: 600;
  cursor: pointer;
}

.checks-put button:hover { background: var(--line-soft); }

/* 🛑 THE REMINDERS WITH NOTHING LEFT TO REMIND HER ABOUT.
   Gee, 17 September: "it'll be good if I can access them when I go to their
   wedding... if it was in the group and the colour code and stuff".

   She could not: "Show them" reveals findings that are snoozed, and a stale row
   has no finding left, so the twelve on Tiffany & Liam appeared on NO screen.

   ⚠️ TEAL, NOT GREY, AND IT SHIPPED GREY FIRST. The reasoning for grey was
   that these are a tidy-up rather than a problem, so they should be the
   quietest thing on the panel. That is half right and it ignored what she
   actually asked for — "the colour code and stuff, very similar to how we get
   those notifications".

   The app already HAS a colour for this and it is not grey: `--teal-deep` is
   what "Done and dusted" wears in the Where we're at panel, twelve inches up
   the same screen. Every row here is good news — she finished the task, or
   moved its due date — so it is the same idea, and it gets the same colour and
   the same ✓. Grey would have made the app's one piece of unambiguously good
   news the only thing on the Overview with no colour at all.

   ⚠️ TINT, NOT FILL. `--teal-tint` behind `--ink-soft` text: coloured enough
   to group, quiet enough that it never competes with a red finding beside it.
   A warning colour here would be the app telling her off for having done the
   work. */
.checks-stale {
  margin: 6px 0 2px;
  padding: 9px 11px;
  border-radius: 10px;
  background: var(--teal-tint, rgba(0, 0, 0, .03));
  border: 1px solid var(--teal-deep);
  border-left-width: 3px;
}

.checks-stale-head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--teal-deep);
  margin-bottom: 6px;
}

.checks-stale-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 5px 0;
  font-size: .78rem;
  color: var(--ink-soft);
}

/* The same ✓ the settled list uses, in the same colour. It is the mark that
   says "this one is answered", and it already means that to her. */
.checks-stale-row .checks-stale-tick {
  flex: none;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.45;
  color: var(--teal-deep);
}

.checks-stale-row + .checks-stale-row { border-top: 1px solid rgba(0, 124, 133, .22); }
.checks-stale-row .checks-stale-what { flex-grow: 1; min-width: 0; }

/* 🛑 CLEAR IS A PLAIN `.check-back` AND GETS NO RULE OF ITS OWN.
   It shipped with one, and the one was a word-for-word copy of `.check-back`
   above — same padding, same border, same colour, same weight. Two definitions
   of one button, and the copy was MORE SPECIFIC, so it beat the phone rule
   twelve lines down: measured under `(hover: none)`, "Bring it back" grew to
   29px tall and Clear stayed at 23. On her phone the tidy-up button was the
   only control on the panel that never got its tap target.

   Nothing was gained by the copy. `opacity: 1` was defensive against a
   hover-reveal that `.check-back` has never had. Deleting it is the fix, and
   it is why a duplicate is worth hunting even when every value agrees: the
   values agreed and the CASCADE did not. */

/* On a phone there is no hover, so "Not now" has to be there already. */
@media (hover: none) {
  .check-later > summary { opacity: 1; padding: 5px 11px; }
  .check-back { padding: 5px 11px; }
  .check-later-menu button { padding: 10px 12px; }
}

/* ---------------------------------------------------------------------------
   The same findings, on the page they are about.

   Gee picked this shape on 31 Aug from the mockup: the Overview keeps the whole
   list AND each tab shows its own. One finding in two places, not two findings.

   Deliberately quieter than the Overview panel. It sits ABOVE the thing it is
   about — the budget table, the run sheet — so it has to read as a note before
   the work, not as a second panel competing with it. No job grouping, no filter
   pills, no severity stripe down the side.
   --------------------------------------------------------------------------- */

/* ⚠️ A BARE CONTAINER NOW, deliberately. The <section> in index.html used to
   carry all the chrome — a pale card with a thin amber rail. The box INSIDE it
   carries it instead, so leaving this styled put a loud box inside a quiet
   card and the two edges fought. */
.checks-onpage {
  margin: 0 0 18px;
}

/* The head, the count pill, the hint and the hairline rows that used to live
   here are GONE, not commented out. They styled a shape this panel no longer
   has — see the .tl-header-onpage block further down. Leaving dead rules for
   classes nothing emits is how the next person reading this file works out the
   wrong layout. */

@media print { .checks-onpage { display: none !important; } }

/* ---------------------------------------------------------------------------
   The count on the tab itself.

   So twenty budget problems are visible without opening anything. Absent
   rather than zero when a tab is clean — a quiet tab should look quiet, and
   "Suppliers 0" reads as a fault rather than as nothing to do.
   --------------------------------------------------------------------------- */

.subnav-n {
  display: inline-block;
  margin-left: 6px;
  min-width: 17px;
  padding: 0 5px;
  border-radius: var(--radius-pill, 999px);
  background: var(--warn-tint);
  color: var(--warn);
  font-size: .68rem;
  font-weight: 800;
  line-height: 17px;
  text-align: center;
  vertical-align: middle;
}

.subnav-item.is-active .subnav-n {
  background: var(--warn);
  color: var(--surface);
}

@media print { .subnav-n { display: none !important; } }

/* ===========================================================================
   "11 THINGS TO LOOK AT ON THIS PAGE" — 11 September.

   Gee: "I actually want exactly how you've got one thing to check in Key
   details, how you've got that big orange… I want it to be very visible and
   not hidden because these are crucial elements."

   So: the same shape as .tl-header-requests + .rsr-queue — a solid bar with
   white bold text, and a bordered box under it. Not a summary line.

   ⚠️ AND IT MUST NOT BE THE SAME ORANGE. Both boxes appear on the run sheet
   AT ONCE: "N things to check in Key details" sits directly above this one.
   Two identical filled bars stack into a single block you have to read to tell
   apart — the exact fault that made the arrival times box blue instead of teal
   on 28 August ("the supplier arrival times box… is the same as the key
   details. We don't want that to be that color").

   Gee, 11 Sept, after seeing both drawn side by side: "I think it needs to
   still be orange, but I'm wondering if it just needs to be distinguished from
   the other one as well… maybe it's a different colour box around it."

   THE SPLIT, and it is two changes not one, because one alone is too subtle:

     Key details   #ff6f00  vivid tangerine, filled body #ffe3e4
     This page     #d4121f  deep burnt orange, WHITE body

   The deep value is `--warn`, which already means "a finding" everywhere else
   in this app — on the tab counts, on the Overview rows, on the amber pills.
   So this is not a new colour at all; it is the colour findings already wear,
   finally worn loudly. The white body is the second tell: one box is filled
   and warm, the other is white and outlined, and they separate before you have
   read a word of either.
   =========================================================================== */

/* ⚠️ NOTHING HERE LAYS ANYTHING OUT. `.tl-header` and `.rsr-queue` above
   already do, and this panel now uses THEM — same bar, same bordered box, same
   cards. These two rules change the hue and nothing else.

   Gee, 11 Sept, on a version that had its own shape: "I don't like the way
   that you've done it… I want the things to look exactly as one thing to check
   in your Key details. The exact same layout as that… but I am happy to have a
   different colour."

   Which also means: if Key details' layout changes, this follows it for free.
   That is the point, and it is why there is no second set of box rules here.

   THE COLOUR. Key details is #ff6f00, the vivid tangerine. This is #d4121f,
   the deep burnt orange — which is `--warn`, and already means "a finding"
   everywhere else in this app: the tab counts, the Overview rows, the amber
   pills. Not a new colour, the colour findings already wear. The two bars sit
   one above the other on the run sheet, so they have to differ somehow, and
   she chose the hue as the thing that differs. */
/* ---------------------------------------------------------------------------
   ⚠️ THE TWO PANELS SWAP ORANGES. 12 September.

   Gee, comparing them: "out of the colours, I really prefer the vivid
   tangerine… I think the key detail should keep a colour of its own."

   Both halves of that, and they pull against each other — tangerine was Key
   details' colour, and this panel is the one she wants it on. So they swap
   rather than one of them getting something invented:

       this panel   #d4121f burnt  →  #ff6f00 vivid tangerine
       Key details  #ff6f00        →  #d4121f burnt

   Nothing new enters the palette, both stay orange (which is what a finding
   wears), and they are still told apart at a glance. Burnt lands on the panel
   that usually holds ONE thing, which is where the quieter colour belongs.

   ⚠️ If she meant it the other way round it is these two blocks and nothing
   else — swap the hexes back and the whole thing is undone.
   -------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   SAME SHAPE, HALF THE VOLUME. 12 September — option 2 of five drawn as HTML.

   Gee: "It's just way too red and orangey and black… It doesn't have to be
   orange. I think orange is good, as in there's a problem here, but I don't
   love the way that it looks."

   She was pointing at something countable rather than a matter of taste. This
   panel had SIX loud elements stacked: a solid #ff6f00 bar, a #ffe3e4 fill
   behind everything, a 2px orange frame, deep-orange bold card titles, black
   count circles and crimson urgent flags. Every layer shouting means none of
   them reads as the important one.

   Option 2 keeps the shape exactly — she has chosen this panel's layout three
   times now and it is not what was wrong — and turns the volume down:

     · the bar goes soft apricot with deep-orange text, instead of white on
       full tangerine with a drop shadow
     · the frame goes 1px, from 2px
     · the fill goes near-white, from #ffe3e4
     · the card titles go back to ink, because an orange marker AND orange
       words is the same signal said twice

   Orange still says "there is a problem here". It just stops being the wall,
   the frame and the text all at once.

   ⚠️ SCOPED TO -onpage ONLY. The Key details check next to it wears
   .tl-header-requests and a plain .rsr-queue, and is deliberately untouched.
   -------------------------------------------------------------------------- */
/* ⚠️ THE OUTLINE IS 2px #ff6f00, NOT A 1px HAIRLINE. Gee, 12 September, after
   option 2 landed: "I want the outline of that box to be bolded so it really
   stands out. I want that everywhere to really stand out."

   This is a deliberate partial reversal of option 2, and only the outer edge
   moves. Option 2 turned four things down at once — the bar's fill, the frame,
   the body fill, the card titles — and the frame is the one that was doing
   useful work. A strong edge around a QUIET interior is not the wall that was
   being fixed: the wall was a strong edge around a strong interior.

   One class pair, so "everywhere" is all three tabs at once — Checklist,
   Budget and Run sheet all mount .tl-header-onpage + .rsr-queue-onpage. */
.tl-header-onpage {
  background: #ffe8d1 !important;
  border: 2px solid #ff6f00 !important;
  border-bottom: none !important;
  justify-content: flex-start;
  gap: 10px;
  padding: 11px 16px;

  /* It is a <button> since 16 September so the whole bar folds the panel.
     A button brings its own font, alignment and centring, so these reset it
     back to the div it was — the look must not change, only the behaviour. */
  width: 100%;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* "Hide" / "Show" at the right-hand end. Pushed there rather than floated so
   it stays put when the heading wraps on a phone. */
.tl-header-onpage .tl-fold {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #8f3e00;
  /* 🛑 FULL OPACITY, MEASURED RATHER THAN EYEBALLED. Gee, 17 September, asked
     why the Checklist and Budget had no Hide. The panel was missing entirely
     (fixed separately) — but measuring this control on the way found the word
     itself sitting at 3.7:1 against the bar, under the 4.5 needed for text
     this small. At .72rem there is nowhere to go on weight (it is already
     800), so CONTRAST is the lever — the same finding as the Key details
     labels, where size, contrast and letter-spacing did what four weight
     bumps could not.

     ⚠️ AND THE TARGET WAS NEVER THE PROBLEM. The whole bar is the button —
     1,168 x 42px, measured — so "make it bigger" would have been work for a
     fault that does not exist. The word is a label, not the control. */
  opacity: 1;
}

/* Hover no longer changes the opacity — it is already 1. Kept as a hover cue
   on the colour instead, so the bar still answers the pointer. */
.tl-header-onpage:hover .tl-fold { color: #6d2f00; }

/* Folded, the bar is the whole panel, so it needs its own bottom edge back —
   .rsr-queue-onpage was carrying it. */
.tl-header-onpage[aria-expanded="false"] {
  border-bottom: 2px solid #ff6f00 !important;
  border-radius: 12px;
}

/* The dot is what lets the heading be dark text and still announce itself.
   Emitted by areaChecksHtml(); without it this reads as a caption, which is
   the failure mode of 11 September. */
.tl-header-onpage .tl-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ff6f00;
}

/* Deep orange on apricot, no shadow. The white-on-tangerine rule this replaces
   came from "make this font bold white because i cant read it properly" — that
   was about dark red on orange, and this is the opposite problem: there is no
   longer a strong fill to read against, so the text carries the colour. */
.tl-header-onpage h3 {
  color: #8f3e00 !important;
  font-weight: 800 !important;
  letter-spacing: .06em;
  text-shadow: none;
}

.rsr-queue-onpage {
  border: 2px solid #ff6f00;
  border-top: none;
  background: #fffaf5;

  /* ⚠️ THE BOTTOM CORNERS WERE SQUARE AND HAD ALWAYS BEEN. Measured on the
     live page while bolding the outline: the bar computes 14px 14px 0 0 and
     the body computed 0 all round, so the panel was a rounded bar sitting on
     a square tray rather than one box. At a 1px hairline nobody saw it; at
     2px it would have been the first thing you noticed. */
  border-radius: 0 0 var(--radius) var(--radius);
}

/* Warm hairlines rather than the orange-tinted ones. On a near-white field the
   old rgba(179,78,0,.22) reads as a second frame around every row. */
.rsr-queue-onpage .rsr-gsum,
.rsr-queue-onpage .rsr-card { border-color: #f3ddc7; }
.rsr-queue-onpage .rsr-gbody { border-left-color: #f3ddc7; }

/* ---------------------------------------------------------------------------
   THE DIVIDER ABOVE THE DEALT-WITH CARDS. Gee chose this, 18 September:
   "I'm happy to give them their own section."

   ⚠️ IT ONLY EXISTS WHEN THERE IS SOMETHING UNDER IT. Drawn from `done.length`
   in areaChecksHtml, so a page with nothing put down never grows a heading for
   an empty section — the empty-state fault from the morning, one layer along.

   ⚠️ TEAL, BECAUSE THE CARDS BELOW IT ARE TEAL. This is the same "done" colour
   the ticks and the card edges already use; a second neutral divider would
   read as a third kind of thing.
   -------------------------------------------------------------------------- */
.checks-done-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 14px 0 8px;
  padding: 7px 11px;
  border-radius: 8px;
  background: #eef4f3;
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  /* Measured, not picked: #00463c on #eef4f3 is 8.9:1. --teal-deep would be
     4.6:1 at this size, which passes but only just, and this is a heading that
     has to be skimmable rather than merely legible. */
  color: #00463c;
}

.checks-done-n {
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  font-size: .8rem;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   A CARD SHE HAS ALREADY DEALT WITH, SHOWING BECAUSE "Show them" IS ON.

   🛑 Gee, 18 September: "i pressed dismiss and it still stats." Her Budget page
   drew TEN cards under the heading "10 things to look at on this page" and
   every single one was already answered — 3 settled, 7 put down. They looked
   identical to live ones, so the page insisted she had ten jobs when she had
   none, and pressing the menu on one changed nothing she could see.

   The heading counts only what is owed now. This is the same fact on the row.

   ⚠️ THE APP ALREADY HAD A COLOUR FOR THIS, and using a grey would have been
   the mistake recorded in `the-app-already-has-a-colour-for-that`: --teal-deep
   is what "done" means everywhere else on these screens.

   ⚠️ NOT dimmed with opacity. She has to be able to READ a put-down card —
   that is the whole point of Show them — so only the edge and a word change.
   -------------------------------------------------------------------------- */
.rsr-queue-onpage .rsr-card.is-put {
  border-left: 3px solid var(--teal-deep);
  background: var(--teal-tint);
}

/* ⚠️ --ink-mint FOR THE WORDS, --teal-deep FOR THE EDGE, AND THE DIFFERENCE IS
   MEASURED. --teal-deep on --teal-tint is 4.48:1 — under the 4.5 this size
   needs, and I shipped exactly that fault on the Hide earlier the same day
   before measuring it. --ink-mint is 13.3:1 and is the token the palette
   already pairs with a tint (see --btn-mint / --ink-mint in styles.css).
   An edge has no contrast requirement; a word does. */
.rsr-queue-onpage .rsr-card.is-put .rsr-line::after {
  content: " · dealt with";
  color: var(--ink-mint);
  font-weight: 700;
  font-size: .82em;
  letter-spacing: .01em;
}

/* ⚠️ INK, NOT ORANGE — and this reverses a rule from 11 September on purpose.
   It used to be var(--warn) so a finding here read differently from Key
   details' red. That distinction still holds, and the pile heading, the dot
   and the bar all carry it now. Saying it a fourth time in the title was most
   of what made the panel a wall. */
.rsr-queue-onpage .rsr-card .rsr-line { color: var(--ink); }

/* The snooze control, inside a card rather than on a pale row. */
.rsr-queue-onpage .check-later {
  margin-top: 6px;
  display: flex;
  justify-content: flex-end;
}

/* 🛑 "NOT NOW" WAS INVISIBLE ON THIS PANEL FOR ITS WHOLE LIFE. DO NOT REMOVE
   THIS RULE.

   The reveal is `.check:hover .check-later > summary`, and it needs an ancestor
   carrying `.check`. In the findings panel the row is `a.rsr-card` — measured
   in the live DOM, `closest('.check')` is null — so the hover rule could never
   match and the summary sat at `opacity: 0` on every desktop, permanently. It
   was in the markup the whole time, 61x21px, and never once drew.

   Gee, 15 September, having been told twice that findings could be put down:
   "can I hide that so I can see that later, when I'm ready... I'm pretty sure
   you said somewhere that it was going to get hidden."

   ⚠️ AND IT IS DELIBERATELY NOT HOVER-GATED HERE. Everywhere else this control
   stays quiet until its row is hovered, so a panel of ten findings is not also
   a panel of ten buttons. That reasoning is sound and it stays where it
   applies. It does not apply to a control she has asked for by name and could
   not find: a hover-reveal she has to be told about is the same as no control.
   It sits bottom-right of the card in faint ink, which costs the panel nothing
   because that corner was already empty.

   ⚠️ UPDATE, 16 SEPTEMBER — THIS RULE IS NOW A NO-OP, AND IT IS KEPT ONLY FOR
   THE STORY ABOVE. The base rule no longer hides the summary at all: the
   hover-reveal was removed outright, because the same fault reached Gee a
   SECOND time. "Settled — don't ask again" was live on all 125 of her findings
   and she could not see a button, because 11px of --ink-faint behind a hover
   is not a button. The first fix here gave this panel the ancestor it needed
   and left the reveal in place everywhere else; the reveal was the fault.
   Safe to delete this line whenever the comment is no longer worth keeping. */
.rsr-queue-onpage .check-later > summary { opacity: 1; }

/* ---------------------------------------------------------------------------
   THE ONE-PRESS ACTION ON A FINDING. 15 September.

   A finding that can fix itself. Rare on purpose — it is only honest where
   there is exactly one right answer, and everything else belongs behind
   "Open it" where she can see the row before it changes.

   ⚠️ IT IS A REAL BUTTON INSIDE A ROW THAT IS A LINK, so `.check-doing` is in
   app.js's skip list beside `.check-later`. Without that the row navigates
   away before the press is handled — which is exactly what happened to "Not
   now" the first time anybody pressed it on the live site.

   Quiet, not a call to action: the row already says what is wrong, and a
   filled blue button repeating it was the loudest thing on the Overview once
   before (§39.1). Outline, ink, and it sits under the detail line.
   --------------------------------------------------------------------------- */
.check-doing {
  margin-top: 8px;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill, 999px);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .74rem;
  font-weight: 600;
  cursor: pointer;
}

.check-doing:hover { background: var(--line-soft); }
.check-doing[disabled] { opacity: .5; cursor: default; }

/* "+ Add to my checklist" sits BESIDE a finding's own button when it has one
   (19 Oct). And once pressed, "✓ On your checklist" — emerald, the app's
   colour for done, and the same pill shape so it reads as the button's other
   state. 🛑 IT NEEDS THIS RULE: a class with no rule is how the TBC tick drew
   four pixels wide for a day (CHECK 69). */
.check-doing + .check-doing,
.check-doing-done + .check-doing { margin-left: 6px; }
.check-doing-done {
  display: inline-block;
  margin-top: 8px;
  padding: 5px 11px;
  border: 1px solid var(--ok, #00733d);
  border-radius: var(--radius-pill, 999px);
  background: var(--ok-tint, #d6f7e2);
  color: var(--ok, #00733d);
  font-size: .74rem;
  font-weight: 700;
  cursor: pointer;
}

@media print {
  .tl-header-onpage,
  .rsr-queue-onpage { display: none !important; }
}


/* ===========================================================================
   THE CREW ROW, COMPACTED. 2 September.

   Gee: "in some of the supplier cards that are linked to the running sheet...
   we've got all of this space there for no reason when we can compact them."
   A photographer with three trips was three tall paragraphs of stacked
   full-width boxes — six rows of chrome to read four times.

   Same fields, no fewer controls, laid out as a grid so one crew is a band you
   scan rather than a page you read. Nothing is hidden and nothing is removed:
   she still edits every value in place.

   ⚠️ THIS BLOCK IS IN checks.css AND NOT bloom.css ON PURPOSE. checks.css is
   linked AFTER bloom.css, so .team-row here beats an identical selector there
   — which is exactly how the clock picker's styling went missing on 1 Sept.
   The rule lives with the rules it is overriding.
   =========================================================================== */

@media (min-width: 720px) {
  .team-row {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr) minmax(0, .9fr);
    align-items: start;
    column-gap: 10px;
    row-gap: 7px;
    padding: 11px 13px;
  }

  /* Name, place and direction across the top — the three things that say
     WHICH crew this is. */
  .team-row > .team-head  { grid-column: 1; }
  .team-row > .team-place { grid-column: 2; }
  .team-row > .team-dir   { grid-column: 3; }

  /* Times across the middle, on one line, because they are read together. */
  .team-row > .team-times {
    grid-column: 1 / -1;
    display: flex;
    gap: 9px;
    flex-wrap: nowrap;
    overflow-x: auto;
  }

  .team-row > .team-times label {
    display: flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
    font-size: .78rem;
    color: var(--ink-soft, #6c6067);
  }

  .team-row > .team-times input,
  .team-row > .team-times select { min-width: 0; width: auto; }

  /* Who to call, and who is on site, share the bottom line. */
  .team-row > .team-driver { grid-column: 1 / 3; display: flex; gap: 8px; }
  .team-row > .team-crew   { grid-column: 3; margin-top: 0; padding-top: 0; border-top: none; }
  .team-row > .team-crew .team-people { grid-column: 1 / -1; }
}

/* The people rows always span the full width — a name and a dietary
   requirement squeezed into a third of a card is unreadable. */
.team-row .team-people { grid-column: 1 / -1; }


/* ===========================================================================
   A TRIP IS A LINE. 3 September.

   Gee, on a chauffeur with four trips: "can we make these cards that have
   multiple locations better and more compact… I think we need to have a drop
   down for multiple locations or something."

   Measured before anything was drawn: 184px per trip, 738px for four, and the
   times row 1185px wide using 670 of it — 515px of empty space on every trip,
   four times over. The block was not badly styled so much as asked to hold six
   controls on a line with room for twelve.

   So the card is a LIST. Each trip is one line you can read — name, where, and
   its times as text — and only the one you click opens. 152px for four instead
   of 738, and the fifth and sixth trips cost a line each rather than a card
   each. The .team-* rules above still dress the inside of the open one, which
   is why they are all still here.

   ⚠️ STILL IN checks.css AND NOT bloom.css, for the reason given above: this
   file is linked later and wins. Class names checked against all six
   stylesheets before they were used — see css-class-name-collisions.
   =========================================================================== */

.trips {
  border: 1px solid var(--line, #ece5e8);
  border-radius: 10px;
  overflow: hidden;
}

.trip-row { position: relative; border-top: 1px solid var(--line-soft, #f5f0f2); }
.trip-row:first-child { border-top: 0; }

/* THE WHOLE LINE IS THE BUTTON. A caret you have to hit is a 12px target on a
   1200px row, and she is doing this on a phone at a venue. */
.trip-sum {
  display: grid;
  grid-template-columns: 16px minmax(0, 1.1fr) minmax(0, 1.6fr) auto auto;
  gap: 10px;
  align-items: center;
  width: 100%;
  padding: 9px 40px 9px 11px;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.trip-sum:hover { background: var(--surface-soft, #faf7f9); }
.trip-sum.is-open { background: var(--c-teal-tint, #d9f7f2); }

/* Was .7rem in --ink-faint, which rendered as a speck you could not see was a
   control. It is the only thing on the line saying "this opens". */
.trip-caret {
  font-size: .9rem;
  line-height: 1;
  color: var(--ink-soft, #6c6067);
  transition: transform .15s ease;
}
.trip-sum.is-open .trip-caret { color: var(--c-teal, #00695c); }
.trip-sum.is-open .trip-caret { transform: rotate(90deg); }

.trip-nm { font-weight: 600; }

.trip-pl,
.trip-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trip-pl { color: var(--ink-soft, #6c6067); }

/* The times are the thing she is scanning for, so they are the one coloured
   item on the line. Tabular so four trips line up as a column. */
.trip-when {
  color: var(--c-teal, #00695c);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.trip-count { color: var(--ink-faint, #93868d); font-size: .78rem; white-space: nowrap; }

/* Out of the grid, so a long place name never pushes it off the row. */
.trip-del {
  position: absolute;
  top: 6px;
  right: 8px;
  padding: 2px 7px;
  border: 0;
  background: none;
  color: var(--ink-faint, #93868d);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
}
.trip-del:hover { color: #b3001b; }

.trip-body {
  padding: 4px 12px 13px;
  background: var(--surface-soft, #faf7f9);
  border-top: 1px solid var(--line-soft, #f5f0f2);
}

/* The open trip keeps the compact grid the blocks already had — the work above
   was not wasted, it was just being asked to do it four times at once. */
@media (min-width: 720px) {
  .trip-body {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr) minmax(0, .9fr);
    align-items: start;
    column-gap: 10px;
    row-gap: 7px;
  }

  /* Placed by row as well as column. Left to DOM order the crew count landed
     under "who to call" and back out at the right-hand edge — the same flung-
     to-the-far-edge fault the whole card was redrawn to get rid of. The times
     and the headcount are read in one glance, so they share a line. */
  .trip-body > .team-head  { grid-column: 1; grid-row: 1; }
  .trip-body > .team-place { grid-column: 2; grid-row: 1; }
  .trip-body > .team-dir   { grid-column: 3; grid-row: 1; }

  .trip-body > .team-times {
    grid-column: 1 / 3;
    grid-row: 2;
    display: flex;
    gap: 9px;
    flex-wrap: wrap;
  }

  .trip-body > .team-times label {
    display: flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
    font-size: .78rem;
    color: var(--ink-soft, #6c6067);
  }

  .trip-body > .team-times input,
  .trip-body > .team-times select { min-width: 0; width: auto; }

  .trip-body > .team-crew {
    grid-column: 3;
    grid-row: 2;
    margin-top: 0;
    padding-top: 0;
    border-top: none;
  }

  .trip-body > .team-driver { grid-column: 1 / -1; grid-row: 3; display: flex; gap: 8px; }
  .trip-body > .team-driver input { flex: 1; min-width: 0; }
  .trip-body .team-people   { grid-column: 1 / -1; }
}

/* On a phone the summary drops the place — the name and the times are what
   tell two trips apart, and a wrapped address on every line is the wall this
   replaced arriving by another route. */
@media (max-width: 719px) {
  .trip-sum { grid-template-columns: 14px minmax(0, 1fr) auto; row-gap: 2px; }
  .trip-pl { display: none; }
  .trip-count { grid-column: 2; font-size: .74rem; }
}


/* ===========================================================================
   ONE ROW ON THE BOARD, AND THE LIST BEHIND IT. 3 September.

   Gee, on running six weddings at once: "we're running multiple weddings at the
   same time, so it's a check to make sure that all the information that's
   spinning through is correct." Then, weighing where to put it: "I'm wondering
   if we just have another separate tab that picks up all the issues for all of
   them separately too, or are we just complicating things then?"

   Neither. Mixing forty findings into the board would undo the morning spent
   making it less overwhelming, and a tab has to be remembered. So the board
   gains ONE row — and it is the only warm thing on a deliberately cool page,
   which is exactly why the couple palette was moved off red this morning.

   ⚠️ IN checks.css, NOT bloom.css. checks.css is linked later and wins. Class
   names were checked against all six stylesheets first — see
   css-class-name-collisions.
   =========================================================================== */

/* ⚠️ THE RED BAR IS DELETED. 11 September.

   .home-problems / .hp-n / .hp-t / .hp-go drew "148 problems across 7
   weddings" in crimson, full width, at the TOP of the landing page. Two
   things were wrong with it and both are colour-meaning faults this app keeps
   re-learning:

   · 148 is not a number you can act on in one press. The strip that replaces
     it leads with the 43 that will cost her on the day.
   · Red means somebody is waiting on you — an overdue payment, an overdue
     task, a change request. A finding is her own preparation, and orange is
     what a finding already wears on the tab counts, the Overview rows and the
     on-page panel (§38.10). It was the loudest thing on the page wearing the
     wrong colour.

   The replacement is .home-findings in bloom.css, at the FOOT of the page. The
   note above about checks.css winning the cascade no longer applies to it —
   nothing in this file styles that strip, so there is no war to win. */

/* ---- the list ---- */
.pl-group { margin: 0 0 18px; }

.pl-group > header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 6px;
  margin-bottom: 4px;
  border-bottom: 2px solid var(--ink);
}

.pl-couple { font-family: var(--display); font-size: 1rem; font-weight: 800; }
.pl-when   { font-size: .78rem; color: var(--ink-faint); }
.pl-count  {
  margin-left: auto;
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--surface-soft);
  font-size: .72rem;
  font-weight: 700;
  color: var(--ink-soft);
}

.pl-row {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  padding: 9px 11px;
  border-radius: 8px;
  color: inherit;
  text-decoration: none;
}

.pl-row:hover { background: var(--surface-soft); }

/* The area chip carries the severity. A colour AND a word, so colour is never
   the only signal — the same reason a departure on the run sheet is marked
   rather than merely tinted. */
.pl-area {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
}

.pl-row.is-high   .pl-area { background: var(--danger-tint, #fdeeec);  color: var(--danger, #b3001b); }
.pl-row.is-medium .pl-area { background: var(--c-coral-tint, #ffe3e4); color: var(--c-coral, #d4121f); }
.pl-row.is-low    .pl-area { background: var(--surface-soft);          color: var(--ink-soft); }

.pl-what { font-size: .9rem; font-weight: 600; min-width: 0; }
.pl-what small {
  display: block;
  margin-top: 2px;
  font-size: .8rem;
  font-weight: 400;
  color: var(--ink-soft);
}


/* ===========================================================================
   THE PASTE SCREEN. 3 September.

   Gee: "Is there a way that we can do import from Aisle Planner and stuff like
   that, so then that way it puts it into our projects… Same with the templates
   and stuff."

   Two tables, both deliberately plain. This screen's whole job is to let her
   check that column 3 really is the due date before anything is written, and
   anything decorative would be in the way of reading it.

   ⚠️ IN checks.css because it is linked later and wins. Names checked against
   all six stylesheets first — see css-class-name-collisions.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   Drop a file on the paste box.

   Gee, 10 Sept: "Why can't I just drag it in there?" — so the drop target IS
   the textarea she is already looking at, not a second zone beside it.

   ⚠️ SCOPED TO THE ID. `.is-over` already exists three times in these
   stylesheets — .upload-zone.is-over, .bg-cat.is-over, .bg-pct-state.is-over —
   and each is scoped to its own parent. An unscoped `.is-over` here would
   reach into all three. Same rule as css-class-name-collisions, and the same
   rule the specificity tie in the Imported panel taught the hard way.
   ------------------------------------------------------------------------- */

#paste-drop { position: relative; }

/* The hint sits over the box and is invisible until something is dragged in,
   so it costs no height and cannot push the modal around. */
#paste-drop-hint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--c-teal-tint, #e2f4f1);
  border: 2px dashed var(--c-teal, #0f766e);
  color: var(--c-teal, #0f766e);
  font-family: var(--display);
  font-weight: 700;
  font-size: .95rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
}

#paste-drop.is-over #paste-drop-hint { opacity: 1; }

/* Keeps the caret out of the way while a file is over the box. */
#paste-drop.is-over #paste-text { opacity: .25; }

#paste-file-note { margin: 6px 0 0; }
#paste-file-note.is-warn { color: var(--c-coral, #d4121f); font-weight: 600; }

.pm-grid { display: grid; gap: 1px; margin-top: 8px; background: var(--line); border: 1px solid var(--line); border-radius: 9px; overflow: hidden; }

.pm-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 200px) minmax(0, 1.3fr);
  gap: 10px;
  align-items: center;
  padding: 7px 11px;
  background: var(--surface);
}

/* Their heading and one of their values, so the pairing is checkable without
   scrolling back to the paste box. */
.pm-their { font-weight: 600; font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pm-eg    { color: var(--ink-faint); font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pm-row select { width: 100%; }

/* ---- what it will do ---- */
.pp { margin-top: 8px; border: 1px solid var(--line); border-radius: 9px; overflow: hidden; }

.pp-row {
  display: grid;
  grid-template-columns: minmax(0, 210px) minmax(0, 1fr);
  gap: 12px;
  padding: 8px 12px;
  border-top: 1px solid var(--line-soft);
  font-size: .88rem;
}
.pp-row:first-child { border-top: 0; }

.pp-a { font-weight: 600; }
.pp-b { color: var(--ink-soft); }

/* Skipped is quiet — it is information, not a problem. A warning is warm,
   because it is the one thing on this screen she has to make a decision about
   before pressing Import. */
.pp-row.is-skip { background: var(--surface-soft); }
.pp-row.is-skip .pp-a { color: var(--ink-faint); font-weight: 500; }

.pp-row.is-warn { background: var(--c-coral-tint, #ffe3e4); }
.pp-row.is-warn .pp-a { color: var(--c-coral, #d4121f); }
.pp-row.is-warn .pp-b { color: var(--ink); }

@media (max-width: 640px) {
  .pm-row, .pp-row { grid-template-columns: 1fr; gap: 4px; }
}


/* ===========================================================================
   "YOU FIXED IT." 9 September.

   Gee: "There are checks in place to make sure that the stuff on the timing
   running sheet is the same as what's on the supplier. If it isn't, for an
   error alert to show us, and then, once it's fixed, for that error alert to
   go and say, yes, you've corrected this now."

   The findings recompute from the data on every render, so a corrected one
   simply vanishes — and vanishing looks IDENTICAL to never having checked. It
   matters most when somebody else did the fixing: if a VA corrects six things
   she needs to see the six, not a clean screen.

   Green, and the ONLY green on this board. The couple palette is cool but
   never green-as-approval, and overdue red is the only warm thing — so this
   third colour says one thing and cannot be confused with either.

   ⚠️ In checks.css because it is linked later and wins. Names checked against
   all six stylesheets first — see css-class-name-collisions.
   =========================================================================== */

.home-fixed {
  display: flex;
  align-items: center;
  gap: 11px;
  max-width: 1080px;
  margin: 0 0 14px;
  padding: 10px 15px;
  border: 1.5px solid var(--c-sage, #00733d);
  border-radius: 11px;
  background: var(--c-sage-tint, #d6f7e2);
}

.hf-tick {
  font-size: 1.15rem;
  line-height: 1;
  font-weight: 700;
  color: var(--c-sage, #00733d);
}

.hf-t { font-size: .92rem; font-weight: 600; color: var(--ink); }

.hf-t small {
  display: block;
  margin-top: 1px;
  font-size: .8rem;
  font-weight: 500;
  color: var(--c-sage, #00733d);
}


/* The "matches no venue" warning under the supplier's place. Warm, because it
   is the one line in that card asking for a decision before she moves on —
   and it is a warning, not small print, which is why it carries an id and
   initFieldHints leaves it visible. 9 September. */
#s-location-warn {
  color: var(--c-coral, #d4121f);
  font-weight: 500;
}


/* ===========================================================================
   AN IMPORTED ROW SAYS SO, UNTIL SHE HAS READ IT. 9 September.

   Gee, part-way through the first real migration: "when it's an upload, I
   think we need to verify the details that are getting uploaded in case
   they're different or changed… a different colour, verify, so we know that
   we're all good."

   ⚠️ AMBER, NOT RED, AND SHE PICKED IT FROM THE MOCK-UP. Red on this platform
   already means overdue or broken — it is the loudest thing on the Coming up
   board and on a run sheet, and it was deliberately made the ONLY warm colour
   there on 3 September. An unchecked import is neither overdue nor broken.
   Amber is what this app already uses for "needs attention, nothing is on
   fire", which is exactly what this is.

   Nothing else about the row changes: same columns, same position, still fully
   editable. The left edge and a wash, and that is all.

   ⚠️ In checks.css because it is linked later and wins. Names checked against
   all six stylesheets first — see css-class-name-collisions.
   =========================================================================== */

tr.is-unchecked > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--c-coral, #d4121f);
}

tr.is-unchecked > td {
  background: var(--c-coral-tint, #ffe3e4);
}

/* The tone classes on a budget row already colour it — over budget, overdue.
   Those must still win, because "you are $4,000 over" outranks "nobody has
   read this yet". So the wash only applies where the row has no tone of its
   own, which is what :not() is doing here rather than raising specificity. */
tr.is-unchecked.is-over > td,
tr.is-unchecked.is-late > td,
tr.is-unchecked.is-danger > td {
  background: var(--danger-tint, #fdeeec);
}

/* Anything that is not a table row — a task, a run sheet line, a supplier
   card. Same two signals, applied to the block instead of the cells. */
.is-unchecked:not(tr) {
  border-left: 3px solid var(--c-coral, #d4121f);
  background: var(--c-coral-tint, #ffe3e4);
}

/* The count above a list. Reads as information, not as an alarm — it is a
   number of things to do, and it goes away by itself as she works. */
.unchecked-count {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 12px;
  padding: 9px 13px;
  border-radius: 9px;
  background: var(--c-coral-tint, #ffe3e4);
  color: var(--c-coral, #d4121f);
  font-size: .86rem;
  font-weight: 600;
}

.unchecked-count b {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.unchecked-count small { font-weight: 500; opacity: .85; }


/* ===========================================================================
   IMPORTED FROM AISLE PLANNER — the panel behind the "Imported" button.

   Gee, 9 September, before running the next migration: "I just want to know
   the lines that have come through from Aisle Planner, so I can tick them
   off… Where's the verification check, and where's the comparison?"

   ⚠️ Named imp-* rather than import-* deliberately. `.import` and `@import`
   are close enough in a stylesheet to be misread by a person, and the six
   sheets have already had one silent collision — .home-card existed twice and
   the later file won. Grepped across all six before naming: nothing else uses
   .imp-.

   ⚠️ AND THE TOKEN NAMES ARE styles.css's OWN. The first version of this block
   invented --surface-2, --rule and --rule-soft, none of which exist here — the
   real ones are --surface-soft, --line and --line-soft. Every one of them fell
   through to its hard-coded fallback, so the panel looked FINE and was not
   using the palette at all. Caught by reading the computed styles in the live
   app, which is the only way this is ever caught.
   ========================================================================== */

/* The count on the Imported button and on a tab. Never drawn at zero — a
   wedding she has finished checking must not carry a permanent mark. */
.imp-badge {
  display: inline-block;
  min-width: 17px;
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 999px;
  /* 🛑 BRIGHT RED, NOT THE CATEGORY BROWN. Gee, 17 September: "it shouldn't be
     brown, it should be a bright red as the colour."
     --c-coral is the LABELLING tangerine, a category hue meant for quiet
     tinted text. Used as a solid fill at 11px it read as brown, so a number
     that means "you have not checked this yet" looked like decoration.
     Red is the only thing on a tab that is asking for something. */
  background: #d4121f;
  color: #fff;
  font-size: .68rem;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  /* It opens the Imported panel at this tab's group — so it has to look like
     something you can press, not like a label sitting on one. */
  cursor: pointer;
}

.subnav-item .imp-badge:hover {
  background: #a60d17;
}

/* The group the red count sent you to. Borrows the deep link's own highlight
   rather than inventing a second one — one idea, one spelling. */
.imp-group.is-linked {
  border-radius: 8px;
  box-shadow: inset 3px 0 0 #ffb74d;
  animation: linked-settle-row 6s ease-out;
}

/* ---- one tab's worth of rows still to read ---- */
.imp-group { margin: 0 0 18px; }

.imp-group-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 7px;
}

.imp-group-head h4 {
  margin: 0;
  font-family: var(--display);
  font-size: .95rem;
}

/* Pushes the "Tick all" button to the right without a spacer element. */
.imp-group-head .btn { margin-left: auto; }

.imp-n {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-soft);
  font-size: .74rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.imp-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.imp-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 11px;
  border-radius: 8px;
  font-size: .88rem;
}

/* ⚠️ :not(.is-unchecked) IS LOAD-BEARING, and this is the second time this
   exact mistake has been made in these stylesheets.

   `.imp-list li` and `.is-unchecked:not(tr)` have the SAME specificity —
   :not() contributes its argument's weight, so `tr` makes it (0,1,1), the
   same as `.imp-list li`. A tie goes to whichever comes later in the file,
   and this block is appended at the end. So a plain `background` here silently
   beat the amber and every row in the tick list came out grey: the left-hand
   rule showed, the fill did not, and it looked like a deliberate design.

   Measured, not eyeballed — rgb(244,241,244) where rgb(255,238,218) was
   wanted. Excluding the class instead of raising specificity keeps ONE
   definition of what amber looks like, in the rule above. */
.imp-list li:not(.is-unchecked) { background: var(--surface-soft); }

/* The li already carries .is-unchecked, which paints it amber and puts the
   3px rule down its left edge. Only the radius has to be restated, because
   that rule is written for blocks that have none. */
.imp-list li.is-unchecked { border-radius: 0 8px 8px 0; }

/* Room for a long supplier name, and the count stays on the right. */
.imp-list li > span:first-of-type { flex: 1 1 auto; min-width: 0; }
.imp-list li .imp-n { flex: 0 0 auto; }

/* THE TICK. Deliberately a real button and deliberately large enough to hit
   on a phone at a venue — this is the control the whole feature is for.

   ⚠️ EMPTY AT REST. The first version showed the ✓ all the time, and the
   screenshot read as "already ticked" on every row — the exact opposite of
   what the row means. An empty box is a thing people know to click, and the
   ✓ arrives filled on hover as a preview of what clicking does. Spotted by
   looking at the rendered panel, after every measurement came back correct. */
.imp-tick {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1.5px solid var(--c-coral);
  border-radius: 7px;
  background: transparent;
  color: transparent;
  font-size: .9rem;
  line-height: 1;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}

.imp-tick:hover,
.imp-tick:focus-visible {
  background: var(--c-coral);
  color: #fff;
}

/* ---- one import, and what it did ---- */
.imp-batch {
  margin: 0 0 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.imp-batch-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 13px;
  background: var(--surface);
}

.imp-batch-head > div { min-width: 0; }
.imp-batch-head .btn  { margin-left: auto; flex: 0 0 auto; }

.imp-when {
  display: block;
  color: var(--ink-soft);
  font-size: .78rem;
}

.imp-tally {
  display: flex;
  gap: 10px;
  margin: 0;
  font-size: .8rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.imp-tally .ok   { color: var(--ok); font-weight: 600; }
.imp-tally .miss { color: var(--c-coral); font-weight: 600; }

/* ---- their text against ours ---- */
.imp-compare {
  padding: 11px 13px;
  border-top: 1px solid var(--line);
  background: var(--surface-soft);
}

/* Two columns on a screen with room, one above the other on a phone — a
   comparison squeezed into 180px columns is not a comparison. */
.imp-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}

.imp-cols h5 {
  margin: 0 0 5px;
  font-size: .68rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.imp-line {
  padding: 5px 0;
  border-top: 1px solid var(--line-soft);
  font-size: .82rem;
}

/* The pasted text, monospaced so a column that arrived EMPTY is visible as a
   gap rather than closing up silently — an empty cell between two tabs is one
   of the things this screen exists to be able to show. */
.imp-line code {
  font-family: ui-monospace, "Cascadia Mono", Menlo, monospace;
  font-size: .78rem;
  color: var(--ink-soft);
  word-break: break-word;
}

.imp-line em     { font-style: normal; color: var(--ok); font-weight: 700; }
.imp-line .miss  { color: var(--c-coral); }

/* The skipped rows, which are the ones she is actually looking for. Padded
   back out because .imp-compare's own padding would otherwise cut the tint
   off at the text edge. */
.imp-line.is-skipped {
  margin: 0 -13px;
  padding: 5px 13px;
  background: var(--c-coral-tint);
}

.imp-raw {
  margin: 0;
  padding: 9px 11px;
  border-radius: 8px;
  background: var(--surface);
  font-size: .78rem;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 260px;
  overflow: auto;
}

@media (max-width: 700px) {
  .imp-cols { grid-template-columns: 1fr; gap: 3px; }
  /* The heading pair becomes one label, so the second is dropped rather than
     stacked — "What is in here" above nothing reads as a missing column. */
  .imp-cols > h5:last-child { display: none; }
}


/* ===========================================================================
   ⚠️ AND NONE OF IT PRINTS.

   Found by checking before Gee hit it, while she was asking whether any of
   this changes what is already there. It does, in one place: print.css sets
   `print-color-adjust: exact` so backgrounds DO print, and checks.css has no
   media attribute — so an imported run sheet line would have printed with an
   amber wash and an orange bar down its left edge, on the document she hands
   to a venue or a photographer.

   "I have not read this yet" is a note to herself. It has no business on a
   supplier's copy, and a supplier seeing it would reasonably read it as
   something being wrong with their line.

   !important because print.css loads AFTER this file and styles .tl-row
   itself. Same convention as the four @media print blocks above.
   ========================================================================== */

@media print {
  .is-unchecked,
  tr.is-unchecked > td,
  .imp-list li.is-unchecked {
    background: transparent !important;
    border-left-color: transparent !important;
    box-shadow: none !important;
  }

  /* The counts on the Imported button and the tabs. The subnav is already
     hidden in print, but the button on the wedding header is not. */
  .imp-badge { display: none !important; }
}


/* ---------------------------------------------------------------------------
   The names the Notion board actually carries.

   Gee, 10 Sept: "Pull from Notion" on Solin & Rony said "nothing new on the
   board" while their meetings were on it. The board is filtered on an EXACT
   match against couple_names, and her naming varies — Fathom holds both
   "SOLIN & RONY FAMILY ZOOM" and "Rony & Solin". So when nothing matches, the
   names that DO exist are offered instead of a dead end.

   ⚠️ .pull-rows, not .pull-count — that one already exists in this file at
   line ~1563 for something else, and would have put a -4px top margin inside
   these buttons. Grepped all six sheets first, as the collision rule says.
   ------------------------------------------------------------------------- */

.pull-names {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

/* The row count beside a name — how much is on the board under it. */
.pull-rows {
  display: inline-block;
  margin-left: 5px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-soft);
  color: var(--ink-soft);
  font-size: .7rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}


/* ---------------------------------------------------------------------------
   The two new section buttons: tick the whole section, and delete it.

   Gee, 10 Sept: "sometimes clients come on board with me later on. Instead of
   having to go, it would be nice if I could just click, for instance, on
   onboarding in one go, where I know it's all done." And: "you can't delete a
   category."

   Both live in .sec-move, which @media print already hides — so neither
   reaches a printed checklist.
   ------------------------------------------------------------------------- */

/* A finished section: the tick reads as ON, so pressing it again clearly
   un-does rather than repeating something. */
.sec-btn.is-on {
  background: var(--ok-tint, #d6f7e2);
  border-color: var(--ok, #00733d);
  color: var(--ok, #00733d);
  font-weight: 700;
}

/* ⚠️ RED ONLY ON HOVER, not at rest. A permanent red × on every section
   heading turns the whole checklist into a row of alarm buttons — and the
   destructive one should be the one you notice as you reach it, not the one
   you see instead of the list. */
.sec-del:hover,
.sec-del:focus-visible {
  color: var(--danger, #b3001b);
  border-color: var(--danger, #b3001b);
}


/* ---------------------------------------------------------------------------
   The contacts card's categories, on two lines instead of seven.

   Gee, 10 Sept: "I don't love the way that the categories look on contacts…
   It looks pretty shit. I'd much rather it go on the same lines or two lines
   instead of the individual lines."

   ⚠️ THE CHIPS WERE NEVER THE PROBLEM. .cat-chip has been inline-block since
   bloom.css was written — but `.card` is `display:flex; flex-direction:column`,
   so every DIRECT child becomes a full-width row and inline-block never gets a
   say. Abra Events' seven categories were seven stacked bars, ~190px, pushing
   her phone number under the fold.

   This wrapper is one flex ITEM that flows inside itself. Nothing about the
   chips changed. The table view was always fine, because a <td> is not a flex
   container — which is why it only ever looked wrong on Cards.

   ⚠️ In checks.css because it loads after styles.css and bloom.css and
   therefore wins. Both names grepped across all six sheets first.
   ------------------------------------------------------------------------- */

.card-cats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 0 2px;
}

/* No phone, no email, no website — the three ways to actually reach somebody.
   Shown only when ALL THREE are missing: a supplier she only ever DMs is not
   incomplete, and a warning on half of 328 contacts is a warning nobody reads. */
.card-gap {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 9px 0 0;
  padding: 6px 10px;
  border-left: 3px solid var(--c-coral, #d4121f);
  border-radius: 0 7px 7px 0;
  background: var(--c-coral-tint, #ffe3e4);
  color: var(--c-coral, #d4121f);
  font-size: .78rem;
  font-weight: 600;
}

/* A printed contact sheet is for reading, not for fixing. */
@media print { .card-gap { display: none; } }


/* ---------------------------------------------------------------------------
   Feature tick-boxes for things that are not built.

   Kadija asked on 8 Sept what the plan was for Calendar and Guests & seating;
   it was never answered. Checked on 10 Sept: neither tab exists anywhere, so
   both boxes did nothing — silently. Gee's answer was "a little bit later",
   so they stay visible and say what they are.
   ------------------------------------------------------------------------- */

.check-inline.is-later {
  opacity: .55;
  cursor: default;
}

.later-tag {
  margin-left: 5px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-soft);
  color: var(--ink-faint);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
}


/* ===========================================================================
   WHAT A CONTRACT SAID — the panel under a file. 12 September 2026.

   Gee, onboarding a couple while we talked: "when we upload a contract, are you
   able to extract the most important information from that contract?… I want to
   upload all their contracts and stuff, like their terms and conditions."

   ⚠️ IT MUST NOT LOOK LIKE THE APP'S OWN DATA. Everything in here was written
   by a model reading a PDF, and the moment it is drawn in the same white rows
   as a supplier's real arrival time, somebody will act on it as if a person had
   typed it. So: its own ground, its own edge, and the clauses are QUOTED —
   indented, in the document's voice, not the app's.

   The same reasoning as the comparison panel in bloom.css, which had to stop
   looking like the budget for exactly this reason.
   =========================================================================== */

.file-read { list-style: none; }

.fr-panel {
  margin: 2px 0 12px;
  padding: 14px 16px;
  background: var(--surface-warm);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.fr-wait { margin: 8px 0 12px; font-size: .88rem; color: var(--ink-soft); font-style: italic; }
.fr-wait.is-bad { color: var(--late); font-style: normal; font-weight: 600; }

.fr-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 9px; }

.fr-kind {
  font-size: .64rem;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--c-sky);
  background: var(--c-sky-tint);
  padding: 3px 10px;
  border-radius: var(--radius-pill);
}

/* Unsigned is the one that changes what she does today, so it wears the colour
   of something waiting on her rather than the colour of a finding. */
.fr-sign { font-size: .78rem; font-weight: 800; padding: 3px 10px; border-radius: var(--radius-pill); }
.fr-sign.is-signed   { color: var(--ok);   background: var(--ok-tint); }
.fr-sign.is-unsigned { color: var(--late); background: var(--late-tint); }
.fr-sign.is-unclear  { color: var(--warn); background: var(--warn-tint); }

.fr-summary { margin: 0 0 12px; font-size: .93rem; color: var(--ink); max-width: 70ch; }

.fr-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px 14px;
  margin: 0 0 14px;
  padding: 11px 13px;
  background: var(--surface);
  border-radius: var(--radius-sm);
}

.fr-facts dt {
  font-size: .63rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.fr-facts dd { margin: 1px 0 0; font-size: .9rem; font-weight: 700; }

/* A clause is QUOTED. The indent and the rule are the whole point — they say
   "these are their words, not ours" without a sentence explaining it. */
.fr-clause { margin: 0 0 10px; }
.fr-clause b {
  display: block;
  font-size: .8rem;
  color: var(--ink);
  margin-bottom: 3px;
}

.fr-clause blockquote {
  margin: 0;
  padding: 8px 12px;
  border-left: 3px solid var(--c-sky);
  background: var(--surface);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: .88rem;
  color: var(--ink-soft);
}

/* A silence is a finding of its own. A contract with nothing about cancellation
   is worth knowing about, and printing nothing would hide it. */
.fr-clause.is-silent span { font-size: .85rem; color: var(--ink-faint); font-style: italic; }

.fr-list { margin: 0 0 10px; }
.fr-list b { display: block; font-size: .8rem; margin-bottom: 3px; }
.fr-list ul { margin: 0; padding-left: 19px; }
.fr-list li, .fr-list p { font-size: .87rem; color: var(--ink-soft); margin: 0 0 2px; }

/* What you are NOT getting, and what you are not allowed to do, are the two
   lists that cost money. They wear the colour a finding wears. */
.fr-list.is-warn b { color: var(--warn); }
.fr-list.is-quiet b { color: var(--ink-faint); }

/* A CONVERSATION'S list item is not one string. 14 September: a filed email
   thread and a filed conversation screenshot both reach this panel now, and a
   thread's promise is an object — what was promised, what it is worth, their
   exact words, and who said them. The quote is the evidence and it reads as
   theirs, not as the app's claim, which is the same treatment the inbox card
   gives it. */
.fr-list .fr-what  { font-weight: 600; color: var(--ink); }
.fr-list .fr-worth { font-weight: 700; font-variant-numeric: tabular-nums; margin-left: 6px; }
.fr-list .fr-who   { display: block; font-size: .8rem; color: var(--ink-faint); }
.fr-list blockquote {
  margin: 2px 0 4px;
  padding-left: 10px;
  border-left: 2px solid var(--line);
  font-size: .85rem;
  color: var(--ink-soft);
}

/* What was actually said, folded away — it is the longest thing in the panel
   and the findings above it are the part she acts on.
   ⚠️ NO display:flex ON THE SUMMARY; it deletes the disclosure triangle. */
/* WHAT THE DOCUMENT COULD FILL IN. 15 September.

   The reader has pulled arrival times, hours and money out of contracts for
   weeks and none of it reached a field — Gee retyped all of it. This is the
   offer, and it is deliberately the last thing in the panel: read what the
   document SAYS first, then decide what to take from it. */
.fr-apply {
  margin: 12px 0 0;
  padding: 12px 14px;
  border-top: 1px solid var(--line);
  background: var(--surface-soft);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}
.fr-apply > b { display: block; font-size: .82rem; margin-bottom: 6px; }
.fr-apply ul { margin: 0 0 10px; padding: 0; list-style: none; }
.fr-apply li { font-size: .87rem; padding: 3px 0; }
.fr-apply label { cursor: pointer; display: flex; gap: 8px; align-items: baseline; }
.fr-apply input { margin: 0; }

/* WHAT THEY NEED, KEPT OFF THE CONTRACT. Migration 111, surfaced 15 September.

   Teal and dashed, because that is already this app's signal for "the reader
   found this and nothing is saved yet" — the rate card has used it for prices
   since it was built, and supplierneeds.js reuses it verbatim on the contact
   card. Inventing a second signal here would make one idea look like two
   features.

   It sits ABOVE .fr-apply on purpose: that box changes this one booking, this
   one changes the supplier for every wedding, and the wider fact reads first. */
.fr-needs {
  border-top: 0;
  border: 1px dashed var(--teal-deep);
  background: var(--teal-tint);
  border-radius: var(--radius-sm);
}
.fr-needs > b { color: var(--teal-deep); }
.fr-needs li { padding: 5px 0; border-top: 1px solid rgba(0, 124, 133, .18); }
.fr-needs li:first-child { border-top: 0; }
.fr-need-what { line-height: 1.4; }

/* The hour and the basis, side by side under the wording. Wraps rather than
   squeezing, because a requirement is a whole sentence and the boxes must not
   fight it for the line. */
.fr-need-when {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0 24px;
  font-size: .8rem;
  color: var(--ink-soft);
}
.fr-need-hrs {
  width: 62px;
  padding: 3px 6px;
  font: inherit;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
}
/* ⚠️ `width: auto` IS THE WHOLE POINT OF THIS RULE, NOT A TIDY-UP.
   styles.css sets `width: 100%` on a bare `select` inside a grouped selector.
   This class beats it on specificity for the properties it DECLARES — and
   width was not one of them, so the dropdown ran the full 1,187px of the
   modal and pushed the hours box onto its own line. Found by asking the
   browser which rule won, which is the standing instruction for exactly this,
   and not by re-reading this file: every line here was already correct. */
.fr-need-basis {
  width: auto;
  max-width: 100%;
  padding: 3px 6px;
  font: inherit;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
}

/* WHAT PAPERWORK THIS SUPPLIER HAS. 15 September, on the supplier card.

   Gee: "contract received, invoice received, deposit paid... I think we also
   need it in the supplier card."

   ⚠️ DERIVED, NOT TICKED — each chip reads whether the thing EXISTS, so it
   cannot drift out of step with the files the way four checkboxes would. Green
   when it is there with what it found; grey and hollow when it is not, which
   is the state she is reading the row FOR. */
.pw-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 10px;
}
.pw-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: .78rem;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--line-hard, #d8ccd2);
  background: var(--surface, #fff);
  color: var(--muted, #6c6067);
}
.pw-chip small { font-weight: 400; opacity: .75; }
.pw-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--line-hard, #d8ccd2);
  flex: none;
}
.pw-chip.is-got {
  border-color: #00733d;
  background: #d6f7e2;
  color: #00733d;
}
.pw-chip.is-got .pw-dot { background: #00733d; }

/* PUT THIS WHERE IT BELONGS. 15 September.

   The money and contact offer, on any reading — a contract, a quote, a
   forwarded thread or a WhatsApp screenshot. Pink rather than the teal above
   because it is the one block here that writes to the BUDGET, and the budget is
   the thing she checks money against. The teal boxes change a supplier; this
   changes what a wedding costs. */
.fr-money {
  border: 1px solid var(--pink);
  border-top: 1px solid var(--pink);
  background: var(--pink-tint, #fdeef5);
  border-radius: var(--radius-sm);
}
.fr-money > b { color: var(--pink); }
.fr-money li { padding: 4px 0; }
.fr-money .fr-foot { margin: 6px 0 0; }

/* A disagreement is never offered, only shown. A contract carries what was
   true the day it was signed; her card carries what she has confirmed since.
   Same rule budgetfiles.js has used for bank details since 30 August. */
.fr-clash {
  margin-top: 10px;
  padding: 9px 12px;
  border-left: 3px solid var(--warn);
  background: var(--warn-tint);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.fr-clash > b { display: block; font-size: .8rem; color: var(--warn); margin-bottom: 3px; }
.fr-clash ul { margin: 0; padding-left: 17px; list-style: disc; }
.fr-clash li { font-size: .85rem; color: var(--ink-soft); }

.fr-transcript { margin: 10px 0 0; }
.fr-transcript > summary {
  cursor: pointer; font-size: .82rem; font-weight: 600; color: var(--teal-deep);
}
.fr-transcript > pre {
  margin: 8px 0 0;
  padding: 10px 12px;
  background: var(--surface-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--sans);
  font-size: .84rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 320px;
  overflow-y: auto;
}

.fr-foot {
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: .8rem;
  color: var(--ink-faint);
}

.fr-foot b { color: var(--warn); }

/* When it was read, beside the file's size and date. A read from before the
   supplier sent a revised contract is worse than no read.

   ⚠️ IT IS A <button> NOW, NOT A <span> — 13 September, when it became the way
   back into what the reader found. So every browser default a button carries
   has to be unset here: border, background, padding, and above all
   `font-family`, which does NOT inherit on form controls and would otherwise
   drop this one word out of Figtree and into the system UI face, beside text
   it is supposed to sit level with. */
.fread {
  color: var(--c-sky);
  font-weight: 700;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
}
.fread:hover { color: var(--pink-deep); }
.fread:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; border-radius: 3px; }


/* ===========================================================================
   FINDINGS IN PILES — option 3, chosen 12 September 2026.

   Gee: "I just want the things to look grouped all as one, if it's budget,
   whatever it is, but clean. Same view, but a cleaner view that I know: hey,
   okay, I've got five invoice issues to sort out."

   ⚠️ WHY CLOSED, WHEN SHE HAS TWICE SAID FINDINGS MUST NOT BE HIDDEN.
   Measured on her run sheet the morning this was written: eight findings as
   open white cards made this panel 902px, which put the Key details panel at
   1,350px and the run sheet itself at 2,694px. She went looking for a finding
   where it used to be on screen and it was gone. Twenty-six on the Budget tab
   would have been ~2,900px.

   So the COUNT is never hidden and a pile holding anything urgent opens
   itself. What closes is ten missing bank details — an afternoon's tidying,
   not something to read on the way past.
   =========================================================================== */

.rsr-group { margin-bottom: 8px; }
.rsr-group:last-child { margin-bottom: 0; }

.rsr-gsum {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 13px;
  background: var(--surface);
  border: 1px solid rgba(179, 78, 0, .22);
  border-radius: 10px;
  cursor: pointer;
  list-style: none;          /* Safari draws its own triangle without this */
  user-select: none;
}

.rsr-gsum::-webkit-details-marker { display: none; }
.rsr-gsum:hover { border-color: #ff6f00; background: #fffaf4; }

/* The count IS the sentence. "Ten bank details" is the thing she reads, so it
   is the first thing on the line and the only thing wearing a fill.

   ⚠️ INK, NOT ORANGE. Gee chose this out of five options drawn as HTML on
   12 September: "I prefer ink."

   Her complaint was "the numbers in the circle are too orange", and it was
   measurable rather than a matter of taste — this panel had FOUR oranges
   stacked on top of each other. The header bar is #ff6f00, the queue behind it
   is #ffe3e4, every card title is #d4121f, and the circle was #d4121f too. The
   loudest element on the line was wearing the same colour as everything around
   it, so it had nothing to stand against.

   A count is a quantity, not an alarm. Ink says so — and it is what gives the
   crimson below something to mean, because red on this circle is now the only
   red on the line rather than the fourth warm thing on it. */
.rsr-gn {
  flex: 0 0 auto;
  min-width: 26px;
  text-align: center;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: #fff;
  font-family: var(--display);
  font-size: .82rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* A pile of one. Grey rather than ink, because "1" is not a quantity worth
   ranking against "21" — it is there to file the finding, not to shout a
   number. 12 September, with option B.

   ⚠️ IT MUST STILL GO RED WHEN IT IS URGENT, which is why this rule sits
   ABOVE the urgent one and carries no extra weight. `.rsr-gn.is-one` is
   (0,2,0) and `.rsr-group.is-urgent .rsr-gn` is (0,2,1), so urgent wins on
   its own. Do not raise this selector.

   The option B mock-up drew those two urgent 1s grey — that was a specificity
   slip in the mock-up, not the design. Red is right: a pile does not stop
   being urgent because it happens to hold one thing. */
.rsr-gn.is-one { background: var(--muted); }

/* Somebody is waiting. Unchanged — it is the whole reason ink is right above. */
.rsr-group.is-urgent .rsr-gn { background: var(--late); }

.rsr-gt { flex: 1 1 auto; font-size: .9rem; font-weight: 700; color: var(--ink); }

/* The chevron is drawn rather than typed, so it cannot land as a stray glyph
   in a font that has no arrow. It turns when the pile opens. */
.rsr-gsum::after {
  content: "";
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-right: 2px solid var(--warn);
  border-bottom: 2px solid var(--warn);
  transform: rotate(-45deg);
  transition: transform .12s ease;
  margin-right: 3px;
}

.rsr-group[open] > .rsr-gsum::after { transform: rotate(45deg); margin-right: 0; }
.rsr-group[open] > .rsr-gsum { border-color: #ff6f00; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }

/* Indented, so an open pile reads as belonging to its heading rather than as
   the list starting again. */
.rsr-gbody {
  padding: 8px 0 2px 13px;
  border-left: 2px solid rgba(179, 78, 0, .22);
  margin-left: 12px;
}

.rsr-gbody .rsr-card { margin-bottom: 7px; }

/* ONE SUPPLIER'S FINDINGS, TOGETHER — the second level inside a pile.
   15 September.

   Gee, on "31 · Asked and never answered" holding six Ritz-Carlton rows: "The
   Ritz should then be its own subcategory, and then it drops down, because
   it's silly that there are four Ritz and I can't distinguish that."

   ⚠️ DELIBERATELY QUIETER THAN THE PILE ABOVE IT. The pile's summary is a
   bordered card with a solid dark count; this is a plain row with a hollow
   count. Giving it the same weight would make the panel read as two competing
   levels of heading rather than one inside the other — the mistake that got a
   findings panel rejected on 11 September for having "a shape of its own". */
.rsr-sub { margin: 0 0 10px; }

/* ⚠️ COLOURED AND FULL-SIZED, and the quiet version this replaces was wrong.
   Gee: "I don't like the way that it's not colourful and that it's so small…
   I'm not loving that they're not different colours, and I think that the
   headings need to be a bit larger."

   The hue comes from `.cat-1` … `.cat-6`, hashed off the supplier's name by
   categoryTone — the same six the budget and the portal use, so the Ritz is
   the same colour wherever she meets it and stays that colour between page
   loads. `--cat` and `--cat-tint` are set by those classes; the fallbacks are
   only there for a name that hashes to nothing. */
.rsr-ssum {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  cursor: pointer;
  list-style: none;
  user-select: none;
  border-radius: 9px;
  background: var(--cat-tint, var(--line-soft));
  border-left: 4px solid var(--cat, var(--muted));
}
.rsr-ssum::-webkit-details-marker { display: none; }
.rsr-ssum:hover { filter: brightness(.97); }

.rsr-sn {
  flex: 0 0 auto;
  min-width: 26px;
  text-align: center;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--cat, var(--muted));
  color: #fff;
  font-size: .82rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.rsr-st {
  font-size: .95rem;
  font-weight: 700;
  color: var(--cat, var(--ink));
}

/* No second border rail. The pile already draws one, and nesting a second
   inside it makes the cards look twice-indented for no extra meaning. */
.rsr-sbody { padding: 4px 0 2px 12px; }
.rsr-sbody .rsr-card { margin-bottom: 6px; }
.rsr-gbody .rsr-card:last-child { margin-bottom: 0; }


/* ===========================================================================
   A TINTED BAND PER PILE. 12 September — option 3 of four drawn as HTML.

   Gee: "Can we do something for each of the problems that we've got in the
   category? Owing no bank details · Still an estimate · Owing no due date.
   Maybe those can be different colours so it really stands out more."
   Then, shown four: "Yeah, I like the tinted bands per pile. That looks nice."

   ⚠️ SIX COLOURS, NOT ONE PER CATEGORY, AND THAT IS THE POINT.

   A hue per category was drawn as option 4 so she could see it — thirteen
   colours across the app, nothing ever repeating, and therefore nothing to
   learn. These six are keyed on the KIND of problem instead (FAMILY_OF in
   checks.js), so mulberry means "the number isn't real yet" on the budget and
   on the run sheet alike. Her three examples still come out three different
   colours, which is what she asked for.

     missing  deep rose   you cannot act without it
     soft     mulberry    the number isn't real yet
     when     violet      a date or a time
     paper    slate       paperwork or tagging
     gap      teal        here but not there
     clash    cobalt      two numbers disagree

   ⚠️ THESE RULES SIT AFTER .rsr-group.is-urgent ON PURPOSE. They weigh the
   same (0,2,1), so the later file position is what makes the family colour
   win on an urgent pile. That is deliberate and it is what she chose: the
   circle wears the PROBLEM, and urgency still shows twice over — the pile
   opens itself, and the card inside keeps its red URGENT tag.

   ⚠️ AND THEY MUST ALSO BEAT .rsr-gn.is-one (0,2,0) — they do, on weight.
   A pile of one is still coloured by its family.
   ========================================================================== */
.rsr-group.fam-missing { --fam: #9b2242; --fam-tint: #fdeef1; --fam-edge: #f2ccd5; }

/* ⚠️ MULBERRY, AND IT USED TO BE AMBER #a86a00. DO NOT PUT THE AMBER BACK.
   Gee, 12 September: "I don't like the still-an-estimate colour. Change that
   colour, and wherever I've got that colour, change to something else." Then,
   shown five muted replacements: "I don't want those ugly colours. Give me a
   nicer, brighter colour… I'm happy with a mulberry if we haven't already
   used mulberry."

   The amber failed for a reason worth keeping: it was the ONLY family sharing
   a hue with the panel around it — an apricot bar, a #ff6f00 dot, a #8f3e00
   heading — so it read as more of the furniture rather than as a category.
   Any replacement has to be outside the orange family.

   Mulberry was free, measured rather than assumed: every hex in the six
   stylesheets was converted to HSL and the 290–350° band listed. It holds the
   brand pinks (#e8197a and friends, hue 331 but far brighter and more
   saturated), the orchid couple hue --cu-5 #93359e at 293 (home page only,
   never this panel), and this family's own rose at 344. #a82b80 sits at 319
   with nothing else near it.

   ⚠️ IT IS 25° FROM fam-missing's ROSE ABOVE, and on the run sheet both
   families appear twice in the same panel. They read as wine and magenta
   rather than as two reds, but that is the thing to look at first if this
   ever needs adjusting — move this one further toward 310, not the rose. */
.rsr-group.fam-soft    { --fam: #a82b80; --fam-tint: #fbebf6; --fam-edge: #edc6e2; }
.rsr-group.fam-when    { --fam: #7a4bab; --fam-tint: #f4eefb; --fam-edge: #ddcdf0; }
.rsr-group.fam-paper   { --fam: #4a5a72; --fam-tint: #eef1f6; --fam-edge: #ccd5e2; }
.rsr-group.fam-gap     { --fam: #0f6b70; --fam-tint: #e6f4f5; --fam-edge: #b9dee0; }
.rsr-group.fam-clash   { --fam: #1f5fa9; --fam-tint: #eaf1fa; --fam-edge: #c3d8ef; }
/* "One supplier, several things" — Budget panel, 30 September. Not a problem
   family: it gathers one supplier's mixed problems at the top. TANGERINE, the
   app's own --c-peach / --c-peach-tint, the one bright hue none of the six
   families above uses.
   GREEN — the app's own --c-sage / --c-sage-tint, the one hue none of the six
   families uses. Chosen by Gee 30 September from green and red drawn on
   Tiffany's live panel.
   ⚠️ THIRD COLOUR IN ONE MORNING, AND EACH FAILED THE SAME WAY — IT MATCHED
   SOMETHING BESIDE IT. Brand pink read as mulberry "Only applies if";
   tangerine vanished into the panel's own peach wash and orange border. Red
   was drawn and turned down: it is the rose of fam-missing, "No number to
   ring them on", which sits on the Suppliers panel. Before recolouring, draw
   it on the live panel beside every family that panel can show.
   🛑 SHE DOES NOT WANT DARK OR NEUTRAL COLOURS — no charcoal, grey, stone,
   slate or navy — for anything she has to read. */
.rsr-group.fam-several { --fam: #00733d; --fam-tint: #d6f7e2; --fam-edge: #8fe0b0; }

/* The band. A 4px rail carries the colour at full strength; the fill stays a
   wash, because six saturated blocks down a panel is the wall this whole
   redesign was undoing. The padding-left compensates for the rail so the
   circles still line up down the page. */
.rsr-group[class*="fam-"] > .rsr-gsum {
  background: var(--fam-tint);
  border-color: var(--fam-edge);
  border-left: 4px solid var(--fam);
  padding-left: 11px;
}

/* Hover deepens the edge rather than washing the tint out. The base rule sends
   it to #fffaf4, which would make a pile turn white under the cursor. */
.rsr-group[class*="fam-"] > .rsr-gsum:hover { background: var(--fam-tint); border-color: var(--fam); }

/* Open: the rail and the edge stay the pile's own colour instead of jumping to
   orange, which is what the base rule does. */
.rsr-group[class*="fam-"][open] > .rsr-gsum { border-color: var(--fam); }

.rsr-group[class*="fam-"] .rsr-gn { background: var(--fam); }
.rsr-group[class*="fam-"] .rsr-gt { color: var(--fam); }

/* The chevron follows the band. Left in --warn it reads as a stray orange mark
   on a violet or teal row — the one detail too small to judge in the mock-up. */
.rsr-group[class*="fam-"] > .rsr-gsum::after {
  border-right-color: var(--fam);
  border-bottom-color: var(--fam);
}

/* And the line down the left of an open pile, so the cards read as belonging
   to the band above them. */
.rsr-group[class*="fam-"] > .rsr-gbody { border-left-color: var(--fam-edge); }


/* ===========================================================================
   THE VIP QUESTIONNAIRE IMPORT — six groups, and a tick on every row.

   ⚠️ NOT THE .pp PREVIEW ABOVE, AND DELIBERATELY NOT. Every other import shows
   a summary you read and accept whole: "29 lines, $83,357 estimated". This one
   proposes changes to rows that already exist — parking a budget line, filling
   a field she may have typed herself — so each one has to be refusable on its
   own. A summary would make "Apply" a single yes to forty different decisions.

   ⚠️ COLOURS ARE THE FINDINGS PANEL'S FAMILIES (§39.1), NOT NEW ONES. Sky for
   what arrives, stone for what is parked, tangerine for the group she must
   read, butter for what she has to chase, mint for kept text. One hue per
   group, and none of them invented here.
   =========================================================================== */

.qp-group {
  border: 1px solid var(--line);
  border-radius: 11px;
  border-left: 3px solid var(--g);
  overflow: hidden;
  margin-top: 12px;
}
.qp-group:first-child { margin-top: 0; }

.qp-group.fills { --g: var(--c-sky);    --g-tint: var(--c-sky-tint);    }
.qp-group.aside { --g: var(--c-stone);  --g-tint: var(--c-stone-tint);  }
.qp-group.wants { --g: var(--c-coral);  --g-tint: var(--c-coral-tint);  }
.qp-group.asks  { --g: var(--c-butter); --g-tint: var(--c-butter-tint); }
.qp-group.notes { --g: var(--c-teal);   --g-tint: var(--c-teal-tint);   }

.qp-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: baseline;
  padding: 11px 14px;
  background: var(--g-tint);
}

.qp-open {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  align-items: baseline;
  text-align: left;
  border: 0;
  background: none;
  padding: 0;
  font-family: inherit;
  color: inherit;
  cursor: pointer;
}
.qp-open .count {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--g);
  font-variant-numeric: tabular-nums;
}
.qp-open .name { font-weight: 700; font-size: .95rem; color: var(--ink); }
.qp-open .say  { display: block; font-weight: 400; font-size: .82rem;
                 color: var(--ink-soft); margin-top: 1px; }

.qp-head .all {
  font-size: .8rem;
  font-weight: 600;
  color: var(--g);
  white-space: nowrap;
  border: 1px solid var(--g);
  border-radius: 7px;
  padding: 3px 9px;
  background: none;
  font-family: inherit;
  cursor: pointer;
}
.qp-head .all:hover { background: var(--surface); }

.qp-rows { display: flex; flex-direction: column; }

.qp-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  padding: 9px 14px;
  border-top: 1px solid var(--line-soft);
  font-size: .88rem;
}
.qp-row:hover { background: var(--surface-soft); }
/* "Needs you" has nothing to tick, so its rows keep the same left edge as
   every other group rather than sliding 28px left and looking like a different
   kind of thing. */
.qp-row.is-flat { grid-template-columns: 17px minmax(0, 1fr); }
.qp-row.is-flat:hover { background: none; }

.qp-row .what { font-weight: 600; }
.qp-row .val  { font-weight: 400; font-variant-numeric: tabular-nums; }
.qp-row .why  { display: block; color: var(--ink-soft); font-size: .83rem; margin-top: 1px; }

/* ⚠️ THE TICK IS DRAWN, NOT A NATIVE CHECKBOX. `accent-color` and
   `border-radius` do NOTHING to a native box's shape — measured back as
   `radius: 0px` on 13 September, which is no change at all. This is the same
   fix the checklist's two ticks needed. */
.qp-tick {
  appearance: none;
  -webkit-appearance: none;
  margin: 2px 0 0;
  width: 17px;
  height: 17px;
  flex: none;
  border: 1.5px solid var(--ink-faint);
  border-radius: 5px;
  background: var(--surface);
  cursor: pointer;
  display: grid;
  place-items: center;
}
.qp-tick:checked { background: var(--g, var(--pink)); border-color: var(--g, var(--pink)); }
.qp-tick:checked::after {
  content: "";
  width: 9px;
  height: 5px;
  margin-top: -2px;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(-45deg);
}
.qp-tick:focus-visible,
.qp-open:focus-visible,
.qp-head .all:focus-visible { outline: 2px solid var(--pink); outline-offset: 2px; }

.qp-row .chip,
.qp-note .chip {
  display: inline-block;
  font-size: .71rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 999px;
  letter-spacing: .02em;
  vertical-align: 1px;
  margin-left: 7px;
}
.chip.where   { background: var(--surface-soft); color: var(--ink-soft); border: 1px solid var(--line); }
.chip.differs { background: var(--c-coral-tint);  color: var(--c-coral); }
.chip.private { background: var(--c-stone-tint);  color: var(--c-stone); }
/* A row she took out of the drawer herself. Mint, the same green that marks a
   questionnaire-parked line on the run sheet, because it is the same fact seen
   from the other side. */
.chip.back    { background: var(--c-teal-tint);   color: var(--c-teal); }

/* A note is a block of her couple's own words, so it gets room rather than
   being squeezed onto one line and clipped. */
.qp-note {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 11px;
  padding: 10px 14px;
  border-top: 1px solid var(--line-soft);
}
.qp-note .label { font-weight: 700; font-size: .83rem; }
.qp-note .text  {
  display: block;
  color: var(--ink-soft);
  font-size: .85rem;
  white-space: pre-wrap;
  margin-top: 3px;
  max-height: 8.4em;
  overflow-y: auto;
}
.qp-note .dest  { display: block; font-size: .78rem; color: var(--ink-faint); margin-top: 4px; }

/* The drop zone wraps the box, the same as the paste screen — "there" is the
   box she is already looking at, not a second place to aim at. */
#q-drop { position: relative; }
#q-drop.is-over textarea { border-color: var(--pink); background: var(--pink-tint); }
#q-drop-hint {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  pointer-events: none;
  font-weight: 700;
  color: var(--pink-deep);
}
#q-drop.is-over #q-drop-hint { display: grid; }

#q-count { font-size: .86rem; color: var(--ink-soft); }
#q-count b { color: var(--ink); font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  .qp-head { grid-template-columns: auto; }
  .qp-head .all { justify-self: start; }
}


/* ===========================================================================
   CONTRACTS ON A SUPPLIER'S BOOKING — 13 September, migration 107.

   Gee: "that contract needs to be in the supplier file in the couple's
   project… And that needs to be visible to me and the couple."

   ⚠️ ONE RULE SET, TWO AUDIENCES. The couple's portal draws the SAME markup
   with the write controls left out, so this styles both. Two copies of one
   list is how the couple's phase headings drifted from the planner's — see
   bloom.css:770.
   =========================================================================== */

.sf-list { list-style: none; margin: 4px 0 8px; padding: 0; }

/* ⚠️ THE <li> IS .sf-item; THE GRID IS .sf-row INSIDE IT. The read panel is the
   item's second child, so it sits UNDER the row rather than becoming a fourth
   grid column. The first version nested a second <li> inside the row's <li>,
   which is invalid — the parser closes the outer one and the panel escapes the
   row entirely.

   ⚠️ AND THE RULE GOES ON .sf-item, NOT .sf-row. Each item holds exactly one
   row, so `.sf-row:last-of-type` is true for EVERY row and would remove every
   divider in the list. */
.sf-item { border-bottom: 1px solid var(--line-soft); }
.sf-item:last-child { border-bottom: 0; }

.sf-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 11px;
  align-items: center;
  padding: 9px 2px;
}

/* What kind of document, as a chip rather than a word in the name — a contract
   and a quote sitting in one list have to be told apart at a glance. */
.sf-kind {
  font-size: .64rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-sky);
  background: var(--c-sky-tint);
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

.sf-meta { min-width: 0; display: flex; flex-direction: column; }
.sf-name { font-weight: 600; font-size: .9rem; overflow-wrap: anywhere; }
.sf-sub  { font-size: .78rem; color: var(--ink-faint); }

.sf-actions { display: flex; gap: 6px; flex: none; flex-wrap: wrap; justify-content: flex-end; }

/* Planner only. Stone, the quiet family — it is a state, not a warning, and
   the row is still perfectly usable. */
.sf-private { color: var(--c-stone); font-weight: 700; }
.sf-row.is-internal { background: var(--c-stone-tint); border-radius: 8px; }

/* The reader's answer, folded under its own row — a sibling of .sf-row inside
   the same .sf-item, so it is outside the grid and needs no column span.
   `[hidden]` is honoured by the reset, but stated because `display: block`
   above it would otherwise win on specificity. */
.sf-read { display: block; padding-bottom: 8px; }
.sf-read[hidden] { display: none; }

/* The file box and its kind, on one line — the box IS the button, so there is
   no second press. */
.s-contract-add {
  display: flex;
  gap: 9px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 8px;
}
.s-contract-add select {
  font-family: inherit;
  font-size: .86rem;
  padding: 6px 9px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
}
.s-contract-add input[type="file"] { font-size: .84rem; max-width: 100%; }

@media (max-width: 640px) {
  .sf-row { grid-template-columns: auto minmax(0, 1fr); }
  .sf-actions { grid-column: 1 / -1; justify-content: flex-start; }
}


/* A photo on a run sheet line shows itself. A floor plan you cannot see is a
   filename, and the whole reason she asked for images was so a picture is a
   picture. Sits where the kind chip sits on a supplier contract, so the two
   lists share one grid. */
.tf-thumb {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--surface-soft);
  flex: none;
}


/* ===========================================================================
   WHAT'S CHANGED, GROUPED BY COUPLE. 14 September.

   Gee: "I'm wondering if we could group the 'what's changed' by couple and
   maybe just by admin… I don't love that it is just a massive line and it's
   very hard to find something."

   ⚠️ THE HAIRLINES ARE A 1px GAP OVER A LINE-COLOURED GROUND, not borders —
   that is how `.chg-rows` above has always drawn them. `.chg-body` repeats the
   same trick INSIDE a group, so rows are separated within a couple and groups
   are separated from each other, with one rule and no double lines where the
   two meet.
   =========================================================================== */

.chg-group { background: var(--surface); }

.chg-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto auto;
  gap: 10px;
  align-items: baseline;
  width: 100%;
  padding: 10px 13px;
  border: 0;
  background: var(--surface-soft);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.chg-head:hover { background: var(--pink-tint); }
.chg-head:focus-visible { outline: 2px solid var(--pink); outline-offset: -2px; }

.chg-fold   { color: var(--ink-faint); font-size: .75rem; }
.chg-couple { font-weight: 700; font-size: .9rem; }

/* The count, as a chip. A number in a row of words is read as a word. */
.chg-n {
  font-size: .72rem;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--line);
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* Pink, matching .chg-row.is-client — a couple's edit is the one she looks
   for, so the group says how many of them are in there before she opens it. */
.chg-theirs {
  font-size: .72rem;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--pink-tint);
  color: var(--pink-deep);
  white-space: nowrap;
}

.chg-latest { color: var(--ink-faint); font-size: .76rem; white-space: nowrap; }

.chg-body {
  display: grid;
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
}

@media (max-width: 640px) {
  /* The timestamp is the first thing to go — the heading is already ordered
     newest-first, so its exact time is the least load-bearing thing on it. */
  .chg-head { grid-template-columns: auto minmax(0, 1fr) auto auto; }
  .chg-latest { display: none; }
}


/* A conversation, not paperwork. Migration 110.

   Gee: "was it an SMS? Was it a WhatsApp? Was it an Instagram or Facebook?…
   because then I have to know where I have to contact the supplier."

   ⚠️ A DIFFERENT COLOUR BECAUSE IT IS A DIFFERENT PROMISE. Every other chip in
   this list is something the couple can open. A chat defaults to Planner only,
   so it should not look like the contract sitting above it. Stone — the quiet
   family, the same one .sf-private already uses for exactly this idea. */
.sf-kind.is-chat {
  color: var(--c-stone);
  background: var(--c-stone-tint);
  border: 1px solid var(--c-stone);
}

/* ---- WHERE WE'RE AT ------------------------------------------------------
   The settled half, above the findings panel on the Overview. Gee, 16
   September: "I'd much rather have a bit of a summary, so I know what's been
   done and dusted... I'm like, oh, did I do that or not do that?"

   TIGHT LINES, NOT CARDS, AND THAT IS THE WHOLE DESIGN CONSTRAINT. This panel
   has been too long three times as findings — eight open cards measured 902px
   and pushed Key details to 1,350px. Twenty-two rows as cards would repeat it
   on the one screen she lands on. A row here is one line of text and its note.

   It borrows the findings panel's own header, so it folds with no extra code
   and looks like part of the same idea rather than a second feature. */
.wwa-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 10px 10px;
}

.wwa-col { padding: 14px 18px 16px; min-width: 0; }
.wwa-col + .wwa-col { border-left: 1px solid var(--line); }

/* One column on a narrow screen, and the rule moves with it — a left border
   on a stacked column draws a stray vertical line down the middle. */
@media (max-width: 760px) {
  .wwa-body { grid-template-columns: 1fr; }
  .wwa-col + .wwa-col { border-left: 0; border-top: 1px solid var(--line); }
}

/* TEAL, NOT AMBER, AND THE REASON IS THE COLOUR LANGUAGE ITSELF. Amber in this
   app means "overdue, needs attention" — see the confetti block in styles.css,
   where every hue carries a meaning. Half of this panel is good news, and a
   summary wearing the warning colour spends amber on something that is not a
   warning. The findings panel directly below KEEPS its amber, so the two read
   as summary and warning rather than as two alarms.

   The amber rules use !important and a bare class, so this needs both the
   extra class and !important to win. Gee chose this on 16 September. */
.tl-header-onpage.wwa-bar {
  background: var(--teal-tint) !important;
  border: 2px solid var(--teal-deep) !important;
  border-bottom: none !important;
}
.tl-header-onpage.wwa-bar .tl-dot { background: var(--teal-deep); }
.tl-header-onpage.wwa-bar .tl-fold { color: var(--teal-deep); }

/* OPTION B, chosen by Gee from three drawn on 16 September: "the headings need
   to be nicer, a bit bolder to really stand out." The other two were bigger
   caps with a rule under them, and a filled pill.

   Sentence case at 17px is the only one of the three that stops reading as a
   LABEL and starts reading as a HEADING, which is what she asked for. The
   colour bar carries the teal and the pink without another block of fill —
   there is already a teal bar directly above this. */
.wwa-head {
  margin: 0 0 11px;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -.012em;
  line-height: 1.2;
  padding-left: 11px;
  border-left: 4px solid currentColor;
}
.wwa-head-done { color: var(--teal-deep); }
.wwa-head-open { color: var(--pink); }

.wwa-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }

.wwa-row {
  display: grid;
  grid-template-columns: 15px 1fr;
  gap: 8px;
  align-items: start;
}

.wwa-mark { font-size: 13px; line-height: 1.45; font-weight: 700; }
.wwa-mark-done { color: var(--teal-deep); }
.wwa-mark-open { color: var(--pink); }

.wwa-text { font-size: 13.5px; line-height: 1.45; color: var(--ink); min-width: 0; }
.wwa-sub { display: block; font-size: 12.5px; color: var(--ink-soft); margin-top: 1px; }

.wwa-none, .wwa-foot { margin: 0; font-size: 12.5px; color: var(--ink-soft); }
.wwa-foot { margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--line); }

/* ==========================================================================
   THE RED STRIP — imported rows on a tab that she has not confirmed.

   Gee, 17 September: "the 3 red should be there below for me to know to fix
   it... it's not there, so I don't know where to put it."

   The count on the tab is 17 pixels wide. This is the same list, on the page,
   where it cannot be missed. Same red as that count, on purpose: one colour
   means one thing, and that thing is "this needs you".

   Sits ABOVE the findings panel. "Is what came across even right?" comes
   before "what is missing?".
   ========================================================================== */

.imp-strip {
  margin: 0 0 16px;
  border: 2px solid #d4121f;
  border-radius: 12px;
  overflow: hidden;
  background: var(--surface, #fff);
}

.imp-strip-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  background: #d4121f;
  color: #fff;
  font-family: var(--display);
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.imp-strip-all {
  margin-left: auto;
  padding: 4px 11px;
  border: 1px solid rgba(255, 255, 255, .8);
  border-radius: 999px;
  background: transparent;
  color: #fff;
  font-family: inherit;
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}

.imp-strip-all:hover { background: rgba(255, 255, 255, .18); }

.imp-strip-list { list-style: none; margin: 0; padding: 0; }

.imp-strip-list li {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 14px;
  border-top: 1px solid var(--line, #ece5e8);
}

.imp-strip-list li:first-child { border-top: none; }

/* A real target, not a caption. The 17px badge is why this rule has a note. */
.imp-strip-tick {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border: 2px solid var(--ok, #12775a);
  border-radius: 6px;
  background: transparent;
  color: var(--ok, #12775a);
  font-size: .8rem;
  line-height: 1;
  cursor: pointer;
}

.imp-strip-tick:hover { background: var(--ok, #12775a); color: #fff; }

.imp-strip-what {
  flex-grow: 1;
  min-width: 0;
  font-size: .9rem;
  color: var(--ink, #2a2126);
}

.imp-strip-go {
  flex-shrink: 0;
  padding: 4px 10px;
  border: 1px solid var(--teal, #009faa);
  border-radius: 999px;
  background: transparent;
  color: var(--teal-deep, #007c85);
  font-family: inherit;
  font-size: .72rem;
  font-weight: 700;
  cursor: pointer;
}

.imp-strip-go:hover { background: var(--teal-tint, #e7f6f7); }

/* Never on paper, and never in the couple's copy. This is her checking list. */
@media print { .imp-strip { display: none !important; } }

/* ---------- the rows a grouped finding is about --------------------------
   Gee, 17 September: "Why are these grouped? They're supposed to be individual
   so I can fix them… If I click the button, why can't I go straight to where
   the problem is to resolve it?"

   One card, and every row inside it is its own way in. See rowsHtml() in
   checks.js for why it stayed one card rather than becoming twenty.

   ⚠️ THESE LIVE IN checks.css, WHICH LOADS AFTER styles.css. An "override"
   written over there at equal specificity would silently lose — that ordering
   has bitten four times now. */
.check-rows {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
}

/* A button, not a link — the findings panel's card is a real <a> and an
   anchor inside an anchor is torn apart by the parser. */
.check-row-link {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  max-width: 100%;
  padding: 3px 10px;
  border: 1px solid var(--line, #ece5e8);
  border-radius: 999px;
  background: #fff;
  color: var(--ink, #2a2126);
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
}

.check-row-link:hover {
  border-color: var(--teal-deep, #00565e);
  color: var(--teal-deep, #00565e);
}

/* The time, or the venue — whichever tells her which row this is. Quieter than
   the name, because the name is what she is scanning for. */
.check-row-note {
  flex: none;
  color: var(--ink-faint, #a0949a);
  font-size: .72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.check-row-link:hover .check-row-note { color: inherit; }

/* On paper a button is a control, and print.css hides every one of them. These
   are not controls there — they are the list of what is outstanding, which is
   the only part of a findings card worth printing. */
@media print {
  .check-row-link {
    display: inline-flex !important;
    border-color: #ece5e8;
  }
}

/* ---------------------------------------------------------------------------
   THE TICK LIST ON A FINDING — picksHtml() in checks.js.

   Gee, 17 September, on "13 of 62 run sheet lines have no place set": "me not
   being able to select it individually… if you had the 13 as individual line
   items and I could press dismiss, that's what I prefer."

   ⚠️ FULL-WIDTH ROWS, NOT PILLS. The chips above are a place to GO; these are
   a thing to ANSWER, and a tick welded into a pill is a small target inside a
   bigger one — the shape she has reported as unusable twice.

   ⚠️ EVERY CONTROL HERE IS A <button>. The card is `a.rsr-card` and app.js has
   to preventDefault inside it, which would cancel a real checkbox's tick. See
   picksHtml() for the whole reason.

   ⚠️ THESE LIVE IN checks.css, WHICH LOADS AFTER styles.css — an override
   written over there at equal specificity would silently lose.
   --------------------------------------------------------------------------- */
.check-picks {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 10px;
}

.check-pick-row {
  display: flex;
  align-items: stretch;
  gap: 6px;
}

/* The row itself is the tick. A big target, because ticking is the job. */
.check-pick {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: 1 1 auto;
  min-width: 0;
  padding: 7px 10px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: var(--surface, #fff);
  color: var(--ink, #2a2126);
  font: inherit;
  font-size: .82rem;
  text-align: left;
  cursor: pointer;
}

.check-pick:hover { background: var(--line-soft, #f6f1f3); }

/* The box is drawn, not native — see picksHtml(). 18px so it reads as a
   tickbox at a glance and is comfortably hittable on a phone, where the whole
   row is the target anyway. */
.check-pick-box {
  flex: none;
  width: 18px;
  height: 18px;
  border: 2px solid var(--ink-faint, #a0949a);
  border-radius: 4px;
  background: var(--surface, #fff);
  position: relative;
}

.check-pick[aria-pressed="true"] .check-pick-box {
  border-color: var(--teal-deep, #00565e);
  background: var(--teal-deep, #00565e);
}

/* 🛑 THE APP ALREADY HAS A MARK FOR "DONE" AND IT IS A TICK IN --teal-deep.
   Drawn with two borders rather than a glyph so it cannot pick up a font that
   has not loaded. */
.check-pick[aria-pressed="true"] .check-pick-box::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 0;
  width: 4px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* The name of the thing is bold — the standing rule on every list screen. */
.check-pick-name {
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.check-pick .check-row-note { margin-left: auto; padding-left: 8px; }

/* The way in, kept. Secondary, never louder than the tick beside it. */
.check-row-open {
  flex: none;
  padding: 0 12px;
  border: 1px solid var(--line, #ece5e8);
  border-radius: 7px;
  background: var(--surface, #fff);
  color: var(--ink-soft, #6b5f65);
  font: inherit;
  font-size: .74rem;
  font-weight: 600;
  cursor: pointer;
}

.check-row-open:hover {
  border-color: var(--teal-deep, #00565e);
  color: var(--teal-deep, #00565e);
}

.check-picks-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}

/* The one action on this card, so it is the one filled control on it. */
.check-picks-go {
  padding: 6px 13px;
  border: 1px solid var(--teal-deep, #00565e);
  border-radius: var(--radius-pill, 999px);
  background: var(--teal-deep, #00565e);
  color: #fff;
  font: inherit;
  font-size: .76rem;
  font-weight: 700;
  cursor: pointer;
}

.check-picks-go[disabled] {
  border-color: var(--line, #ece5e8);
  background: var(--surface, #fff);
  color: var(--ink-faint, #a0949a);
  cursor: default;
}

/* The second action a card can offer over the same ticks — "Set the place on
   N…" beside "Mark N as needing no place".

   ⚠️ OUTLINED, NOT A SECOND SOLID BUTTON. Two filled teal pills side by side
   read as one control drawn twice, and she would have to read both to find out
   which is which. Same family, same colour, different weight — the app already
   has a colour for this and it did not need a new one.

   ⚠️ THE DISABLED RULE ABOVE STILL APPLIES, because this carries
   `.check-picks-go` too and that selector comes first. */
.check-picks-also:not([disabled]) {
  background: var(--surface, #fff);
  color: var(--teal-deep, #00565e);
}

/* Same tier as .check-doing, because it does the same amount: outline, ink. */
.check-picks-all {
  padding: 6px 12px;
  border: 1px solid var(--line, #ece5e8);
  border-radius: var(--radius-pill, 999px);
  background: var(--surface, #fff);
  color: var(--ink, #2a2126);
  font: inherit;
  font-size: .74rem;
  font-weight: 600;
  cursor: pointer;
}

.check-picks-all:hover { background: var(--line-soft, #f6f1f3); }

.check-picks-count {
  font-size: .74rem;
  font-weight: 600;
  color: var(--ink-soft, #6b5f65);
  font-variant-numeric: tabular-nums;
}

/* On paper the ticks are not controls, they are the list of what is still
   outstanding — the only part of a findings card worth printing. Same
   reasoning as .check-row-link above. */
@media print {
  .check-pick {
    display: flex !important;
    border-color: #ece5e8;
  }
  .check-row-open,
  .check-picks-bar { display: none !important; }
}

/* ---------------------------------------------------------------------------
   THE TICK ON A CARD — selecting several findings that offer the same action.

   Gee, 17 September: "I can select multiple and then choose if I want all of
   them to go onto my checklist or not."

   ⚠️ IT BORROWS `.check-pick` AND `.check-pick-box` ON PURPOSE. This is the
   same control as the row tick list above, in its second home, so it must be
   the same square in the same teal. A second look for one idea is how two
   things that should read as one start drifting.

   Only the LAYOUT differs: a row tick fills its row, a card tick sits at the
   card's top-left and lets the card's own text run past it.
   --------------------------------------------------------------------------- */
.check-pick-card {
  position: absolute;
  top: 12px;
  left: 10px;
  padding: 4px;
  border: 0;
  background: transparent;
  line-height: 0;
}

/* The card has to make room for it, and only where one is drawn — a card with
   no tick keeps every pixel it had. */
.rsr-card:has(.check-pick-card) { position: relative; padding-left: 38px; }

/* A ticked card says so as a whole, not just in its box. Quiet: the tick is
   the answer, this is only confirmation that the row is in the set. */
.rsr-card:has(.check-pick-card[aria-pressed="true"]) {
  border-color: var(--teal-deep, #00565e);
  background: var(--teal-tint, #e7f6f7);
}

.check-pick-card:hover .check-pick-box { border-color: var(--teal-deep, #00565e); }

/* The bar sits under the last card in a supplier's pile, inside its body. */
.rsr-sbody > .check-picks-bar {
  margin: 8px 0 2px;
  padding-top: 10px;
  border-top: 1px solid var(--line, #ece5e8);
}

/* On paper none of this is a control — the cards are the list of what is
   outstanding, and a tickbox printed beside them is furniture. */
@media print {
  .check-pick-card,
  .rsr-sbody > .check-picks-bar { display: none !important; }
  .rsr-card:has(.check-pick-card) { padding-left: 16px; }
}

/* A row in a tick list that has nothing to offer — see the heading finding.
   It keeps its name, its note and its way in, and shows an empty square that
   cannot be pressed, so it is visibly "not this one" rather than missing. */
.check-pick-none { cursor: default; }
.check-pick-none:hover { background: transparent; }
.check-pick-box.is-na {
  border-style: dashed;
  border-color: var(--line, #ece5e8);
  background: transparent;
}


/* ===========================================================================
   HIDE ON THE IMPORTED STRIP — 18 September 2026
   ---------------------------------------------------------------------------
   Gee: "This should also be a Hide or a Not Now button as well... get this
   Hide all website-wide."

   The findings panel has had Hide, Show them and Not now for weeks. This strip
   — the red "N imported lines still to check" — is drawn by a different module
   and had only Tick all, so the same idea existed on one panel and not the
   other. Same words as the findings panel on purpose: "Not now", "Bring it
   back", "Show them". One action, one name, or she learns the drawer's
   vocabulary and cannot find it on the card.
   ========================================================================= */

/* Sits beside Tick all in the red head, quieter than it: ticking is the
   thing she came to do, hiding is the escape hatch. */
.imp-strip-hideall {
  padding: 4px 11px;
  border: 1px solid rgba(255, 255, 255, .45);
  border-radius: 999px;
  background: transparent;
  color: #fff;
  font-family: inherit;
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}
.imp-strip-hideall:hover { background: rgba(255, 255, 255, .18); }

/* ⚠️ `margin-left: auto` MOVES TO WHICHEVER BUTTON COMES FIRST. `.imp-strip-all`
   carries it and this sits after, so the pair stays welded to the right edge
   with a gap between them rather than drifting apart. */
.imp-strip-head .imp-strip-all + .imp-strip-hideall { margin-left: 0; }

/* Per row. Ghost-quiet next to the tick and the Go, because it is the one
   action of the three that changes nothing about the data. */
.imp-strip-hide {
  flex-shrink: 0;
  padding: 4px 10px;
  border: 1px solid var(--line, #ece5e8);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft, #6c6067);
  font-size: .72rem;
  font-weight: 700;
  cursor: pointer;
}
.imp-strip-hide:hover {
  border-color: var(--teal-deep, #007c85);
  color: var(--teal-deep, #007c85);
}

/* A row she has put aside. ⚠️ IT STAYS ON THE LIST — 18 September, Gee:
   *"I wanted to stay the way it was… and then adding the additional."* The
   count above is every unchecked row, so removing one would leave the heading
   describing a list that is shorter than it says. Tinted and faded instead, so
   it cannot be mistaken for something still owed, and it says when it is due
   back rather than leaving her to guess. */
.imp-strip-list li.is-put { background: var(--surface-soft, #faf7f8); }
.imp-strip-list li.is-put .imp-strip-what { color: var(--ink-soft, #6c6067); }
.imp-strip-when {
  font-style: normal;
  font-size: .72rem;
  font-weight: 700;
  color: var(--teal-deep, #007c85);
  white-space: nowrap;
}

/* The "already paid" tick when the line already holds that money — 18 Sept.
   Amber, not red: this is a warning about what WOULD happen, and nothing has
   gone wrong yet. The tick is off and the sentence says why. */
.inbox-paid.is-clash { align-items: flex-start; }
.inbox-paid-why {
  display: block;
  margin-top: 3px;
  color: var(--warn-ink, #9c4a00);
  font-size: .8rem;
  font-weight: 600;
}

/* FIND A FILED DOCUMENT — the search above the Files tab's own list.
   ⚠️ Borrows `.sf-list` / `.sf-item` / `.sf-row` from supplierfiles.js on
   purpose, exactly as timelinefiles.js does. A result looks like a file row
   because it IS one; giving the search its own look would read as a second
   kind of document. `.sf-where` is the only new class it needs. */
.ff-find {
  margin: 14px 0 18px;
  padding: 13px 15px;
  background: var(--surface-soft, #faf7f8);
  border: 1px solid var(--line, #ece5e8);
  border-radius: 10px;
}
.ff-find > label {
  display: block;
  margin-bottom: 6px;
  font-size: .78rem;
  font-weight: 700;
  color: var(--ink-soft, #6c6067);
}
.ff-find > input[type="search"] { width: 100%; max-width: 460px; }
#ff-results { margin-top: 10px; }
#ff-results .hint { margin: 0 0 6px; }

/* Where the document actually lives — the whole point of the list, so it is
   readable rather than a whisper under the name. */
.sf-where {
  display: block;
  font-size: .8rem;
  color: var(--ink-soft, #6c6067);
  margin-top: 1px;
}

/* ---------------------------------------------------------------------------
   HIDE ALL, AT EVERY LEVEL THAT SHOWS A COUNT — 18 September.

   Gee: "every page that's got a heading with 'Things to look at' should have a
   Hide All, a Select All, and an individual button... individually, not as a
   group", and then "hide everything in one go, but then hide everything
   according to the category as well."

   The button sits INSIDE the summary rather than in a bar of its own, because
   a bar under every heading would have added thirteen rows of furniture to
   Tiffany's Budget page. Quiet by default and only coloured on hover, so the
   heading still reads as a heading.
   --------------------------------------------------------------------------- */
.rsr-hideall {
  margin-left: auto;
  flex-shrink: 0;
  padding: 3px 10px;
  border: 1px solid var(--line, #ece5e8);
  border-radius: 999px;
  background: var(--surface, #fff);
  color: var(--ink-soft, #6c6067);
  font-size: .71rem;
  font-weight: 700;
  cursor: pointer;
}
.rsr-hideall:hover {
  border-color: var(--teal-deep, #007c85);
  color: var(--teal-deep, #007c85);
}
.rsr-hideall:focus-visible {
  outline: 2px solid var(--pink, #b3145e);
  outline-offset: 2px;
}
.rsr-hideall[disabled] { opacity: .5; cursor: default; }

/* The chevron on a group heading is drawn with ::after, so it comes after the
   button. margin-left:auto on the button welds the pair to the right edge. */
.rsr-gsum .rsr-hideall { margin-right: 4px; }
.rsr-ssum .rsr-hideall { margin-right: 4px; }

/* "✓ Settle all 4", beside "Hide all 4".

   ⚠️ THE SECOND ONE MUST CANCEL THE `margin-left: auto`. Both buttons carry it,
   and in a flex row two auto margins SPLIT the free space between them — so the
   pair would have drifted apart with the heading's own text stranded in the
   middle, on every group on every page. Higher specificity than the base rule,
   so it wins without a duplicate selector (`a-duplicate-rule-wins-the-cascade`).

   ⚠️ AND THE COLOUR IS ALREADY DECIDED. `--teal-deep` with a tick is what this
   app has meant by "done" since 17 September — inventing a new one here would
   be a second visual language for the same idea on the same screen.
   `the-app-already-has-a-colour-for-that`. */
.rsr-hideall + .rsr-hideall { margin-left: 6px; }

.rsr-hideall.is-settle {
  border-color: var(--teal-deep, #007c85);
  color: var(--teal-deep, #007c85);
}
.rsr-hideall.is-settle:hover {
  background: var(--teal-deep, #007c85);
  border-color: var(--teal-deep, #007c85);
  color: #fff;
}

/* The panel-level one has no heading to sit on, so it gets a thin right-aligned
   row above the first group. Only drawn when there is more than one thing. */
.rsr-hidebar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 2px;
}

/* The live half of a panel, wrapped so Hide all cannot reach the dealt-with
   half underneath it. Layout is inherited from .rsr-queue. */
.rsr-live { display: grid; gap: 9px; }

/* ---------------------------------------------------------------------------
   🛑 THE BLUE BAR — `.arr-card.is-bar`, the arrivals box DOWN THE RUN SHEET.

   Gee, 26 September, choosing "C1" out of nine mocked in her own colours: "it's
   just so similar to the design of the actual running sheet. I need this to
   be different so it really stands out, so I can understand that that is the
   arrival, especially when I hide it." A white box with a pink left edge was
   the same shape as the heading above it. Nothing else on the sheet is a
   filled dark bar, and folded it is a solid blue strip.

   ⚠️ SCOPED TO `.is-bar` AND IT MUST STAY SCOPED. The first version restyled
   bare `.arr-card`, which also painted the colour-coded SUPPLIER ARRIVAL TIMES
   block at the top of the sheet. She stopped it within the hour: "You changed
   the wrong one… This part should have stayed the same." Every rule above for
   `.arr-card` is exactly as it was; only these add the bar, and only
   arrivalCardHtml() emits the class.

   At the END of the file on purpose: `.arr-card.is-shut .arr-card-head` above
   carries the same specificity, so a tie must go to these.
   --------------------------------------------------------------------------- */
.arr-card.is-bar {
  padding: 0;
  border: 1.5px solid var(--c-sky, #0067a3);
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
}

.arr-card.is-bar .arr-card-head {
  flex-wrap: wrap;
  gap: 6px 9px;
  margin: 0;
  padding: 7px 12px;
  background: var(--c-sky, #0067a3);
  color: #fff;
}

.arr-card.is-bar .arr-card-icon { font-size: .95rem; line-height: 1; }

.arr-card.is-bar .arr-card-label {
  font-family: var(--display);
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* The pink these cards always had, now on the place pill. */
.arr-card.is-bar .arr-card-place {
  padding: 1px 9px;
  border-radius: 999px;
  background: #fff;
  color: var(--pink-deep, #c31465);
  font-size: .74rem;
  font-weight: 800;
}

.arr-card.is-bar .arr-card-count {
  padding: 0 8px;
  border-radius: 999px;
  background: #fff;
  color: var(--c-sky, #0067a3);
  font-size: .72rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* White-outlined on the bar — teal on deep blue would vanish, which is the
   17 September complaint about this very button. 5.9 to 1, white on #0067a3. */
.arr-card.is-bar .arr-card-hide {
  border-color: #fff;
  background: transparent;
  color: #fff;
}
.arr-card.is-bar .arr-card-hide:hover { background: #fff; color: var(--c-sky, #0067a3); }

/* The padding moves from the card to the list now the head runs edge to edge. */
.arr-card.is-bar .arr-card-list { padding: 8px 12px; }

/* ===========================================================================
   🛑 THE BUDGET PANEL, IN FOUR LABELLED ROWS — 27 September 2026.

   Gee: "look at the budget section. It's a bit messy. It's really, really
   messy… And on the phone, it looks even messier." Then, choosing from mock-ups
   on Solin & Rony's real numbers: layout A (four rows), scheme 3 (a soft band
   behind each group), Tools in SAGE ("it's all teal… You can't distinguish
   anything"), small OUTLINED Add buttons ("look how big the circle is"), the
   balance in a GOLD box instead of pink, and "D" — amount first, word
   underneath. The totals are rounded in budget.js; the table keeps its cents.

   ⚠️ EVERY CONTROL KEPT ITS ID. This block only places and colours them. The
   sort ticks are still the three checkboxes budget.js reads; "Bank details" is
   still #hide-bank, drawn from its opposite.

   ⚠️ AT THE END OF checks.css ON PURPOSE: styles.css has older `.bg-stat .k`
   and `.bg-summary` rules at equal or lower weight, and these must win.
   =========================================================================== */
.bg-summary {
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  padding: 16px 18px;
}

.bg-band-money {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  flex-wrap: wrap;
}

.bg-stats {
  display: flex;
  align-items: center;
  gap: 14px 30px;
  flex-wrap: wrap;
}

/* D — the amount leads, the word sits quietly underneath. */
.bg-summary .bg-stat .v {
  color: var(--ink);
  font-size: 1.32rem;
  font-weight: 700;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.bg-summary .bg-stat .k {
  color: var(--ink-soft);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

/* The balance, in its gold box. Pink was "too close to the print and export
   colours" and to the Add buttons beside it. */
.bg-summary .bg-stat.is-balance {
  padding: 5px 13px;
  border: 1.5px solid #e8c84a;
  border-radius: 10px;
  background: #fff7d6;
}
.bg-summary .bg-stat.is-balance .v,
.bg-summary .bg-stat.is-balance .k { color: #5c4400; }

/* Small outlined Add buttons — the only pink left in the panel. */
.bg-adds { display: flex; gap: 8px; flex-wrap: wrap; }
.bg-add {
  padding: 5px 13px;
  border: 1.5px solid var(--pink-deep, #c31465);
  border-radius: 999px;
  background: #fff;
  color: var(--pink-deep, #c31465);
  font-family: inherit;
  font-size: .8rem;
  font-weight: 700;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
}
.bg-add:hover { background: var(--pink-deep, #c31465); color: #fff; }
.bg-add:focus-visible { outline: 2px solid var(--pink-deep, #c31465); outline-offset: 2px; }

/* ---- the three bands ---- */
.bg-band:not(.bg-band-money) {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 9px 12px;
  border-radius: 10px;
}
.bg-band-lab {
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.bg-band-row { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; }
.bg-band-row .check-inline { margin: 0; }

/* View — navy. */
.bg-band-view { background: #eaf0fa; }
.bg-band-view .bg-band-lab { color: #1e3f7d; }
.bg-band-view .check-inline input { accent-color: #1e3f7d; }

.bg-seg {
  display: inline-flex;
  border: 1.5px solid #1e3f7d;
  border-radius: 999px;
  overflow: hidden;
  background: #fff;
}
.bg-seg-opt {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 5px 12px;
  border: 0;
  border-left: 1.5px solid #1e3f7d;
  background: #fff;
  color: #1e3f7d;
  font: inherit;
  font-size: .78rem;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}
.bg-seg-opt:first-child { border-left: 0; }
/* The checkbox is still there for budget.js and the keyboard; it is simply not
   drawn — the whole segment is its label. */
.bg-seg-opt input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.bg-seg-opt:has(input:checked),
.bg-seg:not(:has(input:checked)) .bg-seg-all {
  background: #1e3f7d;
  color: #fff;
}
.bg-seg-opt:has(input:focus-visible),
.bg-seg-all:focus-visible { outline: 2px solid #1e3f7d; outline-offset: 2px; }

/* "Bank details" — the real #hide-bank is invisible; this box is ticked when
   it is NOT, i.e. when the bank columns SHOW. */
.bg-bank-tick { position: relative; }
.bg-bank-tick input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}
.bg-bank-tick i {
  width: 16px;
  height: 16px;
  border: 2px solid #1e3f7d;
  border-radius: 4px;
  background: #fff;
  display: inline-block;
  vertical-align: -3px;
  position: relative;
}
.bg-bank-tick input:not(:checked) + i { background: #1e3f7d; }
.bg-bank-tick input:not(:checked) + i::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 0;
  width: 4px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.bg-bank-tick input:focus-visible + i { outline: 2px solid #1e3f7d; outline-offset: 2px; }

/* Needs a look — soft orange. The whole band steps aside when every filter
   button is hidden (nothing needs a look). */
.bg-band-attn { background: #fff3e3; }
.bg-band-attn .bg-band-lab { color: #a85700; }
.bg-band-attn:not(:has(.bg-band-row > button:not([hidden]))) { display: none; }
.bg-summary .bg-band-attn .btn {
  border-color: #f0b37e;
  background: #fff;
  color: #a85700;
}
.bg-summary .bg-band-attn .btn.is-on {
  border-color: #a85700;
  background: #a85700;
  color: #fff;
}

/* Tools — sage. */
.bg-band-tools { background: #e9f5ee; }
.bg-band-tools .bg-band-lab { color: #2f7a5f; }
.bg-summary .bg-band-tools .btn,
.bg-summary .bg-band-tools .aside-chip {
  border-color: #9fcdb4;
  background: #fff;
  color: #235e49;
}
.bg-summary .bg-band-tools .btn.is-on,
.bg-summary .bg-band-tools .btn[aria-pressed="true"] {
  border-color: #235e49;
  background: #235e49;
  color: #fff;
}
.bg-summary .bg-band-tools .bg-paste {
  border: 0;
  background: none;
  color: #2f7a5f;
  text-decoration: underline;
  padding-inline: 4px;
}

/* Print / Export — one menu. */
.bg-output { position: relative; }
.bg-output > summary { list-style: none; cursor: pointer; }
.bg-output > summary::-webkit-details-marker { display: none; }
.bg-output-menu {
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  min-width: 210px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 8px 22px rgba(42, 33, 38, .14);
}
.bg-output-menu .btn { width: 100%; text-align: left; }

/* The couple's copy — Gee: "The couple doesn't need to see 4 set aside… They
   probably don't need to see comparison now… Maybe we don't need Select All
   for the couple." Hidden, not removed: the tab is HER one element, moved into
   the portal and back (§36.1), and this rule stops applying the moment it
   leaves #portal-body. */
#portal-body #bg-select-all,
#portal-body #bg-comparisons,
#portal-body #bg-aside-chip { display: none !important; }
/* The payment labels for a selection, and their Undo, are HER press only
   (CHECK 105) — a couple never marks a line ready, held or paid. */
#portal-body .bg-bulk-pay,
#portal-body .bg-bulk-vis,
#portal-body #bg-undo-bar { display: none !important; }

/* On a phone: the four totals in a two-by-two grid, everything else stacked. */
@media (max-width: 620px) {
  .bg-summary { padding: 12px; gap: 10px; }
  .bg-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; width: 100%; }
  .bg-summary .bg-stat .v { font-size: 1.15rem; }
  .bg-adds { width: 100%; }
  .bg-band-tools .bg-search-field { width: 100%; }
  .bg-seg-opt { padding: 4px 9px; font-size: .72rem; }
}

/* THE ACCOUNT, COPYABLE — 22 Oct, CHECK 255. Plain words she can select, each
   with a Copy button, on the budget line window AND the supplier window's
   Money box. `user-select: text` on purpose: a placeholder cannot be selected,
   which is the fault this replaces. Her pink for what she can press. */
.bank-copy { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.bank-copy-part { display: inline-flex; align-items: center; gap: 6px; }
.bank-copy-v { font-weight: 800; color: var(--ink); user-select: text; font-variant-numeric: tabular-nums; }
.bank-copy-btn {
  font: inherit; font-size: .78rem; font-weight: 800;
  min-height: 26px; padding: 2px 10px;
  border: 1.5px solid var(--pink); border-radius: 8px;
  background: var(--surface); color: var(--pink-deep); cursor: pointer;
}
.bank-copy-btn:hover { background: #fde4ef; }
.bank-copy-btn.is-all { background: var(--pink); color: #fff; }
.bank-copy-btn.is-done { background: #e6f7ef; border-color: #16a36a; color: #0d7a4f; }
#budget-modal .bank-copy-row { margin-top: 8px; padding: 6px 10px; border-radius: 8px; background: #f6efff; }

/* The supplier window's Money box — 22 Oct, CHECK 260. */
#s-budget-hint .sbh-money { grid-template-columns: 74px minmax(0, 1fr) auto; }
#s-budget-hint .sbh-money b { color: var(--pink-deep); }
#s-budget-hint .sbh-due { font-weight: 700; }
#s-budget-hint .sbh-due.is-late { color: #b3261e; font-weight: 800; }
#s-budget-hint .sbh-remind {
  justify-self: start; font-weight: 800; min-height: 28px;
  background: var(--pink); color: #fff; border: 0; border-radius: 8px; padding: 3px 12px;
}
#s-budget-hint .sbh-files { margin-left: 8px; font-size: .84rem; font-weight: 600; color: var(--ink); }
#s-budget-hint .sbh-none { font-weight: 600; color: #b3261e; }
@media print { .bank-copy-btn, .sbh-remind { display: none; } }

/* ---------------------------------------------------------------------------
   🍽 THE SUPPLIER TABLE CARD — the arrival card's shape, in ORANGE. Gee picked
   "Option A" off a mock-up on Solin & Rony's real sheet, 22 Oct 2026, "with the
   Planner only / Everyone switch". Scoped to `.is-suptable` so the blue
   arrival card cannot change. timeline.js supplierTableCardHtml(). CHECK 261.
   --------------------------------------------------------------------------- */
.arr-card.is-bar.is-suptable { border-color: #c2410c; }
.arr-card.is-bar.is-suptable .arr-card-head { background: #c2410c; }
.arr-card.is-bar.is-suptable .arr-card-count { color: #c2410c; }
/* The body — big enough to read at a glance. Gee, 22 Oct, on Natasha's
   breakdown at 11px grey: "It was very lost." Her pick off the mock-up:
   the table line big, a count in bold orange beside the bold name, the
   dietary in RED like her venue's crew meal sheet. CHECK 268. */
.suptable-body { padding: 10px 14px 12px; cursor: pointer; background: #fff3ea; }
.suptable-where { font-size: 1.12rem; font-weight: 800; color: #007c85; line-height: 1.3; }
.suptable-where span { color: var(--pink); }
.suptable-counts { margin: 6px 0 2px; }
.suptable-count {
  display: grid; grid-template-columns: 44px minmax(0, 1fr); align-items: baseline;
  padding: 6px 0; border-top: 1px solid #f6d3bd; font-size: .95rem; color: var(--ink);
}
.suptable-n { font-size: 1.08rem; font-weight: 800; color: #c2410c; }
.suptable-who b { font-weight: 800; }
.suptable-diet { display: block; color: #d61f1f; font-weight: 700; }
.suptable-note { padding-top: 6px; font-size: .9rem; font-weight: 700; color: var(--pink); }
.suptable-note.is-empty { font-weight: 600; color: #c2410c; }
.suptable-vis {
  margin-left: auto;
  display: inline-flex;
  border: 1.5px solid #fff;
  border-radius: 999px;
  overflow: hidden;
}
.suptable-vis button {
  border: 0;
  background: transparent;
  color: #fff;
  font: inherit;
  font-size: .74rem;
  font-weight: 800;
  padding: 3px 11px;
  cursor: pointer;
}
.suptable-vis button.is-on { background: #fff; color: #c2410c; }
.suptable-vis button:not(.is-on):hover { background: rgba(255, 255, 255, .25); }
@media print { .suptable-vis { display: none; } }

/* OPTIONS UNDER THEIR BUDGET LINE — 22 Oct, CHECK 264. Several quotes for one
   job, listed in the row's supplier cell. Lilac, the colour the comparison
   panel already wears, so it reads as "choosing", never as money owed. */
#budget-body .bg-opts {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px;
  margin-top: 6px; padding: 5px 8px;
  border-left: 3px solid #b9a1ea; border-radius: 6px; background: #faf6ff;
  font-size: .82rem; color: var(--ink); white-space: normal;
}
#budget-body .bg-opts-head { font-size: .7rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: #5b2fa8; flex-basis: 100%; }
#budget-body .bg-opt { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 8px; background: #fff; border: 1px solid #e3d8fb; }
#budget-body .bg-opt.is-picked { border-color: #5b2fa8; }
#budget-body .bg-opt-note { color: #6f5a8f; font-weight: 600; }
#budget-body .bg-opt-book {
  font: inherit; font-size: .74rem; font-weight: 800; min-height: 24px; padding: 1px 8px;
  border: 1.5px solid var(--pink); border-radius: 7px; background: var(--surface); color: var(--pink-deep); cursor: pointer;
}
#budget-body .bg-opt-book:hover { background: #fde4ef; }
@media print { #budget-body .bg-opt-book { display: none; } }
