/* ==========================================================================
   Toral Panel — Userside auth layer
   --------------------------------------------------------------------------
   Three things live here, and nothing else:

     1. .tp-authbg  — the default watercolour background of the sign-in page
                      (ToralPanel\Frontend\Userside\UI\AuthBackground)
     2. .tp-pub     — the ONE header a visitor without an account ever sees
                      (ToralPanel\Frontend\Userside\UI\PublicHeader)
     3. .tp-auth    — the sign-in / sign-up card
                      (ToralPanel\Frontend\Userside\Auth\LoginForm)

   Rules, identical to the rest of the Userside:
   - every colour, radius and shadow comes from a token in
     toral-userside-tokens.css — never a hard-coded colour here;
   - only CSS logical properties (inline-start / inline-end), so RTL needs no
     mirrored rules and no second stylesheet;
   - the form controls are the shared components from
     toral-userside-widgets.css (.tp-field / .tp-label / .tp-input /
     .tp-select / .tp-btn / .tp-alert), which is why this file declares that
     sheet as its dependency instead of restyling inputs.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Ground
   --------------------------------------------------------------------------
   The auth page and the guest view of a Userside page are ordinary scrolling
   documents, NOT the fixed 100vh application grid. toral-userside-chrome.css
   already paints `body.tp-us-body-auth`; `body.tp-us-body-public` is the guest
   view and is set up here.
   -------------------------------------------------------------------------- */
body.tp-us-body-public {
  margin: 0;
  min-height: 100vh;
  background: var(--tp-us-app-bg);
  color: var(--tp-us-text);
  font: 14px/1.65 var(--tp-us-font);
  -webkit-font-smoothing: antialiased;
}

body.tp-us-body-auth {
  min-height: 100vh;
}

/* --------------------------------------------------------------------------
   1. Watercolour background
   --------------------------------------------------------------------------
   Three soft colour washes with wave bands drifting across them.

   Performance is the design constraint here, because this layer sits behind a
   page people scroll and type in. So:

   - NO `filter: blur()`. A blurred element is re-rasterised whenever anything
     about it changes, and a full-viewport blurred layer made scrolling stutter
     on this page. A radial-gradient that fades to `transparent` already has a
     perfectly soft edge and costs one gradient fill.
   - NO `backdrop-filter` anywhere (see the card further down) and no
     `mix-blend-mode`: both force the browser to read back what is already on
     screen, every frame.
   - ONLY `transform` is animated. Transform-only animations run on the
     compositor, so the washes and the waves move without touching layout,
     paint, or the thread that handles scrolling and keystrokes.

   Colours default to the ACTIVE THEME's palette, which is what keeps the login
   page looking like the panel in all five themes. The admin can override each
   wash from Elementor's Page Settings; those values arrive as the
   --tp-authbg-1..3 variables on the wrapper, so the fallbacks below are the
   theme defaults.
   -------------------------------------------------------------------------- */
.tp-authbg {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--tp-us-app-bg);
  /* Nothing inside can affect anything outside, so the browser may skip this
     subtree entirely while the page scrolls. */
  contain: strict;
}

/* --- colour washes ------------------------------------------------------- */
.tp-authbg-wash {
  position: absolute;
  display: block;
  border-radius: 50%;
  opacity: .5;
  will-change: transform;
}

.tp-authbg-wash--1 {
  width: 78vmax;
  height: 78vmax;
  inset-inline-start: -24vmax;
  inset-block-start: -30vmax;
  background: radial-gradient(closest-side,
              var(--tp-authbg-1, var(--tp-us-b-600)) 0%,
              color-mix(in srgb, var(--tp-authbg-1, var(--tp-us-b-600)) 35%, transparent) 45%,
              transparent 72%);
  animation: tp-authbg-wash-1 14s ease-in-out infinite alternate;
}

.tp-authbg-wash--2 {
  width: 66vmax;
  height: 66vmax;
  inset-inline-end: -20vmax;
  inset-block-start: -6vmax;
  background: radial-gradient(closest-side,
              var(--tp-authbg-2, var(--tp-us-b-400)) 0%,
              color-mix(in srgb, var(--tp-authbg-2, var(--tp-us-b-400)) 35%, transparent) 45%,
              transparent 72%);
  animation: tp-authbg-wash-2 17s ease-in-out infinite alternate;
}

