/* =============================================================================
   hyyryn-jobshell.css
   The three column job shell, built 18 Aug 2026 from the comp Sir supplied.
   Used by: inspect-release-homeowner, transaction-detail-active,
            raise-dispute-homeowner.
   Prefix is jsh- on purpose. js- was already taken by the job-summary block
   on inspect-release (.js-bar, .js-details, .jsd-label) and colliding there
   cost two deploy cycles last time.
   Assumes the host page already defines --cream --navy --green --gold --ink
   --muted --line --serif --sans.
============================================================================= */

.jsh-body { background: var(--cream); }

/* ---------- slim bar, replaces the marketing topbar on these pages -------- */
.jsh-bar {
  position: sticky; top: 0; z-index: 60;
  background: rgba(250,248,243,0.92); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.jsh-bar-inner {
  margin: 0 auto; padding: 14px var(--jsh-edge);
  display: flex; align-items: center; gap: 20px;
}
.jsh-bar .jsh-brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.jsh-bar .jsh-brand svg { width: 26px; height: 24px; display: block; }
.jsh-bar .jsh-brand span {
  font-family: var(--sans); font-size: 12px; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--navy);
}
.jsh-bar-spacer { flex: 1 1 auto; }
.jsh-assurebar { display: flex; align-items: center; gap: 10px; }
.jsh-assurebar svg { width: 17px; height: 17px; stroke: var(--navy); fill: none; stroke-width: 1.6; flex: none; }
.jsh-assurebar-t { font-family: var(--sans); font-size: 12.5px; font-weight: 600; color: var(--ink); line-height: 1.25; }
.jsh-assurebar-s { font-family: var(--sans); font-size: 11px; color: var(--muted); line-height: 1.25; }
.jsh-bar .nm-acct { flex: none; margin-left: 6px; }

