CasinoGames/SETTINGS_STYLING_GUIDE.md

28 KiB

Settings View Styling Guide

A comprehensive guide to achieving the polished casino-style settings interface with golden accents, proper section separation, and consistent styling.

Table of Contents

  1. Overview
  2. The Complete Stack
  3. Step 1: Set Up Design Constants
  4. Step 2: Use SheetContainerView
  5. Step 3: Structure with SheetSection
  6. Step 4: Use Proper Settings Components
  7. Step 5: Apply Consistent Colors
  8. Complete Example
  9. Color Reference
  10. Troubleshooting

Overview

The polished casino settings interface you see in Blackjack and Baccarat is achieved through a combination of:

  1. SheetContainerView - Dark background, proper navigation bar styling
  2. SheetSection - Icon + title headers with card-like content containers
  3. CasinoKit components - Pre-styled toggles, pickers, and selectable rows
  4. Color.Sheet constants - Consistent golden accent and background colors
  5. Design constants - Standardized spacing, corner radius, and opacity values

Key Styling Elements

  • Golden accent color: Color.Sheet.accent = Color(red: 0.9, green: 0.75, blue: 0.3)
  • Dark blue background: Color.Sheet.background = Color(red: 0.08, green: 0.12, blue: 0.18)
  • Section cards: White opacity fill with rounded corners
  • Radio buttons: Golden checkmark circles for selected items
  • Proper spacing: xxLarge (24pt) between sections

The Complete Stack

Required Components from CasinoKit

import CasinoKit

Views:

  • SheetContainerView - Outer container with navigation and dark background
  • SheetSection - Section container with icon/title header and card
  • SelectableRow - Radio button rows for pickers
  • SelectionIndicator - Golden checkmark circles
  • SettingsToggle - Toggle switches with titles and subtitles
  • SpeedPicker, VolumePicker, BalancePicker - Specialized pickers
  • BadgePill - Badge for displaying values like "$10 - $1,000"

Constants:

  • CasinoDesign - Spacing, corner radius, opacity, font sizes, etc.
  • Color.Sheet - Sheet-specific colors (background, accent, etc.)

Local Design Constants Setup

Create a DesignConstants.swift file in your app that imports and typealias CasinoKit constants:

import SwiftUI
import CasinoKit

enum Design {
    // Import shared constants via typealias
    typealias Spacing = CasinoDesign.Spacing
    typealias CornerRadius = CasinoDesign.CornerRadius
    typealias LineWidth = CasinoDesign.LineWidth
    typealias Shadow = CasinoDesign.Shadow
    typealias Opacity = CasinoDesign.Opacity
    typealias Animation = CasinoDesign.Animation
    typealias BaseFontSize = CasinoDesign.BaseFontSize
    typealias IconSize = CasinoDesign.IconSize
    
    // Your game-specific constants
    enum Size {
        static let cardWidth: CGFloat = 90
        // ... other game-specific sizes
    }
}

This allows you to write Design.Spacing.large instead of CasinoDesign.Spacing.large throughout your app.


Step 1: Set Up Design Constants

1.1 Create DesignConstants.swift

Create a file called DesignConstants.swift in your app's Theme/ folder:

//
//  DesignConstants.swift
//  YourGame
//

import SwiftUI
import CasinoKit

enum Design {
    // MARK: - Shared Constants (from CasinoKit)
    
    typealias Spacing = CasinoDesign.Spacing
    typealias CornerRadius = CasinoDesign.CornerRadius
    typealias LineWidth = CasinoDesign.LineWidth
    typealias Shadow = CasinoDesign.Shadow
    typealias Opacity = CasinoDesign.Opacity
    typealias Animation = CasinoDesign.Animation
    typealias Scale = CasinoDesign.Scale
    typealias MinScaleFactor = CasinoDesign.MinScaleFactor
    typealias BaseFontSize = CasinoDesign.BaseFontSize
    typealias IconSize = CasinoDesign.IconSize
    
    // MARK: - Game-Specific Sizes
    
    enum Size {
        // Add your game-specific sizes here
        static let cardWidth: CGFloat = 90
    }
}

// MARK: - App Colors

extension Color {
    // Import CasinoKit table colors
    typealias Table = CasinoTable
    
    // Add game-specific colors here
}

1.2 Why This Matters

