/* ==========================================================================
   styles.css — VOID Door Scanner
   Dark, quiet chrome; deliberately loud verdicts. Everything is tuned for a
   phone held at arm's length in a dark club, so the interface recedes and the
   pass/fail screen does all the shouting.
   ========================================================================== */

:root {                                        /* design tokens, defined once and reused everywhere */
  /* Surfaces — slightly blue-tinted blacks read as richer than neutral grey */
  --bg:        #08080a;                        /* page background (pure #000 crushes shadows on OLED) */
  --surface:   #101014;                        /* raised surface: sheets and inputs */
  --glass:     rgb(12 12 16 / 0.72);           /* translucent bar colour, paired with a backdrop blur */
  --line:      rgb(255 255 255 / 0.09);        /* hairline border */
  --line-2:    rgb(255 255 255 / 0.16);        /* stronger border for focus and hover */

  /* Text */
  --ink:       #fafafa;                        /* primary text */
  --ink-2:     #a1a1ab;                        /* secondary text */
  --ink-3:     #6c6c78;                        /* tertiary text and placeholders */

  /* Accent */
  --accent:    #8b5cf6;                        /* violet, used only for focus and small highlights */

  /* Verdict colours — saturated on purpose, these must survive a dark doorway */
  --ok:        #05c66c;                        /* admitted */
  --ok-ink:    #00190e;                        /* text on the green field */
  --bad:       #f5162e;                        /* rejected */
  --bad-ink:   #ffffff;                        /* text on the red field */
  --warn:      #ffb020;                        /* indeterminate: never treated as pass or fail */
  --warn-ink:  #231700;                        /* text on the amber field */

  /* Geometry */
  --r-sm: 10px;                                /* small radius: pills */
  --r-md: 14px;                                /* medium radius: inputs and buttons */
  --r-lg: 22px;                                /* large radius: sheets */

  /* Safe areas */
  --safe-top:    env(safe-area-inset-top, 0px);    /* iOS notch inset */
  --safe-bottom: env(safe-area-inset-bottom, 0px); /* iOS home-indicator inset */
  --safe-left:   env(safe-area-inset-left, 0px);   /* landscape inset */
  --safe-right:  env(safe-area-inset-right, 0px);  /* landscape inset */
}                                              /* end tokens */

* { box-sizing: border-box; }                  /* predictable sizing: padding/border never blow out a width */
html, body {                                   /* full-height, non-scrolling app shell */
  height: 100%;                                /* let child screens use 100% height reliably */
  margin: 0;                                   /* remove default body margin */
  overflow: hidden;                            /* the app never page-scrolls; only the manual sheet moves */
  overscroll-behavior: none;                   /* kills pull-to-refresh, which would reload mid-queue */
}                                              /* end shell */
body {                                         /* base typography and colour */
  background: var(--bg);                       /* dark ground */
  color: var(--ink);                           /* light text */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", Roboto, system-ui, sans-serif; /* native UI font: zero download, renders instantly, and looks current on each OS */
  font-size: 16px;                             /* base size for rem maths */
  line-height: 1.45;                           /* comfortable default leading */
  -webkit-font-smoothing: antialiased;         /* crisper light-on-dark text on WebKit */
  -webkit-tap-highlight-color: transparent;    /* removes the grey flash box on tap */
  user-select: none;                           /* stops accidental text selection when staff tap quickly */
  touch-action: manipulation;                  /* disables double-tap-to-zoom for snappier taps */
}                                              /* end body */

/* --------------------------------------------------------------------------
   SCREENS — only one is visible at a time; app.js toggles .is-active
   -------------------------------------------------------------------------- */
.screen {                                      /* base screen container */
  position: fixed;                             /* pinned to the viewport, immune to scroll */
  inset: 0;                                    /* stretch to all four edges */
  display: none;                               /* hidden unless activated */
}                                              /* end screen */
.screen.is-active { display: block; }          /* the active screen is shown; children position themselves */

