/* =====================================================
   highlight-select.css
   PURPOSE: Styles for the highlight-to-card selection
   feature. Controls the OCR (OCR = Optical Character
   Recognition = technology that reads text from
   images) overlay UI (UI = User Interface = the
   visual elements the user sees and interacts with),
   canvas wrapper, highlight toolbar, PDF page
   navigation, and flashcard preview.

   LAYOUT: a 3-step guided flow — Mark, Extract, Review
   (see the .hs-stepper rules below) — rather than every
   control visible at once. The bottom bar's CONTENT is
   swapped per step by highlight-select.js's
   renderBottomBarForStep(); its own container styling
   lives here as .hs-bottom-bar.

   DEPENDS ON: theme.css (must load first)

   RELATED JS (JS = JavaScript = the programming
   language that controls app behaviour) FILES:
   - js/features/highlight-select.js
   - js/features/pdf-viewer.js
   - js/screens/card-editor.js
   ===================================================== */


/* ── UPLOAD BUTTONS ──────────────────────────────────
   The Image and PDF upload trigger buttons shown
   in the card editor before a file is loaded.      */

.upload-btns {
  display: flex;
  gap: 10px;
}

.upload-label {
  padding: 10px 20px;
  background: var(--color-button-bg);
  color: var(--color-button-text);
  border-radius: var(--border-radius);
  border: var(--border-width) var(--border-style) var(--color-button-border);
  cursor: pointer;
  font-size: var(--font-size-small);
  display: inline-block;
  transition: background 0.15s;
}

.upload-label:hover {
  background: var(--color-button-hover);
}

/* Hidden file inputs — triggered by .upload-label clicks */
#file-input-image,
#file-input-pdf {
  display: none;
}


/* ── HEADER ───────────────────────────────────────────
   Close button + step title, centered via a right-side
   spacer matching the close button's own width — keeps
   the title visually centered whether or not #pdf-nav
   (its own row, right below) is showing.            */

.hs-header {
  display:         flex;
  align-items:     center;
  gap:             12px;
  width:           100%;
}

.hs-header__title {
  flex:        1;
  text-align:  center;
  font-size:   var(--font-size-headline);
  font-weight: 700;
  color:       var(--color-text-primary);
}

.hs-header__spacer {
  width:       32px;
  flex-shrink: 0;
}

/* Close button — circular icon button, same treatment
   as the rest of the app's small round icon buttons
   (Edit/Delete on the Scheduler list, etc).          */
#btn-close {
  width:            32px;
  height:           32px;
  border-radius:    50%;
  background:       var(--ios-tertiarySystemFill);
  color:            var(--ios-systemGray);
  border:           none;
  cursor:           pointer;
  display:          flex;
  align-items:      center;
  justify-content:  center;
  flex-shrink:      0;
  transition:       background 0.15s;
}

#btn-close:hover {
  background: var(--ios-secondarySystemFill);
}


/* ── PDF PAGE NAVIGATION ─────────────────────────────
   Its own compact row directly under the header —
   only shown while marking (step 1) AND only once a
   multi-page PDF has actually loaded (both controlled
   by JS: loadPDF() shows it on file load,
   goToStep() hides it again outside step 1). Hidden
   by default so a plain image source never reveals an
   empty nav row. */

#pdf-nav {
  display:          none;           /* JS toggles to flex      */
  align-items:      center;
  justify-content:  center;
  gap:              14px;
  width:            100%;
}

#pdf-nav button {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  width:            28px;
  height:           28px;
  border-radius:    50%;
  background:       var(--ios-tertiarySystemFill);
  color:            var(--color-text-primary);
  border:           none;
  cursor:           pointer;
  transition:       background 0.15s, opacity 0.15s;
}

#pdf-nav button:hover:not(:disabled) {
  background: var(--ios-secondarySystemFill);
}

#pdf-nav button:disabled {
  opacity: 0.35;
  cursor:  not-allowed;
}

#page-info {
  font-size:   var(--font-size-footnote);
  font-weight: 600;
  color:       var(--color-text-secondary);
}


/* ── STEPPER ──────────────────────────────────────────
   Mark → Extract → Review. Three states per step, set
   by highlight-select.js's updateStepperUI():
   .hs-step--done      (past — filled, checkmark)
   .hs-step--active    (current — filled, number)
   .hs-step--upcoming  (future — outlined, dim)
   The connecting line between two steps fills solid
   once the step BEFORE it is done. */

.hs-stepper {
  display:      flex;
  align-items:  center;
  width:        100%;
  padding:      2px 10px 0;
}

.hs-step {
  display:        flex;
  flex-direction: column;
  align-items:    center;
  gap:            6px;
  width:          46px;
  flex-shrink:    0;
}

