<template>
    <div class="container pb-2xl">
        <div class="tool-header">
            <router-link to="/" class="back-link">
                <ChevronLeft class="icon-sm" /> 返回首页
            </router-link>
            <h2>
                <Globe class="icon-lg" /> 坐标系统与格式转换
            </h2>
            <p>支持经纬度格式转换、常用地图坐标系互转及 CGCS2000 高斯平面投影与批量转换</p>
        </div>

        <div class="tabs-wrapper">
            <!-- Tab Navigation -->
            <div class="tabs-header">
                <button 
                    v-for="tab in tabsList" 
                    :key="tab.id" 
                    @click="activeTab = tab.id"
                    :class="['tab-btn', { active: activeTab === tab.id }]"
                >
                    <component :is="tab.icon" class="icon-sm mr-xs" />
                    {{ tab.name }}
                </button>
            </div>

            <!-- Tab Content -->
            <div class="tab-content card">
                
                <!-- 1. Format Conversion -->
                <div v-show="activeTab === 'format'">
                    <h3 class="card-title text-center mb-xl">度分秒与十进制度数互转</h3>
                    <div class="grid grid-2 gap-xl">
                        <div class="flex-col">
                            <div class="input-group flex-1">
                                <label class="input-label">度分秒 → 十进制</label>
                                <div class="dms-input mb-sm">
                                    <input type="number" v-model.number="dms.lat.degrees" class="input" placeholder="度">
                                    <input type="number" v-model.number="dms.lat.minutes" class="input" placeholder="分">
                                    <input type="number" v-model.number="dms.lat.seconds" class="input" placeholder="秒">
                                    <select v-model="dms.lat.direction" class="input px-xs">
                                        <option value="N">N</option>
                                        <option value="S">S</option>
                                    </select>
                                </div>
                                <div class="dms-input">
                                    <input type="number" v-model.number="dms.lon.degrees" class="input" placeholder="度">
                                    <input type="number" v-model.number="dms.lon.minutes" class="input" placeholder="分">
                                    <input type="number" v-model.number="dms.lon.seconds" class="input" placeholder="秒">
                                    <select v-model="dms.lon.direction" class="input px-xs">
                                        <option value="E">E</option>
                                        <option value="W">W</option>
                                    </select>
                                </div>
                            </div>
                            <button @click="convertToDecimal" class="btn btn-primary btn-full mt-md">转换为十进制</button>
                        </div>

                        <div class="flex-col">
                            <div class="input-group flex-1">
                                <label class="input-label">十进制 → 度分秒</label>
                                <div class="flex flex-col gap-sm">
                                    <input type="number" v-model.number="decimal.lat" class="input" placeholder="纬度 (Lat)">
                                    <input type="number" v-model.number="decimal.lon" class="input" placeholder="经度 (Lon)">
                                </div>
                            </div>
                            <button @click="convertToDms" class="btn btn-primary btn-full mt-md">转换为度分秒</button>
                        </div>
                    </div>
                </div>

                <!-- 2. CRS Transformation -->
                <div v-show="activeTab === 'crs'">
                    <h3 class="card-title text-center mb-xl">常用地图坐标系互转</h3>
                    <div class="max-w-3xl mx-auto">
                        <div class="input-group">
                            <label class="input-label">输入坐标 (经度, 纬度)</label>
                            <input type="text" v-model="crsInput" class="input" placeholder="例: 116.397, 39.908">
                        </div>

                        <div class="grid grid-2 gap-md mt-md">
                            <div class="input-group">
                                <label class="input-label">来源坐标系</label>
                                <select v-model="sourceCrs" class="input">
                                    <option value="WGS84">WGS84 (大地坐标/GPS)</option>
                                    <option value="GCJ02">GCJ02 (火星坐标/高德/腾讯)</option>
                                    <option value="BD09">BD09 (百度坐标)</option>
                                </select>
                            </div>
                            <div class="input-group">
                                <label class="input-label">目标坐标系</label>
                                <select v-model="targetCrs" class="input">
                                    <option value="GCJ02">GCJ02 (火星坐标/高德/腾讯)</option>
                                    <option value="WGS84">WGS84 (大地坐标/GPS)</option>
                                    <option value="BD09">BD09 (百度坐标)</option>
                                </select>
                            </div>
                        </div>

                        <button @click="transformCrs" class="btn btn-primary btn-full mt-lg">执行地图坐标转换</button>
                    </div>
                </div>

                <!-- 3. CGCS2000 Projection -->
                <div v-show="activeTab === 'proj'">
                    <h3 class="card-title text-center mb-xl">高斯-克吕格平面投影计算</h3>
                    <div class="max-w-3xl mx-auto">
                        <div class="grid grid-2 gap-md mb-md">
                            <div class="input-group">
                                <label class="input-label">转换方向</label>
                                <select v-model="projConfig.direction" class="input">
                                    <option value="toPlane">经纬度 → 平面坐标</option>
                                    <option value="toLngLat">平面坐标 → 经纬度</option>
                                </select>
                            </div>
                            <div class="input-group">
                                <label class="input-label">分带方式 (CGCS2000)</label>
                                <select v-model="projConfig.zoneType" class="input">
                                    <option :value="3">3 度带</option>
                                    <option :value="6">6 度带</option>
                                </select>
                            </div>
                        </div>

                        <div v-if="projConfig.direction === 'toPlane'" class="flex-col pb-md">
                            <div class="grid grid-2 gap-md mb-md">
                                <div class="input-group">
                                    <label class="input-label">经度 (Lon)</label>
                                    <input type="number" v-model.number="projConfig.lng" class="input" placeholder="输入经度">
                                </div>
                                <div class="input-group">
                                    <label class="input-label">纬度 (Lat)</label>
                                    <input type="number" v-model.number="projConfig.lat" class="input" placeholder="输入纬度">
                                </div>
                            </div>
                            <label class="checkbox-label mb-md">
                                <input type="checkbox" v-model="projConfig.withZone">
                                投影后的 X 坐标 (北移/纬距对应国内Y) 包含带号
                            </label>
                            <button @click="doProjection" class="btn btn-primary btn-full">投影到平面</button>
                        </div>
                        
                        <div v-else class="flex-col pb-md">
                            <div class="grid grid-2 gap-md mb-md">
                                <div class="input-group">
                                    <label class="input-label">北移坐标 (国内X)</label>
                                    <input type="number" v-model.number="projConfig.y" class="input" placeholder="对应测量的 X 坐标 (Northing)">
                                </div>
                                <div class="input-group">
                                    <label class="input-label">东移坐标 (国内Y)</label>
                                    <input type="number" v-model.number="projConfig.x" class="input" placeholder="对应测量的 Y 坐标 (Easting)">
                                </div>
                            </div>
                            
                            <div class="grid grid-2 gap-md mb-md align-center">
                                <label class="checkbox-label">
                                    <input type="checkbox" v-model="projConfig.withZone"> 东移坐标包含带号
                                </label>
                                <div class="input-group m-0" v-if="!projConfig.withZone">
                                    <input type="number" v-model.number="projConfig.manualZone" class="input" placeholder="请手动输入区域带号">
                                </div>
                            </div>
                            <button @click="doProjection" class="btn btn-primary btn-full">反投到经纬度</button>
                        </div>
                    </div>
                </div>

                <!-- 4. Execute Bulk Conversion -->
                <div v-show="activeTab === 'batch'">
                    <h3 class="card-title text-center mb-md">通过 Excel 批量互转平面与地理坐标</h3>
                    <p class="text-secondary text-sm text-center mb-xl">
                        请先下载对应的格式模板，填写数据后上传即可自动解析、计算并导出。所有计算均在浏览器本地完成。
                    </p>

                    <div class="max-w-3xl mx-auto flex-col">
                        <div class="grid grid-2 gap-md mb-xl">
                            <button @click="downloadTemplate('toPlane')" class="btn btn-secondary flex-center gap-xs">
                                <DownloadCloud class="icon-sm" /> 下载 经纬度转平面 模板
                            </button>
                            <button @click="downloadTemplate('toLngLat')" class="btn btn-secondary flex-center gap-xs">
                                <DownloadCloud class="icon-sm" /> 下载 平面转经纬度 模板
                            </button>
                            <button @click="downloadTemplate('toDecimal')" class="btn btn-secondary flex-center gap-xs">
                                <DownloadCloud class="icon-sm" /> 下载 度分秒转十进制 模板
                            </button>
                            <button @click="downloadTemplate('toDms')" class="btn btn-secondary flex-center gap-xs">
                                <DownloadCloud class="icon-sm" /> 下载 十进制转度分秒 模板
                            </button>
                        </div>

                        <div class="upload-area">
                            <input type="file" id="excel-upload" accept=".xlsx, .xls" class="hidden" @change="handleFileUpload">
                            <label for="excel-upload" class="upload-label">
                                <UploadCloud class="icon-xl mb-md text-primary" />
                                <span class="text-lg font-600 mb-xs">点击此处选择 Excel 文件</span>
                                <span class="text-tertiary text-sm">支持 .xlsx, .xls 格式</span>
                            </label>
                        </div>
                    </div>
                </div>

            </div>
        </div>

        <!-- Single Result Area -->
        <div v-if="result && activeTab !== 'batch'" class="card mt-xl">
            <div class="flex justify-between items-center mb-md">
                <h4 class="m-0 flex items-center gap-xs">
                    <CheckCircle2 class="icon-md text-success" /> 单点计算结果
                </h4>
                <button @click="copyResult" class="btn btn-secondary btn-sm flex-center gap-xs">
                    <Copy class="icon-sm" /> 复制
                </button>
            </div>
            
            <div class="result-box">
                <div v-if="result.type === 'decimal'">
                    <p><strong>纬度 (Lat):</strong> {{ result.lat }}</p>
                    <p><strong>经度 (Lon):</strong> {{ result.lon }}</p>
                </div>
                <div v-else-if="result.type === 'dms'">
                    <p><strong>纬度:</strong> {{ result.lat }}</p>
                    <p><strong>经度:</strong> {{ result.lon }}</p>
                </div>
                <div v-else-if="result.type === 'crs'">
                    <p><strong>经度 (Lon):</strong> {{ result.lon.toFixed(8) }}°</p>
                    <p><strong>纬度 (Lat):</strong> {{ result.lat.toFixed(8) }}°</p>
                    <small class="text-tertiary">由 {{ sourceCrs }} 转换为 {{ targetCrs }}</small>
                </div>
                <div v-else-if="result.type === 'proj_plane'">
                    <p><strong>北移坐标 (国内X):</strong> {{ result.northing.toFixed(4) }} m</p>
                    <p><strong>东移坐标 (国内Y):</strong> {{ result.easting.toFixed(4) }} m</p>
                    <small class="text-tertiary">基于 CGCS2000 {{ projConfig.zoneType }}度带高斯投影 (带号: {{ result.zone }}, 中央子午线: {{ result.meridian }}°)</small>
                </div>
                <div v-else-if="result.type === 'proj_lnglat'">
                    <p><strong>经度 (Lon):</strong> {{ result.lng.toFixed(8) }}°</p>
                    <p><strong>纬度 (Lat):</strong> {{ result.lat.toFixed(8) }}°</p>
                    <small class="text-tertiary">基于 CGCS2000 {{ projConfig.zoneType }}度带高斯投影 (带号: {{ result.zone }}, 中央子午线: {{ result.meridian }}°)</small>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref } from 'vue'
