<template>
  <CustomNav title="身高" leftType="back" />
  <view class="page">
    <view class="header">
      <view class="month-selector">
        <button class="btn" @click="prevMonth">‹</button>
        <picker mode="date" :value="pickerValue" @change="onPickerChange">
          <view class="month-label">{{ displayYear }} 年 {{ displayMonth }} 月</view>
        </picker>
        <button class="btn" @click="nextMonth">›</button>
      </view>
    </view>
    <!-- 趋势图：放在月份选择下面 -->
    <view class="chart-wrap">
      <view class="chart-header">本月趋势</view>
      <canvas ref="chartCanvas" id="chartCanvas" canvas-id="heightChart" class="chart-canvas" width="340"
        height="120"></canvas>
    </view>

    <!-- 刻度尺控制（已移入添加模态） -->

    <view class="content">
      <view class="summary">共 {{ records.length }} 条记录，本月平均：{{ averageHeight }} cm</view>

      <view class="list">
        <view v-if="records.length === 0" class="empty">本月暂无身高记录，点击右下角 + 添加</view>
        <view v-for="(r, idx) in records" :key="r.id" class="list-item">
          <view class="date">{{ r.date }}</view>
          <view class="value">{{ r.height }} cm</view>
          <button class="btn-delete" @click.stop.prevent="confirmDeleteRecord(r.id)">✕</button>
        </view>
      </view>
    </view>

    <!-- 悬浮添加按钮 -->
    <view class="fab" @click="openAdd">
      <view class="fab-inner">+</view>
    </view>

    <!-- 添加模态（包含刻度尺） -->
    <view class="modal" v-if="showAdd">
      <view class="modal-backdrop" @click="closeAdd"></view>
      <view class="modal-panel">
        <!-- Drag handle -->
        <view class="drag-handle" />
        <view class="modal-header centered">
          <view class="modal-title">新增身高记录</view>
        </view>

        <!-- 将表单与按钮限制在中间的窄容器，便于阅读和操作 -->
  <view class="modal-inner">
          <view class="form-row">
            <text class="label">日期</text>
            <picker mode="date" :value="pickerValue" @change="onAddDateChange">
              <view class="picker-display">{{ addDateLabel }}</view>
            </picker>
          </view>

          <view class="form-row">
            <text class="label">身高 (cm)</text>
            <input type="number" v-model.number="addHeight" class="input" placeholder="请输入身高" />
          </view>

        </view>

        <!-- 刻度尺：独立于 .modal-inner，保持屏幕全宽以便手指操作 -->
        <view class="ruler-wrap">
          <ScaleRuler v-if="showAdd" :min="120" :max="220" :step="1" :gutter="16" :initialValue="addHeight ?? 170"
            @change="onAddRulerChange" @update:value="onAddRulerUpdate" />
        </view>
        <!-- 固定底部的大保存按钮（距离屏幕底部至少 100rpx） -->
        <view class="fixed-footer">
          <button class="btn-primary btn-full" @click="confirmAdd">保存</button>
        </view>
      </view>
    </view>

  </view>
  <TabBar />
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import CustomNav from '@/components/CustomNav.vue'
import TabBar from '@/components/TabBar.vue'
import ScaleRuler from '@/components/scale-ruler.vue'

type RecordItem = { id: string; date: string; height: number }

// 当前展示的年月（以 JS Date 管理）
const current = ref(new Date())

const pickerValue = ref(formatPickerDate(current.value))

function formatPickerDate(d: Date) {
  // 返回 yyyy-MM-dd，用于 picker 的 value
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return `${y}-${m}-${day}`
}

const displayYear = computed(() => current.value.getFullYear())
const displayMonth = computed(() => current.value.getMonth() + 1)

// 模拟数据：默认展示本月数据
const records = ref<RecordItem[]>(generateMockRecords(current.value))

function generateMockRecords(d: Date): RecordItem[] {
  const y = d.getFullYear()
  const m = d.getMonth()
  const arr: RecordItem[] = []
  // 随机生成 0-6 条数据
  const n = Math.floor(Math.random() * 7)
  for (let i = 0; i < n; i++) {
    const day = Math.max(1, Math.floor(Math.random() * 28) + 1)
    const date = new Date(y, m, day)
    arr.push({ id: `${y}${m}${i}${Date.now()}`, date: formatDisplayDate(date), height: 150 + Math.floor(Math.random() * 50) })
  }
  // 按日期排序
  return arr.sort((a, b) => (a.date < b.date ? 1 : -1))
}

