/* ==========================================================================
   Jebly auth — the shared login and password-reset views.

   Loaded after landing.css, which supplies every token, the .jb element reset
   and the shared components this sheet composes (.jb-btn, .jb-input, .jb-disc,
   .jb-iconbtn). Nothing below may contain a raw hex colour, radius, duration
   or easing curve — reference a --jb-* token instead.

   The page is NOT inside the landing chrome, so `.jb` sits on <main> and on
   each .modal-content rather than on <body>; body styling is restated here.

   Bootstrap 4 is still loaded for the modal plumbing and the reCAPTCHA grid,
   so a handful of rules below neutralise its element defaults. Each one is
   marked `bs4:`.

   Order: 1 page shell · 2 brand rail · 3 form card · 4 fields · 5 captcha
          6 modals · 7 immersive login · 8 responsive · 9 reduced motion
          10 dark theme
   ========================================================================== */

/* =========================== 1 · PAGE SHELL ============================== */

/* landing.css reserves the fixed nav's height with
   `body:not(.jb) { padding-block-start: var(--jb-nav-height) }`. This page has
   no nav, so the reservation is released — at (0,1,1), matching that rule. */
body.jbl-auth-body {
  margin: 0;
  padding-block-start: 0;
  min-block-size: 100vh;
  font-family: var(--jb-font);
  font-size: var(--jb-fs-body);
  line-height: var(--jb-lh-body);
  color: var(--jb-text-primary);
  background: var(--jb-background);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.jbl-auth {
  --jb-auth-orbit-radius: 50%;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: var(--jb-sp-24);
  padding: var(--jb-sp-24);
  min-block-size: 100vh;
  min-block-size: 100svh;
}

.jbl-auth > *, .jbl-auth__card, .jbl-field, .jbl-field__control { min-inline-size: 0; }

/* bs4: Bootstrap's reboot puts a bottom margin on every heading, <p>, <ul>
   and <label>. landing.css resets those at zero specificity via :where(), so
   it loses to the reboot here. Restated at the page root, still inside
   :where() so every component class below outranks it. */
.jbl-auth :where(h1, h2, p, label),
.jbl-modal :where(h2, p) { margin: 0; }
.jbl-auth :where(ul) { margin: 0; padding: 0; list-style: none; }


/* =========================== 2 · BRAND RAIL ============================== */

.jbl-auth__brand {
  position: relative;
  display: flex; flex-direction: column;
  gap: var(--jb-sp-48);
  padding: var(--jb-sp-48);
  /* One soft bloom over the brand gradient so it does not read as a flat
     wash. A radial-gradient, not a disc element: it has no edge to catch. */
  background:
    radial-gradient(38% 34% at 88% 86%, var(--jb-primary-a12) 0%, transparent 100%),
    var(--jb-gradient-brand);
  overflow: hidden;
  border-radius: var(--jb-radius-extra-large);
  isolation: isolate;
}

/* Decorative rings stay clipped to the rail and never cover its links. */
.jbl-auth__brand::before, .jbl-auth__brand::after {
  content: "";
  position: absolute;
  z-index: -1;
  inline-size: 75%;
  aspect-ratio: 1;
  inset-inline-end: -30%;
  inset-block-end: -25%;
  border: var(--jb-hairline) solid var(--jb-on-inverse-70);
  border-radius: var(--jb-auth-orbit-radius);
  pointer-events: none;
}
.jbl-auth__brand::after {
  inline-size: 95%;
  inset-inline-end: -40%;
  inset-block-end: -35%;
}

/* The version line is optional, so the copy centres itself between the logo
   and whatever is below rather than relying on space-between. */
.jbl-auth__brandcopy { margin-block: auto; }

.jbl-auth__brandlogo, .jbl-auth__minilogo {
  align-items: center;
  gap: var(--jb-sp-16);
  inline-size: fit-content;
  max-inline-size: 100%;
}
.jbl-auth__brandlogo {
  display: inline-flex;
  padding: var(--jb-sp-16) var(--jb-sp-24);
  border: var(--jb-hairline) solid var(--jb-on-inverse-70);
  border-radius: var(--jb-radius-extra-large);
  background: var(--jb-surface);
  box-shadow: var(--jb-shadow-glow);
}
.jbl-auth__wordmark {
  font-size: var(--jb-fs-h2);
  font-weight: var(--jb-fw-bold);
  line-height: var(--jb-lh-h3);
  color: var(--jb-text-primary);
}
.jbl-auth__brandaccent { color: var(--jb-accent-primary-text); }

.jbl-auth__brandlogo img {
  inline-size: auto; block-size: var(--jb-sp-96);
  max-inline-size: 160px; max-block-size: var(--jb-sp-96);
  object-fit: contain;
}

.jbl-auth__brandtitle {
  font-size: var(--jb-fs-h1);
  line-height: var(--jb-lh-h1);
  font-weight: var(--jb-fw-bold);
  max-inline-size: 16ch;
  text-wrap: balance;
}
.jbl-auth__brandsub {
  margin-block-start: var(--jb-sp-16);
  font-size: var(--jb-fs-lead);
  line-height: var(--jb-lh-lead);
  color: var(--jb-text-secondary);
  max-inline-size: 44ch;
}

.jbl-auth__points {
  display: grid; gap: var(--jb-sp-12);
  margin-block-start: var(--jb-sp-32);
  max-inline-size: 440px;
}
.jbl-auth__points li {
  display: flex; align-items: center; gap: var(--jb-sp-12);
  font-size: var(--jb-fs-sm);
  font-weight: var(--jb-fw-medium);
  padding: var(--jb-sp-12) var(--jb-sp-16);
  border: var(--jb-hairline) solid var(--jb-on-inverse-70);
  border-radius: var(--jb-radius-card);
  background: var(--jb-on-inverse-56);
  overflow-wrap: anywhere;
}
.jbl-auth__points svg {
  inline-size: var(--jb-icon); block-size: var(--jb-icon); flex: none;
  padding: 2px;
  border-radius: var(--jb-radius-pill);
  background: var(--jb-surface);
  color: var(--jb-accent-primary-text);
}

.jbl-auth__version {
  font-size: var(--jb-fs-xs);
  color: var(--jb-text-secondary);
}


/* ============================ 3 · FORM CARD ============================== */

.jbl-auth__panel {
  position: relative;
  display: grid; place-items: center;
  padding: var(--jb-sp-48) var(--jb-gutter);
  background: var(--jb-background);
}
/* Theme switch parked in the panel's top inline-end corner (reset view; the
   login view carries it in its .jbl-auth__nav row instead). */
.jbl-auth__theme {
  position: absolute; z-index: 1;
  inset-block-start: var(--jb-sp-24); inset-inline-end: var(--jb-sp-24);
}

.jbl-auth__card {
  inline-size: min(100%, 484px);
  padding: var(--jb-sp-32);
  border: var(--jb-hairline) solid var(--jb-chip-border);
  border-radius: var(--jb-radius-extra-large);
  background: var(--jb-surface);
  box-shadow: var(--jb-shadow-float);
}
.jbl-auth__head {
  padding-block-end: var(--jb-sp-24);
  border-block-end: var(--jb-hairline) solid var(--jb-chip-border);
}
.jbl-auth__head, .jbl-auth__brandcopy, .jbl-modal__body { overflow-wrap: anywhere; }

.jbl-auth__nav {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--jb-sp-16);
  margin-block-end: var(--jb-sp-32);
}

