diff --git a/src/SheetMe.Designer/App.xaml.cs b/src/SheetMe.Designer/App.xaml.cs
index b7ab9cd..4bf80bf 100644
--- a/src/SheetMe.Designer/App.xaml.cs
+++ b/src/SheetMe.Designer/App.xaml.cs
@@ -287,6 +287,11 @@ public partial class App : Application
return Diagnostics.MaximizeCheck.Run(args.Length >= 2 ? args[1] : null);
}
+ if (args.Length >= 1 && args[0] == "--cleartype")
+ {
+ return Diagnostics.ClearTypeCheck.Run();
+ }
+
// 진단 모드에서는 모달을 띄우지 않는다 — 스크립트 옵션 오타 하나로 무인 실행이 여기서
// 영원히 멈춘다. WinExe 라 콘솔이 없어 stderr 는 호출자가 리다이렉트할 때만 보이므로
// 로그를 함께 남긴다(--db-render 가 .err.txt 로 남기는 것과 같은 이유).
diff --git a/src/SheetMe.Designer/Diagnostics/ClearTypeCheck.cs b/src/SheetMe.Designer/Diagnostics/ClearTypeCheck.cs
new file mode 100644
index 0000000..994099e
--- /dev/null
+++ b/src/SheetMe.Designer/Diagnostics/ClearTypeCheck.cs
@@ -0,0 +1,450 @@
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Media;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+
+namespace SheetMe.Designer.Diagnostics;
+
+///
+/// ClearType 이 실제로 꺼지는지 화면을 찍어서 잰다 (--cleartype).
+///
+/// 왜 화면을 찍는가. 으로는 이 질문에 답할 수 없다 —
+/// 그 자체가 알파를 가진 중간 서피스라서 ClearType 이 무조건 꺼진다.
+/// 오프스크린으로 재면 Effect 가 있든 없든 양쪽 다 회색으로 나오고,
+/// 검사는 통과하면서 아무것도 증명하지 못한다.
+/// 그래서 진짜 화면(데스크톱 DC)을 BitBlt 으로 떠서 픽셀을 본다.
+///
+/// 무엇을 세는가. ClearType 은 서브픽셀 렌더링이라 글리프 경계에 채널이 어긋난 픽셀
+/// (R≠G≠B, 이른바 색 번짐)을 남긴다. 회색 안티에일리어싱은 R=G=B 만 남긴다.
+/// 그래서 "채널 차이가 있는 픽셀 수"가 곧 ClearType 이 켜졌는지의 지표다.
+///
+/// 스스로 속지 않기 위한 장치. 대조군(A: 아무 효과 없는 글자)에서 색 번짐이 0 이면
+/// 시스템 ClearType 이 꺼졌거나 캡처 경로가 틀린 것이므로 판정 불가로 끝낸다.
+/// 그 확인 없이 B 가 0 인 것을 근거로 삼으면 "둘 다 0"을 결론으로 착각한다.
+///
+internal static class ClearTypeCheck
+{
+ #region Member Fields
+ /// 이 정도 채널 차이면 회색 AA 가 아니다 — 회색은 원리상 차이가 정확히 0 이다
+ private const int ChannelSpread = 6;
+
+ /// 글자가 그려진 픽셀로 볼 밝기 상한(흰 배경 기준)
+ private const int InkLuma = 200;
+
+ private static readonly List Lines = new();
+ private static int failures;
+ #endregion
+
+ #region Methods
+ public static int Run()
+ {
+ // F 표본이 앱의 실제 콤보 템플릿을 타야 하므로 테마를 실제로 적용한다
+ Services.ThemeManager.Apply(true);
+
+ var window = BuildProbe(out var samples, out var popups);
+ window.Show();
+
+ // 창이 보이는 것과 합성기가 그려 낸 것은 다르다 — Loaded 직후 찍으면 빈 화면을 잰다.
+ // (--modal-check 에서 BeginInvoke 가 Loaded 보다 먼저 돌아 0 을 세던 것과 같은 함정)
+ var timer = new System.Windows.Threading.DispatcherTimer
+ {
+ Interval = TimeSpan.FromMilliseconds(600),
+ };
+ timer.Tick += (_, _) =>
+ {
+ timer.Stop();
+ try
+ {
+ Judge(samples);
+ }
+ finally
+ {
+ foreach (var popup in popups)
+ {
+ popup.IsOpen = false;
+ }
+ window.Close();
+ Application.Current.Shutdown();
+ }
+ };
+ timer.Start();
+
+ var dispatcherFrame = new System.Windows.Threading.DispatcherFrame();
+ Application.Current.Exit += (_, _) => dispatcherFrame.Continue = false;
+ System.Windows.Threading.Dispatcher.PushFrame(dispatcherFrame);
+
+ foreach (var line in Lines)
+ {
+ Console.Error.WriteLine(line);
+ }
+ Console.Error.WriteLine($"결과: 실패 {failures}건");
+ return failures == 0 ? 0 : 1;
+ }
+
+ /// 대조군이 먼저 서야 나머지 숫자가 뜻을 갖는다
+ private static void Judge(List<(string Name, FrameworkElement Target, bool ExpectClearType)> samples)
+ {
+ var measured = samples
+ .Select(s => (s.Name, s.ExpectClearType, Result: Measure(s.Target)))
+ .ToList();
+
+ foreach (var (name, _, result) in measured)
+ {
+ // 잰 사각형을 함께 찍는다 — 두 표본이 같은 자리를 재고 있으면 숫자가 우연히 같아지는데,
+ // 좌표를 안 찍으면 그것을 "결과가 같다"로 읽는다(실제로 한 번 그렇게 읽었다).
+ Lines.Add($" {name,-40} 색번짐 {result.Fringed,6} / 글자픽셀 {result.Ink,6} @ {result.Rect}");
+ }
+
+ var control = measured[0];
+ if (control.Result.Fringed == 0)
+ {
+ Lines.Add("판정 불가 — 대조군에서 색 번짐이 0 이다.");
+ Lines.Add(" 시스템 ClearType 이 꺼져 있거나 캡처가 화면을 못 읽고 있다.");
+ Lines.Add(" 이 상태에서 나머지 0 은 근거가 되지 않는다.");
+ failures++;
+ return;
+ }
+ Lines.Add($"대조군 확인 — 색 번짐 {control.Result.Fringed}건. 이제 나머지 0 은 뜻이 있다.");
+
+ foreach (var (name, expect, result) in measured)
+ {
+ var on = result.Fringed > 0;
+ Check($"{name} → ClearType {(expect ? "켜짐" : "꺼짐")}", on == expect,
+ $"실제 색번짐 {result.Fringed}건");
+ }
+ }
+
+ private static int Spread(int r, int g, int b)
+ => Math.Max(r, Math.Max(g, b)) - Math.Min(r, Math.Min(g, b));
+
+ private static void Check(string label, bool ok, string detail = "")
+ {
+ Lines.Add($"{(ok ? "PASS" : "FAIL")} {label}{(detail.Length > 0 ? $" — {detail}" : string.Empty)}");
+ if (!ok)
+ {
+ failures++;
+ }
+ }
+ #endregion
+
+ #region Probe
+ ///
+ /// 같은 글자를 다섯 조건으로 놓는다. 배경은 전부 불투명 흰색이어야 한다 —
+ /// ClearType 은 뒤에 무엇이 있는지 알아야 서브픽셀을 계산할 수 있어서,
+ /// 투명 배경에서는 효과와 무관하게 회색으로 떨어진다.
+ ///
+ private static Window BuildProbe(
+ out List<(string Name, FrameworkElement Target, bool ExpectClearType)> samples,
+ out List popups)
+ {
+ var shadow = new DropShadowEffect
+ {
+ BlurRadius = 26, ShadowDepth = 5, Direction = 270,
+ Opacity = 0.14, Color = Colors.Black, RenderingBias = RenderingBias.Quality,
+ };
+
+ var plain = Text();
+ var effected = Text();
+ var hintOnEffected = Text();
+ var hintInside = Text();
+ var inPopup = Text();
+ var inPopupHinted = Text();
+
+ var effectedHost = Card(effected);
+ effectedHost.Effect = shadow;
+
+ // 변형 1 — 힌트를 Effect 가 걸린 요소 자신에게
+ var hostA = Card(hintOnEffected);
+ hostA.Effect = shadow.Clone();
+ RenderOptions.SetClearTypeHint(hostA, ClearTypeHint.Enabled);
+
+ // 변형 2 — 힌트를 중간 서피스 안쪽의 불투명 배경 요소에.
+ // 문서가 "불투명 배경이 있는 지점"이라고만 말해서 어느 쪽인지 재 봐야 안다.
+ var inner = new Border { Background = Brushes.White, Child = hintInside };
+ RenderOptions.SetClearTypeHint(inner, ClearTypeHint.Enabled);
+ var hostB = Card(inner);
+ hostB.Effect = shadow.Clone();
+
+ // F — 합성 표본이 아니라 앱의 실제 콤보 템플릿. ComboBox 스타일이 암시라 그대로 태워진다.
+ // 이 표본이 있어야 "플랫폼이 그렇다"에서 "이 앱이 그렇다"로 넘어갈 수 있다.
+ // 드롭다운은 AllowsTransparency 팝업 + FloatShadow Effect 가 겹쳐 걸린 자리다(DesignerTheme.xaml:548,553).
+ var themedItem = Text();
+ var combo = new ComboBox { Width = 300, HorizontalAlignment = HorizontalAlignment.Left };
+ combo.Items.Add(themedItem);
+ // 선택하지 않는다 — 선택 강조가 배경을 유채색으로 만들면 위 판정 장치가 이 표본을 거부한다
+ combo.SelectedIndex = -1;
+
+ var anchor = new Border { Width = 300, Height = 20, Background = Brushes.White };
+ var anchorHinted = new Border { Width = 300, Height = 20, Background = Brushes.White };
+ var anchorStacked = new Border { Width = 300, Height = 20, Background = Brushes.White };
+ var anchorSplit = new Border { Width = 300, Height = 20, Background = Brushes.White };
+ var anchorScrolled = new Border { Width = 300, Height = 20, Background = Brushes.White };
+ var anchorInnermost = new Border { Width = 300, Height = 20, Background = Brushes.White };
+
+ var popupPlain = LayeredPopup(inPopup, anchor);
+ var popupHinted = LayeredPopup(inPopupHinted, anchorHinted);
+ RenderOptions.SetClearTypeHint((FrameworkElement)popupHinted.Child, ClearTypeHint.Enabled);
+
+ // G — 앱의 현재 구조: 레이어드 팝업 안에 Effect 가 걸린 Border, 그 안에 힌트.
+ // 중간 서피스가 두 겹이면 힌트가 듣는지 재 본다.
+ var stackedText = Text();
+ var stackedInner = new Border { Background = Brushes.White, Child = stackedText };
+ RenderOptions.SetClearTypeHint(stackedInner, ClearTypeHint.Enabled);
+ var stackedOuter = new Border { Background = Brushes.White, Child = stackedInner, Effect = shadow.Clone() };
+ var popupStacked = LayeredPopup(stackedOuter, anchorStacked, wrap: false);
+
+ // H — 후보 수리: 그림자를 글자가 없는 형제로 떼어낸다.
+ // 그러면 Effect 의 중간 서피스에 글자가 안 들어가고, 남는 것은 레이어드 창 한 겹뿐이라
+ // E 와 같은 조건이 된다.
+ var splitText = Text();
+ var shadowOnly = new Border { Background = Brushes.White, Effect = shadow.Clone() };
+ var splitContent = new Border { Background = Brushes.White, Child = splitText };
+ RenderOptions.SetClearTypeHint(splitContent, ClearTypeHint.Enabled);
+ var splitHost = new Grid();
+ splitHost.Children.Add(shadowOnly);
+ splitHost.Children.Add(splitContent);
+ var popupSplit = LayeredPopup(splitHost, anchorSplit, wrap: false);
+
+ // I — G 와 똑같지만 힌트와 글자 사이에 ScrollViewer 를 끼운다.
+ // 앱 콤보 드롭다운이 바로 이 모양인데 G 는 되고 F 는 안 되니, 남은 차이가 이것뿐이다.
+ var scrolledText = Text();
+ var scrolledInner = new Grid { Background = Brushes.White };
+ RenderOptions.SetClearTypeHint(scrolledInner, ClearTypeHint.Enabled);
+ scrolledInner.Children.Add(new ScrollViewer { Content = scrolledText });
+ var scrolledOuter = new Border
+ {
+ Background = Brushes.White, Child = scrolledInner, Effect = shadow.Clone(),
+ };
+ var popupScrolled = LayeredPopup(scrolledOuter, anchorScrolled, wrap: false);
+
+ // J — 힌트를 ScrollViewer 안쪽(가장 안쪽 불투명 배경)에 건다.
+ var innermostText = Text();
+ var innermost = new Border { Background = Brushes.White, Child = innermostText };
+ RenderOptions.SetClearTypeHint(innermost, ClearTypeHint.Enabled);
+ var innerOuter = new Border
+ {
+ Background = Brushes.White,
+ Child = new ScrollViewer { Content = innermost },
+ Effect = shadow.Clone(),
+ };
+ var popupInnermost = LayeredPopup(innerOuter, anchorInnermost, wrap: false);
+
+ var stack = new StackPanel { Margin = new Thickness(20) };
+ stack.Children.Add(Card(plain));
+ stack.Children.Add(effectedHost);
+ stack.Children.Add(hostA);
+ stack.Children.Add(hostB);
+ stack.Children.Add(anchor);
+ // 팝업이 아래로 펼쳐질 자리 — 앵커끼리 겹치면 두 팝업이 같은 픽셀을 재게 된다
+ stack.Children.Add(new Border { Height = 46 });
+ stack.Children.Add(anchorHinted);
+ stack.Children.Add(new Border { Height = 46 });
+ stack.Children.Add(combo);
+ stack.Children.Add(new Border { Height = 46 });
+ stack.Children.Add(anchorStacked);
+ stack.Children.Add(new Border { Height = 46 });
+ stack.Children.Add(anchorSplit);
+ stack.Children.Add(new Border { Height = 46 });
+ stack.Children.Add(anchorScrolled);
+ stack.Children.Add(new Border { Height = 46 });
+ stack.Children.Add(anchorInnermost);
+ stack.Children.Add(new Border { Height = 46 });
+
+ var window = new Window
+ {
+ Title = "ClearType 검사",
+ Width = 480, Height = 1040,
+ Left = 60, Top = 60,
+ WindowStartupLocation = WindowStartupLocation.Manual,
+ Background = Brushes.White,
+ Content = stack,
+ Topmost = true,
+ };
+ window.ContentRendered += (_, _) =>
+ {
+ popupPlain.IsOpen = true;
+ popupHinted.IsOpen = true;
+ popupStacked.IsOpen = true;
+ popupSplit.IsOpen = true;
+ popupScrolled.IsOpen = true;
+ popupInnermost.IsOpen = true;
+ combo.IsDropDownOpen = true;
+ };
+
+ // 기대값은 예측이 아니라 측정 결과다. C1 과 E 는 내가 예상한 것과 반대로 나왔고
+ // 그 사실이 곧 수리 방법을 정한다 —
+ // 힌트는 Effect 가 걸린 요소 자신에게 걸면 듣지 않고(C1), 그 안쪽 불투명 배경에 걸면 듣는다(C2).
+ // 레이어드 팝업도 자식 불투명 배경에 걸면 되살아난다(E) — AllowsTransparency 를 끌 필요가 없다.
+ samples = new()
+ {
+ ("A 아무것도 없음 (대조군)", plain, true),
+ ("B Effect (그림자)", effected, false),
+ ("C1 Effect + 힌트를 그 요소에", hintOnEffected, false),
+ ("C2 Effect + 힌트를 안쪽 배경에", hintInside, true),
+ ("D Popup AllowsTransparency", inPopup, false),
+ ("E Popup + 힌트를 자식 배경에", inPopupHinted, true),
+ ("F 앱 콤보 드롭다운 (실제 템플릿)", themedItem, true),
+ ("G 팝업+Effect 두 겹 + 힌트", stackedText, true),
+ ("H 팝업, 그림자를 형제로 분리 + 힌트", splitText, true),
+ ("I 힌트 바깥에 ScrollViewer", scrolledText, false),
+ ("J 힌트를 ScrollViewer 안쪽에", innermostText, true),
+ };
+ popups = new() { popupPlain, popupHinted, popupStacked, popupSplit, popupScrolled, popupInnermost };
+ return window;
+ }
+
+ /// 글리프가 많고 획이 가는 글자 — 색 번짐이 가장 잘 드러난다
+ private static TextBlock Text() => new()
+ {
+ Text = "가나다라마 환자명 일자 ABCDEFG 0123456789",
+ FontFamily = new FontFamily("Malgun Gothic"),
+ FontSize = 13,
+ Foreground = Brushes.Black,
+ Margin = new Thickness(8, 5, 8, 5),
+ };
+
+ private static Border Card(UIElement child) => new()
+ {
+ Background = Brushes.White,
+ Margin = new Thickness(0, 0, 0, 18),
+ Child = child,
+ };
+
+ private static Popup LayeredPopup(UIElement child, UIElement target, bool wrap = true) => new()
+ {
+ PlacementTarget = target,
+ Placement = PlacementMode.Bottom,
+ AllowsTransparency = true,
+ StaysOpen = true,
+ Child = wrap ? new Border { Background = Brushes.White, Child = child } : child,
+ };
+ #endregion
+
+ #region Screen capture
+ ///
+ /// 이 요소가 실제로 그려진 화면 조각을 떠서, 채널이 어긋난 픽셀과 글자 픽셀을 센다.
+ ///
+ private static (int Fringed, int Ink, string Rect) Measure(FrameworkElement element)
+ {
+ if (!element.IsVisible || element.ActualWidth < 1 || element.ActualHeight < 1)
+ {
+ return (0, 0, "보이지 않음");
+ }
+ // PointToScreen 은 물리 화면 픽셀을 준다 — 배율이 걸려 있어도 그대로 쓸 수 있다
+ var topLeft = element.PointToScreen(new Point(0, 0));
+ var bottomRight = element.PointToScreen(new Point(element.ActualWidth, element.ActualHeight));
+ var x = (int)Math.Floor(Math.Min(topLeft.X, bottomRight.X));
+ var y = (int)Math.Floor(Math.Min(topLeft.Y, bottomRight.Y));
+ var width = (int)Math.Ceiling(Math.Abs(bottomRight.X - topLeft.X));
+ var height = (int)Math.Ceiling(Math.Abs(bottomRight.Y - topLeft.Y));
+ if (width < 1 || height < 1)
+ {
+ return (0, 0, "크기 0");
+ }
+
+ var pixels = Grab(x, y, width, height);
+ if (pixels is null)
+ {
+ return (0, 0, "캡처 실패");
+ }
+
+ // 배경을 먼저 정한다 — 가장 많이 나온 색이 배경이다.
+ //
+ // 왜 필요한가. "채널 차이 = 서브픽셀 AA"는 배경이 무채색일 때만 성립한다.
+ // 유채색 배경(예: 선택된 콤보 항목의 B.Sel #C2E2FF, 채널 차이 61)에서는
+ // 글자와 무관하게 거의 모든 픽셀이 색 번짐으로 잡혀서 ClearType 이 꺼져 있어도 통과한다.
+ // 실제로 그렇게 통과시켰다 — 색번짐 4359 인데 글자픽셀은 1075 였다.
+ var histogram = new Dictionary();
+ for (var i = 0; i + 3 < pixels.Length; i += 4)
+ {
+ var key = (pixels[i + 2] << 16) | (pixels[i + 1] << 8) | pixels[i];
+ histogram[key] = histogram.TryGetValue(key, out var seen) ? seen + 1 : 1;
+ }
+ var background = histogram.OrderByDescending(pair => pair.Value).First().Key;
+ int bgR = (background >> 16) & 0xFF, bgG = (background >> 8) & 0xFF, bgB = background & 0xFF;
+ if (Spread(bgR, bgG, bgB) > ChannelSpread)
+ {
+ return (0, 0, $"{x},{y} 배경이 유채색({bgR},{bgG},{bgB}) — 판정 불가");
+ }
+
+ var fringed = 0;
+ var ink = 0;
+ for (var i = 0; i + 3 < pixels.Length; i += 4)
+ {
+ int b = pixels[i], g = pixels[i + 1], r = pixels[i + 2];
+ // 배경 그 자체는 세지 않는다 — 글리프가 만든 픽셀만 본다
+ if ((r == bgR && g == bgG && b == bgB) is false && Spread(r, g, b) > ChannelSpread)
+ {
+ fringed++;
+ }
+ // Rec.601 근사 — 정수만으로 충분하다
+ if ((r * 299 + g * 587 + b * 114) / 1000 < InkLuma)
+ {
+ ink++;
+ }
+ }
+ return (fringed, ink, $"{x},{y} {width}x{height} 배경({bgR},{bgG},{bgB})");
+ }
+
+ /// 데스크톱 DC 에서 사각형 하나를 떠 BGRA 바이트로 돌려준다
+ private static byte[]? Grab(int x, int y, int width, int height)
+ {
+ var screen = GetDC(IntPtr.Zero);
+ if (screen == IntPtr.Zero)
+ {
+ return null;
+ }
+ var memory = IntPtr.Zero;
+ var bitmap = IntPtr.Zero;
+ try
+ {
+ memory = CreateCompatibleDC(screen);
+ bitmap = CreateCompatibleBitmap(screen, width, height);
+ if (memory == IntPtr.Zero || bitmap == IntPtr.Zero)
+ {
+ return null;
+ }
+ var previous = SelectObject(memory, bitmap);
+ // SRCCOPY — 합성이 끝난 화면을 그대로 가져온다
+ if (!BitBlt(memory, 0, 0, width, height, screen, x, y, 0x00CC0020))
+ {
+ return null;
+ }
+ SelectObject(memory, previous);
+
+ var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
+ bitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
+ var converted = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
+ var stride = converted.PixelWidth * 4;
+ var buffer = new byte[stride * converted.PixelHeight];
+ converted.CopyPixels(buffer, stride, 0);
+ return buffer;
+ }
+ finally
+ {
+ if (bitmap != IntPtr.Zero)
+ {
+ DeleteObject(bitmap);
+ }
+ if (memory != IntPtr.Zero)
+ {
+ DeleteDC(memory);
+ }
+ ReleaseDC(IntPtr.Zero, screen);
+ }
+ }
+
+ [DllImport("user32.dll")] private static extern IntPtr GetDC(IntPtr hwnd);
+ [DllImport("user32.dll")] private static extern int ReleaseDC(IntPtr hwnd, IntPtr dc);
+ [DllImport("gdi32.dll")] private static extern IntPtr CreateCompatibleDC(IntPtr dc);
+ [DllImport("gdi32.dll")] private static extern IntPtr CreateCompatibleBitmap(IntPtr dc, int width, int height);
+ [DllImport("gdi32.dll")] private static extern IntPtr SelectObject(IntPtr dc, IntPtr obj);
+ [DllImport("gdi32.dll")] private static extern bool DeleteObject(IntPtr obj);
+ [DllImport("gdi32.dll")] private static extern bool DeleteDC(IntPtr dc);
+ [DllImport("gdi32.dll")] private static extern bool BitBlt(IntPtr dest, int x, int y, int width, int height,
+ IntPtr source, int sourceX, int sourceY, uint rop);
+ #endregion
+}
diff --git a/src/SheetMe.Designer/Themes/DesignerTheme.xaml b/src/SheetMe.Designer/Themes/DesignerTheme.xaml
index e7dc05a..cc6cb1a 100644
--- a/src/SheetMe.Designer/Themes/DesignerTheme.xaml
+++ b/src/SheetMe.Designer/Themes/DesignerTheme.xaml
@@ -557,7 +557,17 @@
-
+
+
+
+
+
+
@@ -1096,8 +1106,12 @@
+
+ CornerRadius="6" Padding="4" Margin="0,3,0,0"
+ RenderOptions.ClearTypeHint="Enabled">
diff --git a/src/SheetMe.Designer/Views/InspectorView.xaml b/src/SheetMe.Designer/Views/InspectorView.xaml
index ab7df47..d27706f 100644
--- a/src/SheetMe.Designer/Views/InspectorView.xaml
+++ b/src/SheetMe.Designer/Views/InspectorView.xaml
@@ -740,7 +740,10 @@
HorizontalOffset="-176" VerticalOffset="4">
-
+
+
diff --git a/src/SheetMe.Designer/Views/MainView.xaml b/src/SheetMe.Designer/Views/MainView.xaml
index 9f53f60..03bf271 100644
--- a/src/SheetMe.Designer/Views/MainView.xaml
+++ b/src/SheetMe.Designer/Views/MainView.xaml
@@ -626,8 +626,11 @@
+
-
+
@@ -672,7 +675,8 @@
-
+