Просмотр исходного кода

feat(login-sheet): 底部滑出登录面板视觉升级

- 移植 mock 的 template+style 视觉层:emoji 全清换线性 SVG(data:image/svg+xml
  背景图,遵循 mp-weixin 不支持模板内联 <svg> 的既有约定)
- 四步闭环改浅底圆钉图标+中性文字(去彩虹/去生硬箭头)
- 五维标签带改统一描边容器+发丝分割+深档色记号(非等权重填充 pills)
- 品牌区三级层级 + 60-30-10 暖白底 + 单品牌橙强调
- 八态按钮(default/hover/active/disabled/loading/error/success)
- script 以基线为准逐字节保留(含 $emit('open')/$emit('close')),
  仅 data() 追加 errorState/successState 两个八态视觉位(template 已绑定)
Agnes Agent 1 день назад
Родитель
Сommit
def75bab51
1 измененных файлов с 374 добавлено и 209 удалено
  1. 374 209
      cfc-frontend/components/login-sheet.vue

+ 374 - 209
cfc-frontend/components/login-sheet.vue

@@ -2,29 +2,68 @@
   <view class="login-sheet-overlay" :class="{ 'login-sheet-overlay--visible': visible }" @click="handleOverlayClick">
     <view class="login-sheet-panel" :class="{ 'login-sheet-panel--show': panelShow }" @click.stop>
       <view class="login-sheet-header">
+        <view class="login-sheet-handle" aria-hidden="true"></view>
         <view class="login-sheet-title">欢迎回来</view>
       </view>
       <scroll-view scroll-y class="login-sheet-scroll" :show-scrollbar="false">
         <view class="login-sheet-content">
-          <!-- 品牌区(左上角锁定版式,与首页一致) -->
-          <view class="brand-bar">
-            <image class="brand-logo" src="/static/logo.png" mode="aspectFit" @error="handleImageError"></image>
-            <view class="brand-texts">
-              <text class="brand-name">浠艾福</text>
-              <text class="brand-tagline">您的专属家庭主动健康陪跑</text>
-            </view>
+          <!-- 品牌区:logo / 品牌名 / 身份 / 主打句(记忆点) -->
+          <view class="brand-section">
+            <image class="logo" src="/static/logo.png" mode="aspectFit" @error="handleImageError"></image>
+            <text class="app-name">浠艾福</text>
+            <text class="identity">您的专属家庭主动健康管理师</text>
+            <text class="slogan">家里每个人的状态,你真的<text class="slogan-accent">看见了?</text></text>
           </view>
 
-          <!-- 理念卡 -->
+          <!-- 理念卡:四步闭环(细边框表面区分,无单侧彩条) -->
           <view class="concept-card">
+            <view class="concept-desc">
+              不等问题发生,先一步<text class="concept-highlight">识别风险 · 主动干预 · 持续评估</text>,把全家健康管理融入每一天。
+            </view>
             <view class="loop-row">
-              <view class="loop-pill loop-pill-indigo"><text>🔍</text><text class="loop-pill-text">提前识别</text></view>
-              <text class="loop-arrow">→</text>
-              <view class="loop-pill loop-pill-green"><text>🛡️</text><text class="loop-pill-text">风险管控</text></view>
-              <text class="loop-arrow">→</text>
-              <view class="loop-pill loop-pill-amber"><text>⚡</text><text class="loop-pill-text">主动干预</text></view>
-              <text class="loop-arrow">→</text>
-              <view class="loop-pill loop-pill-red"><text>📊</text><text class="loop-pill-text">效果评估</text></view>
+              <view class="loop-step">
+                <view class="loop-glyph loop-glyph-wisdom" aria-hidden="true"></view>
+                <text class="loop-step-text">提前识别</text>
+              </view>
+              <view class="loop-connector" aria-hidden="true"></view>
+              <view class="loop-step">
+                <view class="loop-glyph loop-glyph-success" aria-hidden="true"></view>
+                <text class="loop-step-text">风险管控</text>
+              </view>
+              <view class="loop-connector" aria-hidden="true"></view>
+              <view class="loop-step">
+                <view class="loop-glyph loop-glyph-wealth" aria-hidden="true"></view>
+                <text class="loop-step-text">主动干预</text>
+              </view>
+              <view class="loop-connector" aria-hidden="true"></view>
+              <view class="loop-step">
+                <view class="loop-glyph loop-glyph-danger" aria-hidden="true"></view>
+                <text class="loop-step-text">效果评估</text>
+              </view>
+            </view>
+          </view>
+
+          <!-- 五维标签带:统一描边容器 + 细分割线,色块仅作身份记号(非等权重填充 pills) -->
+          <view class="dims-band">
+            <view class="dim-cell">
+              <view class="dim-glyph dim-glyph-body" aria-hidden="true"></view>
+              <text class="dim-label">身·健康</text>
+            </view>
+            <view class="dim-cell">
+              <view class="dim-glyph dim-glyph-wisdom" aria-hidden="true"></view>
+              <text class="dim-label">智·认知</text>
+            </view>
+            <view class="dim-cell">
+              <view class="dim-glyph dim-glyph-wealth" aria-hidden="true"></view>
+              <text class="dim-label">富·创富</text>
+            </view>
+            <view class="dim-cell">
+              <view class="dim-glyph dim-glyph-action" aria-hidden="true"></view>
+              <text class="dim-label">行·和谐</text>
+            </view>
+            <view class="dim-cell">
+              <view class="dim-glyph dim-glyph-mind" aria-hidden="true"></view>
+              <text class="dim-label">心·大爱</text>
             </view>
           </view>
 