.jbl-auth__back {
  display: inline-flex; align-items: center; gap: var(--jb-sp-8);
  font-size: var(--jb-fs-sm); font-weight: var(--jb-fw-medium);
  color: var(--jb-text-secondary);
  transition: color var(--jb-motion-fast) var(--jb-ease-out);
  max-inline-size: 100%;
}
.jbl-auth__back:hover { color: var(--jb-accent-primary-text); text-decoration: none; }
/* CSS has no logical mirror for a glyph, so the arrow flips on --jb-dir. */
.jbl-auth__backicon {
  inline-size: var(--jb-icon-sm); block-size: var(--jb-icon-sm); flex: none;
  transform: scaleX(var(--jb-dir));
  transition: transform var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-auth__back:hover .jbl-auth__backicon {
  transform: translateX(calc(var(--jb-dir) * -2px)) scaleX(var(--jb-dir));
}

/* The rail carries the logo on wide screens; under 900px the card does. */
.jbl-auth__minilogo { display: none; }
.jbl-auth__minilogo img {
  inline-size: auto; block-size: var(--jb-sp-64);
  max-inline-size: 132px; max-block-size: var(--jb-sp-64);
  object-fit: contain;
}

.jbl-auth__chip {
  display: inline-flex; align-items: center; gap: var(--jb-sp-8);
  padding: var(--jb-sp-4) var(--jb-sp-12);
  border-radius: var(--jb-radius-pill);
  background: var(--jb-soft-primary);
  color: var(--jb-accent-primary-text);
  font-size: var(--jb-fs-xs); font-weight: var(--jb-fw-semibold);
}
.jbl-auth__chip svg { inline-size: var(--jb-icon-sm); block-size: var(--jb-icon-sm); flex: none; }

.jbl-auth__title {
  margin-block-start: var(--jb-sp-16);
  font-size: var(--jb-fs-h2); line-height: var(--jb-lh-h2);
  font-weight: var(--jb-fw-bold);
}
.jbl-auth__sub {
  margin-block-start: var(--jb-sp-8);
  font-size: var(--jb-fs-sm); line-height: var(--jb-lh-lead);
  color: var(--jb-text-secondary);
}

.jbl-auth__form {
  display: grid; gap: var(--jb-sp-20);
  margin-block-start: var(--jb-sp-32);
}

.jbl-auth__row {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--jb-sp-12);
}

.jbl-auth__forgot {
  font-size: var(--jb-fs-sm); font-weight: var(--jb-fw-medium);
  color: var(--jb-accent-primary-text);
  background: none; border: 0; padding: 0; cursor: pointer;
  transition: color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-auth__forgot:hover { color: var(--jb-primary); }

.jbl-auth__submiticon { inline-size: var(--jb-icon-sm); block-size: var(--jb-icon-sm); transform: scaleX(var(--jb-dir)); }
.jbl-auth__submit:hover .jbl-auth__submiticon {
  transform: translateX(calc(var(--jb-dir) * 2px)) scaleX(var(--jb-dir));
}

.jbl-auth__demo {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--jb-sp-16);
  margin-block-start: var(--jb-sp-24);
  padding: var(--jb-sp-16);
  border: var(--jb-hairline) dashed var(--jb-chip-border);
  border-radius: var(--jb-radius-card);
  background: var(--jb-background);
}
.jbl-auth__democred { display: grid; gap: var(--jb-sp-4); font-size: var(--jb-fs-sm); min-inline-size: 0; overflow-wrap: anywhere; }
.jbl-auth__demo .jb-iconbtn { flex: none; }


/* ============================== 4 · FIELDS =============================== */

.jbl-field { display: grid; gap: var(--jb-sp-8); }

.jbl-field__label {
  font-size: var(--jb-fs-sm);
  font-weight: var(--jb-fw-medium);
  color: var(--jb-text-primary);
}

.jbl-field__control { position: relative; display: block; }

