/* The lens looks at an actual drop photo instead of a drawn box: one of the
   three thumbnails already inside s3.jpg (the Proof screen), cropped to fill
   the frame. url() resolves against this stylesheet, which sits beside the
   image, so one rule serves the homepage and /demo/ alike.

   s3.jpg is 720x1560 and the middle thumbnail measures x 259..460,
   y 613..815 - 201x202. The viewfinder is the whole phone: 36em wide by 78em
   tall (36 / 0.4615). Filling it by height takes 78/202 = 0.386em per source
   pixel, so the whole image is 720 x 0.386 = 278em wide; the crop lands at
   -236.7em vertically, and horizontally at -(100 + 20.8)em - its own offset
   plus half the 41.6em it overhangs the frame by, which centres it. */
/* The DelPod walkthrough - the phone, the screens it cycles, and the paper
   run sheet that turns into them. Shared verbatim by the homepage and by the
   standalone /demo/ page; neither owns it, so a change lands on both.

   Page layout, typography and captions live with each page. Nothing here
   positions the component or sets a font size in px - it scales entirely off
   --pw, the phone's width, which the page supplies. */

:root {
  /* The phone's own palette - it is a render of the app, so these are the
     app's colours (src/theme/colors.js), not the page's. */
  --a-teal: #7DD3CE;
  --a-bg: #F8F9FA;
  --a-ink: #111827;
  --a-grey: #6B7280;
  --a-blue: #3B5FE0;
  --a-sys: #4A7B77;
}

/* --pw is the phone's rendered width and everything inside is sized from it.
   Each page sets it: /demo/ from the viewport, the homepage from whatever
   height its one screen has left over. */
/* ---------- 3D stage ---------- */
.scene{perspective:1900px;display:grid;place-items:center;height:calc(var(--pw) / .4615 + 90px);position:relative}
.rig{position:relative;width:var(--pw);aspect-ratio:1080/2340;transform-style:preserve-3d;transition:transform 1.5s cubic-bezier(.22,.8,.2,1)}
.rig[data-pose="iso"]{transform:translateY(24%) rotateX(56deg) rotateZ(-34deg) scale(.68)}
.rig[data-pose="front"]{transform:none}

