/* =============================================================================
   KilusNa — SUBMIT REPORT WIZARD (submit.html) — wizard.css
   -----------------------------------------------------------------------------
   Everything in the 4-step "Submit a Report" flow: guest sign-in gate, the
   stepper, the category picker, the details form, the article editor, the
   review step, the action bar and both wizard modals.

   Contract:
   - Consumes ONLY tokens.css — zero hex/rgb/hsl here, so light + dark both
     resolve from custom properties.
   - NO media queries: every breakpoint lives in mobile.css, which loads
     AFTER this file — its "Submit wizard" section owns the grid columns, the
     stacked action bar and the ≤647 type floor.
   - Reuses components.css recipes (.btn, .form-group, .form-control,
     .report-card, .modal-*) rather than restyling them; this file only adds
     what the wizard introduces.
   - Focus comes from base_theme's global :focus-visible (2px --accent-text
     outline) plus :focus-within where a hidden child carries it (upload).
     Reduced motion is already crushed globally in base_theme, so decorative
     transitions below need no per-component block.

   Load order: tokens → base_theme → layout → components → wizard → mobile →
   auth-state → dark.
   ============================================================================= */

/* ===== Wizard shell ======================================================= */
/* Card plate over --bg; also the .auth-only wrapper, so stepper, steps,
   action bar and both modals swap in as one unit (?auth=1). No display is
   declared — auth-state owns visibility — and no overflow, so the dropdowns
   and modals inside can never be clipped. */
.wizard {
  padding: var(--s6);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}

/* main[tabindex="-1"]: focus is moved here programmatically, so it scrolls
   without painting a ring around the page */
.wizard-main:focus { outline: none; }

/* ===== Guest gate (logged-out default) ====================================
   EXTRAPOLATED — the live page has no logged-out variant. Built from system
   ingredients: card shell, accent-soft disc, standard button pair. Hidden
   once ?auth=1 sets html.is-auth (auth-state's 0,2,1 beats this 0,1,0). */
.submit-gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s4);
  padding: var(--s7) var(--s5);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  text-align: center;
}

.submit-gate-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: 50%;
  color: var(--accent-text);   /* 5.38:1 on --accent-soft light / 9.14:1 dark */
}

.submit-gate-icon svg { width: 26px; height: 26px; }
.submit-gate h1 { font-size: var(--fs-h2); font-weight: 800; color: var(--text); letter-spacing: -0.01em; }

.submit-gate-text {
  max-width: 54ch;
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--body);
}

.submit-gate-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s3); }
.submit-gate-actions .btn { min-width: 168px; }

/* ===== Stepper ============================================================
   <nav> > <ol> of number nodes; JS swaps .active / .completed / .pending on
   the nodes (and .completed on the connectors) exactly as the live page
   does, and moves aria-current="step". */
.wizard-stepper { margin-bottom: var(--s6); }
.wizard-stepper ol { display: flex; align-items: flex-start; }

.wizard-step {
  flex: 1 1 0;                 /* even label columns… */
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

/* …bridged by fixed-width connectors (live's .wizard-step-line) */
.wizard-step-line {
  flex: 0 0 auto;
  width: clamp(16px, 5vw, 56px);
  height: 2px;
  margin-top: 15px;            /* centre on the 32px node (16 − 1) */
  background: var(--border-strong);
  border-radius: var(--r-pill);
  transition: background .15s ease;
}

.wizard-step-line.completed { background: var(--accent); }

.wizard-step-node {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}

/* pending: quiet plate with a visible edge (a bare --card node vanishes) */
.wizard-step-node.pending { background: var(--hover); border-color: var(--border); color: var(--faint); }

/* active: gold disc + inset --accent-text rim — the 3:1 defining edge a bare
   --accent disc cannot carry on --card (1.6:1) */
.wizard-step-node.active {
  background: var(--accent);
  border-color: var(--accent-text);
  box-shadow: inset 0 0 0 2px var(--accent-text);
  color: var(--on-accent);     /* 11.42:1 on the gold fill */
}

/* completed: the .section-count plate recipe (accent-text on accent-soft) */
.wizard-step-node.completed { background: var(--accent-soft); border-color: var(--accent-text); color: var(--accent-text); }

.wizard-step-label { font-size: var(--fs-label); font-weight: 600; color: var(--muted); text-align: center; }
.wizard-step.active .wizard-step-label { color: var(--text); }

/* ===== Step canvas (header, title, subtitle) ============================== */
.wizard-step-content { min-width: 0; }
.wizard-header { margin-bottom: var(--s5); }

.wizard-title { font-size: var(--fs-h2); font-weight: 800; color: var(--text); letter-spacing: -0.01em; }

.wizard-subtitle {
  margin-top: 6px;
  max-width: 72ch;
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--muted);
}