function formatDisplayDate(d: Date) {
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
}

const averageHeight = computed(() => {
  if (records.value.length === 0) return '--'
  const sum = records.value.reduce((s, r) => s + r.height, 0)
  return (sum / records.value.length).toFixed(1)
})

function daysInMonth(year: number, month: number) {
  return new Date(year, month + 1, 0).getDate()
}

// 生成用于绘制折线图的数据点（坐标）
const pointCoords = computed(() => {
  const year = current.value.getFullYear()
  const month = current.value.getMonth()
  const days = daysInMonth(year, month)
  // 宽度 340，高度 120，给上下留白
  const W = 340
  const H = 120
  const leftPad = 10
  const rightPad = 10
  const topPad = 10
  const bottomPad = 10
  const innerW = W - leftPad - rightPad
  const innerH = H - topPad - bottomPad

  // 按日填充值（null 表示无数据）
  const values: Array<number | null> = Array(days).fill(null)
  records.value.forEach(r => {
    const parts = r.date.split('-')
    if (parts.length >= 3) {
      const y = parseInt(parts[0], 10)
      const m = parseInt(parts[1], 10) - 1
      const d = parseInt(parts[2], 10)
      if (y === year && m === month && d >= 1 && d <= days) {
        values[d - 1] = r.height
      }
    }
  })

  const numeric = values.filter(v => v !== null) as number[]
  const min = numeric.length ? Math.min(...numeric) : 140
  const max = numeric.length ? Math.max(...numeric) : 180
  const range = Math.max(1, max - min)

  // 计算每个点的坐标
  const coords = values.map((v, idx) => {
    const x = leftPad + (innerW * idx) / Math.max(1, days - 1)
    if (v === null) return null
    const y = topPad + innerH - ((v - min) / range) * innerH
    return { x, y }
  })
  return coords
})

const polylinePoints = computed(() => {
  const pts = pointCoords.value
  const arr: string[] = []
  pts.forEach(p => {
    if (p) arr.push(`${p.x},${p.y}`)
  })
  return arr.length ? arr.join(' ') : ''
})

const areaPoints = computed(() => {
  const pts = pointCoords.value
  if (!pts.length) return ''
  const arr: string[] = []
  pts.forEach(p => {
    if (p) arr.push(`${p.x},${p.y}`)
  })
  // 加上底部闭合
  if (arr.length) {
    const firstX = pts.find(p => p)?.x ?? 0
    const lastX = pts.slice().reverse().find(p => p)?.x ?? 0
    const baseY = 120 - 10
    return `${firstX},${baseY} ` + arr.join(' ') + ` ${lastX},${baseY}`
  }
  return ''
})

// Canvas 绘图
import { onMounted, watch, nextTick, onBeforeUnmount, ref as vueRef, getCurrentInstance } from 'vue'
const chartCanvas = vueRef<HTMLCanvasElement | null>(null)
const vm = getCurrentInstance()

function getCanvasSize(): Promise<{ width: number; height: number }> {
  return new Promise(resolve => {
    try {
      if (typeof uni !== 'undefined' && uni.createSelectorQuery) {
        const query = uni.createSelectorQuery().in(vm?.proxy)
        query.select('#chartCanvas').boundingClientRect((rect: any) => {
          if (rect) resolve({ width: rect.width, height: rect.height })
          else resolve({ width: 340, height: 120 })
        }).exec()
      } else if (chartCanvas.value) {
        resolve({ width: chartCanvas.value.clientWidth || 340, height: chartCanvas.value.clientHeight || 120 })
      } else {
        resolve({ width: 340, height: 120 })
      }
    } catch (e) {
      resolve({ width: 340, height: 120 })
    }
  })
}

