Files
community-rule/app/components/asset/Logo/Logo.tsx
T
adilalloandCursor 4bd9fa6dc6 Restore the folder header to Figma layout without cloning the nav, and page-center inner-page links with the home cluster.
Park the skip link in the Tailwind sheet so it cannot sit in document flow and push the yellow tab down.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-09 21:39:39 -06:00

140 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { memo } from "react";
import Link from "next/link";
import { useTranslation } from "../../../contexts/MessagesContext";
import { getAssetPath, ASSETS } from "../../../../lib/assetUtils";
interface LogoProps {
size?:
| "default"
| "footer"
| "createFlow"
| "topNavFolderTop"
| "topNavHeader";
/**
* Visual style: default (dark on light) or inverse (e.g. black/white on teal).
* @default "default"
*/
palette?: "default" | "inverse";
/**
* Whether to show the "CommunityRule" wordmark.
* @default true
*/
wordmark?: boolean;
}
interface SizeConfig {
containerHeight: string;
gap: string;
textSize: string;
lineHeight: string;
iconSize: string;
}
const Logo = memo<LogoProps>(
({ size = "default", palette = "default", wordmark = true }) => {
const t = useTranslation("controlsChrome");
// Figma: "Asset / Logo" (4002:6735) — 40×6×27 at 1x; nav/footer/create-flow
// instances scale that lockup.
const sizes: Record<string, SizeConfig> = {
default: {
containerHeight: "h-[var(--spacing-scale-040)]",
gap: "gap-[var(--spacing-scale-006)]",
textSize: "text-[21.97px]",
lineHeight: "leading-[27.05px]",
iconSize: "w-[27px] h-[27px]",
},
footer: {
containerHeight: "h-[41px] md:h-[56px] lg:h-[82px]",
gap: "gap-[6.21px] md:gap-[8.49px] lg:gap-[12.43px]",
textSize:
"text-[22.75px] md:text-[31.08px] lg:text-[45.51px]",
lineHeight:
"leading-[28px] md:leading-[38.25px] lg:leading-[56.01px]",
iconSize:
"w-[27.96px] h-[27.96px] md:w-[38.18px] md:h-[38.18px] lg:w-[55.91px] lg:h-[55.91px]",
},
createFlow: {
containerHeight: "h-[30px] md:h-[var(--spacing-scale-040)]",
gap: "gap-[4.5px] md:gap-[var(--spacing-scale-006)]",
textSize: "text-[16.48px] md:text-[21.97px]",
lineHeight: "leading-[20.28px] md:leading-[27.05px]",
iconSize: "w-[20.25px] h-[20.25px] md:w-[27px] md:h-[27px]",
},
topNavFolderTop: {
containerHeight:
"h-[14.1px] sm:h-[21.35px] md:h-[var(--spacing-scale-032)] lg:h-[var(--spacing-scale-040)] xl:h-[50.35px]",
gap: "gap-0 sm:gap-[3.2px] md:gap-[4.8px] lg:gap-[var(--spacing-scale-006)] xl:gap-[7.5px]",
textSize:
"text-[11.57px] sm:text-[11.72px] md:text-[17.58px] lg:text-[21.97px] xl:text-[27.47px]",
lineHeight:
"leading-[14.24px] sm:leading-[14.42px] md:leading-[21.64px] lg:leading-[27.05px] xl:leading-[33.81px]",
iconSize:
"w-[14.1px] h-[14.1px] sm:w-[14.4px] sm:h-[14.4px] md:w-[21.6px] md:h-[21.6px] lg:w-[27px] lg:h-[27px] xl:w-[33.75px] xl:h-[33.75px]",
},
topNavHeader: {
containerHeight:
"h-[14.2px] sm:h-[21.22px] md:h-[var(--spacing-scale-032)] lg:h-[40.69px] xl:h-[50.35px]",
gap: "gap-0 sm:gap-[3.18px] md:gap-[4.85px] lg:gap-[6.06px] xl:gap-[7.5px]",
textSize:
"text-[11.57px] sm:text-[11.66px] md:text-[17.76px] lg:text-[22.2px] xl:text-[27.47px]",
lineHeight:
"leading-[14.24px] sm:leading-[14.35px] md:leading-[21.86px] lg:leading-[27.32px] xl:leading-[33.81px]",
iconSize:
"w-[14.2px] h-[14.2px] sm:w-[14.33px] sm:h-[14.33px] md:w-[21.82px] md:h-[21.82px] lg:w-[27.27px] lg:h-[27.27px] xl:w-[33.75px] xl:h-[33.75px]",
},
};
const config = sizes[size || "default"] || sizes.default;
const isInverse = palette === "inverse";
const textColorClass = isInverse
? "text-[var(--color-content-invert-primary)]"
: "text-[var(--color-content-default-primary)]";
const wordmarkVisibilityClass =
size === "topNavHeader"
? wordmark
? "hidden md:block"
: "hidden"
: wordmark
? ""
: "hidden";
return (
<Link href="/" className="group block" aria-label={t("logoAlt")}>
<div
className={`flex items-center ${config.containerHeight} ${
wordmark ? config.gap : ""
} cursor-pointer`}
>
{/* Logo Text - responsive visibility for topNav sizes */}
<div
className={`font-bricolage-grotesque ${textColorClass} ${config.textSize} ${config.lineHeight} font-normal tracking-[0px] transition-opacity duration-200 ease-out group-hover:opacity-80 ${wordmarkVisibilityClass}`}
aria-label={t("logoText")}
>
{t("logoText")}
</div>
{/* Vector Icon */}
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={getAssetPath(ASSETS.LOGO)}
alt={t("logoAlt")}
width={27}
height={27}
className={`flex-shrink-0 ${config.iconSize} origin-center transition-transform duration-200 ease-out group-hover:scale-110 ${
isInverse ? "brightness-0" : ""
}`}
aria-hidden="true"
/>
</div>
</Link>
);
},
);
Logo.displayName = "Logo";
export default Logo;