.hs-step__dot {
  width:            26px;
  height:           26px;
  border-radius:    50%;
  display:          flex;
  align-items:      center;
  justify-content:  center;
  font-size:        12px;
  font-weight:      800;
  transition:       background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.hs-step__label {
  font-size:      10px;
  font-weight:    700;
  letter-spacing: 0.04em;
  transition:     color 0.2s ease;
}

.hs-step-line {
  flex:       1;
  height:     2px;
  background: var(--color-border);
  margin:     0 4px 18px;
  transition: background 0.2s ease;
}

.hs-step-line--filled {
  background: var(--color-accent-amber);
}

/* Upcoming (default) state */
.hs-step--upcoming .hs-step__dot {
  border: 2px solid var(--color-border);
  color:  var(--color-text-secondary);
}
.hs-step--upcoming .hs-step__label {
  color: var(--color-text-secondary);
}

/* Active (current) state */
.hs-step--active .hs-step__dot {
  background: var(--color-accent-amber);
  color:      #fff;
}
.hs-step--active .hs-step__label {
  color: var(--color-accent-amber);
}

/* Done (past) state — same fill as active, swaps its
   number for a checkmark icon via JS. */
.hs-step--done .hs-step__dot {
  background: var(--color-accent-amber);
  color:      #fff;
}
.hs-step--done .hs-step__label {
  color: var(--color-accent-amber);
}


/* ── STATUS MESSAGE ──────────────────────────────────
   Small text shown below the stepper. Updated by
   highlight-select.js to reflect current state
   e.g. "Finding words… 42%", "Drag across words to
   mark them", error messages.                        */

#status {
  font-size:   var(--font-size-small);
  color:       var(--color-text-muted);
  min-height:  20px;
  text-align:  center;
  width:       100%;
}


/* ── CANVAS WRAPPER ──────────────────────────────────
   Holds two stacked canvas (canvas = an HTML
   element used to draw graphics via JavaScript)
   elements:
   - #image-canvas  — the rendered image or PDF page
   - #selection-canvas — the highlight overlay drawn
                         on top by highlight-select.js
   Visible during Mark/Extract (steps 1-2), hidden
   during Review (step 3) — see goToStep() — when
   #flashcard takes its place instead.               */

#canvas-wrapper {
  position:      relative;
  display:       block;
  width:         100%;
  background:    var(--ios-systemGray5);
  border:        var(--border-width) var(--border-style) var(--color-border);
  border-radius: var(--border-radius-card);
  overflow:      hidden;        /* clips zoomed/panned content to this fixed viewport */
  cursor:        crosshair;
  max-width:     100%;
  touch-action:  none;      /* stops the browser's own pinch-zoom/scroll from
                                fighting the custom pan/pinch handled in JS */
  /* flex-shrink: 0 — .highlight-select-overlay (modal.css) is a
     column flex container with a FIXED height (100% of the
     viewport) and its own overflow-y: auto, meaning it's
     supposed to grow scrollable once its content is taller than
     the screen. Without this, flexbox's default shrink behavior
     does the opposite for a tall image/PDF page: it squeezes
     THIS wrapper down to whatever fits inside that fixed height
     instead of letting the overlay's total content height
     exceed it — and since this wrapper clips its own content
     (overflow: hidden, above, for the pan/zoom viewport), the
     squeezed-away bottom portion of the image was just gone,
     not scrollable to. Confirmed directly: before this, a tall
     test image's own canvas rendered at its full intended
     height, but this wrapper was measured at barely a third of
     that, and the overlay's scrollHeight exactly equalled its
     clientHeight (i.e. nothing was even registering as
     overflowing for it to scroll to). flex-shrink: 0 keeps this
     wrapper at its natural (image-aspect-ratio) height no matter
     how tall that is, so the overlay is what ends up taller than
     the screen and scrollable, the way it was always meant to. */
  flex-shrink:   0;
}

/* Everything that pans/scales together as one unit — see
   highlight-select.js's applyViewTransform(). transform-
   origin:0 0 keeps the scale/translate math in that file
   simple: scale always happens from the content's own
   top-left corner, not its center. #canvas-wrapper itself
   never transforms, so it stays a stable clipping viewport. */
#canvas-transform-target {
  position:        relative;
  transform-origin: 0 0;
}

#image-canvas {
  display: block;
}

/* Selection canvas sits directly on top of the
   image canvas. Pointer events pass through to
   the wrapper for drag detection.                */
#selection-canvas {
  position: absolute;
  top: 0;
  left: 0;
}


