App.vue 7.88 KB
<script>
export default {
  onLaunch() {
    console.log('绿纤美业会员端启动')
  }
}
</script>

<style lang="scss">
@import '@/styles/mixins.scss';

page {
  min-height: 100%;
  background: $bg-page;
  color: $text-primary;
  font-family: 'PingFang SC', 'Helvetica Neue', sans-serif;
}

view,
text,
button,
image,
scroll-view,
swiper,
swiper-item {
  box-sizing: border-box;
}

button {
  margin: 0;
  padding: 0;
  line-height: 1;
  background: transparent;

  &::after {
    border: 0;
  }
}

.page-shell {
  min-height: 100vh;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.34) 0%, rgba(255, 255, 255, 0.12) 16%, rgba(255, 255, 255, 0) 34%),
    linear-gradient(180deg, rgba(211, 191, 156, 0.05) 0%, rgba(175, 194, 181, 0.045) 42%, $bg-page 100%);
}

.page-shell::before,
.page-shell::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.page-shell::before {
  z-index: 0;
  opacity: 0.45;
  background:
    radial-gradient(circle at 20% 18%, rgba(255, 255, 255, 0.18) 0 2rpx, transparent 2rpx 100%),
    radial-gradient(circle at 78% 30%, rgba(100, 140, 118, 0.08) 0 1.5rpx, transparent 1.5rpx 100%),
    radial-gradient(circle at 36% 68%, rgba(211, 191, 156, 0.10) 0 1.5rpx, transparent 1.5rpx 100%);
  background-size: 180rpx 180rpx, 260rpx 260rpx, 220rpx 220rpx;
  background-repeat: repeat;
  animation: lfAtmosphereShift 20s ease-in-out infinite alternate;
}

.page-shell::after {
  z-index: 0;
  opacity: 0.28;
  background:
    repeating-linear-gradient(
      115deg,
      rgba(255, 255, 255, 0.06) 0,
      rgba(255, 255, 255, 0.06) 2rpx,
      transparent 2rpx,
      transparent 30rpx
    );
  animation: lfAtmosphereGlow 14s ease-in-out infinite alternate;
}

.page-content {
  position: relative;
  z-index: 2;
  padding: calc(var(--status-bar-height, 0px) + 28rpx) $page-padding calc(#{$tabbar-space} + env(safe-area-inset-bottom));
}

.page-content > view:not(.safe-bottom-space),
.page-content > scroll-view,
.page-content > swiper {
  opacity: 0;
  transform: translate3d(0, 22rpx, 0);
  animation: lfRevealUp 720ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.page-content > view:nth-child(1) { animation-delay: 0.04s; }
.page-content > view:nth-child(2) { animation-delay: 0.1s; }
.page-content > view:nth-child(3) { animation-delay: 0.16s; }
.page-content > view:nth-child(4) { animation-delay: 0.22s; }
.page-content > view:nth-child(5) { animation-delay: 0.28s; }
.page-content > view:nth-child(6) { animation-delay: 0.34s; }
.page-content > view:nth-child(7) { animation-delay: 0.4s; }
.page-content > view:nth-child(8) { animation-delay: 0.46s; }
.page-content > view:nth-child(9) { animation-delay: 0.52s; }
.page-content > view:nth-child(10) { animation-delay: 0.58s; }

.page-blur,
.page-blur-secondary,
.page-blur-tertiary {
  position: absolute;
  border-radius: 999rpx;
  filter: blur(16rpx);
  z-index: 1;
}

.page-blur {
  width: 320rpx;
  height: 320rpx;
  top: 80rpx;
  right: -120rpx;
  background: rgba(100, 140, 118, 0.16);
  animation: lfFloatSoft 8.2s ease-in-out infinite;
}

.page-blur-secondary {
  width: 280rpx;
  height: 280rpx;
  left: -100rpx;
  top: 560rpx;
  background: rgba(211, 191, 156, 0.16);
  animation: lfFloatSoft 10.4s ease-in-out infinite 0.9s reverse;
}

.page-blur-tertiary {
  width: 220rpx;
  height: 220rpx;
  right: 50rpx;
  bottom: 240rpx;
  background: rgba(175, 194, 181, 0.12);
  animation: lfPulseSoft 7.6s ease-in-out infinite 1.3s;
}

.safe-bottom-space {
  height: 24rpx;
}

.capsule-safe {
  padding-right: 188rpx;
}

.primary-button {
  @include primary-button;
}

.secondary-button {
  @include secondary-button;
}

.primary-button,
.secondary-button {
  position: relative;
  overflow: hidden;
  white-space: nowrap;
  transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 320ms ease, filter 320ms ease;
}

.primary-button::before,
.secondary-button::before {
  content: '';
  position: absolute;
  left: 20rpx;
  right: 20rpx;
  top: 0;
  height: 1rpx;
  background: rgba(255, 255, 255, 0.34);
  pointer-events: none;
}

.primary-button::after,
.secondary-button::after {
  content: '';
  position: absolute;
  top: -24rpx;
  left: -90rpx;
  width: 72rpx;
  height: calc(100% + 48rpx);
  opacity: 0.34;
  transform: skewX(-20deg);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0));
  animation: lfSheen 4.8s ease-in-out infinite;
  pointer-events: none;
}

