/* Colours and type sizes for the business-account slide are measured off the
   reference render (pemo-business-account, 3204x4892): the mock card is
   70.4% of the panel width there, so everything inside it is expressed as a
   fraction of that width and rebuilt in em against --pemo-mock-unit.
   Spacing deliberately does NOT match the reference — its density read as
   cramped at panel size, so the paddings, row heights and the partner lockup
   are opened up from it. Type sizes are still the reference's, except the
   headline/subhead, which are matched to the cashback and Wakala slides
   below (both render at 33.3px/16px in this slot) rather than to their own
   larger reference. */
:root {
  --pemo-color-plate-photo: #eeedf4;
  --pemo-color-plate-gradient: linear-gradient(157deg, #f4f4f8 0%, #efeef5 32%, #eae7f0 66%, #e4dfe8 100%);
  --pemo-color-ink: #222529;
  --pemo-color-ink-secondary: #62666a;
  --pemo-color-ink-muted: #8f8aa9;
  --pemo-color-surface: #ffffff;
  --pemo-color-surface-subtle: #f3f6fc;
  --pemo-color-hairline: #dbdbe8;
  --pemo-color-brand: #00a4d7;
  --pemo-color-credit: #339970;
  --pemo-color-tint-deposit: #d7eff4;
  --pemo-color-icon-deposit: #008492;
  --pemo-color-tint-vendor: #f7ead9;
  --pemo-color-icon-vendor: #995c02;
  --pemo-color-tint-card: #e2eafd;
  --pemo-color-icon-card: #003bd3;

  --pemo-font-sans: "Figtree", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --pemo-weight-regular: 400;
  --pemo-weight-medium: 500;
  --pemo-weight-semibold: 600;

  --pemo-space-0: 0px;
  --pemo-space-3: 12px;
  --pemo-space-10: 40px;

  --pemo-shadow-md: 0px 5px 20px 5px rgba(0, 0, 0, .12);

  /* Fluid mock sizing, same trick as the signup card: the whole composition is
     authored against ONE length, --pemo-mock-unit, set as the font-size on
     .login-panel__mock, and every measurement below is em against it. The
     headline and subhead read it through calc() so the copy scales with the
     card exactly as it does in the reference.

       10px    floor   = 285x284; below this the amounts stop being legible,
                         so a panel shorter than ~410px clips instead
       2.61vw          = holds the mock at ~74% of the panel's width
       2.15vh          = the vertical budget. The whole column is ~40 units
                         tall (card 27.9 + copy 7.6 + gap 4.7) plus ~50px of
                         fixed padding and hairlines, so (H-50)/40 is the unit
                         that just fits; 2.15vh sits under that with margin.
                         Deriving it from the budget rather than from a share
                         of the height keeps a short, wide panel from pinning
                         the mock to its floor.
       22px    ceiling = 627x624, where it stops growing

     min() takes whichever of width or height is the binding constraint.
     vw/vh here are this iframe's own box, not the host page's. */
  --pemo-mock-unit: clamp(10px, min(2.61vw, 2.15vh), 22px);

  /* Copy. Matched to the cashback/Wakala slides, which both render their
     title at 33.3px and share this same 696x852 slot: the business slide's
     own reference ratio (2.28 of the unit) gave 41.4px, too big to match. */
  --pemo-text-headline: calc(var(--pemo-mock-unit) * 1.833);
  /* Matched to "Trusted by 6000+ companies" on the sign-up screen, which
     renders at 16px: 18.17 x 0.881 = 16.0px. */
  --pemo-text-subhead: calc(var(--pemo-mock-unit) * 0.881);
  /* Reference gap from subhead baseline to card top is 4.73 units; the vh cap
     lets a short panel close it up rather than clipping. */
  --pemo-space-copy-mock: min(calc(var(--pemo-mock-unit) * 4.73), 7vh);

  /* em against --pemo-mock-unit — every use site inherits that font-size from
     .login-panel__mock, so these stay in proportion. */
  --pemo-size-mock-w: 28.5em;               /* 456 at unit 16 */
  --pemo-size-mock-radius: .8em;
  --pemo-size-mock-pad: 1.05em;
  --pemo-size-mock-header-pad: 1em;
  --pemo-size-mock-badge: 2.4em;
  --pemo-size-mock-badge-radius: .7em;
  /* calc, not em: this token is consumed inside the pill, whose own font-size
     is smaller than the unit — an em here would resolve against that instead
     and render the lockup at a third of its intended size. */
  --pemo-size-mock-logo-h: calc(var(--pemo-mock-unit) * 1.45);
  --pemo-size-mock-row-icon: 1.95em;
  --pemo-size-mock-row-pad: .85em;
  --pemo-size-mock-activity-pad: .75em;
  --pemo-size-mock-action-h: 2.25em;
  --pemo-size-mock-action-radius: .45em;

  /* The card renders at 0.792 of the panel unit (see .login-panel__mock
     below), which took its type down with it. These are the panel's own em
     ratios stepped up to compensate, so the card keeps its size and only the
     lettering grows back. The balance figure is left alone — it was already
     the one thing reading large enough.

     Two ceilings, both found by probing until something wrapped:
     - The title tops out at 1.18em. It shares its row with the "Powered by"
       credit, so the credit goes back to its original 0.68 and stops
       crowding it — that alone bought the title 1.08 -> 1.16.
     - The activity rows are a label and an amount in one flex row, so the
       two are coupled; 0.99 and 1.04 sit inside what the pair allows
       together. */
  --pemo-text-mock-title: 1.16em;        /* 0.99 — ceiling is 1.18 */
  --pemo-text-mock-amount: 2.38em;       /* 2.07 */
  --pemo-text-mock-label: 0.92em;        /* 0.68 */
  --pemo-text-mock-activity: 0.97em;     /* 0.72 */
  --pemo-text-mock-row: 0.99em;          /* 0.73 */
  --pemo-text-mock-row-amount: 1.04em;   /* 0.77 */
  --pemo-text-mock-powered: 0.68em;      /* unchanged, to leave the title room */
  --pemo-text-mock-action: 0.99em;       /* 0.73 */
}

* { box-sizing: border-box; }

html {
  height: 100%;
  margin: 0;
  background: var(--pemo-color-plate-photo);
}

body {
  height: 100%;
  margin: 0;
  background: var(--pemo-color-plate-photo);
  background-image: var(--pemo-color-plate-gradient);
  font-family: var(--pemo-font-sans);
}

.login-panel {
  position: relative;
  height: 100%;
  width: 100%;
  overflow: hidden;
}

/* ---------- slide stack ----------
   The three slides are stacked and cross-dissolved rather than swapped, so
   one can fade into the next. visibility rides along on a delayed step so a
   faded-out slide stops taking hover/focus once it is gone. */

.login-panel__stage {
  position: absolute;
  inset: 0;
}

.login-panel__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 1s cubic-bezier(.4, 0, .2, 1), visibility 0s linear 1s;
}

