# Application 4 — Liquid Glass Tab Bars · Design System & Integration Guide

> **For AI agents:** start with **`AI_GUIDE.md`** (in this folder). It has the decision tree, exact install and usage steps per platform, and verification rules. This file holds the full design tokens.
>
> **The page is scrollable and has 7 sections:** 01 LiquidGlassTabBars · 02 UnionTabView · 03 FabBar · 04 Square · 05 expo-glass-tabs · 06 AndroidLiquidGlass (Backdrop) · **07 iOS 26 Liquid Glass Effect (Figma kit)**. Sections 0–11 cover 01; §12 covers 02; §13 covers 03; **§15 covers 04 (Square)**; **§16 covers 05 (expo-glass-tabs)**; **§17 covers 06 (Backdrop)**; **§18 covers 07 (Figma glass kit)**; §14 helps you choose.
>
> **Machine-readable tokens for all 7 sections:** `tokens.json` (same folder). If a number here and in `tokens.json` disagree, the CSS in the source file wins.

| # | Package | Author | Repo | SPM URL | License |
|---|---|---|---|---|---|
| 01 | LiquidGlassTabBars (`LiquidUI`) | mikonyaa | https://github.com/mikonyaa/LiquidGlassTabBars | `https://github.com/mikonyaa/LiquidGlassTabBars.git` | MIT |
| 02 | UnionTabView | Ben Sage · [Union St](https://unionst.com/) | https://github.com/unionst/union-tab-view | `https://github.com/unionst/union-tab-view.git` | MIT |
| 03 | FabBar | Ryan Ashcraft | https://github.com/ryanashcraft/FabBar | `https://github.com/ryanashcraft/FabBar.git` (from `1.0.0`) | MIT |
| 04 | Square (Android **app**; design reference) | Lelonio | https://github.com/Lelonio/Square | not a library: use [Kyant0/AndroidLiquidGlass](https://github.com/Kyant0/AndroidLiquidGlass) for the glass | **GPL-3.0-or-later** |
| 05 | expo-glass-tabs | David Mokos | https://github.com/davidmokos/expo-glass-tabs | npm `expo-glass-tabs` | MIT |
| 06 | AndroidLiquidGlass (Backdrop) | Kyant0 | https://github.com/Kyant0/AndroidLiquidGlass | Gradle `io.github.kyant0:backdrop:<version>` | Apache-2.0 |
| 07 | iOS 26 Liquid Glass Effect (Figma kit) | Jan Decker | https://www.figma.com/community/file/1514186232748375562/ios-26-liquid-glass-effect | Figma → *Open in Figma* / Duplicate | Figma Community (free) |

> Web reference implementation plus a SwiftUI integration guide for three production tab-bar patterns in Apple's Liquid Glass style. Read this before editing App 4 or using these bars in another project.

---

## 0. Project card

| | |
|---|---|
| **Project name** | Liquid Glass Tab Bars |
| **Swift package / product** | `LiquidUI` (zero dependencies) |
| **Author** | [@mikonyaa](https://github.com/mikonyaa) |
| **Source repository** | https://github.com/mikonyaa/LiquidGlassTabBars |
| **SPM URL** | `https://github.com/mikonyaa/LiquidGlassTabBars.git` |
| **Collection** | [Apple Design Templates](https://github.com/mikonyaa/Apple-Design-Templates) |
| **License** | MIT: free for personal and commercial use; keep the copyright notice |
| **Platforms** | iOS 26+ for native Liquid Glass · iOS 17–25 with a material fallback · macOS 14+ (compiles, for tests) |
| **Toolchain** | Xcode 26+, Swift 6 |
| **Docs** | [Getting Started](https://github.com/mikonyaa/LiquidGlassTabBars/blob/main/Docs/GettingStarted.md) · [Customization](https://github.com/mikonyaa/LiquidGlassTabBars/blob/main/Docs/Customization.md) · [Architecture](https://github.com/mikonyaa/LiquidGlassTabBars/blob/main/Docs/Architecture.md) · [Design Principles](https://github.com/mikonyaa/LiquidGlassTabBars/blob/main/Docs/DesignPrinciples.md) |
| **This web port** | `apps/app-4/App 4 - Liquid Glass Tab Bars.html` + `src/icons.jsx` (SF look-alikes + hooks), `src/tabbars.jsx` (01), `src/union.jsx` (02 + shared `Device`, `SecHead`, `Code`), `src/fabbar.jsx` (03), `src/demo.jsx` (01 demo + page shell) |

> Inspired by Apple's Liquid Glass design language. Not affiliated with or endorsed by Apple. Apple, SwiftUI and SF Symbols are trademarks of Apple Inc. The web icons are look-alikes drawn for the prototype; in a real iOS app, use the real SF Symbols by name (see §4).

---

## 1. The three variants

| Variant | When to use | Structure |
|---|---|---|
| **System** (`SystemGlassTabView`) | Default choice. Platform-native behaviour, overflow and accessibility come for free | Native `TabView`; on iOS 26 the system renders the glass. No custom blur |
| **Floating** (`LiquidTabBar(variant: .floating)`) | Brand-forward single capsule | One glass capsule. A tinted pill slides to the selected item (`matchedGeometryEffect`); only the selected item shows its label |
| **Morphing** (`LiquidTabBar(variant: .morphing)`) | Expressive, few destinations | Separate interactive glass capsules inside one `GlassEffectContainer`; the selected capsule expands to show its title |

**Rule:** Floating and Morphing support **2–5** destinations. For more, use System.

---

## 2. Metrics (from `LiquidTabBar.swift`)

| Token | Value | Notes |
|---|---|---|
| `barHeight` | **60 pt** | `@ScaledMetric`, grows with Dynamic Type |
| `minimumItemHeight` | **48 pt** | Floating item / pill height; morphing min width |
| Floating padding | 6 pt | Inside the capsule |
| Floating item spacing | 2 pt | `HStack(spacing: 2)` |
| Floating icon | 19 pt semibold | Label: `.caption2` semibold (web: 11px) |
| Morphing icon | 18 pt semibold | Label: `.subheadline` semibold (web: 15px), icon–label gap 7 |
| Morphing h-padding | 14 pt idle / **16 pt** selected | |
| Morphing spacing | `theme.itemSpacing` = 8 pt | Also the morph threshold |
| Shape | `Capsule()` everywhere | Glass, hit area, border and pill must share the same shape |
| Shadow | `radius: theme.shadowRadius (18)`, `y: 8` | |
| Placement | `.safeAreaInset(edge: .bottom)` with `.padding(.horizontal, 16)` and `.padding(.vertical, 8)` | Never use hard-coded bottom padding |
| Min touch target | 44 pt | |

Web port device: 393×852 pt (iPhone 15/16 Pro) rendered at 1 pt = 1 px, then scaled down to fit the stage.

---

## 3. Themes (1:1 from `LiquidTabBarTheme.swift`)

Default values for every theme: `selectedFillOpacity 0.18` · `selectedBorderOpacity 0.48` · `shadowRadius 18` · `itemSpacing 8`.

| Theme | `tint` | `inactiveForeground` | `fallbackFill` | `fallbackBorder` | `shadowColor` |
|---|---|---|---|---|---|
| **classic** | `rgb(0.20,0.58,1.00)` → `#3394FF` | white 62% | `rgb(0.12,0.13,0.15)` `#1F2126` | white 12% | black 14% |
| **violet** | `rgb(0.76,0.53,1.00)` → `#C287FF` | white 58% | `rgb(0.10,0.07,0.16)` @96% | `rgb(0.82,0.69,1)` @24% | purple 18% |
| **ocean** | `rgb(0.28,0.82,1.00)` → `#47D1FF` | white 60% | `rgb(0.04,0.10,0.15)` @96% | cyan 22% | cyan 14% |
| **neutral** ("Graphite" in the demo) | `.primary` (white in dark mode) | `.secondary` | `secondarySystemBackground` | primary 10% | black 12% |

Custom brand theme:

```swift
let brandTheme = LiquidTabBarTheme(
    tint: .mint,
    inactiveForeground: .secondary,
    fallbackFill: .black.opacity(0.90),
    fallbackBorder: .white.opacity(0.12),
    selectedFillOpacity: 0.16,
    selectedBorderOpacity: 0.42,
    shadowColor: .mint.opacity(0.12),
    shadowRadius: 16,
    itemSpacing: 10
)
```

**Web CSS variables** (set by `themeVars(name)` in `tabbars.jsx`):
`--tint`, `--tint-rgb`, `--inactive`, `--fb-fill`, `--fb-border`, `--lq-shadow`, `--sel-fill`, `--sel-border`, `--lq-radius`, `--lq-spacing`.

### Demo backgrounds (`DemoScreen.swift → DemoBackdrop`)
- **Classic:** solid `rgb(0.065,0.07,0.08)` → `#111214`
- **Graphite:** vertical gradient `#0E0E0F → #212125 → #060608`

---

## 4. Icons: SF Symbols map

Use these **exact SF Symbol names** in SwiftUI (`Image(systemName:)`). The web port draws look-alikes under the same keys in `src/icons.jsx` (`<Sym name="house.fill"/>`).

| Role | SF Symbol |
|---|---|
| Home tab | `house.fill` |
| Activity tab | `waveform.path.ecg` |
| Library tab | `square.grid.2x2.fill` |
| Profile tab | `person.crop.circle.fill` |
| Search tab (5th, demo only) | `magnifyingglass` |
| Style menu: System / Floating / Morphing | `apple.logo` (web: `app.dashed`) / `capsule.fill` / `circle.grid.3x3.fill` |
| Palette menu | `paintpalette.fill` |
| Quick actions | `plus` · `timer` · `square.and.arrow.up` |
| Recent rows | `rectangle.3.group.fill` · `slider.horizontal.3` |
| Status | `checkmark.circle.fill` |

Other good tab icons: `tray.fill`, `bell.fill`, `bag.fill`, `heart.fill`, `gearshape.fill`, `chart.bar.fill`.
Browse all symbols in Apple's free **SF Symbols app**: https://developer.apple.com/sf-symbols/

---

## 5. Motion

| Pattern | SwiftUI | Web port |
|---|---|---|
| Selection | `.spring(response: 0.32, dampingFraction: 0.82)` | `transform .42s cubic-bezier(.34,1.28,.64,1)` |
| Floating label | `.opacity + .move(edge: .bottom)` | max-height/opacity/translateY |
| Morphing label | `.opacity + .scale(0.92)` | grid-template-columns 0fr → 1fr |
| Reselect | `onReselect` (e.g. scroll to top) | tapping the active tab smooth-scrolls to the top |
| Reduce Motion | animation = `nil` | `.rm` class disables all transitions |

---

## 6. Accessibility

- **Reduce Transparency:** glass is replaced by the opaque `fallbackFill` plus a `fallbackBorder` hairline (web: `.rt` class).
- **Reduce Motion:** no spring and no morph (web: `.rm`).
- **Dynamic Type:** heights use `@ScaledMetric`.
- Each item has `accessibilityLabel(title)` and the `.isSelected` trait (web: `role="tab"` + `aria-selected`).
- Keep a 44 pt minimum hit area. Test the tint over both bright and dark content.

---

## 7. Glass material: web recipe

```css
.glass{
  background:linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,.045));
  backdrop-filter:blur(22px) saturate(1.8);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),      /* top specular */
             inset 0 0 0 1px rgba(255,255,255,.08),     /* rim */
             0 8px var(--lq-radius) var(--lq-shadow);   /* separation */
}
```
Use glass only on navigation and controls, never on long-form content.

---

## 8. SwiftUI quick start (copy-paste)

**Install:** Xcode → **File → Add Package Dependencies…** → paste `https://github.com/mikonyaa/LiquidGlassTabBars.git` → select the **LiquidUI** product.

```swift
import SwiftUI
import LiquidUI

enum AppTab: Hashable, Sendable { case home, activity, library, profile }

struct RootView: View {
    @State private var selectedTab: AppTab = .home

    private let items = [
        LiquidTabItem(id: AppTab.home,     title: "Home",     systemImage: "house.fill"),
        LiquidTabItem(id: AppTab.activity, title: "Activity", systemImage: "waveform.path.ecg"),
        LiquidTabItem(id: AppTab.library,  title: "Library",  systemImage: "square.grid.2x2.fill"),
        LiquidTabItem(id: AppTab.profile,  title: "Profile",  systemImage: "person.crop.circle.fill")
    ]

    var body: some View {
        content(for: selectedTab)
            .safeAreaInset(edge: .bottom, spacing: 0) {
                LiquidTabBar(
                    selection: $selectedTab,
                    items: items,
                    variant: .floating,     // or .morphing
                    theme: .classic,        // .violet · .ocean · .neutral · custom
                    onReselect: { tab in /* scroll to top */ }
                )
                .padding(.horizontal, 16)
                .padding(.vertical, 8)
            }
    }

    @ViewBuilder func content(for tab: AppTab) -> some View { /* your screens */ }
}
```

**System (native) variant:**

```swift
SystemGlassTabView(selection: $selectedTab, tint: .purple) {
    HomeView().tabItem { Label("Home", systemImage: "house.fill") }.tag(AppTab.home)
    ActivityView().tabItem { Label("Activity", systemImage: "waveform.path.ecg") }.tag(AppTab.activity)
}
```

---

## 9. Web port: how to reuse

1. Copy `src/icons.jsx` and `src/tabbars.jsx`, plus the CSS blocks **glass material**, **SYSTEM**, **FLOATING** and **MORPHING** from the HTML.
2. Wrap your screen in an element with `style={themeVars('classic')}`.
3. Render `<LiquidTabBar variant="floating" items={[{id,title,systemImage}]} sel={sel} onSel={setSel}/>` inside a bottom inset (`left/right 16px`, `bottom 22px` on a phone with a home indicator).
4. Add the `.rt` or `.rm` class on an ancestor to honour Reduce Transparency or Reduce Motion.

## 10. Demo screen content (verbatim from the repo)

| Tab | Headline | Message |
|---|---|---|
| Home | A clear view of today | Keep the controls light and let the content lead. |
| Activity | Your momentum | Small, meaningful signals work better than visual noise. |
| Library | Saved for later | A flexible surface for collections, media, or projects. |
| Profile | Make it yours | Colors, spacing, icons, and motion are all configurable. |

Card pattern: `white 7.5%` fill, `0.75px white 10%` stroke, radius 28 (progress card), 22 (actions, 76 pt tall), 24 (list, rows 58 pt).
Typography: SF Pro. Large Title 34 bold rounded, Body 17, Subheadline 15, Caption 12, Caption2 11.

## 11. Checklist before shipping
- [ ] Is the native `TabView` enough? If yes, use System.
- [ ] 2–5 items for Floating or Morphing.
- [ ] The bar sits in `safeAreaInset`, not overlaid on content.
- [ ] One tint, used for selection only.
- [ ] Tested with Reduce Transparency, Reduce Motion and the largest Dynamic Type size.
- [ ] MIT copyright notice kept in your acknowledgements.


---

## 12. UnionTabView (package 02)

| | |
|---|---|
| **Project name** | UnionTabView |
| **Author** | Ben Sage, [Union St](https://unionst.com/) |
| **Repository** | https://github.com/unionst/union-tab-view |
| **SPM URL** | `https://github.com/unionst/union-tab-view.git` |
| **API docs** | https://www.swiftipedia.org/documentation/uniontabview |
| **Guide** | [Profile pictures in the Liquid Glass tab bar](https://www.swiftipedia.org/documentation/uniontabview/customviewsinliquidglasstabbars) |
| **Requirements** | iOS 17+, Swift 6, Xcode 16+ (glass on iOS 26, clean custom fallback on 17–25) |
| **License** | MIT |

**What it solves:** the native iOS 26 `TabView` only allows system tab items. UnionTabView keeps the floating glass capsule (`glassEffect(.regular.interactive())`) and the native sliding indicator, and lets you render **any SwiftUI view** per tab: avatars, badges, animated icons.

**How it works:** an invisible `UISegmentedControl` (empty segments, clear background) provides the sliding selection, haptics and VoiceOver. Your custom item views are drawn on top with `allowsHitTesting(false)`.

**Web port (`src/union.jsx`):** `<UnionBar tabs sel onSel item lens/>`. `item(tab, isSelected)` is the equivalent of the Swift `item:` closure. Three demo item styles are provided:

| Demo | Web key | Look |
|---|---|---|
| Custom item views | `custom` | Icon + label, **profile avatar** (gradient circle, blue ring when selected), red **badge** `#FF3B30` with a 2px ring |
| Symbol effects | `bounce` | Icon only; bounce keyframe on select (≈ `.symbolEffect(.bounce)`) + 5px dot |
| Custom pill | `pill` | No lens; the selected item becomes a blue gradient capsule (`#3B9BFF → #0A6CFF`) with its title |

Metrics (web): bar 70 pt, radius 35, padding 5, lens `rgba(255,255,255,.10)` that scales to 1.12 on press (the interactive glass bubble). Tint `#0A84FF` (systemBlue, dark).

```swift
import UnionTabView

enum RootTab: CaseIterable { case home, explore, activity, profile
    var icon: String { switch self { case .home: "house.fill"; case .explore: "safari.fill"; case .activity: "bell.fill"; case .profile: "person.crop.circle.fill" } }
}

struct ContentView: View {
    @State private var tab: RootTab = .home
    var body: some View {
        UnionTabView(selection: $tab, tabs: RootTab.allCases) {
            NavigationStack { HomeView() }.unionTab(RootTab.home)
            NavigationStack { ExploreView() }.unionTab(RootTab.explore)
            NavigationStack { ActivityView() }.unionTab(RootTab.activity)
            NavigationStack { ProfileView() }.unionTab(RootTab.profile)
        } item: { tab, isSelected in
            VStack(spacing: 6) {
                Image(systemName: tab.icon)
                    .font(.system(size: 22))
                    .symbolEffect(.bounce, value: isSelected)
                Circle().fill(isSelected ? .blue : .clear).frame(width: 5, height: 5)
            }
            .foregroundStyle(isSelected ? .blue : .secondary)
        }
    }
}
```
`.unionTab(_:)` on iOS 26+ hides the system bar and adds safe-area spacing; on iOS 17–25 it applies `.tag()`.

SF Symbols used: `house.fill`, `safari.fill` (compass), `bell.fill`, `person.crop.circle.fill`.

---

## 13. FabBar (package 03)

| | |
|---|---|
| **Project name** | FabBar |
| **Author** | Ryan Ashcraft ([@ryanashcraft](https://github.com/ryanashcraft)) |
| **Repository** | https://github.com/ryanashcraft/FabBar |
| **SPM** | `.package(url: "https://github.com/ryanashcraft/FabBar.git", from: "1.0.0")` |
| **Example app** | https://github.com/ryanashcraft/FabBar/tree/main/Example/FabBarExample |
| **Credit** | Segmented-control technique idea by [Kavsoft](https://youtu.be/wfHIe8GpKAU) |
| **Requirements** | iOS 26 (SwiftUI API, UIKit inside) |
| **License** | MIT |
| ⚠️ | Manipulates the internal UIKit view hierarchy, so it may break in future iOS updates |

**What it solves:** a real, tinted **floating action button** beside a faithful iOS 26 tab bar, for the app's primary action (compose, log, create). This replaces the `role: .search` hack and the unbalanced trailing FAB.

**Web port (`src/fabbar.jsx`):** `<FabBar tabs sel onSel tint onAction visible/>`

| Token | Value |
|---|---|
| Placement | **21 pt** padding on left, right and bottom |
| Bar | 64 pt tall, radius 32, padding 4, light glass `rgba(255,255,255,.72)` + blur 24 + 0.5px hairline + shadow `0 8px 28px rgba(0,0,0,.10)` |
| Selection lens | `rgba(118,118,128,.14)`; on press it scales to 1.14 and turns white glass (the "bubbly" touch effect) |
| Item | icon 24 + label 10/600, black idle, **tint** when selected |
| FAB | 64 pt circle, gap 10, fill = tint, white `plus` 26, tinted shadow; press scale .9 |
| Tints (demo) | Blue `#0A84FF` · Pink `#FF375F` · Green `#30D158` · Orange `#FF9F0A` |
| Visibility | `isVisible: false` slides the bar down 120 and fades it (demo: gear button → selection mode) |
| Screen | white bg, Large Title 34 bold at top-left, 44 pt round settings button at top-right |

```swift
import FabBar

enum AppTab: Hashable { case home, explore, profile }

struct ContentView: View {
    @State private var selectedTab: AppTab = .home
    @State private var isSelecting = false
    @Environment(\.horizontalSizeClass) private var hSize
    private var tabBarVisibility: Visibility { hSize == .compact ? .hidden : .visible }

    var body: some View {
        TabView(selection: $selectedTab) {
            Tab("Home", systemImage: "house.fill", value: .home) {
                HomeView().fabBarSafeAreaPadding().toolbarVisibility(tabBarVisibility, for: .tabBar)
            }
            Tab("Explore", systemImage: "map.fill", value: .explore) {
                ExploreView().fabBarSafeAreaPadding().toolbarVisibility(tabBarVisibility, for: .tabBar)
            }
            Tab("Profile", systemImage: "person.fill", value: .profile) {
                ProfileView().fabBarSafeAreaPadding().toolbarVisibility(tabBarVisibility, for: .tabBar)
            }
        }
        .fabBar(
            selection: $selectedTab,
            tabs: [
                FabBarTab(value: .home, title: "Home", systemImage: "house.fill", onReselect: { /* scroll to top */ }),
                FabBarTab(value: .explore, title: "Explore", systemImage: "map.fill"),
                FabBarTab(value: .profile, title: "Profile", systemImage: "person.fill"),
            ],
            action: FabBarAction(systemImage: "plus", accessibilityLabel: "Add Item") { /* primary action */ },
            isVisible: !isSelecting
        )
    }
}
```
Custom asset icons: `FabBarTab(value:, title:, image: "custom.icon", imageBundle: .main)`. On iPad, `.fabBar()` hides itself and shows the native bar.

**Known limitations:** no Large Content Viewer (a popover appears instead) · VoiceOver focus may jump after selection · no automatic scroll-to-top (use `onReselect`) · dimensions are hard-coded to iOS 26.

SF Symbols used: `house.fill`, `map.fill`, `person.fill`, `plus`, `gearshape`.

---

## 14. Which one should I use?

| Need | Pick |
|---|---|
| Native behaviour, least maintenance | **01 System** (`SystemGlassTabView`) |
| Branded capsule or expanding tabs, iOS 17+ | **01 Floating / Morphing** |
| Profile picture, badges or animated icons *inside* the glass bar | **02 UnionTabView** |
| A primary "create" action next to the tabs | **03 FabBar** (accepting the UIKit-internals risk) |
| Android / Compose (or Compose Multiplatform) glass UI | **06 Backdrop** (code) + **04 Square** (visual reference) |
| Glass **material + general controls** (buttons, cards, search, toggles, sliders, menus, widgets) on web or in mock-ups | **07 Figma glass kit** (`src/figma-glass.*`) |
| React Native / Expo Router, Revolut-style bar that minimizes on scroll | **05 expo-glass-tabs** |

01, 02, 03 and 05 are MIT; 06 Backdrop is Apache-2.0. 04 Square is GPL-3.0 (copying its code makes your app GPL). Keep each author's copyright notice in your app's Acknowledgements.


---

## 15. Square (project 04): Android, "one refracting glass"

| | |
|---|---|
| **Project name** | Square |
| **What it is** | An unofficial **Android app** (music client for Spotify Premium and YouTube Music). **Not a library** |
| **Author** | Lelonio · https://github.com/Lelonio/Square · [Releases (APK)](https://github.com/Lelonio/Square/releases/latest) · [DEVELOPMENT.md](https://github.com/Lelonio/Square/blob/master/docs/DEVELOPMENT.md) |
| **License** | **GPL-3.0-or-later**. Reusing its code forces your app to be GPL |
| **Platform** | Android 8.0+ (Kotlin, Jetpack Compose), 8 UI languages |
| **Glass engine** | Backdrop / AndroidLiquidGlass (§17, Apache-2.0) |
| **Icons** | Phosphor Icons (MIT): *fill* weight for tabs and transport, *regular* for everything else |

### 15.1 Screens reproduced (web port `src/square.jsx`, 393×852 pt device)
All four phones share **one player state** (`useSqPlayer`): tapping a song on Album or Artist updates the Player, mini players and equalizer indicators everywhere.

**Player.** The background is taken from the cover: base colour top → `bg` → `bg2` bottom. The cover is full-bleed at the top and fades out with a mask.
| Element | Spec |
|---|---|
| Top bar (y 54) | 41 pt glass circles: caret-down (collapse) and **devices** (Connect sheet: This phone / speaker / laptop). Centre title 15/600 = artist, or the pane name (Lyrics · Effects · Credits) |
| "Switch to video" (y 458) | 146×35 glass pill, video icon + 11/600, letter-spacing .7. Toggles the music-video view in place |
| Now-playing pill (y 504) | 61 pt glass capsule, left pad 21: title 17.5/600 (ellipsis) + artist 12 @78%; three **39 pt outlined rings** (1.2 px white 60%): radio · queue · like |
| Progress (y 586) | 5 pt track, white 35%, white fill; grows to 8 pt while dragging. Times 10.5 tabular (y 610) |
| Transport (y 640) | shuffle 36 · **58** prev · **73** play/pause · **58** next · repeat 36. Every circle is glass; shuffle/repeat get a 22% white disc when active |
| Pane switcher (y 742) | 254×41 glass segmented control: disc · lyrics · effects (sliders) · info, with a sliding dark lens (`rgba(40,36,32,.28)`) |
| Lyrics pane | 22/700 lines, inactive white 42% (past 28%, slight blur); the active line lights **word by word**; auto-scrolls with the active line near the top third. Side glass buttons (right, y 335): **translate** (adds a translated line under each) and **karaoke** (mic). Tap a line to seek |
| Effects pane | PRESETS chips (Original · Slowed + Reverb · Sped Up · Nightcore) · SPEED 0.50–1.60× · PITCH ±12 st · REVERB 0–100%, each with a value and **Reset** · Sleep timer chips Off/5/15/30/45 min |
| Credits pane | Performed by · Written by · Produced by · Source (quality / downloaded) |
| Glass tint | `--g` = cover tint RGB, so all glass on the player adopts the artwork colour |

**Album.** Background `#57514b` (the cover's dark tone). The cover is a 392 pt full-bleed hero that fades into the background. Title 21/700, artist 17/600, "Album" 11/600 @60%. Actions: 45 pt outlined **shuffle**, white **Play/Pause pill** (49 pt, 15/600), 45 pt outlined **download** (turns white + check when done). Description 12.4 at 75%, clamped to 3 lines, with a **MORE / LESS** toggle. Songs header 15/700 with a red sort icon. Rows 66 pt: number (or a live equalizer when playing), title 15/600, an "E" badge + duration 11, overflow dots. Top-right light glass **group** (+ · search · ⋯); top-left glass back button.

**Artist.** Background `#2b2b2b`. A 440 pt monochrome grain portrait fades out; the name is condensed ultra-bold (~54 pt Anton-like, scaleY 1.08) overlapping the portrait. Actions: 45 pt outlined info · **65 pt white play** · 45 pt outlined star (follow, fills white). "Top Songs" 17.5/700 + sort. Rows 71 pt: 46 pt cover, title 15/600, "Album · Year" 11.5 @55%; the playing row is mint `#9CF0B0` with an equalizer.

**Shared chrome (light glass).** Mini player 55 pt (bottom 130): 40 pt cover, title 13/500, artist 11 @60%, next + play. **Tab bar** 58 pt (bottom 58), 5 tabs **Home · New · Radio · Library · Search**, icon 24 + label 9/600, sliding lens black 7.5% that scales 1.08 on press, selected colour = page accent (Album: warm brown `#8B5E34`; Artist: ink).

**App › Glass settings.** Light `#F2F2F7`; back glass circle 50 pt + "App" 32/700. The GLASS card (`#E5E5EA`, radius 20) holds presets **Fastest · Balanced · Quality** (check on the active one) and a **live preview** (gradient artwork with a glass mini player, glass tabs and a glass search circle). Under "Adjust it yourself" are the sliders:
| Setting | Range | Quality | Balanced | Fastest | Maps to (Backdrop) |
|---|---|---|---|---|---|
| Colour | 0–100 % | 100 | 100 | 100 | `colorControls(saturation)` / vibrancy |
| Frost | 0–10 dp | 2 | 2 | 0 | `blur(radius)` |
| Edge depth | 0–40 dp | 24 | 16 | 0 | `lens(refractionHeight)` |
| Bend | 0–60 dp | 38 | 22 | 0 | `lens(refractionAmount)` |
| Edge light | 0–100 % | 55 | 45 | 30 | `highlight` alpha |
Moving any slider restyles **every** glass control on all four phones live (CSS vars `--frost`, `--depth`, `--bend`, `--elight`, `--colour`).

### 15.2 Glass recipe (web)
`.sq2g` (dark / cover-tinted) and `.sq2g.lt` (light chrome): tint fill + `backdrop-filter: blur(var(--frost)) saturate(1+colour·0.8) brightness(1+bend·0.1)` + top specular (`inset 0 1.2px`, alpha = edge light) + hairline rim + inner glow sized by edge depth + a soft drop shadow. Press = scale .94. Reduce Transparency = solid tint.

### 15.3 Reproducing in your own app (legal path)
Use **Backdrop** (§17 / AI_GUIDE §5b) and expose the same five settings. Copy the *look* (this section), never Square's source. Artwork, artist ("Nova Lane") and lyrics in the web port are original placeholders.

---

## 16. expo-glass-tabs (project 05): React Native / Expo, Revolut-style

| | |
|---|---|
| **Project name** | expo-glass-tabs |
| **Author** | David Mokos · https://github.com/davidmokos/expo-glass-tabs · npm https://www.npmjs.com/package/expo-glass-tabs |
| **License** | MIT |
| **Platform** | Expo Router (headless tabs `expo-router/ui`). Real `UIGlassEffect` on iOS 26 via `expo-glass-effect`; solid fallback on older iOS and Android. Pure TypeScript, works in Expo Go |
| **Peer deps** | expo-blur, expo-glass-effect, expo-haptics, expo-symbols, react-native-gesture-handler, react-native-reanimated, react-native-safe-area-context, react-native-screens |

**Behaviour (what makes it different):**
1. **Minimize on scroll:** scrolling down shrinks the pill in *both* dimensions and collapses the labels; **all icons stay visible** (the native iOS 26 bar collapses to one icon). Scrolling up expands it. Rubber-band overscroll is ignored.
2. **Sliding highlight:** the active pill travels between tabs on an interruptible, transform-only spring.
3. **Finger scrubbing:** drag along the bar and the highlight tracks the finger 1:1, with a haptic tick at each boundary. **Navigation happens on release.**
4. **Progressive edge blur** behind the bar, with no hard line.
5. **Screen transition:** fade + micro-scale (`renderFadingTabScreen`).

**Theme API (defaults):** `activeTint #FFFFFF` · `inactiveTint #9E9EA6` · `highlight rgba(255,255,255,0.14)` · `glassTint rgba(10,10,12,0.55)` · `solidFallback rgba(18,18,20,0.94)` · `haptics: true`.

**Web port metrics:** bar 357×72 pt expanded → 250×52 pt minimized, fully rounded; labels 12/600 collapse to 0; spring `cubic-bezier(.22,1,.36,1)` 0.5 s; 150 pt progressive blur at the bottom edge.

**Demo items (from the README):** Home `house.fill` · Invest `chart.line.uptrend.xyaxis` · Payments `arrow.left.arrow.right` · Crypto `bitcoinsign` (+ RevPoints in the gif).

**Exports:** `GlassTabBar`, `GlassTabButton`, `TabBarMinimizeProvider`, `useMinimizeOnScroll()`, `useTabBarMinimized()`, `renderFadingTabScreen`, `ProgressiveBlur`, `MINIMIZE_SPRING`.


---

## 17. AndroidLiquidGlass / Backdrop (project 06): Compose Multiplatform library

| | |
|---|---|
| **Project name** | Liquid Glass (**Backdrop**); the repo is called AndroidLiquidGlass |
| **Author** | Kyant0 · https://github.com/Kyant0/AndroidLiquidGlass (default branch `kmp`, ★ ~3.9k) |
| **Docs** | https://kyant.gitbook.io/backdrop · AI index: https://kyant.gitbook.io/backdrop/llms.txt (append `.md` to any page URL for Markdown) |
| **Install** | `implementation("io.github.kyant0:backdrop:<version>")`; take `<version>` from [Maven Central](https://central.sonatype.com/artifact/io.github.kyant0/backdrop) |
| **Platform** | Compose Multiplatform (Android + iOS). Effects are `RenderEffect`s: **Android 12+**; `lens` and `gammaAdjustment` need **Android 13+** |
| **License** | Apache-2.0 (keep the NOTICE if you copy catalog components) |
| **Demo** | Backdrop Catalog APK in `androidApp/release/` |
| **Scope** | Low-level only: **no high-level components are shipped**. Copy these from the catalog: [LiquidButton](https://github.com/Kyant0/AndroidLiquidGlass/blob/kmp/app/src/commonMain/kotlin/com/kyant/backdrop/catalog/components/LiquidButton.kt), [LiquidToggle](https://github.com/Kyant0/AndroidLiquidGlass/blob/kmp/app/src/commonMain/kotlin/com/kyant/backdrop/catalog/components/LiquidToggle.kt), [LiquidSlider](https://github.com/Kyant0/AndroidLiquidGlass/blob/kmp/app/src/commonMain/kotlin/com/kyant/backdrop/catalog/components/LiquidSlider.kt), [LiquidBottomTabs](https://github.com/Kyant0/AndroidLiquidGlass/blob/kmp/app/src/commonMain/kotlin/com/kyant/backdrop/catalog/components/LiquidBottomTabs.kt) |

**Core model:** `rememberLayerBackdrop()` records the background → apply `Modifier.layerBackdrop(backdrop)` to the content → `Modifier.drawBackdrop(backdrop, shape, effects, highlight, shadow, innerShadow, layerBlock, onDrawSurface)` on the glass element.

**Effect order is mandatory:** color filter (`vibrancy()` = saturation ×1.5, `colorControls`, `opacity`, `exposureAdjustment`) **⇒** `blur(radius)` **⇒** `lens(refractionHeight, refractionAmount, depthEffect, chromaticAberration)`.
- `lens` requires a `CornerBasedShape` (e.g. `CircleShape`, `RoundedCornerShape`, `Capsule()` from `com.kyant.shapes`).
- `refractionHeight` ∈ [0, shape.minCornerRadius]; `refractionAmount` ∈ [0, size.minDimension].
- Readability: always add `onDrawSurface = { drawRect(Color.White.copy(alpha = 0.5f)) }` (light) or a dark equivalent.
- Tinted glass: `drawRect(tint, blendMode = BlendMode.Hue)` + `drawRect(tint.copy(alpha = 0.75f))`.
- Paint the background into the backdrop (`rememberLayerBackdrop { drawRect(bg); drawContent() }`) or transparent pixels appear.

**LiquidBottomTabs tokens (from source):**

| Token | Value |
|---|---|
| Bar | Capsule, **64 dp** tall, padding 4, `fillMaxWidth` |
| Effects | `vibrancy(); blur(8.dp); lens(24.dp, 24.dp)` |
| Container | light `#FAFAFA` @ 40% · dark `#121212` @ 40% |
| Accent (selected) | light `#0088FF` · dark `#0091FF` (applied as a `ColorFilter.tint` on a duplicate row, revealed through the indicator) |
| Indicator | tab width = (maxWidth − 8 dp) / count; **draggable** (`DampedDragAnimation`), pressed scale **78/56** (≈1.39), lens(10 dp, 14 dp) × press, highlight alpha = press |
| Press | the whole bar scales by +16 dp / width; content scale 1 → **1.2** |
| Rubber band | panel offset ±4 dp with EaseOut; spring(1f, 300f, 0.5f) back |

**Glass playground parameters (catalog):** Corner radius · Blur radius · Refraction height · Refraction amount · Chromatic aberration.

**Web port (`src/backdrop.jsx`):** `<LiquidBottomTabs count sel onSel/>` (tap or drag the indicator; it stretches and magnifies on press), `BdPlayground` (5 sliders + draggable glass square), `BdControls` (toggle, slider, tinted buttons). Glass class `.bdg` = `rgba(250,250,250,.4)` + `blur(8px) saturate(1.5)` + inner white glow + top specular.


---

## 18. iOS 26 Liquid Glass Effect — Figma kit (project 07)

| | |
|---|---|
| **Name** | iOS 26 Liquid Glass Effect |
| **Author** | Jan Decker ([@jandecker1](https://www.figma.com/@jandecker1)) |
| **Source** | https://www.figma.com/community/file/1514186232748375562/ios-26-liquid-glass-effect |
| **What it is** | A Figma Community file: a realistic Liquid Glass *material* plus liquid-glass UI components in editable auto-layout frames. Cover shot: a dark-glass capsule "Button primary" with a white icon disc, over a misty forest photo |
| **Licence** | Free Figma Community file. The web port here is original code; wallpapers in `assets/` are public-domain photos |
| **Web port** | `src/figma-glass.css` (all styles) · `src/figma-glass.jsx` (primitive, components, 3 phones, playground) · tokens in `tokens.json › 07_figma_liquid_glass` |
| **Fidelity note** | The Community page cannot be read by tools, so the port follows the cover image and the kit's layer model. To match exact frame values, duplicate the file and give the agent a `figma.com/design/<key>` link, then update `tokens.json` |

### 18.1 The material: one primitive, four layers
Everything in 07 is built from `<LGlass>`. It renders four absolutely-positioned layers under its content, in this order, the same stack as the Figma layer panel:

| # | Layer (class) | What it does | Variable(s) |
|---|---|---|---|
| 1 | **Effect** `.lg-fx` | `backdrop-filter: blur() saturate() brightness()`, plus an optional SVG displacement for refraction | `--lg-blur` `--lg-sat` `--lg-bright` |
| 2 | **Tint** `.lg-tint` | Flat fill. Dark tone `rgba(26,32,28,a)`, light tone `rgba(255,255,255,a)`, tinted = `color-mix(accent a%)` | `--lg-tint` |
| 3 | **Shine** `.lg-shine` | Inner light: top-left specular (inset 1.5px 1.5px 1px −1px), bottom-right bounce (inset −1px −1px), soft inner glow 14px | `--lg-shine` |
| 4 | **Rim** `.lg-rim` | 1px **gradient** stroke masked to a ring. Bright at the top-left and bottom-right corners, faint in between | `--lg-rim` `--lg-angle` |
| 5 | Drop shadow | On the element itself: `0 6px 22px rgba(0,0,0,shadow)` | `--lg-shadow` |

Shape = `--lg-radius` (default `999px` = capsule; pass `radius={28}` for cards). **Interactive** (`interactive` prop, like SwiftUI `.interactive()`): press → scale 1.05, shine 1, brightness 1.18.

### 18.2 Material presets
| Preset | Blur | Sat | Bright | Tint α | Shine | Rim | Shadow | Use |
|---|---|---|---|---|---|---|---|---|
| **Regular** (default) | 10 | 1.5 | 1.05 | 0.28 | 0.75 | 0.60 | 0.25 | Most controls: the Figma cover look |
| **Clear** | 2 | 1.8 | 1.08 | 0.05 | 0.90 | 0.75 | 0.20 | Over media (photos, video). Needs a dimming layer for legibility |
| **Tinted** | 10 | 1.5 | 1.05 | 0.48 (accent) | 0.75 | 0.60 | 0.25 | Primary actions, brand colour |
| **Frosted** | 24 | 1.3 | 1.10 | 0.36 | 0.60 | 0.50 | 0.20 | Busy backgrounds, long labels |

**Tones:** dark (`fg #fff`, `fg-2 white 70%`) and light (`fg #111`, `fg-2 black 58%`). **Accents:** `#0A84FF` · `#30D158` · `#FF9F0A` · `#BF5AF2`.
**Refraction:** off · soft (`feTurbulence 0.009/0.012`, scale 14) · strong (0.006/0.009, scale 38). Chromium only; other browsers show blur only.
**Reduce Transparency** (`.rt` on an ancestor) turns off the Effect layer and makes the tint opaque `--lg-solid`.

### 18.3 Components (props → metrics)
| Component | JSX | Metrics (pt) |
|---|---|---|
| Button | `<LGButton icon="location.fill" prominent>Label</LGButton>` | 56 tall capsule; left pad 9, right 26; **white 38 disc** with the icon; gap 14; 19/600. `prominent` = accent tint 72% |
| Icon button | `<LGIconButton icon="ellipsis" size={44} iconSize={20} label/>` | Circle, 44 default (40 / 56 / 62 / 88 used) |
| Search field | `<LGSearch placeholder value onChange/>` | 48 capsule, pad 16, magnifier 18, text 17 |
| Segmented | `<LGSegmented options value onChange/>` | 40 capsule, pad 3, sliding **glass lens** (`--lg-lens` + inner highlights), 14/600 |
| Card / grouped list | `<LGlass radius={28} className="lg-card">` + `.lg-row` | Radius 28, pad-x 16, rows 54 (62 with a slider), 30pt rounded-8 icon tiles, 0.5 separators |
| Toggle | `<LGToggle on onChange label/>` | 64×28 track, **38×24 pill thumb**; on = `#34C759`; while pressed the thumb grows ×1.35 and turns to clear glass |
| Slider | `<LGSlider value onChange min max left right thin/>` | 6 track, 38×24 pill thumb that turns to glass on drag. `thin` = 5 → 9 track, no thumb (media scrubber) |
| Tab bar | `<LGTabBar tabs sel onSel onSearch/>` | 62 capsule (pad 4, sliding lens) + **separate 62 search circle**, gap 10; icon 23, label 10/600; selected = accent. Place 16/16/22 |
| Menu | `<LGMenu items={[[t, icon, destructive?], '-']} onPick style/>` | Radius 22, pad 6, rows 44 (radius 14), min width 230, pop animation |
| Toast | `useToast()` → `[el, show(msg)]` | 40 capsule dropping from y 60 with a spring |
| Notification | `LGHomePhone` | Radius 24; 38 icon (radius 9); tap to expand, glass action buttons 34 tall |
| Widget | `.lg-wd` | Radius 24, 170 tall, 2-column grid, gap 13 |
| App icon / dock | `.lg-app` / `.lg-dock` | 62 icon, radius 16 · dock 92 tall, radius 36, inset 14, bottom 18 |
| Now-playing panel | `LGPlayerPhone` | Radius 34, inset 16, bottom 34, pad 22; thin scrubber; 64 transport targets; volume slider |

Icons: `<LgI n="…"/>` uses SF-Symbol names (`LGI` map in `figma-glass.jsx`, falling back to `SF` in `icons.jsx`). In native apps, use the real SF Symbol with the same name.

### 18.4 Demo phones + playground
1. **Home Screen**: forest wallpaper, expandable notification, weather and calendar widgets, 8 glass app icons, "Search" pill, glass dock.
2. **Controls**: back / more (opens the menu), large title, search, segmented, **Button primary** + compose circle, a grouped card with 3 toggles and a brightness slider, tab bar + search circle.
3. **Now Playing**: flower wallpaper, artwork, a glass panel with favourite/more, a live scrubber, transport, volume, lyrics / AirPlay / queue.
4. **Playground**: drag a glass button, circle or card over 3 wallpapers; tune 7 sliders, tone, accent and refraction; **export** the result as CSS, React, SwiftUI or Compose code.
The section toolbar (Material · Tone · Accent · Refraction) and the playground share **one state**. It is saved in `localStorage['lg07']` and restyles all three phones live.

### 18.5 Mapping to native
| Web | SwiftUI (iOS 26) | Compose (Backdrop) |
|---|---|---|
| Regular | `.glassEffect(.regular, in: .capsule)` | `blur(10.dp)` + `colorControls(saturation 1.5)` + surface tint 28% |
| Clear | `.glassEffect(.clear)` | `blur(2.dp)` + `lens()` |
| Tinted | `.glassEffect(.regular.tint(accent))` / `.buttonStyle(.glassProminent)` | surface `drawRect(accent, BlendMode.Hue)` + `accent@α` |
| interactive | `.glassEffect(.regular.interactive())` | press animation (LiquidButton) |
| Several glass shapes that touch | `GlassEffectContainer(spacing:)` | one `drawBackdrop` per shape |
| Refraction | built in | `lens(refractionHeight, refractionAmount)` |


---

## 19. Apple Design Workbench (section 08, `workbench/`)

A separate single-page tool built from the Apple Design Agent Pack (`workbench/pack/`, `workbench/data/sources.json`). Its own look: Apple-like neutral UI (`#F5F5F7` bg, `#0071E3` accent, Vazirmatn + system-ui), RTL by default. Docs: `workbench/README.md`. Agent skill: `workbench/AGENT_SKILL.md`. Tests: `workbench/TEST_REPORT.md`. It does not reuse the tab-bar CSS. It links back to sections 01–07 as internal references.
