/* TRU-841 — the floating preview window. Every selector in this file is `.pvw`-
   prefixed or starts `body.pvw-`; nothing here may reach the form, and nothing here
   styles the miniatures themselves (those are .sgpv*, owned elsewhere).

   That boundary is now absolute again. TRU-867 had widened it by one step so the
   window could reserve a gutter out of the document's own containers — .top .in2,
   .prog .in4, .wrap, .shell, .foot. TRU-886 removed the gutter entirely, and those
   five selectors went with it: the window floats and reshapes nothing. The only rule
   in this file that still names a page element is `body.pvw-open-sheet`, which
   reserves the bottom of a phone screen for the sheet that genuinely occupies it.
   No field, no control, and no band is reachable from here.

   The window is TrueEval chrome wrapped around the client's brand, and the two have
   to stay tellable apart — a client who cannot see where our colours stop and theirs
   start cannot judge their own palette. So the chrome commits hard to the house
   style (deep green title bar, mono uppercase label, Inter tab strip) and the
   client's work sits inside it as a card on a neutral ground, never bleeding to the
   window edge.

   Every custom property is used with a literal fallback: this window is appended to
   <body> and could be mounted on a page that never declared the :root block.

   Contrast measured with assets/suggest.js contrastRatio(). Pairings introduced here:
     #ffffff       on --green   #0d5e38   7.85   title bar label + control glyphs
     --green       on --paper   #ffffff   7.85   locked chip, active tab, focused glyph
     --muted       on --paper   #ffffff   5.43   idle tab label
     --ink         on --paper   #ffffff  17.23   hovered tab label
   The pane ground is --bg #eef2ef, where the miniature's own caption (--green-d)
   measures 5.28 and --muted measures 4.80 — both still AA on this ground.

   `scroll-margin-top:var(--stick)` is deliberately absent: it exists so a focused
   control is not scrolled under the sticky header, and nothing inside a
   position:fixed window is ever scrolled by the document. */

/* ---------- the window ---------- */

