Files
SheetMe/src/SheetMe.Designer/Themes/DesignerTheme.xaml
T
MsystechandClaude Opus 5 b47c7af8df 레이어 행 이름 잘림 해소 + 라이트 선택색을 연한 파랑으로
이름이 잘려 행을 구분할 수 없었다
  눈·자물쇠가 48px 를 상시 차지해 이름 칸이 한글 11자로 줄었다. 운영 서식에는
  '입원일 복용약-전립선약' 처럼 앞이 같고 끝에서 갈리는 이름이 흔해 전부
  '입원일 복용약-…' 로 잘렸다 — 목록만 보고는 어느 행인지 알 수 없었다.
  두 토글을 평소엔 숨기고 마우스를 올린 행에서만 띄운다. 잠김·숨김이 켜진 행에서는
  계속 띄운다(거기서까지 숨기면 마우스를 올리기 전에는 상태를 알 방법이 없다).
  [200] 은 항상 띄우지만 여기서만 갈라선다 — 폭이 곧 가독성이라서.

라이트 모드 선택 밴드가 너무 무거웠다
  양 테마 모두 짙은 파랑(#0F6FBF)에 흰 글자를 쓰다 보니, 흰 배경에 짙은 슬라브가
  얹혀 선택 몇 줄이 패널 전체를 짓눌렀다. 라이트만 방향을 뒤집는다 —
  연한 채움(#A8D3F7, 흰 패널 대비 1.58:1) + 진한 글자(10.1:1).
  서브트리도 한 단계 옅게(#DCEBFB) 해서 '폴더가 주인, 멤버는 딸림'이 색 세기로 읽힌다.
  밴드 위 글자색을 B.OnAccent(흰색 고정)에서 신설 토큰 B.OnLayerSel 로 바꿔
  테마별로 갈라지게 했다(다크 흰색 / 라이트 #222222). 보조 텍스트도 라이트만
  #35536C 로(연한 채움 위 5.12:1 — 기존 #E6F1FB 는 라이트에서 사라진다).

회귀: 테스트 124/124, 편집 스모크 실패 0(레이어 검사 45건), DB 왕복 1,271건
diff 0/예외 0, 종이 렌더 P062 바이트 동일.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 18:19:59 +09:00

1245 lines
76 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"
xmlns:ctl="clr-namespace:SheetMe.Designer.Controls">
<!-- ============================================================
디자이너 공유 테마 (암시 스타일 + 컨트롤 템플릿)
· 색상은 {DynamicResource B.*} 로 참조 → 토큰 dict(Tokens.Dark/Light.xaml) 교체로 라이트/다크 전환
· MainWindow.Resources 에 [이 파일 + 토큰 dict] 머지(토큰 dict 만 스왑)
· 스타일 키(Subtle/CaptionBtn/B.ComboItem/ScrollThumb…)는 StaticResource 유지
============================================================ -->
<!-- ===== 창 공통(다이얼로그 배경/폰트 — 로컬 지정이 있으면 로컬 우선) =====
FontSize/Foreground 가 없으면 대화상자들이 WPF 기본 12px + 시스템 검정으로 렌더돼
메인 셸(13px)과 결이 어긋난다. 토큰 참조는 DynamicResource 로 둬야 테마 전환에 따라간다. -->
<!--
⚠ 창에는 **반드시 Style="{StaticResource ThemedWindow}" 를 직접 걸어야 한다.**
WPF 는 암시 스타일을 요소의 '정확한 런타임 타입'으로만 찾는다. 모든 대화상자가
Window 를 **상속한** 클래스(SheetOpenDialogView : Window 등)라 아래 암시 스타일은
이들에게 단 한 번도 적용된 적이 없었다 — 진단(dialog-shots)이 창 8종 전부
배경=#FFFFFFFF / Style=null 로 보고했다. 결과적으로 다크 테마에서 흰 창 위에
B.Ink(#EDEDED) 글자가 얹혀 대화상자 내용이 통째로 보이지 않았다.
(TextBlock·TextBox 등은 정확한 타입이라 암시 스타일이 정상 적용돼, 창 배경만
WPF 기본 흰색으로 남는 형태로 드러났다.)
-->
<Style x:Key="ThemedWindow" TargetType="Window">
<Setter Property="Background" Value="{DynamicResource B.AppBg}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="13" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
</Style>
<!-- 순수 Window 인스턴스용(파생 클래스에는 위 키 스타일을 직접 걸어야 한다) -->
<Style TargetType="Window" BasedOn="{StaticResource ThemedWindow}" />
<!-- ===== 타이포 ===== -->
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
</Style>
<!-- ===== 버튼 (기본: 은은한 다크 채움) ===== -->
<Style TargetType="Button">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="Background" Value="{DynamicResource B.Input}" />
<Setter Property="BorderBrush" Value="{DynamicResource B.Line}" />
<Setter Property="Padding" Value="10,5" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" CornerRadius="5" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ButtonBase}}" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.BtnHover}" />
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource B.Line2}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.BtnPressed}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="bd" Property="Opacity" Value="0.45" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- 강조 버튼 -->
<Style x:Key="Primary" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<!-- 흰 글자를 얹는 채움이라 브랜드색(#0099FF, 흰 글자 대비 3.0:1)이 아니라 짙은 강조 토큰을 쓴다 -->
<Setter Property="Background" Value="{DynamicResource B.AccentFill}" />
<Setter Property="Foreground" Value="{DynamicResource B.OnAccent}" />
<Setter Property="BorderBrush" Value="{DynamicResource B.AccentFill}" />
</Style>
<!-- 텍스트형(테두리 없는) 버튼 — 툴바 아이콘/네비 -->
<Style x:Key="Subtle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource B.Muted}" />
</Style>
<!-- ===== 텍스트박스 ===== -->
<!-- Framer 식 입력칩: 채움만(평소 테두리 없음)·라운드8·높이30·세로 가운데 -->
<Style TargetType="TextBox">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="BorderBrush" Value="{DynamicResource B.InputBorder}" />
<Setter Property="Background" Value="{DynamicResource B.Input}" />
<Setter Property="Padding" Value="4,0" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="CaretBrush" Value="{DynamicResource B.Accent}" />
<Setter Property="SelectionBrush" Value="{DynamicResource B.Accent}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" CornerRadius="8" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Margin="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource B.Line2}" />
</Trigger>
<!-- 포커스는 호버와 같은 색이면 안 된다 — 어디에 입력되는지가 유일한 단서인데
B.Line2 는 입력칩 배경과 1.3~1.4:1 이라 포커스 위치를 알 수 없었다 -->
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource B.Accent}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<!--
여러 줄 입력은 위에서부터 흘러야 한다. 종전에는 템플릿 트리거가 ScrollViewer 의
VerticalContentAlignment 만 Stretch 로 바꿨는데, 텍스트를 배치하는 것은 TextBox 자신의
VerticalContentAlignment 이라 아무 효과가 없었다 — 쿼리 편집기에서 SQL 이 큰 상자
한가운데 떠 있었다(dialog-shots 진단으로 확인).
-->
<Trigger Property="AcceptsReturn" Value="True">
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="Padding" Value="6,5" />
</Trigger>
</Style.Triggers>
</Style>
<!--
칩 안에 얹는 입력 — 자기 테두리·채움을 그리지 않는다.
전역 TextBox 템플릿은 <c>BorderThickness="1"</c> 이 하드코딩돼 있어 인스턴스에서
BorderThickness=0 을 줘도 무시된다. 그대로 두면 검색칩 안에 <b>둥근 상자가 하나 더</b> 그려져
상자 속 상자가 된다. 포커스 표시는 칩 쪽에서 준다(IsKeyboardFocusWithin).
-->
<Style x:Key="ChipTextBox" TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="MinHeight" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="0,0,6,0" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<ScrollViewer x:Name="PART_ContentHost" Margin="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Framer 식 슬라이더(불투명도 등): 얇은 트랙 + 흰 원형 썸 -->
<Style TargetType="Slider">
<Setter Property="MinHeight" Value="20" />
<Setter Property="IsMoveToPointEnabled" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Slider">
<Grid VerticalAlignment="Center">
<Border Height="4" CornerRadius="2" Background="{DynamicResource B.Chip}" VerticalAlignment="Center" />
<Track x:Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton Command="Slider.DecreaseLarge" Focusable="False">
<RepeatButton.Template>
<ControlTemplate TargetType="RepeatButton">
<Border Height="4" CornerRadius="2" Background="{DynamicResource B.Accent}" VerticalAlignment="Center" />
</ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="Slider.IncreaseLarge" Focusable="False">
<RepeatButton.Template>
<ControlTemplate TargetType="RepeatButton"><Border Background="Transparent" /></ControlTemplate>
</RepeatButton.Template>
</RepeatButton>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb>
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Ellipse Width="13" Height="13" Fill="White" Stroke="{DynamicResource B.SliderRing}" StrokeThickness="1" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 리스트 ===== -->
<Style TargetType="ListBox">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
</Style>
<Style TargetType="ListBoxItem">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="Padding" Value="6,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="bd" Background="Transparent" CornerRadius="5" Padding="{TemplateBinding Padding}" Margin="2,1">
<!-- string Content 가 앱 라이트 TextBlock 스타일(어두운색)로 떨어지지 않게 밝은색 지역 지정(ComboBoxItem 과 동일 패턴) -->
<ContentPresenter TextElement.Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter.Resources>
<Style TargetType="TextBlock"><Setter Property="Foreground" Value="{DynamicResource B.Ink}" /></Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Hover}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Sel}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- =====================================================================
ListView / GridView — 반드시 필요하다.
ListView·ListViewItem·GridViewColumnHeader 는 각자 DefaultStyleKey 를 자기 타입으로
재정의하므로 위의 ListBox·ListBoxItem 암시 스타일을 <b>물려받지 못한다</b>. 스타일이 없으면
WPF 기본(Aero2)의 흰 시스템 크롬으로 떨어지는데, 그 안의 글자는 앱 전역 암시 TextBlock
스타일(B.Ink)을 받는다 → 다크에서 흰 바탕에 흰 글자(1.0~1.2:1)로 목록이 통째로 사라진다.
실제 피해 화면: DB에서 서식 열기, 서식 수정이력.
===================================================================== -->
<Style TargetType="ListView" BasedOn="{StaticResource {x:Type ListBox}}" />
<!--
행 템플릿은 반드시 GridViewRowPresenter 를 써야 한다.
ListBoxItem 스타일을 그대로 물려주면(BasedOn) 그 안의 ContentPresenter 템플릿이 GridView 의
열 구성을 대체해, 행이 열 대신 바인딩 객체의 ToString() 한 줄로 렌더된다
(SheetSummary { ShtCod = C020, Name = … } 이 그대로 노출된다).
저장소의 ListView 는 둘 다 GridView 를 쓴다(DB에서 서식 열기 · 서식 수정이력).
-->
<Style TargetType="ListViewItem">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="Padding" Value="2,4" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="bd" Background="Transparent" Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}"
VerticalAlignment="Center">
<GridViewRowPresenter.Resources>
<Style TargetType="TextBlock"><Setter Property="Foreground" Value="{DynamicResource B.Ink}" /></Style>
</GridViewRowPresenter.Resources>
</GridViewRowPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Hover}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Sel}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Foreground" Value="{DynamicResource B.Muted}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="Padding" Value="8,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Border x:Name="bd" Background="{DynamicResource B.PanelHeader}"
BorderBrush="{DynamicResource B.Line}" BorderThickness="0,0,1,1">
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock"><Setter Property="Foreground" Value="{DynamicResource B.Muted}" /></Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Hover}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- =====================================================================
ToolBar / ToolBarTray — 같은 이유. 스타일이 없으면 다크 창 위에 WPF 기본 밝은 회색 띠가
그대로 박히고, 그 안의 글자는 B.Ink 라 배율 표시 등이 사라진다(미리보기 창).
===================================================================== -->
<Style TargetType="ToolBarTray">
<Setter Property="Background" Value="{DynamicResource B.PanelHeader}" />
</Style>
<Style TargetType="ToolBar">
<Setter Property="Background" Value="{DynamicResource B.PanelHeader}" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolBar">
<Border Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource B.Line}" BorderThickness="0,0,0,1" Padding="6,4">
<ToolBarPanel IsItemsHost="True" Orientation="Horizontal" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- =====================================================================
ToolTip — 저장소 48곳에서 쓰는데 스타일이 없었다.
스타일이 없으면 Aero2 기본 밝은 팝업으로 떨어지고, 내부 문자열이 만든 TextBlock 은
앱 전역 암시 스타일(B.Ink)을 받아 **다크에서 1.15:1 로 글자가 사라진다**.
(ListView·Window 와 정확히 같은 부류의 결함이다.)
===================================================================== -->
<Style TargetType="ToolTip">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="Background" Value="{DynamicResource B.Surface}" />
<Setter Property="BorderBrush" Value="{DynamicResource B.Line2}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12" />
<Setter Property="MaxWidth" Value="420" />
<Setter Property="HasDropShadow" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" CornerRadius="6" Padding="9,6" SnapsToDevicePixels="True">
<ContentPresenter>
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--
ToolBar 는 직계 자식에 SetResourceReference 로 자기 키 스타일을 꽂아 암시 Button 스타일을
이긴다 — 이 키들을 채워주지 않으면 툴바 안 버튼만 Aero2 로 남는다(미리보기 창).
-->
<Style x:Key="{x:Static ToolBar.ButtonStyleKey}" TargetType="Button" BasedOn="{StaticResource Subtle}" />
<Style x:Key="{x:Static ToolBar.ToggleButtonStyleKey}" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}" />
<Style x:Key="{x:Static ToolBar.SeparatorStyleKey}" TargetType="Separator" BasedOn="{StaticResource {x:Type Separator}}" />
<Style x:Key="{x:Static ToolBar.TextBoxStyleKey}" TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}" />
<!--
키보드 포커스 표시. Aero2 기본은 검정 점선이라 다크 버튼 채움(#262626) 위에서 1.39:1 이고,
커스텀 Button 템플릿에 IsKeyboardFocused 트리거도 없어 Tab 위치를 알 단서가 전혀 없었다.
-->
<Style x:Key="{x:Static SystemParameters.FocusVisualStyleKey}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="-2" StrokeThickness="1.4" RadiusX="6" RadiusY="6"
Stroke="{DynamicResource B.Accent}" StrokeDashArray="2 2" SnapsToDevicePixels="True" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 콤보박스 ===== -->
<Style x:Key="B.ComboItem" TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="Padding" Value="8,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border x:Name="bd" Background="Transparent" CornerRadius="4" Padding="{TemplateBinding Padding}" Margin="2,1">
<!-- 생성되는 글자 TextBlock 이 앱 라이트 TextBlock 스타일(어두운색)로 떨어지지 않게, 여기서 밝은색 스타일을 지역 지정 -->
<ContentPresenter>
<ContentPresenter.Resources>
<Style TargetType="TextBlock"><Setter Property="Foreground" Value="{DynamicResource B.Ink}" /></Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Hover}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Sel}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- 전역 암시 콤보 항목(드롭다운 밖 용도 대비) — 키 스타일 상속 -->
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource B.ComboItem}" />
<Style TargetType="ComboBox">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="Background" Value="{DynamicResource B.Input}" />
<Setter Property="BorderBrush" Value="{DynamicResource B.Line}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="Height" Value="30" />
<!-- 드롭다운 항목 스타일을 컨테이너에 직접 지정(생성기가 적용 → 앱 라이트 ComboBoxItem 누수보다 우선) -->
<Setter Property="ItemContainerStyle" Value="{StaticResource B.ComboItem}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Focusable="False" ClickMode="Press"
IsChecked="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="bd" Background="{DynamicResource B.Input}" BorderBrush="{DynamicResource B.InputBorder}"
BorderThickness="1" CornerRadius="8" SnapsToDevicePixels="True">
<Path x:Name="arr" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,9,0"
Data="M0,0 L4,4 L8,0" Stroke="{DynamicResource B.Muted}" StrokeThickness="1.4"
StrokeStartLineCap="Round" StrokeEndLineCap="Round" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource B.Line2}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter x:Name="cp" Margin="9,0,26,0" VerticalAlignment="Center" HorizontalAlignment="Left"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
TextElement.Foreground="{DynamicResource B.Ink}"
IsHitTestVisible="False">
<!-- 닫힌 표시 텍스트(SelectionBoxItem)가 앱 라이트 TextBlock 스타일(어두운색)로 떨어지지 않게 스코프 지정 -->
<ContentPresenter.Resources>
<Style TargetType="TextBlock"><Setter Property="Foreground" Value="{DynamicResource B.Ink}" /></Style>
</ContentPresenter.Resources>
</ContentPresenter>
<!-- 편집 가능 콤보(글꼴·형식 등)의 입력/표시 텍스트 -->
<TextBox x:Name="PART_EditableTextBox" Margin="8,0,26,0" VerticalAlignment="Center"
Foreground="{DynamicResource B.Ink}" CaretBrush="{DynamicResource B.Accent}"
Background="Transparent" Visibility="Collapsed" IsReadOnly="{TemplateBinding IsReadOnly}">
<TextBox.Template>
<ControlTemplate TargetType="TextBox">
<ScrollViewer x:Name="PART_ContentHost" Focusable="False"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" />
</ControlTemplate>
</TextBox.Template>
</TextBox>
<!-- HorizontalOffset(-10)+좌우 Margin(10): 그림자 여백 확보하면서 드롭다운을 콤보 좌측에 정렬 -->
<Popup IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" AllowsTransparency="True"
Focusable="False" PopupAnimation="Fade" HorizontalOffset="-10">
<Border Background="{DynamicResource B.Surface}" BorderBrush="{DynamicResource B.Line}" BorderThickness="1"
CornerRadius="5" Margin="10,3,10,12" Padding="2"
MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}">
<Border.Effect>
<DynamicResource ResourceKey="B.FloatShadow"/>
</Border.Effect>
<!-- 드롭다운(별도 팝업)이 앱 라이트 ComboBoxItem 으로 새지 않게, 팝업 안에 다크 항목 스타일을 지역 지정 -->
<Border.Resources>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource B.ComboItem}" />
</Border.Resources>
<ScrollViewer MaxHeight="260"><ItemsPresenter /></ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEditable" Value="True">
<Setter TargetName="cp" Property="Visibility" Value="Collapsed" />
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</Style.Triggers>
</Style>
<!-- ===== 탭 (좌측 패널) ===== -->
<Style TargetType="TabControl">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabControl">
<DockPanel>
<!-- 세그먼트(알약) 탭 바 — FlutterFlow 식: 둥근 컨테이너 안에 알약 탭 -->
<Border DockPanel.Dock="Top" Background="{DynamicResource B.Panel}" BorderBrush="{DynamicResource B.Line}" BorderThickness="0,0,0,1" Padding="8">
<Border Background="{DynamicResource B.Chip}" CornerRadius="9" Padding="3">
<UniformGrid Rows="1" IsItemsHost="True" />
</Border>
</Border>
<ContentPresenter ContentSource="SelectedContent" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TabItem">
<Setter Property="Foreground" Value="{DynamicResource B.Muted}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border x:Name="bd" Background="Transparent" CornerRadius="6" Margin="2,0" Padding="6,6">
<ContentPresenter ContentSource="Header" HorizontalAlignment="Center" VerticalAlignment="Center"
TextElement.Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.TabHover}" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.TabSel}" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 문서 탭 (중앙 상단 — 크롬식: 라운드 상단, 활성=Surface+테두리) ===== -->
<Style x:Key="DocTabs" TargetType="TabControl">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabControl">
<DockPanel>
<Border DockPanel.Dock="Top" Background="{DynamicResource B.Titlebar}"
BorderBrush="{DynamicResource B.Line}" BorderThickness="0,0,0,1" Padding="8,5,8,0">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom">
<StackPanel Orientation="Horizontal" IsItemsHost="True" />
<!-- 새 서식 탭(+) — 탭 흐름 바로 옆([200] 문서탭 관행) -->
<Button Content="" Command="{Binding NewFileCommand}" Style="{StaticResource Subtle}"
Width="26" Height="24" Padding="0" Margin="2,0,0,3" FontSize="13"
VerticalAlignment="Center" ToolTip="새 서식 탭"/>
</StackPanel>
</ScrollViewer>
</Border>
<ContentPresenter ContentSource="SelectedContent" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DocTabItem" TargetType="TabItem">
<Setter Property="Foreground" Value="{DynamicResource B.Muted}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<!-- 비활성 탭은 사면 테두리, 활성 탭만 하단을 끊어 본문과 이어지게 한다(크롬식 룩) -->
<Border x:Name="bd" CornerRadius="6,6,0,0" Padding="11,5,6,6" Margin="0,0,3,0"
Background="Transparent" BorderBrush="Transparent" BorderThickness="1"
SnapsToDevicePixels="True">
<ContentPresenter ContentSource="Header" VerticalAlignment="Center"
TextElement.Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.TabHover}" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Surface}" />
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource B.Line}" />
<Setter TargetName="bd" Property="BorderThickness" Value="1,1,1,0" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontWeight" Value="SemiBold" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- 좌측 탭 헤더 텍스트 — 미선택=Muted, 선택=Ink+Bold(알약 위 밝은 글씨). 템플릿 색 상속 불안정 우회 -->
<Style x:Key="TabHeaderText" TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource B.Muted}" />
<Setter Property="FontSize" Value="12" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TabItem}}" Value="True">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontWeight" Value="Bold" />
</DataTrigger>
</Style.Triggers>
</Style>
<!-- ===== 토글 버튼 ===== -->
<Style TargetType="ToggleButton">
<Setter Property="Foreground" Value="{DynamicResource B.Muted}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Padding" Value="6,4" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" CornerRadius="5" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ButtonBase}}" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Hover}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Sel}" />
<Setter Property="Foreground" Value="{DynamicResource B.Accent}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="bd" Property="Opacity" Value="0.45" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- 플로팅 바 도구 토글(선택/손) — [200] 은 켜짐을 B.Accent2 로 은은하게 채운다.
암시 ToggleButton 스타일(위)은 인스펙터·레이어 토글도 함께 쓰므로 손대지 않고 키 스타일로 분리한다. -->
<Style x:Key="BarToolToggle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Style.Triggers>
<!-- '켜짐'을 채움색 하나로만 알리면 안 된다 — 바 배경 대비 1.14~1.19:1 이라 어느 도구가
활성인지 읽히지 않았다. 강조 테두리를 함께 얹어 채움이 옅어도 상태가 드러나게 한다. -->
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="{DynamicResource B.Accent2}" />
<Setter Property="BorderBrush" Value="{DynamicResource B.Accent}" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
</Trigger>
</Style.Triggers>
</Style>
<!-- 레이어 행의 눈·자물쇠 같은 소형 토글 — 꺼짐은 흐리게, 켜짐만 강조색 -->
<Style x:Key="MiniToggle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Width" Value="24" />
<Setter Property="Height" Value="22" />
<Setter Property="Padding" Value="0" />
<!-- 0.55 는 이미 옅은 B.Muted 를 또 반으로 깎아 라이트 2.22:1 이 된다(아이콘 기준 3:1 미달) -->
<Setter Property="Opacity" Value="0.75" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Opacity" Value="1" />
<Setter Property="Foreground" Value="{DynamicResource B.Accent}" />
</Trigger>
</Style.Triggers>
</Style>
<!--
레이어 목록 전용 행 컨테이너 — [200]SheetMe 아웃라인 룩.
공용 ListBoxItem 스타일을 쓰지 않는 이유가 셋 있다.
① 공용은 Margin 2,1 이 고정이라 위아래 행이 1px 씩 떨어져 '이어진 선택 블록'이 절대 안 만들어진다.
② 배경을 IsSelected 가 아니라 <b>Highlight 3상태</b>가 결정해야 한다 — 그룹 폴더(파랑)와
그 멤버(서브트리 배경)는 색이 다르면서도 하나의 블록이어야 하고, 페이지 행은 선택 자체가 없다.
③ 공용 스타일 안의 지역 TextBlock Foreground 지정은 '다크에서 문자열 Content 가 라이트 색으로
떨어지던 회귀'를 막는 장치라 뺄 수 없는데, 레이어 행은 전부 DataTemplate 이라 그 지역 지정이
오히려 선택 밴드 위 흰 글자를 막는다. 그래서 전용 스타일에서만 뺀다.
-->
<Style x:Key="LayerRowItem" TargetType="ListBoxItem">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="bd" Background="{TemplateBinding Background}" CornerRadius="6"
SnapsToDevicePixels="True">
<ContentPresenter TextElement.Foreground="{TemplateBinding Foreground}" />
</Border>
<ControlTemplate.Triggers>
<!-- 호버는 무강조 행에만. 강조 밴드 위에 회색 호버가 겹치면 밴드가 탁해진다 -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Highlight}" Value="None" />
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Hover}" />
</MultiDataTrigger>
<DataTrigger Binding="{Binding Highlight}" Value="Blue">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.LayerSel}" />
<!-- 흰색 고정이 아니다 — 라이트는 연한 채움이라 진한 글자를 얹는다 -->
<Setter Property="Foreground" Value="{DynamicResource B.OnLayerSel}" />
</DataTrigger>
<DataTrigger Binding="{Binding Highlight}" Value="Navy">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.LayerSubtree}" />
</DataTrigger>
<!-- 연속 강조 행은 맞닿는 모서리를 각지게 하고 1px 겹쳐 하나의 덩어리로 만든다 -->
<DataTrigger Binding="{Binding MergeTop}" Value="True">
<Setter TargetName="bd" Property="CornerRadius" Value="0,0,6,6" />
</DataTrigger>
<DataTrigger Binding="{Binding MergeBottom}" Value="True">
<Setter TargetName="bd" Property="CornerRadius" Value="6,6,0,0" />
<Setter TargetName="bd" Property="Margin" Value="0,0,0,-1" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding MergeTop}" Value="True" />
<Condition Binding="{Binding MergeBottom}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter TargetName="bd" Property="CornerRadius" Value="0" />
<Setter TargetName="bd" Property="Margin" Value="0,0,0,-1" />
</MultiDataTrigger>
<!-- 페이지 행·'페이지 추가' 행은 선택 대상이 아니다(Shift 범위에 끼어들면 안 된다) -->
<DataTrigger Binding="{Binding IsSelectableRow}" Value="False">
<Setter Property="Focusable" Value="False" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--
레이어 행의 눈·자물쇠 — 평소엔 숨기고, 마우스를 올렸거나 상태가 켜진 행에서만 보인다.
항상 띄워 두면 두 토글이 48px 를 상시 차지해 이름 칸이 한글 11자로 줄어든다. 운영 서식에는
'입원일 복용약-전립선약' 처럼 앞부분이 같고 끝에서 갈리는 이름이 흔해서, 그 폭에서는
목록만 보고 행을 구분할 수 없다(전부 '입원일 복용약-…' 로 잘린다).
상태가 켜진 행에서는 계속 띄운다 — 거기서까지 숨기면 마우스를 올리기 전에는
무엇이 잠겼는지 알 방법이 없다.
-->
<Style x:Key="LayerRowToggle" TargetType="ToggleButton" BasedOn="{StaticResource MiniToggle}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding HasLayerFlag}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
<!--
접기/펼치기 셰브론 — 켜짐(=펼침)이 기본 상태라 IsChecked 채움이 들어가면 항상 눌린 것처럼 보인다.
방향이 이미 상태를 말해 주므로 채움은 빼고 호버 반응만 남긴다.
-->
<Style x:Key="MiniChevron" TargetType="ToggleButton" BasedOn="{StaticResource MiniToggle}">
<Setter Property="Opacity" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="bd" Background="Transparent" CornerRadius="5" SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Hover}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 체크박스 ===== -->
<Style TargetType="CheckBox">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<StackPanel Orientation="Horizontal" Background="Transparent">
<Border x:Name="box" Width="17" Height="17" CornerRadius="4" BorderThickness="1.3"
BorderBrush="{DynamicResource B.Line2}" Background="{DynamicResource B.Input}" VerticalAlignment="Center" SnapsToDevicePixels="True">
<Path x:Name="chk" Data="M 3.5 8 L 7 11 L 13 4.5" Stroke="{DynamicResource B.OnAccent}" StrokeThickness="2"
StrokeStartLineCap="Round" StrokeEndLineCap="Round" Visibility="Collapsed" />
</Border>
<ContentPresenter Margin="7,0,0,0" VerticalAlignment="Center"
TextElement.Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="box" Property="Background" Value="{DynamicResource B.Accent}" />
<Setter TargetName="box" Property="BorderBrush" Value="{DynamicResource B.Accent}" />
<Setter TargetName="chk" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="box" Property="BorderBrush" Value="{DynamicResource B.Accent}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 익스팬더 (인스펙터 섹션) ===== -->
<Style TargetType="Expander">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Expander">
<DockPanel Background="Transparent">
<ToggleButton DockPanel.Dock="Top" Focusable="False" Cursor="Hand"
Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}"
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="hb" Background="Transparent" CornerRadius="5" Padding="2,6">
<StackPanel Orientation="Horizontal">
<Path x:Name="arrow" Data="M 0 0 L 4 4 L 8 0" Stroke="{DynamicResource B.Muted}" StrokeThickness="1.6"
Margin="2,1,8,0" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform><RotateTransform Angle="-90" /></Path.RenderTransform>
</Path>
<ContentPresenter VerticalAlignment="Center" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="arrow" Property="RenderTransform">
<Setter.Value><RotateTransform Angle="0" /></Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="hb" Property="Background" Value="{DynamicResource B.Hover}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter x:Name="content" DockPanel.Dock="Bottom" Visibility="Collapsed" Margin="8,2,2,10" />
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="content" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 카드 / 패널헤더 / 칩 ===== -->
<Style x:Key="Card" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource B.Surface}" />
<Setter Property="BorderBrush" Value="{DynamicResource B.Line}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Padding" Value="12" />
</Style>
<Style x:Key="PanelHeader" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource B.Surface}" />
<Setter Property="BorderBrush" Value="{DynamicResource B.Line}" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
<Setter Property="Padding" Value="10,7" />
</Style>
<Style x:Key="Chip" TargetType="Border">
<Setter Property="Background" Value="{DynamicResource B.Chip}" />
<Setter Property="CornerRadius" Value="20" />
<Setter Property="Padding" Value="9,2" />
</Style>
<!-- ===== 메뉴 (타이틀바) ===== -->
<Style TargetType="Menu">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
</Style>
<Style TargetType="Separator">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Separator">
<Border Height="1" Background="{DynamicResource B.Line}" Margin="8,4" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="MenuItem">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="Padding" Value="10,6" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Grid TextElement.Foreground="{DynamicResource B.Ink}">
<Border x:Name="bd" Background="Transparent" CornerRadius="4" Padding="{TemplateBinding Padding}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" x:Name="icon" ContentSource="Icon" Margin="0,0,8,0" VerticalAlignment="Center" />
<ContentPresenter Grid.Column="1" ContentSource="Header" VerticalAlignment="Center" RecognizesAccessKey="True" />
<TextBlock Grid.Column="2" x:Name="gesture" Text="{TemplateBinding InputGestureText}" Foreground="{DynamicResource B.Muted}"
Margin="20,0,0,0" VerticalAlignment="Center" />
<Path Grid.Column="2" x:Name="sub" Visibility="Collapsed" Data="M0,0 L4,4 L0,8"
Stroke="{DynamicResource B.Muted}" StrokeThickness="1.4" Margin="14,0,0,0" VerticalAlignment="Center" />
</Grid>
</Border>
<Popup x:Name="pop" Placement="Bottom" IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True"
Focusable="False" PopupAnimation="Fade">
<Border Background="{DynamicResource B.Surface}" BorderBrush="{DynamicResource B.Line}" BorderThickness="1"
CornerRadius="6" Padding="4" Margin="0,3,0,0">
<StackPanel IsItemsHost="True" />
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter TargetName="pop" Property="Placement" Value="Right" />
<Setter TargetName="sub" Property="Visibility" Value="Visible" />
</Trigger>
<!-- 최상위 메뉴(파일/편집…)는 아이콘·단축키 칸을 접어 폭을 좁힘 -->
<Trigger Property="Role" Value="TopLevelHeader">
<Setter TargetName="icon" Property="Visibility" Value="Collapsed" />
<Setter TargetName="gesture" Property="Visibility" Value="Collapsed" />
</Trigger>
<!-- 키보드로 메뉴를 훑을 때 현재 위치를 알려주는 유일한 표시라 호버용 옅은 채움으로는
부족하다(양 테마 1.1:1). 선택 채움과 같은 강도로 올린다. -->
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Sel}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.4" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 우클릭 컨텍스트 메뉴 (다크 컨테이너) — 캔버스 우클릭 메뉴가 기본 라이트 팝업으로 안 깨지게 ===== -->
<Style TargetType="ContextMenu">
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
<Setter Property="FontFamily" Value="Malgun Gothic" />
<Setter Property="FontSize" Value="12.5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border Background="{DynamicResource B.Surface}" BorderBrush="{DynamicResource B.Line}" BorderThickness="1"
CornerRadius="6" Padding="4" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 창 캡션 버튼 (최소화/최대화/닫기) ===== -->
<Style x:Key="CaptionBtn" TargetType="Button">
<Setter Property="Width" Value="46" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource B.CaptionFg}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
<Setter Property="FontSize" Value="10" />
<Setter Property="Cursor" Value="Arrow" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
TextElement.FontFamily="{Binding FontFamily, RelativeSource={RelativeSource TemplatedParent}}"
TextElement.FontSize="{Binding FontSize, RelativeSource={RelativeSource TemplatedParent}}"
TextElement.Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}">
<!-- Content 가 <TextBlock> 요소면 그 자신의 암시 스타일(B.Ink)이 위의
TextElement.Foreground 상속을 이긴다 — B.CaptionFg/Hover/CloseHover 4종이
통째로 죽은 코드가 된다. 지역 암시 스타일로 되돌려 잡는다. -->
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource B.CaptionHover}" />
<Setter Property="Foreground" Value="{DynamicResource B.CaptionFgHover}" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="CloseBtn" TargetType="Button" BasedOn="{StaticResource CaptionBtn}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource B.CloseHover}" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
<!-- ===== 컬럼 스플리터 (사이드바 너비 드래그 조절) ===== -->
<Style x:Key="ColSplitter" TargetType="GridSplitter">
<Setter Property="Width" Value="5" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="ResizeBehavior" Value="PreviousAndNext" />
<Setter Property="ResizeDirection" Value="Columns" />
<Setter Property="Background" Value="{DynamicResource B.Line}" />
<Setter Property="Cursor" Value="SizeWE" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridSplitter">
<Border x:Name="bd" Background="{TemplateBinding Background}" SnapsToDevicePixels="True" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Accent}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 행 스플리터 (팔레트 ↔ 레이어 높이 조절) ===== -->
<Style x:Key="RowSplitter" TargetType="GridSplitter">
<Setter Property="Height" Value="6" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="ResizeBehavior" Value="PreviousAndNext" />
<Setter Property="ResizeDirection" Value="Rows" />
<Setter Property="Background" Value="{DynamicResource B.Line}" />
<Setter Property="Cursor" Value="SizeNS" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridSplitter">
<Border x:Name="bd" Background="{TemplateBinding Background}" SnapsToDevicePixels="True" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource B.Accent}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== 스크롤바 ([200] 통일 규격 이식) =====
9px 폭 + 상하 14px 화살표 + 둥근 막대. 전 ScrollViewer/ListBox/캔버스/팝업에 암시 적용된다.
막대 색은 토큰이 아니라 리터럴 중립 그레이다 — 다크·라이트 양쪽에서 같은 회색으로 보여야
스크롤바가 배경에 따라 튀지 않는다([200] 과 동일한 의도적 선택).
막대 최소 길이는 MinThumbTrack 이 보장한다. 기본 WPF Track 은 Thumb.MinHeight 를 무시해
항목이 많은 목록에서 막대가 실처럼 가늘어진다. -->
<SolidColorBrush x:Key="ScrollBtnHover" Color="#22808080" />
<!--
스크롤 썸 — MinWidth/MinHeight 를 두지 않는다.
여기에 24 를 박으면 세로 막대(폭 9)에서 썸이 24 폭으로 강제돼 오른쪽이 통째로 잘린다
(둥근 모서리가 사라지고 수직으로 싹둑 잘린 막대가 된다. 가로 막대는 아래쪽이 같은 식으로 잘렸다).
최소 '길이'는 MinThumbTrack.MinThumbLength=44 가 이미 보장한다 — 최소 '두께'는 필요 없다.
-->
<Style x:Key="ScrollThumb" TargetType="Thumb">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Border x:Name="t" CornerRadius="5" Background="{DynamicResource B.ScrollThumb}" Margin="2" SnapsToDevicePixels="True" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True"><Setter TargetName="t" Property="Background" Value="{DynamicResource B.ScrollThumbHover}" /></Trigger>
<Trigger Property="IsDragging" Value="True"><Setter TargetName="t" Property="Background" Value="{DynamicResource B.ScrollThumbDrag}" /></Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollLineBtn" TargetType="RepeatButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Focusable" Value="False" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Border x:Name="b" Background="Transparent" CornerRadius="3" SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True"><Setter TargetName="b" Property="Background" Value="{StaticResource ScrollBtnHover}" /></Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollPageBtn" TargetType="RepeatButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Focusable" Value="False" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton"><Border Background="Transparent" /></ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="VScrollBar" TargetType="ScrollBar">
<Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid.RowDefinitions>
<RowDefinition Height="14" />
<RowDefinition Height="*" />
<RowDefinition Height="14" />
</Grid.RowDefinitions>
<RepeatButton Grid.Row="0" Style="{StaticResource ScrollLineBtn}" Command="ScrollBar.LineUpCommand">
<Path Stretch="None" Data="M1,5 L4.5,1.5 L8,5" Stroke="{DynamicResource B.ScrollThumb}"
StrokeThickness="1.4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" />
</RepeatButton>
<ctl:MinThumbTrack x:Name="PART_Track" MinThumbLength="44" Grid.Row="1" Orientation="Vertical"
Minimum="{TemplateBinding Minimum}" Maximum="{TemplateBinding Maximum}"
Value="{TemplateBinding Value}" ViewportSize="{TemplateBinding ViewportSize}">
<ctl:MinThumbTrack.DecreaseRepeatButton><RepeatButton Style="{StaticResource ScrollPageBtn}" Command="ScrollBar.PageUpCommand" /></ctl:MinThumbTrack.DecreaseRepeatButton>
<ctl:MinThumbTrack.Thumb><Thumb Style="{StaticResource ScrollThumb}" /></ctl:MinThumbTrack.Thumb>
<ctl:MinThumbTrack.IncreaseRepeatButton><RepeatButton Style="{StaticResource ScrollPageBtn}" Command="ScrollBar.PageDownCommand" /></ctl:MinThumbTrack.IncreaseRepeatButton>
</ctl:MinThumbTrack>
<RepeatButton Grid.Row="2" Style="{StaticResource ScrollLineBtn}" Command="ScrollBar.LineDownCommand">
<Path Stretch="None" Data="M1,1.5 L4.5,5 L8,1.5" Stroke="{DynamicResource B.ScrollThumb}"
StrokeThickness="1.4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" />
</RepeatButton>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="HScrollBar" TargetType="ScrollBar">
<Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<RepeatButton Grid.Column="0" Style="{StaticResource ScrollLineBtn}" Command="ScrollBar.LineLeftCommand">
<Path Stretch="None" Data="M5,1 L1.5,4.5 L5,8" Stroke="{DynamicResource B.ScrollThumb}"
StrokeThickness="1.4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" />
</RepeatButton>
<ctl:MinThumbTrack x:Name="PART_Track" MinThumbLength="44" Grid.Column="1" Orientation="Horizontal"
Minimum="{TemplateBinding Minimum}" Maximum="{TemplateBinding Maximum}"
Value="{TemplateBinding Value}" ViewportSize="{TemplateBinding ViewportSize}">
<ctl:MinThumbTrack.DecreaseRepeatButton><RepeatButton Style="{StaticResource ScrollPageBtn}" Command="ScrollBar.PageLeftCommand" /></ctl:MinThumbTrack.DecreaseRepeatButton>
<ctl:MinThumbTrack.Thumb><Thumb Style="{StaticResource ScrollThumb}" /></ctl:MinThumbTrack.Thumb>
<ctl:MinThumbTrack.IncreaseRepeatButton><RepeatButton Style="{StaticResource ScrollPageBtn}" Command="ScrollBar.PageRightCommand" /></ctl:MinThumbTrack.IncreaseRepeatButton>
</ctl:MinThumbTrack>
<RepeatButton Grid.Column="2" Style="{StaticResource ScrollLineBtn}" Command="ScrollBar.LineRightCommand">
<Path Stretch="None" Data="M1,1 L4.5,4.5 L1,8" Stroke="{DynamicResource B.ScrollThumb}"
StrokeThickness="1.4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" />
</RepeatButton>
</Grid>
</ControlTemplate>
<!--
폭 11 인 이유: 화살표 글리프가 7 단위 + StrokeThickness 1.4(양옆 0.7씩) = 8.4 를 차지한다.
9 로 두면 캡이 경계에 닿아 오른쪽 팔이 잘린 채로 그려진다(썸의 둥근 모서리도 같이 잘렸다).
11 이면 양옆 1.3 여유가 생겨 글리프와 썸이 온전히 들어간다.
-->
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="Transparent" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Width" Value="11" />
<Setter Property="MinWidth" Value="11" />
<Setter Property="Template" Value="{StaticResource VScrollBar}" />
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Width" Value="Auto" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="Height" Value="11" />
<Setter Property="MinHeight" Value="11" />
<Setter Property="Template" Value="{StaticResource HScrollBar}" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>