import React from 'react'; import type { IsoBoxProps, MountainClusterProps, PineTreeProps, IsoPencilProps, IsoMonitorProps, IsoTowerProps, IsoSignpostProps, } from './IsoTypes'; /** * Single isometric box: top diamond + two shaded side faces. * (x, y) is the TOP vertex of the diamond. s = half-width, h = height. */ export function IsoBox({ x, y, s, h, top, left, right, stroke = 'none' }: IsoBoxProps) { const topPts = `${x},${y} ${x + s},${y + s / 2} ${x},${y + s} ${x - s},${y + s / 2}`; const leftPts = `${x - s},${y + s / 2} ${x},${y + s} ${x},${y + s + h} ${x - s},${y + s / 2 + h}`; const rightPts = `${x + s},${y + s / 2} ${x},${y + s} ${x},${y + s + h} ${x + s},${y + s / 2 + h}`; return ( ); } /** * Mountain Cluster * Four stacked isometric boxes forming the mountain peak and foothills */ export function MountainCluster({ x, y, flip = false, scale = 1 }: MountainClusterProps) { const f = flip ? -1 : 1; const boxes = [ { dx: 15 * f, dy: -45, s: 95, h: 130 }, { dx: -60 * f, dy: 52, s: 58, h: 70 }, { dx: 85 * f, dy: 65, s: 55, h: 60 }, { dx: 0, dy: 98, s: 46, h: 46 }, ]; return ( {boxes.map((b, i) => ( ))} ); } /** * Pine tree * Features signature smooth teardrop/conical foliage and rounded capsule trunk */ export function PineTree({ x, y, scale = 1, dark = false }: PineTreeProps) { const foliageColor = dark ? 'var(--hero-illus-tree-dark, #104179)' : 'var(--hero-illus-tree-light, #2166A9)'; const trunkColor = 'var(--hero-illus-tree-trunk, #08234B)'; return ( {/* Capsule Trunk */} {/* Foliage */} ); } /** * Modern SVG Icons for Top Contact Bar and Signposts */ export const PhoneIcon: React.FC<{ size?: number; color?: string }> = ({ size = 20, color = 'currentColor', }) => ( ); export const LinkedInIcon: React.FC<{ size?: number; color?: string }> = ({ size = 20, color = 'currentColor', }) => ( ); export const GitHubIcon: React.FC<{ size?: number; color?: string }> = ({ size = 20, color = 'currentColor', }) => ( ); export const TelegramIcon: React.FC<{ size?: number; color?: string }> = ({ size = 20, color = 'currentColor', }) => ( ); export const MailIcon: React.FC<{ size?: number; color?: string }> = ({ size = 18, color = 'currentColor', }) => ( ); /** * Upright Majestic Faceted Pencil matching reference * Blue faceted hexagonal shaft, cool white wood collar, and royal blue conical tip. */ export function IsoUprightPencil({ x, y, height = 84, width = 18 }: IsoPencilProps) { const hw = width / 2; const bodyH = height - 26; const collarH = 14; const tipH = 12; const baseY = y; const collarBaseY = baseY - bodyH; const tipBaseY = collarBaseY - collarH; const tipY = tipBaseY - tipH; const p1 = `${x - hw},${baseY - 2} ${x - hw * 0.25},${baseY + 1} ${x - hw * 0.25},${collarBaseY} ${x - hw},${collarBaseY - 2}`; const p2 = `${x - hw * 0.25},${baseY + 1} ${x + hw * 0.25},${baseY + 1} ${x + hw * 0.25},${collarBaseY} ${x - hw * 0.25},${collarBaseY}`; const p3 = `${x + hw * 0.25},${baseY + 1} ${x + hw},${baseY - 2} ${x + hw},${collarBaseY - 2} ${x + hw * 0.25},${collarBaseY}`; const woodLeft = `${x - hw},${collarBaseY - 2} ${x - hw * 0.25},${collarBaseY} ${x},${tipBaseY}`; const woodMid = `${x - hw * 0.25},${collarBaseY} ${x + hw * 0.25},${collarBaseY} ${x},${tipBaseY}`; const woodRight = `${x + hw * 0.25},${collarBaseY} ${x + hw},${collarBaseY - 2} ${x},${tipBaseY}`; const leadLeft = `${x - hw * 0.32},${tipBaseY} ${x},${tipBaseY} ${x},${tipY}`; const leadRight = `${x},${tipBaseY} ${x + hw * 0.32},${tipBaseY} ${x},${tipY}`; return ( {/* Ground Contact Shadow */} {/* Shaft Facets (Light / Front / Dark matching 3D isometric lighting) */} {/* Scalloped Wood Facets */} {/* Lead Tip */} ); } /** * Isometric Workstation Monitor matching reference * Sizable flat panel screen angled in 3D, standing proudly on Tile 1 */ export function IsoMonitorDisplay({ x, y, scale = 1 }: IsoMonitorProps) { const baseW = 20; const baseH = 10; // Stand Base diamond const sbFront = `${x},${y + baseH / 2}`; const sbLeft = `${x - baseW / 2},${y}`; const sbRight = `${x + baseW / 2},${y}`; const sbBack = `${x},${y - baseH / 2}`; const sbTop = `${sbBack} ${sbRight} ${sbFront} ${sbLeft}`; const sbLeftDrop = `${sbLeft} ${sbFront} ${x},${y + baseH / 2 + 2} ${x - baseW / 2},${y + 2}`; const sbRightDrop = `${sbFront} ${sbRight} ${x + baseW / 2},${y + 2} ${x},${y + baseH / 2 + 2}`; // Monitor Display Panel (sleek, well-proportioned, clear of pencil) const panCx = x; const panCy = y - 24; const hw = 21; const hh = 15; const slopeDy = 10.5; // 21 * 0.5 = 10.5 const depth = 3.5; // Stand Neck column (extends from base plate up solidly behind the opaque screen panel) const neckTop = panCy + 4; const neckFront = `${x - 2},${neckTop} ${x + 2},${neckTop + 2} ${x + 2},${y} ${x - 2},${y - 2}`; const neckSide = `${x + 2},${neckTop + 2} ${x + 4},${neckTop + 1} ${x + 4},${y - 1} ${x + 2},${y}`; const fTopLeft = `${panCx - hw},${panCy - hh - slopeDy}`; const fTopRight = `${panCx + hw},${panCy - hh + slopeDy}`; const fBottomRight = `${panCx + hw},${panCy + hh + slopeDy}`; const fBottomLeft = `${panCx - hw},${panCy + hh - slopeDy}`; const pFront = `${fTopLeft} ${fTopRight} ${fBottomRight} ${fBottomLeft}`; const bTopLeft = `${panCx - hw + depth},${panCy - hh - slopeDy - depth * 0.5}`; const bTopRight = `${panCx + hw + depth},${panCy - hh + slopeDy - depth * 0.5}`; const pTop = `${fTopLeft} ${bTopLeft} ${bTopRight} ${fTopRight}`; const bBottomRight = `${panCx + hw + depth},${panCy + hh + slopeDy - depth * 0.5}`; const pRight = `${fTopRight} ${bTopRight} ${bBottomRight} ${fBottomRight}`; return ( {/* Ground Contact Shadow */} {/* Stand Base Drop Faces */} {/* Stand Neck Column */} {/* Monitor Display Bezel & Screen Face */} ); } /** * Isometric PC Tower Unit matching reference * Vertical rectangular prism sitting on a clean white pedestal plate */ export function IsoPCTower({ x, y, size = 20, height = 40 }: IsoTowerProps) { const hs = size / 2; const plateW = size + 10; const plateH = (size + 10) * 0.5; // Base Pedestal Plate const plFront = `${x},${y + plateH / 2}`; const plLeft = `${x - plateW / 2},${y}`; const plRight = `${x + plateW / 2},${y}`; const plBack = `${x},${y - plateH / 2}`; const plTop = `${plBack} ${plRight} ${plFront} ${plLeft}`; const plLeftDrop = `${plLeft} ${plFront} ${x},${y + plateH / 2 + 2.5} ${x - plateW / 2},${y + 2.5}`; const plRightDrop = `${plFront} ${plRight} ${x + plateW / 2},${y + 2.5} ${x},${y + plateH / 2 + 2.5}`; // Cube Base corners const baseY = y - 1; const cFront = `${x},${baseY + hs * 0.5}`; const cLeft = `${x - hs},${baseY}`; const cRight = `${x + hs},${baseY}`; const cBack = `${x},${baseY - hs * 0.5}`; // Cube Top corners const topY = baseY - height; const tFront = `${x},${topY + hs * 0.5}`; const tLeft = `${x - hs},${topY}`; const tRight = `${x + hs},${topY}`; const tBack = `${x},${topY - hs * 0.5}`; const faceTop = `${tBack} ${tRight} ${tFront} ${tLeft}`; const faceLeft = `${cLeft} ${cFront} ${tFront} ${tLeft}`; const faceRight = `${cFront} ${cRight} ${tRight} ${tFront}`; return ( {/* Pedestal Plate */} {/* Main Vertical Tower Body */} ); } /** * Isometric Signpost * True 3D item with elevated 3D cylindrical base plate and shaded 3D cylindrical metallic pole */ export function IsoSignpost({ id: _id, x, y, postHeight = 48, facing = 'right', backdropDirection, icon, label: _label, isActive = false, onMouseEnter, onMouseLeave, onClick, }: IsoSignpostProps) { const isRight = facing === 'right'; const postTopY = y - postHeight; const cardSize = 32; const radius = 6; // 3D Isometric Shear Matrix: // facing="right" (SE): slope +0.5 -> matrix(1, 0.5, 0, 1, 0, 0) // facing="left" (SW): slope -0.5 -> matrix(1, -0.5, 0, 1, 0, 0) const shearSlope = isRight ? 0.5 : -0.5; const gradId = `standPoleGrad-${_id}`; // Directional Backdrop Offset: // Rightside items (GitHub, Telegram): 'left-top' (backShiftX = -3.5, backShiftY = -3.2) // Leftside items (Phone, LinkedIn): 'right-top' (backShiftX = +3.5, backShiftY = -3.2) const dir = backdropDirection ?? (isRight ? 'right-top' : 'left-top'); const isRightTop = dir === 'right-top'; const backShiftX = isRightTop ? 3.5 : -3.5; const backShiftY = -3.2; return ( {/* 3D Cylindrical Metallic Gradient for Upright Pole */} {/* Expanded invisible touch hit box */} {/* 3D Ground Base Assembly */} {/* 1. 3D Cylindrical Disc Drop Apron (Thickness = 4px) */} {/* Center ridge divider on the cylinder drop */} {/* 3. 3D Disc Top Surface */} {/* 4. Concentric Socket Collar / Ring where pole enters */} {/* 3D Cylindrical Metallic Pole (extends seamlessly up behind the card body) */} {/* Left-edge specular highlight glint line */} {/* 3D Rotated Isometric Signboard */} {/* 1. Backdrop Layer (Positioned to left-top for rightside items, right-top for leftside items) */} {/* Subtle Ambient Shadow behind the backdrop plate */} {/* 3D Backdrop Plate with signature royal blue fill and darker border */} {/* 2. Front Card Layer (Centered flush on the pole axis at x, postTopY - 18) */} {/* Crisp Opaque Card Body with Blue Border */} {/* 3D Rotated Icon inside Card */} {icon} ); }