/* =============================================================================
   FILE: assets/css/signup.css
   PROJECT: Smart Bookmark
   PURPOSE: Sign-up page additions on top of the shared component styles.

   This file is loaded AFTER login.css, which already provides:
     - Split-screen layout (.page, .panel-left, .panel-right)
     - Card, card-header, card-footer, card-builder-credit
     - Form, field, field-label, input-wrap, input-icon, btn-toggle
     - Field error states (.input-wrap.error, .field-error)
     - Alert banner (.alert)
     - Submit button (.btn-primary, .spinner)
     - Animations (slideUp, fadeIn, spin)
     - Responsive breakpoints

   ONLY sign-up-specific additions live here:
     1. Card width override   – wider card for the extra fields
     2. Password strength meter
     3. Terms & Conditions row
     4. Success screen
     5. Responsive overrides specific to the wider card

   DEPENDS ON: assets/css/base.css, assets/css/login.css
   USED BY:    signup.html
============================================================================= */


/* =============================================================================
   1. CARD WIDTH OVERRIDE + CARD HEADER VISIBILITY
   The signup card has 4 fields + a checkbox, so we give it a little more
   breathing room than the login card (420px → 460px).

   login.css sets opacity:0 on .card-eyebrow/.card-title/.card-subtitle so
   that login-gsap.js can animate them in. signup.html does not load
   login-gsap.js, so we restore visibility here.
============================================================================= */

/* Pin the page grid to exactly the viewport height.
   login.css uses min-height:100vh which allows the page div to grow taller
   than the screen, causing body scroll. Overriding with height:100vh and
   min-height:0 locks the container to the viewport so nothing can escape. */
.page {
  height: 100vh;
  min-height: 0;
}

/* Prevent the body from ever showing a scrollbar on this page.
   Everything that needs to scroll does so internally (panel-right / card). */
body {
  overflow: hidden;
}

/* Right panel: fill the grid row, centred, no scrollbars.
   The form is compact enough to fit — nothing needs to clip or scroll.
   Gradient mesh + breathing orb ::before are inherited from login.css. */
.panel-right {
  height: 100%;
  overflow: visible;
  padding: 16px 32px;
}

.card {
  max-width: 460px;
  overflow-y: visible;
  padding: 20px 36px;
  /* position, z-index, will-change inherited from login.css */
}

/* Compact the card header */
.card-header {
  margin-bottom: 12px;
}

/* Tighten the gap between form fields */
.form {
  gap: 6px;
}

/* Shrink input height */
.input-wrap input {
  height: 38px;
}

/* Reduce submit button height */
.btn-primary {
  height: 40px;
  margin-top: 2px;
}

/* Reduce terms row padding */
.terms-row {
  padding: 6px 10px;
}

/* Reduce card footer spacing */
.card-footer {
  margin-top: 8px;
}

/* Reduce builder credit spacing */
.card-builder-credit {
  margin-top: 8px;
  padding-top: 8px;
}

/* Compact card title size */
.card-title {
  font-size: 1.5rem;
}

.card-eyebrow,
.card-title,
.card-subtitle {
  opacity: 1;
}


/* =============================================================================
   2. NO-SHIFT VALIDATION MESSAGES
   Override login.css's max-height:0 animation (which causes layout shift)
   with a visibility + opacity approach that reserves space at all times.

   Space is always held → messages appear in-place → zero layout shift.
   Only applies on the signup page; login.css behaviour is unchanged.
============================================================================= */

/* Always occupy height; invisible when not triggered */
.field-error {
  max-height: none;           /* Override login.css max-height:0 */
  min-height: 18px;           /* Reserve a fixed slot for one error line */
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.18s ease, visibility 0s linear 0.18s;
}

.field-error.visible {
  max-height: none;
  visibility: visible;
  opacity: 1;
  transition: opacity 0.18s ease, visibility 0s linear 0s;
}

/* Email availability hint — same reserved-space treatment */
.field-hint {
  min-height: 18px;
  font-size: 0.75rem;
  font-weight: 500;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.18s ease, visibility 0s linear 0.18s;
}

.field-hint:not(:empty) {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.18s ease, visibility 0s linear 0s;
}

/* ── Password strength meter — reserve space from the start ────────────── */

