|
2 | 2 | <html lang="zh-CN"> |
3 | 3 | <head> |
4 | 4 | <meta charset="UTF-8"> |
5 | | -<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 5 | +<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> |
6 | 6 | {%- assign page_title = page.title | append: " — " | append: site.title -%} |
7 | 7 | {%- assign page_desc = page.description | default: site.description -%} |
8 | 8 | {%- assign page_kw = page.keywords | default: site.keywords -%} |
|
52 | 52 | --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace; |
53 | 53 | } |
54 | 54 | * { margin: 0; padding: 0; box-sizing: border-box; } |
55 | | -body { font-family: var(--font-sans); color: var(--ink); line-height: 1.6; background: var(--canvas); } |
| 55 | +body { font-family: var(--font-sans); color: var(--ink); line-height: 1.6; background: var(--canvas); overflow-x: hidden; } |
| 56 | +h1, h2, h3 { text-wrap: balance; } |
| 57 | +.doc-content p, .doc-content li { text-wrap: pretty; } |
56 | 58 |
|
57 | 59 | /* Nav */ |
58 | | -.nav { background: var(--canvas); border-bottom: 1px solid var(--hairline); height: 64px; display: flex; align-items: center; position: sticky; top: 0; z-index: 100; backdrop-filter: blur(8px); background: rgba(255,255,255,0.8); } |
| 60 | +.nav { border-bottom: 1px solid var(--hairline); height: calc(64px + env(safe-area-inset-top, 0px)); padding-top: env(safe-area-inset-top, 0px); display: flex; align-items: center; position: sticky; top: 0; z-index: 100; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); background: rgba(255,255,255,0.8); } |
59 | 61 | .nav-inner { max-width: 1100px; margin: 0 auto; padding: 0 24px; width: 100%; display: flex; align-items: center; justify-content: space-between; } |
60 | 62 | .nav-logo { font-size: 16px; font-weight: 700; color: var(--ink); text-decoration: none; letter-spacing: -0.5px; } |
| 63 | +.logo-short { display: none; } |
61 | 64 | .nav-links { display: flex; gap: 8px; align-items: center; } |
62 | 65 | .nav-links a { color: var(--body); text-decoration: none; font-size: 14px; font-weight: 500; padding: 6px 12px; border-radius: var(--rounded-pill); transition: background 0.15s, color 0.15s; } |
63 | 66 | .nav-links a:hover { background: var(--canvas-soft-2); color: var(--ink); } |
64 | 67 | .nav-cta { background: var(--primary) !important; color: var(--on-primary) !important; font-size: 14px !important; font-weight: 500; padding: 6px 16px !important; border-radius: var(--rounded-sm); } |
65 | 68 | .nav-cta:hover { opacity: 0.9; background: var(--primary) !important; } |
| 69 | +.nav-toggle { display: none; align-items: center; justify-content: center; width: 44px; height: 44px; border: none; background: none; cursor: pointer; border-radius: var(--rounded-md); color: var(--ink); } |
| 70 | +.nav-toggle:hover { background: var(--canvas-soft-2); } |
| 71 | +.nav-toggle svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; } |
| 72 | +.nav-toggle .icon-close { display: none; } |
| 73 | +.nav-toggle[aria-expanded="true"] .icon-menu { display: none; } |
| 74 | +.nav-toggle[aria-expanded="true"] .icon-close { display: block; } |
| 75 | +.menu-backdrop { display: none; } |
66 | 76 |
|
67 | 77 | /* Doc layout */ |
68 | | -.doc-layout { display: grid; grid-template-columns: 220px 1fr; max-width: 1100px; margin: 0 auto; min-height: calc(100vh - 64px); } |
| 78 | +.doc-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); max-width: 1100px; margin: 0 auto; min-height: calc(100vh - 64px); } |
69 | 79 |
|
70 | 80 | /* Sidebar */ |
71 | | -.sidebar { border-right: 1px solid var(--hairline); padding: 32px 0 32px 24px; position: sticky; top: 64px; height: calc(100vh - 64px); overflow-y: auto; } |
| 81 | +.sidebar { border-right: 1px solid var(--hairline); padding: 32px 0 32px 24px; position: sticky; top: calc(64px + env(safe-area-inset-top, 0px)); height: calc(100vh - 64px - env(safe-area-inset-top, 0px)); overflow-y: auto; } |
72 | 82 | .sidebar-section { margin-bottom: 24px; } |
73 | 83 | .sidebar-title { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--mute); margin-bottom: 8px; padding-left: 12px; } |
74 | 84 | .sidebar a { display: block; font-size: 14px; color: var(--body); text-decoration: none; padding: 6px 12px; border-radius: var(--rounded-sm); margin-bottom: 2px; transition: all 0.12s; border-left: 2px solid transparent; } |
|
85 | 95 | .doc-content a:hover { text-decoration: underline; } |
86 | 96 | .doc-content ul, .doc-content ol { padding-left: 20px; margin-bottom: 16px; } |
87 | 97 | .doc-content li { font-size: 15px; color: var(--body); line-height: 26px; margin-bottom: 8px; } |
88 | | -.doc-content code { font-family: var(--font-mono); font-size: 13px; background: var(--canvas-soft-2); padding: 2px 6px; border-radius: 4px; color: var(--ink); } |
| 98 | +.doc-content code { font-family: var(--font-mono); font-size: 13px; background: var(--canvas-soft-2); padding: 2px 6px; border-radius: 4px; color: var(--ink); overflow-wrap: anywhere; } |
89 | 99 | .doc-content pre { background: var(--primary); color: var(--on-primary); padding: 20px 24px; border-radius: var(--rounded-md); margin-bottom: 20px; overflow-x: auto; font-size: 13px; line-height: 22px; } |
90 | 100 | .doc-content pre code { background: none; padding: 0; color: inherit; } |
91 | 101 | .doc-content blockquote { border-left: 3px solid var(--hairline); padding-left: 16px; margin: 16px 0; color: var(--mute); font-style: italic; } |
92 | | -.doc-content table { width: 100%; border-collapse: collapse; margin: 16px 0 24px; font-size: 14px; } |
| 102 | +.table-wrap { overflow-x: auto; margin: 16px 0 24px; } |
| 103 | +.doc-content table { width: 100%; border-collapse: collapse; font-size: 14px; } |
93 | 104 | .doc-content th { text-align: left; font-weight: 600; padding: 10px 12px; border-bottom: 2px solid var(--hairline); color: var(--ink); } |
94 | 105 | .doc-content td { padding: 10px 12px; border-bottom: 1px solid var(--hairline); color: var(--body); } |
95 | 106 | .doc-content tr:hover td { background: var(--canvas-soft); } |
|
107 | 118 |
|
108 | 119 | /* Code copy button */ |
109 | 120 | .code-block-wrapper { position: relative; margin-bottom: 20px; } |
110 | | -.code-block-wrapper pre { margin-bottom: 0; padding-right: 48px; } |
111 | | -.copy-btn { position: absolute; top: 50%; right: 12px; transform: translateY(-50%); background: rgba(255,255,255,0.15); border: 1px solid rgba(255,255,255,0.2); color: rgba(255,255,255,0.7); width: 32px; height: 32px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s; } |
| 121 | +.code-block-wrapper pre { margin-bottom: 0; } |
| 122 | +.copy-btn { position: absolute; top: 8px; right: 8px; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.15); color: rgba(255,255,255,0.5); width: 32px; height: 32px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s, opacity 0.15s; opacity: 0; } |
| 123 | +.code-block-wrapper:hover .copy-btn, .copy-btn:focus { opacity: 1; } |
112 | 124 | .copy-btn:hover { background: rgba(255,255,255,0.25); color: #fff; } |
113 | | -.copy-btn.copied { background: rgba(34,197,94,0.3); border-color: rgba(34,197,94,0.4); color: #4ade80; } |
| 125 | +.copy-btn.copied { opacity: 1; background: rgba(34,197,94,0.3); border-color: rgba(34,197,94,0.4); color: #4ade80; } |
114 | 126 | .copy-btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; } |
| 127 | +@media (hover: none) { .copy-btn { opacity: 0.6; } } |
115 | 128 |
|
116 | 129 | /* Page footer */ |
117 | 130 | .doc-footer { margin-top: 64px; padding-top: 24px; border-top: 1px solid var(--hairline); font-size: 13px; color: var(--mute); } |
118 | 131 | .doc-footer a { color: var(--link); text-decoration: none; } |
119 | 132 | .doc-footer a:hover { text-decoration: underline; } |
120 | 133 |
|
| 134 | +/* Tablet */ |
| 135 | +@media (max-width: 1024px) { |
| 136 | + .doc-layout { grid-template-columns: 200px minmax(0, 1fr); } |
| 137 | + .doc-content { padding: 40px 32px 72px; } |
| 138 | +} |
| 139 | + |
121 | 140 | /* Mobile */ |
122 | 141 | @media (max-width: 768px) { |
123 | | - .doc-layout { grid-template-columns: 1fr; } |
124 | | - .sidebar { display: none; } |
125 | | - .doc-content { padding: 32px 24px 60px; } |
126 | | - .doc-content h1 { font-size: 26px; } |
127 | | - .nav-links a:not(.nav-cta) { display: none; } |
| 142 | + .nav-links a { display: none; } |
| 143 | + .nav-toggle { display: flex; } |
| 144 | + .logo-full { display: none; } |
| 145 | + .logo-short { display: inline; } |
| 146 | + .menu-backdrop.open { display: block; position: fixed; inset: 0; z-index: 98; background: rgba(23,23,23,0.24); } |
| 147 | + .doc-layout { grid-template-columns: minmax(0, 1fr); } |
| 148 | + .sidebar { position: fixed; top: calc(64px + env(safe-area-inset-top, 0px)); left: 0; bottom: 0; height: auto; width: min(300px, 84vw); padding: 20px 12px calc(20px + env(safe-area-inset-bottom, 0px)); background: var(--canvas); transform: translateX(-102%); transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1); z-index: 99; } |
| 149 | + .sidebar.open { transform: translateX(0); box-shadow: 16px 0 48px rgba(23,23,23,0.12); } |
| 150 | + .sidebar a { display: flex; align-items: center; min-height: 44px; padding: 10px 12px; font-size: 15px; } |
| 151 | + .doc-content { padding: 28px 20px calc(56px + env(safe-area-inset-bottom, 0px)); } |
| 152 | + .doc-content h1, .blog-meta-title { font-size: 26px; } |
| 153 | + .doc-content h2 { font-size: 20px; } |
| 154 | + .doc-content pre { padding: 16px 18px; } |
| 155 | + .doc-content code { font-size: 12.5px; } |
| 156 | + .doc-content table { font-size: 13px; } |
| 157 | + .doc-content th, .doc-content td { padding: 8px 10px; } |
| 158 | + .doc-content td img { max-width: 64px; height: auto; } |
| 159 | + .doc-content blockquote { padding-left: 12px; margin: 12px 0; } |
| 160 | + .blog-meta-desc { padding: 12px 14px; } |
| 161 | +} |
| 162 | + |
| 163 | +@media (pointer: coarse) { |
| 164 | + .copy-btn { width: 40px; height: 40px; top: 6px; right: 6px; } |
| 165 | +} |
| 166 | + |
| 167 | +@media (prefers-reduced-motion: reduce) { |
| 168 | + *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; } |
128 | 169 | } |
129 | 170 | </style> |
130 | 171 | </head> |
131 | 172 | <body> |
132 | 173 |
|
133 | 174 | <nav class="nav"> |
134 | 175 | <div class="nav-inner"> |
135 | | - <a href="/" class="nav-logo">ModelStudio for Developers</a> |
| 176 | + <a href="/" class="nav-logo"><span class="logo-full">ModelStudio for Developers</span><span class="logo-short">ModelStudio</span></a> |
136 | 177 | <div class="nav-links"> |
137 | 178 | <a href="/playbook/">岗位能力样板</a> |
138 | 179 | <a href="/blog/">Blog</a> |
139 | 180 | <a href="/showcase/">案例</a> |
140 | 181 | <a href="https://github.com/modelstudioai" target="_blank">GitHub</a> |
141 | 182 | <a href="{{ site.bailian_apikey_url }}" class="nav-cta" target="_blank">获取 API Key</a> |
| 183 | + <button class="nav-toggle" aria-label="菜单" aria-expanded="false" aria-controls="doc-sidebar"> |
| 184 | + <svg class="icon-menu" viewBox="0 0 24 24"><line x1="4" y1="7" x2="20" y2="7"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="17" x2="20" y2="17"/></svg> |
| 185 | + <svg class="icon-close" viewBox="0 0 24 24"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg> |
| 186 | + </button> |
142 | 187 | </div> |
143 | 188 | </div> |
144 | 189 | </nav> |
| 190 | +<div class="menu-backdrop"></div> |
145 | 191 |
|
146 | 192 | <div class="doc-layout"> |
147 | | - <aside class="sidebar"> |
| 193 | + <aside class="sidebar" id="doc-sidebar"> |
148 | 194 | <div class="sidebar-section"> |
149 | 195 | <div class="sidebar-title">文档</div> |
150 | 196 | <a href="/guide/" {% if page.url == '/guide/' %}class="active"{% endif %}>完整教程</a> |
@@ -200,6 +246,31 @@ <h1 class="blog-meta-title">{{ page.title }}</h1> |
200 | 246 |
|
201 | 247 | <script> |
202 | 248 | document.addEventListener('DOMContentLoaded', function() { |
| 249 | + var toggle = document.querySelector('.nav-toggle'); |
| 250 | + var sidebar = document.getElementById('doc-sidebar'); |
| 251 | + var backdrop = document.querySelector('.menu-backdrop'); |
| 252 | + if (toggle && sidebar && backdrop) { |
| 253 | + function setDrawer(open) { |
| 254 | + sidebar.classList.toggle('open', open); |
| 255 | + backdrop.classList.toggle('open', open); |
| 256 | + toggle.setAttribute('aria-expanded', String(open)); |
| 257 | + toggle.setAttribute('aria-label', open ? '关闭菜单' : '菜单'); |
| 258 | + document.body.style.overflow = open ? 'hidden' : ''; |
| 259 | + } |
| 260 | + toggle.addEventListener('click', function() { setDrawer(!sidebar.classList.contains('open')); }); |
| 261 | + backdrop.addEventListener('click', function() { setDrawer(false); }); |
| 262 | + sidebar.addEventListener('click', function(e) { if (e.target.closest('a')) setDrawer(false); }); |
| 263 | + document.addEventListener('keydown', function(e) { if (e.key === 'Escape') setDrawer(false); }); |
| 264 | + window.addEventListener('resize', function() { if (window.innerWidth > 768) setDrawer(false); }); |
| 265 | + } |
| 266 | + |
| 267 | + document.querySelectorAll('.doc-content table').forEach(function(table) { |
| 268 | + var wrap = document.createElement('div'); |
| 269 | + wrap.className = 'table-wrap'; |
| 270 | + table.parentNode.insertBefore(wrap, table); |
| 271 | + wrap.appendChild(table); |
| 272 | + }); |
| 273 | + |
203 | 274 | var pres = document.querySelectorAll('.doc-content pre'); |
204 | 275 | pres.forEach(function(pre) { |
205 | 276 | var wrapper = document.createElement('div'); |
|
0 commit comments