/* --------------------------------------------------------------------------
   BRAND
   -------------------------------------------------------------------------- */
.stack {                                       /* generic vertical stack */
  display: flex;                               /* flex column layout */
  flex-direction: column;                      /* one item per row */
  align-items: center;                         /* horizontally centred */
}                                              /* end stack */
.stack--centred {                              /* stack centred in its parent */
  position: absolute;                          /* positioned against the screen */
  inset: 0;                                    /* fill the screen... */
  justify-content: center;                     /* ...so this centres vertically */
}                                              /* end centred stack */
.mark {                                        /* the ring logomark: a void, i.e. a hole with a bright edge */
  width: 56px;                                 /* fixed size */
  height: 56px;                                /* square, so border-radius makes a circle */
  border-radius: 50%;                          /* circle */
  border: 1.5px solid rgb(255 255 255 / 0.28); /* faint outer ring */
  box-shadow: inset 0 0 22px rgb(139 92 246 / 0.4), 0 0 34px rgb(139 92 246 / 0.15); /* violet glow inside and out, giving the ring depth without an image */
  margin-bottom: 1.5rem;                       /* gap before the wordmark */
}                                              /* end mark */
.mark--pulse { animation: pulse 1.8s ease-in-out infinite; } /* the boot screen's loading indicator, replacing a spinner */
@keyframes pulse {                             /* slow breathe */
  0%, 100% { opacity: 0.35; transform: scale(0.94); } /* dim and slightly small */
  50%      { opacity: 1;    transform: scale(1); }    /* bright and full size */
}                                              /* end pulse */
.brand {                                       /* the VOID wordmark */
  font-size: 2rem;                             /* confident but not shouty */
  font-weight: 650;                            /* semibold; the tracking does the work, not the weight */
  letter-spacing: 0.28em;                      /* wide tracking reads as a logotype */
  text-indent: 0.28em;                         /* compensates the trailing letter-space so it stays optically centred */
  line-height: 1;                              /* tight so the subtitle sits close */
}                                              /* end brand */
.brand-sub {                                   /* small label under the wordmark */
  margin-top: 0.6rem;                          /* breathing room below the logotype */
  font-size: 0.8rem;                           /* small */
  font-weight: 450;                            /* light, so it recedes behind the wordmark */
  letter-spacing: 0.06em;                      /* barely tracked; wide tracking here would compete with the logotype */
  color: var(--ink-3);                         /* de-emphasised */
}                                              /* end subtitle */

/* --------------------------------------------------------------------------
   LOGIN
   -------------------------------------------------------------------------- */
