/* ==========================================================================
   Solution pages. One template, two pages — Documents & Tracking, and
   Warehouse & scanner. The home page borrows .caps / .proof / .limits from
   here so the Email AI and Customers blocks match them exactly.
   ========================================================================== */

.sol-hero {
  padding-block: var(--section-y);
  background: var(--surface-warm);
}

.sol-hero__grid { display: grid; gap: var(--s-9); align-items: center; }

@media (min-width: 900px) {
  .sol-hero__grid { grid-template-columns: 1.05fr 1fr; gap: var(--s-10); }
}

.sol-hero__copy { display: flex; flex-direction: column; align-items: flex-start; }
.sol-hero h1 { margin-block: var(--s-5) var(--s-5); }
.sol-hero .btn { margin-top: var(--s-7); }

.sol-hero .eyebrow::before { background: var(--accent); }

/* The drawn object: one paper thing per area, same family, tilted a hair. */
.object {
  width: 100%;
  max-width: 420px;
  margin-inline: auto;
  transform: rotate(-1.2deg);
}

/* ---------- Pain ------------------------------------------------------- */

.pain { display: grid; gap: var(--s-8); }

@media (min-width: 900px) {
  .pain { grid-template-columns: 5fr 7fr; gap: var(--s-9); align-items: start; }
  /* When the right column holds the handheld rather than a list, the copy is
     the wider of the two. */
  .pain--phone { grid-template-columns: 7fr 5fr; align-items: center; }
}

/* A photograph small enough to be a still life. It sits on a white section
   with no scrim, so the filter has to do all the work on its own: the office
   blue goes out, the paper lands around #E8E1DC — inside the warm family. */
.pain__plate { margin: 0 0 var(--s-6); max-width: 420px; }

.pain__plate img {
  display: block;
  width: 100%;
  /* The source is exactly 3:2 (8256x5504), so a 3:2 frame with object-fit:cover
     crops nothing at all and object-position does nothing. A letterbox forces a
     real vertical crop, and anchoring it to the bottom puts the face out of
     frame — leaving the desk and the two stacks of paper. */
  aspect-ratio: 5 / 2;
  object-fit: cover;
  object-position: 62% 100%;
  border-radius: var(--r-card);
  border: 1px solid var(--hairline);
  filter: saturate(0.45) contrast(1.02) brightness(1.06) sepia(0.18);
}

.pain__plate figcaption {
  margin-top: var(--s-3);
  font-size: var(--t-caption);
  color: var(--ink-400);
}

.pain__said {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.5rem;
  line-height: 1.5;
  color: var(--ink-900);
  padding-left: var(--s-5);
  border-left: 2px solid var(--accent);
}

:lang(ja) .pain__said, :lang(zh) .pain__said { font-style: normal; line-height: 1.8; }

.pain__list {
  list-style: none;
  margin: 0;
  padding-left: var(--s-5);
  border-left: 1px solid var(--hairline-strong);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.pain__list li {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: var(--s-3);
  align-items: start;
  font-size: var(--t-body);
  color: var(--ink-600);
}

.pain__list svg { margin-top: 4px; color: var(--warm-500); }

/* ---------- Three capabilities ------------------------------------------ */

.caps { display: grid; gap: var(--s-5); }

@media (min-width: 860px) {
  .caps { grid-template-columns: repeat(3, 1fr); }
}

.cap {
  padding: var(--s-6);
  border-radius: var(--r-card);
  background: var(--surface-warm);
  position: relative;
  overflow: hidden;
}

.cap__cap {
  position: absolute;
  top: -1.5px;
  left: var(--s-6);
  width: 40px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent);
}

.cap h3 { margin-bottom: var(--s-3); }
.cap p { color: var(--ink-600); font-size: var(--t-body); }

/* Capability cards standing on a photographic band: the warm card surface
   would go muddy over a photograph, so they become translucent panels with a
   hairline instead. */
.caps--on-dark .cap {
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(2px);
}