async function drawChart() {
  // If running in H5 and canvas DOM is available, use native canvas
  const canvas = chartCanvas.value as HTMLCanvasElement | null
  if (canvas && canvas.getContext) {
    const ctx = canvas.getContext('2d')
    if (!ctx) return
    const dpr = (typeof uni !== 'undefined' && uni.getSystemInfoSync) ? (uni.getSystemInfoSync().pixelRatio || (window?.devicePixelRatio || 1)) : (window?.devicePixelRatio || 1)
    const cssWidth = canvas.clientWidth || 340
    const cssHeight = canvas.clientHeight || 120
    canvas.width = Math.round(cssWidth * dpr)
    canvas.height = Math.round(cssHeight * dpr)
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
    ctx.clearRect(0, 0, cssWidth, cssHeight)
    ctx.strokeStyle = 'rgba(0,0,0,0.04)'
    ctx.lineWidth = 1
    for (let i = 0; i <= 4; i++) {
      const y = (cssHeight / 4) * i
      ctx.beginPath()
      ctx.moveTo(0, y)
      ctx.lineTo(cssWidth, y)
      ctx.stroke()
    }
    const scaleX = cssWidth / 340
    const scaleY = cssHeight / 120
    const pts = pointCoords.value.map(p => p ? { x: p.x * scaleX, y: p.y * scaleY } : null)
    const validPts = pts.filter(p => p !== null) as { x: number; y: number }[]

    // draw Y axis labels (4 ticks) and X axis day labels
    const year = current.value.getFullYear()
    const month = current.value.getMonth()
    const days = daysInMonth(year, month)
    const valuesForTicks: Array<number | null> = Array(days).fill(null)
    records.value.forEach(r => {
      const parts = r.date.split('-')
      if (parts.length >= 3) {
        const y = parseInt(parts[0], 10)
        const m = parseInt(parts[1], 10) - 1
        const d = parseInt(parts[2], 10)
        if (y === year && m === month && d >= 1 && d <= days) valuesForTicks[d - 1] = r.height
      }
    })
    const numeric = valuesForTicks.filter(v => v !== null) as number[]
    const minVal = numeric.length ? Math.min(...numeric) : 140
    const maxVal = numeric.length ? Math.max(...numeric) : 180
    const range = Math.max(1, maxVal - minVal)
    const leftPad = 10 * scaleX
    const topPad = 10 * scaleY
    const innerW = (340 - 10 - 10) * scaleX
    const innerH = (120 - 10 - 10) * scaleY
    ctx.fillStyle = '#999'
    ctx.font = '12px sans-serif'
    ctx.textAlign = 'right'
    ctx.textBaseline = 'middle'
    for (let j = 0; j <= 4; j++) {
      const val = Math.round((maxVal - (range * j) / 4) * 10) / 10
      const y = topPad + (innerH * j) / 4
      ctx.fillText(String(val), leftPad - 6, y)
      ctx.beginPath()
      ctx.moveTo(leftPad - 3, y)
      ctx.lineTo(leftPad, y)
      ctx.strokeStyle = 'rgba(0,0,0,0.08)'
      ctx.stroke()
    }
    const step = Math.max(1, Math.ceil(days / 6))
    ctx.textAlign = 'center'
    ctx.textBaseline = 'top'
    for (let d = 1; d <= days; d += step) {
      const x = leftPad + (innerW * (d - 1)) / Math.max(1, days - 1)
      const yTick = topPad + innerH
      ctx.beginPath()
      ctx.moveTo(x, yTick)
      ctx.lineTo(x, yTick + 6)
      ctx.strokeStyle = 'rgba(0,0,0,0.08)'
      ctx.stroke()
      ctx.fillText(String(d), x, yTick + 8)
    }
    if (validPts.length) {
      ctx.beginPath()
      ctx.moveTo(validPts[0].x, validPts[0].y)
      validPts.forEach(p => ctx.lineTo(p.x, p.y))
      ctx.lineTo(validPts[validPts.length - 1].x, cssHeight)
      ctx.lineTo(validPts[0].x, cssHeight)
      ctx.closePath()
      ctx.fillStyle = 'rgba(255,106,0,0.08)'
      ctx.fill()
    }
    if (validPts.length) {
      ctx.beginPath()
      ctx.moveTo(validPts[0].x, validPts[0].y)
      validPts.forEach(p => ctx.lineTo(p.x, p.y))
      ctx.strokeStyle = '#ff6a00'
      ctx.lineWidth = 2
      ctx.lineJoin = 'round'
      ctx.lineCap = 'round'
      ctx.stroke()
    }
    validPts.forEach(p => {
      ctx.beginPath()
      ctx.fillStyle = '#ff6a00'
      ctx.arc(p.x, p.y, 3, 0, Math.PI * 2)
      ctx.fill()
    })
    return
  }

  // Otherwise fallback to uni.createCanvasContext for mini-programs / native canvases
  try {
    const size = await getCanvasSize()
    const cssWidth = size.width || 340
    const cssHeight = size.height || 120
    const ctx = (typeof uni !== 'undefined' && uni.createCanvasContext) ? uni.createCanvasContext('heightChart', vm?.proxy) : null
    if (!ctx) return
    // clear by drawing a transparent rect
    ctx.clearRect && ctx.clearRect(0, 0, cssWidth, cssHeight)
    ctx.setStrokeStyle && ctx.setStrokeStyle('rgba(0,0,0,0.04)')
    for (let i = 0; i <= 4; i++) {
      const y = (cssHeight / 4) * i
      if (ctx.beginPath) ctx.beginPath()
      ctx.moveTo && ctx.moveTo(0, y)
      ctx.lineTo && ctx.lineTo(cssWidth, y)
      ctx.stroke && ctx.stroke()
    }
    const scaleX = cssWidth / 340
    const scaleY = cssHeight / 120
    const pts = pointCoords.value.map(p => p ? { x: p.x * scaleX, y: p.y * scaleY } : null)
    const validPts = pts.filter(p => p !== null) as { x: number; y: number }[]
    // draw labels (mini-program canvas API)
    const year = current.value.getFullYear()
    const month = current.value.getMonth()
    const days = daysInMonth(year, month)
    const valuesForTicks: Array<number | null> = Array(days).fill(null)
    records.value.forEach(r => {
      const parts = r.date.split('-')
      if (parts.length >= 3) {
        const y = parseInt(parts[0], 10)
        const m = parseInt(parts[1], 10) - 1
        const d = parseInt(parts[2], 10)
        if (y === year && m === month && d >= 1 && d <= days) valuesForTicks[d - 1] = r.height
      }
    })
    const numeric = valuesForTicks.filter(v => v !== null) as number[]
    const minVal = numeric.length ? Math.min(...numeric) : 140
    const maxVal = numeric.length ? Math.max(...numeric) : 180
    const range = Math.max(1, maxVal - minVal)
    const leftPad = 10 * scaleX
    const topPad = 10 * scaleY
    const innerW = (340 - 10 - 10) * scaleX
    const innerH = (120 - 10 - 10) * scaleY
    ctx.setFillStyle && ctx.setFillStyle('#999')
    ctx.setFontSize && ctx.setFontSize(12)
    // Y axis
    for (let j = 0; j <= 4; j++) {
      const val = Math.round((maxVal - (range * j) / 4) * 10) / 10
      const y = topPad + (innerH * j) / 4
      ctx.fillText && ctx.fillText(String(val), leftPad - 6, y)
      ctx.beginPath && ctx.beginPath()
      ctx.moveTo && ctx.moveTo(leftPad - 3, y)
      ctx.lineTo && ctx.lineTo(leftPad, y)
      ctx.stroke && ctx.stroke()
    }
    const step = Math.max(1, Math.ceil(days / 6))
    // X axis
    for (let d = 1; d <= days; d += step) {
      const x = leftPad + (innerW * (d - 1)) / Math.max(1, days - 1)
      const yTick = topPad + innerH
      ctx.moveTo && ctx.moveTo(x, yTick)
      ctx.lineTo && ctx.lineTo(x, yTick + 6)
      ctx.stroke && ctx.stroke()
      ctx.fillText && ctx.fillText(String(d), x, yTick + 8)
    }
    if (validPts.length) {
      ctx.beginPath && ctx.beginPath()
      ctx.moveTo && ctx.moveTo(validPts[0].x, validPts[0].y)
      validPts.forEach(p => ctx.lineTo && ctx.lineTo(p.x, p.y))
      ctx.lineTo && ctx.lineTo(validPts[validPts.length - 1].x, cssHeight)
      ctx.lineTo && ctx.lineTo(validPts[0].x, cssHeight)
      ctx.closePath && ctx.closePath()
      ctx.setFillStyle && ctx.setFillStyle('rgba(255,106,0,0.08)')
      ctx.fill && ctx.fill()
    }
    if (validPts.length) {
      ctx.beginPath && ctx.beginPath()
      ctx.moveTo && ctx.moveTo(validPts[0].x, validPts[0].y)
      validPts.forEach(p => ctx.lineTo && ctx.lineTo(p.x, p.y))
      ctx.setStrokeStyle && ctx.setStrokeStyle('#ff6a00')
      ctx.setLineWidth && ctx.setLineWidth(2)
      ctx.stroke && ctx.stroke()
    }
    validPts.forEach(p => {
      ctx.beginPath && ctx.beginPath()
      ctx.arc && ctx.arc(p.x, p.y, 3, 0, Math.PI * 2)
      ctx.setFillStyle && ctx.setFillStyle('#ff6a00')
      ctx.fill && ctx.fill()
    })
    ctx.draw && ctx.draw(true)
  } catch (err) {
    // ignore
  }
}

