<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>tt-blog — 文章</title><description>tt 的个人主页：AI 全栈开发，作品集与技术博客。Agent 工作流、3D 可视化、原生桌面工具。</description><link>https://www.ttlist.top/</link><language>zh-cn</language><item><title>给个人站造一台仪器：Signal 设计系统笔记</title><link>https://www.ttlist.top/blog/signal-design-notes/</link><guid isPermaLink="true">https://www.ttlist.top/blog/signal-design-notes/</guid><description>这个网站第一版设计系统的取舍：一种信号色、三种字体、12 列网格，以及一套“像仪器一样响应”的动效规则。</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;做个人站最容易掉进的坑，是把它当成作品陈列柜：卡片、圆角、渐变、居中，每个模板都差不多。这一次我换了一个出发点——把主页当作一台&lt;strong&gt;正在运行的观测仪器&lt;/strong&gt;来设计。网格是刻度，编号是通道，状态灯告诉你系统是否在线，动效是仪器对输入的物理响应。&lt;/p&gt;
&lt;p&gt;这个比喻给了我一条很好用的判断标准：&lt;strong&gt;任何装饰，都必须能被解释为“仪表的一部分”&lt;/strong&gt;。解释不了的，就删掉。&lt;/p&gt;
&lt;h2 id=&quot;一种信号色&quot;&gt;一种信号色&lt;/h2&gt;
&lt;p&gt;整站只有一种强调色，我叫它 signal。它不是用来“好看”的，而是用来表示“这里有信号”：在线状态、当前所在的导航、滚动进度、需要你注意的那一个按钮。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Token&lt;/th&gt;
&lt;th&gt;深色&lt;/th&gt;
&lt;th&gt;浅色&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--bg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#09090B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#F7F7F8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;页面底&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--fg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#EDEDEF&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#121215&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;主文字&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--fg-muted&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#8A8A93&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#5C5C66&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;次要文字，对比度 ≥ 4.5:1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--signal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#7CFFB2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#0AA864&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;唯一强调色&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--signal-ink&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#7CFFB2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#067A48&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;小字号的信号色文字&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;浅色模式里有一个细节：&lt;code&gt;#0AA864&lt;/code&gt; 这种绿放在浅底上只有 2.9:1 的对比度，做指示灯没问题，做文字就不及格。所以多拆出一个 &lt;code&gt;--signal-ink&lt;/code&gt;，专门给链接和编号用。&lt;/p&gt;
&lt;h2 id=&quot;网格是刻度&quot;&gt;网格是刻度&lt;/h2&gt;
&lt;p&gt;12 列、24px 的槽、最大 1440px 的容器。和大多数网格系统不同的是，这里的网格是&lt;strong&gt;可见的&lt;/strong&gt;：整页有极淡的列参考线，Hero 和页脚铺着方格场，四角标着十字准星。&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;https://www.ttlist.top/_astro/signal-grid.DXzCbz1v_6yTcP.svg&quot; alt=&quot;Signal 的 12 列网格示意：页边距、列与槽&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1600&quot; height=&quot;900&quot;&gt;&lt;/p&gt;
&lt;p&gt;可见网格有一个副作用：它会逼着你对齐。任何没有落在列边界上的元素，都会被参考线出卖。&lt;/p&gt;
&lt;h2 id=&quot;动效像仪器一样响应&quot;&gt;动效：像仪器一样响应&lt;/h2&gt;
&lt;p&gt;动效只有三条规则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;进入动画只做&lt;strong&gt;位移 + 透明度&lt;/strong&gt;，不做缩放弹跳；&lt;/li&gt;
&lt;li&gt;滚动驱动的动画一律 &lt;code&gt;scrub&lt;/code&gt;，让人感觉是自己在推动；&lt;/li&gt;
&lt;li&gt;hover 反馈不超过 200ms。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;缓动曲线在 CSS 和 GSAP 里各有一份，需要保证它们是同一条曲线：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes vitesse-dark vitesse-light&quot; style=&quot;--shiki-dark:#dbd7caee;--shiki-light:#393a34;--shiki-dark-bg:#121212;--shiki-light-bg:#ffffff;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#758575DD;--shiki-light:#A0ADA0&quot;&gt;// CSS 的 --ease-out: cubic-bezier(.22, 1, .36, 1) 就是 easeOutQuint，&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#758575DD;--shiki-light:#A0ADA0&quot;&gt;// 对应 GSAP 的 power4.out；--ease-in-out 是 easeInOutCubic，对应 power2.inOut&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#CB7676;--shiki-light:#AB5959&quot;&gt; const &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#BD976A;--shiki-light:#B07D48&quot;&gt;EASE&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;  out&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#C98A7D77;--shiki-light:#B5695977&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#C98A7D;--shiki-light:#B56959&quot;&gt;power4.out&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#C98A7D77;--shiki-light:#B5695977&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;  inOut&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#C98A7D77;--shiki-light:#B5695977&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#C98A7D;--shiki-light:#B56959&quot;&gt;power2.inOut&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#C98A7D77;--shiki-light:#B5695977&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#CB7676;--shiki-light:#AB5959&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#BD976A;--shiki-light:#B07D48&quot;&gt;gsap&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#80A665;--shiki-light:#59873A&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#BD976A;--shiki-light:#B07D48&quot;&gt;chars&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;  yPercent&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4C9A91;--shiki-light:#2F798A&quot;&gt;110&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;  opacity&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4C9A91;--shiki-light:#2F798A&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;  duration&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4C9A91;--shiki-light:#2F798A&quot;&gt;0.9&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;  ease&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#BD976A;--shiki-light:#B07D48&quot;&gt;EASE&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#BD976A;--shiki-light:#B07D48&quot;&gt;out&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;  stagger&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4C9A91;--shiki-light:#2F798A&quot;&gt;0.018&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后，所有动效都必须响应系统的“减少动态效果”设置。这不是锦上添花，而是底线：&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes vitesse-dark vitesse-light&quot; style=&quot;--shiki-dark:#dbd7caee;--shiki-light:#393a34;--shiki-dark-bg:#121212;--shiki-light-bg:#ffffff;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt;media&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#DBD7CAEE;--shiki-light:#393A34&quot;&gt;prefers-reduced-motion&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#DBD7CAEE;--shiki-light:#393A34&quot;&gt; reduce&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt;  *&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt;  *&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#BD976A;--shiki-light:#B07D48&quot;&gt;before&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt;  *&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#BD976A;--shiki-light:#B07D48&quot;&gt;after&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;    animation-duration&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4C9A91;--shiki-light:#2F798A&quot;&gt; 0.01&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#CB7676;--shiki-light:#AB5959&quot;&gt;ms&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt; !important&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#B8A965;--shiki-light:#998418&quot;&gt;    transition-duration&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4C9A91;--shiki-light:#2F798A&quot;&gt; 0.01&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#CB7676;--shiki-light:#AB5959&quot;&gt;ms&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#4D9375;--shiki-light:#1E754F&quot;&gt; !important&lt;/span&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-dark:#666666;--shiki-light:#999999&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步是首页：三维点阵的 Hero、层叠滑入的作品卡片，以及一台真正会“响应”光标的仪器。&lt;/p&gt;</content:encoded><category>设计系统</category><category>Astro</category><category>动效</category></item></channel></rss>