.login-panel__slide.is-shown {
  opacity: 1;
  visibility: visible;
  transition: opacity 1s cubic-bezier(.4, 0, .2, 1), visibility 0s;
}

.login-panel__slide--cashback,
.login-panel__slide--wakala {
  padding: clamp(12px, 4vh, 40px);
}

/* ---------- business-account slide ---------- */

.login-panel__content {
  display: flex;
  height: 100%;
  width: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--pemo-space-copy-mock);
  /* Scales with panel height: the mock bottoms out at its floor, so on a short
     panel the frame has to give way, or the column overflows the hidden
     overflow and clips the headline. */
  padding: clamp(var(--pemo-space-3), 4vh, var(--pemo-space-10));
}

.login-panel__copy {
  text-align: center;
}

.login-panel__headline {
  font-size: var(--pemo-text-headline);
  line-height: 1.18;
  font-weight: var(--pemo-weight-semibold);
  letter-spacing: -.2px;
  color: var(--pemo-color-ink);
  /* em against the headline's own size — 14.2 holds the reference's two-line
     break ("…from a single" / "Pemo Business Account"), which needs 13.3. */
  max-width: 14.2em;
  margin: 0 auto;
}

.login-panel__subhead {
  margin: .55em auto 0;
  font-size: var(--pemo-text-subhead);
  line-height: 1.35;
  font-weight: var(--pemo-weight-regular);
  letter-spacing: .1px;
  color: var(--pemo-color-ink-secondary);
  max-width: 20em;
}

