906 lines
27 KiB
HTML
906 lines
27 KiB
HTML
<!doctype html>
|
|
<html lang="zh-CN" data-theme="dark">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="color-scheme" content="dark light">
|
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3C/svg%3E">
|
|
<title>Havline Logo V2 概念预览</title>
|
|
<style>
|
|
:root {
|
|
--page: #06121e;
|
|
--panel: #0b1c2b;
|
|
--panel-soft: #10283a;
|
|
--text: #f2fbfa;
|
|
--muted: #8daab6;
|
|
--line: rgba(235, 255, 252, 0.13);
|
|
--line-strong: rgba(235, 255, 252, 0.24);
|
|
--blue: #2fa9ff;
|
|
--mint: #63f0d0;
|
|
--gold: #ffb15a;
|
|
--radius: 8px;
|
|
--shadow: 0 22px 70px rgba(0, 0, 0, 0.28);
|
|
--font: "Segoe UI", "Microsoft YaHei", "PingFang SC", system-ui, sans-serif;
|
|
--mono: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
|
|
}
|
|
|
|
html[data-theme="light"] {
|
|
--page: #eef5f6;
|
|
--panel: #ffffff;
|
|
--panel-soft: #e4f0f1;
|
|
--text: #0a2535;
|
|
--muted: #58717b;
|
|
--line: rgba(10, 37, 53, 0.12);
|
|
--line-strong: rgba(10, 37, 53, 0.21);
|
|
--shadow: 0 22px 70px rgba(20, 55, 70, 0.13);
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
background: var(--page);
|
|
color: var(--text);
|
|
font-family: var(--font);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
button {
|
|
cursor: pointer;
|
|
font: inherit;
|
|
}
|
|
|
|
.sprite {
|
|
position: absolute;
|
|
width: 0;
|
|
height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.topbar {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 5;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 18px;
|
|
min-height: 70px;
|
|
padding: 14px clamp(18px, 4vw, 56px);
|
|
background: color-mix(in srgb, var(--page) 92%, transparent);
|
|
border-bottom: 1px solid var(--line);
|
|
backdrop-filter: blur(18px);
|
|
}
|
|
|
|
.topbar__brand,
|
|
.topbar__actions,
|
|
.inline-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.topbar__mark {
|
|
width: 34px;
|
|
height: 34px;
|
|
}
|
|
|
|
.topbar__title {
|
|
display: grid;
|
|
line-height: 1.15;
|
|
}
|
|
|
|
.topbar__title strong {
|
|
font-size: 17px;
|
|
}
|
|
|
|
.topbar__title span {
|
|
color: var(--muted);
|
|
font-family: var(--mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.12em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.control {
|
|
min-height: 38px;
|
|
padding: 0 14px;
|
|
color: var(--text);
|
|
background: transparent;
|
|
border: 1px solid var(--line-strong);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
.control:hover,
|
|
.control[aria-pressed="true"] {
|
|
background: var(--panel-soft);
|
|
}
|
|
|
|
.control--primary {
|
|
color: #04131d;
|
|
background: linear-gradient(135deg, var(--blue), var(--mint));
|
|
border-color: transparent;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.wrap {
|
|
width: min(1160px, calc(100% - 36px));
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.hero {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 0.92fr) minmax(380px, 1.08fr);
|
|
gap: clamp(28px, 5vw, 72px);
|
|
align-items: center;
|
|
min-height: calc(100vh - 70px);
|
|
padding: 70px 0;
|
|
}
|
|
|
|
.eyebrow {
|
|
margin: 0 0 14px;
|
|
color: var(--mint);
|
|
font-family: var(--mono);
|
|
font-size: 12px;
|
|
letter-spacing: 0.15em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h3,
|
|
p {
|
|
margin-top: 0;
|
|
}
|
|
|
|
h1 {
|
|
margin-bottom: 12px;
|
|
font-size: clamp(52px, 8vw, 92px);
|
|
line-height: 0.94;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.lead {
|
|
margin-bottom: 18px;
|
|
font-size: clamp(19px, 2.3vw, 29px);
|
|
font-weight: 600;
|
|
line-height: 1.28;
|
|
}
|
|
|
|
.copy {
|
|
max-width: 620px;
|
|
margin-bottom: 22px;
|
|
color: var(--muted);
|
|
font-size: 15px;
|
|
}
|
|
|
|
.pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 7px 10px;
|
|
color: var(--mint);
|
|
background: color-mix(in srgb, var(--mint) 12%, transparent);
|
|
border: 1px solid color-mix(in srgb, var(--mint) 28%, transparent);
|
|
border-radius: 999px;
|
|
font-family: var(--mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.08em;
|
|
}
|
|
|
|
.stage {
|
|
position: relative;
|
|
display: grid;
|
|
place-items: center;
|
|
min-height: 560px;
|
|
padding: 48px;
|
|
overflow: hidden;
|
|
background:
|
|
linear-gradient(to right, color-mix(in srgb, var(--line) 62%, transparent) 1px, transparent 1px) 0 0 / 36px 36px,
|
|
linear-gradient(to bottom, color-mix(in srgb, var(--line) 62%, transparent) 1px, transparent 1px) 0 0 / 36px 36px,
|
|
color-mix(in srgb, var(--panel) 95%, #071a29);
|
|
border: 1px solid var(--line);
|
|
border-radius: var(--radius);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
.stage::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 18px;
|
|
border: 1px solid color-mix(in srgb, var(--mint) 17%, transparent);
|
|
border-radius: var(--radius);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.hero-lockup {
|
|
position: relative;
|
|
z-index: 1;
|
|
width: min(100%, 570px);
|
|
color: var(--text);
|
|
}
|
|
|
|
.section {
|
|
padding: 82px 0;
|
|
border-top: 1px solid var(--line);
|
|
}
|
|
|
|
.section__head {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
|
|
gap: 28px;
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.section__head h2 {
|
|
margin-bottom: 0;
|
|
font-size: clamp(27px, 4vw, 44px);
|
|
line-height: 1.08;
|
|
}
|
|
|
|
.section__head p {
|
|
max-width: 680px;
|
|
margin-bottom: 0;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.fix-grid,
|
|
.concept-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
gap: 16px;
|
|
}
|
|
|
|
.fix-card,
|
|
.concept-card,
|
|
.preview-card {
|
|
background: var(--panel);
|
|
border: 1px solid var(--line);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
.fix-card {
|
|
min-height: 200px;
|
|
padding: 22px;
|
|
}
|
|
|
|
.fix-card__index {
|
|
display: block;
|
|
margin-bottom: 42px;
|
|
color: var(--mint);
|
|
font-family: var(--mono);
|
|
font-size: 12px;
|
|
letter-spacing: 0.12em;
|
|
}
|
|
|
|
.fix-card h3 {
|
|
margin-bottom: 8px;
|
|
font-size: 17px;
|
|
}
|
|
|
|
.fix-card p {
|
|
margin-bottom: 0;
|
|
color: var(--muted);
|
|
font-size: 14px;
|
|
}
|
|
|
|
.compare {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
gap: 16px;
|
|
}
|
|
|
|
.compare-card {
|
|
display: grid;
|
|
place-items: center;
|
|
min-height: 360px;
|
|
padding: 34px;
|
|
background: #f4fbfb;
|
|
border: 1px solid rgba(7, 34, 50, 0.12);
|
|
border-radius: var(--radius);
|
|
color: #092638;
|
|
}
|
|
|
|
.compare-card--dark {
|
|
color: var(--text);
|
|
background: #071a29;
|
|
border-color: var(--line);
|
|
}
|
|
|
|
.compare-card__label {
|
|
align-self: end;
|
|
margin-top: 22px;
|
|
color: inherit;
|
|
font-family: var(--mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.1em;
|
|
opacity: 0.62;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.mark-large {
|
|
width: min(100%, 190px);
|
|
height: auto;
|
|
}
|
|
|
|
.concept-grid {
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
}
|
|
|
|
.concept-card {
|
|
display: grid;
|
|
place-items: center;
|
|
min-height: 340px;
|
|
padding: 30px;
|
|
}
|
|
|
|
.concept-card__mark {
|
|
width: 140px;
|
|
height: 140px;
|
|
}
|
|
|
|
.concept-card__copy {
|
|
align-self: end;
|
|
margin-top: 22px;
|
|
text-align: center;
|
|
}
|
|
|
|
.concept-card__copy h3 {
|
|
margin-bottom: 5px;
|
|
font-size: 17px;
|
|
}
|
|
|
|
.concept-card__copy p {
|
|
margin-bottom: 0;
|
|
color: var(--muted);
|
|
font-size: 14px;
|
|
}
|
|
|
|
.concept-card--recommended {
|
|
border-color: color-mix(in srgb, var(--mint) 42%, transparent);
|
|
box-shadow: 0 0 0 1px color-mix(in srgb, var(--mint) 12%, transparent);
|
|
}
|
|
|
|
.sidebar-preview {
|
|
display: grid;
|
|
grid-template-columns: 300px minmax(0, 1fr);
|
|
gap: 16px;
|
|
}
|
|
|
|
.sidebar-card {
|
|
width: 300px;
|
|
padding: 18px 0;
|
|
color: #0b2735;
|
|
background: #ffffff;
|
|
border: 1px solid rgba(12, 43, 58, 0.13);
|
|
border-radius: var(--radius);
|
|
box-shadow: var(--shadow);
|
|
}
|
|
|
|
.sidebar-brand {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 0 18px 18px;
|
|
border-bottom: 1px solid rgba(12, 43, 58, 0.1);
|
|
}
|
|
|
|
.sidebar-brand__mark {
|
|
width: 40px;
|
|
height: 40px;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.sidebar-brand__name {
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.sidebar-brand__tagline {
|
|
color: #66808b;
|
|
font-size: 11px;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
.sidebar-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
margin: 10px 12px 0;
|
|
padding: 10px 14px;
|
|
color: #2a4a57;
|
|
font-size: 14px;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.sidebar-item--active {
|
|
color: #168f75;
|
|
background: #e5f6f1;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.sidebar-dot {
|
|
width: 17px;
|
|
height: 17px;
|
|
border: 2px solid currentColor;
|
|
border-radius: 5px;
|
|
opacity: 0.82;
|
|
}
|
|
|
|
.sidebar-note {
|
|
display: grid;
|
|
align-content: center;
|
|
padding: 34px;
|
|
background: var(--panel);
|
|
border: 1px solid var(--line);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
.sidebar-note h3 {
|
|
margin-bottom: 8px;
|
|
font-size: 21px;
|
|
}
|
|
|
|
.sidebar-note p {
|
|
margin-bottom: 0;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.size-row {
|
|
display: flex;
|
|
align-items: end;
|
|
gap: 28px;
|
|
flex-wrap: wrap;
|
|
padding: 34px;
|
|
background: var(--panel);
|
|
border: 1px solid var(--line);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
.size-sample {
|
|
display: grid;
|
|
gap: 10px;
|
|
justify-items: center;
|
|
color: var(--muted);
|
|
font-family: var(--mono);
|
|
font-size: 11px;
|
|
}
|
|
|
|
.size-sample svg {
|
|
width: var(--size);
|
|
height: var(--size);
|
|
}
|
|
|
|
.source {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
gap: 14px;
|
|
align-items: start;
|
|
padding: 18px;
|
|
background: #04101a;
|
|
border: 1px solid var(--line);
|
|
border-radius: var(--radius);
|
|
overflow: hidden;
|
|
}
|
|
|
|
pre {
|
|
max-height: 430px;
|
|
margin: 0;
|
|
overflow: auto;
|
|
color: #b9dbe7;
|
|
font-family: var(--mono);
|
|
font-size: 12px;
|
|
line-height: 1.6;
|
|
white-space: pre;
|
|
}
|
|
|
|
.footnote {
|
|
padding: 34px 0 56px;
|
|
color: var(--muted);
|
|
font-size: 13px;
|
|
}
|
|
|
|
@media (max-width: 980px) {
|
|
.hero,
|
|
.section__head,
|
|
.sidebar-preview {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.hero {
|
|
min-height: auto;
|
|
}
|
|
|
|
.fix-grid,
|
|
.concept-grid {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
}
|
|
|
|
@media (max-width: 650px) {
|
|
.topbar {
|
|
align-items: flex-start;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.topbar__actions {
|
|
width: 100%;
|
|
}
|
|
|
|
.control {
|
|
flex: 1 1 auto;
|
|
}
|
|
|
|
.stage {
|
|
min-height: 390px;
|
|
padding: 28px;
|
|
}
|
|
|
|
.fix-grid,
|
|
.concept-grid,
|
|
.compare {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.sidebar-card {
|
|
width: 100%;
|
|
}
|
|
|
|
.source {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<svg class="sprite" aria-hidden="true" focusable="false">
|
|
<defs>
|
|
<linearGradient id="v2-bg" x1="0" y1="0" x2="1" y2="1">
|
|
<stop offset="0" stop-color="#0f506d"></stop>
|
|
<stop offset="1" stop-color="#061827"></stop>
|
|
</linearGradient>
|
|
<linearGradient id="v2-ink" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="0" stop-color="#f6fffd"></stop>
|
|
<stop offset="1" stop-color="#c9f5ed"></stop>
|
|
</linearGradient>
|
|
<linearGradient id="v2-line" x1="0" y1="1" x2="1" y2="0">
|
|
<stop offset="0" stop-color="#299cff"></stop>
|
|
<stop offset="1" stop-color="#68f3d2"></stop>
|
|
</linearGradient>
|
|
<symbol id="mark-v2" viewBox="0 0 96 96">
|
|
<rect x="4" y="4" width="88" height="88" rx="22" fill="url(#v2-bg)"></rect>
|
|
<rect x="4.8" y="4.8" width="86.4" height="86.4" rx="21.2" fill="none" stroke="rgba(242,255,252,.14)" stroke-width="1.6"></rect>
|
|
<path d="M17 62C29 52 37 68 47 58C57 48 66 52 79 43" stroke="url(#v2-line)" stroke-width="6.5" fill="none" stroke-linecap="round"></path>
|
|
<rect x="28" y="24" width="11" height="48" rx="5.5" fill="url(#v2-ink)"></rect>
|
|
<rect x="57" y="24" width="11" height="48" rx="5.5" fill="url(#v2-ink)"></rect>
|
|
</symbol>
|
|
<symbol id="mark-gate" viewBox="0 0 96 96">
|
|
<rect x="4" y="4" width="88" height="88" rx="22" fill="url(#v2-bg)"></rect>
|
|
<rect x="4.8" y="4.8" width="86.4" height="86.4" rx="21.2" fill="none" stroke="rgba(242,255,252,.14)" stroke-width="1.6"></rect>
|
|
<path d="M40 24C32 24 28 31 28 48C28 65 32 72 40 72" stroke="url(#v2-ink)" stroke-width="10" fill="none" stroke-linecap="round"></path>
|
|
<path d="M56 24C64 24 68 31 68 48C68 65 64 72 56 72" stroke="url(#v2-ink)" stroke-width="10" fill="none" stroke-linecap="round"></path>
|
|
<path d="M34 59C43 51 54 45 63 37" stroke="url(#v2-line)" stroke-width="7" fill="none" stroke-linecap="round"></path>
|
|
</symbol>
|
|
<symbol id="mark-lower" viewBox="0 0 96 96">
|
|
<rect x="4" y="4" width="88" height="88" rx="22" fill="url(#v2-bg)"></rect>
|
|
<rect x="4.8" y="4.8" width="86.4" height="86.4" rx="21.2" fill="none" stroke="rgba(242,255,252,.14)" stroke-width="1.6"></rect>
|
|
<path d="M31 23V73" stroke="url(#v2-ink)" stroke-width="11" stroke-linecap="round"></path>
|
|
<path d="M31 51C31 36 40 29 50 29C60 29 66 37 66 51V73" stroke="url(#v2-ink)" stroke-width="11" fill="none" stroke-linecap="round"></path>
|
|
<circle cx="49" cy="51" r="5" fill="#68f3d2"></circle>
|
|
<path d="M39 62C44 55 54 55 58 62" stroke="url(#v2-line)" stroke-width="5" fill="none" stroke-linecap="round"></path>
|
|
</symbol>
|
|
</defs>
|
|
</svg>
|
|
|
|
<header class="topbar">
|
|
<div class="topbar__brand">
|
|
<svg class="topbar__mark" viewBox="0 0 96 96" aria-label="Havline V2 标志">
|
|
<use href="#mark-v2"></use>
|
|
</svg>
|
|
<div class="topbar__title">
|
|
<strong>Havline V2</strong>
|
|
<span>Refined mark / harbor gate</span>
|
|
</div>
|
|
</div>
|
|
<div class="topbar__actions">
|
|
<button class="control" type="button" data-theme-set="dark" aria-pressed="true">深海</button>
|
|
<button class="control" type="button" data-theme-set="light" aria-pressed="false">白昼</button>
|
|
<button class="control control--primary" type="button" id="download-v2">下载 SVG</button>
|
|
</div>
|
|
</header>
|
|
|
|
<main>
|
|
<section class="wrap hero">
|
|
<div>
|
|
<p class="eyebrow">Logo evolution / 02</p>
|
|
<h1>Havline</h1>
|
|
<p class="lead">从“一个 H”变成“一个港湾入口”。</p>
|
|
<p class="copy">V2 保留 H 的识别骨架,但不再用两个端点圆点做连接。线路改为从 H 后方穿过的连续波浪,视觉上像一条服务路径穿过港湾入口,也更适合侧栏的小尺寸使用。</p>
|
|
<div class="inline-row">
|
|
<span class="pill">NO EYES / CONTINUOUS ROUTE</span>
|
|
<span class="pill">40PX SIDEBAR SAFE</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stage">
|
|
<div class="hero-lockup">
|
|
<svg viewBox="0 0 560 140" role="img" aria-labelledby="hero-v2-title hero-v2-desc">
|
|
<title id="hero-v2-title">Havline V2 横向标志</title>
|
|
<desc id="hero-v2-desc">左侧为 Havline V2 标志,右侧为 havline 字体组合。</desc>
|
|
<use href="#mark-v2" x="0" y="10" width="120" height="120"></use>
|
|
<text x="146" y="67" fill="currentColor" font-family="Segoe UI, Microsoft YaHei, sans-serif" font-size="49" font-weight="700" letter-spacing="0.4">havline</text>
|
|
<text x="148" y="94" fill="currentColor" font-family="SFMono-Regular, Consolas, monospace" font-size="12" letter-spacing="1.5" opacity="0.62">SAFE LINE FOR EVERY SERVICE</text>
|
|
<line x1="148" y1="110" x2="525" y2="110" stroke="currentColor" stroke-width="1" opacity="0.16"></line>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="wrap">
|
|
<div class="section__head">
|
|
<h2>这版改了什么</h2>
|
|
<p>问题不在 H,而在连接方式。旧版的端点圆点在 40px 侧栏里会形成类似“眼睛”的视觉焦点,抢掉了 H 和线路的主次关系。V2 让线路后退,保留一个干净的入口。</p>
|
|
</div>
|
|
<div class="fix-grid">
|
|
<article class="fix-card">
|
|
<span class="fix-card__index">01 / REMOVE</span>
|
|
<h3>去掉端点圆点</h3>
|
|
<p>不再在左右立柱上放节点,避免小尺寸下像双眼或天线,让 H 的主体轮廓更干净。</p>
|
|
</article>
|
|
<article class="fix-card">
|
|
<span class="fix-card__index">02 / LAYER</span>
|
|
<h3>线路退到 H 后方</h3>
|
|
<p>波浪线路从双柱背后穿过,只在中间形成连接,保留“服务穿过港湾入口”的叙事。</p>
|
|
</article>
|
|
<article class="fix-card">
|
|
<span class="fix-card__index">03 / FLOW</span>
|
|
<h3>改用连续波浪</h3>
|
|
<p>斜线改成更平滑的水波路径,既有链路感,也接近港湾与水面意象。</p>
|
|
</article>
|
|
<article class="fix-card">
|
|
<span class="fix-card__index">04 / SIDEBAR</span>
|
|
<h3>为 40px 优化</h3>
|
|
<p>主结构只保留两根立柱和一条线路,缩放后仍能读出 H,不依赖额外细节。</p>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="wrap">
|
|
<div class="section__head">
|
|
<h2>前后对比</h2>
|
|
<p>左侧是上一版,右侧是 V2。对比重点不是“更复杂”,而是让标志在侧栏尺寸下更稳定、更耐看。</p>
|
|
</div>
|
|
<div class="compare">
|
|
<article class="compare-card">
|
|
<svg class="mark-large" viewBox="0 0 96 96" aria-label="旧版 Havline 标志">
|
|
<rect x="4" y="4" width="88" height="88" rx="22" fill="url(#v2-bg)"></rect>
|
|
<rect x="4.8" y="4.8" width="86.4" height="86.4" rx="21.2" fill="none" stroke="rgba(242,255,252,.13)" stroke-width="1.6"></rect>
|
|
<path d="M31 25.5V70.5" stroke="#f2fffc" stroke-width="11" stroke-linecap="round"></path>
|
|
<path d="M65 25.5V70.5" stroke="#f2fffc" stroke-width="11" stroke-linecap="round"></path>
|
|
<path d="M31 59C39 59 42.5 49 49.5 49C56.5 49 57.5 37 65 37" stroke="url(#v2-line)" stroke-width="7" fill="none" stroke-linecap="round" stroke-linejoin="round"></path>
|
|
<circle cx="31" cy="59" r="5" fill="#2fa9ff" stroke="#061827" stroke-width="2.2"></circle>
|
|
<circle cx="65" cy="37" r="5" fill="#63f0d0" stroke="#061827" stroke-width="2.2"></circle>
|
|
</svg>
|
|
<span class="compare-card__label">V1 / endpoint nodes</span>
|
|
</article>
|
|
<article class="compare-card compare-card--dark">
|
|
<svg class="mark-large" viewBox="0 0 96 96" aria-label="新版 Havline V2 标志">
|
|
<use href="#mark-v2"></use>
|
|
</svg>
|
|
<span class="compare-card__label">V2 / continuous route</span>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="wrap">
|
|
<div class="section__head">
|
|
<h2>三个方向</h2>
|
|
<p>推荐主案是左侧的“连续路线 H”。另外两个方向可以用于周边、活动或后续品牌迭代,不适合直接替代主标志。</p>
|
|
</div>
|
|
<div class="concept-grid">
|
|
<article class="concept-card concept-card--recommended">
|
|
<svg class="concept-card__mark" viewBox="0 0 96 96" aria-label="连续路线 H">
|
|
<use href="#mark-v2"></use>
|
|
</svg>
|
|
<div class="concept-card__copy">
|
|
<h3>连续路线 H</h3>
|
|
<p>推荐主案</p>
|
|
</div>
|
|
</article>
|
|
<article class="concept-card">
|
|
<svg class="concept-card__mark" viewBox="0 0 96 96" aria-label="港湾拱门">
|
|
<use href="#mark-gate"></use>
|
|
</svg>
|
|
<div class="concept-card__copy">
|
|
<h3>港湾拱门</h3>
|
|
<p>更抽象、画面感更强</p>
|
|
</div>
|
|
</article>
|
|
<article class="concept-card">
|
|
<svg class="concept-card__mark" viewBox="0 0 96 96" aria-label="小写 h 路线">
|
|
<use href="#mark-lower"></use>
|
|
</svg>
|
|
<div class="concept-card__copy">
|
|
<h3>小写 h 路线</h3>
|
|
<p>更亲和、更偏产品化</p>
|
|
</div>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="wrap">
|
|
<div class="section__head">
|
|
<h2>侧栏模拟</h2>
|
|
<p>在当前的 40px 品牌区里,V2 不再出现两个高亮圆点,视觉重心重新回到 H 和品牌名称上。</p>
|
|
</div>
|
|
<div class="sidebar-preview">
|
|
<div class="sidebar-card">
|
|
<div class="sidebar-brand">
|
|
<svg class="sidebar-brand__mark" viewBox="0 0 96 96" aria-label="Havline V2 侧栏标志">
|
|
<use href="#mark-v2"></use>
|
|
</svg>
|
|
<div>
|
|
<div class="sidebar-brand__name">Havline</div>
|
|
<div class="sidebar-brand__tagline">让 NAS 访问更简单</div>
|
|
</div>
|
|
</div>
|
|
<div class="sidebar-item sidebar-item--active">
|
|
<span class="sidebar-dot"></span>
|
|
仪表盘
|
|
</div>
|
|
<div class="sidebar-item">
|
|
<span class="sidebar-dot"></span>
|
|
DDNS
|
|
</div>
|
|
<div class="sidebar-item">
|
|
<span class="sidebar-dot"></span>
|
|
证书管理
|
|
</div>
|
|
<div class="sidebar-item">
|
|
<span class="sidebar-dot"></span>
|
|
反向代理
|
|
</div>
|
|
</div>
|
|
<div class="sidebar-note">
|
|
<h3>更像“连接”,不像“表情”</h3>
|
|
<p>旧版的两个端点圆点在侧栏压缩后过于醒目。V2 取消了端点节点,把线路收进 H 的结构里,因此远看是一个稳定的入口符号,近看才读到服务路径。</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="wrap">
|
|
<div class="section__head">
|
|
<h2>尺寸检查</h2>
|
|
<p>主标志建议最小使用 16px。侧栏品牌区 40px,应用图标 64px,登录页主标志 120px 以上。</p>
|
|
</div>
|
|
<div class="size-row">
|
|
<span class="size-sample" style="--size:16px">
|
|
<svg viewBox="0 0 96 96"><use href="#mark-v2"></use></svg>
|
|
16
|
|
</span>
|
|
<span class="size-sample" style="--size:24px">
|
|
<svg viewBox="0 0 96 96"><use href="#mark-v2"></use></svg>
|
|
24
|
|
</span>
|
|
<span class="size-sample" style="--size:40px">
|
|
<svg viewBox="0 0 96 96"><use href="#mark-v2"></use></svg>
|
|
40
|
|
</span>
|
|
<span class="size-sample" style="--size:64px">
|
|
<svg viewBox="0 0 96 96"><use href="#mark-v2"></use></svg>
|
|
64
|
|
</span>
|
|
<span class="size-sample" style="--size:96px">
|
|
<svg viewBox="0 0 96 96"><use href="#mark-v2"></use></svg>
|
|
96
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<div class="wrap">
|
|
<div class="section__head">
|
|
<h2>SVG 源文件</h2>
|
|
<p>这是 V2 主案的可下载 SVG,后续可以直接替换侧栏中的现有标志,不需要再调整图片尺寸。</p>
|
|
</div>
|
|
<div class="source">
|
|
<pre id="v2-code"></pre>
|
|
<div class="inline-row">
|
|
<button class="control control--primary" type="button" id="copy-v2">复制 SVG</button>
|
|
<button class="control" type="button" id="download-v2-2">下载 SVG</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<footer class="wrap footnote">
|
|
Havline V2 · 主案:连续路线 H · 设计目标:更干净、更有港湾入口感、在 40px 侧栏里不产生“表情”错觉。
|
|
</footer>
|
|
|
|
<script>
|
|
const root = document.documentElement;
|
|
const themeButtons = document.querySelectorAll("[data-theme-set]");
|
|
|
|
function setTheme(theme) {
|
|
root.dataset.theme = theme;
|
|
themeButtons.forEach((button) => {
|
|
button.setAttribute("aria-pressed", String(button.dataset.themeSet === theme));
|
|
});
|
|
}
|
|
|
|
themeButtons.forEach((button) => {
|
|
button.addEventListener("click", () => setTheme(button.dataset.themeSet));
|
|
});
|
|
|
|
const exportSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-label="Havline logo v2">
|
|
<defs>
|
|
<linearGradient id="havline-v2-bg" x1="0" y1="0" x2="1" y2="1">
|
|
<stop offset="0" stop-color="#0f506d"/>
|
|
<stop offset="1" stop-color="#061827"/>
|
|
</linearGradient>
|
|
<linearGradient id="havline-v2-ink" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="0" stop-color="#f6fffd"/>
|
|
<stop offset="1" stop-color="#c9f5ed"/>
|
|
</linearGradient>
|
|
<linearGradient id="havline-v2-line" x1="0" y1="1" x2="1" y2="0">
|
|
<stop offset="0" stop-color="#299cff"/>
|
|
<stop offset="1" stop-color="#68f3d2"/>
|
|
</linearGradient>
|
|
</defs>
|
|
<rect x="4" y="4" width="88" height="88" rx="22" fill="url(#havline-v2-bg)"/>
|
|
<rect x="4.8" y="4.8" width="86.4" height="86.4" rx="21.2" fill="none" stroke="rgba(242,255,252,.14)" stroke-width="1.6"/>
|
|
<path d="M17 62C29 52 37 68 47 58C57 48 66 52 79 43" stroke="url(#havline-v2-line)" stroke-width="6.5" fill="none" stroke-linecap="round"/>
|
|
<rect x="28" y="24" width="11" height="48" rx="5.5" fill="url(#havline-v2-ink)"/>
|
|
<rect x="57" y="24" width="11" height="48" rx="5.5" fill="url(#havline-v2-ink)"/>
|
|
</svg>`;
|
|
|
|
document.getElementById("v2-code").textContent = exportSvg;
|
|
|
|
function downloadV2() {
|
|
const blob = new Blob([exportSvg], { type: "image/svg+xml;charset=utf-8" });
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement("a");
|
|
link.href = url;
|
|
link.download = "havline-logo-v2.svg";
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
link.remove();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
document.getElementById("download-v2").addEventListener("click", downloadV2);
|
|
document.getElementById("download-v2-2").addEventListener("click", downloadV2);
|
|
|
|
document.getElementById("copy-v2").addEventListener("click", async (event) => {
|
|
try {
|
|
await navigator.clipboard.writeText(exportSvg);
|
|
event.currentTarget.textContent = "已复制";
|
|
setTimeout(() => {
|
|
event.currentTarget.textContent = "复制 SVG";
|
|
}, 1400);
|
|
} catch {
|
|
event.currentTarget.textContent = "复制失败";
|
|
setTimeout(() => {
|
|
event.currentTarget.textContent = "复制 SVG";
|
|
}, 1400);
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|