.layer{position:absolute;inset:0;transform-style:preserve-3d;transition:transform 1.25s cubic-bezier(.22,.8,.2,1), opacity .7s ease;will-change:transform,opacity}
.chassis{inset:-3.4%;border-radius:calc(var(--pw) * .15);background:linear-gradient(150deg,#26312F 0%,#0A0F0E 55%,#050707 100%);box-shadow:inset 0 0 0 1.5px #33413E, 0 50px 90px -30px rgba(0,0,0,.85)}
.chassis::after{content:"";position:absolute;top:2.2%;left:50%;width:22%;height:1.1%;transform:translateX(-50%);border-radius:99px;background:#030505}
.scr .clip{position:absolute;inset:0;border-radius:calc(var(--pw) * .115);overflow:hidden;background:var(--a-bg);box-shadow:0 0 0 1px rgba(255,255,255,.07), 0 24px 50px -24px rgba(0,0,0,.7)}
.scr img{width:100%;height:100%;object-fit:cover;object-position:top;display:block}
.glass{border-radius:calc(var(--pw) * .115);pointer-events:none;background:linear-gradient(122deg,rgba(255,255,255,.16) 0%,rgba(255,255,255,.03) 38%,rgba(255,255,255,0) 60%);box-shadow:inset 0 0 0 1px rgba(127,212,204,.28)}
.tag{position:absolute;left:106%;top:46%;white-space:nowrap;font-size:17px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);opacity:0;transition:opacity .5s ease;pointer-events:none}
.tag::before{content:"";display:inline-block;width:30px;height:1.5px;background:currentColor;vertical-align:middle;margin-right:9px;opacity:.7}

.scr{opacity:0}
.scr.next{transform:translateX(9%);opacity:0}
.scr.active{transform:translateZ(1px);opacity:1}
.scr.past{transform:translateX(-22%) translateZ(40px) rotateY(32deg);opacity:0}
.glass{transform:translateZ(3px)}
.rig[data-mode="explode"] .layer.chassis{transform:translateZ(-70px)}
.rig[data-mode="explode"] .layer.scr{transform:translateZ(var(--z));opacity:1}
.rig[data-mode="explode"] .layer.glass{transform:translateZ(310px);opacity:.9}
.rig[data-mode="explode"] .tag{opacity:1}

/* ---------- live app screen (Today's run), sized in em: 36em = screen width ---------- */
.app{position:absolute;top:0;left:0;width:360px;height:780px;font-size:10px;transform:scale(var(--appscale, 1));transform-origin:top left;font-family:"Roboto",system-ui,sans-serif;color:var(--a-ink);background:var(--a-bg);display:flex;flex-direction:column;text-align:left}
.app .sb{height:2.6em;background:var(--a-teal);flex:none}
.app .hd{height:5.4em;background:var(--a-teal);flex:none;position:relative;display:flex;align-items:center;padding:0 1.5em}
.logo{display:flex;align-items:center;gap:.6em}
.logo .mk{width:1.9em;height:1.9em;border:.2em solid #0b0f0f;border-radius:.45em;display:grid;place-items:center}
.logo .mk i{width:.8em;height:.8em;background:#0b0f0f;border-radius:.15em}
.logo b{font-size:1.9em;font-weight:700;letter-spacing:-.01em;color:#0b0f0f}
.logo small{font-size:inherit;font-weight:inherit;letter-spacing:inherit;color:#04342C}
.cam{position:absolute;right:1.6em;top:50%;transform:translateY(-50%);width:2.6em;height:2.2em}
.pill{position:absolute;left:68%;top:50%;transform:translate(-50%,-50%) scale(.6);opacity:0;min-width:3.2em;height:2.5em;padding:0 .8em;border-radius:99px;background:#0F2A27;color:#fff;font-family:"Roboto",sans-serif;font-weight:900;font-size:1.25em;display:grid;place-items:center;letter-spacing:.02em;font-variant-numeric:tabular-nums;transition:transform .45s cubic-bezier(.3,1.6,.5,1),opacity .3s ease}
.pill.on{opacity:1;transform:translate(-50%,-50%) scale(1)}
.pill.tick{animation:tick .45s ease}
@keyframes tick{0%{transform:translate(-50%,-50%) scale(1)}40%{transform:translate(-50%,-50%) scale(1.22)}100%{transform:translate(-50%,-50%) scale(1)}}
.pill.done{background:#1F7A55}

.app .bd{flex:1;padding:1.3em 1.2em 0;position:relative;overflow:hidden}
.scanbtn{display:inline-flex;align-items:center;gap:.7em;background:var(--a-blue);color:#fff;font-weight:700;font-size:1.55em;padding:.72em 1.25em;border-radius:99px}
.scanbtn svg{width:.95em;height:.95em}
.empty{position:absolute;left:0;right:0;top:44%;text-align:center;color:var(--a-grey);font-size:1.45em;transition:opacity .4s ease}
.lbl{margin:1.6em 0 .7em;font-size:1.2em;font-weight:700;color:var(--a-grey);height:1.3em;position:relative}
.lbl span{position:absolute;left:0;top:0;transition:opacity .4s ease}
.lbl .learn{color:#1F7A55}
.rows{position:relative;height:60em}
.row{position:absolute;left:0;right:0;height:4.3em;background:#fff;border-radius:1.1em;display:flex;align-items:center;gap:1em;padding:0 1.2em;box-shadow:0 .1em .3em rgba(17,24,39,.06);
  transition:top .9s cubic-bezier(.6,0,.2,1), opacity .45s ease, box-shadow .6s ease, background .6s ease}
.row .nav{flex:none;width:2em;height:2em}
.row .nm{flex:1;min-width:0;font-weight:700;font-size:1.28em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.005em}
.row .ds{flex:none;color:var(--a-grey);font-weight:500;font-size:1.2em}
.row.moved{background:#E9F7F4;box-shadow:0 0 0 .12em rgba(31,122,85,.35)}
.app[data-state="empty"] .row{opacity:0}
.app[data-state="empty"] .lbl{opacity:0}
.app:not([data-state="empty"]) .empty{opacity:0}
.app[data-state="alpha"] .lbl .learn,.app[data-state="seq"] .lbl .az{opacity:0}
.app[data-state="empty"] .lbl span{opacity:0}

.app .nb{flex:none;height:5em;background:var(--a-teal);display:flex;justify-content:space-around;align-items:center;padding-top:.3em}
.app .nb div{display:flex;flex-direction:column;align-items:center;gap:.25em;font-size:1em;color:#2E4A47}
.app .nb div svg{width:1.9em;height:1.9em}
.app .nb div.on{color:#0b0f0f;font-weight:700}
.app .sys{flex:none;height:3.3em;background:var(--a-sys)}

/* delivered-screen counter overlay */
.pill.ov{font-size:calc(var(--pw) / 36 * 1.25);top:8.78%;left:68%}
/* The signature sits over a screenshot layer, not inside .app, so it keeps
   sizing off --pw rather than the scaled grid. */

/* fleet: fixed header + nav, form scrolls between them */
.fleet .clip img{position:absolute;left:0;width:100%;height:auto;object-fit:initial}
.fleet .fhd{top:0;z-index:2}.fleet .fnav{bottom:0;z-index:2}
.fleet .fbody{top:12.82%;transition:transform 4.5s cubic-bezier(.45,0,.3,1)}
.fleet.scrolled .fbody{transform:translateY(-49.63%)}

/* ---------- the paper run sheet ---------- */
.paper{position:absolute;left:50%;top:50%;z-index:5;width:calc(var(--pw) * 1.12);background:#fff;color:#111;border-radius:3px;
  font-family:"Roboto Mono","Liberation Mono",ui-monospace,monospace;font-size:calc(var(--pw) / 36 * .78);
  box-shadow:0 30px 60px -20px rgba(0,0,0,.7), 0 0 0 1px rgba(0,0,0,.08);padding:1.8em 1.9em 1.6em;overflow:hidden;
  opacity:0;transform:translate(calc(-50% - var(--pw) * .95), -46%) rotate(-11deg);pointer-events:none;
  transition:transform 1s cubic-bezier(.22,.8,.2,1), opacity .6s ease}
.paper.in{opacity:1;transform:translate(calc(-50% - var(--pw) * .5), -50%) rotate(-5deg)}
.paper.out{opacity:0;transform:translate(-50%,-50%) scale(.28) rotate(0deg);transition:transform .9s cubic-bezier(.6,0,.3,1), opacity .9s ease .1s}
@media (max-width:800px){ .paper.in{transform:translate(-50%,-50%) rotate(-4deg)} }
.paper .ph{display:flex;justify-content:space-between;align-items:flex-end;border-bottom:.2em solid #111;padding-bottom:.7em;margin-bottom:.4em;font-family:"Roboto",sans-serif}
.paper .ph b{font-size:1.45em;letter-spacing:.02em}
.paper .ph span{font-size:1.05em;font-weight:700;letter-spacing:.14em}
.paper .pm{font-size:1em;color:#333;margin-bottom:.9em;letter-spacing:.02em}
.paper .pr{display:flex;justify-content:space-between;gap:1em;padding:.42em .4em;border-bottom:1px dashed #bbb;font-size:1.12em}
.paper .pr i{font-style:normal;color:#555}
.paper .pt{display:flex;justify-content:space-between;padding:.55em .4em 0;font-weight:700;font-size:1.12em;border-top:.15em solid #111;margin-top:.2em}
.beam{position:absolute;left:0;right:0;top:-12%;height:12%;pointer-events:none;opacity:0;
  background:linear-gradient(180deg,rgba(127,212,204,0) 0%,rgba(127,212,204,.35) 70%,rgba(59,95,224,.9) 97%,rgba(127,212,204,0) 100%)}
.paper.scan .beam{animation:sweep 1.9s cubic-bezier(.4,0,.6,1) forwards}
@keyframes sweep{0%{top:-12%;opacity:1}92%{opacity:1}100%{top:100%;opacity:0}}
.paper.scan .pr{animation:read 1.9s linear forwards;animation-delay:calc(var(--i) * .095s + .12s)}
@keyframes read{0%{background:transparent}6%{background:rgba(127,212,204,.55)}100%{background:rgba(127,212,204,.16)}}

@media (prefers-reduced-motion: reduce) {
  .rig, .layer, .row, .paper, .pill { transition: opacity .4s ease !important; animation: none !important; }
  .rig[data-pose] { transform: none !important; }
  .scr.past, .scr.next { transform: none; }
}

/* ---------- the save flow (step 4), a live screen rather than a screenshot ----
   Matches src/screens/CaptureScreen.js and CustomerPickerScreen.js: the same
   grey ground, the same teal circle and label, the same row height and group
   heading, the same green tick and its two buttons. Driven by data-cap on the
   .app element; the engine steps that attribute through the flow. */
.app-cap .hd { padding: 0; }
.hd-face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: 0 1.5em;
  opacity: 0;
  transition: opacity .35s ease;
}
.hd-brand { justify-content: flex-start; }
.hd-brand .cam { right: 1.6em; }
.hd-title { gap: 1em; }
.hd-title svg { width: 2.2em; height: 2.2em; flex: none; }
.hd-title span { font-size: 1.85em; font-weight: 700; color: #0b0f0f; }
.app-cap[data-cap="idle"] .hd-brand { opacity: 1; }
.app-cap[data-cap="picker"] .hd-title,
.app-cap[data-cap="picked"] .hd-title,
.app-cap[data-cap="saved"] .hd-title { opacity: 1; }

.cap-bd { padding: 0; position: relative; background: #F9FAFB; }
.cap-pane {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transition: opacity .4s ease;
}
.app-cap[data-cap="idle"] .cap-idle { opacity: 1; }
.app-cap[data-cap="picker"] .cap-pick,
.app-cap[data-cap="picked"] .cap-pick { opacity: 1; }
.app-cap[data-cap="saved"] .cap-done { opacity: 1; }

/* CaptureScreen.js: centred hint, then a teal circle ~54% of the width. */
.cap-idle { align-items: center; justify-content: center; }
.cap-hint { margin: 0 0 3.3em; font-size: 1.4em; font-weight: 500; color: #9CA3AF; }
.cap-shutter {
  width: 19.4em;
  height: 19.4em;
  border-radius: 50%;
  background: var(--a-teal);
  display: grid;
  place-content: center;
  justify-items: center;
  box-shadow: 0 .55em 1.1em rgba(125, 211, 206, .4);
  transition: transform .18s ease;
}
.cap-shutter svg { width: 5.9em; height: 5.9em; }
.cap-shutter span { margin-top: .9em; font-size: 1.66em; font-weight: 700; color: #0b0f0f; letter-spacing: .02em; }
.app-cap.press .cap-shutter { transform: scale(.93); }

/* CustomerPickerScreen.js: group heading, then plain white rows. */
.cap-group { margin: 1.3em 1.85em .5em; font-size: 1.2em; font-weight: 700; color: #6B7280; }
.cap-list { flex: 1; overflow: hidden; }
.cap-row {
  background: #fff;
  padding: 1.66em 1.85em;
  font-size: 1.57em;
  font-weight: 500;
  color: #111827;
  border-bottom: 1px solid #F3F4F6;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background .25s ease;
}
.app-cap[data-cap="picked"] .cap-pickme { background: #E9F7F4; }

/* The saved screen, with the signature offer that follows every save. */
.cap-done { align-items: center; justify-content: center; padding: 0 3em; text-align: center; }
.cap-tick {
  width: 6.6em;
  height: 6.6em;
  border-radius: 50%;
  background: #059669;
  display: grid;
  place-items: center;
}
.cap-tick svg { width: 3.5em; height: 3.5em; }
.cap-done-t { margin: 1.5em 0 0; font-size: 2em; font-weight: 700; color: #111827; }
.cap-done-s { margin: .4em 0 0; font-size: 1.5em; font-weight: 500; color: #6B7280; }
.cap-sign {
  margin-top: 2.4em;
  background: #2563EB;
  color: #fff;
  font-size: 1.5em;
  font-weight: 700;
  padding: .85em 1.6em;
  border-radius: .7em;
}
.cap-more { margin-top: 1.2em; font-size: 1.5em; font-weight: 700; color: #2563EB; }

/* The camera covers the whole phone - the real screen sets headerShown:false. */
.cap-cam {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: #0E0E0E;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}
.app-cap[data-cap="shot"] .cap-cam { opacity: 1; }
/* The preview is a 1:1 band, not full-bleed - which is how a phone camera
   really shows a square sensor on a tall screen, and why this is sharp. The
   photo is drop.jpg: a 600x800 crop of a real delivery, downscaled from the
   3060x4080 original the driver's phone took. On screen it renders about
   343px wide, so it is being scaled DOWN and is genuinely sharp. Earlier
   attempts cropped a 166px thumbnail out of the Proof screenshot and blew it
   up 2-4x, which read as permanently out of focus however the focus
   animation behaved. */
.cap-view {
  position: absolute;
  left: 0;
  right: 0;
  top: 7em;
  height: 43.8em;
  background-image: url(drop.jpg);
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
}
/* Corner falloff, as a lens gives. The heavy scrim this replaces was only
   there to keep a white shutter legible on pale concrete; the shutter now
   sits on the dark chrome below the band and needs no help. */
.cap-view::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(76% 76% at 50% 45%, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, .3) 100%);
}

/* Focus settles onto the subject: brief and slight, so the preview reads as
   sharp almost throughout. The reticle carries the "focusing", not the blur. */
.app-cap[data-cap="shot"] .cap-view { animation: capfocus .62s cubic-bezier(.3,.8,.3,1) forwards; }
@keyframes capfocus {
  0%   { filter: blur(.2em);  transform: scale(1.012); }
  70%  { filter: blur(.03em); transform: scale(1.001); }
  100% { filter: blur(0);     transform: scale(1); }
}

/* The square the camera puts over what it is focusing on: arrives wide,
   closes onto the subject, turns teal on lock, then gets out of the way
   before the shutter fires. Centred on the band, not on the screen. */
.cap-focus {
  position: absolute;
  left: 50%;
  top: 28.9em;
  width: 12em;
  height: 12em;
  margin: -6em 0 0 -6em;
  border: .26em solid rgba(255, 255, 255, .95);
  border-radius: .5em;
  opacity: 0;
  box-shadow: 0 0 .6em rgba(0, 0, 0, .45);
  pointer-events: none;
}
.app-cap[data-cap="shot"] .cap-focus { animation: capreticle 1.5s ease forwards; }
@keyframes capreticle {
  0%   { opacity: 0; transform: scale(1.55); }
  16%  { opacity: 1; transform: scale(1.14); }
  46%  { opacity: 1; transform: scale(1); border-color: rgba(255, 255, 255, .95); }
  58%  { opacity: 1; border-color: var(--a-teal); }
  86%  { opacity: 1; border-color: var(--a-teal); }
  100% { opacity: 0; transform: scale(1); border-color: var(--a-teal); }
}
.cap-ring {
  position: relative;
  width: 6.4em;
  height: 6.4em;
  margin-bottom: 3.2em;
  border-radius: 50%;
  border: .35em solid rgba(255, 255, 255, .9);
  background: transparent;
  box-shadow: 0 0 0 .18em rgba(0, 0, 0, .35);
}
/* The filled disc inside the ring, as the app draws its shutter. */
.cap-ring::after {
  content: "";
  position: absolute;
  inset: .55em;
  border-radius: 50%;
  background: #fff;
}
.cap-strip {
  position: absolute;
  left: 1.6em;
  bottom: 3.4em;
  display: flex;
  align-items: center;
  gap: .8em;
  opacity: 0;
  transform: translateY(1em);
  transition: opacity .45s ease, transform .45s ease;
}
.app-cap.shot-done .cap-strip { opacity: 1; transform: none; }
.cap-thumb {
  width: 5.4em;
  height: 5.4em;
  border-radius: .6em;
  border: .18em solid rgba(255, 255, 255, .85);
  background-image: url(drop.jpg);
  background-repeat: no-repeat;
  /* The same photo that was just taken. */
  background-size: cover;
  background-position: center;
}
.cap-strip b { font-size: 1.2em; font-weight: 700; color: #fff; }
/* The Proof screenshot was taken before the driver signed, so it reads
   "No signature". The line is covered and a signed one drawn over it, placed
   off the measured ink: x 82..279, y 1235..1265 of the 720x1560 image, which
   at 36em/720px is 0.05em per source pixel. */
.sig {
  position: absolute;
  left: 0;
  right: 0;
  top: 55em;
  height: 11.6em;
  font-size: calc(var(--pw) / 36);
  background: #fff;
  padding: 0 1.9em;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* Drawn, not typeset. A typeface always reads as a typeface however
   script-like it is; this is eight strokes the way a hand makes them - the
   A and its bar, "nth", the t bar, then o, n and y lifted apart, and the
   flourish thrown off at the end. Constant width with round caps, which is
   exactly what the app's own SignatureScreen records from a finger. */
.sig-ink {
  display: block;
  width: 20.5em;
  margin-left: .2em;
}
.sig-ink path {
  fill: none;
  stroke: #111827;
  stroke-width: 3.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.sig-rule {
  display: block;
  height: 1px;
  margin: .1em 0 0;
  background: #E5E7EB;
}
.sig-by { margin-top: .45em; font-size: 1.2em; font-weight: 500; color: #6B7280; }

.cap-flash { position: absolute; inset: 0; background: #fff; opacity: 0; }
.app-cap.shot-done .cap-flash { animation: capflash .45s ease; }
.app-cap.shot-done .cap-ring::after { animation: capfire .42s ease; }
@keyframes capfire { 0% { transform: scale(1); } 38% { transform: scale(.78); } 100% { transform: scale(1); } }
@keyframes capflash { 0% { opacity: .92; } 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .cap-pane, .cap-cam, .cap-strip, .cap-shutter { transition: none !important; }
  .app-cap.shot-done .cap-flash,
  .app-cap.shot-done .cap-ring::after,
  .app-cap[data-cap="shot"] .cap-view,
  .app-cap[data-cap="shot"] .cap-focus { animation: none !important; }
  .cap-focus { opacity: 0; }
}