.login {                                       /* login form layout */
  position: absolute;                          /* positioned against the screen */
  inset: 0;                                    /* fill it */
  display: flex;                               /* vertical stack */
  flex-direction: column;                      /* one control per row */
  justify-content: center;                     /* centre vertically */
  gap: 0.9rem;                                 /* consistent spacing between controls */
  width: 100%;                                 /* full width... */
  max-width: 400px;                            /* ...but stay readable on tablets */
  margin: 0 auto;                              /* centre horizontally */
  padding: 0 1.5rem;                           /* inner gutter so fields never touch the edges */
}                                              /* end login */
.login__head {                                 /* branding block above the password field */
  position: static;                            /* overrides .stack--centred's absolute positioning inside the form */
  inset: auto;                                 /* clear the inset */
  margin-bottom: 2rem;                         /* generous gap before the field */
}                                              /* end login head */
.field { display: block; }                     /* each labelled field is a full-width block */
.field__label {                                /* the label above an input */
  display: block;                              /* own line */
  margin-bottom: 0.5rem;                       /* gap above the input */
  font-size: 0.78rem;                          /* small but readable, not a tiny caps label */
  font-weight: 500;                            /* medium */
  color: var(--ink-2);                         /* muted */
}                                              /* end field label */
input[type="password"], input[type="text"] {   /* all visible text inputs share one look */
  width: 100%;                                 /* full width of the field */
  padding: 0.95rem 1rem;                       /* tall enough to hit with a thumb */
  font-family: inherit;                        /* match the app font rather than the browser default */
  font-size: 16px;                             /* 16px exactly — anything smaller makes iOS zoom the page on focus */
  color: var(--ink);                           /* light text */
  background: var(--surface);                  /* raised surface */
  border: 1px solid var(--line);               /* subtle edge */
  border-radius: var(--r-md);                  /* soft corners */
  outline: none;                               /* we draw our own focus state below */
  user-select: text;                           /* re-enable selection inside inputs (body disabled it) */
  transition: border-color 0.15s ease, box-shadow 0.15s ease; /* smooth focus transition */
}                                              /* end inputs */
input::placeholder { color: var(--ink-3); }    /* placeholders sit a step below secondary text */
input:focus {                                  /* focus state */
  border-color: var(--accent);                 /* violet edge shows which field is live */
  box-shadow: 0 0 0 3.5px rgb(139 92 246 / 0.18); /* soft focus ring, visible in a dark room */
}                                              /* end focus */
.fineprint {                                   /* notice under the login button */
  margin: 0.25rem 0 0;                         /* small top gap, no bottom margin */
  text-align: center;                          /* centred under the button */
  font-size: 0.75rem;                          /* small */
  color: var(--ink-3);                         /* muted */
}                                              /* end fineprint */
.sr-only {                                     /* visually hidden but still a real form control (unlike display:none, which password managers ignore) */
  position: absolute;                          /* removed from the layout flow */
  width: 1px;                                  /* collapsed to a single pixel */
  height: 1px;                                 /* collapsed to a single pixel */
  padding: 0;                                  /* no padding to expand it */
  margin: -1px;                                /* pulled off its own box */
  overflow: hidden;                            /* clip any overflow */
  clip-path: inset(50%);                       /* clip to nothing */
  white-space: nowrap;                         /* prevent wrapping from expanding the height */
  border: 0;                                   /* no border to render */
}                                              /* end screen-reader-only utility */

/* --------------------------------------------------------------------------
   BUTTONS
   -------------------------------------------------------------------------- */
.btn {                                         /* shared button base */
  display: block;                              /* full-width block button */
  width: 100%;                                 /* stretch to container */
  padding: 1.05rem 1rem;                       /* ~54px tall: comfortably above the 44px touch-target minimum */
  font-family: inherit;                        /* inherit the app font */
  font-size: 1rem;                             /* readable label */
  font-weight: 600;                            /* semibold; sentence case rather than shouty caps */
  letter-spacing: 0;                           /* no tracking — tracked-out button labels look dated */
  border: 0;                                   /* no default chrome */
  border-radius: var(--r-md);                  /* soft corners */
  cursor: pointer;                             /* desktop affordance */
  transition: transform 0.08s ease, opacity 0.15s ease, background 0.15s ease; /* quick press feedback */
}                                              /* end button base */
.btn:active { transform: scale(0.985); }       /* subtle tactile push on tap */
.btn:disabled { opacity: 0.45; cursor: default; } /* clearly inert while a request is in flight */
.btn--primary {                                /* main call-to-action: solid near-white on black reads as premium and has the highest possible contrast */
  color: #0a0a0c;                              /* near-black label */
  background: var(--ink);                      /* near-white fill */
}                                              /* end primary */
.btn--ghost {                                  /* secondary/cancel button */
  color: var(--ink);                           /* normal text colour */
  background: rgb(255 255 255 / 0.06);         /* barely-there fill */
  border: 1px solid var(--line);               /* outlined rather than solid */
}                                              /* end ghost */
.btn--next {                                   /* the reset button on the result overlay */
  margin-top: 2.25rem;                         /* pushed well below the verdict so it is never tapped by reflex */
  max-width: 320px;                            /* not absurdly wide on tablets */
  color: inherit;                              /* takes the verdict's ink colour */
  background: rgb(0 0 0 / 0.16);               /* darkened chip that works on green, red and amber alike */
  border: 1.5px solid currentColor;            /* outlined in the verdict's own ink, which keeps contrast on every background */
}                                              /* end next button */