/* ===== Category picker (step 1) =========================================== */
/* Base = single column; mobile.css grows it to 2 (≥641) and 3 (≥1024). */
.category-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s3); }

.category-card {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s4);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}

.category-card:hover { background: var(--hover); border-color: var(--border-strong); }

/* Selected is declared twice on purpose: .selected is live's class,
   aria-pressed is the accessible source of truth this page ships — both must
   read identically so a wizard.js flipping only one still renders right. */
.category-card.selected,
.category-card[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent-text); }

.category-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: var(--accent-soft);
  border-radius: var(--r-btn);
  color: var(--accent-text);
  transition: background .15s ease, color .15s ease;
}

.category-icon svg { width: 22px; height: 22px; }

.category-card.selected .category-icon,
.category-card[aria-pressed="true"] .category-icon { background: var(--accent); color: var(--on-accent); }

.category-title { font-size: var(--fs-title); font-weight: 700; color: var(--text); }
.category-desc { font-size: var(--fs-desc); line-height: 1.55; color: var(--muted); }

/* ===== Reassurance cards (step 1 footer) ==================================
   EXTRAPOLATED: two semantic plates — anonymity rides the accent family,
   privacy the green family (same language as .auth-verified-badge). */
.info-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--s3); margin-top: var(--s5); }

/* Icon column spans both text rows: title and copy stack beside it */
.info-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "icon title" "icon text";
  column-gap: var(--s3);
  align-items: start;
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
}

.info-card-icon { grid-area: icon; width: 20px; height: 20px; margin-top: 2px; }
.info-card-title { grid-area: title; font-size: var(--fs-title); font-weight: 700; color: var(--text); }
.info-card-text { grid-area: text; margin-top: 4px; font-size: var(--fs-desc); line-height: 1.55; color: var(--body); }
.info-card.anonymity { background: var(--accent-soft); border-color: var(--accent-line); }
.info-card.anonymity .info-card-icon,
.info-card.anonymity .info-card-title { color: var(--accent-text); }
.info-card.privacy { background: var(--green-soft); border-color: var(--green); }
.info-card.privacy .info-card-icon { color: var(--green); }

/* ===== Form scaffolding (step 2) ========================================== */
/* Single column while stacked; mobile.css makes it 3-up at ≥1024. */
.form-columns { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s5); }

.form-column {
  display: flex;
  flex-direction: column;
  min-width: 0;                 /* lets grid children shrink instead of
                                   forcing a horizontal scrollbar */
}

.form-column .form-group:last-child { margin-bottom: 0; }

/* Full-width band under the columns (Additional Information) */
.wizard-step-content > section { margin-top: var(--s5); }

/* Label furniture: "required" asterisk + the grey em-dash note live puts in
   the field labels */
.required { color: var(--red); }
.label-note { font-size: var(--fs-meta); font-weight: 400; color: var(--faint); }
.form-hint { font-size: var(--fs-meta); line-height: 1.5; color: var(--muted); }

/* ===== Entity picker (search field + dropdown) ============================ */
.entity-selector { position: relative; }
.entity-add-btn { margin-top: var(--s2); }

/* JS-rendered suggestion dropdown — hidden until JS adds .open (live's
   contract), then pinned under the field. Never clipped: neither the section
   nor .wizard declares overflow. */
.entity-search-results {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  left: 0;
  z-index: 40;
  display: none;
  max-height: 260px;
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  box-shadow: var(--shadow-pop);
}

.entity-search-results.open { display: block; }

.entity-result-item {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  cursor: pointer;
}

.entity-result-item + .entity-result-item { border-top: 1px solid var(--border); }
.entity-result-item:hover { background: var(--hover); }

.entity-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  background: var(--accent-soft);
  border-radius: 50%;
  color: var(--accent-text);
}

.entity-avatar svg { width: 16px; height: 16px; }
.entity-name { font-size: var(--fs-desc); font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.entity-role { font-size: var(--fs-meta); color: var(--muted); overflow-wrap: anywhere; }

/* JS-rendered person rows (addEntityRow): live inlines these styles, they
   live here so wizard.js can render bare markup. */
.entity-row {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s3);
  margin-bottom: var(--s2);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
}

/* JS-rendered case chips (#selectedCases) — the system's accent plate as a
   pill, matching live's inline chip */
#selectedCases { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s2); }
#selectedCases:empty { display: none; }   /* empty box must not leave 8px stray */

.case-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  color: var(--accent-text);
  font-size: var(--fs-meta);
  font-weight: 600;
}

.case-chip button { padding: 0 2px; color: inherit; font-size: var(--fs-sm); line-height: 1; }

/* ===== Media upload (step 2) ============================================== */
/* The <label> IS the drop target. The file input keeps .sr-only so it stays
   focusable: tab lands on it, the label's :focus-within paints the ring, the
   native control opens on Enter/Space (live hides it with inline
   display:none, which would strand keyboard users). */
