/* The answer-sheet scanner (creator/assessment_tools_scan.html).
   The outline flash is the creator's main feedback, so it is thick and lasts ~0.9s.
   Colour is never the only signal — #scan-status says the same thing in words. */

.scan-stage {
  position: relative;
  aspect-ratio: 4 / 3;
  max-height: 70vh;
  background: var(--color-surface-sunken, #EDE7E4);
  /* One quiet rule, no bevel: a thick inset border read as an unrendered video. The
     flash feedback is a thick OUTLINE drawn inside the edge (below), so it stays loud. */
  border: 1px solid var(--color-border, #D6CFCB);
  border-radius: 12px;
  outline: 6px solid transparent;
  outline-offset: -6px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: outline-color .15s ease-out;
}

.scan-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

/* The view controls transform the video through the CSSOM (never a style attribute). */
.scan-video { transform-origin: 0 0; }
.scan-view { border: 1px solid var(--color-border, #D6CFCB); border-radius: 8px; padding: .75rem; }
.scan-view-grid { display: grid; grid-template-columns: 6.5rem 1fr 3rem; align-items: center; gap: .25rem .75rem; }
.scan-view-grid .form-range { margin: 0; }

/* A sheet-shaped frame to aim at. pointer-events:none so it never eats a click. Its box is set
   from the script (answer-sheet-camera.js `guideRect`) to sit inside the camera's picture, not the
   stage; this inset is only the shape it has before the camera reports its size. */
.scan-guide {
  position: absolute;
  inset: 6% 18%;
  border: 2px dashed rgba(255, 255, 255, .7);
  border-radius: 6px;
  pointer-events: none;
}

/* The sheet the reader found, over the picture. Sized from the script to the stage's pixels. */
.scan-overlay { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.scan-stage[data-guidance="ready"] .scan-guide { border-color: var(--color-success, #15803D); border-style: solid; }
.scan-stage[data-guidance="warn"] .scan-guide { border-color: var(--color-warning, #D97706); }

.scan-placeholder {
  text-align: center;
  color: var(--color-muted-fg, #6B625C);
  padding: 1rem;
}
.scan-placeholder-icon { font-size: 3rem; display: block; margin-bottom: .5rem; }

.scan-stage.scan-flash-ok   { outline-color: var(--color-success, #15803D); animation: scan-pulse .9s ease-out; }
.scan-stage.scan-flash-warn { outline-color: var(--color-warning, #D97706); animation: scan-pulse .9s ease-out; }
.scan-stage.scan-flash-err  { outline-color: var(--color-error, #DC2626);   animation: scan-pulse .9s ease-out; }

@keyframes scan-pulse {
  0%   { box-shadow: 0 0 0 0 currentColor; }
  30%  { box-shadow: 0 0 0 6px rgba(0, 0, 0, .08); }
  100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .scan-stage.scan-flash-ok, .scan-stage.scan-flash-warn, .scan-stage.scan-flash-err { animation: none; }
}

#scan-status.scan-status-ok   { color: var(--color-success, #15803D); }
#scan-status.scan-status-warn { color: #8A5A10; }
#scan-status.scan-status-err  { color: var(--color-error, #DC2626); }

.scan-log-warnings { font-size: .8rem; color: var(--color-muted-fg, #6B625C); }

/* "Scan with your phone" (T3): pointless on the phone itself, so it is not shown on a
   phone-width screen or a touch-first device. */
.scan-phone-qr { image-rendering: pixelated; background: #fff; border-radius: .25rem; }
@media (max-width: 767.98px), (pointer: coarse) {
  .scan-phone-panel { display: none; }
}

/* ── Design QA r2 ─────────────────────────────────────────────────────────── */

/* Idle, the stage is only a placeholder: capped so the upload fallback is not pushed below
   the fold. It takes its full 4:3 height once the camera is live. */
.scan-stage[data-state="idle"] { max-height: min(50vh, 420px); margin-inline: auto; background: var(--color-surface-raised, #F5F2F0); }

/* The phone link is one line with an ellipsis; the full address is on title. */
/* min-width: 0 down the chain, or a flex child grows to the URL's full width (121px overflow at 1440). */
.scan-phone-text { min-width: 0; }
.scan-phone-text > .d-flex { min-width: 0; }
.scan-phone-url { display: block; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Segmented Single/Multi: the chosen segment in brand ink, not a cool slate fill. */
.btn-check:checked + .scan-seg {
  background: var(--color-primary, #7B5F5F); border-color: var(--color-primary, #7B5F5F); color: #fff;
}

/* Scan sheet waits as an outline until the camera is live, so Start scanner is the
   only primary on screen before then. */
#scan-capture:disabled {
  background: transparent; color: var(--color-primary, #7B5F5F);
  border-color: var(--color-border-strong, #C8BDB6); opacity: 1; cursor: not-allowed; pointer-events: auto;
  color: var(--color-muted-fg, #6B625C);
}
#scan-phone-copy { text-decoration: none; }
#scan-phone-copy .scan-copy-text { text-decoration: underline; }

/* Upload: the visually-hidden input drives the label button's states. */
.scan-upload-input:disabled + .scan-upload-btn { opacity: .5; pointer-events: none; }
.scan-upload-input:focus-visible + .scan-upload-btn { outline: 2px solid var(--color-primary, #7B5F5F); outline-offset: 2px; }

@media (max-width: 575.98px) {
  /* Used one-handed while holding paper: every control reaches 44px. */
  .scan-seg { min-height: 44px; display: inline-flex; align-items: center; }
  .scan-switch-row { min-height: 44px; display: flex; align-items: center; gap: .5rem; }
  .scan-switch-row .form-check-input { width: 2.5rem; height: 1.35rem; margin-top: 0; }
  .scan-switch-row .form-check-label { min-height: 44px; display: inline-flex; align-items: center; }
}
