diff --git a/ts/web/nextjs/polaris/public/backgrounds/test.jpg b/ts/web/nextjs/polaris/public/backgrounds/test.jpg index 61ecead..bf7a2bc 100644 Binary files a/ts/web/nextjs/polaris/public/backgrounds/test.jpg and b/ts/web/nextjs/polaris/public/backgrounds/test.jpg differ diff --git a/ts/web/nextjs/polaris/public/brand/logo.svg b/ts/web/nextjs/polaris/public/brand/logo.svg index 6ad38af..25f12b5 100644 --- a/ts/web/nextjs/polaris/public/brand/logo.svg +++ b/ts/web/nextjs/polaris/public/brand/logo.svg @@ -1,111 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + 北极星标志 + 透明背景的蓝色八角北极星标志,纵向星芒略长。 + + diff --git a/ts/web/nextjs/polaris/public/brand/logo_old.svg b/ts/web/nextjs/polaris/public/brand/logo_old.svg new file mode 100644 index 0000000..45595ac --- /dev/null +++ b/ts/web/nextjs/polaris/public/brand/logo_old.svg @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ts/web/nextjs/polaris/src/app/globals.css b/ts/web/nextjs/polaris/src/app/globals.css index d140882..4b5f6e3 100644 --- a/ts/web/nextjs/polaris/src/app/globals.css +++ b/ts/web/nextjs/polaris/src/app/globals.css @@ -4,7 +4,7 @@ --color-background: var(--background); --color-foreground: var(--text-primary); --color-primary: var(--primary); - --color-primary-foreground: #ffffff; + --color-primary-foreground: #10223e; --color-muted-foreground: var(--text-secondary); --color-border: var(--border-subtle); --radius-lg: var(--radius-card); @@ -12,41 +12,44 @@ } :root { - color-scheme: light; - --background: #dcebf5; - --text-primary: #0f172a; - --text-secondary: #64748b; - --text-muted: #94a3b8; - --primary: #3b82f6; - --primary-hover: #2563eb; - --primary-soft: rgba(59, 130, 246, 0.1); + color-scheme: dark; + --background: #101a2a; + --text-primary: #f4f7fc; + --text-secondary: #d7e2f0; + --text-muted: #bfd0e4; + --primary: #a9c9ff; + --primary-hover: #d3e3ff; + --primary-soft: rgba(147, 190, 255, 0.15); + /* Navigation stays translucent; a future reading surface can use this opaque tone. */ + --surface-reading: rgba(13, 23, 39, 0.96); --surface-sidebar: linear-gradient( - 180deg, - rgba(235, 243, 251, 0.52), - rgba(204, 220, 238, 0.34) + 155deg, + rgba(23, 34, 53, 0.69), + rgba(15, 26, 44, 0.64) ); --surface-search: linear-gradient( - 135deg, - rgba(240, 246, 252, 0.56), - rgba(210, 225, 241, 0.4) + 145deg, + rgba(30, 43, 62, 0.72), + rgba(19, 31, 50, 0.68) ); --surface-card: linear-gradient( - 135deg, - rgba(231, 240, 249, 0.43), - rgba(198, 216, 236, 0.32) + 145deg, + rgba(36, 50, 70, 0.64), + rgba(19, 31, 49, 0.61) ); --surface-card-hover: linear-gradient( - 135deg, - rgba(242, 248, 253, 0.6), - rgba(216, 230, 244, 0.48) + 145deg, + rgba(49, 65, 87, 0.73), + rgba(27, 42, 63, 0.71) ); - --border-glass: rgba(255, 255, 255, 0.38); - --border-subtle: rgba(15, 23, 42, 0.08); - --shadow-soft: inset 0 1px 0 rgba(255, 255, 255, 0.34); + --border-glass: rgba(222, 234, 255, 0.17); + --border-subtle: rgba(213, 228, 250, 0.16); + --shadow-soft: + 0 12px 32px rgba(3, 9, 23, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.12); --shadow-medium: - 0 22px 58px rgba(4, 12, 34, 0.17), inset 0 1px 0 rgba(255, 255, 255, 0.4); + 0 20px 48px rgba(3, 9, 23, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.14); --shadow-panel: - 0 28px 72px rgba(4, 12, 34, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.42); + 0 24px 64px rgba(3, 9, 23, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.13); --radius-card: 20px; --radius-panel: 24px; --sidebar-expanded: 240px; @@ -68,15 +71,15 @@ body { margin: 0; overflow-x: hidden; color: var(--text-primary); - background-color: #0b102b; + background-color: var(--background); background-image: url("/backgrounds/test.jpg"); background-position: center; background-size: cover; background-repeat: no-repeat; background-attachment: fixed; font-family: - Inter, - "SF Pro Display", + "Avenir Next", + Avenir, "SF Pro Text", -apple-system, BlinkMacSystemFont, @@ -95,9 +98,9 @@ body::before { pointer-events: none; background: linear-gradient( 180deg, - rgba(3, 7, 28, 0.2) 0%, - rgba(9, 18, 54, 0.07) 48%, - rgba(216, 230, 244, 0.08) 100% + rgba(5, 12, 25, 0.43) 0%, + rgba(8, 16, 31, 0.37) 48%, + rgba(7, 15, 28, 0.47) 100% ); -webkit-backdrop-filter: none; backdrop-filter: none; @@ -115,7 +118,7 @@ a { } :focus-visible { - outline: 3px solid rgba(59, 130, 246, 0.34); + outline: 2px solid #c9dfff; outline-offset: 3px; } @@ -124,8 +127,8 @@ a { border-radius: var(--radius-panel); background: var(--surface-card); box-shadow: var(--shadow-soft); - -webkit-backdrop-filter: blur(16px) saturate(134%); - backdrop-filter: blur(16px) saturate(134%); + -webkit-backdrop-filter: blur(18px) saturate(108%); + backdrop-filter: blur(18px) saturate(108%); } .app-shell { @@ -155,8 +158,8 @@ a { border-radius: var(--radius-panel); background: var(--surface-sidebar); box-shadow: var(--shadow-panel); - -webkit-backdrop-filter: blur(18px) saturate(132%); - backdrop-filter: blur(18px) saturate(132%); + -webkit-backdrop-filter: blur(20px) saturate(108%); + backdrop-filter: blur(20px) saturate(108%); transition: width 180ms ease; } @@ -167,7 +170,7 @@ a { align-items: center; gap: 10px; padding: 0 16px; - border-bottom: 1px solid rgba(255, 255, 255, 0.26); + border-bottom: 1px solid rgba(222, 234, 255, 0.11); } .sidebar__brand { @@ -233,7 +236,7 @@ a { justify-content: flex-start; gap: 12px; padding: 0 14px; - color: #334155; + color: var(--text-secondary); text-decoration: none; border: 0; border-radius: 16px; @@ -252,6 +255,7 @@ a { .sidebar__nav-item--active { color: var(--primary-hover); background: var(--primary-soft); + box-shadow: inset 0 0 0 1px rgba(169, 201, 255, 0.13); font-weight: 650; } @@ -322,7 +326,7 @@ a { font-weight: 700; line-height: 1.16; letter-spacing: -0.035em; - text-shadow: 0 3px 24px rgba(2, 6, 23, 0.48); + text-shadow: 0 2px 12px rgba(2, 6, 23, 0.8); text-wrap: balance; } @@ -331,7 +335,7 @@ a { color: rgba(241, 245, 249, 0.86); font-size: 16px; line-height: 1.6; - text-shadow: 0 2px 16px rgba(2, 6, 23, 0.42); + text-shadow: 0 2px 12px rgba(2, 6, 23, 0.8); } .search-box { @@ -349,8 +353,8 @@ a { border-radius: var(--radius-panel); background: var(--surface-search); box-shadow: var(--shadow-medium); - -webkit-backdrop-filter: blur(18px) saturate(136%); - backdrop-filter: blur(18px) saturate(136%); + -webkit-backdrop-filter: blur(20px) saturate(108%); + backdrop-filter: blur(20px) saturate(108%); transition: border-color 180ms ease, box-shadow 180ms ease, @@ -358,14 +362,10 @@ a { } .search-box__form:focus-within { - border-color: rgba(191, 219, 254, 0.46); - background: linear-gradient( - 135deg, - rgba(245, 249, 253, 0.66), - rgba(218, 231, 245, 0.52) - ); + border-color: rgba(185, 214, 255, 0.52); + background: var(--surface-search); box-shadow: - 0 0 0 4px rgba(147, 197, 253, 0.12), + 0 0 0 3px rgba(147, 197, 253, 0.17), var(--shadow-medium); } @@ -376,7 +376,7 @@ a { justify-content: center; margin-left: 10px; padding: 0; - color: #334155; + color: var(--text-secondary); border-radius: 16px; } @@ -387,18 +387,41 @@ a { object-fit: contain; } +/* The bundled GitHub mark is charcoal; lift only that mark on dark glass. */ +.search-provider-menu__icon[src*="github.svg"] { + filter: brightness(0) invert(1); + opacity: 0.88; +} + .search-provider-menu__trigger:hover, .search-provider-menu__trigger[aria-expanded="true"] { color: var(--primary-hover); background: var(--primary-soft); } +/* The provider menu is portalled outside the app shell. Match the search glass. */ +[data-slot="dropdown-menu-content"] { + color: var(--text-primary); + border-color: var(--border-glass); + background: rgba(19, 31, 49, 0.96); + box-shadow: var(--shadow-medium); +} + +[data-slot="dropdown-menu-radio-item"]:focus { + color: var(--primary-hover); + background: var(--primary-soft); +} + +[data-slot="dropdown-menu-radio-item"][data-state="checked"] { + color: var(--primary-hover); +} + .search-box__icon { width: 20px; height: 20px; flex: none; margin-left: 10px; - color: rgba(51, 65, 85, 0.58); + color: var(--text-muted); } .search-box__input { @@ -415,10 +438,15 @@ a { } .search-box__input::placeholder { - color: rgba(51, 65, 85, 0.62); + color: var(--text-muted); opacity: 1; } +.search-box__input:focus-visible { + /* The entire search field receives a visible focus ring above. */ + outline: none; +} + .search-box__shortcut { display: inline-flex; min-width: 50px; @@ -432,10 +460,10 @@ a { font-family: inherit; font-size: 12px; line-height: 1; - border: 1px solid rgba(100, 116, 139, 0.2); + border: 1px solid var(--border-subtle); border-radius: 9px; - background: rgba(255, 255, 255, 0.42); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.68); + background: rgba(201, 220, 248, 0.08); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); } .local-search-results { @@ -449,10 +477,10 @@ a { padding: 8px; border: 1px solid var(--border-glass); border-radius: 20px; - background: rgba(255, 255, 255, 0.9); + background: rgba(19, 31, 49, 0.95); box-shadow: var(--shadow-medium); - -webkit-backdrop-filter: blur(24px); - backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(20px); + backdrop-filter: blur(20px); } .local-search-results__option { @@ -473,10 +501,14 @@ a { .local-search-results__option[aria-selected="true"] { color: var(--primary-hover); - border-color: rgba(59, 130, 246, 0.08); + border-color: rgba(169, 201, 255, 0.17); background: var(--primary-soft); } +.local-search-results__option:hover { + background: rgba(147, 190, 255, 0.1); +} + .local-search-results__copy { display: flex; min-width: 0; @@ -521,7 +553,7 @@ a { color: rgba(248, 250, 252, 0.96); font-size: 16px; font-weight: 650; - text-shadow: 0 2px 14px rgba(2, 6, 23, 0.44); + text-shadow: 0 2px 12px rgba(2, 6, 23, 0.8); } .quick-links__grid { @@ -554,9 +586,9 @@ a { .quick-link-card:hover { transform: translateY(-2px); - border-color: rgba(255, 255, 255, 0.54); + border-color: rgba(222, 234, 255, 0.3); background: var(--surface-card-hover); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5); + box-shadow: var(--shadow-medium); } .quick-link-card > span:last-child { @@ -574,20 +606,24 @@ a { } .category-page__panel { + /* Leave the wallpaper sharp; only the text-bearing elements need glass. */ display: flex; height: 100%; min-height: 0; overflow: hidden; flex-direction: column; - padding: 48px clamp(32px, 4vw, 64px) 56px; - background: var(--surface-sidebar); - box-shadow: var(--shadow-panel); - -webkit-backdrop-filter: blur(18px) saturate(132%); - backdrop-filter: blur(18px) saturate(132%); + padding: 40px clamp(24px, 3.2vw, 48px) 32px; + border-color: transparent; + background: transparent; + box-shadow: none; + -webkit-backdrop-filter: none; + backdrop-filter: none; } .category-header { max-width: 720px; + padding: 16px 22px; + border: 1px solid transparent; } .category-header__title { @@ -597,6 +633,7 @@ a { font-weight: 700; line-height: 1.15; letter-spacing: -0.03em; + text-shadow: 0 2px 16px rgba(2, 8, 19, 0.85); } .category-header__description { @@ -604,6 +641,7 @@ a { color: var(--text-secondary); font-size: 16px; line-height: 1.7; + text-shadow: 0 2px 12px rgba(2, 8, 19, 0.9); } .category-tools { @@ -611,7 +649,7 @@ a { min-height: 0; flex: 1; flex-direction: column; - margin-top: 36px; + margin-top: 28px; } .category-tools__viewport { @@ -620,19 +658,25 @@ a { overflow-y: auto; overscroll-behavior-y: contain; flex: 1; - padding: 16px; - border: 1px solid rgba(255, 255, 255, 0.36); + padding: 14px; + border: 1px solid rgba(222, 234, 255, 0.2); border-radius: 20px; - background: rgba(82, 113, 151, 0.09); + background: rgba(5, 14, 29, 0.18); box-shadow: - inset 0 2px 10px rgba(29, 56, 93, 0.07), - inset 0 1px 0 rgba(255, 255, 255, 0.22); + 0 14px 36px rgba(2, 8, 19, 0.12), + inset 0 1px 0 rgba(255, 255, 255, 0.07); } .category-tools__viewport:focus-visible { outline-offset: -4px; } +.category-tools__viewport:has(> .category-empty-state) { + display: flex; + align-items: center; + justify-content: center; +} + .category-section-header { display: flex; flex: none; @@ -645,34 +689,35 @@ a { margin: 0; font-size: 18px; font-weight: 700; + text-shadow: 0 2px 12px rgba(2, 8, 19, 0.9); } .category-section-header__count { padding: 4px 10px; - color: #334155; + color: var(--text-secondary); font-size: 14px; font-weight: 600; - border: 1px solid rgba(71, 104, 138, 0.24); + border: 1px solid var(--border-subtle); border-radius: 999px; - background: rgba(238, 246, 253, 0.88); + background: rgba(10, 21, 38, 0.65); } .tool-card { position: relative; display: flex; min-width: 0; - height: 96px; + height: 82px; align-items: center; - gap: 16px; - padding: 20px 22px; + gap: 14px; + padding: 14px 16px; color: var(--text-primary); text-decoration: none; - border: 1px solid var(--border-glass); + border: 1px solid rgba(222, 234, 255, 0.22); border-radius: 18px; - background: var(--surface-card); + background: rgba(12, 24, 42, 0.65); box-shadow: var(--shadow-soft); - -webkit-backdrop-filter: blur(16px) saturate(134%); - backdrop-filter: blur(16px) saturate(134%); + -webkit-backdrop-filter: blur(10px) saturate(108%); + backdrop-filter: blur(10px) saturate(108%); transition: transform 180ms ease, background 180ms ease, @@ -681,8 +726,9 @@ a { .tool-card:hover { transform: translateY(-2px); - border-color: rgba(255, 255, 255, 0.54); - background: var(--surface-card-hover); + border-color: rgba(222, 234, 255, 0.42); + background: rgba(25, 43, 65, 0.84); + box-shadow: var(--shadow-medium); } .tool-card__icon { @@ -739,7 +785,7 @@ a { padding: 0; list-style: none; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 20px 24px; + gap: 14px 16px; } .tool-grid__item { @@ -757,9 +803,12 @@ a { } .category-tools__viewport > .category-empty-state { - height: 100%; - min-height: 0; - padding-block: 20px; + width: min(100%, 440px); + min-height: 200px; + flex: none; + padding: 20px; + border-radius: 14px; + background: rgba(10, 21, 38, 0.65); } .category-empty-state > svg { @@ -822,14 +871,14 @@ a { color: var(--primary-hover); font-size: 15px; font-weight: 700; - background: rgba(219, 234, 254, 0.7); - box-shadow: inset 0 0 0 1px rgba(59, 130, 246, 0.08); + background: rgba(138, 180, 238, 0.16); + box-shadow: inset 0 0 0 1px rgba(169, 201, 255, 0.13); } .local-search-results, .sidebar__nav, .category-tools__viewport { - scrollbar-color: rgba(100, 116, 139, 0.32) transparent; + scrollbar-color: rgba(185, 206, 233, 0.34) transparent; scrollbar-width: thin; } @@ -860,45 +909,43 @@ a { } @media (max-width: 767px) { - /* Keep category navigation usable without squeezing the boxed content. */ - .app-shell:has(.category-page) .sidebar { + /* A shared top rail keeps home and category navigation usable on phones. */ + .app-shell .sidebar { inset: 12px 12px auto; width: auto; height: 124px; } - .app-shell:has(.category-page) .sidebar__header, - .app-shell:has(.category-page)[data-sidebar-collapsed="true"] - .sidebar__header { + .app-shell .sidebar__header, + .app-shell[data-sidebar-collapsed="true"] .sidebar__header { min-height: 56px; flex-direction: row; padding: 0 12px; } - .app-shell:has(.category-page) .sidebar__header > button { + .app-shell .sidebar__header > button { display: none; } - .app-shell:has(.category-page) .sidebar__brand { + .app-shell .sidebar__brand { justify-content: flex-start; } - .app-shell:has(.category-page) .sidebar__nav, - .app-shell:has(.category-page)[data-sidebar-collapsed="true"] .sidebar__nav { + .app-shell .sidebar__nav, + .app-shell[data-sidebar-collapsed="true"] .sidebar__nav { flex-direction: row; overflow-x: auto; overflow-y: hidden; padding: 8px 12px 12px; } - .app-shell:has(.category-page) .sidebar__categories { + .app-shell .sidebar__categories { flex: none; flex-direction: row; } - .app-shell:has(.category-page) .sidebar__nav-item, - .app-shell:has(.category-page)[data-sidebar-collapsed="true"] - .sidebar__nav-item { + .app-shell .sidebar__nav-item, + .app-shell[data-sidebar-collapsed="true"] .sidebar__nav-item { width: auto; height: 40px; min-height: 40px; @@ -907,8 +954,8 @@ a { padding-inline: 12px; } - .app-shell:has(.category-page) .sidebar__site-name.sr-only, - .app-shell:has(.category-page) .sidebar__label.sr-only { + .app-shell .sidebar__site-name.sr-only, + .app-shell .sidebar__label.sr-only { position: static; width: auto; height: auto; @@ -918,20 +965,44 @@ a { white-space: nowrap; } - .app-shell:has(.category-page) .app-shell__content { + .app-shell .app-shell__content { margin-left: 0; } + .home-content { + padding: 188px 20px 48px; + } + + .search-box { + margin-top: 32px; + } + + .quick-links { + margin-top: 36px; + } + + .quick-links__grid { + gap: 12px; + } + + .quick-link-card { + padding-inline: 14px; + } + .category-page { padding: 148px 12px 12px; } .category-page__panel { - padding: 28px 20px 36px; + padding: 24px 12px 20px; + } + + .category-header { + padding: 14px 16px; } .category-tools__viewport { - padding: 12px; + padding: 8px; } .category-header__title { @@ -939,6 +1010,20 @@ a { } } +@media (max-width: 420px) { + .quick-links__grid { + grid-template-columns: minmax(0, 1fr); + } + + .home-content { + padding-inline: 16px; + } + + .search-box__shortcut { + display: none; + } +} + /* When the header would leave only a sliver of cards, let the page scroll instead. */ @media (max-height: 540px), (max-width: 767px) and (max-height: 700px) { .category-page { @@ -960,11 +1045,6 @@ a { overflow: visible; flex: none; } - - .category-tools__viewport > .category-empty-state { - height: auto; - min-height: 200px; - } } @media (max-width: 767px) and (max-height: 700px) { diff --git a/ts/web/nextjs/polaris/src/app/layout.tsx b/ts/web/nextjs/polaris/src/app/layout.tsx index d2cd296..67f2364 100644 --- a/ts/web/nextjs/polaris/src/app/layout.tsx +++ b/ts/web/nextjs/polaris/src/app/layout.tsx @@ -11,8 +11,8 @@ export const metadata: Metadata = { } export const viewport: Viewport = { - colorScheme: "light", - themeColor: "#dcebf5", + colorScheme: "dark", + themeColor: "#101a2a", } export default function RootLayout({