.tp-authbg-wash--3 {
  width: 84vmax;
  height: 84vmax;
  inset-inline-start: 12vmax;
  inset-block-end: -42vmax;
  opacity: .38;
  background: radial-gradient(closest-side,
              var(--tp-authbg-3, var(--tp-us-cyan)) 0%,
              color-mix(in srgb, var(--tp-authbg-3, var(--tp-us-cyan)) 30%, transparent) 45%,
              transparent 74%);
  animation: tp-authbg-wash-3 20s ease-in-out infinite alternate;
}

/* color-mix() is only used for the MIDDLE stop, so a browser without it still
   gets the same wash, just with a slightly harder falloff. */

@keyframes tp-authbg-wash-1 {
  from { transform: translate3d(-5vmax, -3vmax, 0) scale(1); }
  to   { transform: translate3d(7vmax, 5vmax, 0) scale(1.16); }
}
@keyframes tp-authbg-wash-2 {
  from { transform: translate3d(4vmax, 2vmax, 0) scale(1.14); }
  to   { transform: translate3d(-6vmax, 7vmax, 0) scale(1); }
}
@keyframes tp-authbg-wash-3 {
  from { transform: translate3d(-4vmax, 3vmax, 0) scale(1.1); }
  to   { transform: translate3d(6vmax, -4vmax, 0) scale(1); }
}

/* --- wave bands ---------------------------------------------------------- */
/*
   Each <svg> is twice the width of the viewport and holds a path that repeats
   every 1440 user units. Sliding the svg by exactly -50% of its own width puts
   the second half of the path where the first half was, so the loop closes on
   itself and needs no fade, no reset and no second keyframe.
*/
.tp-authbg-wave,
.tp-authbg-line {
  position: absolute;
  /* Physical `left`, not inset-inline-start: the band is 200% wide and slides
     left by half of itself. In RTL a logical start would anchor it to the
     right edge, so it would slide away and leave the screen empty. */
  left: 0;
  inset-block-end: 0;
  width: 200%;
  display: block;
  will-change: transform;
}

.tp-authbg-wave { height: 44vh; min-height: 260px; }
.tp-authbg-line { height: 58vh; min-height: 320px; }

.tp-authbg-wave path { fill: currentColor; }

.tp-authbg-wave--1 {
  color: var(--tp-authbg-1, var(--tp-us-b-600));
  opacity: .16;
  animation: tp-authbg-slide 15s linear infinite;
}
.tp-authbg-wave--2 {
  color: var(--tp-authbg-2, var(--tp-us-b-400));
  opacity: .2;
  animation: tp-authbg-slide 22s linear infinite reverse;
}
.tp-authbg-wave--3 {
  color: var(--tp-authbg-3, var(--tp-us-cyan));
  opacity: .14;
  animation: tp-authbg-slide 30s linear infinite;
}

.tp-authbg-line path {
  stroke: currentColor;
  stroke-width: 2.5;
  /* preserveAspectRatio="none" stretches the x axis, and a stretched stroke
     would go lumpy; this keeps the line an even thickness. */
  vector-effect: non-scaling-stroke;
}

.tp-authbg-line--1 {
  color: var(--tp-authbg-2, var(--tp-us-b-400));
  opacity: .3;
  animation: tp-authbg-slide 18s linear infinite reverse;
}
.tp-authbg-line--2 {
  color: var(--tp-authbg-1, var(--tp-us-b-600));
  opacity: .22;
  animation: tp-authbg-slide 26s linear infinite;
}