.image-upload {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 132px;
  padding: var(--s5) var(--s4);
  background: var(--bg);
  border: 1.5px dashed var(--input-border);   /* 3.35:1 — the affordance edge */
  border-radius: var(--r-input);
  text-align: center;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}

.image-upload:hover { background: var(--hover); border-color: var(--accent-text); }
.image-upload:focus-within { border-color: var(--accent-text); box-shadow: var(--ring); }
.image-upload-icon { width: 28px; height: 28px; color: var(--accent-text); }
.image-upload-text { font-size: var(--fs-desc); font-weight: 600; color: var(--body); }
.image-upload-hint { font-size: var(--fs-meta); color: var(--muted); }

/* JS flips #photoPreview to display:block (inline), so only spacing lives
   here — the inline style wins over any display this file could set */
#photoPreview { margin-top: var(--s2); }

/* ===== Character counter ================================================== */
.char-counter { margin-top: 6px; font-size: var(--fs-meta); color: var(--muted); text-align: right; }
.char-counter.warning,
.article-stat.warning { color: var(--amber); font-weight: 600; }
.char-counter.error,
.article-stat.error { color: var(--red); font-weight: 700; }

/* ===== Violations checkbox group (step 2) ================================= */
.checkbox-group { display: flex; flex-direction: column; }

.checkbox-item {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;             /* full-size pointer/finger target */
  cursor: pointer;
}

.checkbox-item input { width: 18px; height: 18px; flex-shrink: 0; accent-color: var(--accent); cursor: pointer; }

/* (0,1,1) — ties components' .form-group label and wins by cascade order */
.checkbox-item label { font-size: var(--fs-desc); color: var(--body); cursor: pointer; }

/* ===== Additional Information (step 2) ====================================
   Five sections (property / family / associate / case / project), each with a
   search field, a JS-rendered .entity-search-results dropdown and a
   JS-rendered list of linked rows. mobile.css makes the grid 2-up ≥768. */
.additional-info-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s3); }

.additional-info-section {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  min-width: 0;
  padding: var(--s3);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
}

.additional-info-header { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); }
.additional-info-title { font-size: var(--fs-h4); font-weight: 700; color: var(--text); }
.additional-info-header .btn svg { width: 14px; height: 14px; }
.additional-info-list { display: flex; flex-direction: column; gap: 6px; }

.additional-info-linked-item {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;
  padding: 4px var(--s2) 4px var(--s3);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
}

.additional-info-linked-label { flex: 1; min-width: 0; font-size: var(--fs-xs); color: var(--body); overflow-wrap: anywhere; }

.additional-info-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: var(--r-btn);
  color: var(--muted);
  transition: background .15s ease, color .15s ease;
}

.additional-info-remove:hover { background: var(--hover); color: var(--text); }
.additional-info-remove svg { width: 14px; height: 14px; }

.additional-info-badge {
  padding: 2px 8px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  color: var(--accent-text);
  font-size: var(--fs-badge);
  font-weight: 700;
}

/* ===== Article editor (step 3) ============================================
   Dependency-free: toolbar buttons map data-cmd to document.execCommand over
   a contenteditable region (live uses the Quill 2 CDN bundle — this
   prototype ships zero network dependencies). */
.article-editor-wrapper { display: flex; flex-direction: column; gap: var(--s3); }

.editor-toolbar {
  display: flex;
  flex-wrap: wrap;              /* 6 tools never overflow 360px; wrap also
                                   survives 200% text zoom */
  gap: 4px;
  padding: 4px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
}

.editor-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: var(--r-btn);
  color: var(--body);
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.editor-btn:hover { background: var(--card); border-color: var(--border); color: var(--text); }
.editor-btn svg { width: 18px; height: 18px; }

/* JS mirrors execCommand state onto aria-pressed; the plate is the visual
   half (accent-text on accent-soft = 5.38:1 light / 9.14:1 dark) */
.editor-btn[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-text); }

.article-editor-meta { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s3); }
.article-stat { font-size: var(--fs-meta); color: var(--muted); }

.article-editor {
  min-height: 320px;
  padding: var(--s4);
  background: var(--card);
  border: 1px solid var(--input-border);
  border-radius: var(--r-input);
  font-size: var(--fs-base);
  line-height: 1.7;
  color: var(--text);
  overflow-wrap: anywhere;
}

.article-editor:focus { outline: none; border-color: var(--accent-text); box-shadow: var(--ring); }

/* contenteditable output — JS inserts these, so they are styled here */
.article-editor p { margin-bottom: var(--s3); }
.article-editor h2,
.article-editor h3 { margin: var(--s4) 0 var(--s2); color: var(--text); }
.article-editor h2 { font-size: var(--fs-h2); }
.article-editor h3 { font-size: var(--fs-modal); }

