/* ============================================================
   PASSAGE — preview-then-send panel. All classes prefixed `pv-`.

   Mobile-first, same breakpoints as fees.css/mobile-*.css rather than
   new ones. The document itself is rendered inside a sandboxed iframe,
   so nothing in here can style it and nothing in it can style the app —
   that separation is the whole reason the frame exists.
   ============================================================ */

/* A retainer agreement is an A4 legal document; the 860px modal that suits
   a form leaves it about 520px of column once the send rail is taken out,
   and at that width the clauses are a narrow ribbon. Widen the card ONLY
   when it is hosting this panel — :has() scopes it to the preview and
   leaves every other modal in the app at its own width. Browsers without
   :has() simply keep the 860px card, which is what this shipped with.

   Held above 760px deliberately: styles.css turns every modal into a
   full-width bottom sheet below that, and this rule outranks it on
   specificity — left unscoped it re-widths the sheet and leaves a strip of
   background down the right edge of a phone. */
@media (min-width:761px){
  .m-card.wide:has(.pv){ width:min(1140px,96vw); }
}

.pv{ display:grid; grid-template-columns:1fr; gap:14px; }

/* Grid items take a content-based min-width by default. A retainer
   letterhead is laid out for A4, so without this the document track
   grows past its 1fr share and the whole modal scrolls sideways —
   the same trap fees.css already documents for .fee-panel. */
.pv > *{ min-width:0; }

/* Document left, send controls in a right rail. 820px is the width at
   which a 268px rail still leaves the page a readable measure; below
   it the two stack, document first. */
@media (min-width:820px){
  .pv{ grid-template-columns:minmax(0,1fr) 268px; align-items:start; }
}

/* ---------- the document ----------

   Three layers, and each one earns its place:

     .pv-doc    the surface the page rests on — a shade darker than the
                modal, so the page has something to sit ON rather than
                being flush against the panel;
     .pv-page   the page itself: bordered, lifted, and PADDED. The padding
                is the fix for "it looks very tight" — the agreement's own
                stylesheet gives its body 4px of side margin, because the
                PDF's printed page margin supplies the rest. On screen
                nothing did, so the clauses ran into the frame edge. The
                frame is sandboxed and this file will not reach into a
                legal document to restyle it, so the margin is made here,
                around the frame;
     .pv-frame  the sandboxed document, scrolling inside itself so the
                Send button never moves while the consultant reads. */
.pv-doc{
  min-width:0; border:1px solid var(--stroke); border-radius:var(--r-lg);
  background:var(--bone-2); overflow:hidden;
  padding:10px;
}
.pv-page{
  min-width:0; background:var(--paper);
  border:1px solid var(--stroke-soft); border-radius:var(--r-md);
  box-shadow:var(--shadow);
  padding:12px;
  /* An A4 page is ~800px of measure at this type size, which is also where
     the document's own layout stops growing. Past that the page is centred
     rather than stretched, so a wide screen gives margins, not longer
     lines. */
  max-width:880px; margin:0 auto;
  /* Clip the frame's square corners to the page's radius. */
  overflow:hidden;
}
.pv-frame{
  display:block; width:100%; border:0; background:transparent;
  /* The document paints its own white ground over the whole frame. Rounding
     the frame stops that ground meeting the page's warm paper in four hard
     square corners inside a rounded page. */
  border-radius:var(--r-sm);
  /* An A4 page letterboxed into a strip is unreadable, which is exactly
     the complaint this panel exists to answer. Give it real height and
     let it scroll inside itself — scrolling the document then never
     moves the Send button. */
  height:46dvh; min-height:260px;
}
@media (min-width:820px){
  .pv-doc{ padding:20px; }
  .pv-page{ padding:24px 26px; }
  /* Taller than the old 58vh: the card is 88vh and the rail beside it is
     short, so the space was there and the document was not using it. */
  .pv-frame{ height:clamp(420px, 62vh, 820px); }
}
/* The loading line and the honest failure message. They stand where the
   page stands, so the panel never opens on a bare coloured slab. */
.pv-doc-msg{
  background:var(--paper); border:1px solid var(--stroke-soft);
  border-radius:var(--r-md); box-shadow:var(--shadow);
  max-width:880px; margin:0 auto;
  padding:22px 20px; font-size:13.5px; color:var(--ink-soft); line-height:1.6;
}
.pv-doc-msg b{ color:var(--ink); }
.pv-doc-msg code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12.5px;
  background:var(--bone-2); border-radius:6px; padding:1px 5px;
}

/* ---------- the send rail ---------- */
.pv-rail{ min-width:0; display:flex; flex-direction:column; gap:12px; }
@media (min-width:820px){
  /* The modal card is the scroll container; sticking the rail to its top
     keeps Send in view no matter how long the sidebar copy gets. */
  .pv-rail{ position:sticky; top:0; }
}