.primary-button:active,
.secondary-button:active {
  transform: translateY(1rpx) scale(0.992);
}

.primary-button:active {
  box-shadow: 0 14rpx 30rpx rgba(36, 74, 61, 0.14);
}

.secondary-button:active {
  box-shadow: 0 10rpx 22rpx rgba(54, 77, 64, 0.06);
}

.glass-card {
  @include glass-panel;
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 320ms ease, border-color 320ms ease;
  will-change: transform, box-shadow;
}

.glass-card:active {
  transform: translateY(2rpx) scale(0.996);
  box-shadow: 0 18rpx 38rpx rgba(54, 77, 64, 0.1);
}

.section-head {
  @include section-head;
}

.section-title {
  font-size: 34rpx;
  font-weight: 700;
  color: $text-primary;
}

.section-link {
  font-size: 24rpx;
  color: $brand-accent;
  text-shadow: 0 2rpx 10rpx rgba(210, 191, 156, 0.18);
  transition: transform 240ms ease, opacity 240ms ease;
}

.section-link:active {
  transform: translateX(4rpx);
  opacity: 0.76;
}

.decor-image {
  display: block;
  width: 100%;
}

.lf-tabbar-wrap {
  position: fixed;
  left: 24rpx;
  right: 24rpx;
  bottom: calc(16rpx + env(safe-area-inset-bottom));
  z-index: 30;
}

.lf-tabbar-panel {
  @include glass-panel(0.96);
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 118rpx;
  padding: 12rpx 12rpx 10rpx;
  border-radius: 999rpx;
  box-shadow: $shadow-strong;
  animation: lfRevealUp 780ms cubic-bezier(0.22, 1, 0.36, 1) 0.14s both;
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 320ms ease;
}

.lf-tabbar-item {
  width: 25%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8rpx 0;
  border-radius: 999rpx;
  transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1), background 260ms ease;
}

.lf-tabbar-item:active {
  transform: scale(0.97);
}

.lf-tabbar-item.active {
  background: rgba(255, 255, 255, 0.72);
  transform: translateY(-2rpx);
}

.lf-tabbar-icon-shell {
  width: 78rpx;
  height: 78rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 260ms ease;
}

.lf-tabbar-icon {
  width: 60rpx;
  height: 60rpx;
}

.lf-tabbar-label {
  margin-top: 4rpx;
  font-size: 22rpx;
  color: $text-tertiary;
  font-weight: 500;
  transition: color 260ms ease;
}

.lf-tabbar-item.active .lf-tabbar-icon-shell {
  animation: lfPulseSoft 3.4s ease-in-out infinite;
}

.lf-tabbar-item.active .lf-tabbar-label {
  color: $brand-primary-deep;
  font-weight: 700;
}

@keyframes lfRevealUp {
  from {
    opacity: 0;
    transform: translate3d(0, 22rpx, 0);
  }

  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes lfFloatSoft {
  0%,
  100% {
    transform: translate3d(0, 0, 0) scale(1);
  }

  50% {
    transform: translate3d(0, -18rpx, 0) scale(1.04);
  }
}

@keyframes lfPulseSoft {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }

  50% {
    transform: scale(1.05);
    opacity: 0.9;
  }
}

@keyframes lfAtmosphereShift {
  0% {
    transform: translate3d(0, 0, 0) scale(1);
  }

  100% {
    transform: translate3d(0, -16rpx, 0) scale(1.03);
  }
}

@keyframes lfAtmosphereGlow {
  0% {
    opacity: 0.2;
    transform: translate3d(0, 0, 0);
  }

  100% {
    opacity: 0.34;
    transform: translate3d(-10rpx, 12rpx, 0);
  }
}

@keyframes lfSheen {
  0%,
  15% {
    transform: translateX(0) skewX(-20deg);
    opacity: 0;
  }

  35% {
    opacity: 0.38;
  }

  55%,
  100% {
    transform: translateX(320rpx) skewX(-20deg);
    opacity: 0;
  }
}
</style>