/* ============================================================ SNIPPETS — the cut-out panel
 *
 * THE OPERATOR'S OWN WORDS are the specification (Kazim, on the affidavit editor):
 *
 *   "anyone who is making an affidavit basically has list of all the documents in the job, and can
 *    like crop out any part of the document, resize it and put it like as a snippet into the
 *    affidavit."
 *
 * This file dresses `snippets.js` and nothing else: the document list, the page with its drag
 * rectangle, and the INSERT bar. It is loaded by the one page (`index.html`) beside the module, the
 * same way `bar-phone.css` is loaded beside `bar-phone.js` — the module and its stylesheet travel
 * together, and this file is the ONLY place a snippet-panel rule lives (the module adds the <link>
 * if the page forgot it, and does not carry a second copy of these rules).
 *
 * EVERY COLOUR, RADIUS AND SPACE COMES OFF THE CONSOLE'S OWN TOKENS — `--surface`, `--raised`,
 * `--sunken`, `--line`, `--line-2`, `--accent`, `--accent-soft`, `--ink-3`, `--r-sm`/`--r-md`/
 * `--r-lg`, `--s1`..`--s5`, `--e2`/`--e4`, `--mono`. That is the same rule `bar-phone.css` states,
 * and it has a concrete payoff here rather than a stylistic one: this console has a dark theme
 * written as a second block of those tokens, so a panel built from tokens is dressed for both
 * themes by a file that never mentions a theme. A hex value here would be a light-theme-only panel.
 *
 * THE ONE LITERAL COLOUR IS THE DRAG RECTANGLE'S FILL, and it is deliberate: `rgba(27,77,143,0.18)`
 * is `--accent` (#1b4d8f) at 18% — the rectangle must READ AS A SELECTION over a page image that is
 * white in both themes, so it cannot take `--accent-soft` (which is a light-theme token that goes
 * dark in the dark theme, and a dark wash over white paper is a black box over the passage the
 * person is trying to read). The border is the token; only the wash is literal.
 */

#snippets-panel {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s3);
  background: rgba(20, 23, 27, 0.45);
}
#snippets-panel[hidden] { display: none; }

.sn-panel {
  display: flex; flex-direction: column;
  width: min(1100px, 100%); height: min(860px, 100%);
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  box-shadow: var(--e4); overflow: hidden;
}

.sn-head {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line); background: var(--raised);
}
.sn-head h3 { margin: 0; font-size: 15px; font-weight: 650; }
.sn-head .sn-sub { font-size: 11.5px; color: var(--ink-3); }
.sn-head .sn-x { margin-left: auto; }

.sn-body { display: flex; flex: 1 1 auto; min-height: 0; }

/* ---- the job's documents ---------------------------------------------------------------- */

.sn-docs {
  flex: none; width: 280px; overflow: auto;
  border-right: 1px solid var(--line); padding: var(--s2); background: var(--sunken);
}
.sn-docs-head {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); padding: var(--s2) var(--s2) var(--s1);
}
/* ---- the job's own document door: ADD one, and take one off -------------------------------- */

/* THE ADD CONTROL SITS AT THE TOP OF THE LIST IT ADDS TO, which is where a person looks when the
   list is empty. The `<input type="file">` is hidden because a browser will only open its picker
   from a real file control, and a raw file control cannot be styled to look like the rest of this
   panel — so the button is the control and the input is behind it (`clip`, not `display:none`, so
   it stays focusable for a keyboard). */
.sn-add { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
          padding: var(--s1) var(--s2) var(--s2); }
.sn-add-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.sn-add-note { flex: 1 1 100%; font-size: 10.5px; color: var(--ink-3); line-height: 1.35; }

/* A DOCUMENT ROW IS THE BUTTON AND ITS OWN REMOVE, side by side. */
.sn-doc-row { display: flex; align-items: stretch; gap: 2px; margin-bottom: 2px; }
.sn-doc-row .sn-doc { flex: 1 1 auto; min-width: 0; margin-bottom: 0; }
/* THE REMOVE IS DRAWN QUIETLY AND IS NOT IN THE TAB ORDER OF THE LIST — it is the destructive act
   beside the act the row is for (choosing the document), and the styling says which is which
   without hiding it: it takes the danger colour only on hover or focus. */
.sn-doc-del { flex: none; width: 26px; padding: 0; line-height: 1; color: var(--ink-3);
              background: none; border: 1px solid transparent; }
.sn-doc-del:hover, .sn-doc-del:focus-visible {
  color: var(--danger); border-color: var(--danger); background: var(--raised);
}

/* WHOSE FILE IS THIS ROW — said on the row, because it decides what the row can do. A "job document"
   has no remove control at all (the panel cannot honestly offer to delete it); a "snippet only" file
   can be removed here and nowhere else. The tag is quiet by design: it answers a question the operator
   asks once, and it must not compete with the file name they are scanning for. */
.sn-doc-tag { flex: none; align-self: center; font-family: var(--mono); font-size: 9.5px;
              letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3);
              padding: 1px 5px; border: 1px solid var(--line); border-radius: 3px; white-space: nowrap; }
.sn-doc-tag-job { color: var(--ink-4); border-style: dashed; }
.sn-doc-row-mine .sn-doc-tag { color: var(--accent); border-color: var(--accent); }

.sn-doc {
  display: block; width: 100%; text-align: left;
  padding: var(--s2); margin-bottom: 2px;
  background: none; border: 1px solid transparent; border-radius: var(--r-sm);
  color: var(--ink); cursor: pointer; font: inherit;
}
.sn-doc:hover { background: var(--hover); }
.sn-doc[aria-current="true"] {
  background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent);
}
/* A DOCUMENT'S NAME IS THE JOB'S OWN BYTES and a scan's name is long: it wraps rather than
   overflowing the 280px column, because a name clipped mid-word is a name an operator cannot check
   against the file they are looking for. */
