/* ============================================================
   Onyx — sign-in v2 (solo page)

   Ported from onyx_user/login.html. That page is one card on a dark canvas
   with no app shell, which is why this stylesheet is standalone rather than an
   addition to panel/onyx/styles.css: the auth page loads before there is a
   session, and pulling three thousand lines of panel chrome to draw one card
   would be the largest render-blocking asset on the most latency-sensitive
   screen in the product.

   What it does share is the vocabulary. The token block, .btn/.input/.field/
   .hint/.gateline primitives and the .vh/.spin utilities below are
   copied verbatim from styles.css so the card is built out of the same parts
   as the panel the customer lands in — a different blue or a different radius
   here would read as a different product.

   Only the tokens this page actually uses are carried over.
   ============================================================ */

@import url("/panel/onyx/fonts/yekan-bakh/yekan-bakh.css");

:root{
  /* surfaces */
  --s1:#FFFFFF;
  --s2:#F7F8FA;
  --s3:#EDEEF1;
  --line:#E7E8EC;
  --line-soft:#F0F1F3;

  /* text */
  --tx1:#14171C;
  --tx2:#4A515D;
  --tx3:#6B7280;

  /* brand + status */
  --brand:#2F6FED;
  --brand-d:#2A63D4;
  --brand-w:#F7F9FF;
  --brand-l:#D9E4FB;
  --mint:#15803D;   --mint-bg:#E9F6EF;   --mint-line:#BFE3CD;
  --amber:#8F640E;  --amber-bg:#FBF1DC;  --amber-line:#F0E6CC;
  --rose:#B42318;   --rose-bg:#FDECEC;   --rose-line:#F1C4C0;

  /* geometry */
  --r-lg:16px; --r-md:12px; --r-sm:10px; --r-xs:8px;

  /* the canvas — the kit's near-black navy, kept as a token because the
     aurora and the footer text below are all mixed against it */
  --canvas:#0B1020;

  /* set by the view from config('onyx_auth.otp.length') */
  --otp-len:4;
}

*{box-sizing:border-box;}
html,body{margin:0;padding:0;}
body{
  color:var(--tx1);
  font-family:'Yekan Bakh FaNum',Tahoma,sans-serif;
  font-size:14px;
  -webkit-font-smoothing:antialiased;
  text-wrap:pretty;
}
a{color:var(--brand);text-decoration:none;}
a:hover{color:var(--brand-d);}
button,input,select,textarea{font-family:inherit;}
input::placeholder{color:#B9BFC9;}
:focus-visible{outline:2px solid var(--brand);outline-offset:2px;}
/* styles.css:468. Load-bearing, not a tidy-up: this whole flow hides its
   inactive steps with the `hidden` attribute, and `.auth-card form` sets
   display:flex — a class selector, which outranks the UA stylesheet's
   [hidden] rule. Without this line every step renders at once. */
[hidden]{display:none!important;}
.num{font-variant-numeric:tabular-nums;letter-spacing:.3px;}
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}
@keyframes onxspin{to{transform:rotate(360deg);}}
.spin{animation:onxspin 1s linear infinite;}

