feat: complete release preparation, 10+ ad mediation, CI/CD, and docker deployment
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped

This commit is contained in:
Yun Chan 2026-08-20 11:12:05 +09:00
parent 5cd1de6859
commit 708e20f747
406 changed files with 42464 additions and 6199 deletions

View file

@ -1,47 +1,121 @@
'use client'
// src/renderer/components/ds/PhysicalButton.tsx
// v2 "Midnight Glass": 글래스 버튼 — 기본은 반투명 표면 + 헤어라인,
// selected 시 액센트 그라디언트 + 글로우 (레퍼런스 프라이머리 버튼)
// packages/ui/src/components/ds/PhysicalButton.tsx
// High-End Tactile Button with Button-in-Button Trailing Icon & Spring Physics
import { Button, type ButtonProps } from '@mui/material'
import React from 'react'
import { Button, Box, type ButtonProps } from '@mui/material'
import { d3roPalette, d3roFontSans, d3roShadow, d3roRadius, d3roTypo } from '../../theme'
interface PhysicalButtonProps extends Omit<ButtonProps, 'variant'> {
export interface PhysicalButtonProps extends Omit<ButtonProps, 'variant'> {
/** Active selected state (renders primary accent gradient) */
selected?: boolean
/** Visual button tone */
tone?: 'accent' | 'glass' | 'danger' | 'success' | 'ghost'
/** Trailing icon rendered in a nested circular capsule (Button-in-Button pattern) */
trailingIcon?: React.ReactNode
}
export function PhysicalButton({ selected = false, sx, ...props }: PhysicalButtonProps): React.ReactElement {
export function PhysicalButton({
selected = false,
tone = 'glass',
trailingIcon,
children,
sx,
...props
}: PhysicalButtonProps): React.ReactElement {
const isAccent = selected || tone === 'accent'
const isDanger = tone === 'danger'
const isSuccess = tone === 'success'
let bg: string = d3roPalette.glass.raised
let bgImage: string = 'none'
let textColor: string = d3roPalette.text.primary
let borderColor: string = d3roPalette.glass.hairline
let shadow: string = 'none'
if (isAccent) {
bg = 'transparent'
bgImage = d3roPalette.gradient.accent
textColor = d3roPalette.text.inverse
borderColor = 'transparent'
shadow = d3roShadow.glowAccent
} else if (isDanger) {
bg = d3roPalette.tag.redBg
textColor = d3roPalette.tag.red
borderColor = d3roPalette.tag.redGlow
} else if (isSuccess) {
bg = d3roPalette.tag.greenBg
textColor = d3roPalette.tag.green
borderColor = d3roPalette.tag.greenGlow
}
return (
<Button
{...props}
sx={{
height: 42,
bgcolor: selected ? 'transparent' : d3roPalette.glass.raised,
backgroundImage: selected ? d3roPalette.gradient.accent : 'none',
border: `1px solid ${selected ? 'transparent' : d3roPalette.glass.hairline}`,
height: 40,
px: trailingIcon ? 2 : 2.5,
bgcolor: bg,
backgroundImage: bgImage,
border: `1px solid ${borderColor}`,
borderRadius: d3roRadius.button,
color: selected ? '#fff' : d3roPalette.text.secondary,
color: textColor,
fontFamily: d3roFontSans,
fontSize: d3roTypo.small.size,
fontSize: d3roTypo.compact.size,
fontWeight: 600,
cursor: 'pointer',
boxShadow: selected ? d3roShadow.glowAccent : 'none',
transition: 'filter 0.15s ease, border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease',
'&:active': {
filter: 'brightness(0.92)',
},
'&:hover': {
bgcolor: selected ? 'transparent' : d3roPalette.bg.cardHover,
borderColor: selected ? 'transparent' : d3roPalette.glass.hairlineStrong,
color: selected ? '#fff' : d3roPalette.text.primary,
filter: selected ? 'brightness(1.08)' : 'none',
},
boxShadow: shadow,
textTransform: 'none',
letterSpacing: d3roTypo.small.spacing,
letterSpacing: '0.01em',
minWidth: 0,
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
gap: 1.25,
transition: 'all 0.2s cubic-bezier(0.16, 1, 0.3, 1)',
'&:hover': {
bgcolor: isAccent ? undefined : d3roPalette.bg.cardHover,
borderColor: isAccent ? 'transparent' : d3roPalette.glass.hairlineStrong,
color: isAccent ? d3roPalette.text.inverse : d3roPalette.text.primary,
filter: isAccent ? 'brightness(1.08)' : 'none',
boxShadow: isAccent ? d3roShadow.glowAccent : d3roShadow.card,
transform: 'translateY(-1px)',
'& .d3-button-trailing-icon': {
transform: 'translateX(2px)',
},
},
'&:active': {
transform: 'translateY(0) scale(0.98)',
filter: 'brightness(0.95)',
},
...sx,
}}
/>
>
<Box component="span" sx={{ display: 'inline-flex', alignItems: 'center', gap: 1 }}>
{children}
</Box>
{trailingIcon && (
<Box
className="d3-button-trailing-icon"
sx={{
width: 24,
height: 24,
borderRadius: '50%',
bgcolor: isAccent ? 'rgba(255, 255, 255, 0.18)' : d3roPalette.bg.inset,
border: `1px solid ${isAccent ? 'rgba(255, 255, 255, 0.2)' : d3roPalette.border.subtle}`,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: isAccent ? d3roPalette.text.inverse : d3roPalette.text.secondary,
transition: 'transform 0.2s ease',
flexShrink: 0,
'& svg': { width: 14, height: 14 },
}}
>
{trailingIcon}
</Box>
)}
</Button>
)
}