Apply Emil Kowalski design across all screens

Near-monochrome palette (ink tokens), black primary buttons, spring
animations, 0.5pt hairline dividers, shadow cards, squircle corners.
Replaces all blue/coloured accents. Adds ButtonStyles component.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Robin Kutesa
2026-05-16 00:43:31 +03:00
parent 848c1da820
commit 04e7a77c1a
14 changed files with 889 additions and 625 deletions

View File

@@ -12,10 +12,6 @@ struct BrowseView: View {
@State private var showCreateFolder = false
@State private var newFolderName = ""
private var service: any NASTransferProtocol {
connection.nasProtocol == .smb ? SMBService() : SFTPService()
}
var body: some View {
NavigationStack {
ZStack {
@@ -23,36 +19,39 @@ struct BrowseView: View {
VStack(spacing: 0) {
// Path bar
HStack {
Image(systemName: "externaldrive.fill")
.foregroundColor(AppTheme.textSecondary)
.font(.system(size: 13))
HStack(spacing: 8) {
Image(systemName: "externaldrive")
.font(.system(size: 12, weight: .medium))
.foregroundStyle(AppTheme.inkTertiary)
Text(currentPath)
.font(AppTheme.captionFont)
.foregroundColor(AppTheme.textSecondary)
.font(AppTheme.caption())
.foregroundStyle(AppTheme.inkSecondary)
.lineLimit(1)
.truncationMode(.middle)
Spacer()
}
.padding(.horizontal, 16)
.padding(.horizontal, AppTheme.cardPad)
.padding(.vertical, 10)
.background(Color(hex: "#F9FAFB"))
.background(AppTheme.surfaceSunken)
Divider()
Rectangle()
.fill(AppTheme.separator)
.frame(height: 0.5)
if isLoading {
Spacer()
ProgressView()
.tint(AppTheme.inkTertiary)
Spacer()
} else if let error {
Spacer()
VStack(spacing: 12) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 32))
.foregroundColor(AppTheme.textTertiary)
.font(.system(size: 28, weight: .light))
.foregroundStyle(AppTheme.inkQuaternary)
Text(error)
.font(AppTheme.bodyFont)
.foregroundColor(AppTheme.textSecondary)
.font(AppTheme.caption())
.foregroundStyle(AppTheme.inkSecondary)
.multilineTextAlignment(.center)
}
.padding()
@@ -61,14 +60,22 @@ struct BrowseView: View {
List {
if currentPath != "/" {
Button(action: navigateUp) {
HStack {
HStack(spacing: 10) {
Image(systemName: "arrow.up")
.foregroundColor(AppTheme.textSecondary)
.font(.system(size: 13, weight: .medium))
.foregroundStyle(AppTheme.inkSecondary)
.frame(width: 22)
Text("Parent folder")
.font(AppTheme.bodyFont)
.foregroundColor(AppTheme.textSecondary)
.font(AppTheme.body())
.foregroundStyle(AppTheme.inkSecondary)
Spacer()
}
.padding(.horizontal, 16)
.padding(.vertical, 12)
}
.buttonStyle(PlainButtonStyle())
.listRowInsets(EdgeInsets())
.listRowSeparator(.hidden)
}
ForEach(items) { item in
@@ -83,7 +90,7 @@ struct BrowseView: View {
}
}
.listRowInsets(EdgeInsets())
.listRowSeparator(.visible)
.listRowSeparator(.hidden)
}
}
.listStyle(.plain)
@@ -95,6 +102,8 @@ struct BrowseView: View {
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel") { dismiss() }
.font(AppTheme.body())
.foregroundStyle(AppTheme.inkSecondary)
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
@@ -102,6 +111,7 @@ struct BrowseView: View {
showCreateFolder = true
} label: {
Image(systemName: "folder.badge.plus")
.foregroundStyle(AppTheme.inkSecondary)
}
}
ToolbarItem(placement: .bottomBar) {
@@ -109,8 +119,8 @@ struct BrowseView: View {
selectedPath = currentPath
dismiss()
}
.font(.system(size: 17, weight: .semibold))
.foregroundColor(AppTheme.blue)
.font(.system(size: 15, weight: .semibold))
.foregroundStyle(AppTheme.ink)
}
}
.alert("New folder", isPresented: $showCreateFolder) {