/* ================= primitives (verbatim from styles.css) ================= */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  min-height:44px;padding:0 16px;border-radius:var(--r-md);
  font-family:inherit;font-size:13.5px;font-weight:700;
  border:1px solid transparent;cursor:pointer;white-space:nowrap;
}
.btn svg{flex:none;}
.btn-pri{background:var(--brand);color:#fff;}
.btn-pri:hover{background:var(--brand-d);color:#fff;}
.btn-pri:active{transform:translateY(1px);}
.btn-gh{background:var(--s1);color:var(--tx2);border-color:var(--line);}
.btn-gh:hover{background:var(--s2);color:var(--tx1);}
.btn[aria-disabled="true"],.btn:disabled{background:var(--s3);color:var(--tx3);cursor:not-allowed;border-color:transparent;}
.btn-block{width:100%;}
.btn-lg{min-height:48px;font-size:14px;font-weight:800;}
/* gating hint — names what is still missing while a CTA stays disabled */
.gateline{display:flex;align-items:center;gap:7px;font-size:11.5px;font-weight:600;color:#96690F;}
.gateline svg{flex:none;}
.gateline[hidden]{display:none;}

.field{display:flex;flex-direction:column;gap:6px;}
.field > label{font-size:13px;font-weight:800;color:var(--tx1);}
.input{
  display:block;width:100%;
  border:1.5px solid #C9CDD6;border-radius:var(--r-md);background:var(--s1);
  font-family:inherit;font-size:16px;font-weight:700;color:var(--tx1);
  padding:12px 14px;text-align:start;
}
.input.num{font-weight:800;letter-spacing:1px;}
.input.ok{border-color:var(--mint);}
.input.bad{border-color:var(--rose);}
.hint{margin:0;font-size:11.5px;color:var(--tx3);line-height:1.6;}
.hint.ok{color:var(--mint);font-weight:700;}
.hint.bad{color:var(--rose);font-weight:700;}
.hint.warn{color:#96690F;font-weight:600;}

/* ================= the page ================= */
.auth{
  min-height:100vh;min-height:100dvh;display:flex;
  background:var(--canvas);
}
/* Two very wide, very low-opacity brand washes. The kit's canvas is flat; on a
   phone-sized viewport a single dark rectangle behind a white card banded
   visibly on OLED screens, and a gradient this shallow costs nothing and
   hides it. Fixed attachment so it does not slide under the card when the
   soft keyboard shortens the viewport. */
.auth::before{
  content:"";position:fixed;inset:0;pointer-events:none;
  background:
    radial-gradient(60% 45% at 78% 8%, rgba(47,111,237,.20), transparent 70%),
    radial-gradient(55% 40% at 12% 96%, rgba(109,79,194,.16), transparent 72%);
}
.auth-wrap{
  position:relative;flex:1;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:16px;padding:32px 20px;
}
.auth-logo{display:block;height:34px;width:auto;}
.auth-card{
  width:100%;max-width:420px;background:var(--s1);border:1px solid var(--line);
  border-radius:20px;padding:28px 24px;box-shadow:0 30px 70px -30px rgba(0,0,0,.7);
  display:flex;flex-direction:column;gap:0;
}
.auth-card form{display:flex;flex-direction:column;gap:14px;margin:0;}
.auth-card h1{margin:0;font-size:19px;font-weight:800;color:var(--tx1);outline:none;}
.auth-sub{margin:-8px 0 0;font-size:12.5px;color:var(--tx3);line-height:1.9;}
.auth-sub b{color:var(--tx1);font-weight:800;}
.linkbtn{border:none;background:none;padding:0 4px;font-family:inherit;font-size:12.5px;font-weight:700;color:var(--brand);cursor:pointer;}
.linkbtn:hover{color:var(--brand-d);}
.auth-fine{margin:0;font-size:11.5px;color:var(--tx3);text-align:center;line-height:1.8;}
.auth-help{position:relative;margin:0;font-size:12px;color:#8A909C;}
.auth-help a{color:#B9C2D0;}
.auth-help a:hover{color:#fff;}

/* ---- step rail ----
   Not in the kit, which is a two-step flow and needs no orientation. This one
   can be three, and the third only appears for people who have never been here
   — exactly the audience that benefits from being told how much is left.
   Purely decorative, so the live region (#notice) carries the same fact for
   anyone who cannot see it. */
.auth-steps{display:flex;align-items:center;gap:6px;margin:0 0 18px;}
.auth-steps i{
  display:block;height:4px;flex:1;border-radius:999px;background:var(--s3);
  transition:background 200ms ease;
}
.auth-steps i[hidden]{display:none;}
.auth-steps i.on{background:var(--brand);}
.auth-steps i.done{background:var(--brand-l);}

/* ---- server-side messages ----
   The inline .hint carries per-field problems; this carries the ones that are
   about the request rather than a field — rate limits, a closed door, a
   gateway that would not send. */
.auth-alert{
  display:flex;gap:9px;align-items:flex-start;margin:0;padding:11px 13px;
  border-radius:var(--r-md);font-size:12px;font-weight:700;line-height:1.8;
}
.auth-alert svg{flex:none;margin-top:2px;}
.auth-alert[hidden]{display:none;}
/* The banner sits between the rail and the active form, both of which carry
   their own spacing; only the banner's own gap has to be added, and only when
   it is showing. Inside a form the flex gap already handles it. */
.auth-card > .auth-alert{margin-bottom:14px;}
.auth-alert.bad{background:var(--rose-bg);border:1px solid var(--rose-line);color:var(--rose);}
.auth-alert.ok{background:var(--mint-bg);border:1px solid var(--mint-line);color:var(--mint);}
.auth-alert.warn{background:var(--amber-bg);border:1px solid var(--amber-line);color:var(--amber);}

/* ---- otp boxes ---- */
.otp{display:grid;grid-template-columns:repeat(var(--otp-len),1fr);gap:8px;}
.otp input{
  width:100%;min-height:56px;text-align:center;border:1.5px solid #C9CDD6;border-radius:12px;
  background:var(--s1);font-family:inherit;font-size:20px;font-weight:800;color:var(--tx1);
  font-variant-numeric:tabular-nums;outline:none;
}
.otp input:focus{border-color:var(--brand);box-shadow:0 0 0 1px var(--brand);}
.otp input.filled{border-color:var(--brand-l);background:var(--brand-w);}
.otp.bad input{border-color:var(--rose);}
.auth-timer{font-size:12px;color:var(--tx3);font-weight:600;}
.auth-timer button{border:none;background:none;padding:0;font-family:inherit;font-size:12.5px;font-weight:700;color:var(--brand);cursor:pointer;}
.auth-timer button:hover{color:var(--brand-d);}

/* ---- profile step ----
   The one part of the flow the kit has no design for: it is a login-only page,
   and this product's registration needs a name and two consents. Built from
   the same .field/.input/.hint parts so the step does not announce itself as
   a later addition. */
.consent{
  display:flex;gap:10px;align-items:flex-start;
  padding:11px 12px;border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--s2);cursor:pointer;
  transition:border-color 160ms ease,background 160ms ease;
}
.consent:hover{border-color:var(--brand-l);background:var(--brand-w);}
.consent:focus-within{border-color:var(--brand);}
.consent input{
  flex:none;width:18px;height:18px;margin:1px 0 0;accent-color:var(--brand);cursor:pointer;
}
.consent span{font-size:11.5px;font-weight:600;color:var(--tx2);line-height:1.95;}
.consent b{color:var(--tx1);font-weight:800;}
.consent.bad{border-color:var(--rose-line);background:var(--rose-bg);}

/* The fraud warning. Long, legally load-bearing, and the thing a mule
   recruiter most wants the customer to skip — so it is amber and it is not
   collapsible. */
.auth-warn{
  margin:0;padding:12px 13px;border-radius:var(--r-md);
  background:var(--amber-bg);border:1px solid var(--amber-line);
  font-size:11.5px;font-weight:600;color:var(--amber);line-height:2;
}
.auth-warn b{font-weight:800;}

.auth-back{
  display:inline-flex;align-items:center;gap:6px;align-self:flex-start;
  border:none;background:none;padding:4px 0;margin:0;
  font-family:inherit;font-size:12.5px;font-weight:700;color:var(--tx3);cursor:pointer;
}
.auth-back:hover{color:var(--tx1);}
.auth-back svg{flex:none;}

/* Registration closed: the card keeps the logo and the support line, but the
   form is replaced rather than disabled — a form that cannot be submitted is
   a worse answer than no form. */
.auth-closed{display:flex;flex-direction:column;gap:14px;}

@media (max-width:420px){
  .auth-wrap{padding:24px 16px;}
  .auth-card{padding:22px 18px;border-radius:16px;}
  .otp input{min-height:50px;font-size:18px;}
}
/* 360px: the four boxes plus their gaps must still clear a 44px tap target. */
@media (max-width:360px){
  .otp{gap:6px;}
  .otp input{min-height:48px;font-size:17px;}
}

@media (prefers-reduced-motion:reduce){
  *{transition-duration:0ms!important;animation-duration:0ms!important;}
}