By typealiasing CasinoDesign, you get:

  • Consistent spacing throughout your app
  • Proper opacity values for layering
  • Standardized corner radii
  • Matching font sizes

Don't hardcode values! Use constants instead:

Bad:

.padding(24)
.opacity(0.1)
.cornerRadius(12)

Good:

.padding(Design.Spacing.xxLarge)
.opacity(Design.Opacity.subtle)
.clipShape(.rect(cornerRadius: Design.CornerRadius.large))

Step 2: Use SheetContainerView

2.1 Basic Structure

SheetContainerView provides the foundation: dark background, navigation bar, and done button.

import SwiftUI
import CasinoKit

struct SettingsView: View {
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        SheetContainerView(
            title: "Settings",
            content: {
                // Your sections go here
            },
            onCancel: nil,  // Optional cancel button
            onDone: {
                dismiss()
            },
            doneButtonText: "Done"
        )
    }
}

2.2 What SheetContainerView Provides

Automatic Styling:

  • Dark blue background: Color.Sheet.background
  • NavigationStack with inline title
  • Golden "Done" button: Color.Sheet.accent
  • Optional "Cancel" button
  • Toolbar with proper dark scheme
  • ScrollView with proper vertical spacing

Key Parameters:

  • title - The navigation bar title
  • content - A @ViewBuilder closure for your sections
  • onCancel - Optional cancel action (if nil, no cancel button)
  • onDone - Done button action
  • doneButtonText - Text for done button (default: "Done")
  • cancelButtonText - Text for cancel button (default: "Cancel")

2.3 Section Spacing

SheetContainerView automatically adds xxLarge (24pt) spacing between sections:

VStack(spacing: CasinoDesign.Spacing.xxLarge) {
    content  // Your sections
}

This creates the clean separation you see between sections.


Step 3: Structure with SheetSection

3.1 Basic SheetSection

Each logical group of settings should be in a SheetSection:

SheetSection(title: "DISPLAY", icon: "eye") {
    // Settings content here
}

3.2 What SheetSection Provides

Header:

  • Icon in golden color with opacity
  • Title in uppercase, bold, rounded font
  • Subtle spacing and padding

Content Card:

  • White opacity background (Color.Sheet.sectionFill)
  • Rounded corners (CornerRadius.large)
  • Proper padding
  • Horizontal margins

Visual Structure:

┌─────────────────────────────────────┐
│ 👁 DISPLAY                           │  ← Header (icon + title)
│ ┌─────────────────────────────────┐ │
│ │                                 │ │  ← Content card
│ │  [Settings content here]        │ │     (white opacity fill)
│ │                                 │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘

3.3 Section Best Practices

Use semantic grouping:

  • GAME STYLE - Game variants and modes
  • RULES - Rule customization
  • TABLE LIMITS - Betting limits
  • DECK SETTINGS - Shoe configuration
  • STARTING BALANCE - Balance picker
  • DISPLAY - Visual settings
  • SOUND - Audio settings
  • DATA - Reset and export

Choose appropriate icons:

SheetSection(title: "GAME STYLE", icon: "suit.club.fill")
SheetSection(title: "RULES", icon: "list.bullet.clipboard")
SheetSection(title: "TABLE LIMITS", icon: "banknote")
SheetSection(title: "DECK SETTINGS", icon: "rectangle.portrait.on.rectangle.portrait")
SheetSection(title: "STARTING BALANCE", icon: "dollarsign.circle")
SheetSection(title: "DISPLAY", icon: "eye")
SheetSection(title: "SOUND", icon: "speaker.wave.2.fill")
SheetSection(title: "DATA", icon: "externaldrive")

Step 4: Use Proper Settings Components

4.1 SelectableRow (Radio Button Rows)

Use SelectableRow for picker options with radio buttons:

SheetSection(title: "DECK SETTINGS", icon: "rectangle.portrait.on.rectangle.portrait") {
    VStack(spacing: Design.Spacing.small) {
        SelectableRow(
            title: "1 Deck",
            subtitle: "Single deck, higher variance",
            isSelected: deckCount == 1,
            accentColor: Color.Sheet.accent,
            action: { deckCount = 1 }
        )
        
        SelectableRow(
            title: "6 Decks",
            subtitle: "Standard casino shoe",
            isSelected: deckCount == 6,
            accentColor: Color.Sheet.accent,
            action: { deckCount = 6 }
        )
    }
}

