Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161/* src/layout/AppShell.css */
.app-shell { display: flex; flex-direction: column; width: 100%; height: 100%; overflow: hidden; /* The shell owns horizontal swipes. Keep native vertical scrolling: * Chromium otherwise claims a horizontal touch pan and sends * pointercancel before useSwipeGesture can receive pointerup. */ touch-action: pan-y;
/* --toolbar-left-offset is set via inline style in AppShell.tsx. * It computes the combined width of ribbon + sidebar (when visible) * so fixed-position elements like FormattingToolbar can offset their * left edge to avoid overlapping the layout chrome. * * On mobile (max-width: 767px), the toolbar starts beside the ribbon; * the sidebar overlays it when open. The desktop offset includes the * sidebar width. */}
.app-shell-body { display: flex; flex: 1; min-height: 0; /* Clip sliding mobile panels without creating a scroll container: a hidden * overflow box can retain scrollLeft after touch/scrollIntoView, leaving an * open sidebar positioned offscreen. */ overflow: clip;}
.app-shell-sidebar { flex-shrink: 0; overflow: hidden;}
/* Desktop: collapse sidebar width to 0 when hidden. Scoped to desktop only — mobile uses translateX for hiding. */@media (min-width: 768px) { .app-shell-sidebar { transition: width 0.15s ease-out; } .app-shell-sidebar[data-hidden="true"] { width: 0 !important; } /* Suppress transition during resize drag so the sidebar tracks the * cursor in real time instead of lagging 150ms behind. #213 */ .app-shell:has(.resize-handle[data-resizing="true"]) .app-shell-sidebar { transition: none; }}
.app-shell-main { position: relative; display: flex; flex-direction: column; flex: 1; min-width: 0; overflow: hidden;}
.app-shell-editor { flex: 1; min-height: 0; overflow: hidden;}
.app-shell-right-panel { flex-shrink: 0; overflow: hidden; background-color: var(--bg-secondary); border-left: 1px solid var(--border-color);}
/* Desktop: collapse right panel width to 0 when collapsed. Scoped to desktop only — mobile uses translateX for hiding. */@media (min-width: 768px) { .app-shell-right-panel { transition: width 0.15s ease-out; } .app-shell-right-panel[data-collapsed="true"] { width: 0 !important; } /* Suppress transition during resize drag (same rationale as sidebar). #213 */ .app-shell:has(.resize-handle[data-resizing="true"]) .app-shell-right-panel { transition: none; }}
.app-shell-empty { display: flex; align-items: center; justify-content: center; flex: 1; color: var(--text-tertiary); font-size: 0.875rem;}
/* Mobile overlay positioning for sidebars. * * Mobile state machine: * - Ribbon stays in normal document flow (var(--ribbon-width)) — editor shifts right. * - Sidebar panel overlays the editor, positioned next to the ribbon. * - Right panel overlays from the right edge. * - Burger menu cycles: hidden → ribbon → full → hidden. * - Editor interaction: full → ribbon (sidebar panel closes, ribbon stays). * * Animation: translateX slide (GPU-accelerated). * Desktop uses width transitions; mobile uses transform for smooth sliding. * overflow: clip on .app-shell-body clips the sidebar as it slides off-screen. */@media (max-width: 767px) { .app-shell-body { position: relative; }
/* Resize handles are meaningless on mobile — sidebars are overlays */ .resize-handle { display: none; }
.app-shell-sidebar { position: absolute; left: var(--ribbon-width); /* Start next to the ribbon */ top: 0; bottom: 0; z-index: 100; box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15); transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; transform: translateX(0); }
.app-shell-sidebar[data-hidden="true"] { /* Slide fully past the left edge of the parent. -100% moves left by own width, -var(--ribbon-width) covers the left offset from the ribbon. */ transform: translateX(calc(-100% - var(--ribbon-width))); box-shadow: none; pointer-events: none; }
.app-shell-right-panel { position: absolute; right: 0; top: 0; bottom: 0; z-index: 100; box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15); transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; transform: translateX(0); }
.app-shell-right-panel[data-collapsed="true"] { /* Slide right off-screen. */ transform: translateX(100%); box-shadow: none; pointer-events: none; }}