.caps--on-dark .cap h3 { color: #fff; }
.caps--on-dark .cap p { color: rgba(255, 255, 255, 0.9); }

/* #1D5BFF is tuned for a white page; on navy it sinks. The area keeps its
   identity by moving up the same hue, not by changing colour. */
.caps--on-dark .cap__cap { background: #7ea6ff; }

/* ---------- One real fragment of product --------------------------------- */

.proof {
  border-radius: var(--r-media);
  border: 1px solid var(--hairline);
  background: var(--surface-white);
  padding: var(--s-6);
  max-width: 720px;
}

.proof__label {
  display: block;
  font-size: var(--t-eyebrow);
  letter-spacing: 0.06em;
  color: var(--ink-400);
  margin-bottom: var(--s-4);
}

.rows { display: flex; flex-direction: column; gap: var(--s-2); }

.row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--hairline);
  border-radius: var(--r-input);
  font-size: var(--t-ui);
  color: var(--ink-600);
}

.row b { color: var(--ink-900); font-weight: 500; }
.row .mono { font-family: var(--font-mono); font-size: 0.8125rem; color: var(--ink-900); }
.row .right { margin-left: auto; color: var(--ink-400); }

.row__dot {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
}

.row__disc {
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: var(--r-pill);
  display: grid;
  place-items: center;
  background: var(--tint);
  color: var(--accent-text);
  font-size: 0.75rem;
  font-weight: 600;
}

.row--flag { background: var(--surface-warm); }

.proof__note { margin-top: var(--s-4); font-size: var(--t-ui); color: var(--ink-400); }

/* ---------- Honest limits ------------------------------------------------ */

.limits {
  max-width: 62ch;
  padding-left: var(--s-5);
  border-left: 1px solid var(--hairline-strong);
}

.limits b { display: block; color: var(--ink-900); margin-bottom: 6px; }
.limits p { color: var(--ink-400); font-size: var(--t-ui); }

/* ---------- Wide hero object (documents) --------------------------------- */

.object--wide { max-width: 560px; transform: none; }

@media (min-width: 900px) {
  .sol-hero__grid--wide { grid-template-columns: 0.92fr 1.08fr; }
}

/* ---------- Warehouse cutaway ------------------------------------------- */

.wh-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-5);
  margin-top: var(--s-5);
  font-size: var(--t-caption);
  color: var(--ink-400);
}

.wh-legend span { display: inline-flex; align-items: center; gap: 7px; }