import gcoord from 'gcoord'
import * as xlsx from 'xlsx'
import { ChevronLeft, Globe, RefreshCw, MapPin, Copy, CheckCircle2, Layers, FileSpreadsheet, DownloadCloud, UploadCloud } from 'lucide-vue-next'
import { dmsToDecimal, formatCoordinate } from '../utils/coordinate'
import { projectToPlane, unprojectToLngLat } from '../utils/proj'

// === Tabs UI State ===
const activeTab = ref('format')
const tabsList = [
    { id: 'format', name: '格式转换', icon: RefreshCw },
    { id: 'crs', name: '地图坐标转换', icon: MapPin },
    { id: 'proj', name: 'CGCS2000投影转换', icon: Layers },
    { id: 'batch', name: 'Excel 批量互转', icon: FileSpreadsheet }
]

// === DMS Conversion State ===
const dms = ref({
    lat: { degrees: 22, minutes: 49, seconds: 16.8640, direction: 'N' },
    lon: { degrees: 108, minutes: 18, seconds: 37.4184, direction: 'E' }
})
const decimal = ref({ lat: 22.8213511, lon: 108.3103940 })

// === CRS Transformation State ===
const crsInput = ref('116.397451, 39.909235')
const sourceCrs = ref('WGS84')
const targetCrs = ref('GCJ02')

