/* ==========================================================================
   Dufour Job Book - the job as it runs (2026-08-01)
   Payment state, progress bars, the job header, the cost list where the money
   is, who is on the job, and the Money owed screen.

   A separate sheet from app.css deliberately: this is one round of work with
   one reason for existing (Jay's 31 July feedback), and keeping it together
   means it can be read, argued with or removed as a unit. Every colour is a
   token from app.css's :root; nothing here invents its own.
   ========================================================================== */

/* ---- payment state, as a pill ---- */
.pay-pill{
  display:inline-flex; align-items:center; padding:3px 10px; border-radius:var(--r-pill);
  font-size:11px; font-weight:700; letter-spacing:.02em; white-space:nowrap;
}
.pay-settled{ background:var(--won-bg); color:var(--won); }
.pay-part{ background:var(--due-bg); color:var(--due); }
.pay-unpaid{ background:var(--overdue-bg); color:var(--overdue); }
.pay-overpaid{ background:var(--due-bg); color:var(--due); }
.pay-unrecorded{ background:var(--info-bg); color:var(--text-muted); }

/* ---- three bars: start, middle, finish ----
   Deliberately a shape, not a percentage. Jay wants to read a row of jobs
   across a screen and know which are near the end; three filled blocks do
   that at a glance and "67%" does not. */
.pbars{ display:inline-flex; align-items:center; gap:3px; vertical-align:middle; }
.pbar{
  display:inline-block; width:16px; height:7px; border-radius:2px;
  background:var(--border-strong); transition:background .12s ease, transform .12s ease;
}
.pbars.small .pbar{ width:11px; height:5px; }
.pbar.on{ background:var(--brand-yellow); box-shadow:inset 0 0 0 1px rgba(17,24,39,.14); }
.pbar.tappable{ cursor:pointer; }
.pbar.tappable:hover{ transform:scaleY(1.45); background:var(--yellow-hover); }
.pbar.tappable:focus-visible{ outline:2px solid var(--chrome); outline-offset:2px; }
.pbars-label{ margin-left:8px; font-size:12px; font-weight:600; color:var(--text-muted); }
/* Named where they are a control. A tap target with no name is a guess. */
.pbars.captioned{ align-items:flex-start; gap:6px; }
.pbar-wrap{ display:inline-flex; flex-direction:column; align-items:center; gap:3px; }
.pbars.captioned .pbar{ width:34px; height:9px; }
.pbar-cap{ font-size:9.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:rgba(255,255,255,.45); }
.pbar-cap.on{ color:var(--brand-yellow); }
.pbars.captioned .pbars-label{ align-self:center; }

