/* Contract viewer — the contract itself, its findings, and the role flags.
 *
 * A full-window layer rather than a panel inside the module: a subcontract is
 * read at page width, and the findings rail has to sit beside it, not under
 * it. Uses the app's own tokens throughout so it stays one product.
 */

.cv-shell {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--bg);
  color: var(--text);
}
/* THE TEST BANNER IS FIXED AND SITS ABOVE EVERYTHING (z-index 10050), and the
   app clears it with `body.has-test-banner { padding-top: 48px }` — which does
   nothing for a fixed element, so this layer opened UNDERNEATH it and buried
   its own toolbar. Start below the banner instead of trying to out-stack it:
   the banner must stay visible, it is the whole point of the banner. Same
   answer the takeoff viewer already uses (styles.css, tk-viewer-fullbleed). */
body.has-test-banner .cv-shell { top: 48px; }
.cv-shell.hidden { display: none; }
/* the page beneath must not scroll while the layer is up */
body.cv-open-body { overflow: hidden; }

/* ---- top bar ---- */
.cv-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-soft);
}
.cv-bar h2 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  max-width: 42ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cv-bar-spacer { flex: 1 1 auto; }
.cv-pos {
  color: var(--muted);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  min-width: 11ch;
  text-align: center;
}
.cv-bar select {
  background: var(--input-bg);
  color: var(--text);
  border: 1px solid var(--input-bd);
  border-radius: var(--radius-md);
  padding: 6px 10px;
  max-width: 34ch;
  font: inherit;
}
.cv-bar select:focus-visible { outline: 2px solid var(--input-halo); outline-offset: 1px; }

/* The app has no screen-reader-only utility of its own; this one is scoped to
   the viewer rather than added to the shared sheet. */