/* ── DETECTING OVERLAY ────────────────────────────────
   Covers the canvas while runWordDetection() (the upfront
   whole-page OCR pass) is running — dragging can't do
   anything useful yet since there's nothing to hit-test
   against. Replaces the old magnifier loupe: that existed
   to help place a free-hand rectangle precisely near text
   at the image's edge, which selecting detected WORDS
   instead makes unnecessary — there's no small target to
   miss in the first place. Hidden once _wordsReady (JS
   toggles display). */
.hs-detecting-overlay {
  position:         absolute;
  inset:            0;
  display:          none;      /* JS toggles to flex */
  align-items:      center;
  justify-content:  center;
  background-color: color-mix(in srgb, var(--ios-systemGray5) 55%, transparent);
  z-index:          15;
}

/* Bigger than the bottom bar's own inline spinner (same
   .hs-extracting__spinner class, reused rather than
   duplicated) — this one needs real visual weight centered
   over the whole canvas, not just sitting inline in a row. */
.hs-detecting-overlay .hs-extracting__spinner {
  width:       32px;
  height:      32px;
  border-width: 3px;
}


/* ── FLASHCARD PREVIEW (Review step) ─────────────────
   The two-half card preview shown during step 3.
   Top half = Question (yellow tint).
   Bottom half = Answer (green tint).
   Hidden by default — shown in place of #canvas-wrapper
   once extraction succeeds (goToStep(3)).           */

#flashcard {
  display:       none;           /* JS toggles to block     */
  width:         100%;
  background:    var(--color-card-bg);
  border-radius: var(--border-radius-card);
  border:        none;
  box-shadow:    var(--shadow-elevation-1);
  overflow:      hidden;
  /* Same reasoning as #canvas-wrapper's own flex-shrink: 0
     comment — a long extracted answer could make this taller
     than the screen; this keeps it scrollable-to instead of
     letting flexbox squeeze it down and clip the bottom off. */
  flex-shrink:   0;
}

/* Shared half styles */
.card-half {
  padding:        20px;
  min-height:     110px;
  display:        flex;
  flex-direction: column;
  gap:            6px;
}

/* Question half — subtle yellow tint over
   the card background                            */
#card-question-half {
  background:     var(--tint-highlight-yellow-faint);
  border-bottom:  var(--border-width) solid var(--color-border);
  /* explicit --color-border (hairline), not
     --color-card-border, which is transparent now
     that cards are borderless elsewhere — this divider
     needs to stay visible to separate the two halves */
}

/* Answer half — subtle green tint over the
   card background                               */
#card-answer-half {
  background: var(--tint-highlight-green-faint);
}

/* Small uppercase label above each card half text */
.card-label {
  display:        inline-flex;
  align-items:    center;
  gap:            6px;
  font-size:      var(--font-size-small);
  font-weight:    bold;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

#card-question-half .card-label {
  color: var(--color-highlight-yellow);
}

#card-answer-half .card-label {
  color: var(--color-confidence-5);       /* Theme green */
}

/* The extracted text content area */
.card-text {
  font-size:   var(--font-size-body);
  color:       var(--color-card-text);
  min-height:  40px;
  white-space: pre-wrap;
  line-height: 1.5;
}

/* Shown before any text is extracted */
.card-placeholder {
  font-size:   var(--font-size-small);
  color:       var(--color-text-muted);
  font-style:  italic;
}


/* ── BOTTOM BAR ───────────────────────────────────────
   Pinned to the very bottom of the screen in EVERY step
   (not just Review) — a fixed dock rather than a normal-
   flow element, so it never eats into the space available
   for viewing/marking the image above it the way an
   in-flow bar of varying height (Mark's two rows vs.
   Review's one) would. Its CONTENT still swaps per step
   (see renderBottomBarForStep() in highlight-select.js);
   this file only styles the container plus the pieces
   that content is built from, below.

   Safe to anchor straight to the real viewport: this
   whole overlay is appended to document.body (not
   #screen-container), so it's outside the router's
   screen-transition animations entirely — none of the
   "position:fixed inside an animated ancestor" issues
   fixed elements elsewhere in this app have needed
   working around apply here.

   #hs-bottom-bar-spacer (plain document flow, sized by
   setupBottomBarSpacer()'s ResizeObserver in
   highlight-select.js) reserves matching space at the
   end of the scrollable content so the last of the
   canvas/flashcard never ends up hidden behind this. */
#hs-bottom-bar-spacer {
  /* Same reasoning as #canvas-wrapper's own flex-shrink: 0
     comment — without this, flexbox could squeeze the spacer's
     own reserved height down on a tall page, letting the fixed
     bar it's meant to reserve room for cover part of the
     content instead. */
  flex-shrink: 0;
}