.article-editor blockquote {
  margin: var(--s3) 0;
  padding: var(--s2) var(--s3);
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-input) var(--r-input) 0;
  color: var(--body);
}

.article-editor ul,
.article-editor ol { margin-bottom: var(--s3); padding-left: 1.3em; }
.article-editor ul { list-style: disc; }
.article-editor ol { list-style: decimal; }
.article-editor a { color: var(--accent-text); text-decoration: underline; }
.article-editor img { height: auto; margin: var(--s3) 0; border-radius: var(--r-input); }

.article-editor-tips { padding: var(--s4); background: var(--bg); border: 1px solid var(--border); border-radius: var(--r-input); }
.article-editor-tips h4 { margin-bottom: var(--s2); color: var(--text); }

/* block + child margins (not flex) so the disc markers still paint */
.article-editor-tips ul {
  padding-left: 1.15em;
  list-style: disc;
  font-size: var(--fs-desc);
  color: var(--body);
}

.article-editor-tips li + li { margin-top: 4px; }

/* ===== Review step (step 4) =============================================== */
.review-section {
  padding: var(--s4);
  margin-bottom: var(--s3);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
}

.review-section-title { margin-bottom: var(--s2); font-size: var(--fs-title); font-weight: 700; color: var(--text); }

.review-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-desc);
}

.review-item:last-of-type { border-bottom: 0; }
.review-label { flex-shrink: 0; color: var(--muted); font-weight: 500; }

.review-value {
  min-width: 0;
  color: var(--text);
  font-weight: 600;
  text-align: right;
  overflow-wrap: anywhere;
}

/* Standalone blocks (#reviewViolations) read as body copy, not as the
   right-aligned half of a label/value pair */
.review-section > .review-value { color: var(--body); font-weight: 400; text-align: left; }

.review-content-box {
  padding: var(--s3);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  font-size: var(--fs-desc);
  line-height: 1.6;
  color: var(--body);
  white-space: pre-wrap;        /* details/article text keeps its breaks */
  overflow-wrap: anywhere;
}

.review-confirm { margin-top: var(--s5); margin-bottom: 0; }
.review-confirm label { align-items: flex-start; font-size: var(--fs-desc); color: var(--body); }
.review-confirm input { margin-top: 3px; }

/* ===== Action bar ========================================================= */
.wizard-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-top: var(--s6);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
}

.wizard-actions-left,
.wizard-actions-right { display: flex; align-items: center; gap: var(--s2); }

/* ===== Wizard modals ======================================================
   Both overlays ship WITHOUT inline display — components.css keeps
   .modal-overlay hidden and .modal-overlay.open flex-centred, so wizard.js
   reveals them with .open (an inline display:flex works too). */
#wizardPrecheckList { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s2); }

.wizard-precheck-q { font-size: var(--fs-base); line-height: 1.6; color: var(--body); }

/* Candidate cards reuse .report-card, but inside the modal they are plain
   body rows: no vote rail, no thumb, no page-level elevation */
#wizardPrecheckList .report-card { grid-template-columns: minmax(0, 1fr); grid-template-areas: "body"; padding: var(--s3); margin: 0; background: var(--bg); box-shadow: none; }
#wizardPrecheckList .report-body { font-size: var(--fs-desc); line-height: 1.6; color: var(--body); }
#wizardPrecheckList .report-body .btn { margin-top: var(--s2); }
#wizardPrecheckList .report-summary { font-size: var(--fs-sm); color: var(--text); }

#additionalInfoForm .form-group:last-child { margin-bottom: 0; }

/* ===== Small shared variants ==============================================
   EXTRAPOLATED: none of these exist in components.css, and the wizard (or
   the JS templates it renders) needs them. */
.btn-sm { padding: 6px 14px; font-size: var(--fs-xs); }   /* compact "Add" — target stays 44px */

.btn-secondary {               /* soft accent plate (precheck "Link this record") */
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: var(--accent-text);
}

.btn-secondary:hover { background: var(--accent); border-color: var(--accent-text); color: var(--on-accent); }

.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }   /* quiet control */
.btn-ghost:hover { background: var(--hover); color: var(--text); }

/* .form-input is live's field class — wizard.js may port its per-type
   templates verbatim, and components.css only styles .form-control. Same
   recipe, minus font-size (base_theme's `font: inherit` plus mobile.css's
   ≤647 element floor keep iOS from zooming on focus). */
.form-input {
  width: 100%;
  min-height: 44px;
  padding: 9px 12px;
  background: var(--card);
  border: 1px solid var(--input-border);
  border-radius: var(--r-input);
  color: var(--text);
}

.form-input:focus { outline: none; border-color: var(--accent-text); box-shadow: var(--ring); }