.wh-legend i {
  width: 14px;
  height: 10px;
  border-radius: 2px;
  border: 1px solid var(--hairline-strong);
  background: var(--swatch, #fff);
  display: inline-block;
}

/* ---------- Hero: the FIFO rule, drawn ------------------------------------
   A still cutaway can show where goods sit; it cannot show which one leaves.
   FIFO here is by GRN receipt date (docs.warehouse.md §2.7) — not by expiry,
   and not by whichever pallet is closest to the door. That is the rule people
   get wrong, so it is the one thing worth moving.

   This never runs at the same time as the handheld sequence further down the
   page: both pause when off screen, and they are a screen apart.
   ------------------------------------------------------------------------ */

.whmap .wh-dates text,
.whmap .wh-call,
.whmap .wh-note {
  opacity: 1;
  transition: opacity 420ms var(--ease);
}

.anim .whmap:not(.is-dated) .wh-dates text { opacity: 0; }
.anim .whmap:not(.is-called) .wh-call { opacity: 0; }

.whmap .wh-dates text:nth-child(1) { transition-delay: 0ms; }
.whmap .wh-dates text:nth-child(2) { transition-delay: 130ms; }
.whmap .wh-dates text:nth-child(3) { transition-delay: 260ms; }

/* A ring, not a fill: the amber fill already means "just put away" in the
   legend, so re-using it for "being picked" would collide. A ring around the
   case is unambiguously a selection. */
.whmap .wh-ring,
.whmap .wh-doorring {
  opacity: 0;
  transition: opacity 380ms var(--ease);
}

.anim .whmap.is-picked .wh-ring { opacity: 1; }
.anim .whmap.is-moved .wh-ring { opacity: 0; }
.anim .whmap.is-moved .wh-doorring { opacity: 1; }

/* The case leaves and its bay goes empty — the same dashed outline the legend
   already calls free space. */
.whmap .wh-oldest {
  fill: #f8edda;
  stroke: #0b2439;
  stroke-width: 1.3;
  stroke-dasharray: none;
  transition: fill 420ms var(--ease), stroke 420ms var(--ease);
}

.anim .whmap.is-moved .wh-oldest { fill: #ffffff; stroke: #c9bfb9; stroke-dasharray: 4 4; }

/* The date belongs to the case, so it leaves with it rather than labelling an
   empty bay. */
.anim .whmap.is-moved .wh-olddate { opacity: 0; }

/* The near, newer pallet dims while the choice is being made, so the eye is
   told what was passed over. */
.whmap .wh-newest { opacity: 1; transition: opacity 400ms var(--ease); }
.anim .whmap.is-picked .wh-newest { opacity: 0.4; }
.anim .whmap.is-moved .wh-newest { opacity: 1; }

/* ---------- The handheld -------------------------------------------------
   Ported from the v1 page, which was easier to read: the notch says phone,
   the scan window says the rack was scanned, and the check digits and pick
   progress are the two details a warehouse manager looks for first. */

.phone-wrap { display: grid; place-items: center; padding-block: 6px; }

.phone {
  position: relative;
  width: 288px;
  max-width: 100%;
  padding: 11px;
  border-radius: 34px;
  background: var(--ink-900);
  box-shadow: 0 30px 60px -34px rgba(11, 36, 57, 0.8);
}

.phone__notch {
  position: absolute;
  top: 11px;
  left: 50%;
  transform: translateX(-50%);
  width: 96px;
  height: 18px;
  border-radius: 0 0 12px 12px;
  background: var(--ink-900);
  z-index: 2;
}

.phone__screen {
  position: relative;
  height: 532px;
  border-radius: 25px;
  background: var(--surface-warm);
  overflow: hidden;
  padding-top: 24px;
  padding-bottom: 4px;
}

.phone__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: var(--surface-white);
  border-bottom: 1px solid var(--hairline);
  font-size: var(--t-caption);
  font-weight: 600;
  color: var(--ink-900);
}

.phone .mono { font-family: var(--font-mono); font-weight: 400; }
.phone__bar .mono { color: var(--ink-400); font-size: 0.75rem; }

.phone__scan {
  position: relative;
  margin: 14px 16px 0;
  height: 82px;
  display: grid;
  place-items: center;
  gap: 2px;
  border: 1.5px solid var(--accent);
  border-radius: var(--r-input);
  background: var(--tint);
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  color: var(--ink-900);
}

.phone__scanline {
  position: absolute;
  left: 8px;
  right: 8px;
  height: 2px;
  background: var(--accent);
  opacity: 0.75;
  top: 12px;
}

/* The one looping motion on the site, and it is doing a job: a scanner beam
   is what tells you the window is live rather than a picture of a code. */
.anim .phone__scanline { animation: scan-sweep 2.6s ease-in-out infinite; }

@keyframes scan-sweep {
  0%, 100% { top: 12px; }
  50% { top: 66px; }
}

.phone__hint {
  font-family: var(--font-sans);
  font-size: 11px;
  color: var(--accent-text);
}

.phone__check {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 12px 16px 0;
  padding: 10px 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-input);
  background: var(--surface-white);
  font-size: var(--t-caption);
  color: var(--ink-400);
}

.phone__digits {
  font-family: var(--font-mono);
  font-size: 1rem;
  color: var(--ink-900);
  letter-spacing: 0.14em;
}

.phone__list {
  list-style: none;
  margin: 12px 16px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.phone__list li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 8px;
  align-items: center;
  padding: 9px 11px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-input);
  background: var(--surface-white);
}

