/* The shell: the grid, the rail, the content column and its notice, each
   view's heading row, and the floating controls with the menu they open. */
@layer components {
  .shell {
    display: grid;
    grid-template-columns: calc(64px + env(safe-area-inset-left)) minmax(0, 1fr);
    height: 100vh;
    height: 100dvh;
    /* The shell owns the inset below its composers; a floating chat
       outside it still pads its own composer. */
    --composer-inset-bottom: 0px;
    padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) 0;
  }

  .nav {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: none;
    align-items: center;
    gap: 15px;
    padding: 28px 10px 28px calc(10px + env(safe-area-inset-left));
    padding-top: clamp(48px, 16vh, 160px);
    background: var(--surface-rail);
    border-right: 1px solid var(--line);
  }

  .nav::-webkit-scrollbar { display: none; }

  .nav a {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 7px;
    color: var(--ink-soft);
    text-decoration: none;
    white-space: nowrap;
  }
  .nav-icon { flex: none; }
  .nav-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    border: 0;
  }
  .nav a:hover { background: var(--hover-tint); }
  .nav a[aria-current="page"] {
    background: var(--paper);
    color: var(--ink);
    font-weight: 600;
    box-shadow: 0 1px 3px var(--shadow-tint);
  }

  .content {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
  }
  .content:focus { outline: none; }

  .notice {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 14px;
    padding: 10px 20px;
    background: var(--amber-bg);
    color: var(--amber);
    border-bottom: 1px solid var(--line);
  }

  .notice button {
    min-height: var(--control-height);
    padding: 0 14px;
    border: 0;
    border-radius: 7px;
    background: var(--green);
    color: var(--on-accent);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
  }
  .notice button:hover { background: var(--green-dark); }

  /* The floating controls over the top of the stage on every view, with no
     bar behind them: the side panel toggle at the left, the bell and the menu
     at the right. The band's empty middle passes clicks to the view under it. */
  .stage-controls {
    position: absolute;
    inset: 0 0 auto;
    z-index: 5;
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: var(--controls-h);
    padding: 10px 12px;
    pointer-events: none;
  }
  .stage-controls-right {
    position: relative;
    display: flex;
    flex: none;
    align-items: center;
    gap: 8px;
    margin-left: auto;
  }
  .stage-controls button,
  .stage-controls .app-menu,
  .stage-controls .app-menu-backdrop,
  .stage-controls .notifications-panel { pointer-events: auto; }
  .view-head {
    display: flex;
    flex: none;
    align-items: center;
    gap: 12px;
  }
  /* The heading row sits at the top of the view's scroller, under the
     floating controls at rest, and sticks to the scroller's top once the
     content scrolls (shell.js watches the sentinel above it and sets
     is-compact). It spans the scroller edge to edge so its background can
     reach them, while its padding keeps the title and actions on the
     content column's edges (the scroller's --page-x and --column). Sticking
     counts from inside the scroller's padding, so the row's top undoes it.
     A phone's settings sheet (z-index 1, later in the page) still covers
     it. The Filter panel under the row takes the same insets, so the
     variables below cover both. */
  .view-head,
  .filter-panel {
    --head-left: calc(var(--page-x) + max(0px, (100% - var(--column)) / 2));
    --head-right: var(--head-left);
  }
  .view-head {
    position: sticky;
    top: calc(-1 * var(--page-top));
    z-index: 1;
    min-height: 0;
    padding: 0 var(--head-right) 16px var(--head-left);
    transition: padding 150ms ease, min-height 150ms ease, background-color 150ms ease;
  }
  /* Compact, the row is a translucent bar the height of the floating
     controls, which sit over it; the title and actions move clear of the
     controls where the column would put them under one. Its box is taller
     at rest than the floating controls' height demands, so the margin
     below pulls back by the same amount the row grows, keeping what
     follows it from shifting when it compacts. */
  .view-head.is-compact {
    min-height: var(--controls-h);
    padding: 0 max(var(--head-right), 116px) 0 max(var(--head-left), 64px);
    margin-bottom: calc(52px - var(--controls-h));
    border-bottom: 1px solid var(--line);
    background-color: color-mix(in srgb, var(--paper) 85%, transparent);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
  }
  .view-head.is-compact .view-title { font-size: 18px; }
  /* In the bar the title keeps its natural width and the actions give up
     space first: their gaps go, then each button narrows to its icon. Only
     a title too long for what is left is cut with an ellipsis. */
  .view-head.is-compact .view-title { flex: 0 1 auto; }
  .view-head.is-compact .view-actions {
    flex: 0 100 auto;
    gap: 0;
    min-width: min-content;
    margin-left: auto;
  }
  .view-head.is-compact .view-actions > button { flex: 0 1 36px; min-width: 28px; }
  .view-head-sentinel {
    height: 1px;
    margin-bottom: -1px;
  }
  .view-title {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-family: var(--serif);
    font-size: 28px;
    font-weight: 600;
    line-height: 1.2;
    transition: font-size 150ms ease;
  }
  @media (prefers-reduced-motion: reduce) {
    .view-head,
    .view-title { transition: none; }
  }
  .view-actions {
    display: flex;
    flex: none;
    align-items: center;
    gap: 8px;
    min-width: 0;
  }
  /* The title keeps its line: it truncates with an ellipsis before it wraps
     or sits under an action. On a phone a heading with three or more
     actions folds all but the first into the ⋯ (core/heading-actions.js);
     its menu is the agent menu's popover, with an icon beside each label. */
  .view-head .view-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .view-actions .is-folded { display: none; }
  .heading-more { position: relative; }
  .heading-menu .heading-menu-entry { display: flex; align-items: center; gap: 10px; }
  .heading-menu .heading-menu-entry svg { flex: none; }
  /* The floating controls are bare icons: no background at rest, and a
     tint on hover and focus. */
  .stage-control {
    display: inline-flex;
    align-items: center;
    height: 44px;
    border: 0;
    background: none;
    font: inherit;
    cursor: pointer;
  }
  .stage-control,
  .stage-controls > .panel-toggle {
    border-radius: 7px;
    color: var(--ink-soft);
  }
  .stage-control:hover,
  .stage-control:focus-visible,
  .stage-controls > .panel-toggle:hover,
  .stage-controls > .panel-toggle:focus-visible { background: var(--hover-tint); color: var(--ink); }
  .app-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 8;
    display: grid;
    width: 230px;
  }
  /* A phone dims and blurs the page behind the open menu (below); a desk
     leaves it clear. */
  .app-menu-backdrop { display: none; }
  /* A phone's way to the notifications, in the bell's place; a desk has the
     bell. */
  #notifications-menu-entry { display: none; }
  /* Theme is one row like a menu entry, its choice a pill of three icons
     with the current one raised. */
  .menu-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: var(--menu-row);
    padding: 0 6px 0 12px;
    color: var(--ink);
    font-weight: 500;
  }
  .theme-options {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    margin: 0;
    padding: 2px;
    border: 0;
    border-radius: 999px;
    background: color-mix(in srgb, var(--ink) 6%, transparent);
  }
  .theme-options label {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    color: var(--muted);
    cursor: pointer;
  }
  .theme-options.connection-access-options label { width: auto; min-width: 0; height: 32px; padding: 0 14px; white-space: nowrap; }
  .theme-options label:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); color: var(--ink); }
  .theme-options label:has(input:checked) {
    background: var(--paper);
    color: var(--ink);
    box-shadow: 0 1px 3px var(--shadow-pop), 0 0 0 1px var(--border-faint);
  }
  .theme-options label:has(input:focus-visible) {
    outline: 2px solid var(--green);
    outline-offset: 2px;
  }
  .theme-options input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    border-radius: inherit;
    opacity: 0;
    cursor: pointer;
  }
  .theme-options svg { pointer-events: none; }
  .theme-divider {
    width: 1px;
    height: 16px;
    margin: 0 2px;
    background: var(--line);
  }
  /* On dark paper a raised round reads lighter, not paper-dark. */
  :root[data-theme="dark"] .theme-options label:has(input:checked) { background: color-mix(in srgb, var(--ink) 14%, var(--paper)); }
  :root[data-theme="dark"] .theme-divider { background: var(--rule); }
  /* The open notification count: on the Notifications button, on a desk and
     on a phone alike. */
  .control-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 10px;
    background: var(--amber);
    color: var(--on-accent);
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
  }

  /* An open notification on a phone, as a dot (the rail's nav-indicator
     look, not a count) on the menu toggle's corner. */
  #app-menu-toggle { position: relative; }
  #app-menu-toggle .control-dot,
  .filter-toggle .control-dot,
  .heading-more .control-dot {
    position: absolute;
    top: 7px;
    right: 7px;
    width: 8px;
    height: 8px;
    border: 2px solid var(--paper);
    border-radius: 50%;
    background: var(--amber);
  }
  .filter-toggle .control-dot,
  .heading-more .control-dot { background: var(--green); }

  /* The Notifications icon button: the count badge sits on the icon's
     corner instead of trailing text. */
  #notifications-toggle { position: relative; }
  #notifications-toggle .control-count {
    position: absolute;
    top: 4px;
    right: 4px;
    min-width: 16px;
    height: 16px;
    margin-left: 0;
    padding: 0 4px;
    font-size: 10px;
  }
  .nav-indicator {
    position: absolute;
    top: 7px;
    right: 7px;
    width: 8px;
    height: 8px;
    border: 2px solid var(--surface-rail);
    border-radius: 50%;
    background: var(--amber);
  }
  .nav a[hidden] { display: none; }
  .menu-entry-dot {
    width: 9px;
    height: 9px;
    margin-left: 8px;
    border-radius: 2px;
    background: var(--red);
    transform: rotate(45deg);
  }
  .menu-entry-dot[hidden] { display: none; }
  .nav-indicator-health {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    background: var(--red);
    transform: rotate(45deg);
  }
  .view {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
  }
  /* The floating controls' first, on every view. Its inner bar fades while the
     panel is collapsed. */
  .panel-toggle {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 7px;
    background: none;
    color: var(--muted);
    cursor: pointer;
  }
  .panel-toggle:hover,
  .panel-toggle:focus-visible {
    color: var(--ink);
  }
  .panel-toggle .bar { transition: opacity 150ms ease; }
  .panel-toggle[aria-expanded="false"] .bar { opacity: 0.35; }

  @media (max-width: 719.98px) {
    /* The rail becomes a fixed tab bar along the bottom; .content reserves
       its height with matching padding so nothing scrolls behind it, and any
       fixed layer that would otherwise reach the physical bottom (the model
       menu) stops above it instead. */
    :root {
      --nav-bar-h: calc(48px + max(8px, env(safe-area-inset-bottom)));
    }

    .shell {
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: minmax(0, 1fr);
      padding-bottom: 0;
      padding-left: env(safe-area-inset-left);
    }

    .content {
      padding-bottom: var(--nav-bar-h);
    }

    .nav {
      position: fixed;
      inset: auto 0 0 0;
      z-index: 6;
      flex-direction: row;
      align-items: stretch;
      gap: 2px;
      padding: 4px max(8px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
      border-right: 0;
      border-bottom: 0;
      border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
      background: var(--surface-page);
    }

    /* Quiet icons, the current one at full strength, on no tile. */
    .nav a { color: var(--faint); }
    .nav a:hover { background: transparent; }
    .nav a[aria-current="page"] {
      background: transparent;
      box-shadow: none;
      color: var(--ink);
    }

    .nav a {
      flex: 1;
      width: auto;
      height: auto;
      min-width: 0;
      min-height: 44px;
      padding: 4px 0;
    }

    /* Icon only: the label stays the accessible name, hidden the same way
       it is on a desk (see the base .nav-label rule above). */
    .nav-indicator {
      top: 6px;
      right: calc(50% - 16px);
    }
    /* The band sits over the drawer (4), so the toggle and the menu stay
       in reach while the drawer is open. */
    .stage-controls {
      z-index: 5;
      gap: 8px;
      padding: 6px 12px;
    }
    /* The bell gives way to the menu's Notifications entry, and an open
       notification dots the menu's toggle (shell.js). */
    #notifications-toggle { display: none; }
    #notifications-menu-entry { display: inline-flex; }
    /* The toggle and the menu sit on rounds of their own fill, a step off the
       paper, ringed like the thread's pill, so they stand out over what
       scrolls under them. */
    :root { --float-fill: color-mix(in srgb, var(--ink) 5%, var(--paper)); }
    .stage-control,
    .stage-controls > .panel-toggle {
      border-radius: 999px;
      background: var(--float-fill);
      box-shadow: 0 0 0 1px var(--line), 0 2px 10px var(--shadow-pop);
    }
    .stage-control:hover,
    .stage-control:focus-visible,
    .stage-controls > .panel-toggle:hover,
    .stage-controls > .panel-toggle:focus-visible { background: color-mix(in srgb, var(--ink) 10%, var(--paper)); }
    #app-menu-toggle .control-dot { top: 8px; right: 8px; border-color: var(--float-fill); }
    /* With no bell, the compact bar's right clears only the menu's round:
       the band's edge, the round, and the band's gap, as its left clears
       the side panel's round, so the actions end one gap from the menu. */
    .view-head.is-compact { padding-right: max(var(--head-right), 64px); }
    /* The open menu stands over a backdrop with a sheet's tint
       and a light blur, across the whole screen: the band rises over the
       bottom nav bar while it is open, the menu's round and the menu stay
       above the backdrop, and quick chat's button steps aside
       (quick-chat.css). */
    .app-menu-backdrop {
      position: fixed;
      inset: 0;
      display: block;
      background: var(--shadow-sheet);
      -webkit-backdrop-filter: blur(2px);
      backdrop-filter: blur(2px);
    }
    .stage-controls:has(> .app-menu-backdrop:not([hidden])) { z-index: 7; }

    .notice { padding: 8px 14px; }
  }
}