/* Always take up layout space; invisible until user types */
.strength-bar {
  display: flex;              /* Override login.css/signup.css display:none */
  visibility: hidden;
  gap: 5px;
  margin-top: 4px;
}

.strength-bar.visible {
  visibility: visible;
}

.strength-label {
  display: block;             /* Override display:none — use visibility instead */
  visibility: hidden;
  min-height: 14px;
  margin-top: 2px;
}

.strength-label.visible {
  visibility: visible;
}

/* ── Collapse the gap login.css's .field gap:6px adds between error rows ── */
/* With reserved space we no longer need the animated gap — keep it tidy */
.field {
  gap: 0;
}

/* Restore sensible spacing between label and input */
.field-label {
  margin-bottom: 5px;
}

/* Space between input and the reserved error/hint row */
.input-wrap {
  margin-bottom: 2px;
}


/* =============================================================================
   3. PASSWORD STRENGTH METER (colours — unchanged)
============================================================================= */

.strength-segment {
  flex: 1;
  height: 3px;
  border-radius: 99px;
  background: var(--clr-brand-200);
  transition: background 0.3s ease;
}

.strength-segment.filled-weak   { background: #ef4444; }
.strength-segment.filled-fair   { background: #f59e0b; }
.strength-segment.filled-good   { background: #3b82f6; }
.strength-segment.filled-strong { background: #22c55e; }

.strength-label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.strength-label.weak   { color: #ef4444; }
.strength-label.fair   { color: #f59e0b; }
.strength-label.good   { color: #3b82f6; }
.strength-label.strong { color: #22c55e; }


/* =============================================================================
   3. TERMS & CONDITIONS ROW
   Wraps the checkbox + label. Inline links inside the label are styled
   with an underline so they read as clickable even inside the grey label text.
============================================================================= */

/* Outer row wrapper – used for error-state border when not accepted */
.terms-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border: 1.5px solid var(--clr-brand-200);
  border-radius: var(--radius-md);
  background: var(--clr-brand-50);
  transition: border-color var(--transition), background var(--transition);
}

/* Error state – applied by JS when the checkbox is unchecked on submit */
.terms-row.error {
  border-color: var(--clr-error);
  background: var(--clr-error-bg);
}

/* Allow the label text to wrap (it contains two links) */
.terms-row .cb-wrap {
  align-items: flex-start;
}

.terms-row .cb-wrap input[type="checkbox"] {
  margin-top: 2px;            /* Optical alignment with first line of text */
  flex-shrink: 0;
}

/* .cb-label is inherited from login.css; links inside it get underlines */
.terms-row .cb-label {
  line-height: 1.5;
  color: var(--clr-brand-600);
}

.terms-row .cb-label a {
  color: var(--clr-indigo-500);
  text-decoration: underline;
  text-decoration-color: rgba(99, 102, 241, 0.35);
  text-underline-offset: 2px;
  font-weight: 600;
  transition: color var(--transition), text-decoration-color var(--transition);
}

.terms-row .cb-label a:hover {
  color: var(--clr-indigo-600);
  text-decoration-color: var(--clr-indigo-600);
}


/* =============================================================================
   4. SUCCESS SCREEN — in-card transition

   TECHNIQUE:
     #signupCard  — position:relative stacking context.
     #formView    — normal flow (its height drives the card height throughout).
                    On success: fades out (opacity→0, slight upward translate).
                    Becomes visibility:hidden so it remains in the layout flow
                    and the card does NOT collapse.
     .success-view — position:absolute inset:0 overlay, starts opacity:0 /
                    visibility:hidden.  On success: fades in over 350 ms.
                    Flex-centred so the content sits in the middle of the
                    space the form naturally occupied.

   ANIMATION TIMING (all motion complete by ≈ 4.4 s):
     t=0    .signup-card--success added by JS
     t=0    form begins fading out (250 ms)
     t=200  success view begins fading in (350 ms) → fully visible at 550 ms
     t=600  bookmark icon settles in (750 ms)       → done 1350 ms
     t=600  bookmark stroke draws on (1100 ms)      → done 1700 ms
     t=1750 amber fill fades in (550 ms)            → done 2300 ms
     t=2000 "+" symbol fades in (450 ms)            → done 2450 ms
     t=2100 heading fades up (550 ms)               → done 2650 ms
     t=2600 subtitle fades in (500 ms)              → done 3100 ms
     t=3000 divider fades in (450 ms)               → done 3450 ms
     t=3800 CTA button fades up (600 ms)            → fully visible 4400 ms ✓
============================================================================= */

/* --------------------------------------------------------------------------
   4a. UTILITY – kept for any other show/hide needs in the page
-------------------------------------------------------------------------- */
.hidden {
  display: none !important;
}


/* --------------------------------------------------------------------------
   4b. CARD STACKING CONTEXT
-------------------------------------------------------------------------- */

/* Makes the card a containing block for the absolutely-positioned success view */
#signupCard {
  position: relative;
}


/* --------------------------------------------------------------------------
   4c. FORM VIEW — drives card height, fades out on success
-------------------------------------------------------------------------- */

#formView {
  transition: opacity 250ms ease, transform 250ms ease;
}

.signup-card--success #formView {
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  /* visibility:hidden fires after opacity animation so the card keeps height */
  visibility: hidden;
  transition: opacity 250ms ease, transform 250ms ease, visibility 0s linear 250ms;
}


/* --------------------------------------------------------------------------
   4d. SUCCESS VIEW — absolute overlay, fades in after the form fades out
-------------------------------------------------------------------------- */

.success-view {
  position: absolute;
  inset: 0;
  /* Flex-centre so content sits in the middle of the card space */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px 28px;
  /* Hidden by default — no animation before state is triggered */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  /* 200ms start delay lets the form begin fading first */
  transition: opacity 350ms ease 200ms, visibility 0s linear 550ms;
}

.signup-card--success .success-view {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 350ms ease 200ms, visibility 0s linear 0s;
}


/* --------------------------------------------------------------------------
   4e. BOOKMARK ICON
   Scale-in from 0.92 → 1; animations only start under .signup-card--success
   so they never run on page load.
-------------------------------------------------------------------------- */

.sv-icon {
  width: 72px;
  height: 72px;
  margin-bottom: 22px;
  /* fill-mode:both holds opacity:0 during the delay — no flash */
  opacity: 0;
}

.sv-icon svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 3px 12px rgba(245, 158, 11, 0.28));
}

.signup-card--success .sv-icon {
  animation: sv-icon-settle 0.75s ease-out 0.6s both;
}


/* --------------------------------------------------------------------------
   4f. SVG BOOKMARK LAYERS
   Three distinct layers painted back-to-front:
     sv-bm-fill  amber gradient fill (fades in once stroke is visible)
     sv-bm-body  stroke outline draws on via dashoffset 72 → 0
     sv-bm-plus  "+" symbol fades in — communicates creation, not closure
-------------------------------------------------------------------------- */

/* Layer 1 – fill: pre-positioned but invisible until stroke defines the shape */
.sv-bm-fill {
  opacity: 0;
}
.signup-card--success .sv-bm-fill {
  animation: sv-fade-in 0.55s ease-out 1.75s both;
}

/* Layer 2 – stroke draw-on (dashoffset 72 → 0) */
.sv-bm-body {
  stroke-dasharray: 72;
  stroke-dashoffset: 72;
}
.signup-card--success .sv-bm-body {
  animation: sv-draw 1.1s ease-in-out 0.6s forwards;
}

/* Layer 3 – "+" symbol: simple fade so both strokes appear together */
.sv-bm-plus {
  opacity: 0;
}
.signup-card--success .sv-bm-plus {
  animation: sv-fade-in 0.45s ease-out 2.0s both;
}


/* --------------------------------------------------------------------------
   4g. TEXT BLOCK
-------------------------------------------------------------------------- */

.sv-text {
  margin-bottom: 18px;
}

.sv-heading {
  font-size: clamp(1.1rem, 2.5vw, 1.35rem);
  font-weight: 700;
  color: var(--clr-brand-900);
  letter-spacing: -0.02em;
  margin: 0 0 6px;
  opacity: 0;
}
.signup-card--success .sv-heading {
  animation: sv-fade-up 0.55s ease-out 2.1s both;
}

.sv-sub {
  font-size: 0.875rem;
  line-height: 1.65;
  color: var(--clr-brand-500);
  margin: 0;
  opacity: 0;
}
.signup-card--success .sv-sub {
  animation: sv-fade-in 0.5s ease-out 2.6s both;
}


/* --------------------------------------------------------------------------
   4h. DIVIDER
-------------------------------------------------------------------------- */

.sv-divider {
  width: 72px;
  height: 1px;
  background: var(--clr-brand-200);
  margin-bottom: 20px;
  opacity: 0;
}
.signup-card--success .sv-divider {
  animation: sv-fade-in 0.45s ease-out 3.0s both;
}


/* --------------------------------------------------------------------------
   4i. CTA BUTTON
   NOTE: NO static opacity:0 here — the button is hidden by its parent
   .success-view (visibility:hidden / opacity:0) before the state fires.
   Setting opacity:0 statically would cause .btn-primary's `transition:opacity`
   to kick in on hover and snap the button invisible.
   The animation's fill-mode:both handles the pre-delay invisible state.

   HOVER / BTN-GLOW-PULSE INTERACTION:
   animations.css has `.btn-primary:hover { animation: btn-glow-pulse }` which
   replaces `sv-fade-up` in the animation list the moment the cursor enters the
   button. When the cursor then leaves the button, `sv-fade-up` is re-added to
   the list — but because it's a "new" animation, it restarts from its
   fill-mode:backwards state (opacity:0), hiding the button for the full 3.8s
   delay again.

   Fix: our higher-specificity :hover rule below keeps `sv-fade-up` at
   position 1 in both hover and non-hover states.  CSS spec says an animation
   at the same list position with the same parameters continues uninterrupted
   — so sv-fade-up never loses its fill-mode:forwards (opacity:1) hold.
   btn-glow-pulse is added at position 2 on hover and removed on leave;
   sv-fade-up at position 1 is untouched.

   JS belt-and-suspenders: showSuccessScreen() sets inline opacity:1 after
   the animation finishes, making the button permanently animation-independent.
-------------------------------------------------------------------------- */

.sv-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  /* Remove opacity from transition — animation owns opacity; we don't want
     btn-primary's `transition:opacity` to ever animate it away */
  transition: transform var(--transition), box-shadow var(--transition);
}
.signup-card--success .sv-btn {
  animation: sv-fade-up 0.6s ease-out 3.8s both;
}
/* Keep sv-fade-up at position 1 on hover so it never restarts */
.signup-card--success .sv-btn:hover:not(:disabled) {
  animation: sv-fade-up 0.6s ease-out 3.8s both,
             btn-glow-pulse 1.8s ease-in-out infinite;
}


/* --------------------------------------------------------------------------
   4j. KEYFRAMES
-------------------------------------------------------------------------- */

@keyframes sv-fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0);   }
}

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

