斗數起盤

<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>信陵文化斗數排盤</title>
    
    <!-- 載入 Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    
    <!-- 載入 React 和 ReactDOM -->
    <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    
    <!-- 載入 Babel (用於解析 JSX) -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <!-- 設定列印樣式 -->
    <style>
        @media print {
          @page {
            size: A4 portrait;
            margin: 10mm;
          }
          body {
            background: white;
            -webkit-print-color-adjust: exact;
          }
          .print-hidden {
            display: none !important;
          }
          .no-print-border {
            border: none !important;
          }
        }
        .writing-vertical-rl {
          writing-mode: vertical-rl;
          text-orientation: upright;
        }
    </style>
</head>
<body class="bg-stone-100 text-stone-900">

    <div id="root"></div>

    <script type="text/babel">
        const { useState, useEffect } = React;

        // --- 圖示組件 (SVG) ---
        const Printer = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg>
        );
        const Settings = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
        );
        const Info = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
        );
        const Moon = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
        );

        // --- 基礎數據定義 ---
        const TIAN_GAN = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
        const DI_ZHI = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
        const PALACE_NAMES = ['命宮', '兄弟', '夫妻', '子女', '財帛', '疾厄', '遷移', '交友', '官祿', '田宅', '福德', '父母'];
        const FIVE_ELEMENTS = { 2: '水二局', 3: '木三局', 4: '金四局', 5: '土五局', 6: '火六局' };
        const ZIWEI_SERIES = ['紫微', '天機', null, '太陽', '武曲', '天同', null, null, '廉貞'];
        const TIANFU_SERIES = ['天府', '太陰', '貪狼', '巨門', '天相', '天梁', '七殺', null, null, null, '破軍'];
        
        const SI_HUA = {
            '甲': { 祿: '廉貞', 權: '破軍', 科: '武曲', 忌: '太陽' },
            '乙': { 祿: '天機', 權: '天梁', 科: '紫微', 忌: '太陰' },
            '丙': { 祿: '天同', 權: '天機', 科: '文昌', 忌: '廉貞' },
            '丁': { 祿: '太陰', 權: '天同', 科: '天機', 忌: '巨門' },
            '戊': { 祿: '貪狼', 權: '太陰', 科: '右弼', 忌: '天機' },
            '己': { 祿: '武曲', 權: '貪狼', 科: '天梁', 忌: '文曲' },
            '庚': { 祿: '太陽', 權: '武曲', 科: '太陰', 忌: '天同' },
            '辛': { 祿: '巨門', 權: '太陽', 科: '文曲', 忌: '文昌' },
            '壬': { 祿: '天梁', 權: '紫微', 科: '左輔', 忌: '武曲' },
            '癸': { 祿: '破軍', 權: '巨門', 科: '太陰', 忌: '貪狼' },
        };

        // --- 工具函數 ---
        const getGanIdx = (gan) => TIAN_GAN.indexOf(gan);
        const getZhiIdx = (zhi) => DI_ZHI.indexOf(zhi);
        
        const getMonthGan = (yearGanIdx, monthZhiIdx) => {
            const base = (yearGanIdx % 5) * 2 + 2; 
            let offset = (getZhiIdx(monthZhiIdx) - 2 + 12) % 12;
            return TIAN_GAN[(base + offset) % 10];
        };

        const getMingShen = (month, hourZhi) => {
            const startZhi = 2; 
            const hourIdx = getZhiIdx(hourZhi);
            let mingPos = (startZhi + (month - 1) - hourIdx + 12) % 12;
            let shenPos = (startZhi + (month - 1) + hourIdx) % 12;
            return { mingPos, shenPos };
        };

        const getBureau = (mingGan, mingZhi) => {
            const mingGanIdx = getGanIdx(mingGan);
            const mingZhiIdx = getZhiIdx(mingZhi);
            const elementMap = [
                [4, 2, 6, 5, 3], [2, 6, 5, 3, 4], [6, 5, 3, 4, 2], [5, 3, 4, 2, 6], [3, 4, 2, 6, 5]
            ];
            const row = Math.floor(mingGanIdx / 2);
            const col = Math.floor(mingZhiIdx / 2) % 5; 
            return elementMap[row][col];
        };

        const getZiweiPos = (bureau, day) => {
            let pos = 2; 
            let quotient, remainder;
            if (day % bureau === 0) {
                quotient = day / bureau;
                remainder = 0;
            } else {
                quotient = Math.floor(day / bureau) + 1;
                remainder = day % bureau;
            }
            let basePos = (2 + (quotient - 1)) % 12;
            if (remainder === 0) {
                pos = basePos;
            } else {
                const makeup = bureau - remainder;
                if (makeup % 2 === 0) pos = (basePos + makeup) % 12;
                else pos = (basePos - makeup + 12) % 12;
            }
            return pos;
        };

        const getTianfuPos = (ziweiPos) => {
            const map = {0:4, 1:3, 2:2, 3:1, 4:0, 5:11, 6:10, 7:9, 8:8, 9:7, 10:6, 11:5};
            return map[ziweiPos];
        };

        const getChangQu = (hourZhi) => {
            const hIdx = getZhiIdx(hourZhi);
            return { chang: (10 - hIdx + 12) % 12, qu: (4 + hIdx) % 12 };
        };

        const getZuoYou = (month) => {
            return { zuo: (4 + (month - 1)) % 12, you: (10 - (month - 1) + 12) % 12 };
        };

        const getDaXian = (mingPos, bureau, gender, yearGan) => {
            const yearGanIdx = getGanIdx(yearGan);
            const isYangYear = yearGanIdx % 2 === 0;
            const isMale = gender === 'M';
            let isClockwise = false;
            if ((isMale && isYangYear) || (!isMale && !isYangYear)) isClockwise = true;

            const ranges = [];
            for (let i = 0; i < 12; i++) {
                let pos = isClockwise ? (mingPos + i) % 12 : (mingPos - i + 12) % 12;
                let startAge = bureau + (i * 10);
                let endAge = startAge + 9;
                ranges.push({ pos, text: `${startAge}-${endAge}` });
            }
            return ranges;
        };

        // --- 主程式組件 ---
        function ZwdsApp() {
            const [inputData, setInputData] = useState({
                name: '某人', gender: 'M', lunarYear: 1990, lunarMonth: 1, lunarDay: 15,
                birthHour: '子', yearGan: '庚', yearZhi: '午', currentYear: new Date().getFullYear(),
            });
            
            const [chartData, setChartData] = useState(null);
            const [showPrintMode, setShowPrintMode] = useState(false);

            const calculateGanZhiYear = (year) => {
                const gan = TIAN_GAN[(year - 4) % 10];
                const zhi = DI_ZHI[(year - 4) % 12];
                return { gan, zhi };
            };

            const handleGenerate = () => {
                const { lunarMonth, lunarDay, birthHour, yearGan, yearZhi, gender } = inputData;
                const { mingPos, shenPos } = getMingShen(parseInt(lunarMonth), birthHour);
                const yearGanIdx = getGanIdx(yearGan);
                const mingPalaceGan = getMonthGan(yearGanIdx, DI_ZHI[mingPos]);
                const bureauVal = getBureau(mingPalaceGan, DI_ZHI[mingPos]);
                const bureauName = FIVE_ELEMENTS[bureauVal];
                
                const zwPos = getZiweiPos(bureauVal, parseInt(lunarDay));
                const tfPos = getTianfuPos(zwPos);
                const { chang, qu } = getChangQu(birthHour);
                const { zuo, you } = getZuoYou(parseInt(lunarMonth));
                const daXian = getDaXian(mingPos, bureauVal, gender, yearGan);

                const cells = Array(12).fill(null).map((_, idx) => ({
                    id: idx, zhi: DI_ZHI[idx], gan: getMonthGan(yearGanIdx, DI_ZHI[idx]),
                    stars: [], minorStars: [], name: '', isShen: idx === shenPos, daXian: '', liuNian: false,
                }));

                for (let i = 0; i < 12; i++) {
                    const palaceIdx = (mingPos - i + 12) % 12;
                    cells[palaceIdx].name = PALACE_NAMES[i];
                }

                daXian.forEach(d => { cells[d.pos].daXian = d.text; });

                ZIWEI_SERIES.forEach((star, i) => {
                    if (star) {
                        const pos = (zwPos - i + 12) % 12;
                        cells[pos].stars.push({ name: star, type: 'major', group: 'ziwei' });
                    }
                });

                TIANFU_SERIES.forEach((star, i) => {
                    if (star) {
                        const pos = (tfPos + i) % 12;
                        cells[pos].stars.push({ name: star, type: 'major', group: 'tianfu' });
                    }
                });

                cells[chang].minorStars.push({ name: '文昌', type: 'good' });
                cells[qu].minorStars.push({ name: '文曲', type: 'good' });
                cells[zuo].minorStars.push({ name: '左輔', type: 'good' });
                cells[you].minorStars.push({ name: '右弼', type: 'good' });

                const luCunMap = {'甲':2, '乙':3, '丙':5, '丁':6, '戊':5, '己':6, '庚':8, '辛':9, '壬':11, '癸':0};
                const luPos = luCunMap[yearGan];
                if (luPos !== undefined) cells[luPos].minorStars.push({name: '祿存', type: 'good'});
                if (luPos !== undefined) {
                    cells[(luPos + 1) % 12].minorStars.push({name: '擎羊', type: 'bad'});
                    cells[(luPos - 1 + 12) % 12].minorStars.push({name: '陀羅', type: 'bad'});
                }

                const siHuaYear = SI_HUA[yearGan];
                cells.forEach(cell => {
                    cell.stars.forEach(star => {
                        Object.entries(siHuaYear).forEach(([hua, starName]) => {
                            if (star.name === starName) {
                                star.hua = hua;
                                star.huaType = 'year';
                            }
                        });
                    });
                });

                setChartData({ cells, info: { bureau: bureauName, mingGan: mingPalaceGan, mingZhi: DI_ZHI[mingPos], mingPos: mingPos } });
            };

            useEffect(() => {
                const gz = calculateGanZhiYear(inputData.lunarYear);
                setInputData(prev => ({...prev, yearGan: gz.gan, yearZhi: gz.zhi}));
            }, [inputData.lunarYear]);

            const getLiuNianData = () => {
                if (!chartData) return null;
                const currentGZ = calculateGanZhiYear(inputData.currentYear);
                const liuNianZhiIdx = getZhiIdx(currentGZ.zhi);
                const newCells = JSON.parse(JSON.stringify(chartData.cells));
                newCells[liuNianZhiIdx].isLiuNianMing = true;
                const siHuaLiu = SI_HUA[currentGZ.gan];
                newCells.forEach(cell => {
                    cell.stars.forEach(star => {
                        Object.entries(siHuaLiu).forEach(([hua, starName]) => {
                            if (star.name === starName) star.liuHua = hua;
                        });
                    });
                    cell.minorStars.forEach(star => {
                        Object.entries(siHuaLiu).forEach(([hua, starName]) => {
                            if (star.name === starName) star.liuHua = hua;
                        });
                    });
                });
                return { cells: newCells, gan: currentGZ.gan, zhi: currentGZ.zhi };
            };

            const renderData = showPrintMode || chartData ? (getLiuNianData() || chartData) : null;
            const displayCells = renderData ? renderData.cells : [];

            const gridMapping = [
                { zhiIdx: 5, r: 1, c: 1 }, { zhiIdx: 6, r: 1, c: 2 }, { zhiIdx: 7, r: 1, c: 3 }, { zhiIdx: 8, r: 1, c: 4 },
                { zhiIdx: 4, r: 2, c: 1 },                                                     { zhiIdx: 9, r: 2, c: 4 },
                { zhiIdx: 3, r: 3, c: 1 },                                                     { zhiIdx: 10, r: 3, c: 4 },
                { zhiIdx: 2, r: 4, c: 1 }, { zhiIdx: 1, r: 4, c: 2 }, { zhiIdx: 0, r: 4, c: 3 }, { zhiIdx: 11, r: 4, c: 4 },
            ];

            const renderCell = (zhiIdx) => {
                const cell = displayCells[zhiIdx];
                if (!cell) return null;

                return (
                    <div className={`relative h-full border border-stone-400 bg-stone-50 p-1 flex flex-col justify-between print:border-stone-800 ${cell.isLiuNianMing ? 'bg-yellow-50 ring-2 ring-yellow-400 ring-inset print:ring-0 print:bg-stone-50' : ''}`}>
                        <div className="flex flex-wrap gap-0.5 text-[10px] text-stone-500 leading-tight">
                           {cell.minorStars.map((s, i) => (
                             <span key={i} className={`${s.type === 'bad' ? 'text-red-400' : 'text-blue-400'} flex items-center`}>
                               {s.name}
                               {s.liuHua && <span className="ml-[1px] text-[8px] bg-red-600 text-white px-[1px] rounded">{s.liuHua}</span>}
                             </span>
                           ))}
                        </div>

                        <div className="flex flex-col items-center justify-center gap-1 my-1">
                          {cell.stars.map((star, i) => (
                            <div key={i} className={`font-bold text-lg writing-vertical-rl tracking-widest ${star.group === 'ziwei' ? 'text-purple-700' : 'text-indigo-700'} relative`}>
                              {star.name}
                              {star.hua && (
                                <span className={`absolute -right-3 top-2 text-[10px] rounded-full px-1 text-white w-4 h-4 flex items-center justify-center ${star.hua === '祿' ? 'bg-green-600' : star.hua === '權' ? 'bg-red-600' : star.hua === '科' ? 'bg-blue-600' : 'bg-stone-800'}`}>
                                  {star.hua}
                                </span>
                              )}
                              {star.liuHua && (
                                <span className={`absolute -left-3 top-4 text-[10px] rounded-full px-1 text-white w-4 h-4 flex items-center justify-center border border-white shadow-sm z-10 ${star.liuHua === '祿' ? 'bg-green-500' : star.liuHua === '權' ? 'bg-red-500' : star.liuHua === '科' ? 'bg-blue-500' : 'bg-black'}`}>
                                  {star.liuHua}
                                </span>
                              )}
                            </div>
                          ))}
                          {cell.stars.length === 0 && <span className="text-stone-300 text-xs py-4">空宮</span>}
                        </div>

                        <div className="mt-auto">
                            <div className="flex justify-between items-end border-t border-stone-200 pt-1">
                                <div className="flex flex-col items-start">
                                    <span className="text-[10px] font-mono text-stone-400">{cell.gan}</span>
                                    <span className="text-sm font-bold text-red-800">{cell.zhi}</span>
                                </div>
                                <div className="flex flex-col items-center">
                                   {cell.isShen && <span className="text-[10px] bg-stone-200 px-1 rounded text-stone-600 mb-0.5">身宮</span>}
                                   {cell.isLiuNianMing && <span className="text-[10px] bg-yellow-200 px-1 rounded text-stone-700 mb-0.5 print:border print:border-stone-800">流命</span>}
                                   <span className="font-serif text-base bg-red-50 px-1 text-red-900 rounded print:bg-transparent print:text-black">{cell.name}</span>
                                </div>
                                <div className="flex flex-col items-end">
                                    <span className="text-[9px] text-stone-400">大限</span>
                                    <span className="text-xs font-mono text-stone-600">{cell.daXian}</span>
                                </div>
                            </div>
                        </div>
                    </div>
                );
            };

            return (
                <div className="min-h-screen font-sans pb-10 print:pb-0">
                    {/* Header */}
                    <div className="bg-purple-900 text-white p-4 shadow-md print-hidden">
                        <div className="max-w-5xl mx-auto flex justify-between items-center">
                            <h1 className="text-xl font-bold flex items-center gap-2">
                                <Moon size={20} /> 信陵文化斗數排盤 (南派)
                            </h1>
                            <div className="flex gap-3">
                                <button onClick={() => window.print()} className="flex items-center gap-1 bg-purple-700 hover:bg-purple-600 px-3 py-1.5 rounded text-sm transition-colors">
                                    <Printer size={16} /> 列印 / 存為PDF
                                </button>
                            </div>
                        </div>
                    </div>

                    <div className="max-w-5xl mx-auto mt-6 px-4 print:px-0 print:mt-0">
                        {/* Input Section */}
                        <div className="bg-white p-6 rounded-xl shadow-sm mb-6 border border-stone-200 print-hidden">
                            <div className="flex items-center gap-2 mb-4 border-b pb-2 border-stone-100">
                                <Settings size={18} className="text-stone-400" />
                                <h2 className="font-bold text-stone-700">命盤設定</h2>
                            </div>
                            <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-stone-500">姓名</label>
                                    <input type="text" value={inputData.name} onChange={(e) => setInputData({...inputData, name: e.target.value})} className="w-full border border-stone-300 rounded px-2 py-1.5 focus:outline-none focus:border-purple-500" />
                                </div>
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-stone-500">性別</label>
                                    <select value={inputData.gender} onChange={(e) => setInputData({...inputData, gender: e.target.value})} className="w-full border border-stone-300 rounded px-2 py-1.5">
                                        <option value="M">男</option>
                                        <option value="F">女</option>
                                    </select>
                                </div>
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-stone-500">農曆生年 (西元)</label>
                                    <input type="number" value={inputData.lunarYear} onChange={(e) => setInputData({...inputData, lunarYear: parseInt(e.target.value)})} className="w-full border border-stone-300 rounded px-2 py-1.5" />
                                </div>
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-stone-500">農曆月/日</label>
                                    <div className="flex gap-2">
                                        <select className="flex-1 border border-stone-300 rounded px-2 py-1.5" value={inputData.lunarMonth} onChange={(e) => setInputData({...inputData, lunarMonth: e.target.value})}>
                                            {Array.from({length: 12}, (_, i) => i + 1).map(m => <option key={m} value={m}>{m}月</option>)}
                                        </select>
                                        <select className="flex-1 border border-stone-300 rounded px-2 py-1.5" value={inputData.lunarDay} onChange={(e) => setInputData({...inputData, lunarDay: e.target.value})}>
                                            {Array.from({length: 30}, (_, i) => i + 1).map(d => <option key={d} value={d}>{d}日</option>)}
                                        </select>
                                    </div>
                                </div>
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-stone-500">生時 (地支)</label>
                                    <select value={inputData.birthHour} onChange={(e) => setInputData({...inputData, birthHour: e.target.value})} className="w-full border border-stone-300 rounded px-2 py-1.5">
                                        {DI_ZHI.map(z => <option key={z} value={z}>{z}時</option>)}
                                    </select>
                                </div>
                                <div className="space-y-1">
                                    <label className="text-xs font-bold text-stone-500">生年干支 (自動/手動)</label>
                                    <div className="flex gap-1">
                                        <select value={inputData.yearGan} onChange={(e) => setInputData({...inputData, yearGan: e.target.value})} className="w-1/2 border rounded px-1">
                                            {TIAN_GAN.map(g => <option key={g} value={g}>{g}</option>)}
                                        </select>
                                        <select value={inputData.yearZhi} onChange={(e) => setInputData({...inputData, yearZhi: e.target.value})} className="w-1/2 border rounded px-1">
                                            {DI_ZHI.map(z => <option key={z} value={z}>{z}</option>)}
                                        </select>
                                    </div>
                                </div>
                                <div className="col-span-1 md:col-span-2 flex items-end">
                                    <button onClick={handleGenerate} className="w-full bg-purple-700 hover:bg-purple-800 text-white font-bold py-2 px-4 rounded transition-colors shadow-sm">起盤 / 更新</button>
                                </div>
                            </div>
                            <div className="mt-4 pt-4 border-t border-stone-100 text-xs text-stone-500 flex gap-2 items-center">
                                <Info size={14} />
                                <span>註:本系統採用南派設定。為求精確,請直接輸入農曆生日,系統不會自動進行節氣換算。</span>
                            </div>
                        </div>

                        {/* Chart Display */}
                        {displayCells.length > 0 && (
                            <div className="bg-white shadow-2xl print:shadow-none max-w-4xl mx-auto aspect-square md:aspect-auto md:h-[900px] print:h-[260mm] print:w-[190mm] flex flex-col relative overflow-hidden border-4 border-stone-800 print:border-2 print:mt-0">
                                <div className="grid grid-rows-4 grid-cols-4 h-full w-full">
                                    {gridMapping.map((map) => (
                                        <div key={map.zhiIdx} style={{ gridRow: map.r, gridColumn: map.c }} className="w-full h-full">
                                            {renderCell(map.zhiIdx)}
                                        </div>
                                    ))}
                                    <div className="row-start-2 row-span-2 col-start-2 col-span-2 flex flex-col p-6 print:p-4 justify-center border border-stone-200 no-print-border">
                                        <div className="text-center mb-6">
                                            <h2 className="text-3xl font-serif font-bold text-stone-800 tracking-widest mb-2">{inputData.name} 命盤</h2>
                                            <div className="h-px w-24 bg-red-800 mx-auto"></div>
                                        </div>
                                        <div className="grid grid-cols-2 gap-4 text-sm text-stone-700 font-serif">
                                            <div className="text-right text-stone-500">農曆生辰:</div>
                                            <div className="font-bold">{inputData.yearGan}{inputData.yearZhi} 年 {inputData.lunarMonth} 月 {inputData.lunarDay} 日 {inputData.birthHour} 時</div>
                                            <div className="text-right text-stone-500">五行局:</div>
                                            <div className="font-bold text-red-800">{chartData?.info.bureau}</div>
                                            <div className="text-right text-stone-500">命主:</div>
                                            <div className="font-bold">{inputData.gender === 'M' ? '乾造' : '坤造'}</div>
                                        </div>
                                        <div className="mt-8 border-t border-stone-200 pt-4">
                                            <div className="flex flex-col items-center gap-2">
                                                <div className="text-xs font-bold text-stone-400 uppercase tracking-widest print-hidden">Current Flow</div>
                                                <div className="flex items-center gap-4">
                                                    <button onClick={() => setInputData(p => ({...p, currentYear: p.currentYear - 1}))} className="print-hidden p-1 rounded-full hover:bg-stone-100">←</button>
                                                    <div className="text-xl font-bold text-purple-800 border-b-2 border-purple-200 px-2">流年 {renderData.gan}{renderData.zhi} ({inputData.currentYear})</div>
                                                    <button onClick={() => setInputData(p => ({...p, currentYear: p.currentYear + 1}))} className="print-hidden p-1 rounded-full hover:bg-stone-100">→</button>
                                                </div>
                                                <p className="text-[10px] text-stone-400 mt-1 print-hidden">切換年份查看流年四化及命宮位置</p>
                                            </div>
                                        </div>
                                        <div className="mt-auto text-center opacity-30">
                                            <span className="font-serif text-4xl">信陵文化</span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        )}
                    </div>
                </div>
            );
        }

        const root = ReactDOM.createRoot(document.getElementById('root'));
        root.render(<ZwdsApp />);
    </script>
</body>
</html>