What SelectableRow Provides:

  • Title in white, large font
  • Subtitle in white with medium opacity
  • Optional badge (e.g., "$10 - $1,000")
  • Golden checkmark circle when selected
  • Outlined circle when not selected
  • Golden border when selected
  • Subtle golden background fill when selected
  • Proper padding and rounded corners

With Badge:

SelectableRow(
    title: "Low Stakes",
    subtitle: "Standard mini table",
    isSelected: true,
    accentColor: Color.Sheet.accent,
    badge: { 
        BadgePill(text: "$10 - $1,000", isSelected: true) 
    },
    action: { }
)

4.2 SettingsToggle (Toggle Switches)

Use SettingsToggle for on/off options:

SheetSection(title: "DISPLAY", icon: "eye") {
    VStack(spacing: Design.Spacing.small) {
        SettingsToggle(
            title: "Show Animations",
            subtitle: "Card dealing animations",
            isOn: $showAnimations,
            accentColor: Color.Sheet.accent
        )
        
        Divider().background(Color.white.opacity(Design.Opacity.hint))
        
        SettingsToggle(
            title: "Show Hints",
            subtitle: "Basic strategy suggestions",
            isOn: $showHints,
            accentColor: Color.Sheet.accent
        )
    }
}

What SettingsToggle Provides:

  • Title in large font, white
  • Subtitle in body font, white with medium opacity
  • Toggle switch with golden accent color
  • Proper vertical alignment
  • Minimum touch target height (44pt)

4.3 Specialized Pickers

SpeedPicker:

SpeedPicker(speed: $dealingSpeed, accentColor: Color.Sheet.accent)

VolumePicker:

VolumePicker(volume: $soundVolume, accentColor: Color.Sheet.accent)

BalancePicker:

BalancePicker(balance: $startingBalance, accentColor: Color.Sheet.accent)

4.4 Dividers Between Items

Use dividers to separate items within a section:

VStack(spacing: Design.Spacing.small) {
    SettingsToggle(title: "Option 1", isOn: $option1, accentColor: accent)
    
    Divider()
        .background(Color.white.opacity(Design.Opacity.hint))
    
    SettingsToggle(title: "Option 2", isOn: $option2, accentColor: accent)
}

Divider opacity levels:

  • Design.Opacity.hint (0.2) - Very subtle, recommended
  • Design.Opacity.subtle (0.1) - Almost invisible
  • Design.Opacity.light (0.3) - More prominent

Step 5: Apply Consistent Colors

5.1 Use Color.Sheet Constants

Always use Color.Sheet.accent for highlights:

private let accent = Color.Sheet.accent

// Then use it everywhere:
SelectableRow(..., accentColor: accent)
SettingsToggle(..., accentColor: accent)
SpeedPicker(..., accentColor: accent)

5.2 Color Constants Available

From CasinoKit:

Color.Sheet.background       // Dark blue: Color(red: 0.08, green: 0.12, blue: 0.18)
Color.Sheet.accent           // Gold: Color(red: 0.9, green: 0.75, blue: 0.3)
Color.Sheet.sectionFill      // White.opacity(0.1)
Color.Sheet.cardBackground   // White.opacity(0.05)
Color.Sheet.secondaryText    // White.opacity(0.6)
Color.Sheet.cancelText       // White.opacity(0.7)

5.3 Text Colors

Primary text (titles):

.foregroundStyle(.white)

Secondary text (subtitles, descriptions):

.foregroundStyle(.white.opacity(Design.Opacity.medium))
// or
.foregroundStyle(Color.Sheet.secondaryText)

Accent highlights:

.foregroundStyle(Color.Sheet.accent)

5.4 Background Colors

Section card fill:

.background(
    RoundedRectangle(cornerRadius: Design.CornerRadius.large)
        .fill(Color.Sheet.sectionFill)
)

Selection highlight:

.background(
    RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
        .fill(isSelected ? accent.opacity(Design.Opacity.subtle) : .clear)
)

Complete Example

Here's a complete settings view demonstrating all the concepts:

//
//  SettingsView.swift
//  YourGame
//

import SwiftUI
import CasinoKit