.phone__sku { font-family: var(--font-mono); font-size: 11px; color: var(--ink-900); }
.phone__qty { font-family: var(--font-mono); font-size: 11px; color: var(--ink-400); text-align: right; }
.phone__list .chip { grid-column: 1 / -1; width: fit-content; }

.phone__cta {
  margin: 14px 16px 18px;
  padding: 11px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  text-align: center;
  font-weight: 600;
  font-size: var(--t-caption);
}

/* ---------- The scan, as it really works ---------------------------------
   From docs.warehouse.md §7.2: a carton carries several barcodes at once —
   shipping label, lot, SKU. A scanner that takes the first hit grabs the wrong
   one. This engine boxes every code it can see, the picker taps the right one,
   and it is only accepted after it holds for five frames. That distinction is
   the product, so the picture shows it rather than claiming it.
   ------------------------------------------------------------------------ */

.scanner { position: relative; }

.cam {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: #3d5468;
  opacity: 0;
  pointer-events: none;
  transition: opacity 380ms var(--ease);
}

/* Only ever visible while the sequence is running; the resting state of the
   phone is the picking list with the line already picked. */
.anim .scanner.is-live .cam { opacity: 1; }

/* A carton, drawn flat, so the boxes have something to sit on. */
.cam__title {
  position: absolute;
  left: 0;
  right: 0;
  top: 32px;
  text-align: center;
  font-size: 10.5px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.9);
}

.cam__carton {
  position: absolute;
  left: 15%;
  top: 17%;
  width: 70%;
  height: 46%;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.07);
}

.cam__carton::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 34%;
  height: 1px;
  background: rgba(255, 255, 255, 0.22);
}

/* Each detected code gets a box and a caption. */
.cam__box {
  position: absolute;
  border: 2px solid rgba(255, 255, 255, 0.72);
  border-radius: 3px;
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 260ms var(--ease), transform 260ms var(--ease-land),
              border-color 260ms var(--ease), background-color 260ms var(--ease);
}

.cam__box span {
  position: absolute;
  left: 0;
  top: -15px;
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.82);
  white-space: nowrap;
}

.anim .scanner.is-boxed .cam__box { opacity: 1; transform: none; }
.scanner.is-boxed .cam__box:nth-of-type(1) { transition-delay: 0ms; }
.scanner.is-boxed .cam__box:nth-of-type(2) { transition-delay: 180ms; }
.scanner.is-boxed .cam__box:nth-of-type(3) { transition-delay: 340ms; }

.cam__box--ship { left: 21%; top: 24%; width: 38%; height: 11%; }
.cam__box--lot  { left: 60%; top: 31%; width: 22%; height: 9%; }
.cam__box--sku  { left: 21%; top: 47%; width: 46%; height: 13%; }

/* The tap: one box is chosen and the others step back. */
.anim .scanner.is-chosen .cam__box--ship,
.anim .scanner.is-chosen .cam__box--lot { opacity: 0.32; }

.anim .scanner.is-chosen .cam__box--sku {
  border-color: #f0b45e;
  border-width: 2px;
  background: rgba(240, 180, 94, 0.16);
}

.cam__tap {
  position: absolute;
  left: 44%;
  top: 53.5%;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  border: 2px solid #f0b45e;
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 220ms var(--ease), transform 420ms var(--ease-land);
}

.anim .scanner.is-tapping .cam__tap { opacity: 0.9; transform: scale(1); }
.anim .scanner.is-chosen .cam__tap { opacity: 0; transform: scale(1.9); }

/* Five frames, not one lucky read. */
.cam__frames {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  background: rgba(11, 26, 38, 0.55);
  font-size: 10px;
  white-space: nowrap;
  color: #fff;
  opacity: 0;
  transition: opacity 240ms var(--ease);
}

.anim .scanner.is-chosen .cam__frames { opacity: 1; }

.cam__frames i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  transition: background-color 160ms linear;
}