// === Projection State ===
const projConfig = ref({
    direction: 'toPlane', // or 'toLngLat'
    zoneType: 3, // 3 or 6
    withZone: true,
    lng: 108.55972199,
    lat: 22.85808956,
    x: 36557444.5725, // Easting (Y)
    y: 2528930.9851,  // Northing (X)
    manualZone: null
})

const result = ref(null)

// --- Methods ---

const convertToDecimal = () => {
    const latDecimal = dmsToDecimal(dms.value.lat.degrees, dms.value.lat.minutes, dms.value.lat.seconds)
    const lonDecimal = dmsToDecimal(dms.value.lon.degrees, dms.value.lon.minutes, dms.value.lon.seconds)

    result.value = {
        type: 'decimal',
        lat: (dms.value.lat.direction === 'S' ? -latDecimal : latDecimal).toFixed(8),
        lon: (dms.value.lon.direction === 'W' ? -lonDecimal : lonDecimal).toFixed(8)
    }
}

const convertToDms = () => {
    result.value = {
        type: 'dms',
        lat: formatCoordinate(decimal.value.lat, 'lat'),
        lon: formatCoordinate(decimal.value.lon, 'lon')
    }
}

const transformCrs = () => {
    const parts = crsInput.value.split(/[,，\s]+/).map(p => parseFloat(p.trim())).filter(p => !isNaN(p))
    if (parts.length < 2) {
        alert('请输入有效的坐标 (经度, 纬度)')
        return
    }

    const [lon, lat] = parts
    const transformed = gcoord.transform(
        [lon, lat],
        gcoord[sourceCrs.value],
        gcoord[targetCrs.value]
    )

    result.value = {
        type: 'crs',
        lon: transformed[0],
        lat: transformed[1]
    }
}

