From ec235b9bc18d8dec271811ab7f4045511cd88f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=94=BF=E7=BF=B0?= Date: Fri, 14 Aug 2026 13:04:47 +0800 Subject: [PATCH] feat(web): add mobile download QR to landing page --- frontend/web/public/brand/mobile-download-qr.png | Bin 0 -> 3003 bytes .../web/src/component/landing/LandingPage.jsx | 6 ++++-- frontend/web/src/component/landing/landing.css | 12 +++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 frontend/web/public/brand/mobile-download-qr.png diff --git a/frontend/web/public/brand/mobile-download-qr.png b/frontend/web/public/brand/mobile-download-qr.png new file mode 100644 index 0000000000000000000000000000000000000000..e51d33b3cb16be265a7a2a718b09c87c1e848de9 GIT binary patch literal 3003 zcmZWrdpy&7A0O?tL)pPlp;##+N*7D!I=8tTMlKUwoD(KQ7lmPH#i2qO4%%ieui54j z(nXPT%B3BbHRj2+TFqsVGxy8r`S$$rJkRT#KX&jgzt8*f`DS=};NV-ewn88f zxQnyHN$}hG{i6T_-_`y#bO>bIB^L**Pn_H|ZCloPw2EV3^U>E^gDSdua^68=_S`7K z?M5w%mg|!Ezy0*p=wA~j2ws6@g}n^&=4!9%z-+QiN_+eB>W_tt(JI^5w>g^l}?#Z-q|s zhPWV`S87@A&G2c^(v1&Oo~lCy3N;OErcQP94d^kF`7qj=;%+!X`3%CJmI6Dqq4q)M z4mxIZq;u7F_93~9qIrgsE#*PlkewdFKzm;lid0qh^V@D*$BjrU+QX{ObPpOp8ZXlyC9K%6uw6?TRBU(ks!#imMq=DOm6zc)Sz`HSLTihE~Wa zhULg9cjx!&m0)|$U;MxNa5a`=W~;9I}Ex~5(jTkcoune=_?)hi!d0b)iSD(c)80m8bnPXql~i#xco{+ zI6d5Qw8Uqfxx#0&;_?q>&Q>fJ6|TJr#n_jT?QoRW_61NsR0-Da8}vkSZVK#zNcvF% zMj&CNm`}_e&x1{+2^@|gR?3Sro=@Rkv4#;MTPbeY+@Aak2{#&@qiKD)=h99&_?4Xj zYQ46$l&(vepicd!{rTZZ{ruMN(~KjAcA!9q;hh4uSthEvC|xu)UKUU=N4O?o6`@2I zU>vWz*;<38vQv>^!Z^vXD`)B|8T<{{Gm%4;xsn|GXqVUEqz2Rj-Knu9z*~M+g^!%& zU!7e5y%%uPDYGiAHn)A<1DfBI$f&3&^?Jv6XO^s-h_)}2NvrBBqb7w~>gR+;8?zaA z2kU*ig%LGX1?l5v&Uy7xH`U+TkZ!w+UeR$td>uosTM&HY7M-GljQ`fQ6iagE`xb$_ zeeIy(x5wEX37qw~mZS<NsbREkW>&E*q&$F_$C{nS0}5HcD)|=zC#){eHVlDa)$hp}so7Fq}_WzAHD0Gr*3yaT^Jm=4)&_NTUx>^-~fSEuq*=W@r4l*K68 zcWN0%*OU_-3s|28}mmFw%g#OO$!meNJ%LYUFZ;{88CX^6y1u3xj zf|B(Pr~8pd{W}b(4<(a*3cn z_kQVYOL?Kddx!?iqI*Z#=k|GSCe)qnT91DB>3GokT6F8U+3?ejb@z8)pJXQv6Pi@n z+lR)JUa%~E%wmSF=IL04d^z%Isgb}Ke$hKdv`TYY4@f#IgA2mDiHN846xg#(rRfjt zfYQ6l9RoFhgBqJH7Eg}=<9&Kn*Z4)TDE+83)Z79G8}FPwq-VT#dSMz^mu}jP-VGQSy@&C{0|rp;SKWc?r%#-GQe|&Tsk%Dg z(L`yTQL-~LD%VZQ#RBSR@NNxKtrj(%RJt;07^se4b(zg$5jTf5Z>D({v}yo+8vWJZ zJ$t3LtiHHdm5(&DP#J!<@o<1 zgvw_`P5H1K$&9VZFFqh!qWw6l>?kxIZ7mVdC0+Np9i?PvmNmeeJ~#XJEz&Bb=)9`D zS~eT2Z+#kX+;&3nw?No@io(Gy0Xq7pACO-VG7^xUjn2 zoBosX-L>fo96W$bQPI4nmHMKQ?G7@OWov)0Rt)(c$T079B|KHl{$z z;e_qtjG@8OI6=cMrdPJqI8gn);7=HHPyauh*zNq`I;>E&{@7hNTgsh;>(|Nha;DDL zxA6s&`YB8NNMRh$9<%5oEhns(ujG$$!Okl1IOa+IPr5(#oyVOqb+(Lg3AzTdV-cS+ zZ>CrkoTIOx>xu;1^yqjWeL->CE?{Sm3#@WV@wULof+hOmdsVkwRi=|HyHZmV4_+ z(nW!!+99ii@Wtmz*L}~31_W=B!^}jJR1MHa13y}L4k+uaQ^{=!9jez{#1L^Yi{3(Z)Wbjh(8;e0;E3YW2>)BH5ZEcP!GrlMFvQ*XHhL6Df{}59 z$j|>ffWYsM%0FQ4c2A44uHm?C+&nvDxD?C^{z z9yN^f @@ -271,7 +273,7 @@ export function LandingPage({ onStart, onLogin, onWeb, onSpecialty }) {

