@layer layout {
  /* Signed-in shell: sidebar + content. The gradient paints the sidebar column past the viewport. */
  .app-shell {
    display: flex; min-height: 100vh; min-height: 100dvh; overflow-x: clip;
    background: linear-gradient(90deg, var(--sidebar) 247px, var(--sidebar-border) 247px 248px, var(--background) 248px);
  }

  .app-sidebar {
    position: sticky; top: 0; height: 100vh; height: 100dvh;
    width: 248px; flex: none; display: flex; flex-direction: column;
    background: var(--sidebar); color: var(--sidebar-foreground);
    border-right: 1px solid var(--sidebar-border); font-size: 13px;
  }
  .sidebar-head { padding: 10px; border-bottom: 1px solid var(--sidebar-border); }

  .brand { display: flex; align-items: center; gap: 8px; min-width: 0; color: inherit; text-decoration: none; border-radius: var(--radius-md); }
  .brand:hover { text-decoration: none; }
  .brand-mark { display: block; width: 24px; height: 24px; flex: none; }
  .brand-lockup { display: block; height: 32px; width: auto; }
  .brand-tile { fill: var(--brand-tile); }
  .brand-word { fill: var(--brand-word); }
  .sidebar-mention {
    display: flex; align-items: center; justify-content: center; gap: 4px; margin: 0; padding: 8px 0 10px;
    color: var(--muted-foreground); font-size: var(--text-meta); line-height: 20px;
  }
  .brand-mono-lockup { display: block; height: 11px; width: auto; }
  .brand-text { min-width: 0; display: flex; flex-direction: column; }
  .brand-name { font-weight: 600; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .brand-meta { color: var(--muted-foreground); line-height: 1.3; }

  /* Positioned so absolute children (visually-hidden labels) are clipped by it: otherwise they hang
     off the sticky sidebar below the fold and make the whole page scroll. */
  .sidebar-nav { position: relative; flex: 1; min-height: 0; overflow-y: auto; padding: 6px 8px 10px; display: flex; flex-direction: column; gap: 1px; }
  .sidebar-section {
    padding: 14px 8px 4px; color: var(--muted-foreground);
    font-size: 13px; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase;
  }
  .sidebar-link {
    position: relative; display: flex; align-items: center; gap: 8px;
    min-height: 32px; padding: 4px 8px; border-radius: 6px; color: inherit; text-decoration: none;
  }
  .sidebar-link svg { width: 14px; height: 14px; flex: none; color: var(--muted-foreground); }
  .sidebar-link:is(:hover, :active) { background: var(--sidebar-accent); text-decoration: none; }
  .sidebar-link[aria-current="page"] { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); font-weight: 600; }
  .sidebar-link[aria-current="page"]::before {
    content: ""; position: absolute; left: 2px; top: 7px; bottom: 7px; width: 2px; border-radius: 2px; background: var(--jx-accent);
  }
  .sidebar-link[aria-current="page"] svg { color: var(--jx-accent); }

  .sidebar-foot {
    border-top: 1px solid var(--sidebar-border); padding: 8px; padding-bottom: calc(8px + var(--safe-bottom));
    display: flex; align-items: center; gap: 8px;
  }
  .sidebar-me {
    min-width: 0; flex: 1; display: flex; align-items: center; gap: 8px;
    margin: -4px 0 -4px -4px; padding: 4px; border: 0; border-radius: 6px; background: transparent;
    font: inherit; text-align: start; color: inherit; text-decoration: none; cursor: pointer;
  }
  .sidebar-me:is(:hover, :active, .is-current, [aria-expanded="true"]) { background: var(--sidebar-accent); text-decoration: none; }
  .me { min-width: 0; flex: 1; display: flex; flex-direction: column; }
  .me-name { font-weight: 600; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .me-role { color: var(--muted-foreground); line-height: 1.3; }
  .sidebar-foot form { margin: 0; }

  .app-main { flex: 1; min-width: 0; padding: 32px 40px calc(64px + var(--safe-bottom)); }
  /* Chat pages fill the viewport: the thread scrolls, not the page. */
  .app-main--flush { padding: 0; height: 100vh; height: 100dvh; display: flex; flex-direction: column; min-width: 0; }
  /* The width lives on <html> (panel-resize), which Turbo Drive keeps from one visit to the next. */
  .app-panel {
    --panel-offset: 0px; /* the panel spans the window's whole height, beside the header */
    width: var(--panel-width, 420px); flex: none; position: sticky; top: 0; margin-top: var(--panel-offset);
    height: calc(100vh - var(--panel-offset)); height: calc(100dvh - var(--panel-offset));
    overflow-y: auto; padding-bottom: var(--safe-bottom);
    border-left: 1px solid var(--border); background: var(--background);
  }
  /* The side panel shows only once the reader opens it, sliding in from the right edge
     (clipped by the shell) when toggled; a page that opens with it shows it at once. */
  body:not(.panel-open) .app-panel { visibility: hidden; margin-right: calc(-1 * var(--panel-width, 420px)); }
  /* The panel's left edge: a 15 px band across its rule; on hover a 52 px grip follows the pointer. The notch's inset
     keeps it on the panel's edge in landscape. */
  .panel-resize {
    position: fixed; top: 0; bottom: 0; z-index: 3; width: 15px;
    right: calc(var(--panel-width, 420px) - 8px + var(--safe-right));
    cursor: col-resize; touch-action: none;
  }
  .panel-resize::after {
    content: ""; position: absolute; left: 6px; width: 3px; height: 52px; border-radius: 3px;
    top: clamp(0px, calc(var(--grip-y, 50vh) - 26px), calc(100% - 52px));
    background: var(--muted-foreground); opacity: 0; transition: opacity .15s;
  }
  .panel-resize:focus-visible::after, .panel-resizing .panel-resize::after { opacity: 1; }
  /* A tap hovers too, and iOS Safari drops the click of a tap whose hover reveals content: a real hover only. */
  @media (hover: hover) { .panel-resize:hover::after { opacity: 1; } }
  .panel-resize:focus-visible { outline: none; }
  .panel-resize:focus-visible::after { background: var(--jx-accent); box-shadow: 0 0 0 3px var(--ring); }
  .panel-resizing, .panel-resizing * { cursor: col-resize; user-select: none; }
  body:not(.panel-open) .panel-resize { display: none; }
  body.panel-sliding .app-panel { transition: margin-right .2s ease, visibility 0s .2s; }
  body.panel-sliding.panel-open .app-panel { transition: margin-right .2s ease, visibility 0s; }
  /* The panel is the settings or the documents, never both: the header keeps to the column left of it. */
  @media (min-width: 1100px) {
    .app-shell:has(> .app-panel) .conversation-header { background: var(--background); }
  }
  /* One view of the panel at a time: the settings, the documents or an extension's tab. */
  .panel-tabs {
    position: sticky; top: 0; z-index: 1; display: flex; gap: 4px; padding: 8px 14px 0;
    border-bottom: 1px solid var(--border); background: var(--background);
  }
  .panel-tab {
    margin-bottom: -1px; padding: 6px 10px 8px; border: 0; border-bottom: 2px solid transparent; background: none;
    font: inherit; font-size: 13px; font-weight: 500; color: var(--muted-foreground); cursor: pointer;
  }
  .panel-tab:is(:hover, :active) { color: var(--foreground); }
  .panel-tab[aria-selected="true"] { color: var(--foreground); border-bottom-color: var(--primary); }
  .panel-tab:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--jx-accent); border-radius: var(--radius-sm); }
  /* !important: a pane's own display rule in the components layer must not keep it showing under another tab. */
  body:not([data-panel-tab="documents"]) [data-panel-pane="documents"],
  body:not([data-panel-tab="onboarding"]) [data-panel-pane="onboarding"] { display: none !important; }
  .page { max-width: 880px; margin: 0 auto; display: flex; flex-direction: column; gap: 20px; }
  /* A stream source holds no content: it must not take a gap of the column (20 px above a document's top bar). */
  .page > turbo-cable-stream-source { display: none; }
  .page--narrow { max-width: 720px; }

  .page-header { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 24px; padding-bottom: 4px; }
  .page-header > div:first-child { flex: 1; min-width: 240px; display: flex; flex-direction: column; gap: 4px; }
  .page-desc { color: var(--muted-foreground); }

  /* Signed-out shell: one centered card on a quiet surface. */
  .auth-shell {
    min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center;
    padding: 48px 16px calc(48px + var(--safe-bottom)); background: var(--surface);
  }
  .auth-column { width: 100%; max-width: 400px; display: flex; flex-direction: column; gap: 20px; }
  .auth-brand { display: flex; justify-content: center; }
  .auth-foot { text-align: center; color: var(--muted-foreground); font-size: 13px; }

  /* Mobile shell, phones and tablets: no sidebar column. The tab bar leads to Accueil and Vous, the screens
     the sidebar itself makes under their page's header; every other page stays clear of the tab bar. */
  @media (max-width: 1099px) {
    .app-shell { background: var(--background); }
    .app-sidebar { display: none; }
    /* The logo's mention belongs to the desktop column, not to the phone's Vous screen. */
    .sidebar-mention { display: none; }
    /* The last row ends 24 px above the floating bar's top, so it stays reachable. */
    .app-main:not(.app-main--flush) { padding-bottom: calc(var(--tab-bar-height) + var(--tab-bar-bottom) + 24px); }
    /* A screen of the pile (a document): no tab bar, its own bar at the bottom, clear of it. */
    /* On the root, so the toasts outside main keep clear of the same bar. */
    :root:has(.app-main--stack) { --stack-clearance: calc(var(--tap) + 32px + var(--safe-bottom)); }
    .app-main.app-main--stack { padding: 0 var(--gutter) var(--stack-clearance); }
    .app-shell[data-screen] { flex-direction: column; }
    /* The sidebar comes first in the document (navigation, then main): the page's header shows above the list. */
    .app-shell[data-screen] .app-main { order: -1; flex: none; padding-inline: var(--gutter); padding-bottom: 12px; }
    .app-shell[data-screen] .app-sidebar {
      display: flex; position: static; width: 100%; height: auto; border-right: 0;
      background: var(--background); font-size: var(--text-body);
      padding-bottom: calc(var(--tab-bar-height) + var(--tab-bar-bottom) + 24px);
    }
    /* The side panel is the conversation's sheet (an inline Ui::SheetComponent): no column, no grip. Visible: a
       hidden panel's visibility would be inherited by the sheet, top layer included. */
    .app-panel, body:not(.panel-open) .app-panel { display: contents; visibility: visible; }
    .panel-resize { display: none; }
  }

  @media (max-width: 767px) {
    .app-main { padding: 20px 16px calc(var(--tab-bar-height) + var(--tab-bar-bottom) + 24px); }
    .app-main--flush { padding: 0; }
    /* A conversation owns its scrolling (the thread): the page never moves, so iOS has nothing to rubber-band when
       the thread is shorter than the screen. Other screens scroll as the document and just do not chain overscroll. */
    html, body { overscroll-behavior: none; }
    html:has(.app-main--flush) { overflow: hidden; }
    /* iOS home-screen apps blur their top edge unless an opaque fixed box sits there: the conversation is that box. */
    body:not(:has(> :is(.support-banner, .quota-banner))) .app-main--flush {
      position: fixed; inset: 0 var(--safe-right) auto var(--safe-left); background: var(--background);
    }
    .auth-shell { align-items: flex-start; padding-top: 32px; }
  }

  /* A touch screen with the desktop sidebar (a tablet in landscape): the workspace link shows it is pressed. */
  @media (pointer: coarse) {
    .brand:active { background: var(--sidebar-accent); }
  }
  .composer-disabled { margin: 6px 0 0; font-size: 13px; color: var(--muted-foreground); }
  /* The hint of an extension lives in its own frame, out of reach of the attachments controller's messages. */
  .composer-hint-frame { flex: 1; font-size: 13px; color: var(--muted-foreground); }
  .thread-extension-banner:empty, .conversation-header-extension:empty { display: none; }
}
