// // AgentZGlyph.swift // Zyquo Agent // // Author: Simon-Pierre Boucher // Mail: contact@spboucher.ai // // The in-app Agent brand glyph (wordmark + empty state): the family // Z-monogram whose lower stroke resolves into a command-prompt caret — // "the Z that acts". Drawn as vector paths on a normalized grid so it scales // from the 22pt wordmark to the 88pt hero without redesign. The full app // icon (Phase 5) shares this creative direction. // import SwiftUI /// Normalized 100×100 design grid for the glyph paths. private enum AgentGlyphGrid { static let unit: CGFloat = 100 } /// The Z stroke: top bar → diagonal → shortened bottom bar (making room for /// the caret block that follows it). private struct AgentZStroke: Shape { func path(in rect: CGRect) -> Path { let scale = min(rect.width, rect.height) / AgentGlyphGrid.unit func point(_ x: CGFloat, _ y: CGFloat) -> CGPoint { CGPoint(x: rect.minX + x * scale, y: rect.minY + y * scale) } var path = Path() path.move(to: point(18, 22)) path.addLine(to: point(82, 22)) path.addLine(to: point(22, 78)) path.addLine(to: point(58, 78)) return path } } /// The command caret `›` finishing the Z's lower stroke. private struct AgentCaretStroke: Shape { func path(in rect: CGRect) -> Path { let scale = min(rect.width, rect.height) / AgentGlyphGrid.unit func point(_ x: CGFloat, _ y: CGFloat) -> CGPoint { CGPoint(x: rect.minX + x * scale, y: rect.minY + y * scale) } var path = Path() path.move(to: point(70, 64)) path.addLine(to: point(84, 78)) path.addLine(to: point(70, 92)) return path } } /// The Zyquo Agent glyph: violet Z monogram with a command caret. struct AgentZGlyph: View { /// Rendered width and height (the glyph is square). var size: CGFloat var tint: Color = ZyquoColor.accent private var lineWidth: CGFloat { size * 14 / AgentGlyphGrid.unit } var body: some View { ZStack { AgentZStroke() .stroke( tint, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round, lineJoin: .round) ) AgentCaretStroke() .stroke( tint.opacity(0.55), style: StrokeStyle(lineWidth: lineWidth, lineCap: .round, lineJoin: .round) ) } .frame(width: size, height: size) .accessibilityHidden(true) } }