@keyframes sv-icon-settle {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1);    }
}

@keyframes sv-draw {
  to { stroke-dashoffset: 0; }
}


/* --------------------------------------------------------------------------
   4k. REDUCED MOTION  (WCAG 2.1 Level AA)
   Collapses all transitions/animations to instantaneous so everything
   appears at once with no motion.
-------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  #formView,
  .success-view {
    transition-duration: 0.01ms !important;
    transition-delay:    0ms    !important;
  }

  /* Stroke path must show in final (fully drawn) state */
  .sv-bm-body {
    stroke-dashoffset: 0 !important;
    animation: none   !important;
  }

  .signup-card--success .sv-icon,
  .signup-card--success .sv-bm-fill,
  .signup-card--success .sv-bm-plus,
  .signup-card--success .sv-heading,
  .signup-card--success .sv-sub,
  .signup-card--success .sv-divider,
  .signup-card--success .sv-btn {
    animation-duration: 0.01ms !important;
    animation-delay:    0ms    !important;
  }
}


/* =============================================================================
   4b. EMAIL AVAILABILITY HINT
   Small inline hint rendered below the email field while the debounced
   check is in flight and after it resolves.
   JS adds/removes .visible and a state modifier class.
============================================================================= */
.field-hint {
  display: none;
  align-items: center;
  gap: 5px;
  font-size: 0.775rem;
  font-weight: 500;
  margin-top: 5px;
  min-height: 16px;            /* Prevent layout jump when it appears */
  transition: opacity 0.2s ease;
}

