/* Shared analysis-surface styles: the drop zone (all states + magnifier), the
   file chip, and the results (verdict / checks). Loaded by BOTH the public verifier
   /analysis page and the member /analyse page via /shared/dropzone.css, so a
   tweak here updates both. Page chrome (nav, banner, headings, footer) stays
   inline per page. */
:root {
  --bg: #FAFAF8; --fg: #1A1A18; --fg-muted: #6B6B66; --fg-faint: #9C9C96;
  --accent: #1B6B4A; --accent-light: #E8F5EE; --accent-hover: #14553A;
  --border: #E2E2DC; --border-strong: #CDCDC7; --drop-bg: #FFFFFF;
  --radius: 14px; --verify: #1A5276; --verify-light: #E8F0F7;
  --anomaly: #B23A2E; --anomaly-light: #FBEDEB; --anomaly-border: #E7C0BA;
  /* verdict green is deliberately BRIGHTER than the dark brand green so a
     "consistent" result can never be read as brand decoration */
  --consistent: #2F9E44; --consistent-light: #E9F7EC; --consistent-border: #C5E8CC;
  /* standardised action colours: blue = analysis actions */
  --action-analysis: #2F6FAE; --action-analysis-hover: #27578A; --action-analysis-light: #E8F0F7;
  --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --sans: 'DM Sans', sans-serif;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: var(--serif); background: var(--bg); color: var(--fg); min-height: 100vh; -webkit-font-smoothing: antialiased; }
code, pre, .mono { font-family: 'DM Mono', monospace; }
/* serif is the page voice (headings + prose); keep small utility labels,
   badges and the CTA in the sans face so they stay crisp */
.internal-banner, .logo, nav span, .badge, .verdict .tag, .section-title, .dz-run, .dz-select { font-family: var(--sans); }
nav { display: flex; align-items: center; justify-content: space-between; padding: 16px 40px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--bg); z-index: 100; }
.logo { font-weight: 700; font-size: 20px; letter-spacing: -0.5px; color: var(--fg); text-decoration: none; }
.wrap { max-width: 820px; margin: 0 auto; padding: 40px 24px 80px; }

.internal-banner { background: #3A3A36; color: #F3F3EE; font-size: 13px; font-weight: 500; text-align: center; padding: 9px 16px; letter-spacing: 0.2px; }
.internal-banner strong { font-weight: 700; }

h1 { font-family: var(--serif); font-size: 36px; font-weight: 700; letter-spacing: -0.5px; line-height: 1.15; margin-bottom: 12px; }
.subtitle { color: var(--fg-muted); font-size: 17px; line-height: 1.5; margin-bottom: 28px; max-width: 600px; }

/* --- Drop zone (self-contained: select link, drop area, Run button) --- */
/* full width (matches the result boxes below) and a fixed height so the box
   never changes size or disappears across the empty / loading / done states */
.dropzone-wrapper { width: 100%; }
.dropzone { width: 100%; min-height: 310px; display: flex; flex-direction: column; justify-content: center; border: 2px dashed var(--border-strong); border-radius: var(--radius); background: var(--drop-bg); padding: 34px 36px; text-align: center; transition: border-color 0.2s ease, background 0.2s ease; position: relative; cursor: pointer; box-shadow: 0 1px 3px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.03); }
.dropzone.loading { cursor: default; }
.dropzone.dragover { border-color: var(--action-analysis); background: var(--action-analysis-light); }
.dropzone:hover:not(.ready):not(.loading):not(.done) { border-color: var(--action-analysis); transition: border-color 0.4s ease, background 0.2s ease; }   /* colour fades in over 0.4s, back to grey in the base 0.2s (17 Oct 2026) */
.dropzone.ready { border-style: solid; border-color: var(--action-analysis); }
/* ease into the ready state so selecting/dropping a file isn't abrupt */
.dropzone.ready .dz-content { animation: dz-enter 0.5s ease; }
@keyframes dz-enter { from { opacity: 0.3; transform: translateY(4px); } to { opacity: 1; transform: none; } }
/* visually-hidden but functional input (a click anywhere in the box opens it via JS) */
.dz-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); border: 0; }
.dz-content { position: relative; }

/* the corner "change file" link only appears once a file is locked in;
   before that, the select prompt lives in the body (.dz-select-hint) */
.dz-select { position: absolute; top: 16px; left: 22px; font-size: 12.5px; color: var(--action-analysis); text-decoration: underline; text-underline-offset: 2px; z-index: 3; display: none; }
.dropzone.ready .dz-select { display: block; }
.dz-select:hover { color: var(--action-analysis-hover); }

