/** * App System Styles * Styles for the app.html template system (facet bar, menu bar, app bar, etc.) */ /* ======================================== * Cross-Document View Transitions * Enables smooth page transitions in supporting browsers * ======================================== */ @view-transition { navigation: auto; } /* Assign transition names to persistent structural elements */ .facet-bar { view-transition-name: facet-bar; } .menu-bar { view-transition-name: menu-bar; } .app-bar { view-transition-name: app-bar; } .workspace { view-transition-name: workspace; } /* Customize transition animations */ ::view-transition-old(workspace), ::view-transition-new(workspace) { animation-duration: 150ms; animation-timing-function: ease-in-out; } /* Other fixed elements that should persist */ .corner-tags { view-transition-name: corner-tags; } .notification-center { view-transition-name: notification-center; } .status-pane { view-transition-name: status-pane; } /* Keep structural elements stable (no animation) */ ::view-transition-old(facet-bar), ::view-transition-new(facet-bar), ::view-transition-old(menu-bar), ::view-transition-new(menu-bar), ::view-transition-old(app-bar), ::view-transition-new(app-bar), ::view-transition-old(corner-tags), ::view-transition-new(corner-tags), ::view-transition-old(notification-center), ::view-transition-new(notification-center), ::view-transition-old(status-pane), ::view-transition-new(status-pane) { animation: none; } /* Universal box-sizing */ * { box-sizing: border-box; } /* Reserve scrollbar space to prevent layout shift on navigation */ html { scrollbar-gutter: stable; } /* Default theme (when no facet is selected) */ :root { --facet-color: #b06a1a; --facet-bg: transparent; --facet-border: #e0e0e0; /* Layout dimensions */ --facet-bar-height: 60px; --menu-bar-width-minimal: 60px; --menu-bar-width-full: 200px; --app-bar-height: 60px; --date-nav-height: 40px; --date-nav-width: 300px; --status-pane-width: 280px; /* Z-index hierarchy (increasing order) */ --z-bars: 100; /* Facet bar, menu bar, app bar */ --z-modals: 200; /* Modal overlays */ --z-notifications: 300; /* Notifications, status pane, error log */ --z-tags: 400; /* Corner tags - topmost layer */ } body { margin: 0; padding: 0; overflow-x: hidden; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } .workspace { margin-top: var(--facet-bar-height); margin-left: var(--menu-bar-width-minimal); margin-bottom: calc(var(--app-bar-height) + 40px); } /* Add extra top margin when date-nav is present */ body.has-date-nav .workspace { margin-top: calc(var(--facet-bar-height) + var(--date-nav-height)); } /* Standard workspace containers */ .workspace-content { max-width: 1200px; margin: 0 auto; padding: 1.5rem 2rem 2rem; } .workspace-content-wide { padding: 1.5rem 2rem 2rem; } .workspace-prose { max-width: 72ch; margin-inline: auto; } /* Responsive */ @media (max-width: 768px) { .workspace-content, .workspace-content-wide { padding: 1rem; } } @media (max-width: 768px) { .menu-bar { width: 0; overflow: hidden; } body.menu-full .menu-bar { width: var(--menu-bar-width-full); box-shadow: 4px 0 16px rgba(0, 0, 0, 0.2); z-index: calc(var(--z-bars) + 2); } .workspace { margin-left: 0 !important; } .facet-bar .facet-pills-container { overflow-x: auto; -webkit-overflow-scrolling: touch; } .app-bar { width: calc(100% - 16px) !important; } .menu-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-bars) + 1); background: rgba(0, 0, 0, 0.3); opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .menu-backdrop.visible { opacity: 1; pointer-events: auto; } } /* Facet Bar (top) */ .facet-bar { position: fixed; top: 0; left: 0; right: 0; background: white; z-index: var(--z-bars); height: var(--facet-bar-height); padding: 12px 16px; overflow: visible; white-space: nowrap; display: flex; align-items: center; gap: 12px; } .facet-bar::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: var(--facet-bg, transparent); transition: background-color 0.3s ease; pointer-events: none; z-index: -1; } /* Border as pseudo-element for selective positioning */ .facet-bar::after { content: ''; position: absolute; bottom: 0; left: var(--menu-bar-width-minimal); right: 0; height: 1px; background: var(--facet-border, #e0e0e0); transition: left 0.3s ease, background-color 0.3s ease; /* right is instant */ pointer-events: none; } /* When sidebar open, border only where workspace is visible */ body.menu-full .facet-bar::after { left: var(--menu-bar-width-full); } /* When status pane open, stop border before it */ body:has(.status-pane.visible) .facet-bar::after { right: var(--status-pane-width); } .facet-bar #hamburger { display: none; font-size: 24px; cursor: pointer; padding: 8px; border-radius: 4px; transition: background 0.2s; user-select: none; flex-shrink: 0; } .facet-bar #hamburger:hover { background: rgba(0,0,0,0.05); } @media (max-width: 768px) { .facet-bar #hamburger { display: flex; } } .facet-bar .status-icon { font-size: 20px; padding: 4px; flex-shrink: 0; cursor: pointer; border-radius: 4px; transition: background 0.2s; margin-left: auto; position: relative; } .facet-bar .status-icon:hover { background: rgba(0,0,0,0.05); } .facet-bar .status-icon.error { box-shadow: 0 0 4px 2px red; border-radius: 4px; } /* Status indicator shapes (SVG inside .status-icon button) */ .status-indicator { display: block; } .status-indicator--connecting { animation: status-spin 1.2s linear infinite; } @keyframes status-spin { to { transform: rotate(360deg); } } /* Date Nav - hangs below facet bar */ .date-nav { position: fixed; top: var(--facet-bar-height); /* Sits directly below facet bar */ left: 50%; transform: translateX(-50%); width: var(--date-nav-width); height: var(--date-nav-height); box-sizing: border-box; /* Grid layout: [left buttons] [centered label] [right buttons] */ display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 0 8px; /* Match facet bar styling */ background: white; border: 1px solid var(--facet-border, #e0e0e0); border-top: none; /* Seamless connection to facet bar */ border-radius: 0 0 12px 12px; /* Rounded bottom only */ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); z-index: var(--z-bars); font-size: 15px; font-weight: 500; color: #374151; user-select: none; view-transition-name: date-nav; } /* Facet-colored background tint (like facet bar) */ .date-nav::before { content: ''; position: absolute; inset: 0; background: var(--facet-bg, transparent); border-radius: 0 0 12px 12px; pointer-events: none; z-index: -1; } /* Cover the facet bar's bottom border where date nav attaches */ .date-nav::after { content: ''; position: absolute; top: -1px; left: 1px; right: 1px; height: 2px; background: white; /* Layer the facet tint on top */ background: linear-gradient(var(--facet-bg, transparent), var(--facet-bg, transparent)), white; } .date-nav-arrow { background: none; border: none; min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: 18px; font-weight: 600; color: #6b7280; border-radius: 4px; transition: background 0.15s, color 0.15s; } .date-nav-arrow:hover { background: rgba(0, 0, 0, 0.05); color: #111827; } /* Button groups for grid layout symmetry */ .date-nav-left { display: flex; justify-content: flex-start; } .date-nav-right { display: flex; justify-content: flex-end; } /* Today button - always visible, de-emphasized when viewing today */ .date-nav-today { background: none; border: none; padding: 4px 12px; cursor: pointer; font-size: 14px; font-weight: 500; color: #9ca3af; border-radius: 4px; transition: background 0.15s, color 0.15s, font-weight 0.15s; } .date-nav-today:hover { background: rgba(0, 0, 0, 0.05); color: #111827; } .date-nav-today:focus-visible { outline: 2px solid #b06a1a; outline-offset: 2px; background: rgba(0, 0, 0, 0.05); color: #111827; } /* Prominent state when viewing a different day */ .date-nav-today.is-other-day { color: #111827; background: rgba(0, 0, 0, 0.05); font-weight: 600; } .date-nav-today.is-other-day:hover { background: rgba(0, 0, 0, 0.08); } .date-nav-label { text-align: center; color: inherit; text-decoration: none; padding: 6px 8px; border-radius: 4px; cursor: pointer; transition: background 0.15s; } .date-nav-label:hover { background: rgba(0, 0, 0, 0.05); } /* Keep date-nav stable during view transitions */ ::view-transition-old(date-nav), ::view-transition-new(date-nav) { animation: none; } /* When picker is open, remove bottom border radius for seamless connection */ .date-nav.picker-open { border-radius: 0; box-shadow: none; } .date-nav.picker-open::before { border-radius: 0; } /* Date nav mobile */ @media (max-width: 480px) { :root { --date-nav-width: 100%; } .date-nav { left: 0; transform: none; border-radius: 0; border-left: none; border-right: none; } } /* Month Picker Dropdown */ .month-picker { position: absolute; top: 100%; left: -1px; /* Align with parent's outer border */ right: -1px; /* Align with parent's outer border */ background: white; border: 1px solid var(--facet-border, #e0e0e0); border-top: none; border-radius: 0 0 12px 12px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); overflow: hidden; z-index: 1; /* Closed state */ max-height: 0; opacity: 0; pointer-events: none; transition: max-height 0.2s ease, opacity 0.15s ease; } /* Facet tint background */ .month-picker::before { content: ''; position: absolute; inset: 0; background: var(--facet-bg, transparent); border-radius: 0 0 12px 12px; pointer-events: none; z-index: -1; } .month-picker.open { max-height: 280px; opacity: 1; pointer-events: auto; } .mp-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); padding: 8px 8px 4px; font-size: 11px; font-weight: 600; color: #9ca3af; text-align: center; } .mp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; padding: 4px 8px 8px; } .mp-day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; font-size: 13px; border-radius: 6px; cursor: pointer; transition: background 0.1s; /* Heat map: intensity controls facet color opacity */ background: color-mix(in srgb, var(--facet-color) calc(var(--intensity, 0) * 30%), transparent); } .mp-day:hover:not(.mp-other):not(.mp-empty):not(.mp-future) { background: color-mix(in srgb, var(--facet-color) 40%, transparent); } /* Empty days - striped pattern, not clickable */ .mp-day.mp-empty { background: repeating-linear-gradient(45deg, transparent, transparent 3px, rgba(0,0,0,0.07) 3px, rgba(0,0,0,0.07) 6px), color-mix(in srgb, var(--facet-color) calc(var(--intensity, 0) * 30%), transparent); color: #999; cursor: default; } /* Future days without data - clickable but muted appearance */ .mp-day.mp-future { color: #999; } .mp-day.mp-future:hover { background: color-mix(in srgb, var(--facet-color) 20%, transparent); } /* Other month days (leading/trailing) - same striped pattern */ .mp-day.mp-other { background: repeating-linear-gradient(45deg, transparent, transparent 3px, rgba(0,0,0,0.07) 3px, rgba(0,0,0,0.07) 6px); cursor: default; } /* Today indicator */ .mp-day.mp-today { box-shadow: inset 0 0 0 2px #b06a1a; } /* Selected day */ .mp-day.mp-selected { background: var(--facet-color, #b06a1a); color: white; font-weight: 600; } .mp-day.mp-selected:hover { background: var(--facet-color, #b06a1a); } /* ARIA row wrappers - invisible to CSS grid */ .mp-grid [role="row"] { display: contents; } /* Focus indicator for keyboard navigation */ .mp-day:focus-visible { outline: 2px solid var(--facet-color, #b06a1a); outline-offset: -2px; } /* Month picker responsive */ @media (max-width: 768px) { .month-picker.open { width: 100%; max-width: 350px; } } @media (max-width: 480px) { .month-picker.open { width: 100%; max-width: none; left: 0; right: 0; } .mp-day { min-height: 44px; min-width: 44px; font-size: 14px; } .mp-grid { gap: 2px; padding: 4px; } } /* Status Pane - slides down from facet bar on right (mirrors menu bar on left) */ .status-pane { position: fixed; top: var(--facet-bar-height); right: 0; width: var(--status-pane-width); background: white; border-left: 1px solid var(--facet-border, #e0e0e0); border-bottom: 1px solid var(--facet-border, #e0e0e0); border-radius: 0 0 0 12px; /* Only bottom-left rounded */ /* Shadow only on left and bottom - offset down to avoid top bleed */ box-shadow: -4px 4px 8px -2px rgba(0, 0, 0, 0.1); z-index: var(--z-bars); overflow: hidden; /* Clip content during animation */ /* Slide animation */ max-height: 0; opacity: 0; transition: max-height 0.3s ease, opacity 0.2s ease; } .status-pane.visible { max-height: 400px; opacity: 1; } /* Facet-colored background tint */ .status-pane::before { content: ''; position: absolute; inset: 0; background: var(--facet-bg, transparent); border-radius: 0 0 0 12px; pointer-events: none; z-index: -1; } .status-pane-content { padding: 16px; max-height: 380px; overflow-y: auto; } .status-pane-content h3 { margin: 0 0 12px 0; font-size: 16px; font-weight: 600; color: #333; } .status-pane-content p { margin: 0; font-size: 14px; color: #666; } .facet-bar .facet-pills-container { flex: 1; display: flex; align-items: center; justify-content: center; overflow: hidden; padding-top: 4px; padding-bottom: 4px; min-width: 0; /* Allow container to shrink below content size */ } /* Menu Bar (left sidebar) */ .menu-bar { position: fixed; top: var(--facet-bar-height); left: 0; width: var(--menu-bar-width-minimal); max-height: calc(100vh - var(--facet-bar-height)); background: white; border-right: none; /* No border on container - items have their own borders */ z-index: calc(var(--z-bars) + 1); /* Above app bar */ transition: width 0.3s ease, background 0.3s ease, box-shadow 0.3s ease, border-radius 0.3s ease; overflow: hidden; /* Clip all content to rounded corner */ border-bottom-right-radius: 12px; display: flex; flex-direction: column; } /* Scrollable container for menu items */ .menu-bar .menu-items { overflow-y: auto; overflow-x: hidden; scrollbar-width: none; /* Firefox */ } ul.menu-items { list-style: none; margin: 0; padding: 0; } .menu-bar .menu-items::-webkit-scrollbar { display: none; /* Chrome, Safari, Edge */ } /* Scroll overflow shadows on .menu-items */ .menu-bar .menu-items::before, .menu-bar .menu-items::after { content: ''; display: block; position: sticky; left: 0; right: 0; height: 28px; pointer-events: none; z-index: 1; opacity: 0; transition: opacity 0.2s ease; } .menu-bar .menu-items::before { top: 0; margin-bottom: -28px; background: linear-gradient(to bottom, rgba(0,0,0,0.06), transparent); } .menu-bar .menu-items::after { bottom: 0; margin-top: -28px; background: linear-gradient(to top, rgba(0,0,0,0.06), transparent); } .menu-bar .menu-items.scroll-shadow-top::before { opacity: 1; } .menu-bar .menu-items.scroll-shadow-bottom::after { opacity: 1; } body.menu-full .menu-bar { width: var(--menu-bar-width-full); background: linear-gradient(var(--facet-bg, transparent), var(--facet-bg, transparent)), white; border-right: 1px solid var(--facet-border, #e0e0e0); box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1); border-bottom-right-radius: 0; /* Remove rounded corner when expanded */ } .menu-bar .menu-item { padding: 8px 0; display: flex; align-items: center; cursor: pointer; transition: background 0.2s, transform 0.3s ease, max-height 0.3s ease, opacity 0.3s ease, padding 0.3s ease, border-radius 0.3s ease; border-bottom: none; border-left: 3px solid transparent; border-right: 1px solid var(--facet-border, #e0e0e0); /* Always present - extends naturally with item animation */ color: inherit; white-space: nowrap; position: relative; overflow: hidden; flex-shrink: 0; /* Don't compress - let container scroll instead */ } .menu-bar .menu-item-link { display: flex; align-items: center; text-decoration: none; color: inherit; flex: 1; min-width: 0; } /* Hide unstarred apps in menu-minimal state */ .menu-bar .menu-item[data-starred="false"] { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; pointer-events: none; } /* Always show current app, even if unstarred in menu-minimal state */ .menu-bar .menu-item[data-starred="false"].current { max-height: 50px; opacity: 1; padding-top: 8px; padding-bottom: 8px; pointer-events: auto; } /* Show all apps when menu-full */ body.menu-full .menu-bar .menu-item[data-starred="false"] { max-height: 50px; opacity: 1; padding-top: 8px; padding-bottom: 8px; pointer-events: auto; } body.menu-full .menu-bar .menu-item.dragging { opacity: 0.5; cursor: grabbing; } .menu-bar .menu-item.drag-over { border-top: 2px solid var(--facet-color); } /* Keyboard reorder visual feedback */ body.menu-full .menu-bar .menu-item.reordering { outline: 2px dashed var(--facet-color, #b06a1a); outline-offset: -2px; background: color-mix(in srgb, var(--facet-color, #b06a1a) 8%, transparent); } /* Apply facet background to menu items in menu-minimal state */ body:not(.menu-full) .menu-bar .menu-item { background: var(--facet-bg, white); } /* Hover state for menu items */ .menu-bar .menu-item:hover { background: rgba(0, 0, 0, 0.05); } /* Active app state - stronger background + accent bar */ .menu-bar .menu-item.current { background: rgba(0, 0, 0, 0.08); border-left-color: var(--facet-color); } /* In menu-minimal state, layer hover tint over facet background */ body:not(.menu-full) .menu-bar .menu-item:hover { background: linear-gradient(rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05)), var(--facet-bg, white); } /* In menu-minimal state, active app with stronger tint + accent bar */ body:not(.menu-full) .menu-bar .menu-item.current { background: linear-gradient(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.08)), var(--facet-bg, white); border-left-color: var(--facet-color); } .menu-bar .menu-item .icon { font-size: 20px; width: var(--menu-bar-width-minimal); text-align: center; flex-shrink: 0; } .menu-bar .menu-item .label { font-size: 14px; padding-right: 4px; flex: 1; } .menu-bar .menu-item .star-toggle { display: none; background: none; border: none; font: inherit; font-size: 16px; min-width: 44px; min-height: 44px; align-items: center; justify-content: center; padding: 0; color: inherit; cursor: pointer; opacity: 0; transition: opacity 0.2s; flex-shrink: 0; user-select: none; } body.menu-full .menu-bar .menu-item .star-toggle { display: inline-flex; } /* Show star on hover or when starred */ body.menu-full .menu-bar .menu-item:hover .star-toggle, .menu-bar .menu-item[data-starred="true"] .star-toggle { opacity: 1; } .menu-bar .menu-item .star-toggle:focus-visible { opacity: 1; } .menu-bar .menu-item[data-starred="true"] .star-toggle { color: #f59e0b; } /* Drag handle */ .menu-bar .menu-item .drag-handle { display: none; background: none; border: none; font: inherit; font-size: 20px; min-width: 44px; min-height: 44px; align-items: center; justify-content: center; padding: 0; cursor: grab; opacity: 0; transition: opacity 0.2s; flex-shrink: 0; user-select: none; color: #999; } body.menu-full .menu-bar .menu-item .drag-handle { display: inline-flex; } body.menu-full .menu-bar .menu-item:hover .drag-handle { opacity: 1; } body.menu-full .menu-bar .menu-item .drag-handle:active { cursor: grabbing; } /* Visual separator after last starred app */ .menu-bar .menu-item.last-starred { border-bottom: 1px solid var(--facet-border, #e0e0e0); padding-bottom: 12px; margin-bottom: 8px; } /* Menu Submenus - hover pop-outs for app quick-links */ .menu-submenu { position: fixed; min-width: 160px; background: white; border: 1px solid var(--facet-border, #e0e0e0); border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); padding: 4px 0; opacity: 0; pointer-events: none; transform: translateX(-8px); transition: opacity 0.15s ease, transform 0.15s ease; z-index: calc(var(--z-bars) + 10); } /* Show when visible class is added via JS */ .menu-submenu.visible { opacity: 1; pointer-events: auto; transform: translateX(0); } .menu-submenu-item { display: flex; align-items: center; padding: 8px 12px; text-decoration: none; color: inherit; font-size: 13px; transition: background 0.15s ease; gap: 8px; white-space: nowrap; } .menu-submenu-item:hover { background: rgba(0, 0, 0, 0.05); } .menu-submenu-item:first-child { border-radius: 7px 7px 0 0; } .menu-submenu-item:last-child { border-radius: 0 0 7px 7px; } .menu-submenu-item:only-child { border-radius: 7px; } .submenu-icon { font-size: 14px; width: 20px; text-align: center; flex-shrink: 0; } .submenu-label { flex: 1; } .submenu-badge { background: var(--facet-color, #b06a1a); color: white; font-size: 10px; font-weight: 600; padding: 2px 6px; border-radius: 8px; min-width: 18px; text-align: center; line-height: 1.2; } /* Menu bar icon badges */ .menu-bar .menu-item .icon { position: relative; } .menu-badge { position: absolute; bottom: -2px; right: 4px; min-width: 15px; height: 15px; font-size: 9px; font-weight: 600; background: #ef4444; color: white; border-radius: 7px; display: flex; align-items: center; justify-content: center; padding: 0 3px; line-height: 1; } /* Menu expander (down arrow below last visible app icon) */ .menu-bar .menu-expander { min-width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; font: inherit; font-size: 16px; cursor: pointer; color: inherit; border: none; border-bottom: 1px solid var(--facet-border, #e0e0e0); border-right: 1px solid var(--facet-border, #e0e0e0); background: var(--facet-bg, white); transition: background 0.2s; user-select: none; position: relative; border-bottom-right-radius: 12px; flex-shrink: 0; /* Never shrink - always visible at bottom */ } .menu-bar .menu-expander:hover { background: rgba(0,0,0,0.05); } /* Hide only when sidebar is menu-full (keep visible during menu-all) */ body.menu-full .menu-bar .menu-expander { display: none; } /* Show all apps in menu-all state (icons only, narrow width) */ body.menu-all .menu-bar .menu-item[data-starred="false"] { max-height: 50px; opacity: 1; padding-top: 8px; padding-bottom: 8px; pointer-events: auto; } /* Keep sidebar narrow in menu-all state (icons only) */ body.menu-all .menu-bar { width: var(--menu-bar-width-minimal); } .facet-pill { appearance: none; font-family: inherit; color: inherit; line-height: inherit; display: flex; align-items: center; padding: 8px 16px; margin-right: 8px; border-radius: 20px; background: #f5f5f5; border: 1px solid #ddd; cursor: grab; font-size: 14px; transition: transform 0.2s ease, opacity 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background 0.2s ease, color 0.2s ease; user-select: none; position: relative; min-width: 0; /* Allow pill to shrink below content size */ flex-shrink: 1; /* Allow shrinking when space is tight */ } .facet-pill .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; /* Can shrink to zero width */ flex-shrink: 1; user-select: none; pointer-events: none; } /* Dim unselected pills when a facet is selected */ .facet-pill:not(.selected) { opacity: 0.85; } .facet-pills-container:not(:has(.selected)) .facet-pill { opacity: 1; } /* "all" label - muted caption before first pill in all-mode */ .facet-all-label { font-size: 12px; color: #999; padding: 0 8px 0 4px; pointer-events: none; user-select: none; white-space: nowrap; } /* Hide "all" label when a facet is selected (CSS backup for JS toggle) */ .facet-pills-container:has(.selected) .facet-all-label { display: none; } /* Empty state: no facets configured */ .facet-empty-state { font-size: 12px; color: #999; white-space: nowrap; user-select: none; padding: 0 4px; } .facet-empty-create { background: none; border: none; color: #777; cursor: pointer; text-decoration: underline; font-size: inherit; font-family: inherit; padding: 0; } .facet-empty-create:hover { color: #555; } .facet-pill:hover { opacity: 1; border-color: var(--pill-color, #999); transform: translateY(-1px); box-shadow: 0 2px 4px rgba(0,0,0,0.1); background: var(--pill-bg, #f5f5f5); } .facet-pill.selected { opacity: 1; background: var(--pill-color); color: white; border-color: var(--pill-color); font-weight: 600; } .facet-pill .emoji-container { position: relative; font-size: 24px; line-height: 1; margin-right: 8px; display: flex; align-items: center; user-select: none; pointer-events: none; flex-shrink: 0; /* Never shrink the emoji */ } .facet-pill .emoji { display: block; user-select: none; pointer-events: none; } .facet-pill .facet-badge { position: absolute; bottom: -2px; right: -2px; min-width: 15px; height: 15px; font-size: 9px; font-weight: 600; background: #ef4444; color: white; border-radius: 7px; display: flex; align-items: center; justify-content: center; padding: 0 3px; line-height: 1; user-select: none; pointer-events: none; } .status-icon .quiet-notif-badge { position: absolute; bottom: 0; right: 0; min-width: 16px; height: 16px; border-radius: 8px; padding: 0 3px; font-size: 10px; font-weight: 700; background: #ef4444; color: white; display: flex; align-items: center; justify-content: center; pointer-events: none; user-select: none; } /* Drag-and-drop states */ .facet-pill:active { cursor: grabbing; } .facet-pill.dragging { opacity: 0.5; cursor: grabbing; transform: scale(1.05) rotate(2deg); box-shadow: 0 6px 16px rgba(0,0,0,0.2); z-index: calc(var(--z-bars) + 1); /* Above bars, below modals */ transition: none; /* Disable transitions while dragging */ } .facet-pill.drag-over { /* Subtle indicator only - actual reordering happens via DOM manipulation */ transform: scale(0.95); } /* Apps without facet support - all pills identical, no selection */ .facet-bar.facets-disabled .facet-pill { pointer-events: none; cursor: default; opacity: 0.5; } /* App Bar (bottom) */ .app-bar { position: fixed; bottom: 12px; left: 50%; transform: translateX(-50%); width: 80%; z-index: var(--z-bars); min-height: var(--app-bar-height); padding: 0; display: flex; flex-direction: column; border-radius: 12px; border: 1px solid var(--facet-border, #e0e0e0); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 -2px 8px rgba(0, 0, 0, 0.06); } .app-bar::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: white; pointer-events: none; z-index: -2; border-radius: 12px; } .app-bar::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: var(--facet-bg, transparent); transition: background-color 0.3s ease; pointer-events: none; z-index: -1; border-radius: 12px; } /* Response panel (above input row) */ .chat-bar-response-panel { max-height: 0; overflow: hidden; padding: 0 16px; position: relative; z-index: 1; transition: max-height 0.2s ease, padding 0.2s ease; } .app-bar--glance .chat-bar-response-panel { max-height: 200px; padding: 12px 16px 0; } .chat-bar-separator { height: 1px; background: var(--facet-border, #e0e0e0); margin: 12px -16px 0; } .chat-bar-dismiss { position: absolute; top: 8px; right: 8px; min-width: 44px; min-height: 44px; border: none; background: transparent; color: #999; font-size: 14px; cursor: pointer; border-radius: 4px; display: flex; align-items: center; justify-content: center; z-index: 2; } .chat-bar-dismiss:hover { background: rgba(0, 0, 0, 0.06); color: #666; } /* Input row */ .chat-bar-input-row { display: flex; flex-direction: row; align-items: center; gap: 12px; padding: 0 16px; min-height: var(--app-bar-height); } /* Chat Bar Elements */ .chat-bar-input { flex: 1; resize: none; border: 1px solid #ddd; border-radius: 20px; padding: 0.75em 1em; font-family: inherit; font-size: 14px; line-height: 1.5; max-height: 120px; min-height: 42px; background: transparent; position: relative; z-index: 1; } .chat-bar-input:focus { outline: none; border-color: var(--facet-color, #b06a1a); } .chat-bar-input::placeholder { color: #999; } .chat-bar-send { width: 44px; height: 44px; border-radius: 50%; border: none; background: var(--facet-color, #b06a1a); color: white; cursor: pointer; display: flex; align-items: center; justify-content: center; position: relative; z-index: 1; flex-shrink: 0; } .chat-bar-send:hover { opacity: 0.85; } @media (max-width: 768px) { .chat-bar-send { width: 48px; height: 48px; } } .chat-bar-thinking { display: flex; align-items: center; gap: 0.5em; color: #999; font-size: 13px; position: relative; z-index: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; } .chat-bar-thinking > [aria-hidden="true"] { overflow: hidden; text-overflow: ellipsis; min-width: 0; } .chat-bar-thinking-dot { width: 8px; height: 8px; background: var(--facet-color, #b06a1a); border-radius: 50%; animation: chat-bar-pulse 1s ease-in-out infinite; } @keyframes chat-bar-pulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } } .thinking-elapsed { opacity: 0.5; font-variant-numeric: tabular-nums; } .chat-bar-response { font-size: 13px; line-height: 1.5; color: #666; max-height: 5em; overflow: hidden; padding-right: 28px; position: relative; z-index: 1; } .chat-bar-response--error { color: #d97706; } /* ======================================== * Conversation Panel * Expandable focus-mode conversation surface. * The chat bar expands upward to 80% viewport. * Backdrop blur excludes aruco corner-tags via z-index layering: * backdrop at z-bars+49 < corner-tags at z-tags (400). * ======================================== */ /* Backdrop — blurs convey content when panel is open */ .conversation-backdrop { position: fixed; inset: 0; z-index: calc(var(--z-bars) + 49); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); background: rgba(0, 0, 0, 0.08); opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .conversation-backdrop.visible { opacity: 1; pointer-events: auto; } /* Panel expanded state */ .app-bar.app-bar--focused { height: 80vh; /* fallback for browsers without dvh */ height: 80dvh; bottom: 0; border-radius: 12px 12px 0 0; z-index: calc(var(--z-bars) + 50); animation: panel-expand 0.3s cubic-bezier(0.4, 0, 0.2, 1); } /* Panel closing animation */ .app-bar.app-bar--dismissing { z-index: calc(var(--z-bars) + 50); animation: panel-collapse 0.25s ease forwards; } @keyframes panel-expand { from { height: var(--app-bar-height); bottom: 12px; border-radius: 12px; } } @keyframes panel-collapse { from { height: 80vh; height: 80dvh; bottom: 0; border-radius: 12px 12px 0 0; } to { height: var(--app-bar-height); bottom: 12px; border-radius: 12px; } } @media (max-width: 768px) { .app-bar.app-bar--focused { width: calc(100% - 16px); } } /* Conversation messages area */ .conversation-messages { display: none; flex-direction: column; gap: 16px; overflow-y: auto; padding: 16px; flex: 1; min-height: 0; background: #fffcf9; scrollbar-width: thin; scrollbar-color: rgba(0, 0, 0, 0.15) transparent; } .conversation-messages::-webkit-scrollbar { width: 6px; } .conversation-messages::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15); border-radius: 3px; } .app-bar.app-bar--focused .conversation-messages { display: flex; } /* Hide inline response panel in panel mode */ .app-bar.app-bar--focused .chat-bar-response-panel { display: none; } /* Separator between messages and input (panel mode only) */ .conversation-separator { display: none; } .app-bar.app-bar--focused .conversation-separator { display: block; height: 1px; background: var(--facet-border, #e0e0e0); flex-shrink: 0; } /* Message bubbles */ .conversation-message { max-width: 85%; padding: 10px 14px; border-radius: 16px; font-size: 14px; line-height: 1.5; word-wrap: break-word; white-space: pre-wrap; } .conversation-message.user { align-self: flex-end; background: var(--facet-color, #b06a1a); color: white; border-bottom-right-radius: 4px; } .conversation-message.agent { align-self: flex-start; background: #f5f0eb; color: #1f2937; border-bottom-left-radius: 4px; white-space: normal; word-break: break-word; overflow-wrap: break-word; } .conversation-message.agent p { margin: 0 0 0.5em 0; } .conversation-message.agent p:last-child { margin-bottom: 0; } .conversation-message.agent ul, .conversation-message.agent ol { margin: 0.25em 0 0.5em 0; padding-left: 1.5em; } .conversation-message.agent li { margin-bottom: 0.2em; } .conversation-message.agent code { background: rgba(0, 0, 0, 0.06); padding: 0.15em 0.35em; border-radius: 4px; font-size: 0.9em; font-family: 'SF Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', monospace; } .conversation-message.agent pre { background: rgba(0, 0, 0, 0.06); padding: 0.6em 0.8em; border-radius: 6px; overflow-x: auto; margin: 0.4em 0; } .conversation-message.agent pre code { background: none; padding: 0; border-radius: 0; font-size: 0.85em; white-space: pre; } .conversation-message.agent blockquote { border-left: 3px solid rgba(0, 0, 0, 0.15); margin: 0.4em 0; padding: 0.2em 0 0.2em 0.8em; color: #4b5563; } .conversation-message.agent h1, .conversation-message.agent h2, .conversation-message.agent h3, .conversation-message.agent h4, .conversation-message.agent h5, .conversation-message.agent h6 { margin: 0.6em 0 0.3em 0; font-weight: 600; line-height: 1.3; } .conversation-message.agent h1 { font-size: 1.2em; } .conversation-message.agent h2 { font-size: 1.1em; } .conversation-message.agent h3 { font-size: 1.05em; } .conversation-message.agent a { color: #b06a1a; text-decoration: underline; text-decoration-color: rgba(176, 106, 26, 0.3); } .conversation-message.agent a:hover { text-decoration-color: rgba(176, 106, 26, 0.7); } .conversation-message.agent hr { border: none; border-top: 1px solid rgba(0, 0, 0, 0.1); margin: 0.5em 0; } .conversation-message.agent.thinking { display: flex; align-items: center; gap: 0.5em; color: #999; font-size: 13px; background: #f5f0eb; } .conversation-message.error { align-self: flex-start; background: rgba(217, 119, 6, 0.06); color: #1f2937; border-left: 4px solid #d97706; border-bottom-left-radius: 4px; } .conversation-message.error::before { content: '\26A0\FE0F '; color: #d97706; } /* Error log display */ #error-log { display: none; position: fixed; bottom: 0; left: 0; right: 0; background: #111; color: #eee; padding: 1em; font: 12px monospace; max-height: 30vh; overflow-y: auto; border-top: 2px solid #ff3b30; z-index: var(--z-notifications); box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.5); } #error-log-dismiss { position: sticky; top: 0; float: right; background: #222; color: #eee; border: 1px solid #444; padding: 2px 8px; font: 12px monospace; cursor: pointer; } /* Notification Center */ .notification-center { position: fixed; top: calc(var(--facet-bar-height) + 4px); right: 20px; width: 280px; z-index: var(--z-notifications); pointer-events: none; display: flex; flex-direction: column; gap: 8px; } /* Notification Card */ .notification-card { background: white; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); padding: 12px; position: relative; overflow: hidden; pointer-events: all; animation: slideIn 0.3s ease; transition: transform 0.2s ease, box-shadow 0.2s ease; cursor: default; display: block; } /* Reset anchor tag styles when used as notification card */ a.notification-card { color: inherit; text-decoration: none; } .notification-card[data-action]:not([data-action=""]) { cursor: pointer; } .notification-card:hover { transform: translateX(-4px); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2); } @keyframes slideIn { from { opacity: 0; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } } @keyframes countdownShrink { from { transform: scaleX(1); } to { transform: scaleX(0); } } .notification-countdown { position: absolute; bottom: 0; left: 0; right: 0; height: 3px; background: #3b82f6; transform-origin: left; animation: countdownShrink linear forwards; border-radius: 0 0 8px 8px; } .notification-card:hover .notification-countdown, .notification-card:focus-within .notification-countdown { animation-play-state: paused; } /* Notification Header */ .notification-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } .notification-app-icon { font-size: 16px; line-height: 1; } .notification-app-name { font-size: 11px; color: #9ca3af; text-transform: capitalize; flex: 1; } .notification-close { background: none; border: none; font-size: 20px; line-height: 1; color: #9ca3af; cursor: pointer; min-width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; border-radius: 4px; transition: background 0.2s, color 0.2s; } .notification-close:hover { background: #f3f4f6; color: #374151; } /* Notification Body */ .notification-body { position: relative; } .notification-title { font-weight: 600; font-size: 14px; color: #1f2937; margin-bottom: 4px; line-height: 1.3; } .notification-message { font-size: 13px; color: #6b7280; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .notification-badge { position: absolute; top: 0; right: 0; background: #ef4444; color: white; font-size: 11px; font-weight: 600; padding: 2px 6px; border-radius: 10px; min-width: 20px; text-align: center; line-height: 1.2; } /* Notification Footer */ .notification-footer { margin-top: 8px; padding-top: 8px; border-top: 1px solid #f3f4f6; } .notification-time { font-size: 11px; color: #9ca3af; } /* Responsive */ @media (max-width: 768px) { .notification-center { top: calc(var(--facet-bar-height) + 4px); right: 8px; left: 8px; width: auto; } .notification-card { width: 100%; } } /* Modal styling */ .modal { display: none; position: fixed; z-index: var(--z-modals); left: 0; top: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); } .modal-content { background: white; margin: 5% auto; padding: 1em; border-radius: 8px; max-width: 500px; max-height: 80vh; overflow: auto; position: relative; } .close { position: absolute; top: 10px; right: 15px; cursor: pointer; font-size: 24px; } /* Corner Tags - fixed markers for screen region detection */ .corner-tags { position: fixed; inset: 0; pointer-events: none; z-index: var(--z-tags); } .corner-tag { position: absolute; width: 16px; height: 16px; background: var(--facet-color); mask-size: contain; -webkit-mask-size: contain; image-rendering: pixelated; image-rendering: crisp-edges; /* Firefox fallback */ } .corner-tag-tl { top: 0; left: 0; mask-image: url('tags/tag-6.png'); -webkit-mask-image: url('tags/tag-6.png'); } .corner-tag-tr { top: 0; right: 0; mask-image: url('tags/tag-7.png'); -webkit-mask-image: url('tags/tag-7.png'); } .corner-tag-bl { bottom: 32px; left: 0; mask-image: url('tags/tag-4.png'); -webkit-mask-image: url('tags/tag-4.png'); } .corner-tag-br { bottom: 32px; right: 0; mask-image: url('tags/tag-2.png'); -webkit-mask-image: url('tags/tag-2.png'); } /* ======================================== * Facet Add Button * Plus button to create new facets * ======================================== */ .facet-add-pill { appearance: none; font-family: inherit; color: inherit; line-height: inherit; display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; background: transparent; border: 2px dashed #ccc; cursor: pointer; font-size: 20px; color: #999; transition: all 0.2s ease; flex-shrink: 0; } .facet-add-pill:hover { border-color: var(--facet-color, #b06a1a); color: var(--facet-color, #b06a1a); background: var(--facet-bg, rgba(176, 106, 26, 0.1)); transform: scale(1.1); } /* ======================================== * Facet Create Modal * Simple modal for creating new facets * ======================================== */ .facet-create-modal { display: none; position: fixed; z-index: var(--z-modals); left: 0; top: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); } .facet-create-modal.visible { display: flex; align-items: center; justify-content: center; } .facet-create-content { background: white; padding: 24px; border-radius: 12px; width: 90%; max-width: 400px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); } .facet-create-content h3 { margin: 0 0 20px 0; font-size: 18px; font-weight: 600; color: #333; } .facet-create-field { margin-bottom: 16px; } .facet-create-field label { display: block; font-size: 14px; font-weight: 500; color: #555; margin-bottom: 6px; } .facet-create-field input { width: 100%; padding: 10px 12px; border: 2px solid #ddd; border-radius: 8px; font-size: 16px; transition: border-color 0.2s; } .facet-create-field input:focus { outline: none; border-color: var(--facet-color, #b06a1a); } .facet-create-slug { font-size: 13px; color: #888; margin-top: 6px; font-family: monospace; } .facet-create-slug.has-slug::before { content: "→ "; } .facet-create-buttons { display: flex; justify-content: flex-end; gap: 12px; margin-top: 24px; } .facet-create-buttons button { padding: 10px 20px; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; } .facet-create-cancel { background: #f5f5f5; border: 1px solid #ddd; color: #666; } .facet-create-cancel:hover { background: #e5e5e5; } .facet-create-submit { background: var(--facet-color, #b06a1a); border: none; color: white; } .facet-create-submit:hover { opacity: 0.9; } .facet-create-submit:disabled { background: #ccc; cursor: not-allowed; } .facet-create-error { color: #dc2626; font-size: 13px; margin-top: 8px; display: none; } .facet-create-error.visible { display: block; } /* Button reset for a11y-converted controls */ button#hamburger, button.status-icon, button.close { appearance: none; background: none; border: none; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; } /* Visually-hidden expand/collapse button - focusable but invisible */ .chat-bar-expand { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; background: none; font: inherit; color: inherit; } .chat-bar-expand:focus-visible { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; white-space: normal; font-size: 14px; } /* ======================================== * Reduced Motion * Respects prefers-reduced-motion user preference * ======================================== */ @media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; } .chat-bar-thinking-dot { animation: none; opacity: 1; } .status-indicator--connecting { animation: none; } .facet-pill:hover { transform: none; } .facet-pill.dragging { transform: none; } .facet-pill.drag-over { transform: none; } .facet-add-pill:hover { transform: none; } .menu-submenu { transform: none; } .notification-card:hover { transform: none; } } /* Focus-visible states for keyboard navigation */ .menu-bar .menu-item-link:focus-visible, .menu-submenu-item:focus-visible, .facet-pill:focus-visible, .facet-add-pill:focus-visible, #hamburger:focus-visible, .facet-bar .status-icon:focus-visible, .chat-bar-send:focus-visible, .chat-bar-dismiss:focus-visible, .date-nav-arrow:focus-visible, .facet-create-submit:focus-visible, .facet-create-cancel:focus-visible, button:focus-visible, a:focus-visible { outline: 2px solid var(--facet-color, #b06a1a); outline-offset: 2px; } /* Visually hidden — accessible to screen readers */ .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } /* Skip-to-content link — visible on focus */ .skip-link { position: absolute; top: -100%; left: 0; z-index: 9999; padding: 8px 16px; background: var(--facet-color, #b06a1a); color: #fff; text-decoration: none; font-size: 14px; border-radius: 0 0 4px 0; } .skip-link:focus { top: 0; }