/* Secondary button, after the app's own "Sign up": white fill, hairline
   border, 12px radius at the 16px subhead size. Sized in em against the
   subhead so it scales with the copy above it. It sits under the card as a
   flex item of .login-panel__content, so the negative margin takes back
   most of the large copy-to-card gap and leaves 1.5em above the button. */
.login-panel__cta {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  margin-top: calc(1.5em - var(--pemo-space-copy-mock));
  height: 2.5em;
  padding: 0 1.25em;
  font-family: inherit;
  font-size: var(--pemo-text-subhead);
  font-weight: var(--pemo-weight-semibold);
  line-height: 1;
  white-space: nowrap;
  color: var(--pemo-color-ink);
  text-decoration: none;
  background: var(--pemo-color-surface);
  border: 1.5px solid var(--pemo-color-hairline);
  border-radius: .75em;
  transition: border-color .2s ease, background-color .2s ease;
  /* Enters once the card has landed (850ms delay + 700ms rise). Without it the
     button shows at once, alone under an empty gap, while the card is still
     held back by its own delay. */
  animation: pemo-mock-rise 500ms cubic-bezier(.4, 0, .2, 1) 1550ms backwards;
}

@media (hover: hover) {
  .login-panel__cta:hover {
    border-color: #bec2c7;
    background: var(--pemo-color-surface-subtle);
  }
}

.login-panel__cta:focus-visible {
  outline: 2px solid #339970;
  outline-offset: 3px;
}

.login-panel__sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- account mock ---------- */

.login-panel__mock {
  /* Not for text — this is the mock's base unit, which every em above reads.
     The mock is authored entirely in em against its own font-size — its
     28.5em width included — so scaling this one length scales the card and
     every row, icon and figure inside it. */
  font-size: calc(var(--pemo-mock-unit) * 0.792);
  width: var(--pemo-size-mock-w);
  max-width: 100%;
  flex-shrink: 0;
  border-radius: var(--pemo-size-mock-radius);
  background: var(--pemo-color-surface);
  box-shadow: var(--pemo-shadow-md);
  overflow: hidden;
  /* The card starts as the panel lands rather than half a second after it.
     'backwards' fill keeps it hidden through the delay. */
  animation: pemo-mock-rise 700ms cubic-bezier(.4, 0, .2, 1) 850ms backwards;
  /* The zoom on hover: same lift, same scale, same easing as the entrance —
     but on the individual `translate`/`scale` properties rather than
     `transform`, which the entrance animation owns. A transition on the same
     property the animation fills would otherwise fire the moment the
     animation stops filling it, re-compositing the card and nudging its
     small vector marks by a fraction of a pixel. CSS resolves
     translate/scale before transform, so the two compose without either one
     triggering the other. */
  transition: translate .45s cubic-bezier(.22, 1, .36, 1),
              scale .45s cubic-bezier(.22, 1, .36, 1);
}

@media (hover: hover) {
  .login-panel__mock:hover {
    translate: 0 -10px;
    scale: 1.025;
  }
}

.login-panel__mock-header {
  display: flex;
  align-items: center;
  gap: .85em;
  padding: var(--pemo-size-mock-header-pad) var(--pemo-size-mock-pad);
  background: var(--pemo-color-surface-subtle);
  border-bottom: 1px solid var(--pemo-color-hairline);
}

.login-panel__mock-badge {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  height: var(--pemo-size-mock-badge);
  width: var(--pemo-size-mock-badge);
  border-radius: var(--pemo-size-mock-badge-radius);
  background: var(--pemo-color-brand);
  color: var(--pemo-color-surface);
}

.login-panel__mock-badge svg {
  height: 52%;
  width: 52%;
}

.login-panel__mock-title {
  font-size: var(--pemo-text-mock-title);
  font-weight: var(--pemo-weight-semibold);
  line-height: 1.2;
  letter-spacing: -.1px;
  color: var(--pemo-color-ink);
}

.login-panel__mock-powered {
  display: flex;
  align-items: center;
  gap: .5em;
  margin-left: auto;
  flex-shrink: 0;
  border: 1px solid var(--pemo-color-hairline);
  border-radius: 999px;
  background: var(--pemo-color-surface);
  padding: calc(var(--pemo-mock-unit) * .3) calc(var(--pemo-mock-unit) * .45);
  font-size: var(--pemo-text-mock-powered);
  font-weight: var(--pemo-weight-medium);
  line-height: 1;
  color: var(--pemo-color-ink-secondary);
  white-space: nowrap;
}

