﻿/* ==================================================
   NumInputX – core input behavior
   ================================================== */

:root {
  --numx-spinner-width: 30px;
  --numx-voice-width: 42px;
  --numx-reserve-space-spinner: calc( var(--numx-spinner-width) + 4px );
  --numx-reserve-space-tools: calc( var(--numx-spinner-width) + var(--numx-voice-width) + 6px );
}

.numx {
  appearance: textfield;
  -webkit-appearance: none;
  -moz-appearance: textfield;
  width: 100%;
  flex: 1 1 auto;
  padding-right: var(--numx-reserve-space-spinner);
}

  /* Hide native number spinners */
  .numx::-webkit-inner-spin-button,
  .numx::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }

.numx-wrap .numx-disabled {
  pointer-events: none;
  opacity: .45;
}

/* Floating mode */
.form-floating.numx-float {
  position: relative;
  width: 100%;
}

  /* ================================
   Floating mode (authoritative)
   ================================ */

  .form-floating.numx-float:focus-within .numx-spin,
  .form-floating.numx-float > .form-control:hover ~ .numx-spin,
  .form-floating.numx-float .numx-spin:hover {
    opacity: 1;
  }

.form-floating > label {
  pointer-events: none;
}

/* ================================
   Non-floating wrapper (RESTORED 102)
   ================================ */

.numx-wrap {
  position: relative;
  display: inline-flex; /* ★ height contract */
  align-items: stretch;
  width: 100%;
}

  .numx-wrap:hover .numx-spin:not(.numx-disabled),
  .numx-wrap:focus-within .numx-spin:not(.numx-disabled) {
    opacity: 1;
  }

/* ==================================================
   Spinner rail
   ================================================== */

.numx-spin {
  position: absolute;
  right: 1px;
  top: 1px;
  width: var(--numx-spinner-width);
  height: calc(100% - 2px);
  display: grid;
  grid-template-rows: 1fr 1fr;
  padding: 0;
  opacity: .45;
  transition: opacity .15s ease;
  border-top-right-radius: var(--bs-border-radius-sm, 3px);
  border-bottom-right-radius: var(--bs-border-radius-sm, 3px);
  z-index: 3;
  overflow: hidden;
  pointer-events: auto;
  /***/
  background: transparent;
}