struct SettingsView: View {
    @Bindable var settings: GameSettings
    @Environment(\.dismiss) private var dismiss
    
    @State private var showClearDataAlert = false
    
    /// Accent color for settings components
    private let accent = Color.Sheet.accent
    
    var body: some View {
        SheetContainerView(
            title: "Settings",
            content: {
                // 1. Table Limits
                SheetSection(title: "TABLE LIMITS", icon: "banknote") {
                    TableLimitsPicker(selection: $settings.tableLimits)
                }
                
                // 2. Deck Settings
                SheetSection(title: "DECK SETTINGS", icon: "rectangle.portrait.on.rectangle.portrait") {
                    DeckCountPicker(selection: $settings.deckCount)
                }
                
                // 3. Starting Balance
                SheetSection(title: "STARTING BALANCE", icon: "dollarsign.circle") {
                    BalancePicker(balance: $settings.startingBalance, accentColor: accent)
                }
                
                // 4. Display
                SheetSection(title: "DISPLAY", icon: "eye") {
                    VStack(spacing: Design.Spacing.small) {
                        SettingsToggle(
                            title: "Show Animations",
                            subtitle: "Card dealing animations",
                            isOn: $settings.showAnimations,
                            accentColor: accent
                        )
                        
                        if settings.showAnimations {
                            Divider()
                                .background(Color.white.opacity(Design.Opacity.hint))
                            
                            SpeedPicker(speed: $settings.dealingSpeed, accentColor: accent)
                        }
                        
                        Divider()
                            .background(Color.white.opacity(Design.Opacity.hint))
                        
                        SettingsToggle(
                            title: "Show Hints",
                            subtitle: "Strategy suggestions",
                            isOn: $settings.showHints,
                            accentColor: accent
                        )
                    }
                }
                
                // 5. Sound
                SheetSection(title: "SOUND", icon: "speaker.wave.2.fill") {
                    VStack(spacing: Design.Spacing.small) {
                        SettingsToggle(
                            title: "Sound Effects",
                            subtitle: "Play game sounds",
                            isOn: $settings.soundEnabled,
                            accentColor: accent
                        )
                        
                        if settings.soundEnabled {
                            Divider()
                                .background(Color.white.opacity(Design.Opacity.hint))
                            
                            VolumePicker(volume: $settings.soundVolume, accentColor: accent)
                        }
                        
                        Divider()
                            .background(Color.white.opacity(Design.Opacity.hint))
                        
                        SettingsToggle(
                            title: "Haptics",
                            subtitle: "Vibration feedback",
                            isOn: $settings.hapticsEnabled,
                            accentColor: accent
                        )
                    }
                }
                
                // 6. Data
                SheetSection(title: "DATA", icon: "externaldrive") {
                    Button {
                        showClearDataAlert = true
                    } label: {
                        HStack {
                            VStack(alignment: .leading, spacing: Design.Spacing.xxSmall) {
                                Text("Clear All Data")
                                    .font(.system(size: Design.BaseFontSize.large, weight: .semibold))
                                    .foregroundStyle(.red)
                                
                                Text("Reset progress and statistics")
                                    .font(.system(size: Design.BaseFontSize.body))
                                    .foregroundStyle(.white.opacity(Design.Opacity.medium))
                            }
                            
                            Spacer()
                            
                            Image(systemName: "trash")
                                .foregroundStyle(.red)
                        }
                        .padding()
                        .background(
                            RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
                                .fill(.clear)
                        )
                        .overlay(
                            RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
                                .strokeBorder(Color.white.opacity(Design.Opacity.subtle), lineWidth: Design.LineWidth.thin)
                        )
                    }
                    .buttonStyle(.plain)
                }
                
                // Version info
                Text("YourGame v1.0 (1)")
                    .font(.system(size: Design.BaseFontSize.body))
                    .foregroundStyle(.white.opacity(Design.Opacity.light))
                    .frame(maxWidth: .infinity)
                    .padding(.top, Design.Spacing.large)
                    .padding(.bottom, Design.Spacing.medium)
            },
            onCancel: nil,
            onDone: {
                settings.save()
                dismiss()
            }
        )
        .alert("Clear All Data?", isPresented: $showClearDataAlert) {
            Button("Cancel", role: .cancel) { }
            Button("Clear", role: .destructive) {
                // Clear data logic
            }
        } message: {
            Text("This will delete all saved progress and statistics. This cannot be undone.")
        }
    }
}