.login-panel__mock-partner {
  display: block;
  height: var(--pemo-size-mock-logo-h);
  width: auto;
  flex-shrink: 0;
}

/* ---------- balance ---------- */

.login-panel__mock-balance {
  /* Asymmetric like the reference — label sits lower than the buttons close —
     but opened out from its 1.4/1 to give the balance room to breathe. */
  padding: 1.5em var(--pemo-size-mock-pad) 1.25em;
  border-bottom: 1px solid var(--pemo-color-hairline);
  /* Column gap rather than margins on the children: an em margin on the
     amount would resolve against its own type, making the label/amount gap
     twice the amount/buttons one. */
  display: flex;
  flex-direction: column;
  gap: 1em;
}

.login-panel__mock-label {
  display: block;
  font-size: var(--pemo-text-mock-label);
  font-weight: var(--pemo-weight-medium);
  line-height: 1.2;
  letter-spacing: .2px;
  color: var(--pemo-color-ink-muted);
}

.login-panel__mock-amount {
  display: flex;
  align-items: center;
  gap: .28em;
  font-size: var(--pemo-text-mock-amount);
  font-weight: var(--pemo-weight-semibold);
  line-height: 1.15;
  letter-spacing: -.5px;
  color: var(--pemo-color-ink);
}

.login-panel__mock-actions {
  display: flex;
  align-items: center;
  gap: .7em;
}

/* Spans, not buttons: the host iframe is sandboxed to allow-scripts only, so
   nothing here can navigate or submit. Keeping them unfocusable stops the
   panel handing the user a dead tab stop next to the login form. */
.login-panel__mock-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45em;
  height: var(--pemo-size-mock-action-h);
  padding: 0 1.1em;
  border-radius: var(--pemo-size-mock-action-radius);
  font-size: var(--pemo-text-mock-action);
  line-height: 1;
  white-space: nowrap;
  user-select: none;
}

.login-panel__mock-action svg {
  height: 1.15em;
  width: 1.15em;
  flex-shrink: 0;
}

.login-panel__mock-action--primary {
  background: #222529;
  color: var(--pemo-color-surface);
  font-weight: var(--pemo-weight-semibold);
}

.login-panel__mock-action--secondary {
  background: var(--pemo-color-surface);
  border: 1px solid var(--pemo-color-hairline);
  color: var(--pemo-color-ink);
  font-weight: var(--pemo-weight-medium);
}

/* ---------- recent activity ---------- */

.login-panel__mock-activity-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pemo-size-mock-pad);
  padding: var(--pemo-size-mock-activity-pad) var(--pemo-size-mock-pad);
  border-bottom: 1px solid var(--pemo-color-hairline);
}

.login-panel__mock-activity-title {
  font-size: var(--pemo-text-mock-activity);
  font-weight: var(--pemo-weight-semibold);
  line-height: 1.2;
  color: var(--pemo-color-ink);
}

.login-panel__mock-rows {
  margin: 0;
  padding: 0;
  list-style: none;
}

.login-panel__mock-row {
  display: flex;
  align-items: center;
  gap: .95em;
  padding: var(--pemo-size-mock-row-pad) var(--pemo-size-mock-pad);
  animation: pemo-mock-row-in 900ms cubic-bezier(.4, 0, .2, 1) both;
}

.login-panel__mock-row + .login-panel__mock-row {
  border-top: 1px solid var(--pemo-color-hairline);
}

/* The rows follow the card by 400ms, on the slower 900ms pace above, with a
   wider stagger between them. */
.login-panel__mock-row:nth-child(1) { animation-delay: 1250ms; }
.login-panel__mock-row:nth-child(2) { animation-delay: 1450ms; }
.login-panel__mock-row:nth-child(3) { animation-delay: 1650ms; }

.login-panel__mock-row-icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  height: var(--pemo-size-mock-row-icon);
  width: var(--pemo-size-mock-row-icon);
  border-radius: 999px;
}