.cv-shell .visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- body: rail + page ---- */
.cv-body {
  display: grid;
  grid-template-columns: minmax(300px, 380px) 1fr;
  min-height: 0;
}
.cv-rail {
  border-right: 1px solid var(--line);
  background: var(--bg-soft);
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.cv-rail h3 {
  margin: 0 0 6px;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.cv-pagewrap {
  overflow: auto;
  padding: 18px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  background: #060b11;
}
.cv-page {
  position: relative;
  box-shadow: var(--shadow);
  background: #fff;
  line-height: 0;
}
#cvCanvas { display: block; }
#cvOverlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* ---- flag boxes over the page ---- */
.cv-flag {
  position: absolute;
  border: 1.5px solid;
  border-radius: 3px;
  pointer-events: auto;
  cursor: pointer;
  transition: filter 0.12s ease;
}
.cv-flag:hover { filter: brightness(1.35); }
.cv-flag.cv-done { border-style: dashed; opacity: 0.65; }
.cv-pulse {
  position: absolute;
  border: 2px solid #ffd166;
  border-radius: 4px;
  pointer-events: none;
  animation: cv-pulse 2.4s ease-out forwards;
}
@keyframes cv-pulse {
  0%, 60% { box-shadow: 0 0 0 4px rgba(255, 209, 102, 0.45); }
  100%    { box-shadow: 0 0 0 0 rgba(255, 209, 102, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .cv-pulse { animation: none; box-shadow: 0 0 0 4px rgba(255, 209, 102, 0.45); }
}

/* ---- the gate ---- */
.cv-gate {
  border: 1px solid var(--panel-border);
  border-left-width: 4px;
  border-radius: var(--radius-md);
  padding: 10px 12px;
  background: var(--surface);
  font-size: 0.9rem;
}
.cv-gate-ok    { border-left-color: #7ac98a; }
.cv-gate-block { border-left-color: #ef6a6a; }
.cv-gate-why   { color: var(--muted); font-size: 0.82rem; margin-top: 4px; }
.cv-bound      { margin-top: 6px; font-size: 0.8rem; color: var(--muted); }
.cv-unbound    { color: #ffd166; }

/* ---- flags list ---- */
.cv-flagrow {
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 9px 10px;
  margin-bottom: 8px;
  font-size: 0.85rem;
}
.cv-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}
.cv-kind, .cv-state {
  display: inline-block;
  border: 1px solid var(--chip-border);
  background: var(--chip);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.cv-state-open         { color: #ffd166; border-color: #6b5a2a; }
.cv-state-approved,
.cv-state-acknowledged { color: #7ac98a; border-color: #2f5a3a; }
.cv-flagq {
  color: var(--muted);
  font-style: italic;
  margin: 5px 0 0;
  border-left: 2px solid var(--line);
  padding-left: 8px;
}
.cv-flagn  { margin-top: 4px; }
.cv-flagby { margin-top: 5px; font-size: 0.74rem; color: var(--muted); }
.cv-empty  { color: var(--muted); font-size: 0.85rem; }

/* ---- findings ---- */
.cv-find {
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 9px 10px;
  margin-bottom: 8px;
  font-size: 0.85rem;
}
.cv-find-h { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.cv-find-s { color: var(--muted); font-size: 0.76rem; margin-top: 2px; }
.cv-find-q {
  color: var(--muted);
  font-style: italic;
  margin: 5px 0 6px;
  border-left: 2px solid var(--line);
  padding-left: 8px;
}
.cv-risk {
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border: 1px solid var(--chip-border);
  background: var(--chip);
  white-space: nowrap;
}
.cv-risk-high, .cv-risk-critical { color: #ef6a6a; border-color: #5e2b2b; }
.cv-risk-medium                  { color: #ffd166; border-color: #6b5a2a; }
.cv-risk-low                     { color: #7ac98a; border-color: #2f5a3a; }

.cv-mini {
  font: inherit;
  font-size: 0.76rem;
  padding: 3px 9px;
  margin: 2px 6px 0 0;
  border-radius: var(--radius-md);
  border: 1px solid var(--chip-border);
  background: var(--chip);
  color: var(--text);
  cursor: pointer;
}
.cv-mini:hover    { background: var(--btn-hover); border-color: var(--btn); }
.cv-mini-go       { background: var(--btn); border-color: var(--btn); }
.cv-mini-go:hover { background: var(--btn-hover); }

/* ---- flag dialog ---- */
.cv-modal {
  position: fixed;
  inset: 0;
  z-index: 950;
  display: grid;
  place-items: center;
  background: rgba(4, 8, 13, 0.72);
  padding: 20px;
}
.cv-modal-box {
  width: min(560px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 18px 20px;
}
.cv-modal-box h3 { margin: 0 0 10px; font-size: 1.02rem; }
.cv-modal-box label {
  display: block;
  margin: 12px 0 4px;
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}
.cv-modal-box select,
.cv-modal-box textarea {
  width: 100%;
  background: var(--input-bg);
  color: var(--text);
  border: 1px solid var(--input-bd);
  border-radius: var(--radius-md);
  padding: 8px 10px;
  font: inherit;
  resize: vertical;
}
.cv-modal-box select:focus-visible,
.cv-modal-box textarea:focus-visible { outline: 2px solid var(--input-halo); outline-offset: 1px; }
.cv-quote {
  border-left: 3px solid var(--btn);
  padding: 6px 10px;
  background: var(--surface);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  font-style: italic;
  color: var(--muted);
  font-size: 0.86rem;
}
.cv-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
}

/* Narrow screens: the rail stacks above the page rather than squeezing it. */
@media (max-width: 900px) {
  .cv-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .cv-rail { border-right: none; border-bottom: 1px solid var(--line); max-height: 40vh; }
}

/* A highlight that covers only the clause's opening words — the clause runs
   across a page break, or was quoted with an elision. Marked, never hidden. */
.cv-flag.cv-partial { border-style: dotted; }

/* ---- the selectable text layer ----
   A rendered PDF page is a canvas — a picture with no text in it. pdf.js
   positions a transparent span over every run of glyphs so the browser can do
   real text selection on top of the page. Without this there is nothing to
   select, and "Flag selected text" has nothing to read. */
.cv-textlayer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  line-height: 1;
  text-align: initial;
  transform-origin: 0 0;
  forced-color-adjust: none;
  z-index: 1;
}
.cv-textlayer span {
  position: absolute;
  white-space: pre;
  transform-origin: 0% 0%;
  color: transparent;
  cursor: text;
}
/* The layer exists so the BOX can read words, not for native selection — a
   drag on the page draws a marquee instead. */
.cv-textlayer, .cv-textlayer span {
  user-select: none;
  -webkit-user-select: none;
  cursor: crosshair;
}
/* while the Flag button is pointing at the page */
.cv-page.cv-arming { outline: 2px solid var(--btn); outline-offset: 2px; }
/* the flag boxes sit above the text so they stay clickable */
#cvOverlay { z-index: 2; }


/* who a flag is actually waiting on — the role is the rule, the name is the person */
.cv-who {
  color: var(--muted);
  font-size: 0.78rem;
}

/* who answered a flag, and when */
.cv-flagdone {
  margin-top: 3px;
  font-size: 0.76rem;
  color: #7ac98a;
  font-weight: 600;
}
/* shown instead of a button to everyone who is not in the seat */
.cv-flagwait {
  margin-top: 6px;
  font-size: 0.76rem;
  color: var(--muted);
  border-left: 2px solid var(--chip-border);
  padding-left: 8px;
}

/* ---- bottom-right stage cluster ----
   The same control Plan Markup and the takeoff viewer use (Tyler 2026-08-28),
   so zooming and paging a contract feels like zooming and paging a plan sheet.
   markup.css is scoped to markup.html and leans on tokens this page does not
   define, so the geometry is reproduced here against the app's own tokens
   rather than cross-linking another surface's whole stylesheet. */
.cv-stage-zoom {
  position: absolute;
  right: 14px;
  bottom: 14px;
  z-index: 24;
}
.cv-zoom-group {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 4px;
  background: rgba(13, 18, 32, 0.92);
  border: 1px solid var(--line);
  border-radius: 10px;
  backdrop-filter: blur(4px);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
}
.cv-sz-row { display: flex; gap: 3px; }
.cv-sz-zoom { justify-content: space-between; }
.cv-sz-fit .cv-sz-btn { flex: 1 1 0; }
.cv-sz-btn {
  border: 1px solid var(--line);
  background: var(--chip);
  color: var(--text);
  border-radius: 7px;
  padding: 4px 9px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  line-height: 1.5;
  white-space: nowrap;
}
.cv-sz-btn:hover { background: var(--btn-hover); border-color: var(--btn); }
.cv-sz-btn:disabled { opacity: 0.35; cursor: default; pointer-events: none; }
.cv-sz-btn.cv-active { background: var(--btn); border-color: var(--btn); }
.cv-sz-btn.cv-zlevel {
  min-width: 54px;
  text-align: center;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* page nav band — hairline-separated, matching the markup cluster.
   NOT a positioning context: the picker anchors to the whole cluster so it
   opens ABOVE it instead of covering the zoom and fit rows. */
.cv-page-nav {
  position: static;
  width: 100%;
  margin-top: 3px;
  padding-top: 5px;
  border-top: 1px solid var(--line);
}
.cv-sz-page { justify-content: space-between; }
.cv-sz-page .cv-page-count {
  flex: 1 1 auto;
  min-width: 0;
  padding: 4px 6px;
  font-variant-numeric: tabular-nums;
}
.cv-sz-page .cv-page-count::after { content: " \25BE"; color: var(--muted); }
.cv-sz-page .cv-page-count.open { border-color: var(--btn); }
.cv-sz-page #cvPrev, .cv-sz-page #cvNext { flex: 0 0 auto; font-size: 15px; line-height: 1; padding: 2px 9px; }

/* the picker opens UPWARD — the cluster sits at the stage bottom */
.cv-page-drop {
  position: absolute;
  right: 0;
  bottom: calc(100% + 6px);
  max-height: min(48vh, 420px);
  overflow-y: auto;
  min-width: 150px;
  padding: 4px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  box-shadow: var(--shadow);
}
.cv-page-drop[hidden] { display: none; }
.cv-page-drop button {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 12px;
  padding: 5px 9px;
  border-radius: 6px;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.cv-page-drop button:hover { background: var(--chip); }
.cv-page-drop button.cv-here { background: var(--btn); font-weight: 700; }

/* ---- one clause, several roles ---- */
.cv-rolepick { display: flex; flex-direction: column; gap: 4px; }
.cv-roleopt {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 7px 9px;
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  background: var(--surface);
  cursor: pointer;
  font-size: 0.86rem;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
}
.cv-roleopt:hover { border-color: var(--btn); }
.cv-roleopt input { accent-color: var(--btn); margin: 0; }
/* each role's own obligation, under the clause they share */
.cv-roleline {
  margin-top: 7px;
  padding-top: 7px;
  border-top: 1px dashed var(--chip-border);
  font-size: 0.85rem;
}
.cv-flagrow > .cv-roleline:first-of-type { border-top: 0; }


.cv-marquee {
  position: absolute;
  z-index: 4;
  border: 1.5px dashed #4da3ff;
  background: rgba(77, 163, 255, 0.16);
  pointer-events: none;
  border-radius: 2px;
}

/* ---- what this reader owes ---- */
.cv-mine {
  border: 1px solid #3b6ea5;
  border-left-width: 4px;
  border-radius: var(--radius-md);
  background: rgba(29, 110, 200, 0.10);
  padding: 10px 12px;
}
.cv-mine.hidden { display: none; }
.cv-mine h3 {
  margin: 0 0 8px;
  color: #9dc4f0;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.cv-mine .cv-roleline { border-top-color: rgba(157, 196, 240, 0.35); }
.cv-mine .cv-roleline:first-of-type { border-top: 0; padding-top: 0; }

/* the actions that belong to one role's obligation */
.cv-lineacts { display: flex; flex-wrap: wrap; gap: 0; margin-top: 2px; }
.cv-mini-del { border-color: #6b3030; color: #ef9a9a; }
.cv-mini-del:hover { background: #6b3030; border-color: #8a3d3d; color: #fff; }

/* an in-app note, not a browser dialog */
.cv-toast {
  position: absolute;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  z-index: 40;
  max-width: min(560px, 82vw);
  padding: 10px 16px;
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  background: rgba(13, 18, 32, 0.96);
  box-shadow: var(--shadow);
  font-size: 0.86rem;
  text-align: center;
}
.cv-toast.hidden { display: none; }
.cv-modal-msg { margin: 0 0 4px; color: var(--muted); font-size: 0.88rem; }

/* a page that is a picture of a contract, not a contract */
.cv-notext {
  position: absolute;
  left: 50%;
  top: 14px;
  transform: translateX(-50%);
  z-index: 6;
  max-width: 84%;
  padding: 9px 14px;
  border: 1px solid #6b5a2a;
  border-radius: 999px;
  background: rgba(43, 35, 12, 0.96);
  color: #ffd166;
  font-size: 0.82rem;
  text-align: center;
  line-height: 1.35;
}
.cv-notext.hidden { display: none; }

/* ---- the continuous page column ---- */
.cv-pages {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
/* each page keeps its footprint even before it is drawn, so the scrollbar is
   honest from the first frame instead of growing as pages appear */
.cv-page {
  position: relative;
  flex: 0 0 auto;
  background: #fff;
  box-shadow: var(--shadow);
  line-height: 0;
}
.cv-page canvas { display: block; }
.cv-pageoverlay { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.cv-pagenum {
  position: absolute;
  right: 8px;
  bottom: 6px;
  z-index: 3;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(9, 16, 24, 0.66);
  color: #cfe1f5;
  font: 600 11px/1.6 system-ui, sans-serif;
  pointer-events: none;
}
.cv-page.cv-arming { outline: 2px solid var(--btn); outline-offset: 2px; }