.anim .scanner.is-confirmed .cam__frames i { background: #7ddba4; }
.scanner.is-confirmed .cam__frames i:nth-child(1) { transition-delay: 0ms; }
.scanner.is-confirmed .cam__frames i:nth-child(2) { transition-delay: 90ms; }
.scanner.is-confirmed .cam__frames i:nth-child(3) { transition-delay: 180ms; }
.scanner.is-confirmed .cam__frames i:nth-child(4) { transition-delay: 270ms; }
.scanner.is-confirmed .cam__frames i:nth-child(5) { transition-delay: 360ms; }

/* The result sheet the app forces you through: it redraws the barcode it read
   and refuses to be dismissed — Rescan or Confirm, nothing else. */
.cam__sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 12px 14px 14px;
  border-radius: 14px 14px 0 0;
  background: var(--surface-white);
  transform: translateY(101%);
  transition: transform 620ms var(--ease-land);
}

.anim .scanner.is-sheet .cam__sheet { transform: translateY(0); }

.cam__sheet b { display: block; font-size: 10px; letter-spacing: 0.05em; color: var(--ink-400); }
.cam__sheet .mono { display: block; margin-top: 3px; font-family: var(--font-mono); font-size: 12px; color: var(--ink-900); }

.cam__bars {
  height: 26px;
  margin: 9px 0 11px;
  border-radius: 2px;
  background: repeating-linear-gradient(90deg,
    var(--ink-900) 0 2px, transparent 2px 4px,
    var(--ink-900) 4px 5px, transparent 5px 9px,
    var(--ink-900) 9px 12px, transparent 12px 13px);
}

.cam__acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

/* The choice appears after the code is readable, not with it — the picker is
   meant to check the number before reaching for a button. */
.cam__acts span {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 320ms var(--ease), transform 320ms var(--ease-land);
  padding: 8px;
  border-radius: 8px;
  text-align: center;
  font-size: 11px;
  font-weight: 500;
  border: 1px solid var(--hairline);
  color: var(--ink-600);
}

.anim .scanner.is-sheet .cam__acts span { opacity: 1; transform: none; }
.scanner.is-sheet .cam__acts span:nth-child(1) { transition-delay: 700ms; }
.scanner.is-sheet .cam__acts span:nth-child(2) { transition-delay: 880ms; }

.cam__acts .is-primary { background: var(--accent); border-color: var(--accent); color: #fff; }

/* The first line's count and chip swap only once the scan is confirmed. The
   swap classes are scoped to that one row so the other rows keep their own
   chips. Resting state — no JS, reduced motion — is the finished one. */
.phone__qty b { font-weight: inherit; }
.q-before { display: none; }
/* .chip sets display later in this file, so these need the extra class to win. */
.phone__list .chip--swap-doing { display: none; }
.anim .scanner:not(.is-done) .q-before { display: inline; }
.anim .scanner:not(.is-done) .q-after { display: none; }
.anim .scanner:not(.is-done) .phone__list .chip--swap-doing { display: inline-flex; }
.anim .scanner:not(.is-done) .phone__list .chip--swap-done { display: none; }

/* Status chips, shared by the handheld and the receiving table. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 500;
}

.chip .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.chip--done { background: #e0f0e6; color: #1f6b3f; }
.chip--doing { background: var(--tint); color: var(--accent-text); }
.chip--wait { background: var(--surface-warm-deep); color: var(--ink-400); }

/* Store badges sitting on a light surface need their own border. */
/* Badges first, then what the app is — the label sits to their right rather
   than above, so the pair reads as one object. The navy plate the footer needs
   is dropped here: this sits on a warm surface, and the badges carry their own
   black. */
.stores--light {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-5);
  margin-top: var(--s-6);
  padding: 0;
  background: none;
}

.stores--light .stores__row { display: flex; flex-wrap: wrap; gap: var(--s-3); }

.stores__label--beside {
  font-size: var(--t-ui);
  font-weight: 500;
  color: var(--ink-600);
  letter-spacing: 0;
  margin: 0;
  max-width: 13ch;
  line-height: 1.35;
}
.stores--light .store-badge { border-color: rgba(11, 36, 57, 0.2); }
.stores--light .store-badge:hover { border-color: var(--ink-900); }