/* Per-icon, because the reference draws the three at different optical sizes
   (ink of 36% / 48% / 52% of the circle) and each glyph fills its own viewBox
   differently. These land each one on its reference ink size. */
.login-panel__mock-row-icon svg {
  height: 45%;
  width: 45%;
}

.login-panel__mock-row-icon--deposit svg,
.login-panel__mock-row-icon--vendor svg {
  height: 68%;
  width: 68%;
}

.login-panel__mock-row-icon--card svg {
  height: 61%;
  width: 61%;
}

.login-panel__mock-row-icon--deposit {
  background: var(--pemo-color-tint-deposit);
  color: var(--pemo-color-icon-deposit);
}

.login-panel__mock-row-icon--vendor {
  background: var(--pemo-color-tint-vendor);
  color: var(--pemo-color-icon-vendor);
}

.login-panel__mock-row-icon--card {
  background: var(--pemo-color-tint-card);
  color: var(--pemo-color-icon-card);
}

.login-panel__mock-row-name {
  font-size: var(--pemo-text-mock-row);
  font-weight: var(--pemo-weight-medium);
  line-height: 1.3;
  color: var(--pemo-color-ink);
}

.login-panel__mock-row-amount {
  display: inline-flex;
  align-items: center;
  gap: .22em;
  margin-left: auto;
  flex-shrink: 0;
  font-size: var(--pemo-text-mock-row-amount);
  font-weight: var(--pemo-weight-semibold);
  line-height: 1.3;
  white-space: nowrap;
  color: var(--pemo-color-ink);
}

.login-panel__mock-row-amount--credit {
  color: var(--pemo-color-credit);
}

/* The AED glyph is a symbol, so it takes its size from the text around it.
   Both axes are set explicitly — the viewBox is square, and width:auto on a
   <use>d symbol resolves to the 300px default rather than to the height. */
.login-panel__aed {
  height: .92em;
  width: .92em;
  flex-shrink: 0;
}

.login-panel__icon-defs {
  position: absolute;
  height: 0;
  width: 0;
  overflow: hidden;
}