.hs-bottom-bar {
  position:         fixed;
  left:             0;
  right:            0;
  bottom:           0;
  z-index:          10;
  background-color: color-mix(in srgb, var(--color-nav-bg) 90%, transparent);
  backdrop-filter:      blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-top:       var(--border-width) solid var(--color-border);
  padding:          14px 16px calc(14px + var(--safe-area-bottom));
}

/* --- Step 1 (Mark): mode segmented control + Undo + Next --- */

.hs-segmented {
  display:       flex;
  gap:           4px;
  background:    var(--ios-tertiarySystemFill);
  border-radius: var(--radius-md);
  padding:       4px;
  height:        44px;
  margin-bottom: 12px;
}

/* Base style for both color toggle segments */
.color-btn {
  flex:            1;
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  gap:             7px;
  border:          1.5px solid transparent;
  border-radius:   9px;
  background:      transparent;
  cursor:          pointer;
  font-size:       var(--font-size-footnote);
  font-weight:     700;
  color:           var(--color-text-secondary);
  transition:      border-color 0.15s, background 0.15s, color 0.15s;
}

/* Small filled circle used as a color legend instead
   of a 🟡/🟢 emoji — matches the highlight-pen colors
   exactly via the theme.css tokens. */
.color-dot {
  display:       inline-block;
  width:         9px;
  height:        9px;
  border-radius: 50%;
  flex-shrink:   0;
}

.color-dot--yellow {
  background-color: var(--color-highlight-yellow);
}

.color-dot--green {
  background-color: var(--color-confidence-5);
}

/* Yellow = Question mode. Uses the dedicated highlight-
   pen legend token (theme.css), not the app's accent
   tint — this is a content color-code, independent of
   whatever the interactive accent color happens to be. */
#btn-yellow.active {
  border-color: var(--color-highlight-yellow);
  background:   var(--tint-highlight-yellow-medium);
  color:        var(--color-highlight-yellow);
}

/* Green = Answer mode */
#btn-green.active {
  border-color: var(--color-confidence-5);
  background:   var(--tint-highlight-green-medium);
  color:        var(--color-confidence-5);
}

.hs-actions-row {
  display: flex;
  gap:     10px;
}

/* Base button reset — overrides any global button
   styles that may conflict from main.css          */
.hs-actions-row button,
.hs-review-actions button {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  gap:             7px;
  height:          48px;
  border:          none;
  border-radius:   var(--radius-md);
  cursor:          pointer;
  font-size:       var(--font-size-footnote);
  font-weight:     600;
  transition:      background 0.15s, transform 0.1s;
}

.hs-actions-row button:disabled {
  opacity:      0.4;
  cursor:       not-allowed;
}

/* Undo — secondary action */
#btn-undo {
  flex:       1;
  background: var(--ios-tertiarySystemFill);
  color:      var(--color-text-primary);
}

#btn-undo:hover:not(:disabled) {
  background: var(--ios-secondarySystemFill);
}

/* Next: Extract Text — primary action, advances to step 2 */
#btn-extract {
  flex:       2.2;
  background: var(--color-button-bg);
  color:      var(--color-button-text);
  font-weight: 700;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--color-button-bg) 35%, transparent);
}

#btn-extract:hover:not(:disabled) {
  background: var(--color-button-hover);
}

/* --- Step 2 (Extract): running state --- */

.hs-extracting {
  display:         flex;
  align-items:     center;
  justify-content: center;
  gap:             10px;
  padding:         10px 0 2px;
}

.hs-extracting__spinner {
  width:         18px;
  height:        18px;
  border-radius: 50%;
  border:        2.5px solid var(--ios-tertiarySystemFill);
  border-top-color: var(--color-accent-amber);
  animation:     hs-spin 0.8s linear infinite;
}

@keyframes hs-spin {
  to { transform: rotate(360deg); }
}

.hs-extracting__label {
  font-size:   var(--font-size-footnote);
  font-weight: 600;
  color:       var(--color-text-secondary);
}

/* --- Step 3 (Review): Redo + Save --- */

.hs-review-actions {
  display:     flex;
  align-items: center;
  gap:         10px;
}

#btn-redo-marking {
  padding:    0 16px;
  height:     48px;
  background: transparent;
  color:      var(--color-accent-amber);
}

#btn-redo-marking:hover {
  background: var(--tint-accent-soft);
}

#btn-save-extracted {
  flex:        1;
  height:      52px;
  background:  var(--color-button-bg);
  color:       var(--color-button-text);
  font-size:   var(--font-size-body);
  font-weight: 700;
  box-shadow:  0 4px 14px color-mix(in srgb, var(--color-button-bg) 40%, transparent);
}

#btn-save-extracted:hover {
  background: var(--color-button-hover);
  transform:  scale(1.02);
}