/* ---------- step rail ---------------------------------------------------- */
.jsh-steps {
  margin: 0 auto; padding: 26px var(--jsh-edge) 4px;
  display: flex; align-items: center; justify-content: center; gap: 0;
}
.jsh-step { display: inline-flex; align-items: center; gap: 11px; flex: none; }
.jsh-step-num {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  font-family: var(--sans); font-size: 11px; font-weight: 600; letter-spacing: .04em;
  background: rgba(10,22,40,0.06); color: var(--muted);
}
.jsh-step-label { font-family: var(--sans); font-size: 13px; color: var(--muted); white-space: nowrap; }
.jsh-step.is-current .jsh-step-num { background: var(--gold, #83632C); color: #fff; }
.jsh-step.is-current .jsh-step-label { color: var(--ink); font-weight: 600; }
.jsh-step.is-done .jsh-step-num { background: var(--navy); color: #fff; }
.jsh-step.is-done .jsh-step-label { color: var(--ink); }
.jsh-step-line { flex: 0 1 120px; height: 1px; background: var(--line); margin: 0 16px; min-width: 24px; }

/* ---------- the grid ----------------------------------------------------- */
.jsh-grid {
  margin: 0 auto; padding: 26px var(--jsh-edge) 64px;
  display: grid;
  /* Same ratio as the trade profile's .pf-head, so a job page and a profile
     page read as the same object at the same scale. Sir's note, 18 Aug. */
  grid-template-columns: clamp(320px, 27vw, 480px) minmax(0,1fr) 360px;
  /* Gap matches the profile's too, so the channel between columns is the
     same width on both pages. */
  gap: clamp(24px, 2.4vw, 42px);
  align-items: start;
}

/* ---------- left, the navy counterparty panel ---------------------------- */
.jsh-side {
  background: var(--navy); color: var(--cream);
  border-radius: 16px; overflow: hidden;
  position: sticky; top: 88px;
  box-shadow: 0 1px 2px rgba(10,22,40,.05), 0 20px 44px -22px rgba(10,22,40,.30);
}
.jsh-side-photo {
  position: relative; min-height: 300px; display: flex; flex-direction: column;
  justify-content: space-between; padding: 26px 24px 22px;
  background-size: cover; background-position: center;
}
.jsh-side-photo::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,22,40,.72) 0%, rgba(10,22,40,.30) 42%, rgba(10,22,40,.86) 100%);
}
.jsh-side-photo > * { position: relative; }
.jsh-side-title {
  font-family: var(--serif); font-size: 25px; line-height: 1.18; color: #fff; font-weight: 400;
}
.jsh-side-sub {
  font-family: var(--sans); font-size: 11.5px; line-height: 1.5; color: rgba(250,248,243,.72); margin-top: 10px;
}
.jsh-side-chip {
  display: inline-flex; align-items: center; gap: 9px; align-self: flex-start;
  background: rgba(10,22,40,.62); border: 1px solid rgba(250,248,243,.22);
  backdrop-filter: blur(6px); border-radius: 999px; padding: 7px 15px 7px 7px;
}
.jsh-side-chip i {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(250,248,243,.14); flex: none;
}
.jsh-side-chip svg { width: 13px; height: 13px; stroke: #fff; fill: none; stroke-width: 1.7; }
.jsh-side-chip span { font-family: var(--sans); font-size: 12px; font-weight: 500; color: #fff; }

.jsh-side-body { padding: 24px 24px 26px; }
.jsh-side-h {
  font-family: var(--serif); font-size: 17px; line-height: 1.35; color: #fff; font-weight: 400; margin-bottom: 18px;
}
.jsh-why { display: grid; gap: 17px; }
.jsh-why-item { display: grid; grid-template-columns: 34px minmax(0,1fr); gap: 13px; align-items: start; }
.jsh-why-item i {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid rgba(250,248,243,.20); background: rgba(250,248,243,.05);
}
.jsh-why-item svg { width: 15px; height: 15px; stroke: rgba(250,248,243,.9); fill: none; stroke-width: 1.5; }
.jsh-why-t { font-family: var(--sans); font-size: 12.5px; font-weight: 600; color: #fff; margin-bottom: 3px; }
.jsh-why-d { font-family: var(--sans); font-size: 11.5px; line-height: 1.5; color: rgba(250,248,243,.62); }

.jsh-side-rule { height: 1px; background: rgba(250,248,243,.14); margin: 22px 0 18px; }
.jsh-side-quote {
  font-family: var(--serif); font-size: 13.5px; line-height: 1.6; color: rgba(250,248,243,.88);
}
.jsh-side-stars { display: flex; gap: 5px; margin-top: 13px; }
.jsh-side-stars svg { width: 13px; height: 13px; fill: var(--gold-soft, #D4A943); }

/* ---------- centre column ------------------------------------------------ */
.jsh-main {
  --jsh-pad: clamp(26px, 2.6vw, 42px);
  background: #fff; border-radius: 16px; padding: var(--jsh-pad); overflow: hidden;
  box-shadow: 0 1px 2px rgba(10,22,40,.05), 0 20px 44px -24px rgba(10,22,40,.20);
}
.jsh-main-h {
  font-family: var(--serif); font-size: clamp(30px, 2.7vw, 40px); line-height: 1.12;
  color: var(--ink); font-weight: 400; letter-spacing: -0.01em;
}
.jsh-main-sub { font-family: var(--sans); font-size: 14px; color: var(--muted); margin-top: 10px; }

.jsh-block {
  border: 1px solid var(--line); border-radius: 13px;
  padding: 22px clamp(18px, 1.8vw, 26px) 24px; margin-top: 22px;
  position: relative;
}
.jsh-block-head { display: grid; grid-template-columns: 40px minmax(0,1fr); gap: 15px; align-items: start; }
.jsh-block-head i {
  width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  background: var(--cream-2, #F3EFE4); flex: none;
}
.jsh-block-head svg { width: 17px; height: 17px; stroke: var(--navy); fill: none; stroke-width: 1.5; }
.jsh-block-t { font-family: var(--serif); font-size: 18px; color: var(--ink); font-weight: 400; }
.jsh-block-d { font-family: var(--sans); font-size: 12.5px; color: var(--muted); margin-top: 4px; line-height: 1.5; }
.jsh-block-body { margin-top: 18px; }

/* field boxes, label floating above the value inside the outline */
.jsh-fields {
  display: grid; gap: 12px;
  /* 210px missed a two-up by 8px once the centre column narrowed to the
     profile ratio, so every field stacked. Measured: 424px of usable width
     inside the block, two 210s plus the gap wanted 432. */
  grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
}
.jsh-field {
  border: 1px solid var(--line); border-radius: 11px; padding: 9px 14px 10px;
  display: grid; grid-template-columns: auto minmax(0,1fr) auto; gap: 11px; align-items: center;
  background: #fff; min-height: 56px;
}
.jsh-field > svg { width: 16px; height: 16px; stroke: var(--muted); fill: none; stroke-width: 1.5; }
.jsh-field-in { min-width: 0; }
.jsh-field-l {
  font-family: var(--sans); font-size: 9px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); display: block; margin-bottom: 2px;
}
.jsh-field-v {
  font-family: var(--sans); font-size: 13.5px; color: var(--ink); line-height: 1.35;
  /* Values WRAP, they do not truncate. In the narrower column the address came
     out as "14 Woburn Sands ..." and a half address is worse than two lines. */
  overflow-wrap: anywhere;
}
.jsh-field-ok svg { width: 15px; height: 15px; stroke: var(--green); fill: none; stroke-width: 2; }
.jsh-field--wide { grid-column: 1 / -1; }

/* footer row of the centre column */
.jsh-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  margin-top: 26px; flex-wrap: wrap;
}
.jsh-back {
  display: inline-flex; align-items: center; gap: 9px; text-decoration: none;
  font-family: var(--sans); font-size: 13px; color: var(--muted);
}
.jsh-back svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.6; }
.jsh-back:hover { color: var(--ink); }
.jsh-cta {
  display: inline-flex; align-items: center; gap: 12px; border: 0; cursor: pointer;
  background: var(--navy); color: #fff; border-radius: 999px;
  padding: 16px 28px; font-family: var(--sans); font-size: 14px; font-weight: 600;
  box-shadow: 0 1px 2px rgba(10,22,40,.10), 0 14px 30px -14px rgba(10,22,40,.55);
  transition: transform .18s ease, box-shadow .18s ease;
}
.jsh-cta:hover { transform: translateY(-1px); box-shadow: 0 1px 2px rgba(10,22,40,.10), 0 18px 36px -14px rgba(10,22,40,.62); }
.jsh-cta svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.jsh-cta[disabled] { opacity: .45; cursor: not-allowed; transform: none; box-shadow: none; }
.jsh-cta--danger { background: var(--danger, #C0392B); }
.jsh-cta--green { background: var(--green); }
/* one plain sentence under the button, the MUJI and Uniqlo move */
.jsh-consequence {
  font-family: var(--sans); font-size: 11.5px; line-height: 1.55; color: var(--muted);
  margin-top: 12px; text-align: right;
}

/* ---------- right rail --------------------------------------------------- */
.jsh-rail { position: sticky; top: 88px; display: grid; gap: 18px; }
.jsh-card {
  background: #fff; border-radius: 16px; padding: 24px 24px 26px;
  box-shadow: 0 1px 2px rgba(10,22,40,.05), 0 20px 44px -24px rgba(10,22,40,.20);
}
.jsh-card-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 20px; }
.jsh-card-t { font-family: var(--serif); font-size: 18px; color: var(--ink); font-weight: 400; }
.jsh-pill {
  border: 1px solid var(--line); background: #fff; border-radius: 999px;
  padding: 7px 16px; font-family: var(--sans); font-size: 12px; color: var(--ink);
  text-decoration: none; cursor: pointer;
}
.jsh-pill:hover { border-color: rgba(10,22,40,.24); }

.jsh-item { display: grid; grid-template-columns: 84px minmax(0,1fr); gap: 15px; align-items: start; }
.jsh-item-ph { width: 84px; height: 84px; border-radius: 10px; overflow: hidden; background: var(--cream-2, #F3EFE4); }
.jsh-item-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.jsh-item-t { font-family: var(--sans); font-size: 14.5px; font-weight: 600; color: var(--ink); }
.jsh-item-by { font-family: var(--sans); font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.jsh-item-rows { margin-top: 11px; display: grid; gap: 7px; }
.jsh-item-row { display: flex; align-items: center; gap: 9px; font-family: var(--sans); font-size: 12.5px; color: var(--ink); }
.jsh-item-row svg { width: 14px; height: 14px; stroke: var(--muted); fill: none; stroke-width: 1.5; flex: none; }

.jsh-rule { height: 1px; background: var(--line); margin: 20px 0 16px; }
.jsh-rule--heavy { height: 1px; background: rgba(10,22,40,.16); margin: 16px 0; }
.jsh-sum { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 6px 0; }
.jsh-sum-l { font-family: var(--sans); font-size: 13px; color: var(--muted); }
.jsh-sum-v { font-family: var(--sans); font-size: 13px; color: var(--ink); font-variant-numeric: tabular-nums; }
.jsh-total { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.jsh-total-l { font-family: var(--serif); font-size: 18px; color: var(--ink); }
.jsh-total-v { font-family: var(--serif); font-size: 27px; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
/* tax as a memo row under the total, the Uniqlo move, not fused into it */
.jsh-memo {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  font-family: var(--sans); font-size: 11.5px; color: var(--muted); margin-top: 7px;
}

/* the protection block, the Fiido move */
.jsh-protect {
  margin-top: 20px; border-radius: 11px; background: var(--cream-2, #F3EFE4);
  padding: 15px 16px; display: grid; grid-template-columns: 22px minmax(0,1fr); gap: 12px; align-items: start;
}
.jsh-protect > svg { width: 20px; height: 20px; stroke: var(--green); fill: none; stroke-width: 1.5; margin-top: 1px; }
.jsh-protect-t { font-family: var(--sans); font-size: 12.5px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.jsh-protect-d { font-family: var(--sans); font-size: 11.5px; line-height: 1.55; color: var(--muted); }

.jsh-pay { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; margin-top: 18px; }
.jsh-pay div {
  border: 1px solid var(--line); border-radius: 9px; height: 38px;
  display: grid; place-items: center; background: #fff; padding: 0 4px;
  font-family: var(--sans); font-size: 8.5px; font-weight: 700; letter-spacing: .06em;
  color: var(--muted); text-align: center; line-height: 1.15;
}

/* the cream reassurance card that sits under the rail */
.jsh-assure {
  background: var(--cream-2, #F3EFE4); border-radius: 16px; padding: 26px 24px 24px; position: relative; overflow: hidden;
}
.jsh-assure-t { font-family: var(--serif); font-size: 21px; line-height: 1.25; color: var(--ink); font-weight: 400; }
.jsh-assure-d { font-family: var(--sans); font-size: 12.5px; line-height: 1.65; color: var(--muted); margin-top: 14px; max-width: 30ch; }
.jsh-assure-sign { font-family: var(--serif); font-size: 19px; color: var(--ink); margin-top: 24px; }
.jsh-assure-who { font-family: var(--sans); font-size: 11.5px; color: var(--muted); margin-top: 5px; }
.jsh-seal {
  position: absolute; right: 16px; bottom: 16px; width: 82px; height: 82px; opacity: .6; pointer-events: none;
}
.jsh-seal svg { width: 100%; height: 100%; }

/* ---------- responsive --------------------------------------------------- */
@media (max-width: 1180px) {
  /* Profile breakpoints, not my old 1240. Same page, same behaviour. */
  .jsh-grid { grid-template-columns: clamp(280px, 34vw, 400px) minmax(0,1fr); gap: 32px; }
  .jsh-rail { grid-column: 1 / -1; position: static; margin-top: 8px; }
}
@media (max-width: 720px) {
  .jsh-grid { grid-template-columns: minmax(0,1fr); gap: 24px; }
  .jsh-col, .jsh-side { position: static; }
  .jsh-rail { position: static; }
  .jsh-steps { justify-content: flex-start; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 10px; }
  .jsh-step-line { flex-basis: 44px; margin: 0 10px; }
  .jsh-foot { flex-direction: column-reverse; align-items: stretch; }
  .jsh-cta { justify-content: center; }
  .jsh-back { justify-content: center; }
  .jsh-consequence { text-align: center; }
}
@media (max-width: 560px) {
  .jsh-assurebar-s { display: none; }
  .jsh-main { padding: 22px 18px 26px; }
  .jsh-fields { grid-template-columns: minmax(0,1fr); }
}

/* ---------- milestone list, used on the live job page -------------------- */
.jsh-mile { list-style: none; margin: 0; padding: 0; position: relative; }
.jsh-mile li {
  display: grid; grid-template-columns: 22px minmax(0,1fr); gap: 14px;
  padding: 0 0 20px; position: relative;
}
.jsh-mile li::before {
  content: ''; position: absolute; left: 10px; top: 18px; bottom: 0; width: 1px; background: var(--line);
}
.jsh-mile li:last-child { padding-bottom: 0; }
.jsh-mile li:last-child::before { display: none; }
.jsh-mile-dot {
  width: 21px; height: 21px; border-radius: 50%; margin-top: 1px;
  border: 1px solid var(--line); background: #fff; display: block; position: relative; z-index: 1;
}
.jsh-mile li.is-done .jsh-mile-dot { background: var(--navy); border-color: var(--navy); }
.jsh-mile li.is-done .jsh-mile-dot::after {
  content: ''; position: absolute; left: 6px; top: 6px; width: 8px; height: 5px;
  border-left: 1.6px solid #fff; border-bottom: 1.6px solid #fff; transform: rotate(-45deg);
}
.jsh-mile li.is-current .jsh-mile-dot {
  border-color: var(--gold, #83632C); box-shadow: 0 0 0 3px rgba(184,148,31,.16);
}
.jsh-mile li.is-current .jsh-mile-dot::after {
  content: ''; position: absolute; inset: 5px; border-radius: 50%; background: var(--gold, #83632C);
}
.jsh-mile-t { font-family: var(--sans); font-size: 13.5px; font-weight: 600; color: var(--ink); }
.jsh-mile li:not(.is-done):not(.is-current) .jsh-mile-t { font-weight: 500; color: var(--muted); }
.jsh-mile-d { font-family: var(--sans); font-size: 12px; color: var(--muted); margin-top: 3px; line-height: 1.5; }

/* a field box used as a link */
a.jsh-field { transition: border-color .16s ease, background .16s ease; }
a.jsh-field:hover { border-color: rgba(10,22,40,.22); background: var(--cream); }

/* ---------- dispute variant of the left panel ---------------------------- */
/* No photograph. Somebody raising a dispute does not want the tradesperson
   sold to them again, so this variant carries the clock and the process. */
.jsh-side--plain .jsh-side-body { padding-top: 26px; }
.jsh-clock { }
.jsh-clock-l {
  font-family: var(--sans); font-size: 9px; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: rgba(250,248,243,.55);
}
.jsh-clock-v { font-family: var(--serif); font-size: 38px; color: #fff; margin-top: 8px; letter-spacing: -0.01em; }
.jsh-clock-s { font-family: var(--sans); font-size: 11.5px; line-height: 1.55; color: rgba(250,248,243,.62); margin-top: 10px; }

/* the dispute form, dropped inside a jsh-block body */
.jsh-form { display: block; }
.jsh-form .form-group { margin-top: 18px; }
.jsh-form .form-group:first-of-type { margin-top: 0; }

/* =============================================================================
   18 AUG 2026, second pass on Sir's notes:
   collapse each step into a dropdown, make the header one sticky unit,
   navy footer, and animate the rail and the progress list.
============================================================================= */

:root {
  --jsh-head: 116px;
  /* Same gutter token as the trade profile's --edge. The profile is FULL BLEED
     with only this for padding, which is why its photograph starts 28px from
     the window edge and ours started 214px: we were boxed at 1560 and centred,
     so 186px of dead margin sat to the left of the picture. */
  --jsh-edge: clamp(16px, 1.6vw, 28px);
}

/* ---------- header, bar and rail as one sticky block --------------------- */
.jsh-head {
  position: sticky; top: 0; z-index: 60;
  background: rgba(250,248,243,0.94); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.jsh-head .jsh-bar { position: static; background: none; backdrop-filter: none; border-bottom: 0; }
.jsh-head .jsh-steps { padding-top: 4px; padding-bottom: 16px; }
/* the columns clear the whole header, not just the bar */
.jsh-side, .jsh-rail { top: calc(var(--jsh-head) + 16px); }

/* ---------- the rail draws itself in on load ----------------------------- */
.jsh-step { opacity: 0; animation: jshStepIn .5s cubic-bezier(.16,1,.3,1) forwards; }
.jsh-step:nth-of-type(1) { animation-delay: .05s; }
.jsh-steps > .jsh-step:nth-child(3)  { animation-delay: .16s; }
.jsh-steps > .jsh-step:nth-child(5)  { animation-delay: .27s; }
.jsh-steps > .jsh-step:nth-child(7)  { animation-delay: .38s; }
.jsh-steps > .jsh-step:nth-child(9)  { animation-delay: .49s; }
@keyframes jshStepIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.jsh-step-line { transform: scaleX(0); transform-origin: left center; animation: jshLine .42s ease forwards; }
.jsh-steps > .jsh-step-line:nth-child(2) { animation-delay: .12s; }
.jsh-steps > .jsh-step-line:nth-child(4) { animation-delay: .23s; }
.jsh-steps > .jsh-step-line:nth-child(6) { animation-delay: .34s; }
.jsh-steps > .jsh-step-line:nth-child(8) { animation-delay: .45s; }
@keyframes jshLine { to { transform: scaleX(1); } }

/* the stage you are actually on keeps a slow breath so the eye finds it */
.jsh-step.is-current .jsh-step-num { position: relative; }
.jsh-step.is-current .jsh-step-num::after {
  content: ''; position: absolute; inset: -4px; border-radius: 50%;
  border: 1px solid rgba(184,148,31,.55); animation: jshPulse 2.8s ease-in-out infinite;
}
@keyframes jshPulse {
  0%, 100% { opacity: .55; transform: scale(1); }
  50%      { opacity: 0;   transform: scale(1.22); }
}

/* ---------- each step is a dropdown -------------------------------------- */
details.jsh-block { padding: 0; overflow: hidden; }
details.jsh-block > summary {
  list-style: none; cursor: pointer; padding: 22px clamp(18px, 1.8vw, 26px);
  display: grid; grid-template-columns: 40px minmax(0,1fr) 18px; gap: 15px; align-items: center;
  transition: background .16s ease;
}
details.jsh-block > summary::-webkit-details-marker { display: none; }
details.jsh-block > summary:hover { background: rgba(10,22,40,.018); }
details.jsh-block > summary:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; }
.jsh-chev { display: grid; place-items: center; transition: transform .32s cubic-bezier(.16,1,.3,1); }
.jsh-chev svg { width: 15px; height: 15px; stroke: var(--muted); fill: none; stroke-width: 1.7; display: block; }
details.jsh-block[open] > summary .jsh-chev { transform: rotate(180deg); }

/* height animation. details cannot tween on its own, so the body is a grid
   whose single row goes 0fr to 1fr and the script holds `open` until the
   closing transition has finished. */
details.jsh-block > .jsh-block-body {
  margin-top: 0; display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .36s cubic-bezier(.16,1,.3,1);
}
details.jsh-block[open] > .jsh-block-body { grid-template-rows: 1fr; }
.jsh-block-inner { overflow: hidden; min-height: 0; padding: 0 clamp(18px, 1.8vw, 26px) 24px; }

/* ---------- the progress list deals itself out when the step opens -------- */
details.jsh-block[open] .jsh-mile li { animation: jshRise .44s cubic-bezier(.16,1,.3,1) both; }
.jsh-mile li:nth-child(1) { animation-delay: .04s; }
.jsh-mile li:nth-child(2) { animation-delay: .10s; }
.jsh-mile li:nth-child(3) { animation-delay: .16s; }
.jsh-mile li:nth-child(4) { animation-delay: .22s; }
.jsh-mile li:nth-child(5) { animation-delay: .28s; }
.jsh-mile li:nth-child(6) { animation-delay: .34s; }
@keyframes jshRise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* the line between the dots draws down behind them */
details.jsh-block[open] .jsh-mile li::before { animation: jshDrop .5s ease both; transform-origin: top center; }
@keyframes jshDrop { from { transform: scaleY(0); } to { transform: scaleY(1); } }

@media (prefers-reduced-motion: reduce) {
  .jsh-step, .jsh-step-line, .jsh-mile li, .jsh-mile li::before { animation: none !important; opacity: 1 !important; transform: none !important; }
  .jsh-step.is-current .jsh-step-num::after { animation: none; }
  details.jsh-block > .jsh-block-body { transition: none; }
}

/* ---------- navy footer, matching the homepage --------------------------- */
.jsh-body .site-footer {
  background: var(--navy); color: rgba(250,248,243,.65);
  border-top: 1px solid rgba(250,248,243,.08);
}
.jsh-body .fb-logo span { color: rgba(250,248,243,.92); }
.jsh-body .fb-logo svg rect { fill: #FAF8F3; }
.jsh-body .fb-tagline { color: rgba(250,248,243,.55); }
.jsh-body .footer-col h4 { color: rgba(250,248,243,0.55); }
.jsh-body .footer-col a { color: rgba(250,248,243,.60); opacity: 1; }
.jsh-body .footer-col a:hover { color: rgba(250,248,243,.95); }
.jsh-body .footer-bottom { border-top: 1px solid rgba(250,248,243,.10); color: rgba(250,248,243,0.55); }
.jsh-body .footer-bottom a { color: rgba(250,248,243,.55); }
.jsh-body .footer-bottom a:hover { color: rgba(250,248,243,.9); }

/* the script drives data-open so the closing tween has time to run */
details.jsh-block[open] > .jsh-block-body { grid-template-rows: 0fr; }
details.jsh-block[open][data-open] > .jsh-block-body { grid-template-rows: 1fr; }

/* The off-canvas profile drawer is fixed at right:-340px and Chrome counts it
   in the document scroll width, which put a horizontal scrollbar on every page
   that carries it. `clip` kills the scroll without turning the body into a
   scroll container, which `hidden` would, and which would break every sticky
   on the page. */
.jsh-body { overflow-x: clip; }
/* overflow on the body does NOT clip a position:fixed descendant, its
   containing block is the viewport. The rule has to sit on the root, where it
   propagates to the viewport. This sheet only loads on job shell pages so it
   is safely scoped. clip, not hidden: hidden would make the root a scroll
   container and kill every sticky. */
html { overflow-x: clip; }

/* ---------- the amber escape hatch --------------------------------------- */
/* Sir asked for Raise it formally to be picked out. Gold is already the
   attention tone in this system (the Awaiting your approval group on my-jobs
   is tinted with it), so it reads as the same signal rather than a new one.
   The text tones are darkened well past --gold because 9px letter-spaced caps
   at #83632C on a pale gold ground do not carry enough contrast. */
a.jsh-field--warn {
  border-color: rgba(184,148,31,.45);
  background: rgba(212,169,67,.12);
}
a.jsh-field--warn:hover {
  border-color: rgba(184,148,31,.78);
  background: rgba(212,169,67,.19);
}
a.jsh-field--warn > svg { stroke: #9A7A18; }
a.jsh-field--warn .jsh-field-l { color: #7A5F14; }
a.jsh-field--warn .jsh-field-v { color: #5E4A10; font-weight: 600; }

/* =============================================================================
   Left column split, 18 Aug 2026. Sir asked for the profile picture and the
   "Where Daniel is up to" list to stop being one object, and for the photo to
   be squared with a single curved top-left, the same move the trade profile
   already makes on .pf-media img.
============================================================================= */
.jsh-col {
  position: sticky; top: calc(var(--jsh-head) + 16px);
  display: grid; gap: clamp(14px, 1.3vw, 20px); align-content: start;
}
.jsh-col > .jsh-side { position: static; top: auto; }

.jsh-face {
  position: relative; overflow: hidden; background: var(--navy);
  border: 1px solid var(--line);
  /* square everywhere, one big curve top left. Same clamp as .pf-media img. */
  border-radius: clamp(48px, 9vw, 132px) 0 0 0;
  box-shadow: 0 1px 2px rgba(10,22,40,.05), 0 20px 44px -24px rgba(10,22,40,.28);
}
.jsh-face > img { width: 100%; aspect-ratio: 1/1; object-fit: cover; display: block; }
.jsh-face-veil {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(10,22,40,.30) 0%, rgba(10,22,40,.05) 34%, rgba(10,22,40,.86) 100%);
}
/* the name sits at the FOOT of the picture. Top left is where the curve is,
   and type in a corner that is being cut away reads as a mistake. */
.jsh-face-body { position: absolute; left: 24px; right: 24px; bottom: 22px; }
.jsh-face-body .jsh-side-title { font-size: 26px; }
.jsh-face-body .jsh-side-sub { margin-top: 8px; }
.jsh-face > .jsh-side-chip { position: absolute; right: 18px; top: 18px; }

@media (max-width: 720px) {
  .jsh-face > img { aspect-ratio: 16/10; }
  .jsh-face { border-radius: clamp(32px, 12vw, 64px) 0 0 0; }
}

/* =============================================================================
   Progress panel, 18 Aug 2026. Sir: fold the "Where Daniel is up to" card into
   step two, revamp it, drop the green, add a visualiser and a slight ground.
============================================================================= */
.jsh-prog {
  background: var(--cream-2, #F3EFE4);
  border: 1px solid rgba(10,22,40,.05);
  border-radius: 12px;
  padding: 20px clamp(16px, 1.6vw, 22px) 22px;
}

.jsh-prog-top {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 18px;
  margin-bottom: 13px;
}
.jsh-prog-now { font-family: var(--sans); font-size: 13.5px; font-weight: 600; color: var(--ink); }
.jsh-prog-sub { font-family: var(--sans); font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.jsh-prog-count {
  font-family: var(--sans); font-size: 11px; color: var(--muted); white-space: nowrap; padding-top: 2px;
}
.jsh-prog-count strong { font-family: var(--serif); font-size: 21px; color: var(--ink); font-weight: 400; }

/* One tick per stage, so the bar IS the list rather than a separate
   abstraction of it. Filled ticks are navy, the live one is gold, and gold is
   the only place colour lands in this panel. */
.jsh-meter { display: flex; gap: 4px; }
.jsh-meter span {
  flex: 1; height: 6px; border-radius: 3px; background: rgba(10,22,40,.10);
  transform: scaleX(0); transform-origin: left center;
  animation: jshTick .38s cubic-bezier(.16,1,.3,1) forwards;
}
.jsh-meter span:nth-child(1) { animation-delay: .04s; }
.jsh-meter span:nth-child(2) { animation-delay: .09s; }
.jsh-meter span:nth-child(3) { animation-delay: .14s; }
.jsh-meter span:nth-child(4) { animation-delay: .19s; }
.jsh-meter span:nth-child(5) { animation-delay: .24s; }
.jsh-meter span:nth-child(6) { animation-delay: .29s; }
.jsh-meter span:nth-child(7) { animation-delay: .34s; }
.jsh-meter span:nth-child(8) { animation-delay: .39s; }
@keyframes jshTick { to { transform: scaleX(1); } }
.jsh-meter span.on  { background: var(--navy); }
.jsh-meter span.now {
  background: var(--gold, #83632C);
  box-shadow: 0 0 0 3px rgba(184,148,31,.18);
}

.jsh-prog .jsh-mile { margin-top: 22px; padding-top: 20px; border-top: 1px solid rgba(10,22,40,.08); }
.jsh-prog .jsh-mile li::before { background: rgba(10,22,40,.14); }
.jsh-prog .jsh-mile-dot { background: var(--cream-2, #F3EFE4); }

@media (prefers-reduced-motion: reduce) {
  .jsh-meter span { animation: none !important; transform: none !important; }
}

/* ---------- the title gets its own ground ------------------------------- */
/* Bleeds to the card edges with a negative margin of the card's own padding,
   which is why that padding is a variable rather than an inline clamp. */
.jsh-main-head {
  margin: calc(-1 * var(--jsh-pad)) calc(-1 * var(--jsh-pad)) 26px;
  padding: var(--jsh-pad) var(--jsh-pad) calc(var(--jsh-pad) - 6px);
  background: var(--cream-2, #F3EFE4);
  border-bottom: 1px solid rgba(10,22,40,.06);
  /* Depth on the two vertical edges. The band bleeds to the card edges and the
     card clips its overflow, so an outer drop shadow would be cut off the
     moment it left the band. INSET is the only shadow that can live here, and
     it reads better anyway: the band appears to roll away at the sides rather
     than float above the card. A hairline of light along the top lifts it. */
  box-shadow:
    inset 20px 0 28px -22px rgba(10,22,40,.50),
    inset -20px 0 28px -22px rgba(10,22,40,.50),
    inset 0 1px 0 rgba(255,255,255,.55);
}
.jsh-main-head .jsh-main-sub { max-width: 62ch; }

/* ---------- the money card answers the picture card --------------------- */
/* The photograph curves top LEFT at the far left of the page. This curves top
   RIGHT at the far right. Two statement corners, one at each outer edge, with
   everything between them square. */
.jsh-card--corner { border-radius: 0 clamp(40px, 7vw, 104px) 0 0; }

/* ---------- compact search in the bar ------------------------------------ */
/* .nm-mini is absolutely centred (position:absolute; left:50%) exactly as it is
   on the profile and the results page, so the bar row needs to be its
   containing block or it would centre on the viewport instead. */
.jsh-bar-inner { position: relative; }
/* With the flexible spacer gone, the assurance block and the account control
   are pushed right by auto margin rather than by an empty div. */
.jsh-assurebar { margin-left: auto; }

/* ---------- pages with no stage rail under the bar ----------------------- */
/* Sir removed the five stage count from job-live. Custom properties inherit,
   so a class on <body> is enough to retune every sticky offset on the page. */
.jsh-norail { --jsh-head: 66px; }   /* measured: the bar alone is 65px */

/* The photographic page ground moved to assets/hyyryn-ground.css the moment a
   second page wanted it. A wash copied into two files is a wash that drifts.
   Pages opt in with class="hy-ground" on <body>. */

/* ---------- latest update, under the picture ----------------------------- */
/* The most valuable thing on a live job page is what the tradesperson last
   said and when. Without it the Message button is a cold start; with it, it is
   a reply. */
.jsh-latest {
  background: #fff; border-radius: 14px; padding: 18px 20px 16px;
  box-shadow: 0 1px 2px rgba(10,22,40,.05), 0 20px 44px -26px rgba(10,22,40,.24);
}
.jsh-latest-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.jsh-latest-label {
  font-family: var(--sans); font-size: 9px; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted);
}
.jsh-latest-time { font-family: var(--sans); font-size: 11px; color: var(--muted); white-space: nowrap; }
.jsh-latest-msg {
  font-family: var(--serif); font-size: 14px; line-height: 1.6; color: var(--ink); margin-top: 11px;
}
.jsh-latest-reply {
  display: inline-flex; align-items: center; gap: 9px; margin-top: 15px; text-decoration: none;
  font-family: var(--sans); font-size: 12.5px; font-weight: 600; color: var(--ink);
  border: 1px solid var(--line); border-radius: 999px; padding: 9px 16px;
  transition: border-color .16s ease, background .16s ease;
}
.jsh-latest-reply svg { width: 14px; height: 14px; stroke: var(--muted); fill: none; stroke-width: 1.6; }
.jsh-latest-reply:hover { border-color: rgba(10,22,40,.24); background: var(--cream); }

/* ---------- compact search styles, moved here from the pages -------------- */
/* raise-dispute never had a compact search, so its inline stylesheet had no
   .nm-mini rules at all and the form I added rendered completely unstyled.
   Caught by serving the three pages locally rather than by reading them. The
   rules live here now so any page that carries the shell gets the search
   whether or not its own <style> block knows about it. */
.jsh-bar .nm-mini {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: min(430px, 34vw); display: flex; align-items: center; height: 40px;
  padding: 0 5px 0 15px; background: #fff; border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(10,22,40,.04), 0 10px 26px -18px rgba(10,22,40,.45);
}
.jsh-bar .nm-mini-icon {
  width: 15px; height: 15px; flex: none; fill: none; stroke: var(--muted);
  stroke-width: 1.7; stroke-linecap: round; margin-right: 10px;
}
.jsh-bar .nm-mini input {
  min-width: 0; border: 0; background: none; outline: none; padding: 0;
  font-family: var(--sans); font-size: 13px; color: var(--ink);
}
.jsh-bar .nm-mini input::placeholder { color: var(--muted); opacity: .75; }
.jsh-bar .nm-mini #miniQ { flex: 1 1 auto; }
.jsh-bar .nm-mini #miniLoc { flex: 0 0 84px; }
.jsh-bar .nm-mini-div { width: 1px; height: 18px; background: var(--line); margin: 0 12px; flex: none; }
.jsh-bar .nm-mini-go {
  flex: none; width: 32px; height: 32px; margin-left: 8px; display: grid;
  place-items: center; cursor: pointer; background: var(--navy); border: 0;
  border-radius: 50%; transition: background .2s ease;
}
.jsh-bar .nm-mini-go svg {
  width: 15px; height: 15px; fill: none; stroke: var(--cream);
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.jsh-bar .nm-mini-go:hover { background: #0E1E34; }
@media (max-width: 900px) { .jsh-bar .nm-mini { display: none; } }