const doProjection = () => {
    try {
        if (projConfig.value.direction === 'toPlane') {
            const { lng, lat, zoneType, withZone } = projConfig.value
            if (!lng || !lat) return alert('请输入经纬度')
            const res = projectToPlane(lng, lat, zoneType, withZone)
            result.value = {
                type: 'proj_plane',
                easting: res.easting,
                northing: res.northing,
                zone: res.zone,
                meridian: res.meridian
            }
        } else {
            const { x, y, zoneType, withZone, manualZone } = projConfig.value
            if (!x || !y) return alert('请输入平面坐标')
            const res = unprojectToLngLat(x, y, zoneType, withZone, manualZone)
            result.value = {
                type: 'proj_lnglat',
                lng: res.lng,
                lat: res.lat,
                zone: res.zone,
                meridian: res.meridian
            }
        }
    } catch (err) {
        alert('转换失败: ' + err.message)
    }
}

const copyResult = () => {
    let text = ''
    if (result.value.type === 'decimal') {
        text = `纬度: ${result.value.lat}, 经度: ${result.value.lon}`
    } else if (result.value.type === 'dms') {
        text = `纬度: ${result.value.lat}, 经度: ${result.value.lon}`
    } else if (result.value.type === 'crs') {
        text = `${result.value.lon.toFixed(8)}, ${result.value.lat.toFixed(8)}`
    } else if (result.value.type === 'proj_plane') {
        text = `X (北移): ${result.value.northing.toFixed(4)}, Y (东移): ${result.value.easting.toFixed(4)}`
    } else {
        text = `${result.value.lng.toFixed(8)}, ${result.value.lat.toFixed(8)}`
    }

    navigator.clipboard.writeText(text).then(() => {
        alert('已复制到剪贴板！')
    })
}

// === Bulk Excel Conversion ===

const downloadTemplate = (type) => {
    let wsData = []
    let filename = ''
    if (type === 'toPlane') {
        wsData = [['点名', '经度', '纬度', '分带类型(3/6)', 'X包含带号(1/0)'], ['pt1', 116.397451, 39.909235, 3, 1]]
        filename = '经纬度转平面模板.xlsx'
    } else if (type === 'toLngLat') {
        wsData = [['点名', 'X坐标(北移)', 'Y坐标(东移)', '分带类型(3/6)', '手动带号'], ['pt1', 4419519.82, 39533966.82, 3, '']]
        filename = '平面转经纬度模板.xlsx'
    } else if (type === 'toDecimal') {
        wsData = [['点名', '纬度度', '纬度分', '纬度秒', '纬度方向(N/S)', '经度度', '经度分', '经度秒', '经度方向(E/W)'], ['pt1', 39, 54, 27, 'N', 116, 23, 50, 'E']]
        filename = '度分秒转十进制模板.xlsx'
    } else if (type === 'toDms') {
        wsData = [['点名', '纬度(十进制)', '经度(十进制)'], ['pt1', 39.9075, 116.3972]]
        filename = '十进制转度分秒模板.xlsx'
    }
    
    const ws = xlsx.utils.aoa_to_sheet(wsData)
    const wb = xlsx.utils.book_new()
    xlsx.utils.book_append_sheet(wb, ws, "Sheet1")
    xlsx.writeFile(wb, filename)
}

