/** * weekly.vue — 与 code.html (Stitch Modern WeChat UI) 1:1 */ .weekly-page { --st-shadow-ambient: 0 24rpx 60rpx -20rpx rgba(0, 108, 73, 0.08), 0 8rpx 20rpx -8rpx rgba(0, 0, 0, 0.03); --st-shadow-cta: 0 16rpx 32rpx rgba(0, 108, 73, 0.2); --st-shadow-float: 0 16rpx 64rpx rgba(0, 108, 73, 0.15); --tab-dock-full-offset: calc(220rpx + env(safe-area-inset-bottom)); padding-bottom: var(--tab-dock-full-offset); } /* ===== Header ===== */ .weekly-page .st-header { position: relative; display: flex; align-items: center; padding-left: var(--st-container-margin); padding-right: var(--st-container-margin); padding-bottom: 32rpx; /* padding-top / padding-right 由 initHeaderSafeArea 动态设置 */ background: var(--surface); } .weekly-page .st-header-text { flex: 1; min-width: 0; overflow: hidden; } .weekly-page .st-header-left { display: flex; align-items: center; gap: var(--st-inline-gap); flex: 1; min-width: 0; } .weekly-page .st-avatar { width: 80rpx; height: 80rpx; border-radius: 50%; background: var(--primary-container); border: 4rpx solid var(--surface-container-lowest); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .weekly-page .st-greet { display: block; font-size: 40rpx; font-weight: 700; line-height: 1.27; color: var(--on-surface); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .weekly-page .st-status { display: block; margin-top: 4rpx; font-size: 24rpx; font-weight: 600; color: var(--on-surface-variant); opacity: 0.8; } .weekly-page .st-voice-round { width: 80rpx; height: 80rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .weekly-page .st-voice-round.disabled { opacity: 0.45; } .weekly-page .st-card-scroll { margin: 0 var(--st-container-margin) 8rpx; white-space: nowrap; } .weekly-page .st-card-row { display: inline-flex; gap: 16rpx; } .weekly-page .st-card-chip { padding: 12rpx 28rpx; border-radius: 999rpx; font-size: 26rpx; font-weight: 600; color: var(--on-surface-variant); background: var(--surface-container-lowest); border: 1rpx solid var(--outline-variant); } .weekly-page .st-card-chip.active { background: var(--primary); border-color: var(--primary); color: var(--on-primary); } /* ===== 居家训练(DEV 内嵌) ===== */ .weekly-page .st-training-section { width: 100%; box-sizing: border-box; } .weekly-page .st-training-section .dev-entry-inline--weekly { overflow: hidden; } .weekly-page .st-training-section .inline-scroll { margin-left: -4rpx; margin-right: -4rpx; width: calc(100% + 8rpx); } .weekly-page .st-training-section .inline-card:first-child { border-color: rgba(0, 108, 73, 0.22); background: linear-gradient(160deg, rgba(0, 108, 73, 0.08) 0%, #f4f7f5 55%); } /* ===== Main ===== */ .weekly-page .st-main { padding: 0 var(--st-container-margin) 32rpx; display: flex; flex-direction: column; gap: 48rpx; margin-top: 16rpx; } .weekly-page .st-daily-context-error { padding: 24rpx 28rpx; border-radius: 24rpx; background: #fef2f2; border: 1rpx solid rgba(220, 38, 38, 0.22); box-sizing: border-box; } .weekly-page .st-daily-context-error-text { font-size: 28rpx; font-weight: 600; color: #991b1b; line-height: 1.5; } .weekly-page .st-main-spacer { height: 32rpx; } /* CTA — rounded-2xl h-14 */ .weekly-page .st-cta { width: 100%; height: 112rpx; display: flex; align-items: center; justify-content: center; gap: 16rpx; border-radius: var(--st-radius-2xl); background: var(--primary); color: var(--on-primary); font-size: 32rpx; font-weight: 700; box-shadow: var(--st-shadow-cta); } .weekly-page .st-cta:active { transform: scale(0.98); } /* 糖分突袭游戏入口 */ .weekly-page .st-game-entry { margin-top: 24rpx; padding: 28rpx 32rpx; display: flex; align-items: center; gap: 24rpx; border-radius: var(--st-radius-2xl); background: var(--surface-container-lowest); border: 1rpx solid rgba(0, 108, 73, 0.14); box-shadow: var(--st-shadow-ambient); box-sizing: border-box; } .weekly-page .st-game-entry:active { transform: scale(0.98); opacity: 0.92; } .weekly-page .st-game-entry-icon { width: 88rpx; height: 88rpx; border-radius: 24rpx; background: rgba(0, 108, 73, 0.1); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .weekly-page .st-game-entry-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6rpx; } .weekly-page .st-game-entry-title { font-size: 32rpx; font-weight: 700; color: var(--on-surface); line-height: 1.25; } .weekly-page .st-game-entry-sub { font-size: 24rpx; font-weight: 500; color: var(--on-surface-variant, #64748b); line-height: 1.35; } /* ===== Chart card — rounded-3xl ===== */ .weekly-page .st-chart-card { padding: 40rpx 10rpx 40rpx 10rpx; border-radius: 48rpx; background: var(--surface-container-lowest); border: 1rpx solid rgba(221, 228, 221, 0.3); box-shadow: var(--st-shadow-ambient); display: flex; flex-direction: column; gap: 0; overflow: hidden; } .weekly-page .st-chart-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12rpx; gap: 16rpx; } .weekly-page .st-chart-title { display: block; font-size: 30rpx; font-weight: 700; color: var(--on-surface); } .weekly-page .st-chart-sub { display: block; margin-top: 4rpx; font-size: 22rpx; font-weight: 600; color: var(--on-surface-variant); } .weekly-page .st-chart-more { display: inline-flex; align-items: center; gap: 4rpx; margin-top: 6rpx; } .weekly-page .st-chart-more-text { font-size: 22rpx; font-weight: 600; color: var(--primary); } .weekly-page .st-chart-more:active { opacity: 0.75; } .weekly-page .st-chart-legend { display: flex; gap: var(--st-inline-gap); } .weekly-page .st-legend-item { display: flex; align-items: center; gap: 8rpx; font-size: 24rpx; font-weight: 600; color: var(--on-surface-variant); } .weekly-page .st-legend-item.inactive { opacity: 0.4; } .weekly-page .st-dot { width: 16rpx; height: 16rpx; border-radius: 50%; } .weekly-page .st-dot-fasting { background: var(--primary); } .weekly-page .st-dot-post { background: var(--tertiary); } .weekly-page .st-chart-summary { display: flex; padding: 32rpx; margin-bottom: 48rpx; border-radius: var(--st-radius-xl); background: var(--surface-container-low); } .weekly-page .st-chart-summary-item { flex: 1; display: flex; flex-direction: column; align-items: center; border-right: 1rpx solid var(--surface-container-highest); } .weekly-page .st-chart-summary-item:last-child { border-right: none; } .weekly-page .st-chart-summary-num { font-size: 40rpx; font-weight: 700; color: var(--on-surface); } .weekly-page .st-chart-summary-num.is-high { color: var(--tertiary); } .weekly-page .st-chart-summary-num.is-good { color: var(--primary); } .weekly-page .st-chart-summary-label { margin-top: 8rpx; font-size: 24rpx; font-weight: 600; color: var(--on-surface-variant); } .weekly-page .st-chart-foot { padding: 20rpx 0 20rpx; } .weekly-page .st-chart-mock-hint { display: block; margin: 0; font-size: 30rpx; font-weight: 600; color: var(--outline); line-height: 1.35; text-align: center; } .weekly-page .st-chart-area { position: relative; height: 360rpx; overflow: hidden; cursor: pointer; } .weekly-page .st-chart-area:active { opacity: 0.92; } .weekly-page .st-chart-canvas { width: 100%; height: 360rpx; display: block; } /* 识糖入口嵌在趋势卡内:轻量分隔,避免大块留白 */ .weekly-page .st-chart-card .st-game-entry--in-card { margin-top: 12rpx; padding: 16rpx 20rpx; gap: 16rpx; border-radius: 24rpx; background: var(--surface-container-low); border: 1rpx solid rgba(0, 108, 73, 0.08); box-shadow: none; } .weekly-page .st-chart-card .st-game-entry--in-card .st-game-entry-icon { width: 64rpx; height: 64rpx; border-radius: 16rpx; } .weekly-page .st-chart-card .st-game-entry--in-card .st-game-entry-title { font-size: 28rpx; } .weekly-page .st-chart-card .st-game-entry--in-card .st-game-entry-sub { font-size: 22rpx; } .weekly-page .st-chart-empty, .weekly-page .st-chart-placeholder { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 26rpx; color: var(--outline); } /* ===== 最新测量 ===== */ .weekly-page .st-latest-section { display: flex; flex-direction: column; gap: 32rpx; } .weekly-page .st-latest-hero { position: relative; overflow: hidden; min-height: 320rpx; padding: 48rpx 40rpx; border-radius: 48rpx; background: var(--surface-container-lowest); box-shadow: var(--st-shadow-ambient); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; } .weekly-page .st-latest-hero.is-high { background: var(--error-container); color: var(--on-error-container); } .weekly-page .st-latest-hero-pattern { position: absolute; inset: 0; opacity: 0.1; background-image: radial-gradient(circle at 4rpx 4rpx, currentColor 2rpx, transparent 0); background-size: 32rpx 32rpx; pointer-events: none; } .weekly-page .st-latest-label { position: relative; z-index: 1; font-size: 24rpx; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.9; margin-bottom: 8rpx; } .weekly-page .st-latest-value-row { position: relative; z-index: 1; display: flex; align-items: baseline; gap: 8rpx; } .weekly-page .st-latest-value { font-size: 112rpx; font-weight: 800; line-height: 1; letter-spacing: -0.02em; } .weekly-page .st-latest-hero.is-high .st-latest-value, .weekly-page .st-latest-hero.is-high .st-latest-unit { color: var(--on-error-container); } .weekly-page .st-latest-unit { font-size: 32rpx; font-weight: 500; opacity: 0.8; } .weekly-page .st-latest-flag { position: relative; z-index: 1; margin-top: 24rpx; display: inline-flex; align-items: center; gap: 12rpx; padding: 8rpx 24rpx; border-radius: 999rpx; background: rgba(255, 255, 255, 0.3); font-size: 24rpx; font-weight: 700; } .weekly-page .st-summary-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24rpx; } .weekly-page .st-summary-card { padding: 32rpx; border-radius: var(--st-radius-2xl); background: var(--surface-container-lowest); border: 1rpx solid rgba(221, 228, 221, 0.5); box-shadow: var(--st-shadow-ambient); display: flex; flex-direction: column; gap: 8rpx; } .weekly-page .st-summary-label { font-size: 24rpx; font-weight: 600; color: var(--on-surface-variant); } .weekly-page .st-summary-value { font-size: 48rpx; font-weight: 700; color: var(--on-surface); } .weekly-page .st-summary-value.is-high { color: var(--tertiary); } .weekly-page .st-summary-tag { align-self: flex-start; padding: 4rpx 16rpx; border-radius: 8rpx; font-size: 20rpx; font-weight: 600; color: var(--tertiary); background: rgba(255, 218, 214, 0.5); } /* ===== AI 饮食 ===== */ .weekly-page .st-ai-section { position: relative; overflow: hidden; padding: 40rpx; border-radius: 48rpx; background: linear-gradient(135deg, rgba(0, 108, 73, 0.1) 0%, rgba(0, 108, 73, 0.05) 100%); border: 1rpx solid rgba(0, 108, 73, 0.1); } .weekly-page .st-ai-deco { position: absolute; width: 256rpx; height: 256rpx; top: -64rpx; right: -64rpx; border-radius: 50%; background: rgba(78, 222, 163, 0.2); filter: blur(40rpx); pointer-events: none; } .weekly-page .st-ai-head { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; margin-bottom: 16rpx; } .weekly-page .st-ai-head-left { display: flex; align-items: center; gap: 16rpx; } .weekly-page .st-ai-icon { width: 64rpx; height: 64rpx; border-radius: 50%; background: var(--primary); display: flex; align-items: center; justify-content: center; } .weekly-page .st-ai-icon.thinking { animation: st-pulse 1.2s ease-in-out infinite; } @keyframes st-pulse { 50% { opacity: 0.65; } } .weekly-page .st-ai-title { font-size: 40rpx; font-weight: 700; color: var(--on-surface); } .weekly-page .st-ai-refresh { display: flex; align-items: center; gap: 8rpx; padding: 12rpx 24rpx; border-radius: 999rpx; background: rgba(255, 255, 255, 0.5); font-size: 24rpx; font-weight: 600; color: var(--primary); } .weekly-page .st-ai-refresh.disabled { opacity: 0.5; } .weekly-page .st-ai-sub { position: relative; z-index: 1; display: block; margin-bottom: 32rpx; font-size: 28rpx; line-height: 1.43; color: var(--on-surface-variant); } .weekly-page .st-meal-list { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 24rpx; } .weekly-page .st-meal-glass { padding: 32rpx; border-radius: var(--st-radius-2xl); background: rgba(255, 255, 255, 0.8); border: 1rpx solid #ffffff; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); } .weekly-page .st-meal-glass--drinks { background: rgba(224, 242, 254, 0.65); border-color: rgba(14, 165, 233, 0.15); } .weekly-page .st-meal-head { display: flex; align-items: center; gap: 16rpx; margin-bottom: 16rpx; } .weekly-page .st-meal-label { font-size: 28rpx; font-weight: 700; color: var(--on-surface); } .weekly-page .st-meal-text { font-size: 28rpx; line-height: 1.43; color: var(--on-surface-variant); } .weekly-page .st-skeleton-line { height: 28rpx; margin-bottom: 16rpx; border-radius: 8rpx; background: rgba(255, 255, 255, 0.5); } .weekly-page .st-skeleton-hint { font-size: 26rpx; color: var(--outline); text-align: center; } /* ===== 底部浮动输入 ===== */ .weekly-page .st-float-ask { position: fixed; left: var(--st-container-margin); right: var(--st-container-margin); bottom: var(--tab-dock-full-offset); z-index: 210; } .weekly-page .st-float-close { position: absolute; top: -18rpx; right: -6rpx; width: 44rpx; height: 44rpx; border-radius: 50%; background: rgba(0, 0, 0, 0.45); display: flex; align-items: center; justify-content: center; z-index: 2; } .weekly-page .st-float-close-icon { color: #ffffff; font-size: 30rpx; line-height: 1; } .weekly-page .st-float-reopen { position: fixed; right: var(--st-container-margin); bottom: var(--tab-dock-full-offset); width: 88rpx; height: 88rpx; border-radius: 50%; background: linear-gradient(180deg, #2d7340 0%, #006c49 100%); box-shadow: var(--st-shadow-float); display: flex; align-items: center; justify-content: center; z-index: 210; } .weekly-page .st-float-inner { display: flex; align-items: center; gap: 16rpx; padding: 16rpx 16rpx 16rpx 28rpx; border-radius: 999rpx; background: rgba(255, 255, 255, 0.9); backdrop-filter: blur(20rpx); border: 1rpx solid rgba(0, 108, 73, 0.1); box-shadow: var(--st-shadow-float); transition: border-radius 0.22s ease, padding 0.22s ease, border-color 0.22s ease; } /* 聚焦/有内容时展开:底部对齐让输入框向上增高,圆角收敛为圆角矩形 */ .weekly-page .st-float-inner.is-expanded { align-items: flex-end; border-radius: 32rpx; padding: 18rpx 16rpx 18rpx 32rpx; border-color: rgba(0, 108, 73, 0.28); } .weekly-page .st-float-icon { width: 64rpx; height: 64rpx; border-radius: 50%; background: rgba(0, 108, 73, 0.1); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .weekly-page .st-float-input { flex: 1; min-width: 0; width: 100%; min-height: 64rpx; max-height: 240rpx; font-size: 28rpx; line-height: 40rpx; color: var(--on-surface); background: transparent; padding: 12rpx 0; box-sizing: border-box; transition: min-height 0.2s ease; } /* 聚焦时输入框变大;内容超长时由 auto-height 继续向上增高,超过上限可滚动 */ .weekly-page .st-float-inner.is-expanded .st-float-input { min-height: 104rpx; } .weekly-page .st-float-placeholder { color: rgba(60, 74, 66, 0.6); font-size: 26rpx; line-height: 40rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .weekly-page .st-float-mic { width: 72rpx; height: 72rpx; border-radius: 50%; background: rgba(0, 108, 73, 0.1); display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: background 0.2s ease, transform 0.15s ease; } .weekly-page .st-float-mic.listening { background: var(--primary); animation: st-float-mic-pulse 1.2s ease-in-out infinite; } .weekly-page .st-float-mic.disabled { opacity: 0.45; pointer-events: none; } .weekly-page .st-float-mic:active { transform: scale(0.94); } .weekly-page .st-float-hold-hint { margin-top: 12rpx; text-align: center; font-size: 24rpx; color: var(--primary); line-height: 1.4; } .weekly-page .st-voice-overlay { position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: 3000; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.32); pointer-events: none; } .weekly-page .st-voice-card { display: flex; flex-direction: column; align-items: center; gap: 20rpx; padding: 56rpx 64rpx; border-radius: 32rpx; background: rgba(20, 24, 22, 0.86); box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.35); } .weekly-page .st-voice-icon { width: 120rpx; height: 120rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: linear-gradient(180deg, #2d7340 0%, #006c49 100%); } .weekly-page .st-voice-icon.active { animation: st-voice-pulse 1.1s ease-in-out infinite; } @keyframes st-voice-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(0, 108, 73, 0.45); } 50% { box-shadow: 0 0 0 20rpx rgba(0, 108, 73, 0); } } .weekly-page .st-voice-title { font-size: 32rpx; font-weight: 700; color: #ffffff; line-height: 1.3; } .weekly-page .st-voice-sub { font-size: 24rpx; color: rgba(255, 255, 255, 0.7); line-height: 1.3; } @keyframes st-float-mic-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(0, 108, 73, 0.35); } 50% { box-shadow: 0 0 0 12rpx rgba(0, 108, 73, 0); } } .weekly-page .st-float-send { width: 80rpx; height: 80rpx; border-radius: 50%; background: var(--primary); display: flex; align-items: center; justify-content: center; flex-shrink: 0; box-shadow: 0 4rpx 12rpx rgba(0, 108, 73, 0.2); line-height: 0; overflow: hidden; } .weekly-page .st-float-send.disabled { opacity: 0.55; } .weekly-page .st-float-send:active { transform: scale(0.95); } .weekly-page .st-float-result { margin-top: 16rpx; padding: 24rpx 32rpx; border-radius: var(--st-radius-xl); background: rgba(255, 255, 255, 0.95); border: 1rpx solid var(--outline-variant); box-shadow: var(--st-shadow-ambient); } .weekly-page .st-float-badge { display: inline-block; margin-bottom: 8rpx; padding: 4rpx 12rpx; border-radius: 8rpx; font-size: 22rpx; font-weight: 700; color: var(--primary); background: rgba(0, 108, 73, 0.1); } .weekly-page .st-float-advice { font-size: 28rpx; line-height: 1.5; color: var(--on-surface-variant); } .weekly-page .ai-stream-cursor { animation: st-blink 0.8s step-end infinite; } @keyframes st-blink { 50% { opacity: 0; } } .weekly-page .chart-tip { position: absolute; z-index: 10; padding: 12rpx 16rpx; border-radius: 12rpx; background: rgba(22, 29, 25, 0.88); color: #fff; font-size: 22rpx; pointer-events: none; } .weekly-page .chart-tip-date { font-weight: 700; margin-bottom: 8rpx; } .weekly-page .chart-tip-row { display: flex; align-items: center; gap: 8rpx; margin-top: 4rpx; }