.field-hint.visible             { display: flex; }
.field-hint--checking           { color: var(--clr-brand-500, #64748b); }
.field-hint--available          { color: #16a34a; } /* green-600 */
.field-hint--taken              { color: #dc2626; } /* red-600   */


/* =============================================================================
   5. RESPONSIVE OVERRIDES
   Inherits all breakpoints from login.css. Only tweaks specific to the
   wider signup card are added here.
============================================================================= */
@media (max-width: 520px) {
  /* On mobile the left panel is already hidden (login.css ≤900px rule).
     The page reverts to a single-column scrollable layout, so unlock
     the viewport-height constraints we added for desktop. */
  body {
    overflow: auto;
  }

  .page {
    height: auto;
    min-height: 100vh;
  }

  .panel-right {
    height: auto;
    overflow-y: visible;
    padding: 24px 16px;
  }

  .card {
    max-width: 100%;
    max-height: none;
    overflow-y: visible;
    padding: 24px 20px;
  }
}


/* =============================================================================
   5. OTP VERIFICATION STEP
   Inline replacement of the form when "Create Account" passes validation.
   Uses the same absolute-overlay technique as the success screen.
   The .signup-card--otp class on #signupCard drives all transitions.
   Digit boxes reuse the .st-verify-digit class (styled below).
============================================================================= */

/* Overlay container — same positioning as .success-view */
.otp-view {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 36px 32px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.28s ease, visibility 0.28s ease;
}

/* When the card is in OTP state: fade form out, fade OTP view in */
.signup-card--otp #formView {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.22s ease, visibility 0.22s ease;
}

.signup-card--otp .otp-view {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.28s ease 0.15s, visibility 0.28s ease 0.15s;
}

/* Envelope icon badge */
.otp-icon {
  width: 52px;
  height: 52px;
  border-radius: 16px;
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.10), rgba(129, 140, 248, 0.18));
  border: 1.5px solid rgba(99, 102, 241, 0.22);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
  color: var(--clr-indigo-500);
  flex-shrink: 0;
}

.otp-icon svg {
  width: 24px;
  height: 24px;
}

/* Heading block */
.otp-header {
  text-align: center;
  margin-bottom: 24px;
}

.otp-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--clr-brand-900);
  margin: 0 0 8px;
  letter-spacing: -0.025em;
}