const handleFileUpload = (e) => {
    const file = e.target.files[0]
    if (!file) return
    
    const reader = new FileReader()
    reader.onload = (evt) => {
        try {
            const data = evt.target.result
            const wb = xlsx.read(data, { type: 'binary' })
            const wsName = wb.SheetNames[0]
            const ws = wb.Sheets[wsName]
            const json = xlsx.utils.sheet_to_json(ws)
            if (json.length === 0) return alert('Excel无数据')

            // 识别是哪种模式 (通过列名)
            const first = json[0]
            const isToDecimal = '纬度度' in first
            const isToDms = '纬度(十进制)' in first || '经度(十进制)' in first
            const isToPlane = !isToDecimal && !isToDms && ('经度' in first || '经度(Lon)' in first)
            const isToLngLat = 'X坐标(北移)' in first || 'X坐标' in first

            const resultData = []

            for (let i = 0; i < json.length; i++) {
                const row = json[i]
                const name = row['点名'] || `Point${i+1}`
                const zoneType = parseInt(row['分带类型(3/6)'] || projConfig.value.zoneType)
                
                if (isToDecimal) {
                    const latDeg = parseFloat(row['纬度度']) || 0
                    const latMin = parseFloat(row['纬度分']) || 0
                    const latSec = parseFloat(row['纬度秒']) || 0
                    const latDir = row['纬度方向(N/S)'] || 'N'
                    
                    const lonDeg = parseFloat(row['经度度']) || 0
                    const lonMin = parseFloat(row['经度分']) || 0
                    const lonSec = parseFloat(row['经度秒']) || 0
                    const lonDir = row['经度方向(E/W)'] || 'E'
                    
                    try {
                        let latDec = dmsToDecimal(latDeg, latMin, latSec)
                        if (latDir.toUpperCase() === 'S') latDec = -latDec
                        let lonDec = dmsToDecimal(lonDeg, lonMin, lonSec)
                        if (lonDir.toUpperCase() === 'W') lonDec = -lonDec
                        
                        resultData.push({
                            ...row,
                            '点名': name,
                            '纬度(十进制)': latDec.toFixed(8),
                            '经度(十进制)': lonDec.toFixed(8)
                        })
                    } catch (err) {
                        resultData.push({ ...row, '点名': name, '错误': err.message })
                    }
                } else if (isToDms) {
                    const latDec = parseFloat(row['纬度(十进制)'])
                    const lonDec = parseFloat(row['经度(十进制)'])
                    
                    if (!isNaN(latDec) && !isNaN(lonDec)) {
                        try {
                            resultData.push({
                                ...row,
                                '点名': name,
                                '纬度(度分秒)': formatCoordinate(latDec, 'lat'),
                                '经度(度分秒)': formatCoordinate(lonDec, 'lon')
                            })
                        } catch (err) {
                            resultData.push({ ...row, '点名': name, '错误': err.message })
                        }
                    }
                } else if (isToPlane) {
                    const lng = parseFloat(row['经度']) || parseFloat(row['经度(Lon)'])
                    const lat = parseFloat(row['纬度']) || parseFloat(row['纬度(Lat)'])
                    const withZone = (row['X包含带号(1/0)'] !== undefined) ? (parseInt(row['X包含带号(1/0)']) === 1) : true
                    
                    if (lng && lat) {
                        try {
                            const res = projectToPlane(lng, lat, zoneType, withZone)
                            resultData.push({
                                ...row,
                                '点名': name,
                                '经度': lng,
                                '纬度': lat,
                                'X坐标(北移/Northing)': res.northing.toFixed(4),
                                'Y坐标(东移/Easting)': res.easting.toFixed(4),
                                '带号': res.zone,
                                '中央子午线': res.meridian
                            })
                        } catch (err) {
                            resultData.push({ ...row, '点名': name, '错误': err.message })
                        }
                    }
                } else if (isToLngLat) {
                    const northing = parseFloat(row['X坐标(北移)']) || parseFloat(row['X坐标'])
                    const easting = parseFloat(row['Y坐标(东移)']) || parseFloat(row['Y坐标'])
                    const manualZone = row['手动带号'] ? parseInt(row['手动带号']) : null
                    
                    const withZone = easting > 1000000 
                    
                    if (northing && easting) {
                        try {
                            const res = unprojectToLngLat(easting, northing, zoneType, withZone, manualZone)
                            resultData.push({
                                ...row,
                                '点名': name,
                                'X坐标(北)': northing,
                                'Y坐标(东)': easting,
                                '经度': res.lng.toFixed(8),
                                '纬度': res.lat.toFixed(8),
                                '带号': res.zone,
                                '中央子午线': res.meridian
                            })
                        } catch (err) {
                            resultData.push({ ...row, '点名': name, '错误': err.message })
                        }
                    }
                }
            }

            const newWs = xlsx.utils.json_to_sheet(resultData)
            const newWb = xlsx.utils.book_new()
            xlsx.utils.book_append_sheet(newWb, newWs, "转换结果")
            xlsx.writeFile(newWb, `坐标转换结果_${Date.now()}.xlsx`)
            
            // clear input
            e.target.value = ''

        } catch (err) {
            alert('文件解析失败: ' + err.message)
        }
    }
    reader.readAsArrayBuffer(file)
}
</script>