onMounted(() => {
  nextTick(() => drawChart())
})

watch([() => records.value, () => current.value], () => {
  nextTick(() => drawChart())
}, { deep: true })

onBeforeUnmount(() => {
  // no special cleanup required
})

function prevMonth() {
  const d = new Date(current.value)
  d.setMonth(d.getMonth() - 1)
  current.value = d
  pickerValue.value = formatPickerDate(d)
  records.value = generateMockRecords(d)
}

function nextMonth() {
  const d = new Date(current.value)
  d.setMonth(d.getMonth() + 1)
  current.value = d
  pickerValue.value = formatPickerDate(d)
  records.value = generateMockRecords(d)
}

function onPickerChange(e: any) {
  const val = e?.detail?.value || e
  const parts = (val as string).split('-')
  if (parts.length >= 2) {
    const y = parseInt(parts[0], 10)
    const m = parseInt(parts[1], 10) - 1
    const d = new Date(y, m, 1)
    current.value = d
    pickerValue.value = formatPickerDate(d)
    records.value = generateMockRecords(d)
  }
}

// 添加逻辑
const showAdd = ref(false)
const addDate = ref(formatPickerDate(new Date()))
const addDateLabel = ref(formatDisplayDate(new Date()))
const addHeight = ref<number | null>(null)