@keyframes tp-authbg-slide {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* Motion is decoration. Anyone who asked their system for less of it gets the
   same picture, standing still. */
@media (prefers-reduced-motion: reduce) {
  .tp-authbg-wash,
  .tp-authbg-wave,
  .tp-authbg-line { animation: none !important; }
}

/* A phone has the least GPU and the most to lose from a busy background: the
   washes stay (they are one gradient fill each) and the moving bands go. */
@media (max-width: 600px) {
  .tp-authbg-wave--3,
  .tp-authbg-line--2 { display: none; }
}
/* --------------------------------------------------------------------------
   2. Public header
   -------------------------------------------------------------------------- */
.tp-pub {
  position: relative;
  z-index: 2;
  background: var(--tp-us-chrome-bg);
  color: var(--tp-us-chrome-text);
  box-shadow: var(--tp-us-shadow);
}

.tp-pub-inner {
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: 1280px;
  min-height: var(--tp-us-chrome-h);
  margin: 0 auto;
  padding: 0 18px;
}

/* --- logo ---------------------------------------------------------------- */
.tp-pub-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
  flex: none;
}
.tp-pub-brand:hover { text-decoration: none; }

.tp-pub-logo {
  display: block;
  max-height: 42px;
  width: auto;
  /* The logo is the admin's own picture: no frame, no plate, nothing added. */
  border: 0;
  background: none;
}

.tp-pub-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--tp-us-radius-md);
  background: var(--tp-us-accent);
  color: var(--tp-us-on-accent);
  font-weight: 800;
  font-size: 17px;
}
.tp-pub-brandtext { font-weight: 700; font-size: 16px; }

/* --- nav ----------------------------------------------------------------- */
.tp-pub-nav {
  display: flex;
  align-items: center;
  gap: 18px;
  flex: 1 1 auto;
  min-width: 0;
}

.tp-pub-links {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.tp-pub-links::-webkit-scrollbar { display: none; }

.tp-pub-link {
  padding: 8px 12px;
  border-radius: var(--tp-us-radius-md);
  color: inherit;
  font-weight: 600;
  font-size: 13.5px;
  white-space: nowrap;
  text-decoration: none;
  transition: background var(--tp-us-transition);
}
.tp-pub-link:hover {
  background: var(--tp-us-chrome-hover);
  color: inherit;
  text-decoration: none;
}

.tp-pub-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}

/* The two buttons are the shared .tp-btn components; only the ghost variant
   needs adjusting, because here it sits on the dark chrome bar rather than on
   a content surface.
   It is re-coloured through the ghost button's own variables, not with a
   competing `color` rule: the base rule in toral-userside-widgets.css sets
   the label with !important (its armour against a theme repainting links),
   which no normal declaration here could ever win. That is why "Sign in"
   kept coming back dark-on-dark. */
.tp-pub-actions {
  --tp-us-btn-ghost-bg:    transparent;
  --tp-us-btn-ghost-text:  var(--tp-us-chrome-text);
  --tp-us-btn-ghost-line:  var(--tp-us-chrome-line);
  --tp-us-btn-ghost-hover: var(--tp-us-chrome-hover);
}
.tp-pub-actions .tp-btn { min-height: 36px; }

/* --- language ------------------------------------------------------------ */
.tp-pub-lang { position: relative; }

.tp-pub-langbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--tp-us-radius-md);
  background: transparent;
  color: var(--tp-us-chrome-text);
  cursor: pointer;
  transition: background var(--tp-us-transition);
}
.tp-pub-langbtn:hover { background: var(--tp-us-chrome-hover); }

/* The dropdown reuses the chrome's .tp-us-menu-panel markup, but the chrome
   stylesheet positions that panel inside the fixed app grid, so the placement
   is restated for this bar. */
.tp-pub-lang .tp-us-menu-panel {
  position: absolute;
  inset-block-start: calc(100% + 6px);
  inset-inline-end: 0;
  z-index: 30;
  min-width: 190px;
  padding: 6px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-lg);
  background: var(--tp-us-surface);
  color: var(--tp-us-text);
  box-shadow: var(--tp-us-shadow-lg);
}

/* --- small screens ------------------------------------------------------- */
.tp-pub-burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 38px;
  margin-inline-start: auto;
  padding: 0;
  border: 0;
  border-radius: var(--tp-us-radius-md);
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.tp-pub-burger:hover { background: var(--tp-us-chrome-hover); }