.pv-block{
  border:1px solid var(--stroke-soft); border-radius:var(--r-md);
  background:var(--bone); padding:11px 13px; min-width:0;
}
.pv-k{
  font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-faint); font-weight:600; margin-bottom:4px;
}
.pv-v{ font-size:14px; font-weight:600; color:var(--ink); overflow-wrap:anywhere; }
.pv-v-sub{ font-size:13px; color:var(--ink-soft); overflow-wrap:anywhere; margin-top:2px; }
.pv-amount{ font-family:var(--disp); font-size:22px; font-weight:800; color:var(--gold-deep); }
.pv-subject{ font-size:13.5px; color:var(--ink); line-height:1.5; overflow-wrap:anywhere; }
/* .hint has no bare rule anywhere in the app — it is always scoped by its
   container, as in styles.css `.panel-title .hint`. Scope it here the same
   way so it reads as a note beside the subject, not as body copy. */
.pv-block .hint{ font-size:12px; color:var(--ink-faint); margin-top:5px; }

/* ---------- actions ---------- */
.pv-act{ display:flex; flex-direction:column; gap:8px; }
/* .btn is inline-ish by default; the rail mixes <button> and the <a>
   download link, so both are forced to the same block shape. */
.pv-act .btn{ display:block; width:100%; text-align:center; }

@media (max-width:819px){
  /* Stacked layout puts the rail below a 46dvh document. Pinning the
     action bar to the bottom of the scrolling card keeps Send within
     thumb reach once it has scrolled into view, instead of it sitting
     at the far end of a long sheet. */
  .pv-act{
    position:sticky; bottom:0; z-index:2;
    background:var(--paper); padding:10px 0 2px;
    border-top:1px solid var(--stroke-soft);
    /* The card's own bottom padding is not a barrier — content scrolls
       underneath it and reappears below the pinned bar. A zero-blur
       shadow paints that strip in paper without taking any layout space
       or hard-coding the card's padding value. */
    box-shadow:0 26px 0 var(--paper);
  }
}

/* ---------- outcome ---------- */
/* Two states, never a third: what the server confirmed, or the error the
   server actually returned. Nothing here reports success on its own. */
/* The rail is a flex column with a gap; an empty result host would
   otherwise open a gap above the actions before anything is sent. */
.pv-result-host:empty{ display:none; }
.pv-result{
  border-radius:var(--r-md); padding:11px 13px; font-size:13.5px; line-height:1.55;
  overflow-wrap:anywhere;
}
.pv-result-ok{
  background:var(--bone); border:1px solid var(--green-soft); color:var(--green);
}
.pv-result-err{
  background:var(--bone); border:1px solid var(--red-soft); color:var(--red);
}
.pv-result b{ font-weight:700; }

/* ============================================================
   THE JOB OFFER DIALOG — the half of the flow that comes BEFORE the
   panel above. All classes prefixed `jo-`.

   It lives in this file because it is one flow with one shape: fill it
   in, press Preview, read the document, send it. The form itself borrows
   the Documents & signing field classes (.dt-sec / .dt-lbl / .dt-in /
   .dt-from / .dt-req) rather than restating them, so a contract read in
   this dialog and the same contract read in that module look the same.
   Only what is genuinely new here is defined below.

   Mobile-first: every rule holds at 390px, and the two that need more
   room are behind the same 761px breakpoint styles.css uses to stop
   turning modals into bottom sheets.
   ============================================================ */

/* ---------- which filing this contract belongs to ---------- */
.jo-strip{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 10px;
  margin:10px 0 4px; padding:9px 12px;
  background:var(--bone); border:1px solid var(--stroke-soft); border-radius:var(--r-md);
}
.jo-strip-k{
  font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-faint); font-weight:600;
}
.jo-strip-v{ font-size:13.5px; color:var(--ink); font-weight:600; overflow-wrap:anywhere; }
/* Carrying a select, the strip is a form row, not a caption. */
.jo-strip-pick{ display:block; padding:11px 12px; }
.jo-strip-pick .fld{ margin:0; }
/* The warning form of the strip supplies its own box. */
.jo-strip .wk-warn{ margin:0; width:100%; }

.jo-loading{ padding:26px 4px; color:var(--ink-soft); font-size:13.5px; }
.jo-loading-err{ color:var(--red); }

/* ---------- what is missing ----------
   The firm's complaint in one box: "if there is any missing information
   … please make sure you call it out". It names the field, says which
   record does not hold it, and offers the way to that record. It is not
   red — nothing here has gone wrong, and a form that shouts at a
   consultant who has only just opened it is a form they stop reading. */
.jo-gapbox{
  margin:12px 0 4px; padding:12px 14px;
  background:rgba(169,130,76,.10);
  border:1px solid var(--stroke-soft); border-left:3px solid var(--gold);
  border-radius:var(--r-md);
}
.jo-gapbox-t{
  font-size:13px; font-weight:700; color:var(--gold-deep);
  line-height:1.45; margin-bottom:9px;
}
/* Stacked on a phone — a label, a reason and a link will not share 390px
   without one of them being cut in half. */