@keyframes pemo-mock-rise {
  from { transform: translateY(12px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
@keyframes pemo-mock-row-in {
  from { transform: translateY(6px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* ---------- cashback & Wakala slides ---------- */

.login-panel__fit {
  container-type: size;
  height: 100%;
  width: 100%;
  display: grid;
  place-items: center;
}

/* One unit drives each composition; it takes whichever axis binds first.
     100u wide  = title block + art
      91.7u tall = title 13.7 + gap 8.7 + art 69.3
   The art is 66.15u wide — 0.9 of the 73.5 it was — and 1.047 as tall. */
.promo { --u: min(1cqi, 1.09cqb); width: calc(100 * var(--u)); }

.promo__title {
  margin: 0 auto;
  font-size: calc(5.4 * var(--u));
  font-weight: 600;
  line-height: 1.27;
  letter-spacing: -.02em;
  text-align: center;
  color: var(--pemo-color-ink);
}

.scene { margin-top: calc(8.7 * var(--u)); display: grid; place-items: center; }

.scene__float {
  animation: visual-float 2s cubic-bezier(.37, 0, .63, 1) infinite alternate;
  transform: translate3d(0, 0, 0) scale(1);
  transition: transform .45s cubic-bezier(.22, 1, .36, 1);
  will-change: transform, translate;
}

@media (hover: hover) {
  .scene__float:hover {
    animation-play-state: paused;
    transform: translate3d(0, -10px, 0) scale(1.025);
  }
}

.scene__visual { display: block; width: calc(66.15 * var(--u)); height: auto; }

@keyframes visual-float {
  from { translate: 0 8px; }
  to   { translate: 0 -8px; }
}

/* Same one-unit system as the cashback slide:
     100u wide = title block
      87.3u tall = title 13.7 + gap 7 + art 66.6
   The art is 69.7u wide — the illustration's share of the reference frame. */
.wakala { --u: min(1cqi, 1.145cqb); width: calc(100 * var(--u)); }

.wakala__title {
  margin: 0 auto;
  font-size: calc(5.4 * var(--u));
  font-weight: 600;
  line-height: 1.27;
  letter-spacing: -.02em;
  text-align: center;
  color: var(--pemo-color-ink);
}

.wakala__art {
  display: block;
  margin: calc(7 * var(--u)) auto 0;
  width: calc(69.7 * var(--u));
  height: auto;
  overflow: visible;
}

/* The dashed ring turns on its own centre — 75s a revolution, slow enough
   that it reads as drift rather than rotation. */
.wk-ring {
  transform-origin: 411px 689px;
  animation: wk-spin 75s linear infinite;
}

@keyframes wk-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* The amount rides the ring itself rather than a traced path: the outer
   group swings around the ring's centre, the inner one counter-rotates by
   the same amount about the pill's own anchor so the text stays upright.
   Angles are SVG-clockwise, so -120deg sits above the bank and -30deg above
   the deposit; the sweep between them passes over the top of the ring.

   One trip, no loop, paced to the 6s the slide is up: the chip is visible by
   1.2s, sets off at 1.2s and takes 4.3s over the arc, landing at 5.5s — half
   a second before the dissolve to the next slide begins. 'both' fill keeps
   it at the start beforehand and on the deposit afterwards, so the money
   arrives and stays arrived. The carousel script rewinds these on replay. */
.wk-carrier {
  transform-origin: 411px 689px;
  animation: wk-carry 4.3s cubic-bezier(.45, 0, .55, 1) 1.2s both;
}

.wk-pill-upright {
  transform-origin: 641px 689px;
  animation: wk-upright 4.3s cubic-bezier(.45, 0, .55, 1) 1.2s both;
}

@keyframes wk-carry {
  from { transform: rotate(-120deg); }
  to   { transform: rotate(-30deg); }
}

@keyframes wk-upright {
  from { transform: rotate(120deg); }
  to   { transform: rotate(30deg); }
}

/* Fades in from 0.8s, finishing at 1.2s — exactly when it sets off — then
   stays. */
.wk-pill-fade { animation: wk-fade .4s linear .8s both; }

@keyframes wk-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ---------- pagination ----------
   Rebuilt in CSS rather than placed as an image, because the active bar has
   to fill. Dots and bar at 8x8 and 24x8, all rx 4, 8px gaps. Always a
   control here, not just an indicator — this panel always auto-rotates, so
   a dot jumps to its slide and lets the rotation carry on from there rather
   than switching into some separate manual mode. */

.pager {
  position: absolute;
  left: 50%;
  bottom: 20px;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 24px;
  padding: 0 8px;
}

/* Every item is the same element; the active one simply grows. Transitioning
   width means the dot stretches into the bar and its neighbours slide over,
   rather than one element being swapped for another. */
.pager__item {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 4px;
  background: #bec2c7;
  transition: width .7s cubic-bezier(.22, 1, .36, 1);
  cursor: pointer;
}

/* 8px is not a target — each dot gets a hit area worth aiming at. */
.pager__item::after {
  content: "";
  position: absolute;
  inset: -10px -4px;
}

.pager__item:focus-visible {
  outline: 2px solid #339970;
  outline-offset: 3px;
}

.pager__item.is-active { width: 24px; }

.pager__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: 4px;
  background: #62666a;
}

/* The loader only runs in the active item, so it starts from zero each time
   the active slot moves. */
.pager__item.is-active .pager__fill {
  animation: pager-load 6s linear infinite;
}

/* Starts at 8px — the dot's own width — so the dark head is a circle from
   the first frame and stretches into the pill, matching the track it runs
   in. From 0 it was a 1-2px slice whose corner radii get clamped to almost
   nothing, which reads as a flat grey edge. */
@keyframes pager-load {
  from { width: 8px; }
  to   { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .login-panel__mock,
  .login-panel__mock-row,
  .scene__float { animation: none; transition: none; }
  .wk-ring, .wk-carrier, .wk-pill-upright, .wk-pill-fade, .login-panel__cta { animation: none; }
  /* animation: none would drop the chip back to its 0deg anchor, so place it
     on the deposit — where the trip would have left it. */
  .wk-carrier { transform: rotate(-30deg); }
  .wk-pill-upright { transform: rotate(30deg); }
  .wk-pill-fade { opacity: 1; }
  .login-panel__slide, .pager__item { transition: none; }
  .pager__item.is-active .pager__fill { animation: none; width: 100%; }
}