@media (max-width: 860px) {
  .tp-pub-inner { flex-wrap: wrap; padding-block: 10px; }
  .tp-pub-burger { display: inline-flex; }

  .tp-pub-nav {
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding-block-end: 6px;
  }
  .tp-pub-nav[hidden] { display: none; }

  .tp-pub-links { flex-direction: column; align-items: stretch; overflow: visible; }
  .tp-pub-link  { padding: 10px 12px; }

  .tp-pub-actions { justify-content: flex-start; }
  .tp-pub-actions .tp-btn { flex: 1 1 auto; }
}

/* --------------------------------------------------------------------------
   3. The auth page body
   -------------------------------------------------------------------------- */
.tp-auth-page {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(18px, 5vh, 56px) 18px 48px;
}

.tp-auth-page-main { width: 100%; }

/* --------------------------------------------------------------------------
   4. The card
   --------------------------------------------------------------------------
   Roughly the proportions of the panel-admin sign-in box, one step wider
   because this card carries more: two tabs, the 2FA field, the captcha and
   seven sign-up fields.
   -------------------------------------------------------------------------- */
.tp-auth {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 452px;
  margin-inline: auto;
}

/* --- logo above the card ------------------------------------------------- */
.tp-auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  margin-block-end: 20px;
  color: var(--tp-us-text);
}

.tp-auth-logo {
  display: block;
  max-width: 220px;
  max-height: 76px;
  width: auto;
  height: auto;
  /* Explicitly nothing: the request was a bare logo, no border and no plate. */
  border: 0;
  background: none;
  box-shadow: none;
}

.tp-auth-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: var(--tp-us-radius-md);
  background: var(--tp-us-accent);
  color: var(--tp-us-on-accent);
  font-weight: 800;
  font-size: 21px;
}
.tp-auth-wordmark { font-weight: 700; font-size: 19px; }

/* --- the surface --------------------------------------------------------- */
.tp-auth-card {
  padding: 22px;
  border: 1px solid var(--tp-us-border);
  border-radius: var(--tp-us-radius-xl);
  /*
   * Solid, on purpose.
   *
   * This used to be a translucent surface with `backdrop-filter: blur(10px)`.
   * A backdrop filter makes the browser re-read and re-blur everything behind
   * the element on every frame — and the sign-up tab is a long card people
   * scroll and type in, so that cost was paid on every scroll tick and every
   * keystroke. That was the cause of the sluggish feel; the frosted look is
   * not worth it. The wash is still visible all around the card.
   */
  background: var(--tp-us-surface);
  box-shadow: var(--tp-us-shadow-lg);
}

.tp-auth-title {
  margin: 0 0 14px;
  font-size: 18px;
  font-weight: 700;
  color: var(--tp-us-text);
}

.tp-auth-intro {
  margin: 0 0 16px;
  color: var(--tp-us-text-soft);
  font-size: 13px;
}

/* --- tabs ---------------------------------------------------------------- */
.tp-auth-tabs {
  display: flex;
  gap: 4px;
  margin-block-end: 20px;
  padding: 4px;
  border-radius: var(--tp-us-radius-pill);
  background: var(--tp-us-surface-3);
}

/* `display: flex` above beats the browser's default for [hidden], so the tab
   strip needs this to actually disappear during the verification step. */
.tp-auth-tabs[hidden] { display: none; }

.tp-auth-tab {
  flex: 1 1 0;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--tp-us-radius-pill);
  background: transparent;
  color: var(--tp-us-text-soft);
  font-family: inherit;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
  transition: background var(--tp-us-transition), color var(--tp-us-transition);
}
.tp-auth-tab:hover { color: var(--tp-us-text); }

.tp-auth-tab.is-active {
  background: var(--tp-us-accent);
  color: var(--tp-us-on-accent);
  box-shadow: var(--tp-us-shadow-sm);
}

/* --- the forms ----------------------------------------------------------- */
.tp-auth-form[hidden] { display: none; }

.tp-auth-card .tp-field { margin-block-end: 13px; }

.tp-auth-forgot { margin: -6px 0 12px; text-align: end; }

.tp-auth-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--tp-us-accent);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.tp-auth-link:hover { text-decoration: underline; }

.tp-auth-check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-block-end: 13px;
  color: var(--tp-us-text-soft);
  font-size: 13px;
  cursor: pointer;
}
.tp-auth-check input { margin: 0; accent-color: var(--tp-us-accent); }