// MARK: - Custom Pickers

struct TableLimitsPicker: View {
    @Binding var selection: TableLimits
    
    var body: some View {
        VStack(spacing: Design.Spacing.small) {
            ForEach(TableLimits.allCases) { limit in
                SelectableRow(
                    title: limit.displayName,
                    subtitle: limit.description,
                    isSelected: selection == limit,
                    accentColor: Color.Sheet.accent,
                    badge: { 
                        BadgePill(
                            text: "$\(limit.minBet) - $\(limit.maxBet)", 
                            isSelected: selection == limit
                        ) 
                    },
                    action: { selection = limit }
                )
            }
        }
    }
}

struct DeckCountPicker: View {
    @Binding var selection: Int
    
    var body: some View {
        VStack(spacing: Design.Spacing.small) {
            ForEach([1, 2, 4, 6, 8], id: \.self) { count in
                SelectableRow(
                    title: "\(count) Deck\(count == 1 ? "" : "s")",
                    subtitle: subtitleFor(count: count),
                    isSelected: selection == count,
                    accentColor: Color.Sheet.accent,
                    action: { selection = count }
                )
            }
        }
    }
    
    private func subtitleFor(count: Int) -> String {
        switch count {
        case 1: return "Single deck, higher variance"
        case 2: return "Lower house edge"
        case 4: return "Common shoe game"
        case 6: return "Standard casino"
        case 8: return "Maximum penetration"
        default: return ""
        }
    }
}

Color Reference

Complete Color.Sheet Definitions

From CasinoKit/Sources/CasinoKit/Theme/CasinoDesign.swift:

public extension Color {
    enum Sheet {
        /// Dark background for sheets and popups.
        public static let background = Color(red: 0.08, green: 0.12, blue: 0.18)
        
        /// Subtle fill for section cards.
        public static let sectionFill = Color.white.opacity(CasinoDesign.Opacity.subtle)
        
        /// Card background in settings/sheets.
        public static let cardBackground = Color.white.opacity(CasinoDesign.Opacity.verySubtle)
        
        /// Accent color for buttons and highlights (gold).
        public static let accent = Color(red: 0.9, green: 0.75, blue: 0.3)
        
        /// Secondary text color.
        public static let secondaryText = Color.white.opacity(CasinoDesign.Opacity.accent)
        
        /// Cancel button color.
        public static let cancelText = Color.white.opacity(CasinoDesign.Opacity.strong)
    }
}

Opacity Reference

public enum Opacity {
    public static let verySubtle: Double = 0.05   // Barely visible backgrounds
    public static let subtle: Double = 0.1        // Section fills
    public static let selection: Double = 0.15    // Selection highlights
    public static let hint: Double = 0.2          // Dividers, borders
    public static let quarter: Double = 0.25      // Quarter opacity
    public static let light: Double = 0.3         // Light text, borders
    public static let overlay: Double = 0.4       // Modal overlays
    public static let medium: Double = 0.5        // Subtitles, secondary info
    public static let secondary: Double = 0.5     // Same as medium
    public static let disabled: Double = 0.5      // Disabled controls
    public static let accent: Double = 0.6        // Accent text
    public static let strong: Double = 0.7        // Cancel buttons
    public static let heavy: Double = 0.8         // Icons, strong text
    public static let nearOpaque: Double = 0.85   // Almost solid
    public static let almostFull: Double = 0.9    // Very solid
}

Common Color Patterns

Selected row:

.background(
    RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
        .fill(accent.opacity(Design.Opacity.subtle))  // 0.1
)
.overlay(
    RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
        .strokeBorder(accent.opacity(Design.Opacity.medium), lineWidth: Design.LineWidth.thin)  // 0.5
)

Unselected row:

.background(
    RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
        .fill(.clear)
)
.overlay(
    RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
        .strokeBorder(Color.white.opacity(Design.Opacity.subtle), lineWidth: Design.LineWidth.thin)  // 0.1
)

Troubleshooting

Issue: Colors don't look golden

Problem: Accent colors appear white or wrong color.

Solution: Ensure you're passing Color.Sheet.accent to the accentColor parameter:

