/* ==========================================================================
   upload-portal — the few components the Synergy kit doesn't carry.
   --------------------------------------------------------------------------
   Everything here is built from synergy.css tokens, per BRAND.md §13.6, and
   is listed in the project README so the additions stay accounted for:

     .tally      countable weekly progress marks
     .dropzone   the file-choosing affordance
     .picked     the list of files about to be sent
     .sheet      the contact sheet of a week's scans
     .stage      the dark surround a scan is judged against
     .pager      previous / position / next in the viewer

   Link it after synergy.css.
   ========================================================================== */

/* --- The tally ----------------------------------------------------------
   A .progress-track says "nearly there"; a tally lets an admin count the
   five that are missing, which is the question they actually came to ask.
   Weekly quotas run 14-21, so the marks stay countable. Beyond 60 the page
   falls back to .progress-track, which stops being a lie about precision. */

.tally { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.tally .grp { display: flex; gap: 4px; }
.tally i {
  display: block; width: 3px; height: 22px; border-radius: 1px;
  background: var(--brand-tint-2);
}
.tally i.on { background: var(--brand); }
.tally i.over { background: var(--brand-pale); }   /* uploaded past the quota */

.tally-line {
  margin-top: 7px;
  font-size: var(--text-sm);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.tally-line strong { color: var(--brand-ink); font-weight: 650; }

/* --- Choosing files -----------------------------------------------------
   Dashed and brand-coloured, the same "additive" language as .btn-add. */

.dropzone {
  display: block; width: 100%;
  padding: 24px 18px;
  text-align: center;
  background: var(--surface-2);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.dropzone:hover, .dropzone.over {
  background: var(--brand-tint);
  border-color: var(--brand);
}
.dropzone.over { border-style: solid; }
.dropzone .lead { display: block; font-weight: 600; color: var(--brand-ink); }
.dropzone .hint { display: block; margin-top: 3px; font-size: var(--text-sm); color: var(--muted); }
.dropzone input[type=file] { display: none; }
/* Without JavaScript the input stays visible and the zone is just a frame. */
.dropzone.plain { cursor: default; }
.dropzone.plain input[type=file] { display: block; margin: 12px auto 0; }
.dropzone.plain:hover { background: var(--surface-2); border-color: var(--border-strong); }

.picked { list-style: none; padding: 0; margin: 12px 0 0; }
.picked li {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 0; border-top: 1px solid var(--border);
}
.picked .thumb {
  flex: none; width: 42px; height: 52px;
  object-fit: cover; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-3);
}
.picked .thumb--doc {
  display: grid; place-items: center;
  font-size: var(--text-xs); font-weight: 650; color: var(--muted);
}
.picked .nm { flex: 1; min-width: 0; font-size: var(--text-sm); word-break: break-all; }
.picked .lose {
  flex: none; width: auto; padding: 5px 10px; font-size: var(--text-sm);
  background: transparent; background-image: none; color: var(--muted);
  border: 1px solid var(--border); box-shadow: none;
}
.picked .lose:hover {
  background: var(--danger-wash); color: var(--danger);
  border-color: var(--danger-border-soft); box-shadow: none; transform: none;
}

/* --- Contact sheet ------------------------------------------------------
   A week at a glance. A blank or crooked scan shows up here without
   anything being opened. */

.sheet {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 14px; margin: 16px 0 0; padding: 0; list-style: none;
}
.sheet .card { overflow: hidden; }
.sheet img { display: block; width: 100%; height: 152px; object-fit: cover; background: var(--surface-3); }
.sheet .doc {
  height: 152px; display: grid; place-items: center;
  background: var(--surface-3); color: var(--muted);
  font-size: var(--text-sm); font-weight: 650;
}
.sheet .cap { padding: 9px 11px; border-top: 1px solid var(--border); }
.sheet .cap strong { display: block; font-size: var(--text-sm); color: var(--brand-ink); }
.sheet .cap span { display: block; font-size: var(--text-xs); color: var(--muted); word-break: break-all; }

/* --- Viewer -------------------------------------------------------------
   The surround stays dark in both themes on purpose: a white page flatters
   an underexposed photograph, and quality is the whole reason for looking.
   The value is the dark theme's own --page-bg, written literally because it
   must not follow the light theme. */

.stage {
  background: #0b1120;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px; text-align: center;
  overflow: auto; max-height: 74vh;
}
.stage img { max-width: 100%; max-height: 70vh; transition: transform 0.15s ease; cursor: zoom-in; }
.stage.zoomed { cursor: zoom-out; }
.stage.zoomed img { max-width: none; max-height: none; width: 190%; cursor: zoom-out; }
.stage embed { width: 100%; height: 70vh; border: 0; background: var(--surface); }

.pager { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.pager .grow { flex: 1; }
.pager .pos {
  font-size: var(--text-sm); color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.pager .btn[aria-disabled="true"] { pointer-events: none; }

/* --- Small shared pieces ------------------------------------------------ */

.stack { display: flex; flex-direction: column; gap: 14px; }
.between { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.between .grow { flex: 1; min-width: 0; }

.empty {
  padding: 26px; text-align: center;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
}

/* The week rows on the dashboard: a .row-link that also carries a tally,
   so it needs to wrap rather than squeeze on a narrow window. */
.week-row { flex-wrap: wrap; }
.week-row .meter { flex: 1 1 190px; }

@media (max-width: 560px) {
  .stage.zoomed img { width: 300%; }
  .sheet { grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); }

  /* The kit's controls are sized for a mouse - 28px on .btn-back, 39px on a
     primary. Staff photograph documents on phones, so on a small screen
     every control gets a finger-sized target. Desktop is left exactly as
     the kit draws it. */
  button, .btn, .btn-back, .btn-add {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* --- Collapsible sections ------------------------------------------------
   Built on <details>/<summary>, so a section is open and readable with no
   JavaScript at all and the browser handles the keyboard for us. Used
   wherever a page holds more rows than anybody wants to scroll past: a
   hundred programs on the settings page, a year of weeks on a dashboard.

   The marker is drawn here rather than left to the browser's triangle,
   which differs per platform and cannot be coloured. */

.fold {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  overflow: hidden;
}
.fold + .fold { margin-top: 8px; }

.fold > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  cursor: pointer;
  font-weight: 600;
  color: var(--brand-ink);
  list-style: none;          /* Safari */
  transition: background 0.15s ease;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary:hover { background: var(--brand-tint); }
.fold > summary:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--brand);
}

/* The marker: a chevron that turns as the section opens. */
.fold > summary::before {
  content: "";
  flex: none;
  width: 7px; height: 7px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
.fold[open] > summary::before { transform: rotate(45deg); }
.fold > summary:hover::before { border-color: var(--brand); }

.fold > summary .grow { flex: 1; min-width: 0; }
.fold > summary .sub {
  font-weight: 400;
  font-size: var(--text-sm);
  color: var(--muted);
}

.fold .fold-body {
  padding: 4px 14px 16px;
  border-top: 1px solid var(--border);
}

/* Reduced motion: the chevron still turns, it just does not animate. */
@media (prefers-reduced-motion: reduce) {
  .fold > summary::before, .fold > summary { transition: none; }
}

/* --- Searching a long list ----------------------------------------------
   The agency runs over a hundred programs. A list that long is not something
   anybody scrolls, so every screen that shows one gets a box above it. */

.finder { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.finder input[type=search] { flex: 1; min-width: 180px; }
.finder .tally-line { margin: 0; }

/* A picker with a hundred options: taller, so more of it is on screen at
   once, and the browser's own type-ahead does the rest. */
select.tall { min-height: 44px; }
