Update branding guidelines and assets
Adds a comprehensive `BRAND_GUIDELINES.md` file detailing brand assets, color palettes, and typography. This commit also introduces multiple SVG assets for various logo usages (icon, horizontal, dark mode), updates the main `layout.tsx` metadata, and adds the necessary component files (`LogoIcon.tsx`, `LogoHorizontal.tsx`, etc.) to support these new assets.
@@ -0,0 +1,76 @@
|
||||
# TimeToLeave Brand Guidelines
|
||||
|
||||
## Logo
|
||||
|
||||
The TimeToLeave logo combines a clock face with an arrow pointing to 10:10 (the classic "watch ad" time), symbolizing "it's time to go."
|
||||
|
||||
### Meaning
|
||||
- **Clock face** = Time awareness, countdowns, punctuality
|
||||
- **Orange→Yellow arrow** = Departure, leaving, urgency
|
||||
- **Blue→Purple gradient** = Trust, technology, professionalism
|
||||
- **Exit door** (on full icon) = Leaving, heading out
|
||||
|
||||
## Colors
|
||||
|
||||
### Primary
|
||||
| Name | Hex | Usage |
|
||||
|------|-----|-------|
|
||||
| System Blue | `#007AFF` | Primary actions, links, active states |
|
||||
| Indigo | `#5856D6` | Gradients, secondary elements |
|
||||
|
||||
### Accent
|
||||
| Name | Hex | Usage |
|
||||
|------|-----|-------|
|
||||
| Orange | `#FF9500` | Warnings, countdowns, arrow accents |
|
||||
| Gold | `#FFD60A` | Highlights, urgency indicators |
|
||||
|
||||
### Status Colors (Countdown)
|
||||
| Status | Color | Meaning |
|
||||
|--------|-------|---------|
|
||||
| Red | `#FF3B30` | Leave now / Late |
|
||||
| Orange | `#FF9500` | Getting close |
|
||||
| Yellow | `#FFCC00` | On track |
|
||||
| Green | `#34C759` | Plenty of time |
|
||||
| Blue | `#5AC8FA` | Confirmed / Done |
|
||||
|
||||
## Typography
|
||||
|
||||
- **Primary:** System font stack (`system-ui, -apple-system, sans-serif`)
|
||||
- **Weights:** 700 for headings, 400 for body, 300 for captions
|
||||
- **Letter spacing:** -0.02em for headings (tighter, more modern)
|
||||
|
||||
## Logo Variants
|
||||
|
||||
### Icon Only
|
||||
Use `LogoIcon` component for favicons, app icons, loading states.
|
||||
|
||||
### Horizontal Logo
|
||||
Use `LogoHorizontal` component for headers, navigation, about pages.
|
||||
|
||||
### Full Logo (SVG)
|
||||
Use `assets/logo.svg` for downloads, print, marketing materials.
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { LogoIcon, LogoHorizontal } from "@/app/ui/logos";
|
||||
|
||||
// Icon only (48px)
|
||||
<LogoIcon size={48} />
|
||||
|
||||
// Horizontal header logo
|
||||
<LogoHorizontal height={32} />
|
||||
|
||||
// Custom sizing
|
||||
<LogoIcon size={128} className="drop-shadow-lg" />
|
||||
```
|
||||
|
||||
## File Locations
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `apps/web/src/app/ui/LogoIcon.tsx` | React icon component |
|
||||
| `apps/web/src/app/ui/LogoHorizontal.tsx` | React horizontal logo |
|
||||
| `apps/web/src/app/icon.svg` | Web favicon (auto-generated by Next.js) |
|
||||
| `apps/web/src/app/opengraph-image.svg` | Social sharing image |
|
||||
| `apps/mobile/assets/logo.svg` | Master SVG for mobile assets |
|
||||
@@ -0,0 +1,58 @@
|
||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
|
||||
<title id="title">TimeToLeave app icon</title>
|
||||
<desc id="desc">An icon-only TimeToLeave mark: a violet and magenta melting clock on a dark rounded-square background, flowing into a right arrow.</desc>
|
||||
<defs>
|
||||
<radialGradient id="iconBg" cx="50%" cy="36%" r="76%">
|
||||
<stop offset="0%" stop-color="#17112A"/>
|
||||
<stop offset="55%" stop-color="#090816"/>
|
||||
<stop offset="100%" stop-color="#03030A"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="iconMelt" x1="205" y1="170" x2="840" y2="745" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#8B5CF6"/>
|
||||
<stop offset="40%" stop-color="#B23CFF"/>
|
||||
<stop offset="72%" stop-color="#D946EF"/>
|
||||
<stop offset="100%" stop-color="#FF2D8D"/>
|
||||
</linearGradient>
|
||||
<filter id="iconGlow" x="-25%" y="-25%" width="150%" height="150%">
|
||||
<feGaussianBlur stdDeviation="9" result="blur"/>
|
||||
<feColorMatrix in="blur" type="matrix" values="0.72 0 0 0 0.26 0 0.18 0 0 0.92 0 0 0.34 0 1 0 0 0 0.35 0" result="glow"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="glow"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<style>
|
||||
.iconStroke { stroke: url(#iconMelt); stroke-width: 56; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.iconTick { stroke: #F4F1EA; stroke-width: 16; stroke-linecap: round; opacity: 0.96; }
|
||||
.iconHand { stroke: #F4F1EA; stroke-width: 22; stroke-linecap: round; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<rect width="1024" height="1024" rx="218" fill="url(#iconBg)"/>
|
||||
|
||||
<g filter="url(#iconGlow)">
|
||||
<!-- Simplified app-icon melting clock -->
|
||||
<path class="iconStroke" d="M266 544 C254 478 271 406 316 350 C372 280 456 246 543 256 C644 268 724 349 738 451 C744 495 737 535 731 559 C726 585 738 604 762 612 C790 621 793 582 815 578 C842 574 850 611 836 642 C826 664 811 674 790 671"/>
|
||||
<path class="iconStroke" d="M266 544 C251 589 263 628 303 632 C339 635 324 578 361 578 C397 578 385 653 430 653 C473 653 463 590 508 590 C551 590 548 671 602 698 C671 734 757 712 821 668"/>
|
||||
<path class="iconStroke" d="M430 653 C428 707 429 753 449 753 C470 753 469 708 474 662"/>
|
||||
<path class="iconStroke" d="M821 668 C855 643 890 626 928 615"/>
|
||||
<path d="M897 564 L1010 609 L916 687 L928 636 Z" fill="#FF2D8D"/>
|
||||
</g>
|
||||
|
||||
<!-- Minimal face details for small-size legibility -->
|
||||
<g>
|
||||
<line class="iconTick" x1="512" y1="326" x2="512" y2="354"/>
|
||||
<line class="iconTick" x1="640" y1="381" x2="663" y2="358"/>
|
||||
<line class="iconTick" x1="704" y1="514" x2="737" y2="514"/>
|
||||
<line class="iconTick" x1="512" y1="649" x2="512" y2="680"/>
|
||||
<line class="iconTick" x1="388" y1="640" x2="411" y2="617"/>
|
||||
<line class="iconTick" x1="318" y1="514" x2="351" y2="514"/>
|
||||
<line class="iconTick" x1="388" y1="388" x2="411" y2="411"/>
|
||||
</g>
|
||||
|
||||
<g>
|
||||
<line class="iconHand" x1="512" y1="514" x2="512" y2="394"/>
|
||||
<line class="iconHand" x1="512" y1="514" x2="631" y2="590"/>
|
||||
<circle cx="512" cy="514" r="29" fill="#F4F1EA"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 871 KiB |
|
After Width: | Height: | Size: 962 KiB |
@@ -0,0 +1,58 @@
|
||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
|
||||
<title id="title">TimeToLeave app icon</title>
|
||||
<desc id="desc">An icon-only TimeToLeave mark: a violet and magenta melting clock on a dark rounded-square background, flowing into a right arrow.</desc>
|
||||
<defs>
|
||||
<radialGradient id="iconBg" cx="50%" cy="36%" r="76%">
|
||||
<stop offset="0%" stop-color="#17112A"/>
|
||||
<stop offset="55%" stop-color="#090816"/>
|
||||
<stop offset="100%" stop-color="#03030A"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="iconMelt" x1="205" y1="170" x2="840" y2="745" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#8B5CF6"/>
|
||||
<stop offset="40%" stop-color="#B23CFF"/>
|
||||
<stop offset="72%" stop-color="#D946EF"/>
|
||||
<stop offset="100%" stop-color="#FF2D8D"/>
|
||||
</linearGradient>
|
||||
<filter id="iconGlow" x="-25%" y="-25%" width="150%" height="150%">
|
||||
<feGaussianBlur stdDeviation="9" result="blur"/>
|
||||
<feColorMatrix in="blur" type="matrix" values="0.72 0 0 0 0.26 0 0.18 0 0 0.92 0 0 0.34 0 1 0 0 0 0.35 0" result="glow"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="glow"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<style>
|
||||
.iconStroke { stroke: url(#iconMelt); stroke-width: 56; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.iconTick { stroke: #F4F1EA; stroke-width: 16; stroke-linecap: round; opacity: 0.96; }
|
||||
.iconHand { stroke: #F4F1EA; stroke-width: 22; stroke-linecap: round; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<rect width="1024" height="1024" rx="218" fill="url(#iconBg)"/>
|
||||
|
||||
<g filter="url(#iconGlow)">
|
||||
<!-- Simplified app-icon melting clock -->
|
||||
<path class="iconStroke" d="M266 544 C254 478 271 406 316 350 C372 280 456 246 543 256 C644 268 724 349 738 451 C744 495 737 535 731 559 C726 585 738 604 762 612 C790 621 793 582 815 578 C842 574 850 611 836 642 C826 664 811 674 790 671"/>
|
||||
<path class="iconStroke" d="M266 544 C251 589 263 628 303 632 C339 635 324 578 361 578 C397 578 385 653 430 653 C473 653 463 590 508 590 C551 590 548 671 602 698 C671 734 757 712 821 668"/>
|
||||
<path class="iconStroke" d="M430 653 C428 707 429 753 449 753 C470 753 469 708 474 662"/>
|
||||
<path class="iconStroke" d="M821 668 C855 643 890 626 928 615"/>
|
||||
<path d="M897 564 L1010 609 L916 687 L928 636 Z" fill="#FF2D8D"/>
|
||||
</g>
|
||||
|
||||
<!-- Minimal face details for small-size legibility -->
|
||||
<g>
|
||||
<line class="iconTick" x1="512" y1="326" x2="512" y2="354"/>
|
||||
<line class="iconTick" x1="640" y1="381" x2="663" y2="358"/>
|
||||
<line class="iconTick" x1="704" y1="514" x2="737" y2="514"/>
|
||||
<line class="iconTick" x1="512" y1="649" x2="512" y2="680"/>
|
||||
<line class="iconTick" x1="388" y1="640" x2="411" y2="617"/>
|
||||
<line class="iconTick" x1="318" y1="514" x2="351" y2="514"/>
|
||||
<line class="iconTick" x1="388" y1="388" x2="411" y2="411"/>
|
||||
</g>
|
||||
|
||||
<g>
|
||||
<line class="iconHand" x1="512" y1="514" x2="512" y2="394"/>
|
||||
<line class="iconHand" x1="512" y1="514" x2="631" y2="590"/>
|
||||
<circle cx="512" cy="514" r="29" fill="#F4F1EA"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -7,8 +7,13 @@ import Navbar from "@/app/layout/Navbar";
|
||||
import ReminderEngine from "@/app/layout/ReminderEngine";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "TimeToLeave",
|
||||
description: "Plan your train journeys and compare with bicycle routing",
|
||||
"TimeToLeave — Smart Departure Planner"
|
||||
description:
|
||||
"Plan your train journeys, sync with your calendar, and know exactly when to leave for your appointments.",
|
||||
icons: {
|
||||
icon: "/icon.svg",
|
||||
apple: "/icon.svg",
|
||||
},
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
@@ -7,6 +7,8 @@ import ReminderSettingsPanel from "@/app/ui/ReminderSettingsPanel";
|
||||
import { useServerHealth } from "@/hooks/useServerHealth";
|
||||
import { useEventsStore } from "@/hooks/useEventsStore";
|
||||
import { useTheme } from "@/hooks/useTheme";
|
||||
import Link from "next/link";
|
||||
import LogoHorizontal from "@/app/ui/LogoHorizontal";
|
||||
|
||||
type HeaderProps = {
|
||||
className?: string;
|
||||
@@ -24,9 +26,9 @@ const Header: React.FC<HeaderProps> = ({ className = "" }) => {
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
<div className="flex items-center">
|
||||
<h1 className="text-xl font-bold text-gray-900 dark:text-white">
|
||||
<span className="text-blue-600">ÖBB</span> Planner
|
||||
</h1>
|
||||
<Link href="/">
|
||||
<LogoHorizontal height={32} />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="hidden md:flex items-center text-sm text-gray-600 dark:text-gray-300">
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" width="1200" height="630">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#007AFF" />
|
||||
<stop offset="100%" stop-color="#5856D6" />
|
||||
</linearGradient>
|
||||
<linearGradient id="arrowGrad" x1="0%" y1="100%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#FF9500" />
|
||||
<stop offset="100%" stop-color="#FFD60A" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="1200" height="630" fill="url(#bgGrad)" rx="24" />
|
||||
|
||||
<!-- Decorative clock circles -->
|
||||
<circle cx="200" cy="100" r="80" fill="rgba(255,255,255,0.05)" />
|
||||
<circle cx="1050" cy="550" r="120" fill="rgba(255,255,255,0.05)" />
|
||||
<circle cx="100" cy="500" r="60" fill="rgba(255,255,255,0.03)" />
|
||||
|
||||
<!-- Large icon -->
|
||||
<g transform="translate(180, 215) scale(1.3)">
|
||||
<circle cx="100" cy="100" r="80" fill="rgba(255,255,255,0.15)" />
|
||||
<g stroke="rgba(255,255,255,0.4)" stroke-width="3" stroke-linecap="round">
|
||||
<line x1="100" y1="25" x2="100" y2="32" />
|
||||
<line x1="100" y1="25" x2="100" y2="32" transform="rotate(60 100 100)" />
|
||||
<line x1="100" y1="25" x2="100" y2="32" transform="rotate(120 100 100)" />
|
||||
<line x1="100" y1="25" x2="100" y2="32" transform="rotate(180 100 100)" />
|
||||
<line x1="100" y1="25" x2="100" y2="32" transform="rotate(240 100 100)" />
|
||||
<line x1="100" y1="25" x2="100" y2="32" transform="rotate(300 100 100)" />
|
||||
</g>
|
||||
<line x1="100" y1="100" x2="65" y2="55" stroke="rgba(255,255,255,0.7)" stroke-width="4" stroke-linecap="round" />
|
||||
<g transform="translate(100,100) rotate(-45)">
|
||||
<line x1="0" y1="0" x2="0" y2="-45" stroke="url(#arrowGrad)" stroke-width="5" stroke-linecap="round" />
|
||||
<polygon points="-9,-38 0,-52 9,-38" fill="url(#arrowGrad)" />
|
||||
</g>
|
||||
<circle cx="100" cy="100" r="5" fill="white" />
|
||||
<circle cx="100" cy="100" r="2.5" fill="rgba(0,122,255,0.8)" />
|
||||
|
||||
{/* Fire-exit running person at date-window position */}
|
||||
<g transform="translate(100, 148) scale(0.35)">
|
||||
<rect x="14" y="-30" width="24" height="60" rx="3" fill="none" stroke="rgba(255,255,255,0.5)" stroke-width="5" />
|
||||
<g stroke="rgba(255,255,255,0.65)" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="-10" cy="-20" r="6" fill="rgba(255,255,255,0.65)" stroke="none" />
|
||||
<line x1="-10" y1="-14" x2="-10" y2="2" />
|
||||
<line x1="-10" y1="-9" x2="-20" y2="-15" />
|
||||
<line x1="-10" y1="-9" x2="-2" y2="-3" />
|
||||
<line x1="-10" y1="2" x2="-22" y2="14" />
|
||||
<line x1="-10" y1="2" x2="-2" y2="12" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="440" y="300" fill="white" font-size="80" font-weight="800" font-family="system-ui, -apple-system, sans-serif" letter-spacing="-2">
|
||||
Time
|
||||
</text>
|
||||
<text x="660" y="300" fill="#FFD60A" font-size="80" font-weight="800" font-family="system-ui, -apple-system, sans-serif" letter-spacing="-2">
|
||||
To
|
||||
</text>
|
||||
<text x="780" y="300" fill="white" font-size="80" font-weight="800" font-family="system-ui, -apple-system, sans-serif" letter-spacing="-2">
|
||||
Leave
|
||||
</text>
|
||||
|
||||
<!-- Subtitle -->
|
||||
<text x="440" y="380" fill="rgba(255,255,255,0.8)" font-size="32" font-weight="400" font-family="system-ui, -apple-system, sans-serif">
|
||||
Smart Departure Planner
|
||||
</text>
|
||||
|
||||
<!-- Tagline -->
|
||||
<text x="440" y="440" fill="rgba(255,255,255,0.5)" font-size="22" font-weight="300" font-family="system-ui, -apple-system, sans-serif">
|
||||
Never miss your train again. ⏱️ 🚆 🚲
|
||||
</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,58 @@
|
||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
|
||||
<title id="title">TimeToLeave app icon</title>
|
||||
<desc id="desc">An icon-only TimeToLeave mark: a violet and magenta melting clock on a dark rounded-square background, flowing into a right arrow.</desc>
|
||||
<defs>
|
||||
<radialGradient id="iconBg" cx="50%" cy="36%" r="76%">
|
||||
<stop offset="0%" stop-color="#17112A"/>
|
||||
<stop offset="55%" stop-color="#090816"/>
|
||||
<stop offset="100%" stop-color="#03030A"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="iconMelt" x1="205" y1="170" x2="840" y2="745" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#8B5CF6"/>
|
||||
<stop offset="40%" stop-color="#B23CFF"/>
|
||||
<stop offset="72%" stop-color="#D946EF"/>
|
||||
<stop offset="100%" stop-color="#FF2D8D"/>
|
||||
</linearGradient>
|
||||
<filter id="iconGlow" x="-25%" y="-25%" width="150%" height="150%">
|
||||
<feGaussianBlur stdDeviation="9" result="blur"/>
|
||||
<feColorMatrix in="blur" type="matrix" values="0.72 0 0 0 0.26 0 0.18 0 0 0.92 0 0 0.34 0 1 0 0 0 0.35 0" result="glow"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="glow"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<style>
|
||||
.iconStroke { stroke: url(#iconMelt); stroke-width: 56; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.iconTick { stroke: #F4F1EA; stroke-width: 16; stroke-linecap: round; opacity: 0.96; }
|
||||
.iconHand { stroke: #F4F1EA; stroke-width: 22; stroke-linecap: round; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<rect width="1024" height="1024" rx="218" fill="url(#iconBg)"/>
|
||||
|
||||
<g filter="url(#iconGlow)">
|
||||
<!-- Simplified app-icon melting clock -->
|
||||
<path class="iconStroke" d="M266 544 C254 478 271 406 316 350 C372 280 456 246 543 256 C644 268 724 349 738 451 C744 495 737 535 731 559 C726 585 738 604 762 612 C790 621 793 582 815 578 C842 574 850 611 836 642 C826 664 811 674 790 671"/>
|
||||
<path class="iconStroke" d="M266 544 C251 589 263 628 303 632 C339 635 324 578 361 578 C397 578 385 653 430 653 C473 653 463 590 508 590 C551 590 548 671 602 698 C671 734 757 712 821 668"/>
|
||||
<path class="iconStroke" d="M430 653 C428 707 429 753 449 753 C470 753 469 708 474 662"/>
|
||||
<path class="iconStroke" d="M821 668 C855 643 890 626 928 615"/>
|
||||
<path d="M897 564 L1010 609 L916 687 L928 636 Z" fill="#FF2D8D"/>
|
||||
</g>
|
||||
|
||||
<!-- Minimal face details for small-size legibility -->
|
||||
<g>
|
||||
<line class="iconTick" x1="512" y1="326" x2="512" y2="354"/>
|
||||
<line class="iconTick" x1="640" y1="381" x2="663" y2="358"/>
|
||||
<line class="iconTick" x1="704" y1="514" x2="737" y2="514"/>
|
||||
<line class="iconTick" x1="512" y1="649" x2="512" y2="680"/>
|
||||
<line class="iconTick" x1="388" y1="640" x2="411" y2="617"/>
|
||||
<line class="iconTick" x1="318" y1="514" x2="351" y2="514"/>
|
||||
<line class="iconTick" x1="388" y1="388" x2="411" y2="411"/>
|
||||
</g>
|
||||
|
||||
<g>
|
||||
<line class="iconHand" x1="512" y1="514" x2="512" y2="394"/>
|
||||
<line class="iconHand" x1="512" y1="514" x2="631" y2="590"/>
|
||||
<circle cx="512" cy="514" r="29" fill="#F4F1EA"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,69 @@
|
||||
<svg width="1200" height="1200" viewBox="0 0 1200 1200" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
|
||||
<title id="title">TimeToLeave dark melting clock logo</title>
|
||||
<desc id="desc">A dark-background TimeToLeave logo with a violet and magenta melting clock flowing into an arrow, plus a wordmark.</desc>
|
||||
<defs>
|
||||
<radialGradient id="bgGlow" cx="50%" cy="38%" r="70%">
|
||||
<stop offset="0%" stop-color="#17112A"/>
|
||||
<stop offset="58%" stop-color="#090816"/>
|
||||
<stop offset="100%" stop-color="#03030A"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="meltGradient" x1="280" y1="210" x2="900" y2="720" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#8B5CF6"/>
|
||||
<stop offset="42%" stop-color="#B23CFF"/>
|
||||
<stop offset="72%" stop-color="#D946EF"/>
|
||||
<stop offset="100%" stop-color="#FF2D8D"/>
|
||||
</linearGradient>
|
||||
<filter id="softGlow" x="-30%" y="-30%" width="160%" height="160%">
|
||||
<feGaussianBlur stdDeviation="8" result="blur"/>
|
||||
<feColorMatrix in="blur" type="matrix" values="0.72 0 0 0 0.26 0 0.18 0 0 0.92 0 0 0.34 0 1 0 0 0 0.35 0" result="glow"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="glow"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<style>
|
||||
.clockStroke { stroke: url(#meltGradient); stroke-width: 42; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.faceMark { stroke: #F4F1EA; stroke-width: 15; stroke-linecap: round; opacity: 0.96; }
|
||||
.hand { stroke: #F4F1EA; stroke-width: 19; stroke-linecap: round; }
|
||||
.word { font-family: Inter, Poppins, Montserrat, Avenir Next, Arial, sans-serif; font-weight: 700; font-size: 116px; letter-spacing: -4px; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<rect width="1200" height="1200" fill="url(#bgGlow)"/>
|
||||
|
||||
<g filter="url(#softGlow)">
|
||||
<!-- Melting clock outline and flowing departure arrow -->
|
||||
<path class="clockStroke" d="M334 552 C324 498 335 437 370 388 C415 324 486 290 562 293 C660 297 744 372 758 471 C763 508 758 541 753 565 C748 589 756 610 779 622 C808 637 810 594 832 590 C855 586 860 620 851 644 C842 669 824 682 803 678"/>
|
||||
<path class="clockStroke" d="M334 552 C322 588 331 622 365 628 C395 633 386 581 415 580 C447 579 441 641 475 641 C510 641 506 585 544 585 C579 585 571 651 604 670 C650 697 733 695 797 657"/>
|
||||
<path class="clockStroke" d="M475 641 C472 690 474 724 489 724 C506 724 506 690 509 651"/>
|
||||
<path class="clockStroke" d="M797 657 C830 639 862 624 898 615"/>
|
||||
<path d="M882 572 L1010 620 L904 708 L917 650 Z" fill="#FF2D8D"/>
|
||||
<ellipse cx="505" cy="725" rx="17" ry="26" fill="#B23CFF"/>
|
||||
</g>
|
||||
|
||||
<!-- Clock ticks -->
|
||||
<g>
|
||||
<line class="faceMark" x1="556" y1="334" x2="556" y2="360"/>
|
||||
<line class="faceMark" x1="694" y1="391" x2="716" y2="378"/>
|
||||
<line class="faceMark" x1="733" y1="526" x2="762" y2="526"/>
|
||||
<line class="faceMark" x1="556" y1="670" x2="556" y2="698"/>
|
||||
<line class="faceMark" x1="405" y1="655" x2="425" y2="633"/>
|
||||
<line class="faceMark" x1="362" y1="526" x2="390" y2="526"/>
|
||||
<line class="faceMark" x1="405" y1="398" x2="425" y2="420"/>
|
||||
<line class="faceMark" x1="658" y1="420" x2="671" y2="398"/>
|
||||
</g>
|
||||
|
||||
<!-- Clock hands -->
|
||||
<g>
|
||||
<line class="hand" x1="556" y1="526" x2="556" y2="405"/>
|
||||
<line class="hand" x1="556" y1="526" x2="665" y2="590"/>
|
||||
<circle cx="556" cy="526" r="25" fill="#F4F1EA"/>
|
||||
</g>
|
||||
|
||||
<!-- Wordmark -->
|
||||
<g aria-label="TimeToLeave">
|
||||
<text class="word" x="163" y="912" fill="#F4F1EA">Time</text>
|
||||
<text class="word" x="502" y="912" fill="#FF2D8D">To</text>
|
||||
<text class="word" x="654" y="912" fill="#F4F1EA">Leave</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,111 @@
|
||||
export default function LogoHorizontal({
|
||||
height = 40,
|
||||
className = "",
|
||||
}: {
|
||||
height?: number;
|
||||
className?: string;
|
||||
}) {
|
||||
const width = height * 4.5;
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox={`0 0 ${width} ${height}`}
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
aria-label="TimeToLeave"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="ttt-h-bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#007AFF" />
|
||||
<stop offset="100%" stopColor="#5856D6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="ttt-h-arrowGrad"
|
||||
x1="0%"
|
||||
y1="100%"
|
||||
x2="100%"
|
||||
y2="0%"
|
||||
>
|
||||
<stop offset="0%" stopColor="#FF9500" />
|
||||
<stop offset="100%" stopColor="#FFD60A" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
{/* Icon on the left */}
|
||||
<g transform={`scale(${height / 48}) translate(0, ${height * 0.1})`}>
|
||||
<circle cx={24} cy={24} r={20} fill="url(#ttt-h-bgGrad)" />
|
||||
<g
|
||||
stroke="rgba(255,255,255,0.3)"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
>
|
||||
{[0, 60, 120, 180, 240, 300].map((angle, i) => (
|
||||
<line
|
||||
key={angle}
|
||||
x1={24}
|
||||
y1={7}
|
||||
x2={24}
|
||||
y2={9}
|
||||
transform={`rotate(${angle} 24 24)`}
|
||||
/>
|
||||
))}
|
||||
</g>
|
||||
<g transform="translate(24,24) rotate(-45)">
|
||||
<line
|
||||
x1={0}
|
||||
y1={0}
|
||||
x2={0}
|
||||
y2={-10}
|
||||
stroke="url(#ttt-h-arrowGrad)"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
<polygon
|
||||
points="-4,-8 0,-12 4,-8"
|
||||
fill="url(#ttt-h-arrowGrad)"
|
||||
/>
|
||||
</g>
|
||||
<circle cx={24} cy={24} r={2} fill="white" />
|
||||
</g>
|
||||
|
||||
{/* Text on the right */}
|
||||
<text
|
||||
x={height * 0.75}
|
||||
y={height * 0.65}
|
||||
fill="currentColor"
|
||||
className="dark:fill-white"
|
||||
fontSize={height * 0.6}
|
||||
fontWeight="700"
|
||||
fontFamily="system-ui, -apple-system, sans-serif"
|
||||
letterSpacing="-0.02em"
|
||||
>
|
||||
Time
|
||||
</text>
|
||||
<text
|
||||
x={height * 0.75 + height * 1.15}
|
||||
y={height * 0.65}
|
||||
fill="#007AFF"
|
||||
className="dark:fill-[#5AC8FA]"
|
||||
fontSize={height * 0.6}
|
||||
fontWeight="700"
|
||||
fontFamily="system-ui, -apple-system, sans-serif"
|
||||
letterSpacing="-0.02em"
|
||||
>
|
||||
To
|
||||
</text>
|
||||
<text
|
||||
x={height * 0.75 + height * 1.75}
|
||||
y={height * 0.65}
|
||||
fill="currentColor"
|
||||
className="dark:fill-white"
|
||||
fontSize={height * 0.6}
|
||||
fontWeight="700"
|
||||
fontFamily="system-ui, -apple-system, sans-serif"
|
||||
letterSpacing="-0.02em"
|
||||
>
|
||||
Leave
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
export default function LogoIcon({
|
||||
size = 48,
|
||||
className = "",
|
||||
}: {
|
||||
size?: number;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
width={size}
|
||||
height={size}
|
||||
className={className}
|
||||
aria-label="TimeToLeave logo"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="ttt-bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#007AFF" />
|
||||
<stop offset="100%" stopColor="#5856D6" />
|
||||
</linearGradient>
|
||||
<linearGradient id="ttt-arrowGrad" x1="0%" y1="100%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor="#FF9500" />
|
||||
<stop offset="100%" stopColor="#FFD60A" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<circle cx="256" cy="256" r="240" fill="url(#ttt-bgGrad)" />
|
||||
|
||||
<g stroke="rgba(255,255,255,0.3)" strokeWidth="8" strokeLinecap="round">
|
||||
{[0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330].map(
|
||||
(angle, i) => (
|
||||
<line
|
||||
key={angle}
|
||||
x1={256}
|
||||
y1={40}
|
||||
x2={256}
|
||||
y2={i % 3 === 0 ? 60 : 52}
|
||||
transform={`rotate(${angle} 256 256)`}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</g>
|
||||
|
||||
<line
|
||||
x1={256}
|
||||
y1={256}
|
||||
x2={168}
|
||||
y2={140}
|
||||
stroke="rgba(255,255,255,0.6)"
|
||||
strokeWidth={10}
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
|
||||
<g transform="translate(256,256) rotate(-45)">
|
||||
<line
|
||||
x1={0}
|
||||
y1={0}
|
||||
x2={0}
|
||||
y2={-120}
|
||||
stroke="url(#ttt-arrowGrad)"
|
||||
strokeWidth={14}
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
<polygon points="-22,-100 0,-145 22,-100" fill="url(#ttt-arrowGrad)" />
|
||||
</g>
|
||||
|
||||
<circle cx={256} cy={256} r={12} fill="white" />
|
||||
<circle cx={256} cy={256} r={6} fill="url(#ttt-bgGrad)" />
|
||||
|
||||
{/* Fire-exit: running person through open door */}
|
||||
<g transform="translate(256, 395) scale(0.7)">
|
||||
<rect
|
||||
x={14}
|
||||
y={-30}
|
||||
width={24}
|
||||
height={60}
|
||||
rx={3}
|
||||
fill="none"
|
||||
stroke="rgba(255,255,255,0.65)"
|
||||
strokeWidth={3.5}
|
||||
/>
|
||||
<rect
|
||||
x={30}
|
||||
y={-27}
|
||||
width={10}
|
||||
height={54}
|
||||
rx={2}
|
||||
fill="none"
|
||||
stroke="rgba(255,255,255,0.35)"
|
||||
strokeWidth={2.5}
|
||||
/>
|
||||
<line
|
||||
x1={30}
|
||||
y1={-27}
|
||||
x2={30}
|
||||
y2={27}
|
||||
stroke="rgba(255,255,255,0.35)"
|
||||
strokeWidth={2.5}
|
||||
/>
|
||||
<g
|
||||
stroke="rgba(255,255,255,0.85)"
|
||||
strokeWidth={3}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<circle
|
||||
cx={-10}
|
||||
cy={-20}
|
||||
r={6}
|
||||
fill="rgba(255,255,255,0.85)"
|
||||
stroke="none"
|
||||
/>
|
||||
<line x1={-10} y1={-14} x2={-10} y2={2} />
|
||||
<line x1={-10} y1={-9} x2={-20} y2={-15} />
|
||||
<line x1={-10} y1={-9} x2={-2} y2={-3} />
|
||||
<line x1={-10} y1={2} x2={-22} y2={14} />
|
||||
<line x1={-10} y1={2} x2={-2} y2={12} />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as LogoIcon } from "./LogoIcon";
|
||||
export { default as LogoHorizontal } from "./LogoHorizontal";
|
||||