// ❌ Wrong
SelectableRow(..., accentColor: .yellow)

// ✅ Correct
private let accent = Color.Sheet.accent
SelectableRow(..., accentColor: accent)

Issue: Sections not separated properly

Problem: Sections appear cramped together.

Solution: Ensure you're using SheetContainerView which automatically adds xxLarge (24pt) spacing:

SheetContainerView(title: "Settings", content: {
    SheetSection(title: "SECTION 1", icon: "icon1") { ... }
    SheetSection(title: "SECTION 2", icon: "icon2") { ... }
    // Auto-spaced by xxLarge (24pt)
})

Issue: Section headers not styled properly

Problem: Section headers missing icon, wrong font, or poor spacing.

Solution: Use SheetSection, not custom VStack:

// ❌ Wrong
VStack {
    Text("DISPLAY")
    // content
}

// ✅ Correct
SheetSection(title: "DISPLAY", icon: "eye") {
    // content
}

Issue: Radio buttons not golden

Problem: Selection indicators are white or blue circles.

Solution: Pass accentColor: Color.Sheet.accent to SelectableRow:

SelectableRow(
    title: "Option",
    subtitle: "Description",
    isSelected: true,
    accentColor: Color.Sheet.accent,  // ← Must include this
    action: { }
)

Issue: Background is wrong color

Problem: Background is white, gray, or wrong shade of blue.

Solution: Use SheetContainerView which sets Color.Sheet.background automatically:

// ❌ Wrong
var body: some View {
    NavigationStack {
        ScrollView {
            // sections
        }
        .background(Color.gray)  // Wrong!
    }
}

// ✅ Correct
var body: some View {
    SheetContainerView(title: "Settings", content: {
        // sections - background automatically applied
    })
}

Issue: Dividers are too prominent or invisible

Problem: Dividers within sections are too thick or can't be seen.

Solution: Use white with Design.Opacity.hint (0.2):

Divider()
    .background(Color.white.opacity(Design.Opacity.hint))

Issue: Text not readable

Problem: Text appears dark gray or hard to read.

Solution: Always use .foregroundStyle(.white) for primary text:

Text("Title")
    .foregroundStyle(.white)

Text("Subtitle")
    .foregroundStyle(.white.opacity(Design.Opacity.medium))

Issue: Spacing inconsistent

Problem: Some spacing is 10pt, some 12pt, some 15pt.

Solution: Always use Design.Spacing constants:

VStack(spacing: Design.Spacing.small) {  // 8pt
    // items
}

.padding(Design.Spacing.medium)  // 12pt

Issue: Missing import

Problem: SheetContainerView, SelectableRow, or other components not found.

Solution: Add import CasinoKit to the top of your file:

import SwiftUI
import CasinoKit  // ← Required for CasinoKit components

Issue: Design constants not available

Problem: Design.Spacing, Design.Opacity, etc. not found.

Solution: Create DesignConstants.swift with typealias to CasinoKit constants (see Step 1).


Quick Checklist

Use this checklist to ensure your settings view has the proper styling:

  • Import CasinoKit at top of file
  • Create local DesignConstants.swift with typealiases
  • Wrap entire settings view in SheetContainerView
  • Each logical group in a SheetSection with icon and title
  • Use SelectableRow for radio button options
  • Use SettingsToggle for on/off switches
  • Pass accentColor: Color.Sheet.accent to all components
  • Use Design.Spacing.small between items in a section
  • Use Divider().background(Color.white.opacity(Design.Opacity.hint)) between items
  • Use .foregroundStyle(.white) for primary text
  • Use .foregroundStyle(.white.opacity(Design.Opacity.medium)) for secondary text
  • No hardcoded spacing, opacity, or corner radius values
  • Version info at bottom with subtle opacity

Summary

The polished casino settings interface is achieved through:

  1. SheetContainerView for the dark background and navigation
  2. SheetSection for icon headers and card-like content containers
  3. SelectableRow for radio button pickers with golden checkmarks
  4. SettingsToggle for toggle switches
  5. Color.Sheet.accent for consistent golden highlights
  6. Design constants for spacing, opacity, and font sizes
  7. Proper text colors (white for primary, white with opacity for secondary)
  8. Subtle dividers with 0.2 opacity between items

Follow this guide and your settings will match the professional casino aesthetic! 🎰