// 刻度尺（添加模态使用）的联动处理
function onAddRulerUpdate(val: number) {
  addHeight.value = val
  // 实时打印用户滑动时的刻度（update 在滚动过程中会频繁触发）
  console.log('[ScaleRuler] add update:value ->', val)
}
function onAddRulerChange(val: number) {
  addHeight.value = val
  console.log('[ScaleRuler] add change ->', val)
}

function openAdd() {
  showAdd.value = true
  // 打开添加模态时，初始化刻度尺/输入默认值（若之前无值则设为 170）
  if (!addHeight.value) addHeight.value = 170
}
function closeAdd() {
  showAdd.value = false
  addHeight.value = null
}

function onAddDateChange(e: any) {
  const val = e?.detail?.value || e
  addDate.value = val
  addDateLabel.value = val.replace(/^(\d{4})-(\d{2})-(\d{2}).*$/, '$1-$2-$3')
}

function confirmAdd() {
  if (!addHeight.value) {
    uni.showToast({ title: '请输入身高', icon: 'none' })
    return
  }
  const id = `user-${Date.now()}`
  const item: RecordItem = { id, date: addDateLabel.value, height: addHeight.value }
  // 如果添加的月份与当前展示月份一致，插入
  const parts = addDate.value.split('-')
  const addY = parseInt(parts[0], 10)
  const addM = parseInt(parts[1], 10) - 1
  if (addY === current.value.getFullYear() && addM === current.value.getMonth()) {
    records.value = [item, ...records.value]
  }
  uni.showToast({ title: '已添加', icon: 'success' })
  closeAdd()
}

// 删除记录逻辑：弹出确认对话框，确认后从 records 中移除
function confirmDeleteRecord(id: string) {
  if (typeof uni !== 'undefined' && uni.showModal) {
    uni.showModal({
      title: '删除记录',
      content: '确认要删除该条身高记录吗？此操作无法撤销。',
      confirmText: '删除',
      cancelText: '取消',
      success: (res: any) => {
        if (res.confirm) {
          records.value = records.value.filter(r => r.id !== id)
          uni.showToast({ title: '已删除', icon: 'success' })
        }
      }
    })
  } else {
    // Fallback:直接删除
    records.value = records.value.filter(r => r.id !== id)
  }
}

