responsiveness fix

This commit is contained in:
debu-2 2026-10-06 20:36:39 +05:30
parent 962f991580
commit 4ad05bf137
7 changed files with 671 additions and 5 deletions

View file

@ -25,7 +25,7 @@ export default function ComposeDock({ account, onSent, agentOpen = true }) {
const focusRef = useRef(null);
const viewport = useViewport();
const agentReserve = agentOpen && viewport.width >= 960 ? AGENT_PANEL_WIDTH + MAIL_GAP : 0;
const agentReserve = agentOpen && viewport.width >= 1200 ? AGENT_PANEL_WIDTH + MAIL_GAP : 0;
const dockRight = agentReserve + 16;
const expandedWindows = useMemo(

View file

@ -28,6 +28,8 @@ import {
import { useCallback, useEffect, useState } from "react";
import { getCurrentAccount, getMyCompanyDomain } from "../api";
import Brand from "./Brand";
import MobileChrome from "./MobileChrome";
import { ShellModeContext } from "../shellMode";
import CompanyDnsSetup from "./CompanyDnsSetup";
import CompanyDomains from "./CompanyDomains";
import CompanyAdministrators from "./CompanyAdministrators";
@ -110,6 +112,7 @@ export default function DashboardPage() {
const [domainError, setDomainError] = useState("");
const [active, setActive] = useState("Inbox");
const [menuOpen, setMenuOpen] = useState(false);
const [sheet, setSheet] = useState(null);
const [notice, setNotice] = useState("");
const [loading, setLoading] = useState(true);
const [mailRefreshKey, setMailRefreshKey] = useState(0);
@ -174,6 +177,7 @@ export default function DashboardPage() {
setCompanyActive(label);
setAgentNav(null);
setMenuOpen(false);
setSheet(null);
}
function selectMailItem(item) {
@ -190,6 +194,7 @@ export default function DashboardPage() {
setLens("all");
}
setMenuOpen(false);
setSheet(null);
}
function selectLabel(name) {
@ -198,6 +203,7 @@ export default function DashboardPage() {
setActive("Inbox");
setLens(name);
setMenuOpen(false);
setSheet(null);
}
function selectAgentItem(item, actionKey) {
@ -206,6 +212,32 @@ export default function DashboardPage() {
setLens("all");
setAgentNav(actionKey);
setMenuOpen(false);
const compact = window.matchMedia("(max-width: 1199px)").matches;
setSheet(actionKey === "handoff" || !compact ? null : "agent");
}
function openAgentDestination(actionKey) {
setCompanyActive(null);
setActive("Inbox");
setLens("all");
setAgentNav(actionKey);
setMenuOpen(false);
setSheet("agent");
}
function showMailboxForSheet() {
setCompanyActive(null);
setActive("Inbox");
setLens("all");
setMenuOpen(false);
}
function openSheet(next) {
if (next === "agent" || next === "calendar" || next === "notes") {
showMailboxForSheet();
setAgentNav(next === "agent" ? "ask" : null);
}
setSheet(next);
}
function openCompose(context = null) {
@ -277,10 +309,15 @@ export default function DashboardPage() {
: active;
return (
<div className="dashboard">
<ShellModeContext.Provider value={{ sheet, setSheet }}>
<div
className="dashboard"
data-sheet={sheet || undefined}
data-onboarding={isOrgOnboarding ? "true" : undefined}
>
<header className="dashboard-mobile-header">
<Brand />
<button aria-label="Open navigation" type="button" onClick={() => setMenuOpen(true)}>
<button aria-label="Open navigation" type="button" onClick={() => { setSheet(null); setMenuOpen(true); }}>
<Menu size={21} />
</button>
</header>
@ -525,7 +562,31 @@ export default function DashboardPage() {
}}
/>
)}
{sheet && sheet !== "more" && (
<button className="shell-drawer-scrim" type="button" aria-label="Close panel" onClick={() => setSheet(null)} />
)}
{!isOrgOnboarding && (
<MobileChrome
sheet={sheet}
mailActive={!sheet && !companyActive && agentNav !== "handoff"}
account={account}
onMail={() => selectMailItem("Inbox")}
onAgent={() => openSheet("agent")}
onCompose={() => openCompose()}
onCalendar={() => openSheet("calendar")}
onMore={() => setSheet((current) => (current === "more" ? null : "more"))}
onClose={() => setSheet(null)}
onSettings={() => selectMailItem("Settings")}
onNotes={() => openSheet("notes")}
onHandoff={() => selectAgentItem("Human Handoff", "handoff")}
onActionItems={() => openAgentDestination("actions")}
onSummaries={() => openAgentDestination("summaries")}
onIntegrations={() => openAgentDestination("integrations")}
onLogout={logout}
/>
)}
<ComposeDock account={account} onSent={emailSent} agentOpen={!companyActive} />
</div>
</ShellModeContext.Provider>
);
}

View file

@ -11,6 +11,7 @@ import {
RefreshCw,
Search,
Settings,
Sparkles,
Sun,
Tag,
Users,
@ -37,6 +38,8 @@ import MailRow from "./MailRow";
import MailboxEmptyState from "./MailboxEmptyState";
import MailboxSelectionBar from "./MailboxSelectionBar";
import StickyNotesPanel from "./StickyNotesPanel";
import { useShellMode } from "../shellMode";
import { shellTitle } from "./MobileChrome";
import {
categoryCounts,
emailCategory,
@ -118,6 +121,7 @@ export default function MailboxView({
onStats,
}) {
const token = sessionStorage.getItem("agmail_access_token");
const { sheet, setSheet } = useShellMode();
const [emails, setEmails] = useState([]);
const [nextCursor, setNextCursor] = useState(null);
const [total, setTotal] = useState(0);
@ -679,6 +683,14 @@ export default function MailboxView({
<button className="workspace-ask agent-action" type="button" onClick={() => runQuickAction("summarize")}>
<AgentSpark /> Ask Agent
</button>
<button
className="shell-agent-toggle"
type="button"
aria-label="Open AG Agent"
onClick={() => setSheet(sheet === "agent" ? null : "agent")}
>
<Sparkles size={16} />
</button>
</div>
<div className="workspace-zone workspace-zone-account">
<button type="button" className="workspace-icon" aria-label="Refresh" onClick={load}><RefreshCw size={16} /></button>
@ -840,7 +852,7 @@ export default function MailboxView({
</div>
)}
<div className={`mailbox-rows${isEmpty ? " is-empty" : ""}`} aria-busy={status.loading}>
<div className={`mailbox-rows${isEmpty ? " is-empty" : ""}${selectedCount > 0 ? " selecting" : ""}`} aria-busy={status.loading}>
{status.loading && <div className="mailbox-state loading">Loading messages…</div>}
{status.error && (
<div className="mailbox-state error" role="alert">
@ -916,7 +928,15 @@ export default function MailboxView({
</div>
</div>
<aside className="mailbox-rail">
<aside className={`mailbox-rail${sheet ? ` shell-${sheet}` : ""}`}>
{(sheet === "agent" || sheet === "calendar" || sheet === "notes") && (
<div className="shell-sheet-bar">
<button type="button" aria-label="Back" onClick={() => setSheet(null)}>
<ChevronLeft size={18} strokeWidth={1.75} />
</button>
<strong>{shellTitle(sheet)}</strong>
</div>
)}
<AgAgentPanel
account={account}
emails={listedEmails}

View file

@ -0,0 +1,101 @@
import {
CalendarDays,
CircleHelp,
HandHelping,
Inbox,
ListChecks,
LogOut,
MoreHorizontal,
Plug,
Plus,
Settings,
Sparkles,
StickyNote,
Sun,
} from "lucide-react";
const SHEET_LABEL = {
agent: "AG Agent",
calendar: "Calendar",
notes: "Notes",
};
export function shellTitle(sheet) {
return SHEET_LABEL[sheet] || "";
}
export default function MobileChrome({
sheet,
mailActive,
account,
onMail,
onAgent,
onCompose,
onCalendar,
onMore,
onClose,
onSettings,
onNotes,
onHandoff,
onActionItems,
onSummaries,
onIntegrations,
onLogout,
}) {
return (
<>
<nav className="mobile-bottom-nav" aria-label="App">
<button type="button" className={mailActive ? "active" : ""} onClick={onMail}>
<Inbox size={18} strokeWidth={1.75} />
<span>Mail</span>
</button>
<button type="button" className={sheet === "agent" ? "active" : ""} onClick={onAgent}>
<Sparkles size={18} strokeWidth={1.75} />
<span>Agent</span>
</button>
<button type="button" className="mobile-bottom-compose" onClick={onCompose}>
<span className="mobile-bottom-plus" aria-hidden="true"><Plus size={20} strokeWidth={2} /></span>
<span>Compose</span>
</button>
<button type="button" className={sheet === "calendar" ? "active" : ""} onClick={onCalendar}>
<CalendarDays size={18} strokeWidth={1.75} />
<span>Calendar</span>
</button>
<button type="button" className={sheet === "more" || sheet === "notes" ? "active" : ""} onClick={onMore}>
<MoreHorizontal size={18} strokeWidth={1.75} />
<span>More</span>
</button>
</nav>
{sheet === "more" && (
<div className="mobile-more-layer">
<button type="button" className="mobile-more-scrim" aria-label="Close more" onClick={onClose} />
<section className="mobile-more-sheet" role="dialog" aria-label="More">
<header className="mobile-more-head">
<strong>More</strong>
<button type="button" onClick={onClose} aria-label="Close">Close</button>
</header>
<div className="mobile-more-account">
<span>{account.first_name[0]}{account.last_name[0]}</span>
<div>
<strong>{account.first_name} {account.last_name}</strong>
<small>{account.email}</small>
</div>
<button type="button" aria-label="Log out" onClick={onLogout}><LogOut size={16} /></button>
</div>
<p>Workspace</p>
<button type="button" onClick={onSettings}><Settings size={16} /> Settings</button>
<button type="button" onClick={onNotes}><StickyNote size={16} /> Notes</button>
<button type="button" onClick={onClose}><CircleHelp size={16} /> Help</button>
<button type="button" onClick={onIntegrations}><Plug size={16} /> Integrations</button>
<button type="button" onClick={onClose}><Sun size={16} /> Appearance</button>
<p>Agent</p>
<button type="button" onClick={onHandoff}><HandHelping size={16} /> Human Handoff</button>
<button type="button" onClick={onActionItems}><ListChecks size={16} /> Action Items</button>
<button type="button" onClick={onSummaries}><Sparkles size={16} /> Summaries</button>
</section>
</div>
)}
</>
);
}

View file

@ -2,6 +2,7 @@ import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./styles.css";
import "./responsive.css";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>

473
frontend/src/responsive.css Normal file
View file

@ -0,0 +1,473 @@
/* Responsive presentation only. Desktop rules at min-width 1200px stay in styles.css. */
.mobile-bottom-nav,
.shell-agent-toggle,
.shell-drawer-scrim,
.shell-sheet-bar,
.mobile-more-layer { display:none; }
@media (min-width:768px) and (max-width:1199px) {
html,body { overflow-x:clip; }
.dashboard { display:grid; grid-template-columns:72px minmax(0,1fr); overflow-x:clip; }
.dashboard-mobile-header { display:none; }
.dashboard-sidebar {
width:72px;
position:sticky;
top:0;
left:auto;
transform:none;
padding:16px 8px 12px;
z-index:12;
}
.dashboard-brand-row { justify-content:center; padding:0; }
.dashboard-brand-row .brand > span:not(.brand-mark),
.dashboard-compose span,
.dashboard-sidebar-section h2,
.dashboard-nav-item em,
.dashboard-profile > div { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
.dashboard-brand-row > button,
.dashboard-profile > button { display:none; }
.dashboard-compose { width:44px; min-height:40px; margin:16px auto 0; padding:0; }
.dashboard-nav-item { justify-content:center; padding:0; gap:0; }
.dashboard-nav-item span { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); }
.dashboard-profile { grid-template-columns:34px; justify-content:center; padding-left:0; padding-right:0; }
.dashboard-content { min-width:0; padding:12px 12px 16px; }
.workspace-header { display:flex; flex-wrap:wrap; height:auto; min-height:56px; }
.workspace-zone-command { flex:1 1 220px; }
.workspace-zone-command .workspace-search { width:100%; max-width:none; }
.workspace-account div,
.workspace-account > svg { display:none; }
.mailbox-stage { grid-template-columns:minmax(0,1fr); }
.mailbox-rail {
display:flex;
position:fixed;
top:0;
right:0;
bottom:0;
width:min(320px,86vw);
min-width:0;
max-width:320px;
z-index:45;
transform:translateX(105%);
transition:transform .25s ease;
overflow:auto;
background:var(--canvas);
padding:12px;
box-shadow:-12px 0 40px rgba(8,8,33,.16);
}
.dashboard[data-sheet="agent"] .mailbox-rail,
.dashboard[data-sheet="calendar"] .mailbox-rail,
.dashboard[data-sheet="notes"] .mailbox-rail { transform:none; }
.mailbox-notes-pane { display:none; }
.mailbox-rail.shell-notes .mailbox-notes-pane { display:flex; min-height:0; max-height:none; }
.shell-agent-toggle {
width:36px;
height:36px;
display:grid;
place-items:center;
border:1px solid var(--agent-border);
border-radius:var(--radius-sm);
background:var(--agent-soft);
color:var(--agent);
}
.dashboard[data-sheet="agent"] .shell-drawer-scrim,
.dashboard[data-sheet="calendar"] .shell-drawer-scrim,
.dashboard[data-sheet="notes"] .shell-drawer-scrim {
display:block;
position:fixed;
inset:0;
z-index:44;
border:0;
background:#08082155;
}
.shell-sheet-bar {
display:flex;
align-items:center;
gap:8px;
min-height:44px;
margin-bottom:8px;
}
.shell-sheet-bar button {
width:32px;
height:32px;
display:grid;
place-items:center;
border:0;
border-radius:8px;
background:transparent;
color:#4a4652;
}
.shell-sheet-bar strong { font-size:14px; color:#171424; }
.compose-dock { right:12px !important; }
.compose-window {
width:min(640px,calc(100vw - 96px));
min-width:0;
max-width:calc(100vw - 96px);
height:min(640px,calc(100vh - 32px));
}
.compose-window.expanded {
width:min(900px,calc(100vw - 48px));
min-width:0;
max-width:calc(100vw - 48px);
height:min(78vh,calc(100vh - 32px));
}
}
@media (max-width:767px) {
html,body { overflow-x:clip; }
.dashboard { display:block; min-height:100vh; overflow-x:clip; }
.dashboard-mobile-header {
height:56px;
padding:0 16px;
display:flex;
align-items:center;
justify-content:space-between;
position:sticky;
top:0;
z-index:40;
border-bottom:1px solid var(--line);
background:#fffefd;
}
.dashboard-mobile-header .brand { font-size:18px; gap:8px; }
.dashboard-mobile-header .brand-mark { width:30px; height:28px; }
.dashboard-mobile-header > button { width:32px; height:32px; }
.dashboard-sidebar {
width:min(320px,86vw);
height:100vh;
max-height:100vh;
position:fixed;
top:0;
left:0;
z-index:70;
transform:translateX(-105%);
transition:transform .25s ease;
}
.dashboard-sidebar.open { transform:translateX(0); }
.dashboard-brand-row > button { display:grid; }
.dashboard-scrim { display:block; position:fixed; inset:0; z-index:65; border:0; background:#08082155; }
.dashboard-content {
min-width:0;
padding:0 0 calc(76px + env(safe-area-inset-bottom));
}
.dashboard-content > *:not(.mailbox-workspace) { padding:16px 16px 0; }
.dashboard-content h1 { font-size:28px; letter-spacing:-0.03em; overflow-wrap:anywhere; }
.human-handoff-page { max-width:none; margin:0; padding:0; }
.handoff-page-title,
.human-handoff-head h1.handoff-page-title { white-space:normal; font-size:22px; }
.human-handoff-card-body {
grid-template-areas:"avatar name status" "avatar email email" "actions actions actions";
grid-template-columns:36px minmax(0,1fr) auto;
}
.human-handoff-card-actions { margin-top:8px; flex-wrap:wrap; justify-content:flex-end; }
.human-handoff-card-chips { padding-left:0; }
.handoff-drawer,.handoff-test-modal,.people-drawer { width:100%; max-width:100%; }
.mailbox-workspace { gap:0; }
.workspace-header {
display:flex;
flex-direction:column;
align-items:stretch;
gap:8px;
min-height:0;
margin:12px 16px 8px;
padding:0;
background:transparent;
border-radius:0;
}
.workspace-zone-command { padding:0; }
.workspace-zone-command .workspace-search { width:100%; max-width:none; height:42px; }
.workspace-search-kbd,.workspace-search kbd { display:none; }
.workspace-zone-account { display:none; }
.workspace-zone-actions { width:100%; padding:0; justify-content:space-between; }
.mailbox-shell { margin-top:0; border-radius:0; }
.mailbox-stage { display:block; }
.mailbox-main-column { min-width:0; }
.mailbox-list-bar { min-height:40px; padding:0 8px; }
.mailbox-pagination-range { font-size:11px; }
.mailbox-categories {
display:flex;
flex-wrap:nowrap;
overflow-x:auto;
white-space:nowrap;
scrollbar-width:none;
}
.mailbox-categories::-webkit-scrollbar { display:none; }
.mailbox-categories button { flex:0 0 auto; }
.mailbox-filters { grid-template-columns:1fr; }
.mailbox-selection-bar { display:flex; flex-wrap:wrap; }
.mailbox-selection-actions { overflow-x:auto; flex-wrap:nowrap; max-width:100%; }
.mailbox-rows { max-height:none; }
.mailbox-row {
height:auto;
min-height:66px;
max-height:none;
padding:9px 12px;
grid-template-columns:30px minmax(0,1fr) auto;
grid-template-rows:auto auto auto;
column-gap:10px;
row-gap:1px;
align-items:center;
overflow:hidden;
}
.mailbox-check { position:absolute; width:1px; height:1px; margin:0; overflow:hidden; opacity:0; }
.mailbox-rows.selecting .mailbox-row { grid-template-columns:16px 30px minmax(0,1fr) auto; }
.mailbox-rows.selecting .mailbox-check {
position:static;
width:16px;
height:16px;
opacity:1;
grid-column:1;
grid-row:1 / span 3;
}
.mailbox-avatar { grid-column:1; grid-row:1 / span 3; align-self:center; width:30px; height:30px; }
.mailbox-rows.selecting .mailbox-avatar { grid-column:2; }
.mailbox-sender-wrap { grid-column:2; grid-row:1; align-self:end; }
.mailbox-rows.selecting .mailbox-sender-wrap { grid-column:3; }
.mailbox-sender { font-size:12px; font-weight:600; }
.mailbox-subject-line {
grid-column:2;
grid-row:2;
display:flex;
flex-direction:column;
align-items:flex-start;
white-space:normal;
overflow:hidden;
}
.mailbox-rows.selecting .mailbox-subject-line { grid-column:3; }
.mailbox-subject { font-size:11.5px; font-weight:550; }
.mailbox-preview { display:block; max-width:100%; font-size:10.5px; white-space:nowrap; }
.mailbox-preview-sep { display:none; }
.mailbox-row-labels {
grid-column:2;
grid-row:3;
min-width:0;
justify-content:flex-start;
overflow:hidden;
}
.mailbox-rows.selecting .mailbox-row-labels { grid-column:3; }
.mailbox-row-labels:empty { display:none; }
.mailbox-attachment-icon.empty { display:none; }
.mailbox-attachment-icon { grid-column:3; grid-row:2; width:16px; height:16px; }
.mailbox-rows.selecting .mailbox-attachment-icon { grid-column:4; }
.mailbox-row-rail { grid-column:3; grid-row:1; height:auto; align-self:start; }
.mailbox-rows.selecting .mailbox-row-rail { grid-column:4; }
.mailbox-time { font-size:9.5px; opacity:1; }
.mailbox-row:hover .mailbox-time,
.mailbox-row:focus-within .mailbox-time,
.mailbox-row.selected .mailbox-time { opacity:1; }
.mailbox-hover-actions { display:none; }
.mailbox-star { grid-column:3; grid-row:3; width:28px; height:28px; align-self:end; }
.mailbox-rows.selecting .mailbox-star { grid-column:4; }
.mailbox-rail { display:none; }
.dashboard[data-sheet="agent"] .mailbox-rail,
.dashboard[data-sheet="calendar"] .mailbox-rail,
.dashboard[data-sheet="notes"] .mailbox-rail {
display:flex;
position:fixed;
top:56px;
left:0;
right:0;
bottom:calc(64px + env(safe-area-inset-bottom));
width:auto;
min-width:0;
max-width:none;
z-index:35;
transform:none;
overflow:auto;
background:var(--canvas);
padding:12px 16px 16px;
}
.dashboard[data-sheet="agent"] .mailbox-main-column,
.dashboard[data-sheet="agent"] .workspace-header,
.dashboard[data-sheet="calendar"] .mailbox-main-column,
.dashboard[data-sheet="calendar"] .workspace-header,
.dashboard[data-sheet="notes"] .mailbox-main-column,
.dashboard[data-sheet="notes"] .workspace-header { display:none; }
.mailbox-notes-pane { display:none; min-height:0; max-height:none; }
.mailbox-rail.shell-notes .agent-panel { display:none; }
.mailbox-rail.shell-notes .mailbox-notes-pane { display:flex; width:100%; }
.shell-sheet-bar {
display:flex;
align-items:center;
gap:8px;
min-height:40px;
margin:0 0 8px;
}
.shell-sheet-bar button {
width:32px;
height:32px;
display:grid;
place-items:center;
border:0;
border-radius:8px;
background:transparent;
color:#4a4652;
}
.shell-sheet-bar strong { font:650 16px/1.2 "DM Sans"; color:#171424; }
.agent-panel { overflow:visible; }
.mail-detail-toolbar { overflow-x:auto; }
.mobile-bottom-nav {
position:fixed;
left:0;
right:0;
bottom:0;
z-index:50;
height:calc(64px + env(safe-area-inset-bottom));
padding:4px 6px env(safe-area-inset-bottom);
display:grid;
grid-template-columns:repeat(5,minmax(0,1fr));
align-items:center;
background:#fff;
border-top:1px solid var(--line);
}
.mobile-bottom-nav button {
min-width:0;
min-height:44px;
padding:0;
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
gap:2px;
border:0;
background:transparent;
color:#6f6b76;
font-size:10px;
font-weight:600;
}
.mobile-bottom-nav button.active { color:var(--coral); }
.mobile-bottom-plus {
width:36px;
height:28px;
display:grid;
place-items:center;
border-radius:10px;
color:#fff;
background:linear-gradient(180deg,#ff806d 0%,#ff5c55 100%);
box-shadow:0 4px 14px rgba(255,88,72,.24);
}
.mobile-bottom-compose { color:#c95945; }
body.compose-open .mobile-bottom-nav { display:none; }
.mobile-more-layer {
position:fixed;
inset:0;
z-index:60;
display:flex;
align-items:flex-end;
}
.mobile-more-scrim { position:absolute; inset:0; border:0; background:#08082155; }
.mobile-more-sheet {
position:relative;
width:100%;
max-height:min(78vh,640px);
overflow:auto;
padding:8px 16px calc(16px + env(safe-area-inset-bottom));
border-radius:16px 16px 0 0;
background:#fff;
box-shadow:0 -12px 40px rgba(8,8,33,.16);
}
.mobile-more-head,.mobile-more-account,.mobile-more-sheet > button {
display:flex;
align-items:center;
}
.mobile-more-head { justify-content:space-between; min-height:44px; }
.mobile-more-head strong { font-size:16px; color:#171424; }
.mobile-more-head button,.mobile-more-account button {
border:0;
background:transparent;
color:#6f6b76;
font-size:12px;
font-weight:600;
}
.mobile-more-account {
gap:10px;
margin-bottom:8px;
padding-bottom:10px;
border-bottom:1px solid var(--line);
}
.mobile-more-account > span {
width:34px;
height:34px;
display:grid;
place-items:center;
border-radius:11px;
background:linear-gradient(180deg,#ff9a82,#ff6f57);
color:#2a2038;
font-size:11px;
font-weight:700;
}
.mobile-more-account div { min-width:0; flex:1; display:grid; }
.mobile-more-account strong,.mobile-more-account small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.mobile-more-account strong { font-size:13px; color:#171424; }
.mobile-more-account small { color:#8d8792; font-size:11px; }
.mobile-more-sheet > p {
margin:12px 0 4px;
color:#97929a;
font-size:10px;
font-weight:700;
letter-spacing:.08em;
text-transform:uppercase;
}
.mobile-more-sheet > button {
width:100%;
min-height:42px;
gap:10px;
border:0;
border-radius:10px;
background:transparent;
color:#3d3948;
font-size:14px;
font-weight:600;
text-align:left;
}
.mobile-more-sheet > button:hover { background:#faf5f2; }
.compose-dock {
position:fixed;
inset:0;
right:0 !important;
bottom:0;
width:100%;
z-index:80;
align-items:stretch;
}
.compose-dock-expanded { width:100%; height:100%; }
.compose-window,
.compose-window.docked,
.compose-window.expanded {
position:fixed;
inset:0;
left:0;
top:0;
right:0;
bottom:0;
transform:none;
width:100%;
min-width:0;
max-width:none;
height:100dvh;
border-radius:0;
z-index:80;
}
.dashboard-notice { left:16px; right:16px; bottom:calc(76px + env(safe-area-inset-bottom)); }
}
@media (max-width:1199px) {
.mailbox-rail.shell-calendar .agent-panel-hello,
.mailbox-rail.shell-calendar .agent-stat-grid,
.mailbox-rail.shell-calendar .agent-quick,
.mailbox-rail.shell-calendar .agent-attention-block,
.mailbox-rail.shell-calendar .agent-deadlines,
.mailbox-rail.shell-calendar .agent-panel-note,
.mailbox-rail.shell-calendar .agent-loading-block,
.mailbox-rail.shell-calendar .agent-caught-up,
.mailbox-rail.shell-calendar .agent-ready-card,
.mailbox-rail.shell-calendar .agent-email-context,
.mailbox-rail.shell-calendar .agent-insight,
.mailbox-rail.shell-calendar .mailbox-notes-pane,
.mailbox-rail.shell-agent .mailbox-notes-pane { display:none; }
.mailbox-rail.shell-notes .agent-panel { display:none; }
}

10
frontend/src/shellMode.js Normal file
View file

@ -0,0 +1,10 @@
import { createContext, useContext } from "react";
export const ShellModeContext = createContext({
sheet: null,
setSheet: () => {},
});
export function useShellMode() {
return useContext(ShellModeContext);
}