.dz-body { display: block; cursor: pointer; padding: 18px 0 2px; }
.dropzone-icon { width: 60px; height: 60px; margin: 0 auto 18px; background: var(--action-analysis-light); border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: background 0.2s ease; position: relative; }
.dropzone-icon svg.zip-folder { width: 34px; height: 30px; position: relative; z-index: 1; }
/* realistic magnifier: grey rim, translucent blue lens, brown handle. rests
   off-centre over the folder. On hover the ORBIT (position, on the wrapper) and
   the PULSE (size, on the glass) run as two independent animations with
   different durations, so they drift out of phase and never look repetitive. */
.dropzone-icon .mag-orbit { position: absolute; width: 30px; height: 30px; top: 50%; left: 50%; margin: -15px 0 0 -15px; transform: translate(8px, 0); z-index: 2; }
.dropzone-icon .magnifier { display: block; width: 100%; height: 100%; transform: scale(1.12); opacity: 0.9; transition: opacity 0.2s ease; }
.magnifier .mag-lens { fill: rgba(120, 190, 232, 0.4); stroke: #8C99A4; stroke-width: 2; }
.magnifier .mag-handle { stroke: #6E4A2F; stroke-width: 3.4; stroke-linecap: round; }
.dropzone:hover:not(.ready):not(.loading):not(.done) .mag-orbit,
.dropzone.dragover:not(.ready) .mag-orbit { animation: mag-orbit 2.1s linear infinite; }
.dropzone:hover:not(.ready):not(.loading):not(.done) .magnifier,
.dropzone.dragover:not(.ready) .magnifier { opacity: 1; animation: mag-pulse 1.7s ease-in-out infinite; }
@keyframes mag-orbit {
  0%    { transform: translate(8px, 0); }
  12.5% { transform: translate(6px, 4px); }
  25%   { transform: translate(2px, 6px); }
  37.5% { transform: translate(-2px, 5px); }
  50%   { transform: translate(-4px, 0); }
  62.5% { transform: translate(-2px, -5px); }
  75%   { transform: translate(2px, -6px); }
  87.5% { transform: translate(6px, -4px); }
  100%  { transform: translate(8px, 0); }
}
@keyframes mag-pulse {
  0%, 100% { transform: scale(1.13); }
  50%      { transform: scale(1.19); }
}
/* two text lines in every state keeps the box balanced:
   pre-drop = lead + "Click to select a file"; ready = "READY TO ANALYSE" + filename */
.dz-ready-label { display: none; font-family: var(--sans); font-size: 12px; font-weight: 700; letter-spacing: 0.7px; text-transform: uppercase; color: var(--action-analysis); margin-bottom: 6px; }
.dropzone.ready .dz-ready-label { display: block; }
.dz-select-hint { display: block; font-family: var(--sans); font-size: 13px; color: var(--action-analysis); margin-top: 6px; text-decoration: underline; text-underline-offset: 2px; }
.dropzone.ready .dz-select-hint { display: none; }
.dropzone-text { font-size: 18px; font-weight: 500; color: var(--fg); }
.dropzone-text strong { font-weight: 700; word-break: break-all; }
/* filename shown like an OS file entry: folder icon then the name, in black */
.dropzone.ready .dropzone-text { color: var(--fg); font-family: var(--sans); font-size: 15.5px; font-weight: 500; display: inline-flex; align-items: center; gap: 8px; }
.fn-icon { width: 21px; height: 19px; flex-shrink: 0; }
.fn-name { word-break: break-all; text-align: left; }

.dz-run { position: relative; overflow: hidden; display: block; width: 100%; max-width: 380px; margin: 30px auto 0; background: var(--action-analysis); color: #fff; border: none; border-radius: var(--radius); padding: 17px 34px; font-size: 16.5px; font-weight: 600; cursor: pointer; box-shadow: 0 2px 6px rgba(47,111,174,0.2); }
.dz-run > span { position: relative; z-index: 1; }
/* hover in: darker shade wipes in from the left, like a progress bar filling.
   hover out: it stays full-width and simply fades back to the light blue
   (the transform reset is delayed until after the 0.5s fade, so it never
   retracts like a reverse progress bar).
   The fill is a keyframe ANIMATION, not a transition, so every hover restarts
   the wipe from the very beginning — re-hovering mid-fade never resumes a
   half-finished wipe; it's all or nothing. */
.dz-run::before { content: ''; position: absolute; inset: 0; background: var(--action-analysis-hover); transform: scaleX(0); transform-origin: left center; opacity: 0; transition: opacity 0.5s ease, transform 0s linear 0.5s; z-index: 0; }
.dz-run:hover:not(:disabled)::before { opacity: 1; transition: opacity 0s; animation: dz-run-wipe 1.0125s cubic-bezier(0.3, 0, 0.2, 1) forwards; }
@keyframes dz-run-wipe { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* pointer-events:none — no "not-allowed" cursor; the click falls through to the
   box and opens the file picker, and the cursor stays the box's normal pointer */
.dz-run:disabled { background: #E7EAE8; color: #AEB4AF; box-shadow: none; pointer-events: none; }

.dropzone.has-error { border-style: solid; border-color: var(--anomaly); background: var(--anomaly-light); }
.dropzone.has-error .dropzone-icon { background: #fce4e1; }
.dropzone.has-error .dropzone-text { color: var(--anomaly); font-weight: 600; }

/* --- Loading state inside the drop zone (kept NEUTRAL — green would pre-suggest
   a "consistent" outcome; the verdict colours belong only to the checks below) --- */
.dz-loading { display: none; padding: 8px 0 6px; }
/* while analysing, the border pulses in the analysis blue */
.dropzone.loading { border-style: solid; border-color: var(--action-analysis); background: var(--drop-bg); animation: dz-border-pulse 1.7s ease-in-out infinite; }
@keyframes dz-border-pulse {
  0%, 100% { border-color: var(--action-analysis); }
  50% { border-color: var(--action-analysis-light); }
}
.dropzone.loading .dz-content { display: none; }
.dropzone.loading .dz-loading { display: block; }
/* while analysing, the same magnifier searches around the folder */
.dropzone.loading .dz-loading .dropzone-icon { background: var(--action-analysis-light); }
.dropzone.loading .dz-loading .mag-orbit { animation: mag-orbit 2.1s linear infinite; }
.dropzone.loading .dz-loading .magnifier { opacity: 1; animation: mag-pulse 1.7s ease-in-out infinite; }
.dz-loading-title { font-size: 17px; font-weight: 600; color: var(--fg); margin-bottom: 6px; letter-spacing: -0.2px; }
.dz-status { font-size: 13.5px; color: var(--fg-muted); min-height: 18px; }
/* solid and chunky, squared like the site's buttons: no gradient (Andrew, 12 Oct 2026) */
.dz-progress { width: 100%; max-width: 380px; height: 16px; background: #fff; border: 1px solid var(--border-strong); border-radius: 3px; margin: 20px auto 0; overflow: hidden; }
.dz-progress-fill { width: 0; height: 100%; background: var(--action-analysis); }

/* The same animation in a small space (the DeepCheck bar under an export on Compare,
   13 Oct 2026): one row: the folder and magnifier at about half size, the title over
   the status line, then the bar. Markup and pacing: /shared/deepcheck-loading.js. */
.dz-loading.dz-compact { display: flex; align-items: center; gap: 10px; padding: 0; flex: 1; min-width: 0; text-align: left; }
.dz-compact .dropzone-icon { flex: none; margin: 0; zoom: 0.6; background: var(--action-analysis-light); }
.dz-compact .mag-orbit { animation: mag-orbit 2.1s linear infinite; }
.dz-compact .magnifier { opacity: 1; animation: mag-pulse 1.7s ease-in-out infinite; }
.dz-compact .dz-loading-text { flex: 1 1 0; min-width: 0; }
.dz-compact .dz-loading-title { font-size: 13px; font-weight: 700; margin: 0; letter-spacing: 0; line-height: 1.3; }
.dz-compact .dz-status { font-size: 11.5px; min-height: 0; line-height: 1.3; color: var(--fg-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-compact .dz-progress { flex: 0 1 170px; min-width: 70px; max-width: none; height: 12px; margin: 0; }

/* --- Done state: box stays put and same size, naming the analysed file --- */
.dz-done { display: none; padding: 6px 0; }
/* neutral once analysed — green means consistent and red means anomaly, so the
   verdict must live only in the results below, never colour the drop zone */
.dropzone.done { border-style: solid; border-color: var(--border-strong); background: var(--drop-bg); cursor: default; }
.dropzone.done .dz-content { display: none; }
.dropzone.done .dz-done { display: block; }
/* no tick — a checkmark reads as a "clean/pass" verdict. Neutral text only. */
.dz-done-label { font-family: var(--sans); font-size: 12px; font-weight: 700; letter-spacing: 0.7px; text-transform: uppercase; color: var(--fg-muted); margin-bottom: 12px; }
.dz-done-file { font-family: var(--sans); font-size: 15.5px; font-weight: 500; color: var(--fg); display: inline-flex; align-items: center; gap: 8px; }
.dz-done-sub { font-size: 13.5px; color: var(--fg-muted); margin-top: 12px; }

/* bottom-of-page action once results are in (back-to-back files are rare,
   so a fresh page load is the clean reset) */
.analyse-new { text-align: center; margin: 40px 0 8px; }
.analyse-new-btn { display: inline-block; font-family: var(--sans); font-size: 15px; font-weight: 600; color: var(--action-analysis); background: none; border: 2px solid var(--action-analysis); border-radius: var(--radius); padding: 13px 30px; text-decoration: none; transition: background 0.15s ease, color 0.15s ease; }
.analyse-new-btn:hover { background: var(--action-analysis); color: #fff; }
.err { background: var(--anomaly-light); border: 1px solid var(--anomaly-border); color: var(--anomaly); border-radius: 10px; padding: 12px 16px; font-size: 14px; margin-bottom: 24px; }

/* --- Results --- */
#results-container { animation: fade-up 0.5s ease both; margin-top: 28px; }
@keyframes fade-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.verdict { border-radius: var(--radius); padding: 22px 24px; margin-bottom: 8px; border: 1px solid var(--border); }
.verdict.anomaly { background: var(--anomaly-light); border-color: var(--anomaly-border); }
.verdict.consistent { background: var(--consistent-light); border-color: var(--consistent-border); }
.verdict .tag { font-size: 12px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; }
.verdict.anomaly .tag { color: var(--anomaly); }
.verdict.consistent .tag { color: var(--consistent); }
.verdict h2 { font-size: 22px; font-weight: 700; margin: 6px 0 4px; letter-spacing: -0.4px; }
.verdict .meta { font-size: 13px; color: var(--fg-muted); }
.export-rec { font-size: 12.5px; color: var(--fg-muted); margin: -2px 0 18px; }
.export-rec code { font-family: 'DM Mono', monospace; background: #f0f0ec; padding: 1px 6px; border-radius: 5px; }
.export-rec .new { color: var(--action-analysis); font-weight: 600; }
.export-rec .seen { color: var(--fg-faint); }
.section-title { font-size: 13px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase; color: var(--fg-faint); margin: 30px 0 12px; }
.check { border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px; margin-bottom: 12px; background: #fff; }
.check.anomaly { border-color: var(--anomaly-border); background: var(--anomaly-light); }
.check-head { display: flex; align-items: baseline; gap: 8px; }
.badge { font-size: 11px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; padding: 3px 9px; border-radius: 100px; white-space: nowrap; }
.badge.anomaly { background: var(--anomaly); color: #fff; }
.badge.consistent { background: var(--consistent-light); color: var(--consistent); }
.badge.not_assessed { background: #ECECE8; color: var(--fg-faint); }
.check-title { font-weight: 600; font-size: 15px; }
/* status written after the title, in parentheses: "Archive create-system (Consistent)" */
.check-status { font-size: 14px; font-weight: 600; white-space: nowrap; }
.check-status.consistent { color: var(--consistent); }
.check-status.anomaly { color: var(--anomaly); }
.check-status.not_assessed { color: var(--fg-faint); font-weight: 500; }
.check .finding { font-size: 14.5px; line-height: 1.5; margin-top: 8px; }
.check .kv { font-size: 13px; line-height: 1.5; margin-top: 8px; color: var(--fg-muted); }
.check .kv b { color: var(--fg); font-weight: 600; }
/* a provided export's report (Request): what was examined */
.scope-note { font-size: 13px; line-height: 1.5; color: var(--fg-muted); margin: 12px 0 4px; }
.scope-note b { color: var(--fg); font-weight: 600; }
.check .files { margin-top: 8px; }
.check .files span { display: inline-block; font-family: 'DM Mono', monospace; font-size: 12px; background: #fff; border: 1px solid var(--anomaly-border); color: var(--anomaly); border-radius: 6px; padding: 3px 9px; margin: 3px 5px 3px 0; line-height: 1.5; }
details.raw { margin-top: 30px; border: 1px solid var(--border); border-radius: 12px; background: #fff; }
details.raw summary { cursor: pointer; padding: 14px 18px; font-weight: 600; font-size: 14px; }
details.raw pre { padding: 0 18px 18px; font-size: 12px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; color: var(--fg-muted); }

footer { border-top: 1px solid var(--border); color: var(--fg-faint); font-size: 12.5px; line-height: 1.6; padding: 24px 24px 60px; max-width: 820px; margin: 40px auto 0; }