PRACTICE FOR REAL LIFE

你想说的,
都可以成为练习。

从日常交流到重要目标,选择一个真实场景,马上进入更有方向的对话。

EVERYDAY ENGLISH

日常场景

点单、购物、出行、住宿和社交,让下次真实交流少一点犹豫。

查看场景

IELTS SPEAKING

IELTS 口语

Part 1、Part 2、Part 3,从回答结构到表达表现,完整练习每一部分。

INTERVIEW PRACTICE

英文面试

用更接近真实面试的方式,练习自我介绍、追问和清晰表达。

-

PRACTICE WHEREVER YOU ARE

电脑前深入练,
手机上随时说。

Web 端适合完整训练和复盘,移动端适合把零碎时间变成开口时间。你的练习路径,会跟着你走。

}>进入 Web 端无需安装,即开即用
app.unispeaking.com
自由对话今天想聊点什么?
{[.25, .5, .8, .43, .68, .32, .58, .92, .44, .7, .35, .62].map((height, index) => )}
开始对话
移动端即将上线把练习放进口袋
Mobile appComing soon
+

PRACTICE WHEREVER YOU ARE

电脑前深入练,
手机上随时说。

Web 端适合完整训练和复盘,移动端适合把零碎时间变成开口时间。扫描二维码,随时把练习带在身边。

}>进入 Web 端Web 与移动端练习同步
app.unispeaking.com
自由对话今天想聊点什么?
{[.25, .5, .8, .43, .68, .32, .58, .92, .44, .7, .35, .62].map((height, index) => )}
开始对话

MEMBERSHIP PREVIEW

先免费开始,
再按你的节奏升级。

免费版足够你建立习惯。需要更长时间、更完整的专项训练时,再选择适合自己的方案。

{plans.map((plan) =>
{plan.id === "pro" ? "最受欢迎" : plan.id === "free" ? "从这里开始" : "目标训练"}

{plan.name}

{plan.id === "pro" && 推荐}

{plan.desc}

{plan.price === "0" ? "免费" : `¥${plan.price}`}{plan.suffix && {plan.suffix}}
    {plan.features.map((feature) =>
  • {feature}
  • )}
}>{plan.id === "free" ? "免费开始" : "加入候补"}
)}

会员支付正在准备中,正式权益和价格以发布版本为准。

