Подпись StackWorks: вариант «штамп» со знаком и анимацией полос
Claude-Session: https://claude.ai/code/session_01BFaqS6mH9sa99RWghq2j46
Этот коммит содержится в:
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Подпись студии StackWorks («штамп»): знак и две строки - «разработка и поддержка» / StackWorks.
|
||||
* В остальных проектах она ставится скриптом https://stackworks.ru/sign/sw-sign.js,
|
||||
* здесь - компонентом, чтобы React не спорил с чужими изменениями страницы.
|
||||
* Оформление в src/index.css, классы swsig*.
|
||||
*/
|
||||
export default function SwSignature({ dark = false }: { dark?: boolean }) {
|
||||
const bg = dark ? '#F3F1EB' : '#16171C';
|
||||
const fg = dark ? '#16171C' : '#F3F1EB';
|
||||
return (
|
||||
<a
|
||||
className={'swsig' + (dark ? ' swsig-dark' : '')}
|
||||
href="https://stackworks.ru/?utm_source=mail.stackworks.ru&utm_medium=signature"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
aria-label="Разработка и поддержка - StackWorks"
|
||||
>
|
||||
<svg viewBox="0 0 100 100" aria-hidden="true">
|
||||
<rect x="2" y="2" width="96" height="96" rx="25" fill={bg} />
|
||||
<rect className="b b1" x="20" y="29" width="44" height="12" rx="6" fill={fg} />
|
||||
<rect className="b b2" x="30" y="45" width="50" height="12" rx="6" fill="#FF4A1C" />
|
||||
<rect className="b b3" x="40" y="61" width="34" height="12" rx="6" fill={fg} />
|
||||
</svg>
|
||||
<span className="swsig-txt">
|
||||
<span className="swsig-cap">разработка и поддержка</span>
|
||||
<span className="swsig-word">Stack<i>Works</i></span>
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
import SwSignature from '@/components/common/SwSignature';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import * as LucideIcons from 'lucide-react';
|
||||
@@ -365,6 +366,10 @@ export function Sidebar() {
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center px-3 py-3">
|
||||
<SwSignature dark />
|
||||
</div>
|
||||
|
||||
{layouts.length > 1 && (
|
||||
<TooltipProvider>
|
||||
<div className="sw-aside-foot flex items-center justify-around border-t bg-background px-2 py-2">
|
||||
|
||||
@@ -165,3 +165,20 @@ aside.sw-aside .text-muted-foreground { color: #8d8f96 !important; }
|
||||
@media (max-width: 640px) {
|
||||
main h1 { font-size: 1.6rem; }
|
||||
}
|
||||
|
||||
/* подпись студии (компонент SwSignature, повторяет https://stackworks.ru/sign/sw-sign.js) */
|
||||
.swsig { --ink: #16171c; --cap: #6a6c75; --acc: #ff4a1c; display: inline-flex; align-items: center; gap: 10px;
|
||||
min-height: 44px; text-decoration: none; color: var(--ink); border-radius: 8px; }
|
||||
.swsig-dark { --ink: #f3f1eb; --cap: #9a9ca3; }
|
||||
.swsig svg { width: 30px; height: 30px; flex: 0 0 auto; display: block; }
|
||||
.swsig-txt { display: flex; flex-direction: column; gap: 4px; }
|
||||
.swsig-cap { font: 400 11.5px/1 'SW Inter', system-ui, sans-serif; color: var(--cap); white-space: nowrap; }
|
||||
.swsig-word { font: 700 16px/1 'SW Rubik', sans-serif; letter-spacing: -.01em; color: var(--ink); white-space: nowrap; }
|
||||
.swsig-word i { font-style: normal; color: var(--acc); }
|
||||
@keyframes swsig-shuffle { 0%, 100% { transform: translateX(0); } 45% { transform: translateX(9px); } }
|
||||
.swsig .b { transform-box: fill-box; }
|
||||
.swsig:hover .b, .swsig:focus-visible .b { animation: swsig-shuffle .38s ease-in-out both; }
|
||||
.swsig:hover .b2, .swsig:focus-visible .b2 { animation-delay: .07s; }
|
||||
.swsig:hover .b3, .swsig:focus-visible .b3 { animation-delay: .14s; }
|
||||
.swsig:focus-visible { outline: 2px solid var(--acc); outline-offset: 4px; }
|
||||
@media (prefers-reduced-motion: reduce) { .swsig .b { animation: none !important; } }
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { ArrowRight, Loader2 } from 'lucide-react';
|
||||
|
||||
import Logo from '@/components/common/Logo';
|
||||
import SwSignature from '@/components/common/SwSignature';
|
||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
@@ -43,7 +44,7 @@ export default function LoginPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-content-background px-4">
|
||||
<div className="flex min-h-screen flex-col items-center justify-center gap-6 bg-content-background px-4">
|
||||
<Card className="w-full max-w-sm shadow-sm">
|
||||
<CardHeader className="items-center text-center">
|
||||
<Logo />
|
||||
@@ -87,6 +88,7 @@ export default function LoginPage() {
|
||||
</form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<SwSignature />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user