</script>

<style scoped>
.page {
  min-height: calc(100vh);
  padding-top: calc(var(--status-bar-height) + 44px);
  background: #f5f6f8;
  box-sizing: border-box
}

.header {
  padding: 20rpx 40rpx
}

.month-selector {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12rpx
}

.month-label {
  font-size: 34rpx;
  color: #333
}

.btn {
  background: transparent;
  border: none;
  font-size: 36rpx;
  color: #666
}

.content {
  padding: 20rpx 24rpx 100rpx 24rpx
}

.chart-wrap {
  padding: 12rpx 24rpx
}

.chart-header {
  font-size: 28rpx;
  color: #666;
  margin-bottom: 10rpx
}

.chart-svg {
  width: 100%;
  height: 160rpx;
  display: block
}

.summary {
  padding: 20rpx;
  color: #666;
  font-size: 28rpx
}

.list {
  background: #fff;
  border-radius: 12rpx;
  padding: 10rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03)
}

.empty {
  padding: 40rpx;
  text-align: center;
  color: #999
}

.list-item {
  display: flex;
  align-items: center;
  padding: 20rpx;
  border-bottom: 1rpx solid #f0f0f0;
}

.list-item .date {
  color: #666
}

.list-item .value {
  color: #333;
  font-weight: 600;
  flex: 1; /* allow value to take remaining space */
  text-align: right; /* keep value left aligned so delete button on right */
}

.btn-delete {
  width: 80rpx;
  height: 60rpx;
  min-width: 60rpx;
  min-height: 60rpx;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #fff0f0;
  color: #d9534f;
  border: 1rpx solid rgba(217,83,79,0.15);
  border-radius: 8rpx;
  margin-left: 30rpx;
}

.fab {
  position: fixed;
  right: 28rpx;
  bottom: 160rpx;
  width: 110rpx;
  height: 110rpx;
  border-radius: 999px;
  background: linear-gradient(180deg, #ff7a00, #ff4a00);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6rpx 18rpx rgba(0, 0, 0, 0.2);
  z-index: 1200
}

.fab-inner {
  color: #fff;
  font-size: 56rpx;
  line-height: 56rpx
}

.modal {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 1300
}

.modal-backdrop {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.4)
}

.modal-panel {
  position: relative;
  width: 100%;
  background: #fff;
  border-top-left-radius: 18rpx;
  border-top-right-radius: 18rpx;
  padding: 28rpx 24rpx 140rpx 24rpx; /* leave space for fixed footer */
  box-shadow: 0 -8rpx 30rpx rgba(0,0,0,0.12);
}

.modal-title {
  font-size: 56rpx;
  margin-block:  60rpx;
  color: #222;
  font-weight: 700;
  letter-spacing: 1rpx;
}

.modal-inner {
  max-width: 70%;
  margin: 0 auto;
}

.form-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 34rpx;
  padding: 14rpx 0;
  font-size: 32rpx;
}

.input {
  width: 240rpx;
  text-align: right;
  padding: 16rpx;
  border-radius: 14rpx;
  border: 1rpx solid #eee;
  background: #fff7f0;
}

.picker-display {
  color: #333
}

.modal-actions {
  display: flex;
  justify-content: center;
  gap: 12rpx;
  margin-top: 18rpx;
}

.modal-actions.full {
  padding: 6rpx 0 24rpx 0;
}

.btn-primary {
  background: #ff6a00;
  color: #fff;
  padding: 18rpx 22rpx;
  border-radius: 16rpx;
  text-align: center;
  width: 50%;
  box-shadow: 0 10rpx 28rpx rgba(255,106,0,0.18);
}


/* Drag handle and header */
.drag-handle {
  width: 64rpx;
  height: 6rpx;
  background: rgba(0,0,0,0.08);
  border-radius: 999px;
  margin: 10rpx auto 14rpx auto;
}
.modal-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12rpx;
  margin-bottom: 6rpx;
}
.label {
  color: #666;
}
.ruler-wrap {
  margin: 12rpx 0;
  /* keep full width so ScaleRuler spans screen width */
}
</style>