.jo-gap{
  display:flex; flex-direction:column; gap:1px;
  padding:7px 0; border-top:1px solid var(--stroke-soft);
}
.jo-gap-l{ font-size:13px; font-weight:600; color:var(--ink); overflow-wrap:anywhere; }
.jo-gap-w{ font-size:12.5px; color:var(--ink-soft); overflow-wrap:anywhere; }
.jo-gap-fix{
  font-size:12.5px; font-weight:600; color:var(--gold-deep);
  text-decoration:underline; text-underline-offset:2px;
  align-self:flex-start; padding:2px 0;
}
@media (min-width:761px){
  /* Three columns once there is room: what is missing, why, and the way
     to fix it — read straight across, one line each. */
  .jo-gap{
    flex-direction:row; align-items:baseline; gap:10px;
    padding:6px 0;
  }
  .jo-gap-l{ flex:0 0 40%; }
  .jo-gap-w{ flex:1; }
  .jo-gap-fix{ align-self:baseline; white-space:nowrap; }
}

/* Nothing missing. Said once, quietly, and only when it is true. */
.jo-ok{
  display:flex; align-items:flex-start; gap:9px;
  margin:12px 0 4px; padding:10px 13px;
  background:var(--bone); border:1px solid var(--green-soft); border-radius:var(--r-md);
  font-size:13px; color:var(--green); line-height:1.45;
}
.jo-ok svg{ width:15px; height:15px; flex:0 0 15px; margin-top:2px; }

/* A field that arrived incomplete rather than empty. */
.jo-note{ font-size:12px; color:var(--gold-deep); margin-top:4px; line-height:1.45; }
.jo-note a{ color:var(--gold-deep); font-weight:600; text-decoration:underline; text-underline-offset:2px; }

/* A required field with nothing in it, marked where it stands so the
   callout box above and the form below agree with each other. */
.dt-f.jo-missing .dt-in{ border-color:var(--gold); background:rgba(169,130,76,.06); }

/* Almost every clause of this contract is required, so a badge on every
   one of them says nothing and reads as clutter. It appears on the
   fields that are actually still empty — and disappears as they are
   filled in, because .jo-missing is recomputed on every keystroke. */
#joBody .dt-f .dt-req{ display:none; }
#joBody .dt-f.jo-missing .dt-req{ display:inline; }

/* ---------- who signs ---------- */
.jo-signer{ display:grid; grid-template-columns:1fr; gap:6px; margin-bottom:10px; }
.jo-signer-r{
  font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-faint); font-weight:600;
}
@media (min-width:761px){
  .jo-signer{ grid-template-columns:120px minmax(0,1fr) minmax(0,1fr); align-items:center; gap:10px; }
  .jo-signer-r{ text-align:right; }
}

/* ---------- the foot ---------- */
.jo-foot{ align-items:center; }
.jo-count{ font-size:12.5px; color:var(--gold-deep); font-weight:600; margin-right:10px; }

/* ---------- the contracts already on this file ----------
   "When I click on a draft, I should see a preview" — so a draft's
   action is Preview, and it opens the same panel Preview in the dialog
   opens. A contract already sent is not editable and does not pretend
   to be: it opens where its signatures are tracked. */
.jo-list{ margin-top:16px; }
.jo-list:empty{ display:none; }
.jo-list-t{
  font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-faint); font-weight:600; margin-bottom:6px;
}
.jo-list-msg{ font-size:12.5px; color:var(--red); }
.jo-row{
  display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px;
  padding:9px 0; border-top:1px solid var(--stroke-soft);
}
.jo-row-ref{ font-size:13px; font-weight:600; color:var(--ink); }
.jo-row-when,
.jo-row-sig{ font-size:12.5px; color:var(--ink-soft); }
/* Push the action to the end of the row on any screen wide enough to
   have an end; on a phone it simply wraps onto the next line. */
.jo-row .btn{ margin-left:auto; }

/* WHICH CONTRACT — low wage or high wage.
   A choice between two documents, so two pills rather than a dropdown: both
   options stay visible and the undecided state is visibly undecided rather
   than looking like a default someone accepted. */
.jo-streamrow{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:10px 0 4px;
}
.jo-streamlbl{
  font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-faint); font-weight:600; margin-right:2px;
}
.jo-stream{
  font:inherit; font-size:12.5px; font-weight:600; line-height:1;
  padding:7px 14px; border-radius:999px; cursor:pointer;
  color:var(--ink-soft); background:transparent; border:1px solid var(--stroke);
  transition:background .2s, color .2s, border-color .2s;
}
.jo-stream:hover{ background:var(--bone); color:var(--ink); }
.jo-stream:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }
.jo-stream.on{
  color:var(--gold-deep); border-color:var(--gold); background:rgba(169,130,76,.12);
}
.jo-streamnote{ font-size:12px; color:var(--ink-soft); flex:1 1 220px; min-width:180px; }
.jo-streamrow-undecided .jo-streamnote{ color:var(--red); }
.jo-streamwhy{
  font-size:11.5px; color:var(--ink-faint); line-height:1.5;
  padding:0 0 8px; border-bottom:1px solid var(--stroke-soft); margin-bottom:10px;
}
.jo-row-stream{
  font-size:11px; color:var(--ink-faint); letter-spacing:.03em;
  white-space:nowrap;
}