/* ---- the job header: what the job IS, before anything else ---- */
.job-header{
  background:var(--chrome); color:var(--text-invert); border-radius:var(--r-card);
  padding:16px 18px; margin-bottom:14px;
}
.jh-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:14px; flex-wrap:wrap; }
.jh-title h2{ margin:0 0 7px; font-size:21px; line-height:1.2; color:var(--text-invert); }
.jh-tags{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.jh-type{
  font-size:12.5px; font-weight:700; letter-spacing:.02em; color:var(--chrome);
  background:var(--brand-yellow); padding:3px 10px; border-radius:var(--r-pill);
}
.jh-actions{ display:flex; gap:8px; flex-wrap:wrap; }
.jh-progress{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin-top:14px; padding-top:13px; border-top:1px solid rgba(255,255,255,.14);
}
.jhp-label{ font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:rgba(255,255,255,.62); }
.jh-progress .pbar{ background:rgba(255,255,255,.22); }
.jh-progress .pbar.on{ background:var(--brand-yellow); }
.jh-progress .pbars-label{ color:rgba(255,255,255,.9); }
.jh-progress .hint{ color:rgba(255,255,255,.5); font-size:11.5px; }
.jh-figures{
  display:grid; grid-template-columns:repeat(6,1fr); gap:1px; margin-top:15px;
  background:rgba(255,255,255,.12); border-radius:8px; overflow:hidden;
}
.jhf{ background:var(--chrome-2); padding:11px 12px; display:flex; flex-direction:column; gap:2px; }
.jhf-label{ font-size:10.5px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:rgba(255,255,255,.55); }
.jhf-value{ font-size:17px; font-weight:700; line-height:1.2; }
.jhf-sub{ font-size:10.5px; color:rgba(255,255,255,.5); }
.jhf.tone-good .jhf-value{ color:#7DDBA0; }
.jhf.tone-bad .jhf-value{ color:#FF9AA3; }
.jhf.tone-warn .jhf-value{ color:var(--brand-yellow); }
.jhf.tone-muted .jhf-value{ font-size:13px; color:rgba(255,255,255,.55); font-weight:600; }
.jh-note{
  margin-top:13px; padding:10px 12px; border-radius:8px; font-size:12.5px;
  background:rgba(255,255,255,.08); color:rgba(255,255,255,.86);
}
.jh-note.warn{ background:rgba(242,229,25,.14); color:var(--brand-yellow); }

/* ---- the cost list, sitting where the totals are ---- */
.form-3col{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:13px; }
.cost-items{ display:flex; flex-direction:column; gap:1px; background:var(--border); border-radius:8px; overflow:hidden; }
.cost-item{
  display:grid; grid-template-columns:118px 1fr 96px 96px 30px; align-items:center; gap:10px;
  background:var(--surface); padding:9px 12px; font-size:13px;
}
.ci-cat{ font-size:11px; font-weight:700; letter-spacing:.02em; color:var(--text-muted); text-transform:uppercase; }
.ci-desc{ font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ci-date{ font-size:12px; color:var(--text-muted); }
.ci-amt{ text-align:right; font-weight:700; font-variant-numeric:tabular-nums; }
.ci-del{
  border:0; background:transparent; color:var(--text-muted); cursor:pointer;
  font-size:17px; line-height:1; padding:2px 5px; border-radius:4px;
}
.ci-del:hover{ background:var(--overdue-bg); color:var(--overdue); }
/* A saved cost has to be impossible to miss. The alternative is the same £200
   entered three times, which is what happened. */
.cost-item.just-added{ animation:costFlash 2.4s ease-out; }
@keyframes costFlash{
  0%{ background:var(--brand-yellow); }
  22%{ background:var(--yellow-soft); }
  100%{ background:var(--surface); }
}
.cost-add{ margin-top:14px; padding-top:14px; border-top:1px solid var(--border); }
.cost-add-foot{ display:flex; align-items:flex-end; gap:12px; margin-top:10px; }
.cost-add-foot .form-row{ margin:0; max-width:190px; }
.empty-state.small{ padding:18px 14px; font-size:12.5px; }
/* Each total opens the rows behind it. */
tr.cost-open, .cost-row.cost-open{ cursor:pointer; }
tr.cost-open:hover, .cost-row.cost-open:hover{ background:var(--yellow-soft); }
.open-hint{ color:var(--text-muted); font-weight:700; }
.kpi-card.clickable{ cursor:pointer; }
.kpi-card.clickable:hover{ box-shadow:var(--shadow-lift); }

/* ---- who is on the job ---- */
.crew-list{ display:flex; flex-direction:column; gap:1px; background:var(--border); border-radius:8px; overflow:hidden; }
.crew-row{
  display:grid; grid-template-columns:150px 1fr 1fr 30px; align-items:center; gap:10px;
  background:var(--surface); padding:9px 12px; font-size:13px;
}
.crew-trade{ font-weight:700; }
.crew-person.needed{ color:var(--due); font-style:italic; }
.crew-note{ font-size:12px; color:var(--text-muted); }
.crew-add{ margin-top:14px; padding-top:14px; border-top:1px solid var(--border); }
.crew-add .btn{ margin-top:10px; }

/* ---- Jay's own steps on the timeline ---- */
.step-add{ margin-top:14px; padding-top:14px; border-top:1px solid var(--border); }
.step-add .form-3col .btn{ width:100%; }
.tl-item.tl-mine{ border-left:3px solid var(--brand-yellow); padding-left:10px; }
.tl-item.tl-mine .tl-title{ display:flex; align-items:center; justify-content:space-between; gap:8px; }

/* ---- Money owed ---- */
.owed-group{ margin-bottom:16px; }
.owed-note{ margin:-4px 0 12px; }
.owed-list{ display:flex; flex-direction:column; gap:1px; background:var(--border); border-radius:8px; overflow:hidden; }
.owed-row{
  display:flex; align-items:center; gap:12px; width:100%; text-align:left;
  background:var(--surface); border:0; padding:12px 14px; cursor:pointer; font:inherit;
}
.owed-row:hover{ background:var(--yellow-soft); }
.or-main{ flex:1 1 auto; display:flex; flex-direction:column; gap:2px; min-width:0; }
.or-name{ font-weight:700; font-size:14px; }
.or-meta{ font-size:12px; color:var(--text-muted); }
.or-money{ display:flex; flex-direction:column; align-items:flex-end; gap:2px; }
.or-owed{ font-weight:700; font-size:15px; font-variant-numeric:tabular-nums; color:var(--due); }
.or-owed.bad{ color:var(--overdue); }
.or-owed.muted{ color:var(--text-muted); font-size:13.5px; }
.or-sub{ font-size:11.5px; color:var(--text-muted); }
.or-go{ color:var(--text-muted); font-size:20px; line-height:1; }

/* ---- payment modal ---- */
.pay-current{ display:grid; grid-template-columns:repeat(3,1fr); gap:12px; }
.pay-current > div{ background:var(--info-bg); border-radius:8px; padding:10px 12px; display:flex; flex-direction:column; gap:3px; }
.pay-current .label{ font-size:10.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--text-muted); }
.pay-current strong{ font-size:16px; }
.pay-current .neg{ color:var(--overdue); }
.pay-current .pos{ color:var(--won); }
.pay-quick{ display:flex; gap:8px; flex-wrap:wrap; margin-top:6px; }
.finish-owed{
  margin-top:12px; padding:12px 14px; border-radius:8px;
  background:var(--due-bg); color:var(--due); font-size:13px;
}
.finish-owed.muted{ background:var(--info-bg); color:var(--text-muted); }

/* ---- counts, badges, inline links ---- */
.count-chip{
  display:inline-block; margin-left:8px; padding:2px 9px; border-radius:var(--r-pill);
  background:var(--info-bg); color:var(--text-muted); font-size:12px; font-weight:700; vertical-align:middle;
}
.inline-link{ color:inherit; font-weight:600; text-decoration:underline; text-underline-offset:2px; }
.nav-badge{
  display:inline-flex; align-items:center; justify-content:center; min-width:19px; height:19px;
  padding:0 5px; border-radius:var(--r-pill); background:var(--brand-yellow); color:var(--chrome);
  font-size:11px; font-weight:800; margin-left:auto;
}
.sidebar.collapsed .nav-badge{ display:none; }
.tabbar button{ position:relative; }
.tab-badge{
  position:absolute; top:3px; left:50%; transform:translateX(6px);
  min-width:17px; height:17px; padding:0 4px; border-radius:var(--r-pill);
  background:var(--brand-yellow); color:var(--chrome);
  font-size:10px; font-weight:800; line-height:17px; text-align:center;
}

/* ---- the running margin, above Jay's two charts ---- */
.margin-hero{ display:flex; align-items:flex-start; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.mh-label{ font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted); }
.mh-value{ font-size:40px; font-weight:800; line-height:1.05; letter-spacing:-.02em; }
.mh-sub{ font-size:12.5px; color:var(--text-muted); }
.mh-chip{ display:inline-block; padding:5px 12px; border-radius:var(--r-pill); font-size:12px; font-weight:700; }
.mh-chip.good{ background:var(--won-bg); color:var(--won); }
.mh-chip.warn{ background:var(--due-bg); color:var(--due); }

/* ==========================================================================
   2026-08-03, Jay's 2 August feedback: the job's dates, the payment list, the
   settle button, the forward view and the overheads editor.
   ========================================================================== */

/* ---- ITEM A: the job's dates, in the header where the facts are ---- */
.jh-dates{
  display:flex; flex-direction:column; gap:8px;
  border-top:1px solid var(--border); margin-top:12px; padding-top:12px;
}
.jh-dates.overran{ border-top-color:var(--overdue); }
.jhd-fields{ display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap; }
.jhd-field{ display:flex; flex-direction:column; gap:4px; }
.jhd-field > span,
.jhd-push > span{
  font-size:10.5px; text-transform:uppercase; letter-spacing:.06em;
  font-weight:700; color:var(--text-muted);
}
.jhd-field input{
  border:1px solid var(--border-strong); border-radius:8px; padding:7px 10px;
  font:inherit; font-size:13.5px; background:var(--surface); color:var(--text);
  min-height:38px;   /* a real tap target on a phone */
}
.jhd-field input:focus{ outline:2px solid var(--brand-yellow); outline-offset:1px; border-color:var(--brand-yellow); }
.jhd-push{ display:flex; flex-direction:column; gap:4px; }
.jhd-btns{ display:flex; gap:6px; flex-wrap:wrap; }
.jhd-btns .btn[disabled]{ opacity:.45; cursor:not-allowed; }
.jhd-sense{ font-size:12.5px; color:var(--text-muted); }
.jh-dates.overran .jhd-sense{ color:var(--overdue); font-weight:600; }

/* ---- ITEM D: the payment list ---- */
.pay-list{ display:flex; flex-direction:column; gap:1px; background:var(--border); border-radius:8px; overflow:hidden; }
.pay-row{
  display:grid; grid-template-columns:110px 1fr auto; align-items:center; gap:12px;
  background:var(--surface); padding:10px 14px; font-size:13.5px;
}
.pr-date{ font-size:12.5px; color:var(--text-muted); font-variant-numeric:tabular-nums; }
.pr-meta{ color:var(--text-muted); font-size:12.5px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pr-amt{ font-weight:700; font-variant-numeric:tabular-nums; }
.pay-row.pay-neg .pr-amt{ color:var(--overdue); }
/* The imported figures. Marked as what they are rather than given a date we
   would have had to invent. */
.pay-row.pay-opening{ background:var(--info-bg); }
.pay-row.pay-opening .pr-date{ font-style:italic; }
.pay-total{
  display:grid; grid-template-columns:repeat(3,1fr); gap:12px; margin-top:12px;
  background:var(--chrome); color:#fff; border-radius:8px; padding:12px 14px;
}
.pay-total > div{ display:flex; flex-direction:column; gap:3px; }
.pay-total .label{ font-size:10.5px; text-transform:uppercase; letter-spacing:.06em; opacity:.72; }
.pay-total strong{ font-size:16px; font-variant-numeric:tabular-nums; }
.pay-total .pos{ color:var(--brand-yellow); }
.pay-total .neg{ color:#FF8A93; }
.pay-foot{ display:flex; gap:8px; margin-top:12px; flex-wrap:wrap; }

/* ---- ITEM E: settle a job from the Money owed row ---- */
/* The row is a flex DIV holding the open button plus the settle button, so the
   two are siblings. It used to be a single <button>, and a button inside a
   button is un-nested by the parser. */
.owed-row > .or-open{
  display:flex; align-items:center; gap:12px; flex:1 1 auto; min-width:0;
  background:transparent; border:0; padding:0; text-align:left; cursor:pointer; font:inherit; color:inherit;
}
.or-settle{ flex:0 0 auto; white-space:nowrap; }

/* ---- ITEM J: the forward view ---- */
.cu-group{ margin-bottom:18px; }
.cu-group:last-of-type{ margin-bottom:12px; }
.cu-head{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin-bottom:2px; }
.cu-head h4{ margin:0; font-size:14px; font-weight:800; }
.cu-note{ margin-bottom:8px; }
.rec-sub{ font-size:11px; color:var(--text-muted); white-space:nowrap; }
.rec-right{ flex-direction:column; align-items:flex-end; gap:2px !important; }

/* ---- ITEM I: the overheads editor ---- */
.ovh-list{ display:flex; flex-direction:column; gap:1px; background:var(--border); border-radius:8px; overflow:hidden; }
.ovh-row{ display:grid; grid-template-columns:1fr 130px 30px; gap:10px; align-items:center; background:var(--surface); padding:8px 12px; }
.ovh-row input{
  border:1px solid transparent; border-radius:6px; padding:6px 8px; font:inherit; font-size:13.5px;
  background:transparent; color:var(--text); min-width:0; min-height:34px;
}
.ovh-row input:hover{ border-color:var(--border-strong); background:var(--surface); }
.ovh-row input:focus{ outline:2px solid var(--brand-yellow); outline-offset:0; border-color:var(--brand-yellow); background:var(--surface); }
.ovh-amt{ text-align:right; font-variant-numeric:tabular-nums; font-weight:600; }
.ovh-add{ display:grid; grid-template-columns:1fr 130px auto; gap:10px; margin-top:12px; }
.ovh-add input{ border:1px solid var(--border-strong); border-radius:8px; padding:8px 10px; font:inherit; font-size:13.5px; min-height:38px; }

/* ---- the assistant's "nothing matched" card (item G) ---- */
.draft-card.draft-empty{ border-color:var(--due); background:var(--due-bg); }
.draft-none{ font-size:13px; line-height:1.5; padding:4px 0 2px; }

/* ---- a tick box that reads as a row, for the confirm forms ---- */
.check-row{ display:flex; align-items:center; gap:9px; margin-top:10px; font-size:13.5px; cursor:pointer; }
.check-row input{ width:17px; height:17px; accent-color:var(--brand-yellow); flex:0 0 auto; }

@media (max-width:1100px){
  .jh-figures{ grid-template-columns:repeat(3,1fr); }
}
@media (max-width:820px){
  .form-3col{ grid-template-columns:1fr; }
  .jh-figures{ grid-template-columns:repeat(2,1fr); }
  .jh-top{ flex-direction:column; }
  .jh-actions{ width:100%; }
  .jh-actions .btn{ flex:1 1 auto; }
  /* On a phone a cost row stacks rather than scrolling sideways: type and date
     on one line, what it was for below, amount on the right. */
  .cost-item{
    grid-template-columns:1fr auto 30px;
    grid-template-areas:"cat date del" "desc amt amt";
    row-gap:3px;
  }
  .ci-cat{ grid-area:cat; }
  .ci-date{ grid-area:date; text-align:right; }
  .ci-del{ grid-area:del; }
  .ci-desc{ grid-area:desc; white-space:normal; }
  .ci-amt{ grid-area:amt; }
  .crew-row{
    grid-template-columns:1fr auto 30px;
    grid-template-areas:"trade person del" "note note note";
    row-gap:3px;
  }
  .crew-trade{ grid-area:trade; }
  .crew-person{ grid-area:person; text-align:right; }
  .crew-note{ grid-area:note; }
  .crew-row .ci-del{ grid-area:del; }
  .cost-add-foot{ flex-direction:column; align-items:stretch; }
  .cost-add-foot .form-row{ max-width:none; }
  .pay-current{ grid-template-columns:1fr; }
  .mh-value{ font-size:32px; }
  /* The dates go full width on a phone rather than squeezing two date pickers
     and three buttons onto one line. */
  .jhd-fields{ flex-direction:column; align-items:stretch; gap:12px; }
  .jhd-field input{ width:100%; }
  .jhd-btns .btn{ flex:1 1 auto; }
  .pay-row{ grid-template-columns:1fr auto; grid-template-areas:"date amt" "meta meta"; row-gap:3px; }
  .pr-date{ grid-area:date; }
  .pr-amt{ grid-area:amt; text-align:right; }
  .pr-meta{ grid-area:meta; white-space:normal; }
  .pay-total{ grid-template-columns:1fr; gap:8px; }
  /* Settle drops under the row on a phone so the tap target is full width and
     cannot be hit by accident while reaching for the row itself. */
  .owed-row{ flex-wrap:wrap; }
  .owed-row > .or-open{ flex:1 1 100%; }
  .or-settle{ flex:1 1 100%; margin-top:8px; }
  .ovh-row{ grid-template-columns:1fr 110px 28px; }
  .ovh-add{ grid-template-columns:1fr; }
}
@media (prefers-reduced-motion:reduce){
  .cost-item.just-added{ animation:none; box-shadow:inset 0 0 0 2px var(--brand-yellow); }
  .pbar{ transition:none; }
}

/* --------------------------------------------------------------------------
   THE SAVE BUTTON ON A JOB'S DATES (2026-08-05)
   Jay asked for a Save button on anything he types into: "otherwise it feels
   like nothing's gone". The state label beside it is the other half of that,
   because a disabled button on its own does not say whether the last thing
   typed reached the server.
   -------------------------------------------------------------------------- */
.jhd-save{ display:flex; align-items:center; gap:10px; align-self:flex-end; padding-bottom:2px; }
.jhd-state{ font-size:12px; color:var(--text-muted); white-space:nowrap; }
.jhd-state.unsaved{ color:var(--overdue); font-weight:600; }
.jhd-state.just-saved{ color:var(--won); font-weight:600; }
.jhd-save .btn[disabled]{ opacity:.45; cursor:default; }
@media (max-width:760px){
  .jhd-save{ align-self:stretch; justify-content:space-between; padding-top:4px; }
}

/* --------------------------------------------------------------------------
   IS THIS A VAT JOB (2026-08-06)
   Jay: "this job here is a VAT job ... but it doesn't say here that it is."
   Same shape as the dates row directly above it, because it answers the same
   kind of question: a fact about the job, readable and changeable where it is
   read. The pill in the header is what makes it visible without scrolling.
   -------------------------------------------------------------------------- */
.jh-vat{
  display:flex; align-items:baseline; gap:16px; flex-wrap:wrap;
  border-top:1px solid var(--border); margin-top:12px; padding-top:12px;
}
.jhv-field{ display:flex; flex-direction:column; gap:4px; }
.jhv-field > span{
  font-size:10.5px; text-transform:uppercase; letter-spacing:.06em;
  font-weight:700; color:var(--text-muted);
}
.jhv-field select{
  border:1px solid var(--border-strong); border-radius:8px; padding:7px 10px;
  font:inherit; font-size:13.5px; background:var(--surface); color:var(--text);
  min-height:38px;   /* a real tap target on a phone */
}
.jhv-field select:focus{ outline:2px solid var(--brand-yellow); outline-offset:1px; border-color:var(--brand-yellow); }
.jhv-sense{ font-size:13px; color:var(--text); flex:1 1 240px; }
.jhv-sense strong{ font-weight:700; }
.jhv-note{ font-size:12px; color:var(--text-muted); flex:1 1 100%; }
.pill-vat{ background:var(--brand-yellow); color:#111827; }
.pill-novat{ background:var(--info-bg); color:#4B5563; }
@media (max-width:760px){
  .jh-vat{ flex-direction:column; align-items:stretch; gap:8px; }
  .jhv-field select{ width:100%; }
}
