feat: iOS appearance, iPad logo fix, demo seed, and landing hero polish

Add System/Light/Dark preference for iPhone and iPad, restore the iPad
sidebar brand mark, ship a DEBUG seed-demo URL for rich placeholder data,
and refresh GitHub Pages with the device composite, full-bleed pale-green
hero wash, and transparent Mac screenshot chrome.
This commit is contained in:
Rocky
2026-07-12 16:24:59 +08:00
parent a57bba9ea0
commit c598ba77e6
18 changed files with 424 additions and 220 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 176 KiB

+35 -218
View File
@@ -41,6 +41,7 @@
--bg: #f7f7f5;
--bg-elevated: #ffffff;
--bg-soft: #efefec;
--hero-wash: #e7f3eb;
--text: #121214;
--text-2: #5a5a62;
--text-3: #8e8e96;
@@ -60,6 +61,7 @@
--bg: #0a0a0b;
--bg-elevated: #131316;
--bg-soft: #18181b;
--hero-wash: #102018;
--text: #f4f4f2;
--text-2: #a8a8b0;
--text-3: #6f6f78;
@@ -77,6 +79,7 @@
--bg: #0a0a0b;
--bg-elevated: #131316;
--bg-soft: #18181b;
--hero-wash: #102018;
--text: #f4f4f2;
--text-2: #a8a8b0;
--text-3: #6f6f78;
@@ -219,24 +222,15 @@
/* —— Hero —— */
.hero {
position: relative;
padding: 4.5rem 0 2rem;
/* Full-bleed solid wash (no side gaps from inset gradients). */
background: var(--hero-wash);
padding: 4.5rem 0 2.5rem;
overflow: hidden;
}
.hero::before {
content: "";
position: absolute;
inset: -20% 10% auto;
height: 70%;
background:
radial-gradient(ellipse at 30% 40%, var(--accent-soft), transparent 55%),
radial-gradient(ellipse at 75% 20%, rgba(47, 154, 82, 0.08), transparent 50%);
pointer-events: none;
z-index: 0;
}
.hero .wrap { position: relative; z-index: 1; }
.hero-copy {
max-width: 42rem;
margin: 0 auto 3rem;
margin: 0 auto 2.5rem;
text-align: center;
}
.eyebrow {
@@ -286,176 +280,19 @@
}
.hero-meta .material-symbols-outlined { font-size: 16px; color: var(--accent); }
/* —— Hero device family (Mac + iPad + iPhone) —— */
/* Marketing device-family composite (replaces CSS mockup frames). */
.hero-stage {
position: relative;
margin-top: 2.75rem;
margin: 2.25rem auto 0;
max-width: 1080px;
margin-left: auto;
margin-right: auto;
}
.device-cluster {
position: relative;
width: 100%;
aspect-ratio: 16 / 10;
min-height: 280px;
transform: translateY(16px);
opacity: 0;
animation: rise-in 1s cubic-bezier(0.22, 1, 0.36, 1) 0.12s forwards;
--device-shell: #1c1c1e;
--device-shell-2: #2c2c2e;
--device-edge: rgba(255, 255, 255, 0.14);
--device-shadow: 0 28px 60px rgba(0, 0, 0, 0.28);
}
html[data-theme="light"] .device-cluster {
--device-shell: #d8d8dc;
--device-shell-2: #c4c4c8;
--device-edge: rgba(0, 0, 0, 0.12);
--device-shadow: 0 24px 50px rgba(18, 18, 20, 0.16);
}
@media (prefers-color-scheme: light) {
html[data-theme="system"] .device-cluster {
--device-shell: #d8d8dc;
--device-shell-2: #c4c4c8;
--device-edge: rgba(0, 0, 0, 0.12);
--device-shadow: 0 24px 50px rgba(18, 18, 20, 0.16);
}
}
.device {
position: absolute;
box-sizing: border-box;
}
.device img {
display: block;
.hero-stage img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: top center;
}
/* MacBook — back right */
.device-mac {
right: 0;
top: 4%;
width: 72%;
z-index: 1;
filter: drop-shadow(var(--device-shadow));
}
.mac-lid {
border-radius: 10px 10px 0 0;
background: linear-gradient(180deg, var(--device-shell-2), var(--device-shell));
padding: 1.4% 1.4% 0.9%;
border: 1px solid var(--device-edge);
border-bottom: none;
}
.mac-bezel {
position: relative;
border-radius: 6px 6px 2px 2px;
overflow: hidden;
background: #000;
aspect-ratio: 16 / 10;
}
.mac-notch {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 18%;
height: 3.2%;
max-height: 12px;
background: #0a0a0b;
border-radius: 0 0 7px 7px;
z-index: 2;
}
.mac-screen {
position: absolute;
inset: 0;
overflow: hidden;
}
.mac-base {
height: 10px;
margin: 0 -1.5% 0;
border-radius: 0 0 10px 10px;
background: linear-gradient(180deg, var(--device-shell), var(--device-shell-2));
border: 1px solid var(--device-edge);
border-top: none;
position: relative;
}
.mac-base::after {
content: "";
position: absolute;
left: 50%;
top: 2px;
transform: translateX(-50%);
width: 16%;
height: 4px;
border-radius: 0 0 4px 4px;
background: rgba(0, 0, 0, 0.22);
}
/* iPad — center */
.device-ipad {
left: 22%;
top: 18%;
width: 36%;
z-index: 2;
filter: drop-shadow(0 22px 40px rgba(0, 0, 0, 0.22));
}
.ipad-bezel {
border-radius: 18px;
background: linear-gradient(160deg, var(--device-shell-2), var(--device-shell));
padding: 2.2%;
border: 1px solid var(--device-edge);
}
.ipad-screen {
border-radius: 10px;
overflow: hidden;
background: #000;
aspect-ratio: 3 / 4;
}
/* iPhone — front left */
.device-phone {
left: 4%;
bottom: 2%;
width: 20%;
z-index: 3;
filter: drop-shadow(0 18px 32px rgba(0, 0, 0, 0.26));
}
.phone-bezel {
position: relative;
border-radius: 22px;
background: linear-gradient(160deg, var(--device-shell-2), var(--device-shell));
padding: 3.2%;
border: 1px solid var(--device-edge);
}
.phone-island {
position: absolute;
top: 5.5%;
left: 50%;
transform: translateX(-50%);
width: 32%;
height: 3.8%;
border-radius: 20px;
background: #0a0a0b;
z-index: 2;
}
.phone-screen {
border-radius: 16px;
overflow: hidden;
background: #000;
aspect-ratio: 9 / 19.5;
}
@media (max-width: 720px) {
.device-cluster { aspect-ratio: 5 / 4; }
.device-mac { width: 78%; right: -2%; top: 0; }
.device-ipad { width: 42%; left: 14%; top: 22%; }
.device-phone { width: 26%; left: 2%; bottom: 0; }
.phone-bezel { border-radius: 18px; }
.phone-screen { border-radius: 12px; }
.ipad-bezel { border-radius: 14px; }
height: auto;
display: block;
}
@keyframes rise-in {
@@ -588,12 +425,13 @@
}
.shot {
margin: 0;
border-radius: 16px;
overflow: hidden;
border: 1px solid var(--line);
background: var(--bg-elevated);
box-shadow: var(--shadow);
line-height: 0;
/* Desktop/Mac window PNGs already include chrome — no card fill behind them. */
border: none;
background: transparent;
box-shadow: none;
border-radius: 0;
overflow: visible;
}
.shot img {
width: 100%;
@@ -605,6 +443,10 @@
max-width: 300px;
width: 100%;
margin-inline: auto;
overflow: hidden;
border: 1px solid var(--line);
background: var(--bg-elevated);
box-shadow: var(--shadow);
}
/* —— Device strip —— */
@@ -617,12 +459,12 @@
}
.device-card {
margin: 0;
border-radius: 16px;
overflow: hidden;
border: 1px solid var(--line);
background: var(--bg-elevated);
box-shadow: var(--shadow);
line-height: 0;
border: none;
background: transparent;
box-shadow: none;
border-radius: 0;
overflow: visible;
}
.device-card img {
width: 100%;
@@ -637,6 +479,10 @@
flex: 0 0 auto;
width: min(260px, 46vw);
border-radius: 26px;
overflow: hidden;
border: 1px solid var(--line);
background: var(--bg-elevated);
box-shadow: var(--shadow);
}
.device-caption {
margin-top: 0.65rem;
@@ -661,9 +507,7 @@
.compare {
border-radius: calc(var(--radius) + 4px);
border: 1px solid var(--line);
background:
linear-gradient(180deg, var(--accent-soft), transparent 42%),
var(--bg-elevated);
background: var(--hero-wash);
padding: 2rem 1.5rem;
overflow: hidden;
}
@@ -793,7 +637,7 @@
transition: none !important;
}
.reveal { opacity: 1; transform: none; }
.device-cluster { opacity: 1; transform: none; }
.hero-stage { opacity: 1; transform: none; }
}
</style>
</head>
@@ -857,34 +701,7 @@
</div>
<div class="hero-stage" aria-label="OSGKeyboard on Mac, iPad, and iPhone">
<div class="device-cluster">
<div class="device device-mac">
<div class="mac-lid">
<div class="mac-bezel">
<div class="mac-notch" aria-hidden="true"></div>
<div class="mac-screen">
<img data-shot="mac-dashboard" src="assets/screenshots/zh/dark/mac-dashboard.png" width="1440" height="900" alt="OSGKeyboard on Mac" loading="eager">
</div>
</div>
</div>
<div class="mac-base" aria-hidden="true"></div>
</div>
<div class="device device-ipad">
<div class="ipad-bezel">
<div class="ipad-screen">
<img data-shot="ipad-home" src="assets/screenshots/zh/light/ipad-home.png" width="800" height="1066" alt="OSGKeyboard on iPad" loading="eager">
</div>
</div>
</div>
<div class="device device-phone">
<div class="phone-bezel">
<div class="phone-island" aria-hidden="true"></div>
<div class="phone-screen">
<img data-shot="iphone-home" src="assets/screenshots/zh/light/iphone-home.png" width="552" height="1200" alt="OSGKeyboard on iPhone" loading="eager">
</div>
</div>
</div>
</div>
<img src="assets/hero-devices.png" width="1024" height="458" alt="OSGKeyboard on iPad, Mac, and iPhone" loading="eager">
</div>
</div>
</section>
@@ -1357,7 +1174,7 @@
}
// Soft parallax after hero entrance animation settles
const stage = document.querySelector(".device-cluster");
const stage = document.querySelector(".hero-stage");
if (stage && !window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
let ready = false;
setTimeout(() => { ready = true; }, 1100);