.jbl-field__lead {
  position: absolute;
  inset-inline-start: var(--jb-sp-16);
  inset-block-start: 50%;
  translate: 0 -50%;
  inline-size: var(--jb-icon); block-size: var(--jb-icon);
  color: var(--jb-hint);
  pointer-events: none;
  transition: color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-field__control:focus-within .jbl-field__lead { color: var(--jb-accent-primary-text); }

/* .jb-input owns the box; only the icon gutters are added here. bs4's
   .form-control is deliberately not used on these inputs. */
.jbl-field__input {
  display: block;
  padding-inline-start: calc(var(--jb-sp-16) + var(--jb-icon) + var(--jb-sp-12));
  min-inline-size: 0;
  background: var(--jb-background);
  transition: border-color var(--jb-motion-fast) var(--jb-ease-out),
              box-shadow var(--jb-motion-fast) var(--jb-ease-out),
              background-color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-field__input:focus { background: var(--jb-surface); }
.jbl-field__control--trail .jbl-field__input {
  padding-inline-end: calc(var(--jb-sp-16) + var(--jb-icon) + var(--jb-sp-12));
}
.jbl-field__input:-webkit-autofill { -webkit-text-fill-color: var(--jb-text-primary); }

.jbl-field__trail {
  position: absolute;
  inset-inline-end: var(--jb-sp-8);
  inset-block-start: 50%;
  translate: 0 -50%;
  display: grid; place-items: center;
  inline-size: var(--jb-control-h-sm); block-size: var(--jb-control-h-sm);
  border: 0; padding: 0; background: none; cursor: pointer;
  border-radius: var(--jb-radius-medium);
  color: var(--jb-text-secondary);
  transition: color var(--jb-motion-fast) var(--jb-ease-out),
              background-color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-field__trail:hover { color: var(--jb-accent-primary-text); background: var(--jb-soft-primary); }
.jbl-field__eye { inline-size: var(--jb-icon); block-size: var(--jb-icon); }
/* Crossed-out eye means "currently hidden, click to show" — the default. */
.jbl-field__eye--on { display: none; }
.jbl-field__trail.is-shown .jbl-field__eye--on { display: block; }
.jbl-field__trail.is-shown .jbl-field__eye--off { display: none; }

/* --- checkbox ------------------------------------------------------------
   The native input stays in the accessibility tree and keeps the focus ring;
   the painted box is a sibling span. */
.jbl-check {
  position: relative;
  display: inline-flex; align-items: center; gap: var(--jb-sp-8);
  cursor: pointer;
  user-select: none;
}
.jbl-check input {
  position: absolute; inline-size: 1px; block-size: 1px;
  opacity: 0; margin: 0;
}
.jbl-check__box {
  display: grid; place-items: center;
  inline-size: var(--jb-icon); block-size: var(--jb-icon); flex: none;
  border: var(--jb-hairline) solid var(--jb-border);
  border-radius: var(--jb-radius-medium);
  background: var(--jb-surface);
  color: var(--jb-on-primary);
  transition: background-color var(--jb-motion-fast) var(--jb-ease-out),
              border-color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-check__box svg { inline-size: 14px; block-size: 14px; opacity: 0; transition: opacity var(--jb-motion-fast) var(--jb-ease-out); }
.jbl-check:hover .jbl-check__box { border-color: var(--jb-primary); }
.jbl-check input:checked + .jbl-check__box { background: var(--jb-primary); border-color: var(--jb-primary); }
.jbl-check input:checked + .jbl-check__box svg { opacity: 1; }
.jbl-check input:focus-visible + .jbl-check__box {
  outline: var(--jb-focus-width) solid var(--jb-primary);
  outline-offset: var(--jb-focus-width);
}
.jbl-check__label { font-size: var(--jb-fs-sm); color: var(--jb-text-secondary); }

/* --- sign-in method switch (store-panel roles) ----------------------------
   landing.css's .jb-seg slides a thumb that admin/js/jebly/components.js
   measures. This page does not load that script, so the switch has no
   .jb-seg__thumb and the selected tab paints its own fill: two equal halves
   at full width, without the scroll snap the landing strips use. */
.jbl-login-by {
  inline-size: 100%;
  overflow: visible;
  scroll-snap-type: none;
}
.jbl-login-by .jb-seg__tab {
  flex: 1 1 0;
  justify-content: center;
  min-inline-size: 0;
  transition: color var(--jb-motion-fast) var(--jb-ease-out),
              background-color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-login-by .jb-seg__tab[aria-selected="true"] { background: var(--jb-soft-primary); }

/* "Sign in with a one-time code instead" and its reverse: a text button
   under the phone field, in the voice of .jbl-auth__forgot. */
.jbl-auth__modelink {
  justify-self: start;
  padding: 0; border: 0; background: none; cursor: pointer;
  font-size: var(--jb-fs-sm); font-weight: var(--jb-fw-medium);
  color: var(--jb-accent-primary-text);
  text-align: start;
  transition: color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-auth__modelink:hover { color: var(--jb-primary); }

/* --- phone field -----------------------------------------------------------
   intl-tel-input wraps the input in an inline-block .iti and draws the flag
   button over its start, so this control has no .jbl-field__lead icon. The
   control is dir=ltr, but the library keys its RTL geometry (flag and
   padding on the right) off any [dir=rtl] ancestor, which on an Arabic page
   is <html>. The LTR geometry is restated here, above the library's (0,4,1)
   rules. */
.jbl-auth .iti { display: block; inline-size: 100%; }
.jbl-auth .jbl-field__control--tel .iti--allow-dropdown .iti__flag-container { left: 0; right: auto; }
.jbl-auth .jbl-field__control--tel .iti--allow-dropdown input.iti__tel-input.jbl-field__input {
  padding-left: calc(var(--jb-sp-48) + var(--jb-sp-4));
  padding-right: var(--jb-sp-16);
}
.jbl-auth .jbl-field__control--tel .iti__arrow { margin-left: 6px; margin-right: 0; }
/* The flag button's hover fill follows the input's rounded start corners. */
.jbl-auth .jbl-field__control--tel .iti__selected-flag {
  border-radius: var(--jb-radius-medium) 0 0 var(--jb-radius-medium);
}
/* The country list is rendered on <body> (_tel-input's dropdownContainer),
   outside the dir=ltr control. On an Arabic page it would inherit rtl from
   <html> and grow leftwards, off screen, from the input's left edge; opening
   it focuses the search field, the page scrolls sideways, and the library
   closes the list on that scroll. Laid out LTR like the field, it opens
   under the input. The library's [dir=rtl] margins still match through
   <html>, so the LTR ones are restated here, above the library's (0,2,0)
   rules. */
.jbl-auth-body > .iti--container { direction: ltr; text-align: left; }
.jbl-auth-body > .iti--container .iti__flag-box,
.jbl-auth-body > .iti--container .iti__country-name { margin-right: 8px; margin-left: 0; }

/* --- code stage (#otpStage) ------------------------------------------------
   Takes #form-id's place once a code is sent, in the same rhythm. otp.css
   styles the code cells and the resend button inside it. */
.jbl-otp-stage { margin-block-start: var(--jb-sp-24); }
.jbl-otp-stage > form { display: grid; gap: var(--jb-sp-20); }
.jbl-otp-stage__back {
  justify-self: start;
  display: inline-flex; align-items: center; gap: var(--jb-sp-8);
  padding: 0; border: 0; background: none; cursor: pointer;
  font-size: var(--jb-fs-sm); font-weight: var(--jb-fw-medium);
  color: var(--jb-text-secondary);
  transition: color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-otp-stage__back:hover { color: var(--jb-accent-primary-text); }
/* An arrow icon on the button points back in RTL too. */
.jbl-otp-stage__back svg {
  inline-size: var(--jb-icon-sm); block-size: var(--jb-icon-sm); flex: none;
  transform: scaleX(var(--jb-dir));
}
.jbl-otp-stage__sent {
  font-size: var(--jb-fs-sm); line-height: var(--jb-lh-lead);
  color: var(--jb-text-secondary);
  overflow-wrap: anywhere;
}
.jbl-otp-stage__sent bdi {
  font-weight: var(--jb-fw-semibold);
  color: var(--jb-text-primary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Wrong-code and resend errors, announced through role=alert. Empty, it
   takes no room, so the page writes it without whitespace when it has
   nothing to say. */
.jbl-otp-stage__alert {
  font-size: var(--jb-fs-sm); font-weight: var(--jb-fw-medium);
  color: var(--jb-error);
}
.jbl-otp-stage__alert:empty { display: none; }
.jbl-otp-stage__actions {
  display: grid; justify-items: center; gap: var(--jb-sp-12);
}
.jbl-otp-stage__actions .jb-btn { inline-size: 100%; }


/* ============================= 5 · CAPTCHA =============================== */

/* The reCAPTCHA partial is shared with the admin panel and ships bs4 grid
   markup. Only its inputs and the reload affordance are restyled. */
.jbl-auth__captcha #reload-captcha {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--jb-sp-12);
  margin: 0;
}
.jbl-auth__captcha #reload-captcha > div {
  min-inline-size: 0;
  max-width: 100%;
  padding: 0;
}
.jbl-auth__captcha #reload-captcha > .d-flex { align-items: center; }
.jbl-auth__captcha .form-control {
  block-size: var(--jb-control-h-inline);
  border-radius: var(--jb-radius-medium);
  border: var(--jb-hairline) solid var(--jb-chip-border);
  font-size: var(--jb-fs-body);
  box-shadow: none;
}
.jbl-auth__captcha .form-control:focus {
  border-color: var(--jb-primary);
  box-shadow: 0 0 0 3px var(--jb-primary-a25);
}
.jbl-auth__captcha img {
  border-radius: var(--jb-radius-medium);
  min-inline-size: 0;
  max-inline-size: 100%;
  block-size: var(--jb-control-h-inline);
  object-fit: contain;
}
.jbl-auth__captcha .capcha-spin.reloadCaptcha { flex: none; padding: var(--jb-sp-8) !important; }
.jbl-auth__captcha .reloadCaptcha { cursor: pointer; color: var(--jb-text-secondary); }
.jbl-auth__captcha .reloadCaptcha:hover { color: var(--jb-accent-primary-text); }
.jbl-auth__captcha .capcha-spin.active svg { animation: jbl-spin var(--jb-motion-slow) linear infinite; }

@keyframes jbl-spin { to { transform: rotate(360deg); } }


/* ============================== 6 · MODALS =============================== */

.jbl-modal .modal-dialog { max-inline-size: min(420px, calc(100% - var(--jb-sp-32))); margin-inline: auto; }

.jbl-modal__content {
  position: relative;
  border: var(--jb-hairline) solid var(--jb-chip-border);
  border-radius: var(--jb-radius-extra-large);
  box-shadow: var(--jb-shadow-float);
  background: var(--jb-surface);
  font-family: var(--jb-font);
}

.jbl-modal__close {
  position: absolute;
  z-index: 1;
  inset-block-start: var(--jb-sp-12);
  inset-inline-end: var(--jb-sp-12);
  display: grid; place-items: center;
  inline-size: var(--jb-disc-sm); block-size: var(--jb-disc-sm);
  border: 0; padding: 0; cursor: pointer;
  border-radius: var(--jb-radius-pill);
  background: var(--jb-chip-background);
  color: var(--jb-text-secondary);
  transition: background-color var(--jb-motion-fast) var(--jb-ease-out),
              color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-modal__close:hover { background: var(--jb-soft-primary); color: var(--jb-accent-primary-text); }
.jbl-modal__close svg { inline-size: var(--jb-icon-sm); block-size: var(--jb-icon-sm); }

.jbl-modal__body {
  display: grid; justify-items: center; gap: var(--jb-sp-16);
  padding: var(--jb-sp-48) var(--jb-sp-32) var(--jb-sp-32);
  text-align: center;
}
.jbl-modal__title { font-size: var(--jb-fs-h3); line-height: var(--jb-lh-h3); font-weight: var(--jb-fw-bold); }
.jbl-modal__text { font-size: var(--jb-fs-sm); line-height: var(--jb-lh-lead); color: var(--jb-text-secondary); }
.jbl-modal__body .jb-btn { inline-size: 100%; margin-block-start: var(--jb-sp-8); }
.jbl-modal__form { display: grid; gap: var(--jb-sp-12); inline-size: 100%; }

/* The reset view keeps its existing theme plugin, input IDs and bindings.
   Scoped overrides give those Bootstrap controls the shared auth treatment. */
.jbl-auth--reset .reset-password { width: 100%; max-inline-size: 484px; margin: 0; }
.jbl-auth__resetmark {
  display: grid; place-items: center;
  inline-size: var(--jb-disc-lg); block-size: var(--jb-disc-lg);
  border-radius: var(--jb-radius-extra-large);
  background: var(--jb-soft-primary);
}
.jbl-auth__resetmark img { inline-size: var(--jb-disc-sm); max-block-size: var(--jb-disc-sm); }
.jbl-auth__resetform { margin-block-start: var(--jb-sp-32); }
.jbl-auth--reset .input-label {
  display: flex; align-items: center; gap: var(--jb-sp-8);
  font-size: var(--jb-fs-sm); font-weight: var(--jb-fw-medium);
  color: var(--jb-text-primary);
}
.jbl-auth--reset .form-label-secondary { margin-inline-start: auto; }
.jbl-auth--reset .input-group {
  flex-wrap: nowrap;
  border: var(--jb-hairline) solid var(--jb-chip-border);
  border-radius: var(--jb-radius-medium);
  background: var(--jb-background);
}
.jbl-auth--reset .input-group:focus-within { border-color: var(--jb-primary); box-shadow: 0 0 0 3px var(--jb-primary-a25); }
.jbl-auth--reset .form-control {
  min-inline-size: 0;
  block-size: var(--jb-control-h-inline);
  font: inherit; color: var(--jb-text-primary);
  background: transparent;
  border: 0; box-shadow: none;
  padding-inline: var(--jb-sp-16);
}
.jbl-auth--reset .input-group-text {
  border: 0; background: transparent;
  color: var(--jb-text-secondary);
  padding-inline: var(--jb-sp-16);
}
.jbl-auth--reset .btn--primary {
  min-block-size: var(--jb-control-h);
  padding: var(--jb-sp-12) var(--jb-sp-24);
  border: 0; border-radius: var(--jb-radius-default);
  background: var(--jb-primary); color: var(--jb-on-primary);
  font: inherit; font-weight: var(--jb-fw-semibold);
  transition: box-shadow var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-auth--reset .btn--primary:hover { box-shadow: var(--jb-shadow-glow-strong); }


/* ====================== 7 · IMMERSIVE LOGIN LAYOUT ======================= */

/* One card split in two: the brand rail with the mascot, and the form. The
   page wash behind it is two soft blooms over the soft brand tint. */
body.jbl-auth-body--login {
  padding: var(--jb-sp-32) var(--jb-sp-24);
  background:
    radial-gradient(ellipse 60% 50% at 0% 0%, var(--jb-primary-a25), transparent 70%),
    radial-gradient(ellipse 50% 45% at 100% 100%, var(--jb-primary-a12), transparent 70%),
    var(--jb-soft-primary);
  overflow-x: hidden;
}
.jbl-auth--login {
  position: relative; isolation: isolate;
  inline-size: min(100%, 1200px); margin-inline: auto;
  min-block-size: calc(100vh - var(--jb-sp-64));
  min-block-size: calc(100svh - var(--jb-sp-64));
  align-items: stretch;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 0; padding: 0;
  border: var(--jb-hairline) solid var(--jb-primary-a12);
  border-radius: var(--jb-radius-extra-large);
  box-shadow: var(--jb-shadow-float), 0 32px 64px var(--jb-primary-a12);
  background: var(--jb-surface); overflow: hidden;
  animation: jbl-auth-arrive var(--jb-motion-slow) var(--jb-ease-out) both;
}

/* --- brand rail ----------------------------------------------------------- */

.jbl-auth--login .jbl-auth__brand {
  display: flex; flex-direction: column;
  gap: var(--jb-sp-20);
  padding: var(--jb-sp-32) var(--jb-sp-48);
  border-radius: 0;
  background:
    radial-gradient(50% 40% at 50% 62%, var(--jb-on-inverse-70), transparent 75%),
    var(--jb-gradient-brand);
}
.jbl-auth--login .jbl-auth__brand::before,
.jbl-auth--login .jbl-auth__brand::after { display: none; }

.jbl-auth--login .jbl-auth__brandlogo {
  padding: 0; background: none; border: 0; box-shadow: none;
  gap: var(--jb-sp-12);
}
.jbl-auth--login .jbl-auth__brandlogo img { block-size: var(--jb-sp-48); max-block-size: var(--jb-sp-48); }
.jbl-auth--login .jbl-auth__brandlogo .jbl-auth__wordmark { font-size: var(--jb-fs-h3); }
.jbl-auth--login .jbl-auth__brandcopy { margin: 0; }
.jbl-auth--login .jbl-auth__brandtitle {
  font-size: var(--jb-fs-h2); line-height: var(--jb-lh-h2);
  max-inline-size: 18ch; color: var(--jb-text-primary);
}
.jbl-auth--login .jbl-auth__brandsub {
  margin-block-start: var(--jb-sp-12);
  font-size: var(--jb-fs-body); color: var(--jb-text-secondary);
  max-inline-size: 42ch;
}

/* Points read as a row of pills under the stage. */
.jbl-auth--login .jbl-auth__points {
  display: flex; flex-wrap: wrap; gap: var(--jb-sp-8);
  max-inline-size: 100%; margin: 0;
}
.jbl-auth--login .jbl-auth__points li {
  gap: var(--jb-sp-8);
  padding: var(--jb-sp-8) var(--jb-sp-16);
  padding-inline-start: var(--jb-sp-8);
  border: var(--jb-hairline) solid var(--jb-on-inverse-70);
  border-radius: var(--jb-radius-pill);
  background: var(--jb-on-inverse-56);
  color: var(--jb-text-primary);
  font-size: var(--jb-fs-xs); font-weight: var(--jb-fw-semibold);
  transition: transform var(--jb-motion-fast) var(--jb-ease-out),
              background-color var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-auth--login .jbl-auth__points li:hover { transform: translateY(var(--jb-lift)); background: var(--jb-surface); }
.jbl-auth--login .jbl-auth__points svg {
  inline-size: var(--jb-icon-lg); block-size: var(--jb-icon-lg);
  padding: var(--jb-sp-4);
  background: var(--jb-surface); color: var(--jb-accent-primary-text);
}
.jbl-auth--login .jbl-auth__version { color: var(--jb-text-secondary); }

/* --- mascot stage ---------------------------------------------------------- */

.jbl-mascot-stage {
  --jbl-stage: clamp(220px, 21vw, 290px);
  position: relative;
  flex: 1 1 auto;
  display: grid; place-items: center;
  min-block-size: calc(var(--jbl-stage) + var(--jb-sp-32));
}
.jbl-mascot-stage__route {
  position: absolute; inset: 0;
  inline-size: 100%; block-size: 100%;
  pointer-events: none;
}
.jbl-mascot-stage__route path {
  stroke: var(--jb-accent-primary-text); stroke-opacity: .28;
  stroke-width: 1.5; stroke-dasharray: 4 10; stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  animation: jbl-route-flow calc(var(--jb-motion-slow) * 40) linear infinite;
}
.jbl-mascot-stage__route path + path { animation-direction: reverse; }

/* The disc the mascot stands on, with one ring breathing out of it. */
.jbl-mascot-stage__disc {
  position: absolute;
  inset-inline-start: 50%; inset-block-start: 50%;
  translate: -50% -50%;
  inline-size: var(--jbl-stage); aspect-ratio: 1;
  border-radius: 50%;
  border: var(--jb-hairline) solid var(--jb-on-inverse-70);
  background: radial-gradient(circle at 50% 40%, var(--jb-surface) 0%, var(--jb-on-inverse-56) 55%, transparent 72%);
  pointer-events: none;
}
[dir="rtl"] .jbl-mascot-stage__disc { translate: 50% -50%; }
.jbl-mascot-stage__disc::after {
  content: ""; position: absolute; inset: 0;
  border-radius: inherit;
  border: var(--jb-focus-width) solid var(--jb-primary-a25);
  animation: jbl-ring calc(var(--jb-motion-slow) * 8) var(--jb-ease-out) infinite;
}

.jbl-mascot-stage__chip {
  position: absolute; z-index: 2;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--jb-sp-8);
  min-inline-size: var(--jb-disc); block-size: var(--jb-disc);
  padding-inline: var(--jb-sp-12);
  border: var(--jb-hairline) solid var(--jb-primary-a12);
  border-radius: var(--jb-radius-card);
  background: var(--jb-surface); color: var(--jb-accent-primary-text);
  box-shadow: var(--jb-shadow-float);
  pointer-events: none;
  animation: jbl-bob calc(var(--jb-motion-slow) * 9) var(--jb-ease-in-out) infinite;
}
.jbl-mascot-stage__chip svg { inline-size: var(--jb-icon-lg); block-size: var(--jb-icon-lg); flex: none; }
.jbl-mascot-stage__chip i {
  display: block; inline-size: var(--jb-sp-32); block-size: var(--jb-sp-4);
  border-radius: var(--jb-radius-pill); background: var(--jb-primary-a25);
}
.jbl-mascot-stage__chip i + i { inline-size: var(--jb-sp-20); }
.jbl-mascot-stage__chip--receipt {
  inset-inline-start: 4%; inset-block-start: 14%;
  rotate: calc(var(--jb-dir) * -6deg);
}
.jbl-mascot-stage__chip--store {
  inset-inline-end: 8%; inset-block-start: 6%;
  animation-delay: calc(var(--jb-motion-slow) * -3);
}
.jbl-mascot-stage__chip--bike {
  inset-inline-end: 4%; inset-block-end: 16%;
  background: var(--jb-soft-secondary); color: var(--jb-accent-secondary);
  border-color: var(--jb-soft-secondary);
  animation-delay: calc(var(--jb-motion-slow) * -6);
}
.jbl-mascot-stage__chip--done {
  inset-inline-start: 12%; inset-block-end: 10%;
  min-inline-size: var(--jb-disc-sm); block-size: var(--jb-disc-sm); padding: 0;
  border-radius: var(--jb-radius-pill);
  background: var(--jb-primary); color: var(--jb-on-primary); border-color: var(--jb-primary);
  box-shadow: var(--jb-shadow-glow-strong);
  animation-delay: calc(var(--jb-motion-slow) * -2);
}
.jbl-mascot-stage__chip--done svg { inline-size: var(--jb-icon); block-size: var(--jb-icon); stroke-width: 2.5; }

/* --- the character ---------------------------------------------------------
   The official Jebly character from public/assets/states. One <img> per pose
   sits in the frame; data-mood (set by the page script) fades the matching
   one in. --jbl-look-* is a gentle tilt toward the pointer while idle. */
.jbl-mascot {
  --jbl-look-x: 0;
  --jbl-look-y: 0;
  position: relative; z-index: 1;
  inline-size: calc(var(--jbl-stage) * .82);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  animation: jbl-mascot-pop calc(var(--jb-motion-slow) * 2) var(--jb-ease-out) both;
  animation-delay: calc(var(--jb-stagger) * 4);
}
.jbl-mascot__frame {
  position: relative;
  aspect-ratio: 1;
  transform: rotate(calc(var(--jbl-look-x) * 3deg)) translate(calc(var(--jbl-look-x) * 4px), calc(var(--jbl-look-y) * 3px));
  transition: transform var(--jb-motion-base) var(--jb-ease-out);
  animation: jbl-mascot-float calc(var(--jb-motion-slow) * 8) var(--jb-ease-in-out) infinite;
}
.jbl-mascot:hover .jbl-mascot__frame { transform: scale(1.04); }
.jbl-mascot__pose {
  position: absolute; inset: 0;
  display: block; inline-size: 100%; block-size: 100%;
  object-fit: contain;
  opacity: 0;
  transform: translateY(var(--jb-sp-8)) scale(.94);
  transform-origin: 50% 100%;
  transition: opacity var(--jb-motion-fast) var(--jb-ease-out),
              transform var(--jb-motion-base) var(--jb-ease-out);
}
/* The cheer artwork is cropped tighter than the rest. Padding shrinks the
   area object-fit draws into, so he stays the same size when it fades in. */
.jbl-mascot__pose--cheer { padding: 14% 14% 6%; }
.jbl-mascot[data-mood="idle"]  .jbl-mascot__pose--idle,
.jbl-mascot[data-mood="watch"] .jbl-mascot__pose--watch,
.jbl-mascot[data-mood="happy"] .jbl-mascot__pose--happy,
.jbl-mascot[data-mood="cheer"] .jbl-mascot__pose--cheer,
.jbl-mascot[data-mood="error"] .jbl-mascot__pose--error { opacity: 1; transform: none; }

/* The watching pose leans toward the form; the cheer bounces. */
.jbl-mascot[data-mood="watch"] .jbl-mascot__frame { transform: rotate(calc(var(--jb-dir) * 4deg)) translateX(calc(var(--jb-dir) * var(--jb-sp-8))); }
.jbl-mascot[data-mood="happy"] .jbl-mascot__frame,
.jbl-mascot[data-mood="cheer"] .jbl-mascot__frame { animation: jbl-mascot-hop calc(var(--jb-motion-slow) * 2) var(--jb-ease-out) infinite; }
.jbl-mascot[data-mood="error"] .jbl-mascot__frame { animation: jbl-mascot-shake calc(var(--jb-motion-slow) * 1.2) var(--jb-ease-out) both; }

.jbl-mascot__shadow {
  position: absolute;
  inset-inline: 18%; inset-block-end: 2%;
  block-size: var(--jb-sp-12);
  border-radius: 50%;
  background: var(--jb-secondary); opacity: .12;
  filter: blur(2px);
  animation: jbl-mascot-shadow calc(var(--jb-motion-slow) * 8) var(--jb-ease-in-out) infinite;
}

/* --- form panel ------------------------------------------------------------ */

.jbl-auth--login .jbl-auth__panel {
  position: relative; display: flex; flex-direction: column;
  justify-content: center; align-items: center;
  padding: var(--jb-sp-32) var(--jb-sp-48);
  background:
    radial-gradient(40% 30% at 100% 0%, var(--jb-soft-primary), transparent 100%),
    var(--jb-surface);
}
.jbl-auth--login .jbl-auth__nav {
  position: relative; inline-size: min(100%, 420px);
  margin-block-end: var(--jb-sp-24);
}
/* The rail carries the logo at every width on this page. */
.jbl-auth--login .jbl-auth__minilogo { display: none; }
.jbl-auth--login .jbl-auth__card {
  position: relative; inline-size: min(100%, 420px);
  padding: 0; border: 0; border-radius: 0;
  box-shadow: none; background: transparent;
}
.jbl-auth--login .jbl-auth__head { padding-block-end: var(--jb-sp-24); }
.jbl-auth--login .jbl-auth__chip {
  border: var(--jb-hairline) solid var(--jb-primary-a12);
  padding: var(--jb-sp-8) var(--jb-sp-12);
}
.jbl-auth--login .jbl-auth__title {
  font-size: var(--jb-fs-h1); color: var(--jb-text-primary);
}
/* A short brand underline that draws itself under the title. */
.jbl-auth--login .jbl-auth__title::after {
  content: ""; display: block;
  inline-size: var(--jb-sp-48); block-size: var(--jb-sp-4);
  margin-block-start: var(--jb-sp-12);
  border-radius: var(--jb-radius-pill);
  background: linear-gradient(90deg, var(--jb-primary), var(--jb-accent-secondary));
  transform-origin: 0 50%;
  animation: jbl-draw var(--jb-motion-slow) var(--jb-ease-out) both;
  animation-delay: calc(var(--jb-stagger) * 6);
}
[dir="rtl"] .jbl-auth--login .jbl-auth__title::after { transform-origin: 100% 50%; }

.jbl-auth--login .jbl-auth__form { margin-block-start: var(--jb-sp-24); }

.jbl-auth--login .jbl-field__label { transition: color var(--jb-motion-fast) var(--jb-ease-out); }
.jbl-auth--login .jbl-field:focus-within .jbl-field__label { color: var(--jb-accent-primary-text); }
.jbl-auth--login .jbl-field__input {
  block-size: calc(var(--jb-control-h-inline) + var(--jb-sp-8));
  background: var(--jb-background);
}
.jbl-auth--login .jbl-field__input:hover { border-color: var(--jb-primary-a28); }
.jbl-auth--login .jbl-field__input:focus {
  background: var(--jb-surface);
  border-color: var(--jb-primary);
  box-shadow: 0 0 0 4px var(--jb-primary-a12), var(--jb-shadow-glow);
}
.jbl-auth--login .jbl-field__lead {
  transition: color var(--jb-motion-fast) var(--jb-ease-out), transform var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-auth--login .jbl-field__control:focus-within .jbl-field__lead { transform: scale(1.12); }

/* The submit button lifts, glows, and a light sheen crosses it on hover. */
.jbl-auth--login .jbl-auth__submit {
  position: relative; overflow: hidden; isolation: isolate;
  min-block-size: calc(var(--jb-control-h) + var(--jb-sp-8));
  background: linear-gradient(135deg, var(--jb-primary), var(--jb-accent-primary-text));
  box-shadow: var(--jb-shadow-glow);
  transition: transform var(--jb-motion-fast) var(--jb-ease-out), box-shadow var(--jb-motion-fast) var(--jb-ease-out);
}
.jbl-auth--login .jbl-auth__submit::after {
  content: ""; position: absolute; z-index: -1;
  inset-block: 0; inset-inline-start: -60%;
  inline-size: 50%;
  background: linear-gradient(100deg, transparent, var(--jb-on-inverse-56), transparent);
  transform: skewX(-20deg);
  opacity: 0;
}
.jbl-auth--login .jbl-auth__submit:hover::after,
.jbl-auth--login .jbl-auth__submit:focus-visible::after {
  opacity: 1;
  animation: jbl-sheen calc(var(--jb-motion-slow) * 2) var(--jb-ease-out) both;
}
.jbl-auth--login .jbl-auth__submit:hover { transform: translateY(var(--jb-lift)); box-shadow: var(--jb-shadow-glow-strong); }
.jbl-auth--login .jbl-auth__submit:active { transform: scale(var(--jb-press)); }
.jbl-auth--login .jbl-auth__submit:hover .jbl-auth__submiticon {
  transform: translateX(calc(var(--jb-dir) * 4px)) scaleX(var(--jb-dir));
}
.jbl-auth--login .jbl-auth__submiticon { transition: transform var(--jb-motion-fast) var(--jb-ease-out); }

/* --- page entry ------------------------------------------------------------ */

.jbl-auth--login .jbl-auth__brandlogo,
.jbl-auth--login .jbl-auth__brandcopy,
.jbl-auth--login .jbl-auth__points,
.jbl-auth--login .jbl-auth__nav,
.jbl-auth--login .jbl-auth__card {
  animation: jbl-auth-arrive var(--jb-motion-slow) var(--jb-ease-out) both;
}
.jbl-auth--login .jbl-auth__brandcopy { animation-delay: var(--jb-stagger); }
.jbl-auth--login .jbl-auth__nav { animation-delay: calc(var(--jb-stagger) * 2); }
.jbl-auth--login .jbl-auth__card { animation-delay: calc(var(--jb-stagger) * 3); }
.jbl-auth--login .jbl-auth__points { animation-delay: calc(var(--jb-stagger) * 5); }

@keyframes jbl-auth-arrive {
  from { opacity: 0; transform: translateY(var(--jb-rise)); }
  to { opacity: 1; transform: none; }
}
@keyframes jbl-mascot-pop {
  0% { opacity: 0; transform: translateY(calc(var(--jb-rise) * 3)) scale(.8); }
  60% { opacity: 1; transform: translateY(calc(var(--jb-rise) * -1)) scale(1.03); }
  100% { opacity: 1; transform: none; }
}
@keyframes jbl-mascot-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
@keyframes jbl-mascot-shadow {
  0%, 100% { transform: scaleX(1); opacity: .12; }
  50% { transform: scaleX(.84); opacity: .08; }
}
@keyframes jbl-mascot-shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-6px) rotate(-2deg); }
  40%, 80% { transform: translateX(6px) rotate(2deg); }
}
@keyframes jbl-mascot-hop {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  30% { transform: translateY(-10px) scale(.98, 1.03); }
  55% { transform: translateY(0) scale(1.04, .96); }
  70% { transform: translateY(-3px) scale(1, 1); }
}
@keyframes jbl-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(calc(var(--jb-rise) * -.8)); }
}
@keyframes jbl-ring {
  0% { transform: scale(.92); opacity: .9; }
  100% { transform: scale(1.18); opacity: 0; }
}
@keyframes jbl-route-flow { to { stroke-dashoffset: -280; } }
@keyframes jbl-draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes jbl-sheen { from { inset-inline-start: -60%; } to { inset-inline-start: 120%; } }

/* ============================ 8 · RESPONSIVE ============================= */

@media (max-width: 1100px) {
  .jbl-auth__brand { padding: var(--jb-sp-32); }
  .jbl-auth__panel { padding: var(--jb-sp-32) var(--jb-gutter); }
  .jbl-auth--login { gap: 0; padding: 0; }
  .jbl-auth--login .jbl-auth__panel, .jbl-auth--login .jbl-auth__brand { padding: var(--jb-sp-32); }
  .jbl-mascot-stage__chip--receipt i { display: none; }
}

@media (max-width: 900px) {
  .jbl-auth { grid-template-columns: minmax(0, 1fr); padding: 0; gap: 0; }
  /* The rail is supporting copy only; the form owns the small viewport. */
  .jbl-auth__brand { display: none; }
  .jbl-auth__minilogo {
    display: inline-flex;
    order: -1;
    inline-size: 100%;
    justify-content: center;
  }
  .jbl-auth__wordmark { font-size: var(--jb-fs-h3); }
  .jbl-auth__brandlogo img { block-size: var(--jb-sp-64); max-block-size: var(--jb-sp-64); }
  .jbl-auth__panel { align-content: start; padding-block: var(--jb-sp-24) var(--jb-sp-48); }
  .jbl-auth--reset .jbl-auth__brand {
    display: flex;
    align-items: center;
    padding: var(--jb-sp-24) var(--jb-sp-16) 0;
    background: transparent;
  }
  .jbl-auth--reset .jbl-auth__brandcopy,
  .jbl-auth--reset .jbl-auth__version,
  .jbl-auth--reset .jbl-auth__brand::before,
  .jbl-auth--reset .jbl-auth__brand::after { display: none; }
  .jbl-auth--reset .jbl-auth__brandlogo { padding: 0; border: 0; background: none; box-shadow: none; }
  .jbl-auth--reset { align-content: start; }

  /* Login: the rail folds into a header band — logo on one side, the
     mascot standing on the band's edge on the other. */
  body.jbl-auth-body--login { padding: var(--jb-sp-24); }
  .jbl-auth--login {
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
    min-block-size: 0;
    max-inline-size: 484px;
    padding: 0;
    gap: 0;
  }
  .jbl-auth--login .jbl-auth__brand {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--jb-sp-12);
    padding: var(--jb-sp-20) var(--jb-sp-24) 0;
  }
  .jbl-auth--login .jbl-auth__brandlogo { align-self: center; padding-block-end: var(--jb-sp-16); }
  .jbl-auth--login .jbl-auth__brandcopy,
  .jbl-auth--login .jbl-auth__points,
  .jbl-auth--login .jbl-auth__version,
  .jbl-mascot-stage__route,
  .jbl-mascot-stage__chip { display: none; }
  .jbl-mascot-stage {
    --jbl-stage: 150px;
    min-block-size: 0;
    inline-size: var(--jbl-stage);
    block-size: calc(var(--jbl-stage) * .9);
    place-items: end center;
  }
  .jbl-mascot-stage__disc { inset-block-start: 62%; }
  .jbl-mascot { inline-size: calc(var(--jbl-stage) * .82); margin-block-end: calc(var(--jb-sp-8) * -1); }
  .jbl-auth--login .jbl-auth__panel { padding: var(--jb-sp-24); }
  .jbl-auth--login .jbl-auth__card { padding: 0; }
}

@media (max-width: 720px) {
  .jbl-auth__panel { padding-inline: var(--jb-sp-16); }
  .jbl-auth__card { padding: var(--jb-sp-24); }
  .jbl-auth__row { align-items: flex-start; }
  .jbl-modal__body { padding: var(--jb-sp-48) var(--jb-sp-24) var(--jb-sp-24); }
  .jbl-auth__captcha #reload-captcha { grid-template-columns: minmax(0, 1fr); }
  body.jbl-auth-body--login { padding: var(--jb-sp-16); }
  .jbl-auth--login { padding: 0; }
  .jbl-auth--login .jbl-auth__panel { padding: var(--jb-sp-24) var(--jb-sp-20); }
  .jbl-auth--login .jbl-auth__card { padding: 0; }
  .jbl-auth--login .jbl-auth__brand { padding-inline: var(--jb-sp-20); }
  .jbl-mascot-stage { --jbl-stage: 132px; }
}


/* ========================= 9 · REDUCED MOTION ============================ */

@media (prefers-reduced-motion: reduce) {
  .jbl-auth *, .jbl-auth *::before, .jbl-auth *::after,
  .jbl-modal *, .jbl-modal *::before, .jbl-modal *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .jbl-auth__back:hover .jbl-auth__backicon,
  .jbl-auth__submit:hover .jbl-auth__submiticon { transform: scaleX(var(--jb-dir)); }
  .jbl-auth--login,
  .jbl-auth--login .jbl-auth__brandlogo,
  .jbl-auth--login .jbl-auth__brandcopy,
  .jbl-auth--login .jbl-auth__points,
  .jbl-auth--login .jbl-auth__nav,
  .jbl-auth--login .jbl-auth__card,
  .jbl-auth--login .jbl-auth__title::after,
  .jbl-mascot, .jbl-mascot__frame, .jbl-mascot__shadow,
  .jbl-mascot-stage__chip, .jbl-mascot-stage__route path,
  .jbl-mascot-stage__disc::after { animation: none !important; }
  .jbl-auth--login .jbl-auth__submit:hover,
  .jbl-auth--login .jbl-auth__submit:active,
  .jbl-auth--login .jbl-auth__points li:hover,
  .jbl-mascot:hover .jbl-mascot__frame,
  .jbl-mascot[data-mood="watch"] .jbl-mascot__frame,
  .jbl-auth--login .jbl-field__control:focus-within .jbl-field__lead { transform: none; }
}


/* ============================ 10 · DARK THEME ============================ */

/* The tokens in landing.css carry the theme; these are the rules whose light
   value is wrong once the surfaces invert. Mostly the brand rail: in light it
   is a pale green wash with white-tinted pills and rings, which on the dark
   gradient would turn into bright white bars under light text. */
:root[data-theme="dark"] body.jbl-auth-body--login {
  background:
    radial-gradient(ellipse 60% 50% at 0% 0%, var(--jb-primary-a12), transparent 70%),
    radial-gradient(ellipse 50% 45% at 100% 100%, var(--jb-primary-a12), transparent 70%),
    var(--jb-background);
}
:root[data-theme="dark"] .jbl-auth--login .jbl-auth__brand {
  background:
    radial-gradient(50% 40% at 50% 62%, var(--jb-primary-a12), transparent 75%),
    var(--jb-gradient-brand);
}
:root[data-theme="dark"] .jbl-auth__brand::before,
:root[data-theme="dark"] .jbl-auth__brand::after,
:root[data-theme="dark"] .jbl-auth__brandlogo,
:root[data-theme="dark"] .jbl-mascot-stage__disc { border-color: var(--jb-on-inverse-12); }
:root[data-theme="dark"] .jbl-auth__points li,
:root[data-theme="dark"] .jbl-auth--login .jbl-auth__points li {
  border-color: var(--jb-on-inverse-12);
  background: var(--jb-on-inverse-08);
}
:root[data-theme="dark"] .jbl-auth--login .jbl-auth__points li:hover { background: var(--jb-on-inverse-12); }
:root[data-theme="dark"] .jbl-mascot-stage__disc {
  background: radial-gradient(circle at 50% 40%, var(--jb-on-inverse-12) 0%, var(--jb-on-inverse-08) 55%, transparent 72%);
}
:root[data-theme="dark"] .jbl-mascot__shadow { background: var(--jb-inverse-surface); opacity: .4; }
:root[data-theme="dark"] .jbl-mascot-stage__chip { border-color: var(--jb-chip-border); }

/* The shared captcha partial paints its image cell .bg-white (bs4, !important)
   and its input is a bs4 .form-control, both light-only. */
:root[data-theme="dark"] .jbl-auth__captcha .bg-white { background-color: var(--jb-surface) !important; }
:root[data-theme="dark"] .jbl-auth__captcha .form-control { background: var(--jb-background); color: var(--jb-text-primary); }
:root[data-theme="dark"] .jbl-auth__captcha .form-control::placeholder { color: var(--jb-hint); }
:root[data-theme="dark"] .jbl-auth__captcha img { border: var(--jb-hairline) solid var(--jb-chip-border); }
:root[data-theme="dark"] .jbl-auth--reset .form-control::placeholder { color: var(--jb-hint); }
/* bs4 reboot gives the modal backdrop its own black; keep the brand scrim. */
:root[data-theme="dark"] .modal-backdrop { background-color: var(--jb-scrim); }
:root[data-theme="dark"] .modal-backdrop.show { opacity: 1; }

/* intl-tel-input on the phone tab, ported from legacy-dark.css (151-165),
   which only the landing layout loads. Unscoped, because the country list
   is rendered on <body>, outside .jbl-auth. */
:root[data-theme="dark"] .iti__country-list {
  background-color: var(--jb-surface);
  border-color: var(--jb-chip-border);
  color: var(--jb-text-primary);
  box-shadow: var(--jb-shadow-float);
}
:root[data-theme="dark"] .iti__country.iti__highlight,
:root[data-theme="dark"] .iti__selected-flag:hover,
:root[data-theme="dark"] .iti--allow-dropdown .iti__flag-container:hover .iti__selected-flag { background-color: var(--jb-chip-background); }
:root[data-theme="dark"] .iti__dial-code { color: var(--jb-text-secondary); }
:root[data-theme="dark"] .iti__divider { border-color: var(--jb-chip-border); }
:root[data-theme="dark"] .iti__arrow { border-top-color: var(--jb-text-secondary); }
:root[data-theme="dark"] .iti__arrow--up { border-bottom-color: var(--jb-text-secondary); }
:root[data-theme="dark"] .iti__search-input { background: var(--jb-background); color: var(--jb-text-primary); border-color: var(--jb-chip-border); }