<style scoped>
.container.pb-2xl {
    padding-bottom: 4rem;
}

.tool-header {
    text-align: center;
    margin-bottom: var(--spacing-xl);
}

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--text-secondary);
    text-decoration: none;
    margin-bottom: var(--spacing-md);
    transition: color var(--transition-base);
}

.back-link:hover {
    color: var(--primary);
}

/* --- Tabs Styling --- */
.tabs-wrapper {
    margin-bottom: var(--spacing-xl);
}

.tabs-header {
    display: flex;
    overflow-x: auto;
    border-bottom: 2px solid var(--border-color);
    margin-bottom: var(--spacing-lg);
    scrollbar-width: none; /* Firefox */
}
.tabs-header::-webkit-scrollbar {
    display: none; /* Chrome/Safari */
}

.tab-btn {
    display: flex;
    align-items: center;
    padding: var(--spacing-md) var(--spacing-lg);
    background: transparent;
    border: none;
    border-bottom: 3px solid transparent;
    color: var(--text-secondary);
    font-size: var(--font-size-md);
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: all var(--transition-base);
    margin-bottom: -2px;
}

.tab-btn:hover {
    color: var(--primary);
    background: var(--bg-secondary);
}

.tab-btn.active {
    color: var(--primary);
    border-bottom-color: var(--primary);
}

.mr-xs {
    margin-right: 4px;
}
.mb-lg {
    margin-bottom: var(--spacing-lg);
}
.max-w-3xl {
    max-width: 768px;
}
.mx-auto {
    margin-left: auto;
    margin-right: auto;
}
.text-center {
    text-align: center;
}

.flex-center {
    display: flex;
    align-items: center;
    justify-content: center;
}

.flex-col {
    display: flex;
    flex-direction: column;
}

.flex-1 {
    flex: 1;
}

.dms-input {
    display: flex;
    gap: var(--spacing-xs);
}

.dms-input .input {
    width: 0;
    flex: 1;
}

.px-xs {
    padding-left: var(--spacing-xs);
    padding-right: var(--spacing-xs);
}

.icon-sm { width: 16px; height: 16px; }
.icon-md { width: 20px; height: 20px; }
.icon-lg { width: 24px; height: 24px; vertical-align: bottom; }
.icon-xl { width: 48px; height: 48px; }

.checkbox-label {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    cursor: pointer;
}

.result-box {
    background: var(--bg-secondary);
    padding: var(--spacing-md);
    border-radius: var(--border-radius-sm);
    border-left: 4px solid var(--primary);
}

.result-box p {
    margin: var(--spacing-xs) 0;
    font-family: monospace;
    font-size: var(--font-size-md);
}

.btn-full { width: 100%; }
.text-success { color: #10b981; }

.upload-area {
    margin-top: var(--spacing-lg);
}

.upload-label {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem 1rem;
    background: var(--bg-tertiary);
    border: 2px dashed var(--border-color);
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: all var(--transition-base);
    color: var(--text-secondary);
}

.upload-label:hover {
    border-color: var(--primary);
    background: var(--bg-secondary);
}

.hidden {
    display: none;
}

</style>