.numx-has-voice .numx-spin {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.numx-spin:hover {
  background: linear-gradient( to bottom, transparent 0, transparent calc(50% - 0.5px), var(--bs-border-color, #999) calc(50% - 0.5px), var(--bs-border-color, #999) calc(50% + 0.5px), transparent calc(50% + 0.5px), transparent 100% );
}

  .numx-spin:hover::before {
    opacity: 1;
  }

/* Left divider */
.numx-spin::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0.5px;
  background: var(--bs-border-color, #999);
}

.numx-spin::before,
.numx-spin::after {
  transition: opacity .12s ease, background-color .12s ease;
}

/* ==================================================
   Spinner buttons – base geometry
   ================================================== */

.numx-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  box-sizing: border-box;
  cursor: pointer;
  user-select: none;
  transition: background-color .125s ease;
}

  .numx-btn:hover {
    background-color: rgba(var(--bs-body-color-rgb), .075);
  }

  .numx-btn:active {
    background-color: rgba(var(--bs-body-color-rgb), 0.15);
  }

  /* ==================================================
   Arrow visuals (chevron style)
   ================================================== */

  .numx-btn::before {
    content: "";
    width: 6px;
    height: 6px;
    border-right: 2px solid var(--bs-body-color, #444);
    border-bottom: 2px solid var(--bs-body-color, #444);
    opacity: 0.5;
    box-sizing: border-box;
    transform-origin: center;
  }

/* Up chevron */
.numx-up::before {
  transform: rotate(-135deg) translate(-1.15px, -1.15px);
}

/* Down chevron */
.numx-down::before {
  transform: rotate(45deg) translate(-1.15px, -1.15px);
}

/* ==================================================
   Arrow visuals (triangle - caret style)
   ================================================== */

.numx-btn.numx-caret::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  opacity: 0.6;
  filter: drop-shadow(0 0 .75px currentColor);
}

.numx-up.numx-caret::before {
  border-bottom: 5.5px solid var(--bs-body-color, #444);
  transform: translateX(-0px); /* 🔧 tweak */
}

.numx-down.numx-caret::before {
  border-top: 5.5px solid var(--bs-body-color, #444);
  transform: translateX(-0px); /* 🔧 tweak */
}

/* ==================================================
   Arrow optical centering – form-floating
   ================================================== */

.form-floating.numx-float .numx-up::before {
  transform: translateX(0px); /* 🔧 independent knob */
}

.form-floating.numx-float .numx-down::before {
  transform: translateX(0px); /* 🔧 independent knob */
}

/* ================================
   Floating mode (keep as-is)
   ================================ */

.form-floating.numx-float > .numx-spin {
  top: 1px;
  bottom: 1px;
  /*height: auto;*/
  transform: none;
}

/* ==================================================
   Bootstrap form-floating integration
   ================================================== */

/* Keep native Bootstrap floating behavior */
.form-floating.numx-float > .form-control,
.form-floating.numx-float > .form-control.form-control-sm {
  padding-right: var(--numx-reserve-space-spinner);
}



/* ==================================================
   NumInputX — Bootstrap input-group (FINAL)
   ================================================== */

/* ------------------------------------------
   1) Input-group context
   ------------------------------------------ */

.input-group.numx-group {
  position: relative;
}

  /* ------------------------------------------
   2) Input owns the spinner
   ------------------------------------------ */

  .input-group.numx-group > .form-control.numx {
    position: relative;
    z-index: 5;
    /* reserve space for spinner */
    padding-right: var(--numx-reserve-space-tools);
    /* default: NOT last → no right radius */
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }

  /* ------------------------------------------
   3) Spinner geometry (above input)
   ------------------------------------------ */

  .input-group.numx-group > .numx-spin-group {
    position: absolute;
    top: 1px;
    bottom: 1px;
    /***/
    width: var(--numx-spinner-width);
    z-index: 10; /* above input & buttons */

    pointer-events: auto;
    background: var(--bs-body-bg);
    overflow: hidden;
    opacity: .45;
    transition: opacity .15s ease;
  }

  .input-group.numx-group.numx-has-voice > .numx-spin-group {
    right: calc(var(--numx-voice-width) - 1px);
  }

  /* divider inside spinner */
  .input-group.numx-group > .numx-spin-group::before {
    background: var(--bs-border-color);
  }

  /* ------------------------------------------
   4) Spinner visibility (input-driven)
   ------------------------------------------ */

  .input-group.numx-group > .form-control.numx:hover ~ .numx-spin-group,
  .input-group.numx-group > .form-control.numx:focus ~ .numx-spin-group,
  .input-group.numx-group > .form-control.numx:focus-within ~ .numx-spin-group,
  .input-group.numx-group > .numx-spin-group:hover {
    opacity: 1;
  }

  /* ------------------------------------------
   5) Restore radius ONLY when numx is last
      (JS adds .numx-last)
   ------------------------------------------ */

  /* input */
  .input-group.numx-group > .form-control.numx.numx-last {
    border-top-right-radius: var(--bs-border-radius) !important;
    border-bottom-right-radius: var(--bs-border-radius) !important;
  }

/* sm */
.input-group-sm.numx-group > .form-control.numx.numx-last {
  border-top-right-radius: var(--bs-border-radius-sm) !important;
  border-bottom-right-radius: var(--bs-border-radius-sm) !important;
}

/* lg */
.input-group-lg.numx-group > .form-control.numx.numx-last {
  border-top-right-radius: var(--bs-border-radius-lg) !important;
  border-bottom-right-radius: var(--bs-border-radius-lg) !important;
}

/* ==================================================
   NumInputX — input-group + form-floating anchor
   ================================================== */

.input-group.numx-group > .form-floating {
  position: relative; /* anchor for spinner */
}

  /* spinner inside form-floating (input-group case) */
  .input-group.numx-group > .form-floating > .numx-spin-group {
    top: 1px;
    bottom: 1px;
    width: var(--numx-spinner-width);
    z-index: 10;
    background: var(--bs-body-bg);
    overflow: hidden;
  }

  /* keep input border visible beside spinner */
  .input-group.numx-group > .form-floating > .form-control.numx {
    background-clip: padding-box;
  }

    /* ==================================================
   NumInputX — spinner visibility
   (input-group + form-floating)
   ================================================== */

    .input-group.numx-group > .form-floating > .form-control.numx:hover ~ .numx-spin-group,
    .input-group.numx-group > .form-floating > .form-control.numx:focus ~ .numx-spin-group,
    .input-group.numx-group > .form-floating:focus-within > .numx-spin-group,
    .input-group.numx-group > .form-floating > .numx-spin-group:hover {
      opacity: 1;
    }

  /* ==================================================
   NumInputX — focus border clearance (STEP 2)
   ================================================== */

  /* ==================================================
   NumInputX — focus border clearance (polite sizing)
   ================================================== */

  /* -------- default (md) -------- */

  .input-group.numx-group:focus-within > .numx-spin-group,
  .input-group.numx-group > .form-floating:focus-within > .numx-spin-group {
    transform: translateX(-1px);
  }

/* -------- small -------- */

.input-group-sm.numx-group:focus-within > .numx-spin-group,
.input-group-sm.numx-group > .form-floating:focus-within > .numx-spin-group,
.form-control-sm:focus ~ .numx-spin-group {
  transform: translateX(-1px);
}

/* -------- large -------- */

.input-group-lg.numx-group:focus-within > .numx-spin-group,
.input-group-lg.numx-group > .form-floating:focus-within > .numx-spin-group,
.form-control-lg:focus ~ .numx-spin-group {
  transform: translateX(-2px);
}

/* input-group without floating */
.input-group.numx-group:focus-within > .numx-spin-group {
  transform: translateX(-1px);
}

.input-group.numx-group:hover > .numx-spin-group,
.input-group.numx-group > .form-floating:hover > .numx-spin-group {
  transform: translateX(-1px);
}


/* defensive CSS: safety guards margins */

input.numx[class*="mt-"] {
  margin-top: 0 !important;
}

input.numx[class*="mb-"] {
  margin-bottom: 0 !important;
}


/* ==== VOICE WAVE ==== */

.numx-voice-wave {
  border-radius: 8px;
  background: rgba(0,0,0,0.05); /* light theme */
}

[data-bs-theme="dark"] .numx-voice-wave {
  background: rgba(255,255,255,0.05);
}

.numx-voice-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden; /* 👈 กันล้น */
  z-index: 10;
  border-top-right-radius: var(--bs-border-radius, 3px) !important;
  border-bottom-right-radius: var(--bs-border-radius, 3px) !important;
}

  .numx-voice-btn i {
    position: relative;
    z-index: 2;
    opacity: .4;
  }

  .numx-voice-btn.text-danger i {
    opacity: 1;
  }

  .numx-voice-btn canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 12% 2px;
    pointer-events: none;
    opacity: 0;
    z-index: 1;
    transition: opacity .2s ease;
    /* 👇 โค้งครึ่งล่าง */
    clip-path: ellipse(80% 55% at 50% 100%);
    mask-image: linear-gradient(to bottom, transparent 0%, black 40%);
    transform: translateY(3%);
  }

  .numx-voice-btn.text-danger canvas {
    opacity: 1; /* ตอน record ชัดขึ้น */
  }

/* ===================== */
