diff --git a/miniprogram/app.json b/miniprogram/app.json index 17cef4e..40a733c 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -4,10 +4,10 @@ "pages/overview/overview" ], "window": { - "navigationBarTitleText": "汇率换算", - "navigationBarBackgroundColor": "#FFFFFF", - "navigationBarTextStyle": "black", - "backgroundColor": "#F5F5F5", + "navigationBarTitleText": "", + "navigationBarBackgroundColor": "#0B1120", + "navigationBarTextStyle": "white", + "backgroundColor": "#0B1120", "backgroundTextStyle": "dark" }, "style": "v2", diff --git a/miniprogram/app.wxss b/miniprogram/app.wxss index e1b7f2a..d2d7a6e 100644 --- a/miniprogram/app.wxss +++ b/miniprogram/app.wxss @@ -1,19 +1,23 @@ page { - background: linear-gradient(180deg, #EEF2FF 0%, #F5F5F5 320rpx); - color: #1E293B; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: #0B1120; + color: #E2E8F0; + font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif; font-size: 28rpx; line-height: 1.6; } .container { - padding: 32rpx; - padding-top: 24rpx; + min-height: 100vh; + padding: 24rpx 28rpx; + background: + radial-gradient(ellipse at 20% 0%, rgba(59, 130, 246, 0.08) 0%, transparent 50%), + radial-gradient(ellipse at 80% 100%, rgba(168, 85, 247, 0.06) 0%, transparent 50%), + #0B1120; } .card { - background-color: #FFFFFF; - border-radius: 24rpx; + background: rgba(30, 41, 59, 0.7); + border: 2rpx solid rgba(148, 163, 184, 0.1); + border-radius: 28rpx; margin-bottom: 24rpx; - box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06); } diff --git a/miniprogram/components/currency-picker/currency-picker.js b/miniprogram/components/currency-picker/currency-picker.js new file mode 100644 index 0000000..989fdbe --- /dev/null +++ b/miniprogram/components/currency-picker/currency-picker.js @@ -0,0 +1,24 @@ +Component({ + properties: { + show: { type: Boolean, value: false }, + list: { type: Array, value: [] }, + current: { type: Number, value: 0 }, + }, + + methods: { + handleSelect(e) { + const index = e.currentTarget.dataset.index; + this.triggerEvent('select', { value: index }); + }, + + handleClose() { + this.triggerEvent('close'); + }, + + handleMaskTap() { + this.triggerEvent('close'); + }, + + preventBubble() {}, + }, +}); diff --git a/miniprogram/components/currency-picker/currency-picker.json b/miniprogram/components/currency-picker/currency-picker.json new file mode 100644 index 0000000..a89ef4d --- /dev/null +++ b/miniprogram/components/currency-picker/currency-picker.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} diff --git a/miniprogram/components/currency-picker/currency-picker.wxml b/miniprogram/components/currency-picker/currency-picker.wxml new file mode 100644 index 0000000..d50ff2f --- /dev/null +++ b/miniprogram/components/currency-picker/currency-picker.wxml @@ -0,0 +1,20 @@ + + + + 选择货币 + + + + + {{item}} + + + + + diff --git a/miniprogram/components/currency-picker/currency-picker.wxss b/miniprogram/components/currency-picker/currency-picker.wxss new file mode 100644 index 0000000..51d6e31 --- /dev/null +++ b/miniprogram/components/currency-picker/currency-picker.wxss @@ -0,0 +1,84 @@ +.picker-mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.6); + z-index: 1000; + display: flex; + align-items: flex-end; +} + +.picker-sheet { + width: 100%; + max-height: 70vh; + background: #1E293B; + border-top-left-radius: 36rpx; + border-top-right-radius: 36rpx; + border-top: 2rpx solid rgba(148, 163, 184, 0.15); + padding-bottom: env(safe-area-inset-bottom); +} + +.sheet-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 36rpx 40rpx 24rpx; + border-bottom: 2rpx solid rgba(148, 163, 184, 0.08); +} + +.sheet-title { + font-size: 34rpx; + font-weight: 700; + color: #F1F5F9; + letter-spacing: 2rpx; +} + +.sheet-close { + font-size: 32rpx; + color: #64748B; + width: 64rpx; + height: 64rpx; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background: rgba(148, 163, 184, 0.08); +} + +.sheet-scroll { + max-height: 56vh; + padding: 12rpx 0; +} + +.sheet-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 28rpx 40rpx; + margin: 0 16rpx; + border-radius: 16rpx; +} + +.sheet-item-active { + background: rgba(99, 102, 241, 0.12); + border: 2rpx solid rgba(99, 102, 241, 0.25); +} + +.item-text { + font-size: 30rpx; + color: #CBD5E1; + font-weight: 500; +} + +.sheet-item-active .item-text { + color: #A5B4FC; + font-weight: 600; +} + +.item-check { + font-size: 30rpx; + color: #818CF8; + font-weight: 700; +} diff --git a/miniprogram/pages/index/index.js b/miniprogram/pages/index/index.js index 397d820..ca43564 100644 --- a/miniprogram/pages/index/index.js +++ b/miniprogram/pages/index/index.js @@ -2,8 +2,8 @@ const { CURRENCIES, getPickerData } = require('../../utils/currencies'); const { getRates, convert, formatAmount, formatRate } = require('../../utils/rate'); const pickerData = getPickerData(); -const DEFAULT_FROM = 0; // CNY -const DEFAULT_TO = 1; // USD +const DEFAULT_FROM = 0; +const DEFAULT_TO = 1; Page({ data: { @@ -18,7 +18,9 @@ Page({ loading: true, error: '', rates: null, - baseCurrency: 'CNY', + // picker state + showPicker: false, + pickerTarget: '', // 'from' or 'to' }, onLoad() { @@ -35,23 +37,15 @@ Page({ this.setData({ loading: true, error: '' }); try { const { rates, updatedAt } = await getRates('CNY'); - this.setData({ - rates, - baseCurrency: 'CNY', - updatedAt, - loading: false, - }); + this.setData({ rates, baseCurrency: 'CNY', updatedAt, loading: false }); this.calculate(); } catch (e) { - this.setData({ - loading: false, - error: '汇率获取失败,请检查网络后下拉刷新', - }); + this.setData({ loading: false, error: '汇率获取失败,请下拉刷新重试' }); } }, calculate() { - const { rates, fromIndex, toIndex, amount, baseCurrency } = this.data; + const { rates, fromIndex, toIndex, amount } = this.data; if (!rates) return; const num = parseFloat(amount); @@ -74,33 +68,39 @@ Page({ }, handleAmountInput(e) { - const value = e.detail.value; - this.setData({ amount: value }); + this.setData({ amount: e.detail.value }); this.calculate(); }, - handleFromChange(e) { - this.setData({ fromIndex: Number(e.detail.value) }); + openFromPicker() { + this.setData({ showPicker: true, pickerTarget: 'from' }); + }, + + openToPicker() { + this.setData({ showPicker: true, pickerTarget: 'to' }); + }, + + handlePickerSelect(e) { + const index = e.detail.value; + if (this.data.pickerTarget === 'from') { + this.setData({ fromIndex: index, showPicker: false }); + } else { + this.setData({ toIndex: index, showPicker: false }); + } this.calculate(); }, - handleToChange(e) { - this.setData({ toIndex: Number(e.detail.value) }); - this.calculate(); + handlePickerClose() { + this.setData({ showPicker: false }); }, handleSwap() { const { fromIndex, toIndex } = this.data; - this.setData({ - fromIndex: toIndex, - toIndex: fromIndex, - }); + this.setData({ fromIndex: toIndex, toIndex: fromIndex }); this.calculate(); }, goOverview() { - wx.navigateTo({ - url: '/pages/overview/overview', - }); + wx.navigateTo({ url: '/pages/overview/overview' }); }, }); diff --git a/miniprogram/pages/index/index.json b/miniprogram/pages/index/index.json index 9fa0b64..65abfd9 100644 --- a/miniprogram/pages/index/index.json +++ b/miniprogram/pages/index/index.json @@ -1,5 +1,7 @@ { - "navigationBarTitleText": "汇率换算", + "navigationBarTitleText": "", "enablePullDownRefresh": true, - "usingComponents": {} + "usingComponents": { + "currency-picker": "/components/currency-picker/currency-picker" + } } diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml index a20aec9..05f41c5 100644 --- a/miniprogram/pages/index/index.wxml +++ b/miniprogram/pages/index/index.wxml @@ -1,76 +1,84 @@ - + - 💱 汇率换算 - {{updatedAt}} 更新 - 正在获取最新汇率... + + 汇率换算 + + + 实时 + + + {{updatedAt}} + 正在同步汇率数据... - - - {{pickerData[fromIndex]}} - - - + + + {{pickerData[fromIndex]}} + + - - - - + + + + - + - - - {{pickerData[toIndex]}} - - - - {{result || '—'}} + + + {{pickerData[toIndex]}} + + + {{result || '0.00'}} - - - - + + + {{unitRate}} - - + {{reverseRate}} - + - {{error}} - - - - 📊 - 查看汇率总览 + + + + 查看全部汇率 + - + + diff --git a/miniprogram/pages/index/index.wxss b/miniprogram/pages/index/index.wxss index 36ee0cf..d5dfa41 100644 --- a/miniprogram/pages/index/index.wxss +++ b/miniprogram/pages/index/index.wxss @@ -1,192 +1,225 @@ -/* ===== 顶部标题 ===== */ +/* ===== HERO ===== */ .hero { - padding: 16rpx 8rpx 24rpx; + padding: 12rpx 4rpx 28rpx; +} + +.hero-row { + display: flex; + align-items: center; + justify-content: space-between; } .hero-title { - font-size: 48rpx; + font-size: 50rpx; font-weight: 800; - color: #1E293B; - letter-spacing: 2rpx; + color: #F8FAFC; + letter-spacing: 3rpx; +} + +.hero-badge { + display: flex; + align-items: center; + background: rgba(16, 185, 129, 0.1); + border: 2rpx solid rgba(16, 185, 129, 0.2); + border-radius: 40rpx; + padding: 8rpx 20rpx; +} + +.badge-dot { + width: 12rpx; + height: 12rpx; + border-radius: 50%; + background: #10B981; + margin-right: 10rpx; + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.3; } +} + +.badge-text { + font-size: 22rpx; + color: #10B981; + font-weight: 600; } .hero-desc { font-size: 24rpx; - color: #94A3B8; + color: #475569; margin-top: 8rpx; } -/* ===== 换算主卡片 ===== */ +/* ===== CONVERTER ===== */ .converter-card { - padding: 40rpx 36rpx; + padding: 32rpx; + background: linear-gradient(160deg, rgba(30, 41, 59, 0.95) 0%, rgba(15, 23, 42, 0.98) 100%); + border: 2rpx solid rgba(148, 163, 184, 0.1); } .currency-block { + display: flex; + flex-direction: column; + align-items: center; + padding: 24rpx; border-radius: 20rpx; - padding: 28rpx; } .from-block { - background: #F8FAFC; - border: 2rpx solid #E2E8F0; + background: rgba(148, 163, 184, 0.04); + border: 2rpx solid rgba(148, 163, 184, 0.06); } .to-block { - background: linear-gradient(135deg, #EEF2FF 0%, #E0E7FF 100%); - border: 2rpx solid #C7D2FE; + background: rgba(251, 191, 36, 0.03); + border: 2rpx solid rgba(251, 191, 36, 0.08); } -.currency-tag { +.block-label { + font-size: 22rpx; + color: #475569; + font-weight: 700; + letter-spacing: 6rpx; + margin-bottom: 16rpx; +} + +.currency-chip { display: inline-flex; align-items: center; - background: #FFFFFF; - border-radius: 12rpx; - padding: 10rpx 20rpx; - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); + background: rgba(148, 163, 184, 0.06); + border: 2rpx solid rgba(148, 163, 184, 0.12); + border-radius: 14rpx; + padding: 14rpx 24rpx; + margin-bottom: 24rpx; } -.currency-tag-text { - font-size: 26rpx; - font-weight: 500; - color: #334155; +.chip-text { + font-size: 28rpx; + font-weight: 600; + color: #CBD5E1; } -.tag-arrow { - font-size: 18rpx; - color: #94A3B8; - margin-left: 10rpx; +.chip-arrow { + font-size: 28rpx; + color: #475569; + margin-left: 12rpx; } .amount-input { width: 100%; - margin-top: 20rpx; - font-size: 56rpx; + font-size: 64rpx; font-weight: 800; - color: #1E293B; - text-align: right; + color: #F1F5F9; + text-align: center; + letter-spacing: 2rpx; } .amount-placeholder { - color: #CBD5E1; - font-weight: 400; + color: #1E293B; + font-weight: 600; } -.result-display { - margin-top: 20rpx; - font-size: 56rpx; +.result-amount { + font-size: 64rpx; font-weight: 800; - color: #4F46E5; - text-align: right; + color: #FBBF24; + text-align: center; + letter-spacing: 2rpx; + text-shadow: 0 0 48rpx rgba(251, 191, 36, 0.12); } -/* ===== 互换按钮 ===== */ -.swap-wrapper { +/* ===== SWAP ===== */ +.swap-zone { display: flex; align-items: center; - justify-content: center; - padding: 12rpx 0; + padding: 16rpx 0; } -.swap-line { +.swap-track { flex: 1; height: 2rpx; - background: #E2E8F0; + background: linear-gradient(90deg, transparent, rgba(148, 163, 184, 0.1), transparent); } .swap-btn { - width: 80rpx; - height: 80rpx; + width: 84rpx; + height: 84rpx; border-radius: 50%; - background: #4F46E5; + background: linear-gradient(140deg, #3B82F6 0%, #6366F1 100%); display: flex; align-items: center; justify-content: center; margin: 0 24rpx; - box-shadow: 0 6rpx 20rpx rgba(79, 70, 229, 0.3); + box-shadow: + 0 8rpx 28rpx rgba(99, 102, 241, 0.3), + inset 0 2rpx 4rpx rgba(255, 255, 255, 0.1); } .swap-icon { - font-size: 36rpx; + font-size: 38rpx; color: #FFFFFF; + font-weight: 700; } -/* ===== 单位汇率 ===== */ -.rate-card { - padding: 28rpx 36rpx; -} - -.rate-row { +/* ===== RATE LIST (竖排) ===== */ +.rate-list { display: flex; - align-items: center; - padding: 8rpx 0; + flex-direction: column; + gap: 12rpx; + margin-bottom: 28rpx; } -.rate-dot { - width: 14rpx; - height: 14rpx; - border-radius: 50%; - margin-right: 16rpx; - flex-shrink: 0; -} - -.from-dot { - background: #64748B; -} - -.to-dot { - background: #4F46E5; +.rate-item { + padding: 24rpx 32rpx; + text-align: center; } .rate-text { font-size: 26rpx; color: #64748B; - font-weight: 500; + font-weight: 600; + letter-spacing: 1rpx; } -/* ===== 错误提示 ===== */ +/* ===== ERROR ===== */ .error-card { - display: flex; - align-items: center; - padding: 28rpx 36rpx; - background: #FEF2F2; -} - -.error-icon { - font-size: 32rpx; - margin-right: 16rpx; + padding: 28rpx 32rpx; + background: rgba(239, 68, 68, 0.08); + border: 2rpx solid rgba(239, 68, 68, 0.15); + text-align: center; } .error-text { font-size: 26rpx; - color: #DC2626; + color: #FCA5A5; } -/* ===== 汇率总览入口 ===== */ -.overview-entry { +/* ===== OVERVIEW ENTRY ===== */ +.overview-btn { + margin-top: 8rpx; + margin-bottom: 48rpx; +} + +.overview-inner { display: flex; align-items: center; - justify-content: space-between; - padding: 36rpx; -} - -.overview-left { - display: flex; - align-items: center; -} - -.overview-icon { - font-size: 36rpx; - margin-right: 16rpx; + justify-content: center; + gap: 12rpx; + padding: 34rpx; + border-radius: 20rpx; + background: linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(99, 102, 241, 0.06) 100%); + border: 2rpx solid rgba(99, 102, 241, 0.15); } .overview-label { font-size: 30rpx; - font-weight: 500; - color: #334155; + font-weight: 600; + color: #93C5FD; + letter-spacing: 2rpx; } .overview-arrow { - font-size: 40rpx; - color: #CBD5E1; - font-weight: 300; + font-size: 30rpx; + color: #93C5FD; } diff --git a/miniprogram/pages/overview/overview.js b/miniprogram/pages/overview/overview.js index eed7de0..7354488 100644 --- a/miniprogram/pages/overview/overview.js +++ b/miniprogram/pages/overview/overview.js @@ -6,13 +6,14 @@ const pickerData = getPickerData(); Page({ data: { pickerData, - baseIndex: 0, // CNY + baseIndex: 0, amount: '100', list: [], updatedAt: '', loading: true, error: '', rates: null, + showPicker: false, }, onLoad() { @@ -30,17 +31,10 @@ Page({ try { const baseCode = CURRENCIES[this.data.baseIndex].code; const { rates, updatedAt } = await getRates(baseCode); - this.setData({ - rates, - updatedAt, - loading: false, - }); + this.setData({ rates, updatedAt, loading: false }); this.buildList(); } catch (e) { - this.setData({ - loading: false, - error: '汇率获取失败,请检查网络后下拉刷新', - }); + this.setData({ loading: false, error: '汇率获取失败,请下拉刷新重试' }); } }, @@ -72,11 +66,19 @@ Page({ this.setData({ list }); }, - handleBaseChange(e) { - this.setData({ baseIndex: Number(e.detail.value) }); + openBasePicker() { + this.setData({ showPicker: true }); + }, + + handlePickerSelect(e) { + this.setData({ baseIndex: e.detail.value, showPicker: false }); this.loadRates(); }, + handlePickerClose() { + this.setData({ showPicker: false }); + }, + handleAmountInput(e) { this.setData({ amount: e.detail.value }); this.buildList(); diff --git a/miniprogram/pages/overview/overview.json b/miniprogram/pages/overview/overview.json index 4100ccf..65abfd9 100644 --- a/miniprogram/pages/overview/overview.json +++ b/miniprogram/pages/overview/overview.json @@ -1,5 +1,7 @@ { - "navigationBarTitleText": "汇率总览", + "navigationBarTitleText": "", "enablePullDownRefresh": true, - "usingComponents": {} + "usingComponents": { + "currency-picker": "/components/currency-picker/currency-picker" + } } diff --git a/miniprogram/pages/overview/overview.wxml b/miniprogram/pages/overview/overview.wxml index 1c6c274..0600324 100644 --- a/miniprogram/pages/overview/overview.wxml +++ b/miniprogram/pages/overview/overview.wxml @@ -1,64 +1,73 @@ - - - - 📊 汇率总览 + + + + 汇率总览 + + {{updatedAt}} + - - 基准 - - - {{pickerData[baseIndex]}} - - - + + 基准货币 + + {{pickerData[baseIndex]}} + + - - 金额 + + 换算金额 - - {{updatedAt}} 更新 - + - {{error}} - - - 正在获取汇率数据... + + + + 加载中 - - + + - - {{item.flag}} - - {{item.code}} - {{item.name}} + + + {{item.flag}} + + + {{item.code}} + {{item.name}} - - {{item.converted}} - 1 = {{item.unitRate}} + + {{item.converted}} + 1 = {{item.unitRate}} + + diff --git a/miniprogram/pages/overview/overview.wxss b/miniprogram/pages/overview/overview.wxss index 07f72f5..a03abbb 100644 --- a/miniprogram/pages/overview/overview.wxss +++ b/miniprogram/pages/overview/overview.wxss @@ -1,157 +1,197 @@ -/* ===== 顶部控制区 ===== */ -.header-card { +/* ===== CONTROL CARD ===== */ +.ctrl-card { padding: 36rpx; + background: + linear-gradient(135deg, rgba(30, 41, 59, 0.9) 0%, rgba(15, 23, 42, 0.95) 100%); + border: 2rpx solid rgba(148, 163, 184, 0.12); } -.header-top { - margin-bottom: 28rpx; -} - -.header-title { - font-size: 40rpx; - font-weight: 800; - color: #1E293B; -} - -.control-row { +.ctrl-top { display: flex; align-items: center; justify-content: space-between; - padding: 20rpx 0; - border-top: 2rpx solid #F1F5F9; + margin-bottom: 28rpx; } -.control-label { - font-size: 28rpx; +.ctrl-title { + font-size: 44rpx; + font-weight: 800; + color: #F8FAFC; + letter-spacing: 4rpx; +} + +.ctrl-badge { + background: rgba(148, 163, 184, 0.08); + border: 2rpx solid rgba(148, 163, 184, 0.12); + border-radius: 40rpx; + padding: 8rpx 20rpx; +} + +.badge-text { + font-size: 20rpx; color: #64748B; font-weight: 500; } -.base-tag { - display: inline-flex; +.ctrl-row { + display: flex; align-items: center; - background: #F8FAFC; - border: 2rpx solid #E2E8F0; - border-radius: 12rpx; - padding: 10rpx 20rpx; + justify-content: space-between; + padding: 24rpx 0; + border-top: 2rpx solid rgba(148, 163, 184, 0.06); } -.base-tag-text { +.ctrl-label { + font-size: 26rpx; + color: #64748B; + font-weight: 600; + letter-spacing: 2rpx; +} + +.ctrl-chip { + display: flex; + align-items: center; + background: rgba(148, 163, 184, 0.08); + border: 2rpx solid rgba(148, 163, 184, 0.15); + border-radius: 16rpx; + padding: 12rpx 20rpx; +} + +.chip-text { font-size: 26rpx; font-weight: 500; - color: #334155; + color: #CBD5E1; } -.tag-arrow { - font-size: 18rpx; - color: #94A3B8; - margin-left: 10rpx; +.chip-arrow { + font-size: 28rpx; + color: #475569; + margin-left: 12rpx; } -.amount-input { +.ctrl-input { flex: 1; text-align: right; - font-size: 40rpx; + font-size: 44rpx; font-weight: 800; - color: #1E293B; + color: #F1F5F9; margin-left: 24rpx; } -.amount-placeholder { - color: #CBD5E1; - font-weight: 400; +.ctrl-placeholder { + color: #334155; + font-weight: 500; } -.updated-at { - font-size: 22rpx; - color: #94A3B8; - margin-top: 16rpx; -} - -/* ===== 错误 & 加载 ===== */ +/* ===== ERROR & LOADING ===== */ .error-card { - display: flex; - align-items: center; padding: 28rpx 36rpx; - background: #FEF2F2; -} - -.error-icon { - font-size: 32rpx; - margin-right: 16rpx; + background: rgba(239, 68, 68, 0.1); + border: 2rpx solid rgba(239, 68, 68, 0.2); + text-align: center; } .error-text { font-size: 26rpx; - color: #DC2626; + color: #FCA5A5; } -.loading-card { - padding: 40rpx; - text-align: center; - color: #94A3B8; +.loading-wrap { + display: flex; + align-items: center; + justify-content: center; + padding: 48rpx; + gap: 16rpx; +} + +.loading-dot { + width: 16rpx; + height: 16rpx; + border-radius: 50%; + background: #6366F1; + animation: pulse 1.5s infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.3; transform: scale(0.8); } +} + +.loading-text { font-size: 26rpx; + color: #64748B; } -/* ===== 汇率列表 ===== */ -.list-card { - padding: 8rpx 0; +/* ===== RATE LIST ===== */ +.list-wrap { + margin-bottom: 32rpx; } -.rate-item { +.rate-row { display: flex; align-items: center; justify-content: space-between; - padding: 28rpx 36rpx; - border-bottom: 2rpx solid #F8FAFC; - transition: background 0.15s; + padding: 28rpx 32rpx; + margin-bottom: 16rpx; + background: rgba(30, 41, 59, 0.5); + border: 2rpx solid rgba(148, 163, 184, 0.06); } -.rate-item:last-child { - border-bottom: none; -} - -.rate-left { +.row-left { display: flex; align-items: center; } -.rate-flag { - font-size: 44rpx; - margin-right: 20rpx; +.flag-circle { + width: 76rpx; + height: 76rpx; + border-radius: 50%; + background: rgba(148, 163, 184, 0.08); + border: 2rpx solid rgba(148, 163, 184, 0.1); + display: flex; + align-items: center; + justify-content: center; + margin-right: 24rpx; } -.rate-info { +.flag-emoji { + font-size: 40rpx; +} + +.row-info { display: flex; flex-direction: column; } -.rate-code { +.row-code { font-size: 30rpx; font-weight: 700; - color: #1E293B; + color: #E2E8F0; + letter-spacing: 2rpx; } -.rate-name { +.row-name { font-size: 22rpx; - color: #94A3B8; + color: #64748B; margin-top: 4rpx; } -.rate-right { +.row-right { display: flex; flex-direction: column; align-items: flex-end; } -.rate-value { - font-size: 32rpx; +.row-value { + font-size: 34rpx; font-weight: 800; - color: #1E293B; + color: #FBBF24; + letter-spacing: 1rpx; } -.rate-unit { +.row-unit { font-size: 22rpx; - color: #94A3B8; - margin-top: 4rpx; + color: #475569; + margin-top: 6rpx; + font-weight: 500; }