.sn-doc-name { display: block; font-size: 12.5px; font-weight: 600; word-break: break-word; }
.sn-doc-meta {
  display: block; font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); margin-top: 2px;
}
.sn-doc[aria-current="true"] .sn-doc-meta { color: var(--accent); }

/* ---- the page, and the rectangle drawn over it ------------------------------------------ */

.sn-stage { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.sn-pages {
  flex: none; display: flex; align-items: center; gap: var(--s2);
  overflow-x: auto; padding: var(--s2) var(--s3); border-bottom: 1px solid var(--line);
}
.sn-page {
  flex: none; padding: 4px 10px;
  border: 1px solid var(--line-2); border-radius: var(--r-pill);
  background: var(--raised); color: var(--ink-2);
  cursor: pointer; font: inherit; font-size: 11.5px;
}
.sn-page[aria-current="true"] {
  border-color: var(--accent); color: var(--accent); background: var(--accent-soft);
}

/* THE CANVAS IS THE IMAGE'S OWN BOX, with the rectangle positioned inside it. `position:relative`
   here and `position:absolute` on `.sn-box` is what makes the drag rectangle's coordinates and the
   image's pixels the same coordinate space — the module measures the drag against this element's
   own `getBoundingClientRect`, so a centered canvas in a padded, scrolling wrapper moves the image
   and the rectangle together and a crop cannot come out shifted. */
.sn-canvas-wrap {
  flex: 1 1 auto; overflow: auto; padding: var(--s4);
  background: var(--bg); min-height: 0;
  display: flex; align-items: flex-start; justify-content: center;
}
.sn-canvas {
  position: relative; line-height: 0;
  box-shadow: var(--e2); background: #fff;
  cursor: crosshair; touch-action: none; user-select: none;
}
/* The page image is never the drag target: the canvas is, so a pointerdown anywhere over the page
   starts a rectangle rather than a native image-drag, which on a desktop opens the image in a new
   tab and on a tablet does nothing at all. */
.sn-canvas img { display: block; max-width: 100%; height: auto; pointer-events: none; }

/* THE RECTANGLE. `pointer-events:none` so it can be drawn across the whole page without becoming
   the thing the next pointermove is measured against — with it hit-testable, a drag that entered
   its own rectangle would stop tracking. */
.sn-box {
  position: absolute; border: 1.5px solid var(--accent);
  background: rgba(27, 77, 143, 0.18); pointer-events: none;
}
.sn-box[hidden] { display: none; }

.sn-hint {
  padding: var(--s3) var(--s4); font-size: 12px; color: var(--ink-3);
  border-top: 1px solid var(--line);
}
.sn-empty { padding: var(--s5); font-size: 13px; color: var(--ink-3); text-align: center; }

/* ---- the INSERT bar --------------------------------------------------------------------- */

.sn-foot {
  flex: none; display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  padding: var(--s3) var(--s4);
  border-top: 1px solid var(--line); background: var(--raised);
}
.sn-note { font-size: 11.5px; color: var(--ink-3); }
/* A REFUSAL IS NOT A NOTE: the server's sentence about a box off the page is printed in the danger
   colour and spans the bar, so it cannot be read as the panel's ordinary explanation. */
.sn-err { flex: 1 1 100%; color: var(--danger); font-size: 12px; }
.sn-err[hidden] { display: none; }
.sn-held { flex: 1 1 100%; display: flex; align-items: center; gap: var(--s2);
           flex-wrap: wrap; margin-top: var(--s1); }
.sn-hold-head {
  flex: none; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3);
}
.sn-thumb { height: 26px; border: 1px solid var(--line-2); border-radius: var(--r-sm); }

/* "IN THIS JOB" — EVERY cut the job really holds, one button each.
   IT WRAPS RATHER THAN SCROLLING SIDEWAYS: this row is a count a person is checking ("there are
   four") and a row that scrolls hides its own end, which is how a list of evidence comes to be
   silently short. It is also the LAST row in the bar, so it takes the full width and the INSERT
   button and the note above it are not pushed around by how many snippets a job has.

   THE BUTTON IS DRAWN AS A SMALL CARD — thumbnail, source, id — because its whole job is to let a
   person RECOGNISE the piece they already cut. A row of bare thumbnails gives no way to tell two
   crops of the same document apart, and the id is what the affidavit's record will carry. */
.sn-snip {
  display: flex; align-items: center; gap: var(--s2);
  padding: 3px 8px 3px 3px;
  background: var(--raised); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  color: var(--ink); cursor: pointer; font: inherit; text-align: left;
}
.sn-snip:hover { border-color: var(--accent); background: var(--accent-soft); }
.sn-snip .sn-thumb { flex: none; }
.sn-snip-src { font-size: 11.5px; font-weight: 600; max-width: 220px;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sn-snip-meta { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }
.sn-snip:hover .sn-snip-meta { color: var(--accent); }

/* A PHONE GETS THE SAME PANEL, ONE COLUMN. MEASURED reasoning rather than taste: the document list
   is 280px and the page needs the rest, so at 390px wide the two cannot both be on screen — the
   list becomes a capped, scrolling band above the page. The head's sub-line goes, because at 390px
   it wraps onto the title and reads as part of it. */
@media (max-width: 900px) {
  .sn-body { flex-direction: column; }
  .sn-docs { width: 100%; max-height: 190px; border-right: none; border-bottom: 1px solid var(--line); }
  .sn-head .sn-sub { display: none; }
  .sn-canvas-wrap { padding: var(--s2); }
}