/* --------------------------------------------------------------------------
   MESSAGES
   -------------------------------------------------------------------------- */
.msg {                                         /* inline message base */
  margin: 0;                                   /* no default margin */
  padding: 0.8rem 1rem;                        /* comfortable padding */
  font-size: 0.88rem;                          /* readable */
  border-radius: var(--r-md);                  /* matches inputs */
}                                              /* end message */
.msg--error {                                  /* error variant */
  color: #ffc9cd;                              /* pale red text */
  background: rgb(245 22 46 / 0.12);           /* translucent red wash */
  border: 1px solid rgb(245 22 46 / 0.3);      /* red edge */
}                                              /* end error message */

/* --------------------------------------------------------------------------
   CAMERA VIEWPORT — full-bleed behind the floating bars
   -------------------------------------------------------------------------- */
.viewport {                                    /* area that hosts the video feed */
  position: absolute;                          /* fills the whole scanner screen */
  inset: 0;                                    /* all four edges */
  overflow: hidden;                            /* crop the video rather than letting it stretch the layout */
  background: #000;                            /* black behind the feed while the camera warms up */
}                                              /* end viewport */
#reader { width: 100%; height: 100%; }         /* html5-qrcode's container fills the viewport */
#reader video {                                /* the video element the library injects */
  width: 100% !important;                      /* override the library's inline sizing */
  height: 100% !important;                     /* fill vertically too */
  object-fit: cover !important;                /* crop-to-fill so there are no black bars in portrait */
}                                              /* end video */
#reader__dashboard_section, #reader__header_message { display: none !important; } /* hide the library's built-in UI; we ship our own */
.reticle {                                     /* aiming frame overlay */
  position: absolute;                          /* layered over the video */
  top: 50%;                                    /* centre vertically... */
  left: 50%;                                   /* ...and horizontally */
  width: min(66vw, 290px);                     /* scales with the phone but caps on tablets */
  aspect-ratio: 1;                             /* perfect square target */
  transform: translate(-50%, -50%);            /* pull back by half its own size to truly centre it */
  pointer-events: none;                        /* never intercepts taps meant for the video */
}                                              /* end reticle */
.reticle::before {                             /* soft dark vignette outside the target area */
  content: "";                                 /* required for a pseudo-element to render */
  position: absolute;                          /* fills the reticle box */
  inset: -50vmax;                              /* extends far past the screen edges */
  background: rgb(0 0 0 / 0.34);               /* dims everything... */
  -webkit-mask: radial-gradient(circle at 50% 50%, transparent 0 32%, #000 33%); /* ...except a clear hole over the target (WebKit prefix for iOS) */
  mask: radial-gradient(circle at 50% 50%, transparent 0 32%, #000 33%); /* standard property, draws focus to the centre */
}                                              /* end vignette */
.reticle__c {                                  /* each of the four corner brackets */
  position: absolute;                          /* placed individually at the corners */
  width: 30px;                                 /* bracket arm length */
  height: 30px;                                /* bracket arm length */
  border: 2.5px solid #fff;                    /* bright white so it is visible against any ticket */
}                                              /* end brackets */
.reticle__c:nth-child(1) { top: 0; left: 0; border-right: 0; border-bottom: 0; border-radius: 12px 0 0 0; }      /* top-left corner */
.reticle__c:nth-child(2) { top: 0; right: 0; border-left: 0; border-bottom: 0; border-radius: 0 12px 0 0; }      /* top-right corner */
.reticle__c:nth-child(3) { bottom: 0; left: 0; border-right: 0; border-top: 0; border-radius: 0 0 0 12px; }      /* bottom-left corner */
.reticle__c:nth-child(4) { bottom: 0; right: 0; border-left: 0; border-top: 0; border-radius: 0 0 12px 0; }      /* bottom-right corner */
.reticle__scan {                               /* the sweeping decode line */
  position: absolute;                          /* moves within the reticle */
  left: 6%;                                    /* inset from the brackets */
  right: 6%;                                   /* inset from the brackets */
  height: 2px;                                 /* thin line */
  border-radius: 2px;                          /* rounded ends */
  background: linear-gradient(90deg, transparent, var(--accent), transparent); /* fades out at both ends so it reads as a beam */
  box-shadow: 0 0 12px 1px rgb(139 92 246 / 0.7); /* violet glow */
  animation: sweep 2.6s ease-in-out infinite;  /* travels down and back, signalling that decoding is live */
}                                              /* end scan line */
@keyframes sweep {                             /* top to bottom and back */
  0%, 100% { top: 8%; opacity: 0.15; }         /* parked at the top, faint */
  50%      { top: 90%; opacity: 0.9; }         /* at the bottom, bright */
}                                              /* end sweep */

/* --------------------------------------------------------------------------
   FLOATING BARS — translucent glass over the live camera
   -------------------------------------------------------------------------- */
.topbar {                                      /* status bar floating over the camera */
  position: absolute;                          /* overlays the viewport */
  top: 0; left: 0; right: 0;                   /* pinned across the top */
  z-index: 10;                                 /* above the video */
  display: flex;                               /* horizontal row */
  align-items: center;                         /* vertically centred */
  justify-content: space-between;              /* identity left, stats right */
  gap: 0.75rem;                                /* space between clusters */
  padding: calc(0.7rem + var(--safe-top)) calc(1rem + var(--safe-right)) 0.7rem calc(1rem + var(--safe-left)); /* safe-area-aware gutters */
  background: var(--glass);                    /* translucent dark */
  backdrop-filter: blur(20px) saturate(1.5);   /* frosted glass over the moving video */
  -webkit-backdrop-filter: blur(20px) saturate(1.5); /* Safari needs the prefix */
  border-bottom: 1px solid var(--line);        /* hairline edge */
  font-size: 0.75rem;                          /* compact */
}                                              /* end topbar */
.topbar__id { display: flex; align-items: center; gap: 0.5rem; min-width: 0; } /* left cluster; min-width:0 lets the label truncate */
.topbar__user {                                /* signed-in account */
  color: var(--ink-2);                         /* muted */
  overflow: hidden;                            /* clip long addresses */
  text-overflow: ellipsis;                     /* show … instead of overflowing */
  white-space: nowrap;                         /* keep on one line */
  max-width: 46vw;                             /* never crowd out the stats */
}                                              /* end user label */
.dot {                                         /* connectivity indicator */
  width: 7px;                                  /* small */
  height: 7px;                                 /* square → circle */
  border-radius: 50%;                          /* circle */
  background: var(--ok);                       /* green when online (default) */
  box-shadow: 0 0 8px currentColor;            /* faint halo so it reads at a glance */
  color: var(--ok);                            /* drives the halo colour */
  flex: none;                                  /* never shrink */
  transition: background 0.2s ease, color 0.2s ease; /* smooth change when connectivity flips */
}                                              /* end dot */
.dot.is-offline { background: var(--bad); color: var(--bad); } /* red when the device loses connectivity */
.topbar__stats { display: flex; gap: 0.4rem; flex: none; } /* right cluster holds the two counters */
.pill {                                        /* a counter chip */
  display: inline-flex;                        /* lets the number and label sit on one baseline */
  align-items: baseline;                       /* align number with label */
  gap: 0.28rem;                                /* small gap between number and label */
  padding: 0.22rem 0.55rem;                    /* compact chip */
  border-radius: var(--r-sm);                  /* rounded */
  font-size: 0.68rem;                          /* small label */
  color: var(--ink-2);                         /* muted label */
  background: rgb(255 255 255 / 0.06);         /* faint fill */
}                                              /* end pill */
.pill b { font-size: 0.9rem; font-weight: 650; font-variant-numeric: tabular-nums; } /* tabular figures stop the counters jittering as they tick up */
.pill i {                                      /* the "/300" total that follows the admitted figure */
  font-style: normal;                          /* the <i> is used for grouping, not emphasis */
  font-size: 0.72rem;                          /* smaller than the live figure it qualifies */
  font-variant-numeric: tabular-nums;          /* same non-jittering figures */
  color: var(--ink-3);                         /* dimmer, so the eye lands on the admitted count first */
  margin-left: -0.16rem;                       /* pulls the slash tight against the number */
}                                              /* end total */
.pill--ok b  { color: var(--ok); }             /* admitted count in green */
.pill--bad b { color: var(--bad); }            /* rejected count in red */
.pill.is-stale { opacity: 0.45; }              /* dimmed while a refresh is failing, so a frozen number never looks authoritative */

.camhint {                                     /* instruction text above the toolbar */
  position: absolute;                          /* floats over the video */
  left: 1rem;                                  /* inset from the left edge */
  right: 1rem;                                 /* inset from the right edge */
  bottom: calc(6.2rem + var(--safe-bottom));   /* sits just above the toolbar */
  z-index: 10;                                 /* above the video */
  margin: 0;                                   /* no default paragraph margin */
  text-align: center;                          /* centred under the reticle */
  font-size: 0.82rem;                          /* small */
  color: rgb(255 255 255 / 0.72);              /* semi-transparent white */
  text-shadow: 0 1px 8px #000;                 /* keeps it legible over a bright ticket in frame */
}                                              /* end hint */
.camhint.is-error {                            /* camera failures */
  color: #ffd0d4;                              /* pale red text */
  background: rgb(245 22 46 / 0.2);            /* red wash so it reads as a problem, not an instruction */
  border: 1px solid rgb(245 22 46 / 0.4);      /* red edge */
  border-radius: var(--r-md);                  /* rounded panel */
  padding: 0.7rem 0.9rem;                      /* room to breathe */
  backdrop-filter: blur(12px);                 /* keeps it readable over the frozen frame */
  -webkit-backdrop-filter: blur(12px);         /* Safari prefix */
}                                              /* end camera error */

.toolbar {                                     /* control bar floating over the camera */
  position: absolute;                          /* overlays the viewport */
  bottom: 0; left: 0; right: 0;                /* pinned across the bottom */
  z-index: 10;                                 /* above the video */
  display: flex;                               /* horizontal */
  background: var(--glass);                    /* translucent dark */
  backdrop-filter: blur(20px) saturate(1.5);   /* frosted glass */
  -webkit-backdrop-filter: blur(20px) saturate(1.5); /* Safari prefix */
  border-top: 1px solid var(--line);           /* hairline edge */
  padding-bottom: var(--safe-bottom);          /* clears the iOS home indicator */
}                                              /* end toolbar */
.tool {                                        /* each toolbar control */
  flex: 1;                                     /* equal widths so every target is large */
  display: flex;                               /* stack icon over label */
  flex-direction: column;                      /* vertical */
  align-items: center;                         /* centred */
  gap: 0.3rem;                                 /* small gap between icon and label */
  padding: 0.75rem 0.25rem;                    /* tall tap target */
  background: none;                            /* no fill */
  border: 0;                                   /* no chrome */
  color: var(--ink-2);                         /* muted until active */
  font-family: inherit;                        /* inherit app font */
  cursor: pointer;                             /* desktop affordance */
  transition: color 0.15s ease;                /* smooth state change */
}                                              /* end tool */
.tool:active { color: var(--ink); }            /* brightens on press */
.tool__icon {                                  /* the inline SVG glyph — sharp at any density, unlike emoji, and consistent across OSes */
  width: 22px;                                 /* icon box */
  height: 22px;                                /* icon box */
  fill: none;                                  /* stroke-only icons */
  stroke: currentColor;                        /* follows the button's text colour, so state changes are free */
  stroke-width: 1.8;                           /* even weight at this size */
  stroke-linecap: round;                       /* rounded ends read as modern */
  stroke-linejoin: round;                      /* rounded joins */
}                                              /* end icon */
.tool__label { font-size: 0.62rem; font-weight: 500; letter-spacing: 0.02em; } /* small caption under the icon */
.tool.is-on { color: var(--warn); }            /* torch-on state glows amber */
.tool--toggle input { display: none; }         /* hide the raw checkbox; the whole label is the control */
.tool--toggle:has(input:checked) { color: var(--ok); } /* AUTO turns green when enabled */

/* --------------------------------------------------------------------------
   MANUAL ENTRY SHEET
   -------------------------------------------------------------------------- */
.manual {                                      /* slide-up sheet for typing a token by hand */
  position: absolute;                          /* overlays the scanner screen */
  left: 0; right: 0; bottom: 0;                /* anchored to the bottom edge */
  z-index: 20;                                 /* above the toolbar */
  padding: 0.75rem 1.25rem calc(1.25rem + var(--safe-bottom)); /* inner gutter plus home-indicator clearance */
  background: var(--surface);                  /* solid surface: the keyboard is up, so glass would just be noise */
  border-top: 1px solid var(--line);           /* top edge */
  border-radius: var(--r-lg) var(--r-lg) 0 0;  /* rounded top corners like a native sheet */
  box-shadow: 0 -24px 70px rgb(0 0 0 / 0.85);  /* dramatic lift off the page */
  animation: sheet-up 0.24s cubic-bezier(0.32, 0.72, 0, 1); /* springy iOS-style slide in */
}                                              /* end manual sheet */
@keyframes sheet-up { from { transform: translateY(100%); } } /* start fully off-screen, settle at rest */
.manual__grip {                                /* the small handle bar at the top of the sheet */
  width: 36px;                                 /* short */
  height: 4px;                                 /* thin */
  margin: 0 auto 1rem;                         /* centred, with a gap below */
  border-radius: 2px;                          /* pill shape */
  background: var(--line-2);                   /* faint */
}                                              /* end grip */
.manual__form { display: flex; flex-direction: column; gap: 1rem; } /* stacked field and buttons */
.manual__row { display: flex; gap: 0.75rem; }  /* side-by-side cancel/confirm buttons */

/* --------------------------------------------------------------------------
   RESULT OVERLAY — the whole point of the app
   -------------------------------------------------------------------------- */
.result {                                      /* fullscreen verdict */
  position: fixed;                             /* covers everything */
  inset: 0;                                    /* all four edges */
  z-index: 50;                                 /* above every other layer */
  display: flex;                               /* centred column */
  flex-direction: column;                      /* badge → status → name → meta → button */
  align-items: center;                         /* horizontally centred */
  justify-content: center;                     /* vertically centred */
  padding: 2rem calc(1.5rem + var(--safe-right)) calc(2rem + var(--safe-bottom)) calc(1.5rem + var(--safe-left)); /* safe-area-aware gutters */
  text-align: center;                          /* centre all text */
  animation: verdict-in 0.18s cubic-bezier(0.32, 0.72, 0, 1); /* fast pop so the verdict feels locked to the scan */
}                                              /* end result */
.result[hidden] { display: none; }             /* the hidden attribute must win over display:flex */
@keyframes verdict-in {                        /* entrance animation */
  from { opacity: 0; transform: scale(1.04); } /* start slightly oversized and transparent */
  to   { opacity: 1; transform: scale(1); }    /* settle at natural size */
}                                              /* end animation */
.result::after {                               /* subtle top-down sheen for depth on the flat colour field */
  content: "";                                 /* required for a pseudo-element */
  position: absolute;                          /* covers the overlay */
  inset: 0;                                    /* all edges */
  background: radial-gradient(ellipse at 50% 22%, rgb(255 255 255 / 0.16), transparent 62%); /* soft highlight behind the badge */
  pointer-events: none;                        /* never blocks the reset tap */
}                                              /* end sheen */
.result--ok   { background: var(--ok);   color: var(--ok-ink); }   /* admitted */
.result--bad  { background: var(--bad);  color: var(--bad-ink); }  /* rejected */
.result--warn { background: var(--warn); color: var(--warn-ink); } /* indeterminate: do NOT admit or reject yet */
.result__badge {                               /* the circular icon disc */
  position: relative;                          /* sits above the ::after sheen */
  z-index: 1;                                  /* above the sheen */
  display: grid;                               /* centres the icon perfectly */
  place-items: center;                         /* dead centre */
  width: clamp(88px, 26vw, 132px);             /* fluid: large on any phone, capped on tablets */
  aspect-ratio: 1;                             /* circle */
  border-radius: 50%;                          /* circle */
  background: rgb(255 255 255 / 0.18);         /* translucent disc that works on all three colour fields */
  box-shadow: 0 0 0 1.5px rgb(255 255 255 / 0.25), 0 18px 50px rgb(0 0 0 / 0.22); /* crisp rim plus a soft drop shadow */
}                                              /* end badge */
.ico {                                         /* every verdict glyph */
  display: none;                               /* hidden until its verdict class matches */
  width: 52%;                                  /* scales with the badge */
  height: 52%;                                 /* scales with the badge */
  fill: none;                                  /* stroke-only */
  stroke: currentColor;                        /* inherits the verdict ink colour */
  stroke-width: 2.6;                           /* heavy enough to read across a doorway */
  stroke-linecap: round;                       /* rounded ends */
  stroke-linejoin: round;                      /* rounded joins */
}                                              /* end icon */
.result--ok   .ico--ok   { display: block; }   /* tick on green */
.result--bad  .ico--bad  { display: block; }   /* cross on red */
.result--warn .ico--warn { display: block; }   /* exclamation on amber */
.result__status {                              /* the verdict word — the single most important element */
  position: relative;                          /* above the sheen */
  z-index: 1;                                  /* above the sheen */
  margin-top: 1.5rem;                          /* gap under the badge */
  font-size: clamp(2.2rem, 11vw, 3.9rem);      /* fluid and enormous */
  font-weight: 750;                            /* very heavy */
  letter-spacing: -0.02em;                     /* slightly tightened: large type needs less tracking, not more */
  line-height: 1.02;                           /* tight for multi-word verdicts */
}                                              /* end status */
.result__name {                                /* the buyer's name */
  position: relative;                          /* above the sheen */
  z-index: 1;                                  /* above the sheen */
  margin-top: 0.9rem;                          /* separated from the verdict */
  font-size: clamp(1.25rem, 6vw, 1.9rem);      /* large enough to read and say out loud */
  font-weight: 550;                            /* medium-bold */
  word-break: break-word;                      /* long names wrap instead of overflowing */
  opacity: 0.92;                               /* a touch softer than the verdict */
}                                              /* end name */
.result__meta {                                /* secondary detail line */
  position: relative;                          /* above the sheen */
  z-index: 1;                                  /* above the sheen */
  margin-top: 0.6rem;                          /* gap under the name */
  font-size: 0.9rem;                           /* small */
  font-weight: 450;                            /* light */
  opacity: 0.72;                               /* de-emphasised */
  max-width: 34ch;                             /* keeps the line readable */
}                                              /* end meta */
.result .btn--next { position: relative; z-index: 1; } /* keep the reset button above the sheen so it stays tappable */

@media (prefers-reduced-motion: reduce) {      /* respect users who disable motion */
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } /* effectively disable animation, including the scan sweep */
}                                              /* end reduced-motion block */