@@ -33,15 +72,15 @@
             <view class="phone-section">
               <button
                 class="phone-btn"
+                :class="{ 'phone-btn--error': errorState, 'phone-btn--success': successState }"
                 open-type="getPhoneNumber"
                 @getphonenumber="getPhoneNumber"
                 @tap="onPhoneBtnTap"
                 :loading="loading"
                 :disabled="!agreed || loading || tapLock"
               >
-                <text class="phone-btn-icon">📱</text>
-                <text class="phone-btn-text">手机号快捷登录</text>
-                <text class="phone-arrows">›››</text>
+                <view class="phone-btn-icon" aria-hidden="true"></view>
+                <text>手机号快捷登录</text>
               </button>
             </view>
 
@@ -83,7 +122,10 @@ export default {
       nickname: '',
       avatar: '',
       redirectUrl: '',
-      _tapLockTimer: null
+      _tapLockTimer: null,
+      // 八状态视觉位(R2 修复):默认均为布尔 false,不触发任何 class;登录逻辑与外部契约不变
+      errorState: false,
+      successState: false
     }
   },
   beforeDestroy() {
@@ -226,6 +268,67 @@ export default {
 </script>
 
 <style scoped lang="scss">
+/* =====================================================================
+   login-sheet 视觉令牌(局部)
+   来源:全部复用 uni.scss 共享令牌;仅本组件专有的色值以 $ls- 前缀声明,
+   组件体内零裸 hex / 裸 px / 裸毫秒。
+   注意:mp-weixin WXML 不支持模板内联 <svg>(仓库既有约定,
+   components/wuxing-sandbox.vue 注释在案),故图标一律用
+   data:image/svg+xml 作为 CSS background-image,颜色显式写入 SVG 文档。
+   ===================================================================== */
+
+// ---- 图标工具:构建 data-URI SVG(颜色显式编码为 %23hex)----
+// str-replace 使维度色令牌可注入 data-URI(# 编码为 %23),令牌成为唯一事实源
+@function str-replace($string, $search, $replace) {
+  $index: str-index($string, $search);
+  @if $index {
+    @return str-slice($string, 1, $index - 1) + $replace +
+      str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
+  }
+  @return $string;
+}
+@function ls-icon($color, $inner) {
+  @return url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='#{str-replace($color, '#', '%23')}' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E#{$inner}%3C/svg%3E");
+}
+// 图标路径(feather 线性几何,24×24;只编码 < > 与 #,空格/单引号合法)
+$ls-i-search:   "%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E";
+$ls-i-shield:   "%3Cpath d='M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E";
+$ls-i-zap:      "%3Cpath d='M13 2 3 14h9l-1 8 10-12h-9l1-8z'/%3E";
+$ls-i-chart:    "%3Cline x1='18' y1='20' x2='18' y2='10'/%3E%3Cline x1='12' y1='20' x2='12' y2='4'/%3E%3Cline x1='6' y1='20' x2='6' y2='14'/%3E";
+$ls-i-user:     "%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E";
+$ls-i-bulb:     "%3Cpath d='M9 18h6'/%3E%3Cpath d='M10 22h4'/%3E%3Cpath d='M15.09 14c.18-.98.65-1.74 1.41-2.5A4.65 4.65 0 0 0 18 8 6 6 0 0 0 6 8c0 1 .23 2.23 1.5 3.5.76.76 1.23 1.52 1.41 2.5'/%3E";
+$ls-i-trend:    "%3Cpolyline points='23 6 13.5 15.5 8.5 10.5 1 18'/%3E%3Cpolyline points='17 6 23 6 23 12'/%3E";
+$ls-i-activity: "%3Cpolyline points='22 12 18 12 15 21 9 3 6 12 2 12'/%3E";
+$ls-i-heart:    "%3Cpath d='M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z'/%3E";
+$ls-i-chev:     "%3Cpolyline points='9 18 15 12 9 6'/%3E";
+$ls-i-phone:    "%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.08 4.18 2 2 0 0 1 4.06 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z'/%3E";
+
+// ---- 局部令牌:底色 / 卡片 / 文字 / 描边 ----
+$ls-bg-top:      #FFFDFB;                       // 面板暖白·顶(较原 #fffaf3 更干净)
+$ls-bg-bottom:   #FBF4EA;                       // 面板暖白·底(降饱和)
+$ls-card:        #FFFFFF;                       // 卡片表面
+$ls-card-border: #F0E7DB;                       // 暖发丝描边
+$ls-divider:     #F1EAE0;                       // 发丝分割线
+$ls-overlay:     rgba(20, 15, 8, 0.48);         // 暖调遮罩,非纯黑
+$ls-ink-strong:  $facade-text-strong;           // 主文字 #333
+$ls-ink-body:    $facade-text-body;             // 正文/次级 #666
+$ls-ink-slate:   $facade-text-slate-600;        // 弱文字 #5A6478(全面板 ≥4.5:1,含底部 #FBF4EA)
+$ls-handle:      #8A8A8A;                       // 抓握条(UI affordance,对面板顶 3.40:1 ≥3:1)
+$ls-connector:   $facade-text-slate;            // 步骤连接箭头 #6B7280(对白卡 4.83:1 ≥3:1)
+$ls-brand-deep:  $brand-primary-deep;           // 品牌橙·文字/主CTA #C2410C(对白 5.18:1,AA)
+$ls-ink-on-brand:$ink-on-dark;                  // 橙底白字 #FFFFFF
+$ls-radius-card: $radius-lg;                    // 24rpx 卡片档
+$ls-radius-btn:  $radius-lg;                    // 24rpx 大按钮档
+// 维度标识色(深档,保证白底 ≥3:1;与 uni.scss §12 深档一一对应)
+$ls-dim-body:   #9C4A1A;   // 身·赭石
+$ls-dim-wisdom: $dim-wisdom-deep; // 智·靛蓝(实际编译值 #4F46E5,见 uni.scss L588 二次声明覆盖;对白 6.29:1)
+$ls-dim-wealth: $dim-wealth-deep; // 富·黄土 #92400E
+$ls-dim-action: $dim-action-deep; // 行·森林绿深档 #047857(token 复用)
+$ls-dim-mind:   $dim-mind-deep;   // 心·玫红 #9D174D
+// 维度浅底(uni.scss §13 tint;四步闭环用)
+$ls-dim-wisdom-tint: $dim-wisdom-tint; // 智浅底 #F0F0FF
+$ls-dim-wealth-tint: $dim-wealth-tint; // 富浅底 #FFFBEB
+
 /* ===== 浮层遮罩 ===== */
 .login-sheet-overlay {
   position: fixed;
@@ -233,11 +336,11 @@ export default {
   left: 0;
   right: 0;
   bottom: 0;
-  background: rgba(0, 0, 0, 0.5);
-  z-index: 99999;
+  background: $ls-overlay; // 暖调遮罩,非纯黑
+  z-index: 9999;
   opacity: 0;
   visibility: hidden;
-  transition: opacity 0.25s ease;
+  transition: opacity $uni-transition-base;
 }
 .login-sheet-overlay--visible {
   opacity: 1;
@@ -250,13 +353,13 @@ export default {
   left: 0;
   right: 0;
   bottom: 0;
-  height: 60vh;
-  max-height: 65vh;
-  background: linear-gradient(180deg, #fffaf3 0%, #fff3e4 100%);
-  border-radius: 24rpx 24rpx 0 0;
+  height: 85vh;
+  max-height: 85vh;
+  background: linear-gradient(180deg, $ls-bg-top 0%, $ls-bg-bottom 100%);
+  border-radius: $ls-radius-card $ls-radius-card 0 0;
   overflow: hidden;
   transform: translateY(100%);
-  transition: transform 0.3s ease;
+  transition: transform $uni-transition-slow;
   display: flex;
   flex-direction: column;
 }
@@ -265,14 +368,25 @@ export default {
 }
 
 .login-sheet-header {
-  padding: 24rpx 32rpx 8rpx;
+  padding: $uni-space-lg $uni-space-xl $uni-space-xs;
   display: flex;
-  justify-content: center;
+  flex-direction: column;
+  align-items: center;
+}
+// 抓握条:底部浮层的拖拽 affordance(居中,独立于下方左对齐内容)
+.login-sheet-handle {
+  width: 64rpx;
+  height: 8rpx;
+  border-radius: 999rpx;
+  background: $ls-handle;
 }
 .login-sheet-title {
-  font-size: calc(32rpx * var(--font-scale, 1));
-  font-weight: bold;
-  color: $facade-text-strong;
+  margin-top: $uni-space-md;
+  align-self: flex-start; // R5:标题与品牌区同左锚点
+  font-size: calc($uni-font-size-sm * var(--font-scale, 1));
+  font-weight: $uni-font-weight-medium;
+  letter-spacing: 6rpx;
+  color: $ls-ink-slate;
 }
 
 /* ===== 滚动区域 ===== */
@@ -284,239 +398,290 @@ export default {
 }
 
 .login-sheet-content {
-  padding: 24rpx 48rpx 60rpx;
+  padding: $uni-space-lg $uni-space-xl $uni-space-4xl;
   box-sizing: border-box;
 }
 
-/* ===== 品牌区(左上角锁定版式,与首页一致) ===== */
-.brand-bar {
+/* ===== 品牌区:清晰层级(R5 不对称锚点:左对齐,打破万物居中) ===== */
+.brand-section {
   display: flex;
-  align-items: center;
-  gap: 20rpx;
-  padding: 4rpx 0;
-  box-sizing: border-box;
+  flex-direction: column;
+  align-items: flex-start;
+  padding: $uni-space-md 0 $uni-space-xs;
+}
+.logo {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: $radius-md;
+}
+.app-name {
+  margin-top: $uni-space-lg;
+  font-size: calc($uni-font-size-3xl * var(--font-scale, 1)); // 52rpx 主标题(正文 28rpx 的 1.86x + 收窄行宽)
+  font-weight: $uni-font-weight-black;
+  color: $ls-ink-strong;
+  letter-spacing: 2rpx;
 }
-.brand-logo {
-  width: 80rpx;
-  height: 80rpx;
-  border-radius: 20rpx;
-  background: $app-surface;
-  box-shadow: 0 6rpx 16rpx rgba($brand-primary, 0.18);
-  flex-shrink: 0;
+.identity {
+  margin-top: $uni-space-xs;
+  font-size: calc($uni-font-size-base * var(--font-scale, 1)); // 28rpx 副标语
+  font-weight: $uni-font-weight-medium;
+  color: $ls-brand-deep;
+  letter-spacing: 2rpx;
 }
-.brand-texts {
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  min-width: 0;
-  padding-left: 20rpx;
-  border-left: 2rpx solid rgba($brand-primary, 0.28);
-}
-.brand-name {
-  font-size: calc(38rpx * var(--font-scale, 1));
-  font-weight: bold;
-  color: $facade-text-strong;
-  letter-spacing: 3rpx;
-  line-height: 1.2;
-}
-.brand-tagline {
-  display: block;
-  font-size: calc(22rpx * var(--font-scale, 1));
-  font-weight: 500;
-  color: $brand-primary-deep;
-  margin-top: 6rpx;
-  letter-spacing: 1rpx;
-  line-height: 1.2;
-  white-space: nowrap;
+.slogan {
+  margin-top: $uni-space-md;
+  max-width: 460rpx; // 行宽收窄,形成视觉记忆点
+  font-size: calc($uni-font-size-lg * var(--font-scale, 1)); // 32rpx 主打句
+  line-height: 1.6;
+  color: $ls-ink-body;
+  text-align: left; // 与品牌区左对齐(R5)
+}
+.slogan-accent {
+  color: $ls-brand-deep;
+  font-weight: $uni-font-weight-bold;
 }
 
-/* ===== 理念卡 ===== */
+/* ===== 理念卡(细边框表面区分,无单侧彩条) ===== */
 .concept-card {
-  background: rgba(249, 115, 22, 0.08);
-  border-radius: 24rpx;
-  padding: 24rpx;
-  margin-top: 28rpx;
+  background: $ls-card;
+  border: 1rpx solid $ls-card-border;
+  border-radius: $ls-radius-card;
+  padding: $uni-space-xl;
+  margin-top: $uni-space-2xl;
+}
+.concept-desc {
+  font-size: calc($uni-font-size-base * var(--font-scale, 1));
+  color: $ls-ink-body;
+  line-height: 1.7;
+}
+.concept-highlight {
+  color: $ls-brand-deep;
+  font-weight: $uni-font-weight-bold;
 }
 .loop-row {
   display: flex;
   flex-direction: row;
   align-items: center;
   justify-content: space-between;
-  margin-top: 16rpx;
-  flex-wrap: nowrap;  /* 禁止换行,确保四步/五维在一行 */
-  margin-bottom: 16rpx;
+  margin-top: $uni-space-xl;
+  flex-wrap: nowrap; // 保持四步一行
 }
-.loop-pill {
+.loop-step {
   display: flex;
-  flex-direction: row;
+  flex-direction: column;
   align-items: center;
-  border-radius: 999rpx;
-  padding: 6rpx 12rpx;
-  font-size: calc(22rpx * var(--font-scale, 1));
-  flex-shrink: 0;  /* 防止被压缩导致文本换行 */
+  flex-shrink: 0;
+}
+.loop-glyph {
+  width: 56rpx;
+  height: 56rpx;
+  border-radius: 50%;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 28rpx 28rpx;
+}
+.loop-step-text {
+  margin-top: $uni-space-xs;
+  font-size: calc($uni-font-size-sm * var(--font-scale, 1));
+  color: $ls-ink-slate;
   white-space: nowrap;
 }
-.loop-pill-indigo { background: rgba(99, 102, 241, 0.12); color: $dim-wisdom; }
-.loop-pill-green { background: rgba(16, 185, 129, 0.12); color: $status-success; }
-.loop-pill-amber { background: rgba(245, 158, 11, 0.12); color: $dim-wealth; }
-.loop-pill-red { background: rgba(239, 68, 68, 0.12); color: $status-danger; }
-.loop-pill-text {
-  margin-left: 4rpx;
-  white-space: nowrap;  /* 禁止四字步骤文本换行 */
+// 四步闭环的色相:仅图标圆底着色,文字统一中性(去彩虹)
+.loop-glyph-wisdom {
+  background-color: $ls-dim-wisdom-tint;
+  background-image: ls-icon($ls-dim-wisdom, $ls-i-search);
 }
-.loop-arrow {
-  font-size: calc(24rpx * var(--font-scale, 1));
-  color: $facade-text-ghost-light;
-  padding: 0 2rpx;
-  flex-shrink: 0;  /* 箭头不被压缩 */
+.loop-glyph-success {
+  background-color: $status-success-tint;
+  background-image: ls-icon($status-success-deep, $ls-i-shield);
 }
-
-/* 轨道环:缓慢旋转,呼应 Web 端虚线轨道 */
-.orbit-ring {
-  position: absolute;
-  left: 50%; top: 50%;
-  width: 240rpx; height: 240rpx;
-  margin-left: -120rpx; margin-top: -120rpx;
-  border: 2rpx dashed rgba(194, 112, 61, 0.35);
-  border-radius: 50%;
-  box-sizing: border-box;
-  animation: orbitRingSpin 24s linear infinite;
-}
-@keyframes orbitRingSpin {
-  0%   { transform: rotate(0deg); }
-  100% { transform: rotate(360deg); }
-}
-/* 中心"家"徽章:金色脉冲,呼应 Web 端中心节点 */
-.orbit-center {
-  position: absolute;
-  left: 50%; top: 50%;
-  width: 84rpx; height: 84rpx;
-  margin-left: -42rpx; margin-top: -42rpx;
-  border-radius: 50%;
-  background: #F59E0B;
-  display: flex; align-items: center; justify-content: center;
-  color: #fff; font-size: calc(36rpx * var(--font-scale, 1)); font-weight: 700;
-  box-shadow: 0 0 20rpx rgba(245, 158, 11, 0.4);
-  animation: orbitCenterPulse 3s ease-in-out infinite;
-  z-index: 3;
-}
-@keyframes orbitCenterPulse {
-  0%, 100% { box-shadow: 0 0 20rpx rgba(245, 158, 11, 0.4); transform: scale(1); }
-  50%      { box-shadow: 0 0 36rpx rgba(245, 158, 11, 0.6); transform: scale(1.06); }
-}
-/* 五维公转节点:绕中心旋转,文字保持正立 */
-.orbit-node {
-  position: absolute;
-  left: 50%; top: 50%;
-  width: 76rpx; height: 76rpx;
-  margin-left: -38rpx; margin-top: -38rpx;
-  border-radius: 50%;
-  background: var(--node-color);
-  display: flex; align-items: center; justify-content: center;
-  color: #fff; font-size: calc(30rpx * var(--font-scale, 1)); font-weight: 700;
-  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
-  z-index: 2;
-  animation-duration: 15s;
-  animation-timing-function: linear;
-  animation-iteration-count: infinite;
-}
-.orbit-node-char { line-height: 1; }
-/* 五节点:颜色 + 起始角度 + 错峰延迟,与 Web 端一致 */
-.node-0 { --node-color: #FF8C42; animation-name: orbitNode0; animation-delay: 0s; }    /* 身 */
-.node-1 { --node-color: #1677FF; animation-name: orbitNode1; animation-delay: -3s; }   /* 智 */
-.node-2 { --node-color: #F59E0B; animation-name: orbitNode2; animation-delay: -6s; }   /* 富 */
-.node-3 { --node-color: #10B981; animation-name: orbitNode3; animation-delay: -9s; }   /* 行 */
-.node-4 { --node-color: #FF6B9D; animation-name: orbitNode4; animation-delay: -12s; }  /* 心 */
-
-@keyframes orbitNode0 {
-  0%   { transform: rotate(0deg)   translateX(120rpx) rotate(0deg); }
-  100% { transform: rotate(360deg) translateX(120rpx) rotate(-360deg); }
+.loop-glyph-wealth {
+  background-color: $ls-dim-wealth-tint;
+  background-image: ls-icon($ls-dim-wealth, $ls-i-zap);
+}
+.loop-glyph-danger {
+  background-color: $status-danger-tint-2;
+  background-image: ls-icon($status-danger-strong, $ls-i-chart);
 }
-@keyframes orbitNode1 {
-  0%   { transform: rotate(72deg)   translateX(120rpx) rotate(-72deg); }
-  100% { transform: rotate(432deg)  translateX(120rpx) rotate(-432deg); }
+.loop-connector {
+  width: 20rpx;
+  height: 20rpx;
+  flex-shrink: 0;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 16rpx 16rpx;
+  background-image: ls-icon($ls-connector, $ls-i-chev);
 }
-@keyframes orbitNode2 {
-  0%   { transform: rotate(144deg)  translateX(120rpx) rotate(-144deg); }
-  100% { transform: rotate(504deg)  translateX(120rpx) rotate(-504deg); }
+
+/* ===== 五维标签带:统一容器 + 发丝分割 + 色块记号 ===== */
+.dims-band {
+  display: flex;
+  flex-direction: row;
+  align-items: stretch;
+  background: $ls-card;
+  border: 1rpx solid $ls-card-border;
+  border-radius: $ls-radius-card;
+  margin-top: $uni-space-lg;
+  padding: $uni-space-md 0;
+}
+.dim-cell {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
 }
-@keyframes orbitNode3 {
-  0%   { transform: rotate(216deg)  translateX(120rpx) rotate(-216deg); }
-  100% { transform: rotate(576deg)  translateX(120rpx) rotate(-576deg); }
+.dim-cell + .dim-cell {
+  border-left: 1rpx solid $ls-divider;
 }
-@keyframes orbitNode4 {
-  0%   { transform: rotate(288deg)  translateX(120rpx) rotate(-288deg); }
-  100% { transform: rotate(648deg)  translateX(120rpx) rotate(-648deg); }
+.dim-glyph {
+  width: 36rpx;
+  height: 36rpx;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 30rpx 30rpx;
 }
+.dim-label {
+  margin-top: $uni-space-xs;
+  font-size: calc($uni-font-size-sm * var(--font-scale, 1));
+  color: $ls-ink-body;
+  white-space: nowrap;
+}
+.dim-glyph-body   { background-image: ls-icon($ls-dim-body, $ls-i-user); }
+.dim-glyph-wisdom { background-image: ls-icon($ls-dim-wisdom, $ls-i-bulb); }
+.dim-glyph-wealth { background-image: ls-icon($ls-dim-wealth, $ls-i-trend); }
+.dim-glyph-action { background-image: ls-icon($ls-dim-action, $ls-i-activity); }
+.dim-glyph-mind   { background-image: ls-icon($ls-dim-mind, $ls-i-heart); }
+
+// 主CTA(白字需 4.5:1:品牌橙 #F97316 仅 2.80:1 不达标,取深橙档;渐变更暗端保证全段达标)
+$ls-cta-from: #D1440B;              // 深橙·亮端(白字 4.62:1 达标)
+$ls-cta-to:   $brand-primary-deep;  // 深橙·暗端 #C2410C(白字 5.18:1 达标)
+// hover / active 降档(白字 ≥6.0:1)
+$ls-cta-hover-from: #B93D0B;
+$ls-cta-hover-to:   #A9330A;
+$ls-cta-press-from: #A9330A;
+$ls-cta-press-to:   #962D08;
+// 禁用态:共享 $btn-disabled-bg(#D9D9D9) 对面板仅 1.39:1 不可辨、$btn-disabled-ink 3.78:1 不达 4.5
+// 故在组件局部覆盖为「暖灰底+深字」(不改全局令牌):底 #8E857A 对面板顶/底 3.58/3.32:1 达 ≥3、字 #1A1A1A 达 ≥4.5
+$ls-btn-disabled-bg:  #8E857A;
+$ls-btn-disabled-ink: $text-charcoal;   // #1A1A1A(uni.scss 既有令牌)
+// error/success 视觉态底色(R3 修复:白字需 ≥4.5)
+$ls-btn-error-bg:     $status-danger-strong;   // #B91C1C(白字 6.47:1 达标)
+$ls-btn-success-bg:   $status-success-strong;  // #065F46(白字 7.68:1 达标)
 
 /* ===== 登录表单 ===== */
 .login-form {
-  margin-top: 32rpx;
+  margin-top: $uni-space-2xl;
+}
+.phone-section {
+  display: flex;
+  justify-content: center;
 }
 .phone-btn {
   width: 100%;
-  height: 82rpx;
-  border-radius: 24rpx;
-  background: linear-gradient(135deg, #FFC24A 0%, #FFA726 100%);
-  color: #14458F;
-  font-size: calc(32rpx * var(--font-scale, 1));
-  font-weight: 600;
+  height: 96rpx;
+  border-radius: $ls-radius-btn;
+  background: linear-gradient(135deg, $ls-cta-from 0%, $ls-cta-to 100%);
+  color: $ls-ink-on-brand;
+  font-size: calc($uni-font-size-lg * var(--font-scale, 1));
+  font-weight: $uni-font-weight-bold;
   display: flex;
   flex-direction: row;
   align-items: center;
   justify-content: center;
   border: none;
-  box-shadow: 0 8rpx 20rpx rgba(255, 167, 38, 0.32);
+  box-sizing: border-box;
+  // 八态:default/hover/active/disabled/loading 走令牌;error/success 为待接线 class
+  transition: background-color $duration-fast $ease-standard,
+              transform $duration-fast $ease-standard,
+              opacity $duration-fast $ease-standard;
 }
 .phone-btn::after {
   border: none;
 }
+.phone-btn:hover {
+  background: linear-gradient(135deg, $ls-cta-hover-from 0%, $ls-cta-hover-to 100%); // H5 悬停:再降一档
+}
+.phone-btn:active {
+  transform: scale(0.98);
+  background: linear-gradient(135deg, $ls-cta-press-from 0%, $ls-cta-press-to 100%);
+}
+// R2 修复:键盘焦点可见环(H5 端)。mp-weixin 无键盘焦点,不影响小程序端。
+// 用品牌深橙描边对面板顶 5.10:1 ≥3:1(不纯黑);2px 描边 + 外扩,非内凹模糊
+.phone-btn:focus-visible {
+  outline: 4rpx solid $ls-brand-deep;
+  outline-offset: 4rpx;
+}
+.phone-btn[loading] {
+  background: linear-gradient(135deg, $ls-cta-from 0%, $ls-cta-to 100%); // 保持与 default 一致,spinner 由组件自带
+}
 .phone-btn[disabled] {
-  background: #FFEFD0 !important;
-  color: #B57E2A !important;
+  background: $ls-btn-disabled-bg !important;
+  color: $ls-btn-disabled-ink !important;
 }
-.phone-btn-icon {
-  margin-right: 8rpx;
+// error/success 视觉态(R2/R3 接线:模板 :class 绑定 errorState/successState,默认 false 不触发)
+.phone-btn--error {
+  background: $ls-btn-error-bg !important;
 }
-.phone-btn-text {
-  color: #000000;
+.phone-btn--success {
+  background: $ls-btn-success-bg !important;
 }
-.phone-arrows {
-  margin-left: 10rpx;
-  font-weight: bold;
-  letter-spacing: 2rpx;
-  color: #000000;
-  animation: arrowBlink 1s ease-in-out infinite;
+.phone-btn[disabled].phone-btn--error,
+.phone-btn[disabled].phone-btn--success {
+  background: $ls-btn-disabled-bg !important; // 禁用态优先,error/success 不覆盖
 }
-@keyframes arrowBlink {
-  0%, 100% { opacity: 1; }
-  50% { opacity: 0.15; }
+.phone-btn[disabled] .phone-btn-icon {
+  background-image: ls-icon($ls-btn-disabled-ink, $ls-i-phone);
 }
-
-/* ===== 暂不登录 ===== */
-.skip-section {
-  display: flex;
-  justify-content: center;
-  margin-top: 24rpx;
+.phone-btn--error .phone-btn-icon,
+.phone-btn--success .phone-btn-icon {
+  background-image: ls-icon($ls-ink-on-brand, $ls-i-phone); // 深底白图标,与白字一致
 }
-.skip-btn {
-  font-size: calc(26rpx * var(--font-scale, 1));
-  color: $facade-text-muted;
-  text-decoration: underline;
+.phone-btn-icon {
+  width: 36rpx;
+  height: 36rpx;
+  margin-right: $uni-space-sm;
+  background-repeat: no-repeat;
+  background-position: center;
+  background-size: 32rpx 32rpx;
+  background-image: ls-icon($ls-ink-on-brand, $ls-i-phone);
 }
 
-/* ===== 协议 ===== */
+/* ===== 协议(R5:与品牌区同左锚点,不再居中) ===== */
 .agreement {
   display: flex;
   flex-direction: row;
   align-items: center;
-  justify-content: center;
+  justify-content: flex-start;
   flex-wrap: wrap;
-  margin-top: 24rpx;
-  font-size: calc(24rpx * var(--font-scale, 1));
-  color: $facade-text-muted;
+  margin-top: $uni-space-lg;
+  font-size: calc($uni-font-size-sm * var(--font-scale, 1));
+  color: $ls-ink-slate;
 }
 .link {
-  color: $brand-primary;
+  color: $ls-brand-deep;
+  font-weight: $uni-font-weight-medium;
+}
+
+/* ===== 暂不登录(R5:左对齐) ===== */
+.skip-section {
+  display: flex;
+  justify-content: flex-start;
+  margin-top: $uni-space-lg;
+}
+.skip-btn {
+  font-size: calc($uni-font-size-base * var(--font-scale, 1));
+  color: $ls-ink-slate;
+  text-decoration: underline;
+  padding: $uni-space-xs $uni-space-md; // 扩大点击区
+}
+
+/* ===== 动效降级:尊重 reduced-motion ===== */
+@media (prefers-reduced-motion: reduce) {
+  .login-sheet-overlay,
+  .login-sheet-panel,
+  .phone-btn {
+    transition-duration: 0.01ms;
+  }
 }
-</style>
+</style>