Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178/* src/layout/Ribbon.css */
/* Ribbon width comes from --icon-column-width (defined in src/index.css) * so the ribbon, the left sidebar's vertical tab strip, and the right * panel's vertical tab strip all share one source of truth. * * --ribbon-width is kept as a backward-compat alias because AppShell.tsx * (toolbar left offset math) and AppShell.css (mobile sidebar offset) * historically read it. New code should reference --icon-column-width * directly. #213 */:root { --ribbon-width: var(--icon-column-width);}
.ribbon { position: relative; display: flex; flex-direction: column; width: var(--icon-column-width); flex-shrink: 0; background: var(--background-secondary, #2d2d2d); border-right: 1px solid var(--background-modifier-border, #3d3d3d); overflow: hidden; transition: width 0.15s ease-out, padding 0.15s ease-out, border-width 0.15s ease-out;}
.ribbon[data-hidden="true"] { width: 0; padding: 0; border-right-width: 0;}
.ribbon-icons { flex: 1; display: flex; flex-direction: column; /* No padding or gap: icon buttons span the full column width as * flush 32px square blocks, matching the sidebar side-tab strip's * geometry. The ribbon does NOT skip its first slot — unlike the * side-tab strip (which leaves its first slot empty so the chrome * row stays pure header chrome next to the panel title), the ribbon * has no peer header to align with, so the first icon sits at Y=0 * and the column begins immediately. The ribbon icons happen to be * the first thing visible on the screen below the app header. */ padding: 0; gap: 0; overflow-y: auto;}
.ribbon-scroll-shadow { position: sticky; left: 0; right: 0; height: 22px; flex-shrink: 0; pointer-events: none; opacity: 0; transition: opacity 0.15s ease-out; z-index: 1;}
.ribbon-scroll-shadow--top { top: 0; margin-bottom: -22px; background: linear-gradient(to bottom, rgba(0, 0, 0, 0.42), transparent);}
.ribbon-scroll-shadow--bottom { bottom: 0; margin-top: -22px; background: linear-gradient(to top, rgba(0, 0, 0, 0.42), transparent);}
.ribbon-icons[data-scroll-shadow-top="true"] .ribbon-scroll-shadow--top { opacity: 1;}
.ribbon-icons[data-scroll-shadow-bottom="true"] .ribbon-scroll-shadow--bottom { opacity: 1;}
/* Account button and settings button — match the header burger's 40 px tap * area so the left-column chrome reads as one uniform vertical rhythm. */.ribbon-account-button,.ribbon-settings-button { display: flex; align-items: center; justify-content: center; /* Full column width, square block, no radius. Height matches the * header band (--header-height) so the settings button at the bottom * mirrors the burger button at the top — same hit area, same visual * weight, easier mobile tap target. */ width: 100%; height: var(--header-height); flex-shrink: 0; background: none; border: none; border-radius: 0; color: var(--text-muted, #b0b0b0); cursor: pointer; transition: background-color 0.1s, color 0.1s;}
.ribbon-account-button:hover,.ribbon-settings-button:hover { background: var(--background-modifier-hover, #3d3d3d); color: var(--text-normal, #e0e0e0);}
.ribbon-account-button:focus-visible,.ribbon-settings-button:focus-visible { outline: 2px solid var(--interactive-accent, #4a9eff); outline-offset: -2px;}
.ribbon-account-avatar { width: 20px; height: 20px; border-radius: 999px; object-fit: cover;}
.ribbon-account-button .lucide,.ribbon-settings-button .lucide { width: 20px; height: 20px;}
/* Ribbon icon button styles (for plugin icons). * * Fills the full ribbon column width so the hover/selected fill reads * as a flush block aligned with the rest of the chrome (no rounded pill * floating in a grid of straight lines). Height stays at --icon-tap-size * so the icon column has the same row metric as the side-tab strip. */.ribbon-icon { width: 100%; height: var(--icon-tap-size); display: flex; align-items: center; justify-content: center; border-radius: 0; cursor: pointer; color: var(--text-muted, #b0b0b0); transition: background-color 0.1s, color 0.1s;}
.ribbon-icon:hover { background: var(--background-modifier-hover, #3d3d3d); color: var(--text-normal, #e0e0e0);}
.ribbon-icon:focus-visible { outline: 2px solid var(--interactive-accent, #4a9eff); outline-offset: -2px;}
/* Lucide icons - size controlled via CSS to avoid viewBox scaling issues */.ribbon-icon .lucide { width: 20px; height: 20px;}
.ribbon-separator { width: 100%; height: 1px; background-color: var(--background-modifier-border, #3d3d3d); flex-shrink: 0;}
.ribbon-account-icon,.ribbon-icon-svg,.ribbon-settings-icon { display: flex; align-items: center; justify-content: center;}