1400 lines
41 KiB
HTML
1400 lines
41 KiB
HTML
<!doctype html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#F5F8EF" />
|
|
<title>来秒AI|让每个行业的灵感,都能一秒成片</title>
|
|
<meta
|
|
name="description"
|
|
content="来秒AI 是面向品牌与创作者的一站式 AI 内容工作流,从电商零售到旅游海报,快速产出可发布的图片。"
|
|
/>
|
|
<link
|
|
rel="icon"
|
|
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='9' fill='%2308482D'/%3E%3Cpath d='M18.6 3 7.5 18h6.7l-1.7 11L24.5 13h-6.6l.7-10Z' fill='%23DAE7C7'/%3E%3C/svg%3E"
|
|
/>
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.cn" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link
|
|
href="https://fonts.googleapis.cn/css2?family=Caveat:wght@600&family=Inter+Tight:wght@700&family=Inter:wght@400;500;600&family=Ma+Shan+Zheng&family=Noto+Sans+SC:wght@400;500;700;900&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
|
|
<style>
|
|
:root {
|
|
--u: min(0.0694444vw, 0.0925926vh);
|
|
--page: #f5f8ef;
|
|
--ink: #101410;
|
|
--forest: #08482d;
|
|
--mint: #dae7c7;
|
|
--muted: #5e5e61;
|
|
--ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
background: var(--page);
|
|
color: var(--ink);
|
|
font-family: Inter, "Noto Sans SC", -apple-system, BlinkMacSystemFont, "PingFang SC",
|
|
"Microsoft YaHei", sans-serif;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
}
|
|
|
|
a {
|
|
color: inherit;
|
|
}
|
|
|
|
.frame {
|
|
position: relative;
|
|
flex: none;
|
|
width: calc(1440 * var(--u));
|
|
height: calc(1080 * var(--u));
|
|
overflow: hidden;
|
|
background: var(--page);
|
|
}
|
|
|
|
.topbar {
|
|
position: absolute;
|
|
inset: 0 0 auto 0;
|
|
height: 0;
|
|
z-index: 20;
|
|
}
|
|
|
|
.logo {
|
|
position: absolute;
|
|
left: calc(37 * var(--u));
|
|
top: calc(36 * var(--u));
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: calc(9 * var(--u));
|
|
color: var(--ink);
|
|
font-size: calc(24 * var(--u));
|
|
font-weight: 700;
|
|
letter-spacing: -0.02em;
|
|
text-decoration: none;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.logo svg {
|
|
display: block;
|
|
width: calc(28 * var(--u));
|
|
height: calc(28 * var(--u));
|
|
}
|
|
|
|
.pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 999px;
|
|
font-weight: 500;
|
|
text-decoration: none;
|
|
transition: background 0.2s ease, transform 0.2s ease;
|
|
}
|
|
|
|
.pill--login {
|
|
position: absolute;
|
|
left: calc(1211 * var(--u));
|
|
top: calc(29 * var(--u));
|
|
width: calc(92 * var(--u));
|
|
height: calc(40 * var(--u));
|
|
border: 1px solid rgba(16, 20, 16, 0.1);
|
|
background: #fff;
|
|
color: var(--ink);
|
|
font-size: calc(15 * var(--u));
|
|
}
|
|
|
|
.pill--signup {
|
|
position: absolute;
|
|
left: calc(1304 * var(--u));
|
|
top: calc(29 * var(--u));
|
|
width: calc(97 * var(--u));
|
|
height: calc(40 * var(--u));
|
|
background: var(--forest);
|
|
color: #fff;
|
|
font-size: calc(15 * var(--u));
|
|
}
|
|
|
|
.pill--login:hover {
|
|
transform: translateY(-1px);
|
|
background: #fbfcf8;
|
|
}
|
|
|
|
.pill--signup:hover {
|
|
transform: translateY(-1px);
|
|
background: #063a24;
|
|
}
|
|
|
|
.headline {
|
|
position: absolute;
|
|
left: 0;
|
|
top: calc(176 * var(--u));
|
|
z-index: 10;
|
|
width: 100%;
|
|
margin: 0;
|
|
color: var(--ink);
|
|
font-family: "Noto Sans SC", "Inter Tight", Inter, sans-serif;
|
|
font-size: calc(72 * var(--u));
|
|
font-weight: 700;
|
|
line-height: calc(80 * var(--u));
|
|
text-align: center;
|
|
}
|
|
|
|
.headline span {
|
|
display: block;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.headline span:first-child {
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.headline span:last-child {
|
|
letter-spacing: -0.015em;
|
|
}
|
|
|
|
.subline {
|
|
position: absolute;
|
|
left: 0;
|
|
top: calc(360 * var(--u));
|
|
z-index: 10;
|
|
width: 100%;
|
|
margin: 0;
|
|
color: var(--muted);
|
|
font-size: calc(18 * var(--u));
|
|
font-weight: 400;
|
|
line-height: calc(27 * var(--u));
|
|
text-align: center;
|
|
}
|
|
|
|
.note {
|
|
position: absolute;
|
|
z-index: 30;
|
|
margin: 0;
|
|
color: var(--forest);
|
|
font-family: "Ma Shan Zheng", Caveat, "Noto Sans SC", cursive;
|
|
font-weight: 400;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.note--seen {
|
|
left: calc(1212 * var(--u));
|
|
top: calc(310 * var(--u));
|
|
font-size: calc(40 * var(--u));
|
|
line-height: 0.96;
|
|
transform: rotate(16deg);
|
|
transform-origin: left top;
|
|
}
|
|
|
|
.note--zero {
|
|
left: calc(492 * var(--u));
|
|
top: calc(944 * var(--u));
|
|
font-size: calc(32 * var(--u));
|
|
line-height: 1;
|
|
transform: rotate(24deg);
|
|
transform-origin: left top;
|
|
}
|
|
|
|
.doodle {
|
|
position: absolute;
|
|
z-index: 30;
|
|
overflow: visible;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.doodle--seen {
|
|
left: calc(1170 * var(--u));
|
|
top: calc(404 * var(--u));
|
|
width: calc(180 * var(--u));
|
|
height: calc(150 * var(--u));
|
|
}
|
|
|
|
.doodle--zero {
|
|
left: calc(596 * var(--u));
|
|
top: calc(955 * var(--u));
|
|
width: calc(34 * var(--u));
|
|
height: calc(28 * var(--u));
|
|
}
|
|
|
|
.doodle path {
|
|
fill: none;
|
|
stroke: var(--forest);
|
|
stroke-linecap: round;
|
|
stroke-linejoin: round;
|
|
stroke-dasharray: 1;
|
|
stroke-dashoffset: 0;
|
|
}
|
|
|
|
.doodle--seen path,
|
|
.doodle--zero path {
|
|
stroke-width: 2.3;
|
|
}
|
|
|
|
.tabs {
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
top: calc(462 * var(--u));
|
|
z-index: 25;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: calc(9 * var(--u));
|
|
}
|
|
|
|
.tab {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: calc(36 * var(--u));
|
|
padding: 0 calc(18 * var(--u));
|
|
border: 1px solid rgba(8, 72, 45, 0.16);
|
|
border-radius: 999px;
|
|
background: rgba(255, 255, 255, 0.55);
|
|
color: var(--forest);
|
|
font-family: inherit;
|
|
font-size: calc(14.5 * var(--u));
|
|
font-weight: 500;
|
|
letter-spacing: 0.01em;
|
|
white-space: nowrap;
|
|
cursor: pointer;
|
|
transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease,
|
|
transform 0.2s ease;
|
|
}
|
|
|
|
.tab:hover {
|
|
border-color: rgba(8, 72, 45, 0.42);
|
|
background: #fff;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.tab:active {
|
|
transform: scale(0.97);
|
|
}
|
|
|
|
.tab.is-active {
|
|
border-color: var(--forest);
|
|
background: var(--forest);
|
|
color: #fff;
|
|
}
|
|
|
|
.tab:focus-visible {
|
|
outline: 2px solid var(--forest);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.cards {
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 5;
|
|
pointer-events: none;
|
|
opacity: 1;
|
|
transition: opacity 0.25s ease;
|
|
}
|
|
|
|
.cards.is-swapping {
|
|
opacity: 0.25;
|
|
}
|
|
|
|
.cards.is-dragging .card {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.card {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
overflow: hidden;
|
|
background: #dfe7d5;
|
|
cursor: grab;
|
|
pointer-events: auto;
|
|
touch-action: pan-y;
|
|
user-select: none;
|
|
-webkit-user-select: none;
|
|
will-change: transform, width, height, clip-path;
|
|
}
|
|
|
|
.card:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.card img {
|
|
position: absolute;
|
|
inset: 0;
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
filter: saturate(0.86) contrast(1.02) brightness(1.02);
|
|
pointer-events: none;
|
|
-webkit-user-drag: none;
|
|
}
|
|
|
|
.card::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
background: linear-gradient(
|
|
180deg,
|
|
rgba(218, 231, 199, 0.08) 0%,
|
|
rgba(218, 231, 199, 0) 40%,
|
|
rgba(8, 72, 45, 0.22) 100%
|
|
);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.cta {
|
|
position: absolute;
|
|
left: calc(626 * var(--u));
|
|
top: calc(936 * var(--u));
|
|
z-index: 30;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: calc(190 * var(--u));
|
|
height: calc(74 * var(--u));
|
|
border: calc(1.6 * var(--u)) dashed rgba(8, 72, 45, 0.5);
|
|
border-radius: 999px;
|
|
}
|
|
|
|
.cta a {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: calc(172 * var(--u));
|
|
height: calc(58 * var(--u));
|
|
border-radius: 999px;
|
|
background: var(--forest);
|
|
color: #fff;
|
|
font-size: calc(18 * var(--u));
|
|
font-weight: 500;
|
|
letter-spacing: 0.02em;
|
|
text-decoration: none;
|
|
transition: background 0.2s ease, transform 0.2s ease;
|
|
}
|
|
|
|
.cta a:hover {
|
|
transform: translateY(-1px);
|
|
background: #063a24;
|
|
}
|
|
|
|
.bottom {
|
|
display: contents;
|
|
}
|
|
|
|
.lightbox {
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 200;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 4vh 5vw;
|
|
background: rgba(6, 26, 18, 0.82);
|
|
-webkit-backdrop-filter: blur(6px);
|
|
backdrop-filter: blur(6px);
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: opacity 0.24s ease, visibility 0.24s ease;
|
|
}
|
|
|
|
.lightbox.is-open {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
.lightbox {
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
}
|
|
|
|
.lightbox__bar {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 8px 10px 8px 16px;
|
|
border-radius: 999px;
|
|
background: rgba(255, 255, 255, 0.12);
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
-webkit-backdrop-filter: blur(8px);
|
|
backdrop-filter: blur(8px);
|
|
}
|
|
|
|
.lightbox__skill {
|
|
color: #fff;
|
|
font-size: calc(13 * var(--u));
|
|
letter-spacing: 0.01em;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.lightbox__skill::before {
|
|
content: "技能 · ";
|
|
color: rgba(255, 255, 255, 0.6);
|
|
}
|
|
|
|
.lightbox__cta {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: calc(34 * var(--u));
|
|
padding: 0 calc(16 * var(--u));
|
|
border: 0;
|
|
border-radius: 999px;
|
|
background: #fff;
|
|
color: var(--forest);
|
|
font-family: inherit;
|
|
font-size: calc(13 * var(--u));
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
cursor: pointer;
|
|
transition: transform 0.2s ease, background 0.2s ease;
|
|
}
|
|
|
|
.lightbox__cta:hover {
|
|
background: var(--mint);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.lightbox__cta:focus-visible {
|
|
outline: 2px solid #fff;
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.card__skill {
|
|
position: absolute;
|
|
left: 50%;
|
|
bottom: calc(10 * var(--u));
|
|
transform: translateX(-50%);
|
|
z-index: 3;
|
|
max-width: calc(100% - calc(16 * var(--u)));
|
|
padding: calc(3 * var(--u)) calc(8 * var(--u));
|
|
border-radius: 999px;
|
|
background: rgba(8, 72, 45, 0.72);
|
|
color: #fff;
|
|
font-size: calc(11 * var(--u));
|
|
line-height: 1.4;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.lightbox__img {
|
|
display: block;
|
|
width: auto;
|
|
height: auto;
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
border-radius: calc(10 * var(--u));
|
|
background: #fff;
|
|
box-shadow: 0 34px 90px -34px rgba(0, 0, 0, 0.65);
|
|
transform: scale(0.94);
|
|
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
|
|
}
|
|
|
|
.lightbox.is-open .lightbox__img {
|
|
transform: scale(1);
|
|
}
|
|
|
|
.lightbox__close {
|
|
position: absolute;
|
|
top: 22px;
|
|
right: 22px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 42px;
|
|
height: 42px;
|
|
padding: 0;
|
|
border: 1px solid rgba(255, 255, 255, 0.28);
|
|
border-radius: 999px;
|
|
background: rgba(255, 255, 255, 0.12);
|
|
color: #fff;
|
|
cursor: pointer;
|
|
transition: background 0.2s ease, transform 0.2s ease;
|
|
}
|
|
|
|
.lightbox__close:hover {
|
|
background: rgba(255, 255, 255, 0.24);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.lightbox__close svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
|
|
.lightbox__close:focus-visible {
|
|
outline: 2px solid #fff;
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
html.has-lightbox,
|
|
html.has-lightbox body {
|
|
overflow: hidden;
|
|
}
|
|
|
|
@media (max-width: 820px) {
|
|
:root {
|
|
--u: 0.15625vw;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
height: auto;
|
|
min-height: 100%;
|
|
}
|
|
|
|
body {
|
|
display: block;
|
|
overflow-x: hidden;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.frame {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
width: 100%;
|
|
height: auto;
|
|
min-height: 100svh;
|
|
padding: 18px 0 26px;
|
|
}
|
|
|
|
.topbar {
|
|
position: static;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
height: auto;
|
|
padding: 0 18px;
|
|
}
|
|
|
|
.logo {
|
|
position: static;
|
|
gap: 8px;
|
|
font-size: 20px;
|
|
}
|
|
|
|
.logo svg {
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
|
|
.pill--login {
|
|
display: none;
|
|
}
|
|
|
|
.pill--signup {
|
|
position: static;
|
|
width: auto;
|
|
height: 38px;
|
|
padding: 0 18px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.headline {
|
|
position: static;
|
|
width: 100%;
|
|
margin: 16px 0 0;
|
|
padding: 0 16px;
|
|
font-size: clamp(34px, 8.2vw, 48px);
|
|
line-height: 1.06;
|
|
}
|
|
|
|
.headline span {
|
|
white-space: normal;
|
|
}
|
|
|
|
.headline span:last-child {
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.lightbox__skill {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.lightbox__cta {
|
|
height: 32px;
|
|
padding: 0 14px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.card__skill {
|
|
bottom: 8px;
|
|
padding: 2px 6px;
|
|
font-size: 10px;
|
|
}
|
|
|
|
.subline {
|
|
position: static;
|
|
width: 100%;
|
|
max-width: 360px;
|
|
margin: 12px auto 0;
|
|
padding: 0 18px;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.subline br {
|
|
display: none;
|
|
}
|
|
|
|
.note--seen,
|
|
.doodle--seen,
|
|
.doodle--zero {
|
|
display: none;
|
|
}
|
|
|
|
.tabs {
|
|
position: static;
|
|
width: 100%;
|
|
margin: 14px 0 0;
|
|
padding: 0 16px;
|
|
gap: 8px;
|
|
}
|
|
|
|
.tab {
|
|
height: 34px;
|
|
padding: 0 14px;
|
|
font-size: 13.5px;
|
|
}
|
|
|
|
.cards {
|
|
position: relative;
|
|
inset: auto;
|
|
flex: none;
|
|
width: min(100%, 420px);
|
|
height: 250px;
|
|
margin: 14px auto 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.bottom {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 12px;
|
|
width: 100%;
|
|
margin-top: auto;
|
|
padding: 20px 18px 0;
|
|
}
|
|
|
|
.note--zero {
|
|
position: static;
|
|
flex: none;
|
|
font-size: 28px;
|
|
transform: rotate(-7deg);
|
|
}
|
|
|
|
.cta {
|
|
position: static;
|
|
flex: none;
|
|
width: 190px;
|
|
height: 74px;
|
|
border-width: 1.6px;
|
|
}
|
|
|
|
.cta a {
|
|
width: 172px;
|
|
height: 58px;
|
|
font-size: 17px;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.cards,
|
|
.card,
|
|
.tab,
|
|
.cta a,
|
|
.pill {
|
|
transition: none;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<main class="frame" id="frame">
|
|
<header class="topbar">
|
|
<a class="logo" href="/" aria-label="返回来秒AI 首页">
|
|
<svg viewBox="0 0 32 32" aria-hidden="true">
|
|
<path d="M19 2 5 19h8l-2 11L27 12h-9l1-10Z" fill="#08482D" />
|
|
<path d="M19 2 11 12" fill="none" stroke="#DAE7C7" stroke-width="1.4" stroke-linecap="round" />
|
|
</svg>
|
|
<span>来秒AI</span>
|
|
</a>
|
|
|
|
<a class="pill pill--login" href="/login/?v=20261107">登录</a>
|
|
<a class="pill pill--signup" href="/login/?v=20261107">免费注册</a>
|
|
</header>
|
|
|
|
<h1 class="headline">
|
|
<span>让每个行业的灵感,</span>
|
|
<span>都能一秒成片</span>
|
|
</h1>
|
|
|
|
<p class="subline">从电商零售,到旅游海报,来秒AI 把创意快速变成可发布的图片。</p>
|
|
|
|
<p class="note note--seen">好内容<br />被看见</p>
|
|
|
|
<svg class="doodle doodle--seen" viewBox="0 0 180 150" aria-hidden="true">
|
|
<path pathLength="1" d="M64 6 C102 38 112 64 82 92 C58 114 52 128 78 144" />
|
|
<path pathLength="1" d="M78 144 L63 131" />
|
|
<path pathLength="1" d="M78 144 L91 128" />
|
|
</svg>
|
|
|
|
<div class="tabs" id="industries" role="tablist" aria-label="选择行业"></div>
|
|
|
|
<div class="cards" id="cards" aria-label="行业案例"></div>
|
|
|
|
<div
|
|
class="lightbox"
|
|
id="lightbox"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-label="案例预览"
|
|
aria-hidden="true"
|
|
>
|
|
<button class="lightbox__close" id="lightboxClose" type="button" aria-label="关闭预览">
|
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
<path
|
|
d="M6 6 18 18M18 6 6 18"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="1.8"
|
|
stroke-linecap="round"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
<img class="lightbox__img" id="lightboxImg" alt="" referrerpolicy="no-referrer" />
|
|
<div class="lightbox__bar">
|
|
<span class="lightbox__skill" id="lightboxSkill"></span>
|
|
<button class="lightbox__cta" id="lightboxCta" type="button">按同样风格生图</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bottom">
|
|
<p class="note note--zero">零成本</p>
|
|
|
|
<svg class="doodle doodle--zero" viewBox="0 0 34 28" aria-hidden="true">
|
|
<path pathLength="1" d="M2 22 C11 22 19 17 30 10" />
|
|
<path pathLength="1" d="M30 10 L21 8" />
|
|
<path pathLength="1" d="M30 10 L25 17" />
|
|
</svg>
|
|
|
|
<div class="cta">
|
|
<a href="/generate">开始创作</a>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<script>
|
|
(function () {
|
|
"use strict";
|
|
|
|
// 每个行业可用的技能(与 team-api skill 库一致),用于图片标注与「按同样风格生图」
|
|
const SKILLS_BY_INDUSTRY = {
|
|
travel: [
|
|
{ id: "travel-general", name: "标准通用风格" },
|
|
{ id: "travel-simple", name: "清新简约风格" },
|
|
{ id: "travel-illustration", name: "插画漫画风格" },
|
|
{ id: "02-skill", name: "家庭亲子风格" },
|
|
{ id: "03-skill", name: "高级杂志封面风格" },
|
|
{ id: "05-skill", name: "视觉冲击风格" },
|
|
],
|
|
ecommerce: [],
|
|
};
|
|
|
|
function buildIndustryImages(id, count) {
|
|
const skills = SKILLS_BY_INDUSTRY[id] || [];
|
|
return Array.from({ length: count }, function (_, index) {
|
|
const skill = skills.length ? skills[index % skills.length] : null;
|
|
return {
|
|
src: "industries/" + id + "/" + String(index + 1).padStart(2, "0") + ".webp",
|
|
skillId: skill ? skill.id : "",
|
|
skillName: skill ? skill.name : "",
|
|
};
|
|
});
|
|
}
|
|
|
|
// 旅游案例墙:按文件名里的风格标注对应技能;展示时不同风格交叉摆放
|
|
const TRIP_BASE = "https://public.laimiaoai.com/laimiao-trip/";
|
|
const TRAVEL_SKILLS = {
|
|
illustration: { id: "travel-illustration", name: "插画漫画风格" },
|
|
simple: { id: "travel-simple", name: "清新简约风格" },
|
|
general: { id: "travel-general", name: "标准通用风格" },
|
|
magazine: { id: "03-skill", name: "高级杂志封面风格" },
|
|
};
|
|
const TRAVEL_GROUPS = [
|
|
{
|
|
skill: "illustration",
|
|
files: ["%E6%8F%92%E7%94%BB1.png", "%E6%8F%92%E7%94%BB10.jpg", "%E6%8F%92%E7%94%BB3.png", "%E6%8F%92%E7%94%BB7.png"],
|
|
},
|
|
{
|
|
skill: "simple",
|
|
files: ["%E7%AE%80%E7%BA%A61.png", "%E7%AE%80%E7%BA%A62.jpg", "%E7%AE%80%E7%BA%A63.jpg"],
|
|
},
|
|
{
|
|
skill: "general",
|
|
files: ["%E9%80%9A%E7%94%A816.jpg", "%E9%80%9A%E7%94%A82.png", "%E9%80%9A%E7%94%A820.png", "%E9%80%9A%E7%94%A823.png", "%E9%80%9A%E7%94%A824.png", "%E9%80%9A%E7%94%A84.png"],
|
|
},
|
|
{
|
|
skill: "magazine",
|
|
files: ["%E9%AB%98%E7%BA%A7%E6%9D%82%E5%BF%97%E9%A3%8E3.png", "%E9%AB%98%E7%BA%A7%E6%9D%82%E5%BF%97%E9%A3%8E4.png", "%E9%AB%98%E7%BA%A7%E6%9D%82%E5%BF%97%E9%A3%8E6.jpg", "%E9%AB%98%E7%BA%A7%E6%9D%82%E5%BF%97%E9%A3%8E6.png"],
|
|
},
|
|
];
|
|
|
|
// 交叉摆放:每一张尽量与上一张风格不同;数量多的风格优先补齐,避免同风格连排
|
|
function interleaveTravelImages(groups) {
|
|
const pools = groups.map(function (group) {
|
|
return { skill: group.skill, items: group.files.slice() };
|
|
});
|
|
const out = [];
|
|
let lastSkill = "";
|
|
while (pools.some(function (pool) { return pool.items.length; })) {
|
|
const remaining = pools.filter(function (pool) { return pool.items.length; });
|
|
const candidates = remaining.filter(function (pool) { return pool.skill !== lastSkill; });
|
|
const pickFrom = candidates.length ? candidates : remaining;
|
|
let chosen = pickFrom[0];
|
|
for (let i = 1; i < pickFrom.length; i++) {
|
|
if (pickFrom[i].items.length > chosen.items.length) chosen = pickFrom[i];
|
|
}
|
|
const file = chosen.items.shift();
|
|
lastSkill = chosen.skill;
|
|
const skill = TRAVEL_SKILLS[chosen.skill];
|
|
out.push({ src: TRIP_BASE + file, skillId: skill.id, skillName: skill.name });
|
|
}
|
|
return out;
|
|
}
|
|
|
|
const TRAVEL_IMAGES = interleaveTravelImages(TRAVEL_GROUPS);
|
|
|
|
const INDUSTRIES = [
|
|
{ id: "travel", name: "旅游", images: TRAVEL_IMAGES },
|
|
{ id: "ecommerce", name: "电商零售", images: buildIndustryImages("ecommerce", 8) },
|
|
];
|
|
|
|
let COUNT = 8;
|
|
const PITCH = 196;
|
|
const RADIUS = 15;
|
|
const SPEED = 50;
|
|
let PERIOD = PITCH * COUNT;
|
|
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
|
|
const layer = document.getElementById("cards");
|
|
const tabsEl = document.getElementById("industries");
|
|
const lightbox = document.getElementById("lightbox");
|
|
const lightboxImg = document.getElementById("lightboxImg");
|
|
const lightboxClose = document.getElementById("lightboxClose");
|
|
const lightboxSkill = document.getElementById("lightboxSkill");
|
|
const lightboxCta = document.getElementById("lightboxCta");
|
|
|
|
const cards = [];
|
|
let activeIndustry = 0;
|
|
let swapTimer = 0;
|
|
let clock = null;
|
|
|
|
let mobile = false;
|
|
let u = 1;
|
|
let cyMobile = 205;
|
|
|
|
let dragging = false;
|
|
let dragOffset = 0;
|
|
let dragStartX = 0;
|
|
let dragStartOffset = 0;
|
|
let lastPointerX = 0;
|
|
let lastPointerTime = 0;
|
|
let releaseVelocity = 0;
|
|
let downX = 0;
|
|
let downY = 0;
|
|
let moved = false;
|
|
|
|
let autoOrigin = 0;
|
|
let flingOffset = 0;
|
|
let flingVelocity = 0;
|
|
let lastFrame = 0;
|
|
|
|
function makeCard(industry, index) {
|
|
const el = document.createElement("div");
|
|
el.className = "card";
|
|
el.dataset.index = String(index);
|
|
el.setAttribute("role", "button");
|
|
el.setAttribute("tabindex", "0");
|
|
el.setAttribute("aria-label", "放大预览:" + industry.name + "案例 " + (index + 1));
|
|
|
|
const item = industry.images[index];
|
|
const img = document.createElement("img");
|
|
img.alt = industry.name + "案例 " + (index + 1);
|
|
img.draggable = false;
|
|
img.decoding = "async";
|
|
img.referrerPolicy = "no-referrer";
|
|
|
|
el.appendChild(img);
|
|
|
|
const badge = document.createElement("span");
|
|
badge.className = "card__skill";
|
|
badge.textContent = (item && item.skillName) || industry.name;
|
|
el.appendChild(badge);
|
|
|
|
layer.appendChild(el);
|
|
|
|
cards.push({ index, el, img, src: item ? item.src : "" });
|
|
}
|
|
|
|
function buildCards(industry) {
|
|
layer.textContent = "";
|
|
cards.length = 0;
|
|
COUNT = industry.images.length;
|
|
PERIOD = PITCH * (COUNT || 1);
|
|
|
|
for (let i = 0; i < COUNT; i++) makeCard(industry, i);
|
|
}
|
|
|
|
buildCards(INDUSTRIES[0]);
|
|
|
|
function buildTabs() {
|
|
for (let i = 0; i < INDUSTRIES.length; i++) {
|
|
const button = document.createElement("button");
|
|
button.type = "button";
|
|
button.className = "tab" + (i === 0 ? " is-active" : "");
|
|
button.textContent = INDUSTRIES[i].name;
|
|
button.setAttribute("role", "tab");
|
|
button.setAttribute("aria-selected", i === 0 ? "true" : "false");
|
|
button.addEventListener("click", function () {
|
|
selectIndustry(i);
|
|
});
|
|
tabsEl.appendChild(button);
|
|
}
|
|
}
|
|
|
|
function selectIndustry(index) {
|
|
if (index === activeIndustry) return;
|
|
activeIndustry = index;
|
|
|
|
for (let i = 0; i < tabsEl.children.length; i++) {
|
|
const tab = tabsEl.children[i];
|
|
tab.classList.toggle("is-active", i === index);
|
|
tab.setAttribute("aria-selected", i === index ? "true" : "false");
|
|
}
|
|
|
|
const industry = INDUSTRIES[index];
|
|
window.clearTimeout(swapTimer);
|
|
layer.classList.add("is-swapping");
|
|
|
|
swapTimer = window.setTimeout(function () {
|
|
buildCards(industry);
|
|
layer.classList.remove("is-swapping");
|
|
}, 180);
|
|
}
|
|
|
|
function preloadIndustries() {
|
|
for (let i = 0; i < INDUSTRIES.length; i++) {
|
|
if (i === activeIndustry) continue;
|
|
const images = INDUSTRIES[i].images;
|
|
for (let j = 0; j < images.length; j++) {
|
|
const image = new Image();
|
|
image.referrerPolicy = "no-referrer";
|
|
image.src = images[j] && images[j].src ? images[j].src : images[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
function roundedQuad(points, radius) {
|
|
const n = points.length;
|
|
let d = "";
|
|
for (let i = 0; i < n; i++) {
|
|
const point = points[i];
|
|
const prev = points[(i - 1 + n) % n];
|
|
const next = points[(i + 1) % n];
|
|
|
|
const v1x = prev.x - point.x;
|
|
const v1y = prev.y - point.y;
|
|
const v2x = next.x - point.x;
|
|
const v2y = next.y - point.y;
|
|
const l1 = Math.hypot(v1x, v1y) || 1;
|
|
const l2 = Math.hypot(v2x, v2y) || 1;
|
|
const r = Math.min(radius, l1 / 2, l2 / 2);
|
|
|
|
const ax = point.x + (v1x / l1) * r;
|
|
const ay = point.y + (v1y / l1) * r;
|
|
const bx = point.x + (v2x / l2) * r;
|
|
const by = point.y + (v2y / l2) * r;
|
|
|
|
d += (i === 0 ? "M" : "L") + ax.toFixed(2) + " " + ay.toFixed(2);
|
|
d += "Q" + point.x.toFixed(2) + " " + point.y.toFixed(2) + " " + bx.toFixed(2) + " " + by.toFixed(2);
|
|
}
|
|
return d + "Z";
|
|
}
|
|
|
|
function measure() {
|
|
mobile = window.matchMedia("(max-width: 820px)").matches;
|
|
if (mobile) {
|
|
const height = layer.clientHeight || 250;
|
|
u = (layer.clientWidth || window.innerWidth) / 640;
|
|
cyMobile = height / u / 2;
|
|
} else {
|
|
u = Math.min(window.innerWidth / 1440, window.innerHeight / 1080);
|
|
}
|
|
}
|
|
|
|
function offsetNow() {
|
|
if (dragging) return dragOffset;
|
|
const t = clock ? clock.currentTime / 1000 : 0;
|
|
return (reduceMotion ? 0 : SPEED * t) + autoOrigin + flingOffset;
|
|
}
|
|
|
|
function render() {
|
|
const offset = offsetNow();
|
|
const cx = mobile ? 320 : 720;
|
|
const norm = mobile ? 314 : 706;
|
|
const baseCy = mobile ? cyMobile : 715;
|
|
const frameW = mobile ? 640 : 1440;
|
|
|
|
for (let i = 0; i < cards.length; i++) {
|
|
const card = cards[i];
|
|
let raw = (card.index * PITCH - offset) % PERIOD;
|
|
raw = ((raw % PERIOD) + PERIOD) % PERIOD;
|
|
const t = raw >= PERIOD / 2 ? raw - PERIOD : raw;
|
|
|
|
const x = cx + t * (1 + 0.083 * Math.pow(t / norm, 2));
|
|
const d = Math.abs(x - cx) / norm;
|
|
const w = 170 + 48 * d * d;
|
|
const cy = baseCy - 12 * d * d;
|
|
|
|
const xL = x - w / 2;
|
|
const xR = x + w / 2;
|
|
if (!card.img.getAttribute("src") && xR > -460 && xL < frameW + 460) {
|
|
card.img.src = card.src;
|
|
}
|
|
if (xR < -20 || xL > frameW + 20) {
|
|
card.el.style.visibility = "hidden";
|
|
continue;
|
|
}
|
|
card.el.style.visibility = "visible";
|
|
|
|
const qL = Math.abs(xL - cx) / norm;
|
|
const qR = Math.abs(xR - cx) / norm;
|
|
let hL = 280 + 92 * Math.pow(qL, 2.6);
|
|
let hR = 280 + 92 * Math.pow(qR, 2.6);
|
|
if (mobile) {
|
|
const cap = cyMobile * 1.76;
|
|
hL = Math.min(hL, cap);
|
|
hR = Math.min(hR, cap);
|
|
}
|
|
const h = Math.max(hL, hR);
|
|
|
|
const wPx = w * u;
|
|
const hPx = h * u;
|
|
|
|
card.el.style.width = wPx + "px";
|
|
card.el.style.height = hPx + "px";
|
|
card.el.style.transform =
|
|
"translate3d(" + xL * u + "px," + (cy - h / 2) * u + "px,0)";
|
|
|
|
const points = [
|
|
{ x: 0, y: ((h - hL) / 2) * u },
|
|
{ x: wPx, y: ((h - hR) / 2) * u },
|
|
{ x: wPx, y: ((h + hR) / 2) * u },
|
|
{ x: 0, y: ((h + hL) / 2) * u },
|
|
];
|
|
const clip = 'path("' + roundedQuad(points, RADIUS * u) + '")';
|
|
card.el.style.clipPath = clip;
|
|
card.el.style.webkitClipPath = clip;
|
|
}
|
|
}
|
|
|
|
let lightboxItem = null;
|
|
let lightboxIndustry = null;
|
|
|
|
function openLightbox(index) {
|
|
const industry = INDUSTRIES[activeIndustry];
|
|
const item = industry.images[index];
|
|
if (!item) return;
|
|
|
|
lightboxItem = item;
|
|
lightboxIndustry = industry;
|
|
lightboxImg.src = item.src;
|
|
lightboxImg.alt = industry.name + "案例 " + (index + 1);
|
|
lightboxSkill.textContent = item.skillName || industry.name;
|
|
lightbox.classList.add("is-open");
|
|
lightbox.setAttribute("aria-hidden", "false");
|
|
document.documentElement.classList.add("has-lightbox");
|
|
|
|
if (lightboxClose) lightboxClose.focus({ preventScroll: true });
|
|
}
|
|
|
|
function startWithSameSkill() {
|
|
if (!lightboxIndustry) return;
|
|
const params = new URLSearchParams();
|
|
if (lightboxItem && lightboxItem.skillId) params.set("skill", lightboxItem.skillId);
|
|
if (lightboxIndustry.name) params.set("industry", lightboxIndustry.name);
|
|
const target = "/generate" + (params.toString() ? "?" + params.toString() : "");
|
|
goEntry(target);
|
|
}
|
|
|
|
function closeLightbox() {
|
|
if (!lightbox.classList.contains("is-open")) return;
|
|
lightbox.classList.remove("is-open");
|
|
lightbox.setAttribute("aria-hidden", "true");
|
|
document.documentElement.classList.remove("has-lightbox");
|
|
}
|
|
|
|
function onPointerDown(event) {
|
|
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
const current = offsetNow();
|
|
autoOrigin = current - (reduceMotion ? 0 : SPEED * (clock.currentTime / 1000));
|
|
flingOffset = 0;
|
|
flingVelocity = 0;
|
|
|
|
dragging = true;
|
|
dragOffset = current;
|
|
dragStartX = event.clientX;
|
|
dragStartOffset = current;
|
|
lastPointerX = event.clientX;
|
|
lastPointerTime = performance.now();
|
|
releaseVelocity = 0;
|
|
downX = event.clientX;
|
|
downY = event.clientY;
|
|
moved = false;
|
|
|
|
layer.classList.add("is-dragging");
|
|
if (layer.setPointerCapture) {
|
|
try {
|
|
layer.setPointerCapture(event.pointerId);
|
|
} catch (error) {
|
|
/* capture can fail when the pointer is already released */
|
|
}
|
|
}
|
|
}
|
|
|
|
function onPointerMove(event) {
|
|
if (!dragging) return;
|
|
if (Math.abs(event.clientX - downX) > 6 || Math.abs(event.clientY - downY) > 6) moved = true;
|
|
const dx = event.clientX - dragStartX;
|
|
dragOffset = dragStartOffset - dx / u;
|
|
|
|
const now = performance.now();
|
|
const dt = Math.max(8, now - lastPointerTime);
|
|
releaseVelocity = (-(event.clientX - lastPointerX) / u) / (dt / 1000);
|
|
lastPointerX = event.clientX;
|
|
lastPointerTime = now;
|
|
}
|
|
|
|
function onPointerUp(event) {
|
|
if (!dragging) return;
|
|
dragging = false;
|
|
layer.classList.remove("is-dragging");
|
|
|
|
if (layer.hasPointerCapture && layer.hasPointerCapture(event.pointerId)) {
|
|
layer.releasePointerCapture(event.pointerId);
|
|
}
|
|
|
|
autoOrigin = dragOffset - (reduceMotion ? 0 : SPEED * (clock.currentTime / 1000));
|
|
flingOffset = 0;
|
|
|
|
const limit = 2600;
|
|
releaseVelocity = Math.max(-limit, Math.min(limit, releaseVelocity));
|
|
flingVelocity = reduceMotion || Math.abs(releaseVelocity) < 24 ? 0 : releaseVelocity;
|
|
|
|
if (!moved) {
|
|
const hit = document.elementFromPoint(event.clientX, event.clientY);
|
|
const cardEl = hit && hit.closest ? hit.closest(".card") : null;
|
|
if (cardEl && layer.contains(cardEl)) openLightbox(Number(cardEl.dataset.index));
|
|
}
|
|
}
|
|
|
|
function frameLoop(now) {
|
|
const dt = Math.min(0.05, lastFrame ? (now - lastFrame) / 1000 : 0);
|
|
lastFrame = now;
|
|
|
|
if (!dragging && !reduceMotion && flingVelocity !== 0) {
|
|
flingOffset += flingVelocity * dt;
|
|
flingVelocity *= Math.pow(0.05, dt);
|
|
if (Math.abs(flingVelocity) < 2) flingVelocity = 0;
|
|
}
|
|
|
|
render();
|
|
requestAnimationFrame(frameLoop);
|
|
}
|
|
|
|
function entrance() {
|
|
if (reduceMotion) return;
|
|
const topbar = document.querySelector(".topbar");
|
|
const lines = document.querySelectorAll(".headline span");
|
|
const subline = document.querySelector(".subline");
|
|
const tabs = document.querySelector(".tabs");
|
|
const cta = document.querySelector(".cta");
|
|
const notes = document.querySelectorAll(".note");
|
|
const doodles = document.querySelectorAll(".doodle path");
|
|
|
|
const ease = "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
const animate = function (el, frames, options) {
|
|
el.animate(frames, Object.assign({ fill: "backwards", easing: ease }, options));
|
|
};
|
|
|
|
animate(
|
|
topbar,
|
|
[
|
|
{ opacity: 0, transform: "translateY(-18px)" },
|
|
{ opacity: 1, transform: "translateY(0)" },
|
|
],
|
|
{ duration: 700 },
|
|
);
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
animate(
|
|
lines[i],
|
|
[
|
|
{ opacity: 0, transform: "translateY(" + 26 * u + "px)", filter: "blur(10px)" },
|
|
{ opacity: 1, transform: "translateY(0)", filter: "blur(0px)" },
|
|
],
|
|
{ duration: 850, delay: 300 + i * 110 },
|
|
);
|
|
}
|
|
|
|
animate(
|
|
subline,
|
|
[
|
|
{ opacity: 0, transform: "translateY(" + 16 * u + "px)" },
|
|
{ opacity: 1, transform: "translateY(0)" },
|
|
],
|
|
{ duration: 700, delay: 560 },
|
|
);
|
|
|
|
animate(
|
|
tabs,
|
|
[
|
|
{ opacity: 0, transform: "translateY(" + 10 * u + "px)" },
|
|
{ opacity: 1, transform: "translateY(0)" },
|
|
],
|
|
{ duration: 650, delay: 630 },
|
|
);
|
|
|
|
animate(
|
|
layer,
|
|
[
|
|
{ opacity: 0, transform: "translateY(" + 64 * u + "px)" },
|
|
{ opacity: 1, transform: "translateY(0)" },
|
|
],
|
|
{ duration: 900, delay: 720 },
|
|
);
|
|
|
|
animate(
|
|
cta,
|
|
[
|
|
{ opacity: 0, transform: "scale(0.9)" },
|
|
{ opacity: 1, transform: "scale(1)" },
|
|
],
|
|
{ duration: 600, delay: 940 },
|
|
);
|
|
|
|
for (let i = 0; i < doodles.length; i++) {
|
|
animate(
|
|
doodles[i],
|
|
[{ strokeDashoffset: 1 }, { strokeDashoffset: 0 }],
|
|
{ duration: 650, delay: 1040 + i * 80 },
|
|
);
|
|
}
|
|
|
|
for (let i = 0; i < notes.length; i++) {
|
|
animate(notes[i], [{ opacity: 0 }, { opacity: 1 }], {
|
|
duration: 700,
|
|
delay: 1240 + i * 120,
|
|
});
|
|
}
|
|
}
|
|
|
|
clock = document.documentElement.animate([{ opacity: 1 }, { opacity: 1 }], {
|
|
duration: 1e9,
|
|
iterations: 1,
|
|
});
|
|
|
|
buildTabs();
|
|
measure();
|
|
requestAnimationFrame(frameLoop);
|
|
entrance();
|
|
|
|
window.setTimeout(preloadIndustries, 900);
|
|
|
|
layer.addEventListener("pointerdown", onPointerDown);
|
|
layer.addEventListener("pointermove", onPointerMove);
|
|
layer.addEventListener("pointerup", onPointerUp);
|
|
layer.addEventListener("pointercancel", onPointerUp);
|
|
|
|
layer.addEventListener("keydown", function (event) {
|
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
const cardEl = event.target && event.target.closest ? event.target.closest(".card") : null;
|
|
if (!cardEl) return;
|
|
event.preventDefault();
|
|
openLightbox(Number(cardEl.dataset.index));
|
|
});
|
|
|
|
if (lightboxCta) lightboxCta.addEventListener("click", startWithSameSkill);
|
|
|
|
lightbox.addEventListener("click", function (event) {
|
|
if (event.target === lightbox) {
|
|
closeLightbox();
|
|
return;
|
|
}
|
|
if (event.target.closest && event.target.closest("#lightboxClose")) closeLightbox();
|
|
});
|
|
|
|
document.addEventListener("keydown", function (event) {
|
|
if (event.key === "Escape") closeLightbox();
|
|
});
|
|
|
|
let resizeTimer = 0;
|
|
window.addEventListener("resize", function () {
|
|
window.clearTimeout(resizeTimer);
|
|
resizeTimer = window.setTimeout(measure, 120);
|
|
});
|
|
|
|
function isLoggedIn() {
|
|
return !!localStorage.getItem("access_token");
|
|
}
|
|
|
|
function goEntry(target) {
|
|
const dest = target || "/generate";
|
|
if (isLoggedIn()) {
|
|
window.location.href = dest;
|
|
return;
|
|
}
|
|
const params = new URLSearchParams({ v: "20261107", redirect: dest });
|
|
window.location.href = "/login/?" + params.toString();
|
|
}
|
|
|
|
document.querySelectorAll("a.pill--login, a.pill--signup").forEach(function (link) {
|
|
link.addEventListener("click", function (event) {
|
|
event.preventDefault();
|
|
goEntry("/generate");
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('a[href="/generate"]').forEach(function (link) {
|
|
link.addEventListener("click", function (event) {
|
|
event.preventDefault();
|
|
goEntry(link.getAttribute("href") || "/generate");
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|