.pvw {
  position: fixed;
  right: 18px;
  bottom: 18px;
  width: min(420px, calc(100vw - 36px));
  max-height: min(72vh, 620px);
  display: flex;
  flex-direction: column;
  /* Above .top (40) and .prog (30); the window has to survive being dragged over
     the sticky chrome. */
  z-index: 60;
  background: var(--paper, #ffffff);
  border: 1px solid var(--line, #dde5e0);
  border-radius: 12px;
  overflow: hidden;
  /* --shadow-card is tuned for a card sitting in the page flow and reads flat under
     something that floats over it; a lift this window can be told apart by needs a
     longer throw. */
  box-shadow: 0 18px 44px rgba(20, 29, 24, .18), 0 2px 8px rgba(20, 29, 24, .08);
  font-family: var(--sans, 'Inter', sans-serif);
  animation: pvw-in .18s ease-out;
}

/* .pvw sets display:flex, which outranks the UA rule for [hidden]. */
.pvw[hidden] { display: none; }

/* Set by JS the moment the window is dragged: the docking offsets have to be
   released or right/bottom would fight the inline left/top. */
.pvw.pvw-is-free { right: auto; bottom: auto; }

@keyframes pvw-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ---------- title bar / drag handle ---------- */

.pvw-bar {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 9px 8px 11px;
  background: var(--green, #0d5e38);
  color: var(--paper, #ffffff);
  cursor: grab;
  /* The bar is the drag surface, so the browser must not claim the gesture for a
     pan. It is not a scroll surface at any width, so this costs nothing on touch. */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.pvw.pvw-is-drag .pvw-bar { cursor: grabbing; }

.pvw-grip {
  width: 9px;
  height: 13px;
  flex: none;
  background-image: radial-gradient(currentColor 1px, transparent 1.2px);
  background-size: 4px 4px;
  opacity: .65;
}

.pvw-name {
  font-family: var(--mono, 'JetBrains Mono', monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The page already flips to .locked-mode when a submission is signed. Without this
   chip the window kept looking live next to a locked form, which reads as "these
   values are still editable". */
.pvw-lock {
  font-family: var(--mono, 'JetBrains Mono', monospace);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  background: var(--paper, #ffffff);
  color: var(--green, #0d5e38);
  border-radius: 4px;
  padding: 2px 6px;
}

.pvw-lock[hidden] { display: none; }

.pvw-acts {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
}

.pvw-bar-btn {
  width: 28px;
  height: 28px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .34);
  border-radius: 6px;
  color: var(--paper, #ffffff);
  cursor: pointer;
}

.pvw-bar-btn:hover { background: rgba(255, 255, 255, .15); }

/* The house focus indicator is an opaque outline of var(--green) — which is
   invisible drawn on the green title bar. The chip inverts to paper on focus so the
   mandated green outline has a 7.85:1 ground, and the outline is inset so it lands
   on that white chip rather than on the bar behind it. --ring stays what it always
   is here: a decorative halo, never the indicator. */
.pvw-bar-btn:focus-visible {
  background: var(--paper, #ffffff);
  color: var(--green, #0d5e38);
  border-color: var(--green, #0d5e38);
  outline: 2px solid var(--green, #0d5e38);
  outline-offset: -3px;
  box-shadow: var(--ring, 0 0 0 3px rgba(13, 94, 56, .28));
}

.pvw-bar-btn svg { display: block; transition: transform .18s ease; }

/* Chevron points up while the window is open (press to fold), down once folded. */
.pvw.pvw-is-fold .pvw-fold svg { transform: rotate(180deg); }

/* ---------- body ---------- */

.pvw-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.pvw-body[hidden] { display: none; }

.pvw-tabs {
  display: flex;
  background: var(--paper, #ffffff);
  border-bottom: 1px solid var(--line, #dde5e0);
  padding: 0 6px;
  flex: none;
}

.pvw-tab {
  flex: 1;
  min-height: 38px;
  padding: 10px 8px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  font-family: var(--sans, 'Inter', sans-serif);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--muted, #636c66);
  cursor: pointer;
  transition: color .14s ease, border-color .14s ease;
}

.pvw-tab:hover { color: var(--ink, #141d18); }

.pvw-tab.is-on {
  color: var(--green, #0d5e38);
  border-bottom-color: var(--green, #0d5e38);
}

.pvw-tab:focus-visible {
  outline: 2px solid var(--green, #0d5e38);
  outline-offset: -3px;
  border-radius: 7px;
}

.pvw-panes {
  flex: 1;
  min-height: 0;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  /* The client's miniature is a card; putting it on the page ground rather than on
     paper is what keeps their surface colour readable as theirs. */
  background: var(--bg, #eef2ef);
  padding: 14px;
}

.pvw-pane { border-radius: 10px; }

.pvw-pane[hidden] { display: none; }

/* The mockups are decorative and aria-hidden, so the panel itself is the tab stop
   after the tab strip and needs a visible indicator of its own. */
.pvw-pane:focus-visible {
  outline: 2px solid var(--green, #0d5e38);
  outline-offset: 2px;
}

.pvw-mount { min-width: 0; }

/* ---------- locked submission ----------
   Nothing is disabled: a signed record is still read, and every mockup stays
   readable and every control stays operable. The state is marked only so the chrome
   agrees with the page's own .locked-mode. */
.pvw.pvw-is-locked .pvw-bar { background: var(--green, #0d5e38); }

/* ---------- <=640px: bottom sheet ---------- */

@media (max-width: 640px) {
  .pvw {
    /* !important because a position dragged on a desktop can arrive here as inline
       left/top (rotate a tablet, resize a window). JS clears those coordinates on
       resize; this is the guarantee that a sheet is never stranded off-screen even
       if that listener never fires. */
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    bottom: 0 !important;
    width: auto;
    height: 46vh;
    max-height: 46vh;
    border-radius: 14px 14px 0 0;
    border-left: none;
    border-right: none;
    border-bottom: none;
    border-top: 2px solid var(--green, #0d5e38);
    box-shadow: 0 -10px 30px rgba(20, 29, 24, .18);
  }

  .pvw.pvw-is-fold { height: auto; max-height: none; }

  /* Dragging is off at this size, so the handle affordance would be a lie. */
  .pvw-grip { display: none; }
  .pvw-bar { cursor: default; padding: 6px 8px 6px 12px; }

  /* 44pt minimum target. */
  .pvw-bar-btn { width: 44px; height: 44px; }
  .pvw-tab { min-height: 44px; font-size: 12.5px; }

  .pvw-panes { padding: 12px; }
}

/* The sheet covers the bottom of the viewport, so the field being edited has to be
   scrollable clear of it — otherwise the window solves seeing the preview by hiding
   the input. Kept out of the media query on purpose: JS only ever sets this class
   while the window is actually a sheet. */
body.pvw-open-sheet { padding-bottom: 46vh; }

/* ---------- >640px: the window FLOATS. It never reshapes the document. --------------

   TRU-886. This block used to reserve a gutter: while the window was open it rewrote
   the max-width of .top .in2, .prog .in4, .wrap and .shell from 1180px to
   calc(1180px + 456px) and padded the difference off the right, so the reading column
   widened and shifted the instant the preview opened. Measured at 1900x1000, .shell
   went 1180px -> 1636px on open: the section cards stretched, the colour presets
   re-wrapped from two columns to four, and the whole page rearranged itself around a
   panel that then read as docked chrome rather than a floating window.

   That gutter came from TRU-848, where the floating window covered the colour fields
   it exists to help with, and TRU-867 moved which containers it was taken from after
   it tore the header, hero and footer bands. Kevin has now seen both and asked for
   floating: a preview is something you glance at, and it must not rearrange the
   document you are filling in.

   So there is deliberately nothing here. The window is position:fixed (see .pvw at the
   top of this file), max-height:min(72vh,620px) so it is never clipped by the fold,
   and its presence has no effect on layout at all. Opening and closing it cannot move
   the page, which also retires the scroll compensation the reflow forced on
   preview-window.js.

   The trade-off, taken knowingly: the document column is capped at 1180px and centred,
   so its right edge sits at (100vw + 1180) / 2 while the docked window's left edge sits
   at 100vw - 438. The window therefore overlaps the column below 2092px, by about 78px
   at 1900 and more as the viewport narrows. That is what a floating window does, and
   the answers to it are the ones the window already has: drag it, collapse it, or close
   it. Do not "fix" this by reserving space again — that is the bug this ticket removed.

   The phone sheet below 640px is a different thing and is still correct: a bottom sheet
   genuinely occupies the bottom of a phone screen, so body.pvw-open-sheet reserves
   padding-bottom for it. That rule stays. */

/* The signed record is kept by printing it. Chrome never prints. */
@media print {
  .pvw { display: none !important; }
  body.pvw-open-sheet { padding-bottom: 0 !important; }
  /* TRU-886 removed the desktop gutter, so there is no longer a reserved column that
     could print as a blank strip down the side of the signed record. The sheet's
     padding is still zeroed above, because a phone that prints must not carry 46vh of
     reserved ground into the record. */
}

@media (prefers-reduced-motion: reduce) {
  .pvw { animation: none; }
  .pvw-bar-btn svg { transition: none; }
  .pvw-tab { transition: none; }
}