.otp-subtitle {
  font-size: 0.875rem;
  color: var(--clr-brand-600);
  line-height: 1.55;
  margin: 0;
}

.otp-subtitle strong {
  color: var(--clr-brand-900);
  font-weight: 600;
}

/* Digit box row */
.otp-digits {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-bottom: 14px;
}

/* Individual digit box — mirrors settings.css .st-verify-digit but using
   the tokens available in base.css (no --db-* variables on this page). */
.st-verify-digit {
  width: 44px;
  height: 52px;
  padding: 0;
  background: var(--clr-brand-50);
  border: 1.5px solid var(--clr-brand-200);
  border-radius: 10px;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--clr-brand-900);
  font-family: 'Courier New', Courier, monospace;
  text-align: center;
  transition: border-color 0.15s, box-shadow 0.15s;
  outline: none;
  box-sizing: border-box;
  caret-color: transparent;
}

.st-verify-digit:focus {
  border-color: var(--clr-indigo-500);
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.18);
}

.st-verify-digit--error {
  border-color: #f43f5e !important;
  box-shadow: 0 0 0 3px rgba(244, 63, 94, 0.12) !important;
}

/* Error message below the digit row */
.otp-error {
  font-size: 0.8125rem;
  color: #f43f5e;
  text-align: center;
  margin: 0 0 12px;
  min-height: 1.15em;
}

.otp-error[hidden] { display: none; }

/* Footer row: back button + verify button */
.otp-footer {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-top: 8px;
}

/* Ghost back button */
.btn-back {
  flex-shrink: 0;
  background: none;
  border: 1.5px solid var(--clr-brand-200);
  border-radius: var(--radius-md);
  padding: 0 16px;
  height: 44px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--clr-brand-600);
  cursor: pointer;
  transition: border-color var(--transition), color var(--transition),
              background var(--transition);
  white-space: nowrap;
}

.btn-back:hover {
  border-color: var(--clr-indigo-400);
  color: var(--clr-indigo-500);
  background: rgba(99, 102, 241, 0.05);
}

/* Primary verify button fills the rest of the row */
.otp-footer .btn-primary {
  flex: 1;
}
