From 29dd5cd04f6e8698e9cd32887a94ebb6bb4d4564 Mon Sep 17 00:00:00 2001 From: Jason <150260202+estelledc@users.noreply.github.com> Date: Sun, 12 Jul 2026 10:30:32 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=95=99=E7=A8=8B=E7=AB=99?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=EF=BC=9A=E6=94=B6=E6=95=9B=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E5=8F=8D=E9=A6=88=E4=B8=8E=E5=8A=A8=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4 --- _sass/jx/VERSION | 2 +- _sass/jx/_base.scss | 8 +--- _sass/jx/_components.scss | 83 ++++++++++++++++++++++++++++++++----- _sass/jx/_tokens.scss | 14 +++++-- _sass/jx/base.css | 8 +--- _sass/jx/components.css | 83 ++++++++++++++++++++++++++++++++----- _sass/jx/tokens.css | 14 +++++-- _sass/opendesign/theme.scss | 25 ++++------- scripts/check-showcase.rb | 9 +++- 9 files changed, 187 insertions(+), 59 deletions(-) diff --git a/_sass/jx/VERSION b/_sass/jx/VERSION index 7ec1d6d..ccbccc3 100644 --- a/_sass/jx/VERSION +++ b/_sass/jx/VERSION @@ -1 +1 @@ -2.1.0 +2.2.0 diff --git a/_sass/jx/_base.scss b/_sass/jx/_base.scss index 96dc573..4bb0069 100644 --- a/_sass/jx/_base.scss +++ b/_sass/jx/_base.scss @@ -1,4 +1,4 @@ -/* Jason DS · Base v2.0.0 +/* Jason DS · Base v2.2.0 * 默认 reset + body 排版基底 + chrome layer 强制 sans */ @@ -155,11 +155,7 @@ hr { color: var(--jx-ink); } -/* Reduce motion */ +/* Reduced motion keeps semantic color/opacity feedback; components remove travel. */ @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } - * { - animation-duration: 0.01ms !important; - transition-duration: 0.01ms !important; - } } diff --git a/_sass/jx/_components.scss b/_sass/jx/_components.scss index c430b87..2f6d438 100644 --- a/_sass/jx/_components.scss +++ b/_sass/jx/_components.scss @@ -82,7 +82,7 @@ --_chip-glyph: var(--jx-state-archived-glyph); } -/* Jason DS · External Pill v1.0.0 +/* Jason DS · External Pill v2.2.0 * 出站链接统一 hairline + 右上 ↗ 箭头 (no icon font) */ @@ -112,15 +112,25 @@ color: var(--jx-accent); box-shadow: 0 0 0 1px var(--jx-accent); } -.jx-pill:hover::after { - color: var(--jx-accent); - transform: translate(1px, -1px); -} +.jx-pill:hover::after { color: var(--jx-accent); } .jx-pill:focus-visible { outline: none; box-shadow: var(--jx-shadow-focus); } +@media (hover: hover) and (pointer: fine) { + .jx-pill:hover::after { + transform: translate(1px, -1px); + } +} + +@media (prefers-reduced-motion: reduce) { + .jx-pill::after { + transform: none; + transition: color var(--jx-duration-fast) var(--jx-ease-out); + } +} + /* Jason DS · Footer v1.0.0 * 三栏:colophon / 索引 / last-updated * Layer 1:9 仓必有此结构 @@ -207,7 +217,7 @@ box-shadow: var(--jx-shadow-focus); } -/* Jason DS · Site chrome v2.0.0 +/* Jason DS · Site chrome v2.2.0 * Shared identity, accessible navigation, skip link, and action styles. */ @@ -237,6 +247,7 @@ background: color-mix(in oklab, var(--jx-paper), transparent 8%); border-bottom: 1px solid var(--jx-rule); backdrop-filter: blur(16px) saturate(120%); + -webkit-backdrop-filter: blur(16px) saturate(120%); } .jx-site-header__inner { @@ -311,13 +322,18 @@ font-weight: var(--jx-weight-ui); line-height: 1; text-decoration: none; - transition: transform var(--jx-duration-fast) var(--jx-easing), - background var(--jx-duration-fast) var(--jx-easing); + transition: transform var(--jx-duration-press) var(--jx-ease-out), + color var(--jx-duration-fast) var(--jx-ease-out), + background-color var(--jx-duration-fast) var(--jx-ease-out), + border-color var(--jx-duration-fast) var(--jx-ease-out); } .jx-action:hover { color: var(--jx-cta-fg); - transform: translateY(-1px); +} + +.jx-action:active { + transform: scale(var(--jx-press-scale)); } .jx-action--secondary { @@ -331,6 +347,54 @@ background: var(--jx-surface-sunk); } +@media (hover: hover) and (pointer: fine) { + .jx-action:hover { + transform: translateY(-1px); + } + + .jx-action:active { + transform: scale(var(--jx-press-scale)); + } +} + +@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { + .jx-site-header { + background: var(--jx-paper); + } +} + +@media (prefers-reduced-transparency: reduce) { + .jx-site-header { + background: var(--jx-paper); + backdrop-filter: none; + -webkit-backdrop-filter: none; + } +} + +@media (prefers-contrast: more) { + .jx-site-header { + background: var(--jx-paper); + border-bottom-color: var(--jx-rule-strong); + backdrop-filter: none; + -webkit-backdrop-filter: none; + } +} + +@media (prefers-reduced-motion: reduce) { + .jx-skip-link { + transition: none; + } + + .jx-action, + .jx-action:hover, + .jx-action:active { + transform: none; + transition-property: color, background-color, border-color; + transition-duration: var(--jx-duration-fast); + transition-timing-function: var(--jx-ease-out); + } +} + @media (max-width: 760px) { .jx-site-header__inner { align-items: flex-start; @@ -383,7 +447,6 @@ } } - /* Jason DS · Project proof v2.0.0 * Hiring-facing evidence block used on project and documentation homepages. */ diff --git a/_sass/jx/_tokens.scss b/_sass/jx/_tokens.scss index c668a15..73048b1 100644 --- a/_sass/jx/_tokens.scss +++ b/_sass/jx/_tokens.scss @@ -1,4 +1,4 @@ -/* Jason DS · Tokens v2.0.0 +/* Jason DS · Tokens v2.2.0 * SoT: dotfiles/home-claude/design-system/jx-tokens.css * 展示站通过 vendor copy 同步:scripts/sync-jx-to-repos.sh * @@ -134,12 +134,18 @@ --jx-shadow-focus: 0 0 0 3px var(--jx-focus-ring); --jx-shadow-press: inset 0 1px 0 rgba(22,24,29,0.06); - /* ── Motion ── */ - --jx-easing: cubic-bezier(0.2, 0.8, 0.2, 1); - --jx-easing-press: cubic-bezier(0.4, 0, 0.6, 1); + /* ── Motion · responsive by default, quiet by frequency ── */ + --jx-ease-out: cubic-bezier(0.23, 1, 0.32, 1); + --jx-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); + --jx-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); + --jx-easing: var(--jx-ease-out); /* compatibility alias */ + --jx-easing-press: var(--jx-ease-out); --jx-duration-fast: 120ms; + --jx-duration-press: 140ms; + --jx-duration-popover: 180ms; --jx-duration-base: 200ms; --jx-duration-slow: 320ms; + --jx-press-scale: 0.97; } /* ── Color · dark mirror ── */ diff --git a/_sass/jx/base.css b/_sass/jx/base.css index 96dc573..4bb0069 100644 --- a/_sass/jx/base.css +++ b/_sass/jx/base.css @@ -1,4 +1,4 @@ -/* Jason DS · Base v2.0.0 +/* Jason DS · Base v2.2.0 * 默认 reset + body 排版基底 + chrome layer 强制 sans */ @@ -155,11 +155,7 @@ hr { color: var(--jx-ink); } -/* Reduce motion */ +/* Reduced motion keeps semantic color/opacity feedback; components remove travel. */ @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } - * { - animation-duration: 0.01ms !important; - transition-duration: 0.01ms !important; - } } diff --git a/_sass/jx/components.css b/_sass/jx/components.css index c430b87..2f6d438 100644 --- a/_sass/jx/components.css +++ b/_sass/jx/components.css @@ -82,7 +82,7 @@ --_chip-glyph: var(--jx-state-archived-glyph); } -/* Jason DS · External Pill v1.0.0 +/* Jason DS · External Pill v2.2.0 * 出站链接统一 hairline + 右上 ↗ 箭头 (no icon font) */ @@ -112,15 +112,25 @@ color: var(--jx-accent); box-shadow: 0 0 0 1px var(--jx-accent); } -.jx-pill:hover::after { - color: var(--jx-accent); - transform: translate(1px, -1px); -} +.jx-pill:hover::after { color: var(--jx-accent); } .jx-pill:focus-visible { outline: none; box-shadow: var(--jx-shadow-focus); } +@media (hover: hover) and (pointer: fine) { + .jx-pill:hover::after { + transform: translate(1px, -1px); + } +} + +@media (prefers-reduced-motion: reduce) { + .jx-pill::after { + transform: none; + transition: color var(--jx-duration-fast) var(--jx-ease-out); + } +} + /* Jason DS · Footer v1.0.0 * 三栏:colophon / 索引 / last-updated * Layer 1:9 仓必有此结构 @@ -207,7 +217,7 @@ box-shadow: var(--jx-shadow-focus); } -/* Jason DS · Site chrome v2.0.0 +/* Jason DS · Site chrome v2.2.0 * Shared identity, accessible navigation, skip link, and action styles. */ @@ -237,6 +247,7 @@ background: color-mix(in oklab, var(--jx-paper), transparent 8%); border-bottom: 1px solid var(--jx-rule); backdrop-filter: blur(16px) saturate(120%); + -webkit-backdrop-filter: blur(16px) saturate(120%); } .jx-site-header__inner { @@ -311,13 +322,18 @@ font-weight: var(--jx-weight-ui); line-height: 1; text-decoration: none; - transition: transform var(--jx-duration-fast) var(--jx-easing), - background var(--jx-duration-fast) var(--jx-easing); + transition: transform var(--jx-duration-press) var(--jx-ease-out), + color var(--jx-duration-fast) var(--jx-ease-out), + background-color var(--jx-duration-fast) var(--jx-ease-out), + border-color var(--jx-duration-fast) var(--jx-ease-out); } .jx-action:hover { color: var(--jx-cta-fg); - transform: translateY(-1px); +} + +.jx-action:active { + transform: scale(var(--jx-press-scale)); } .jx-action--secondary { @@ -331,6 +347,54 @@ background: var(--jx-surface-sunk); } +@media (hover: hover) and (pointer: fine) { + .jx-action:hover { + transform: translateY(-1px); + } + + .jx-action:active { + transform: scale(var(--jx-press-scale)); + } +} + +@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { + .jx-site-header { + background: var(--jx-paper); + } +} + +@media (prefers-reduced-transparency: reduce) { + .jx-site-header { + background: var(--jx-paper); + backdrop-filter: none; + -webkit-backdrop-filter: none; + } +} + +@media (prefers-contrast: more) { + .jx-site-header { + background: var(--jx-paper); + border-bottom-color: var(--jx-rule-strong); + backdrop-filter: none; + -webkit-backdrop-filter: none; + } +} + +@media (prefers-reduced-motion: reduce) { + .jx-skip-link { + transition: none; + } + + .jx-action, + .jx-action:hover, + .jx-action:active { + transform: none; + transition-property: color, background-color, border-color; + transition-duration: var(--jx-duration-fast); + transition-timing-function: var(--jx-ease-out); + } +} + @media (max-width: 760px) { .jx-site-header__inner { align-items: flex-start; @@ -383,7 +447,6 @@ } } - /* Jason DS · Project proof v2.0.0 * Hiring-facing evidence block used on project and documentation homepages. */ diff --git a/_sass/jx/tokens.css b/_sass/jx/tokens.css index c668a15..73048b1 100644 --- a/_sass/jx/tokens.css +++ b/_sass/jx/tokens.css @@ -1,4 +1,4 @@ -/* Jason DS · Tokens v2.0.0 +/* Jason DS · Tokens v2.2.0 * SoT: dotfiles/home-claude/design-system/jx-tokens.css * 展示站通过 vendor copy 同步:scripts/sync-jx-to-repos.sh * @@ -134,12 +134,18 @@ --jx-shadow-focus: 0 0 0 3px var(--jx-focus-ring); --jx-shadow-press: inset 0 1px 0 rgba(22,24,29,0.06); - /* ── Motion ── */ - --jx-easing: cubic-bezier(0.2, 0.8, 0.2, 1); - --jx-easing-press: cubic-bezier(0.4, 0, 0.6, 1); + /* ── Motion · responsive by default, quiet by frequency ── */ + --jx-ease-out: cubic-bezier(0.23, 1, 0.32, 1); + --jx-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); + --jx-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); + --jx-easing: var(--jx-ease-out); /* compatibility alias */ + --jx-easing-press: var(--jx-ease-out); --jx-duration-fast: 120ms; + --jx-duration-press: 140ms; + --jx-duration-popover: 180ms; --jx-duration-base: 200ms; --jx-duration-slow: 320ms; + --jx-press-scale: 0.97; } /* ── Color · dark mirror ── */ diff --git a/_sass/opendesign/theme.scss b/_sass/opendesign/theme.scss index 4f3c278..0ed46c9 100644 --- a/_sass/opendesign/theme.scss +++ b/_sass/opendesign/theme.scss @@ -570,13 +570,7 @@ a:hover { color: var(--jx-accent-hover); } background: var(--jx-surface); border-top: 3px solid var(--jx-rule-strong); text-decoration: none; - transition: transform var(--jx-duration-fast) var(--jx-easing), - border-color var(--jx-duration-fast) var(--jx-easing); -} -.week-card:hover { - color: var(--jx-ink); - border-color: var(--jx-accent); - transform: translateY(-3px); + transition: border-color var(--jx-duration-fast) var(--jx-ease-out); } .week-card__meta { margin-top: auto; @@ -1036,14 +1030,13 @@ a:hover { color: var(--jx-accent-hover); } .jx-footer { padding-inline: 0; } } -@media (prefers-reduced-motion: reduce) { - *, - *::before, - *::after { - scroll-behavior: auto !important; - transition-duration: 0.01ms !important; - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; +@media (hover: hover) and (pointer: fine) { + .week-card:hover { + color: var(--jx-ink); + border-color: var(--jx-accent); } - .week-card:hover { transform: none; } +} + +@media (prefers-reduced-motion: reduce) { + html { scroll-behavior: auto; } } diff --git a/scripts/check-showcase.rb b/scripts/check-showcase.rb index 008aea9..3c90431 100644 --- a/scripts/check-showcase.rb +++ b/scripts/check-showcase.rb @@ -122,9 +122,14 @@ def png_dimensions(path) check(layout.include?('"@type": "Person"'), "homepage JSON-LD must describe its creator") check(!layout.include?("{% seo %}"), "layout must not emit a second incomplete Person through jekyll-seo-tag") check(theme.include?("@media (prefers-reduced-motion: reduce)"), "theme is missing reduced-motion handling") +check(theme.include?("@media (hover: hover) and (pointer: fine)"), "theme is missing fine-pointer hover gating") +check(!theme.match?(/\btransition\s*:\s*all\b/i), "theme contains transition: all") +check(!theme.match?(/\bscale\(\s*0(?:\.0+)?\s*\)/i), "theme contains scale(0)") +check(!theme.match?(/(?