/* --- password reveal ----------------------------------------------------- */
.tp-auth-pass { position: relative; display: block; }

.tp-auth-pass .tp-input { padding-inline-end: 42px; }

.tp-auth-eye {
  position: absolute;
  inset-inline-end: 6px;
  inset-block-start: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: var(--tp-us-radius-sm);
  background: transparent;
  color: var(--tp-us-text-dim);
  cursor: pointer;
}
.tp-auth-eye:hover { background: var(--tp-us-surface-3); color: var(--tp-us-text); }

/* The eye itself, so the button needs no inline SVG and no icon font. */
.tp-auth-eye::before {
  content: "";
  display: block;
  width: 18px;
  height: 18px;
  margin: 0 auto;
  background: currentColor;
  -webkit-mask: var(--tp-auth-eye-mask) center / 18px 18px no-repeat;
  mask: var(--tp-auth-eye-mask) center / 18px 18px no-repeat;
}

.tp-auth-eye {
  --tp-auth-eye-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7Z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
}

.tp-auth-eye.is-on {
  --tp-auth-eye-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 3l18 18'/%3E%3Cpath d='M10.6 5.2A9.8 9.8 0 0 1 12 5c6.4 0 10 7 10 7a18 18 0 0 1-2.4 3.4'/%3E%3Cpath d='M6.2 6.6A18 18 0 0 0 2 12s3.6 7 10 7a9.6 9.6 0 0 0 3.6-.7'/%3E%3C/svg%3E");
}

/* --- captcha ------------------------------------------------------------- */
.tp-auth-captcha {
  display: flex;
  justify-content: center;
  margin-block-end: 14px;
  /* No border and no scrollbar: the widget is centred in the card. */
  overflow: visible;
  border: 0;
}
@media (max-width: 400px) {
  .tp-auth-captcha { transform: scale(.88); transform-origin: center top; }
}

/* --- submit + footer ----------------------------------------------------- */
.tp-auth-card .tp-auth-submit {
  width: 100%;
  min-height: 44px;
  margin-block-start: 4px;
  font-size: 14px;
}
.tp-auth-card .tp-auth-submit[disabled] { opacity: .6; cursor: default; transform: none; }

.tp-auth-foot {
  margin: 16px 0 0;
  color: var(--tp-us-text-soft);
  font-size: 12.5px;
  text-align: center;
}

.tp-auth-msg { margin-block-end: 14px; }
.tp-auth-msg[hidden] { display: none; }

/* Result of the verification link from the e-mail, when it lands on the card. */
.tp-auth-notice { margin-block-end: 14px; }

/*
 * The 6-digit code.
 *
 * Wide tracking and a centred, tabular figure set: a verification code is read
 * one character at a time, and it is usually retyped from another screen.
 */
.tp-auth-code {
  text-align: center;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: .5em;
  /* The tracking is applied after each glyph, including the last one, which
     pushes the whole string off-centre without this. */
  text-indent: .5em;
  font-variant-numeric: tabular-nums;
}

/* Note shown in place of the card inside the Elementor editor. */
.tp-auth-editor-note { max-width: 452px; margin-inline: auto; text-align: center; }

@media (max-width: 480px) {
  .tp-auth-card { padding: 18px 15px; }
  .tp-auth-logo { max-height: 62px; }
}

/* --------------------------------------------------------------------------
   5. Guest view of a Userside page (the services catalogue)
   --------------------------------------------------------------------------
   Printed by UI\Shell::open_guest() instead of the panel chrome.
   -------------------------------------------------------------------------- */
.tp-us-public {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.tp-us-public-content {
  flex: 1 1 auto;
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 18px;
}

/* The "create an account to order" strip above the catalogue. */
.tp-services-guest {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-block-end: 14px;
}

.tp-services-guest-text {
  margin: 0;
  color: var(--tp-us-text-soft);
  font-size: 13.5px;
}

/* A link-style button waiting for its resend timer (verify step). */
.tp-auth-link[disabled] {
  opacity: .75;
  cursor: default;
  text-decoration: none;
}