diff --git a/frontend/web/src/component/landing/landing.css b/frontend/web/src/component/landing/landing.css index b8346fea..41261767 100644 --- a/frontend/web/src/component/landing/landing.css +++ b/frontend/web/src/component/landing/landing.css @@ -276,13 +276,18 @@ .landing-device--mobile { right: 2%; bottom: 4px; width: 160px; height: 320px; padding: 8px; border: 4px solid #2f2f2d; border-radius: 24px; transform: rotate(4deg); background: #292927; } .landing-device__speaker { position: absolute; z-index: 2; top: 8px; left: 50%; width: 42px; height: 5px; border-radius: 5px; transform: translateX(-50%); background: #30302e; } .landing-device--mobile .landing-device__screen { width: 100%; height: 100%; padding: 44px 14px 22px; display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: 17px; color: #1c1c1b; text-align: center; background: #f4f4f0; } +.landing-mobile-download { text-decoration: none; } .landing-device--mobile img { width: 42px; height: 42px; margin-bottom: 15px; border-radius: 8px; } +.landing-device--mobile .landing-mobile-download__qr { width: 82px; height: 82px; padding: 6px; object-fit: contain; border: 1px solid #deded8; border-radius: 6px; background: #fff; image-rendering: pixelated; } .landing-device--mobile strong { font-size: 11px; } .landing-device--mobile span { margin-top: 6px; color: #83837d; font-size: 8px; } -.landing-device--mobile .landing-device__screen i { width: 40px; height: 40px; margin-top: 28px; display: grid; place-items: center; border: 1px solid #d6d6d0; border-radius: 50%; background: #fff; } +.landing-device--mobile .landing-device__screen i { width: 40px; height: 40px; margin-top: 18px; display: grid; place-items: center; border: 1px solid #d6d6d0; border-radius: 50%; background: #fff; } .landing-device--mobile svg { width: 18px; height: 18px; } -.landing-devices__badge { position: absolute; z-index: 4; right: 32px; bottom: 22px; padding: 10px 12px; display: flex; align-items: center; gap: 9px; border: 1px solid #d6d6d0; border-radius: 7px; color: #282826; background: #fff; box-shadow: 0 16px 34px rgba(0,0,0,.24); } +.landing-devices__badge { position: absolute; z-index: 4; right: 32px; bottom: 22px; padding: 10px 12px; display: flex; align-items: center; gap: 9px; border: 1px solid #d6d6d0; border-radius: 7px; color: #282826; background: #fff; box-shadow: 0 16px 34px rgba(0,0,0,.24); text-decoration: none; transition: transform .2s ease, box-shadow .2s ease; } +.landing-devices__badge:hover { transform: translateY(-2px); box-shadow: 0 20px 40px rgba(0,0,0,.3); } +.landing-devices__badge:focus-visible, .landing-mobile-download:focus-visible { outline: 3px solid var(--landing-yellow); outline-offset: 3px; } .landing-devices__badge svg { width: 21px; height: 21px; } +.landing-devices__badge > svg:last-child { width: 12px; height: 12px; margin-left: 2px; } .landing-devices__badge strong, .landing-devices__badge small { display: block; } .landing-devices__badge strong { font-size: 9px; } .landing-devices__badge small { margin-top: 3px; color: #898983; font-size: 7px; } @@ -470,8 +475,9 @@ .landing-mini-wave { height: 38px; } .landing-device--mobile { right: -2%; width: 112px; height: 230px; border-radius: 20px; } .landing-device--mobile .landing-device__screen { padding-inline: 8px; } + .landing-device--mobile .landing-mobile-download__qr { width: 58px; height: 58px; padding: 5px; margin-bottom: 10px; } .landing-device--mobile strong { font-size: 8px; } - .landing-device--mobile .landing-device__screen i { width: 32px; height: 32px; margin-top: 20px; } + .landing-device--mobile .landing-device__screen i { width: 32px; height: 32px; margin-top: 12px; } .landing-devices__badge { right: 4px; bottom: 2px; } .landing-plan { min-height: 400px; padding: 24px; } .landing-pricing__footnote { align-items: flex-start; text-align: left; line-height: 1.5; }