/* ═══════════════════════════════════════════════════════════════════════════
   Shell — the frame every surface sits in.

   Two columns at desktop, one column with an overlay rail under 900px. The
   grid owns the scroll: the rail and the surface scroll independently, so a
   long transcript never drags the navigation out of reach.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer layout {


  .skip-link {
    position: absolute; left: var(--space-3); top: var(--space-3);
    z-index: var(--z-modal); padding: var(--space-2) var(--space-4);
    background: var(--bg-raised); color: var(--fg-primary);
    border: 1px solid var(--border-strong); border-radius: var(--radius-control);
    transform: translateY(-200%); transition: transform var(--dur-fast) var(--ease-out);
  }
  .skip-link:focus-visible { transform: translateY(0); }

  .shell {
    display: grid;
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
    height: 100dvh;
    background: var(--bg-canvas);
  }

  /* ── Collapsed rail (desktop only) ──────────────────────────────────────
     "Collapsed" is a DESKTOP preference: hide the rail, give the surface the
     full width. Three rules keep it honest, all learned the hard way:

     · Scoped to >900px. Below that the rail is a fixed drawer driven by
       data-sidebar="open"; an unscoped collapsed rule outranks the drawer's
       single-column grid by specificity and the two regimes render on top of
       each other — a squeezed rail with wrapped labels under the topbar.
     · min-width: 0 on the item. A grid item's automatic minimum is
       min-content, so a 0 track alone leaves a ~50px strip of wrapped labels
       painting over the content; letting the item actually reach 0 removes
       the strip no matter what the transform is doing mid-transition.
     · visibility: hidden. The rail's links must leave the tab order — a
       hidden navigation you can still focus is a screen-reader maze — and it
       kills the last 1px sliver.

     The reopen control is the topbar hamburger, which is display:none on
     desktop by default: while the rail is collapsed it comes back, because a
     collapse whose only undo lives inside the thing that was hidden is a
     one-way door. */
  @media (min-width: 901px) {
    :root[data-sidebar="collapsed"] .shell { grid-template-columns: 0 minmax(0, 1fr); }
    :root[data-sidebar="collapsed"] .sidebar {
      transform: translateX(-100%);
      visibility: hidden;
      min-width: 0;
      overflow: hidden;
    }
    :root[data-sidebar="collapsed"] .topbar__menu { display: inline-flex; }
  }

  .shell__main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
  .shell__scrim { display: none; }

  /* `position: relative`: the surface is the box anything absolute inside it is
     placed against, so a hidden input (`.sr-only`) scrolls and clips with the
     page instead of hanging off <body> -- where it made the WINDOW scrollable
     and a focus or swipe slid the whole app away (21 Oct, a blank screen). */
  .surface {
    position: relative;
    flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
    padding: var(--space-6) var(--space-8) var(--space-12);
  }
  .surface:focus { outline: none; }
  .surface > * { max-width: var(--content-max); margin-inline: auto; }

  /* ── Rail ──────────────────────────────────────────────────────────────── */
  .sidebar {
    display: flex; flex-direction: column; min-height: 0;
    background: var(--bg-sunken);
    border-right: 1px solid var(--border-subtle);
    transition: transform var(--dur-base) var(--ease-out);
  }
  .sidebar__head {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-3) var(--space-3) var(--space-2);
  }
  .brand {
    display: flex; align-items: center; gap: var(--space-2);
    min-width: 0; flex: 1; color: var(--fg-primary); text-decoration: none;
    font-weight: var(--weight-semibold); font-size: var(--text-sm);
  }
  .brand__mark {
    display: grid; place-items: center; width: 28px; height: 28px; flex: none;
    border-radius: var(--radius-control);
    background: linear-gradient(135deg, #059669 0%, #10b981 100%);
    color: #ffffff;
    box-shadow: 0 2px 8px rgba(16, 185, 129, 0.35);
  }
  .brand__text-wrap {
    display: flex; flex-direction: column; min-width: 0; line-height: 1.15;
  }
  .brand__name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: var(--weight-bold); letter-spacing: -0.01em; }
  .brand__tag {
    font-size: 0.625rem; font-weight: var(--weight-semibold);
    letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--accent-text); opacity: 0.9;
  }
  .brand__env { flex: none; }
  .sidebar__collapse { flex: none; }

  .sidebar__actions { display: grid; gap: var(--space-1); padding: 0 var(--space-2) var(--space-2); }
  .sidebar__new, .sidebar__search {
    display: flex; align-items: center; gap: var(--space-2);
    width: 100%; padding: var(--space-2) var(--space-2);
    border: 1px solid var(--border-subtle); border-radius: var(--radius-control);
    background: var(--bg-surface);
    color: var(--fg-secondary); font: inherit; font-size: var(--text-sm);
    text-decoration: none; text-align: left; cursor: pointer;
    box-shadow: var(--shadow-xs);
    transition: all var(--dur-fast) var(--ease-out);
  }
  .sidebar__new {
    background: linear-gradient(135deg, rgba(16, 185, 129, 0.08) 0%, rgba(99, 102, 241, 0.04) 100%);
    border-color: var(--accent-border);
    color: var(--fg-primary);
    font-weight: var(--weight-medium);
  }
  .sidebar__new:hover {
    background: linear-gradient(135deg, rgba(16, 185, 129, 0.16) 0%, rgba(99, 102, 241, 0.08) 100%);
    border-color: var(--accent);
    color: var(--fg-primary);
    box-shadow: var(--shadow-sm);
    transform: translateY(-1px);
  }
  .sidebar__search:hover {
    background: var(--bg-hover);
    border-color: var(--border-strong);
    color: var(--fg-primary);
    box-shadow: var(--shadow-sm);
  }
  .sidebar__new span, .sidebar__search span { flex: 1; }

  /* Appraise a vehicle (APR-LAND, LAND-D4).  Under New chat it is a quiet second
     entry; with New chat hidden (no `ask`) it is the sidebar's solid primary
     action.  `data-only-start` is set by `nav.js` from the same answer. */
  .sidebar__start {
    display: flex; align-items: center; gap: var(--space-2);
    width: 100%; padding: var(--space-2) var(--space-2);
    border: 1px solid transparent; border-radius: var(--radius-control);
    background: transparent;
    color: var(--fg-secondary); font: inherit; font-size: var(--text-sm);
    text-decoration: none; text-align: left;
    transition: all var(--dur-fast) var(--ease-out);
  }
  .sidebar__start span { flex: 1; }
  .sidebar__start:hover { background: var(--bg-hover); color: var(--fg-primary); }
  .sidebar__actions[data-only-start] .sidebar__start {
    background: var(--accent); border-color: var(--accent);
    color: var(--accent-fg); font-weight: var(--weight-medium);
    box-shadow: var(--shadow-xs);
  }
  .sidebar__actions[data-only-start] .sidebar__start:hover {
    background: var(--accent-hover); border-color: var(--accent-hover);
    color: var(--accent-fg); box-shadow: var(--shadow-sm);
  }

  .sidebar__fleet-card {
    margin: 0 var(--space-2) var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-xs);
    transition: border-color var(--dur-fast) var(--ease-out);
  }
  .sidebar__fleet-card:hover {
    border-color: var(--accent-border);
  }
  .sidebar__fleet-row {
    display: flex; align-items: center; gap: 6px;
  }
  .sidebar__fleet-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: #10b981;
    box-shadow: 0 0 6px rgba(16, 185, 129, 0.7);
    animation: pulse-dot 2s infinite ease-in-out;
  }
  .sidebar__fleet-title {
    font-size: 0.72rem; font-weight: var(--weight-semibold);
    color: var(--fg-primary); letter-spacing: -0.01em;
  }
  .sidebar__fleet-meta {
    display: block; font-size: 0.65rem; color: var(--fg-muted);
    margin-top: 2px;
  }

  @keyframes pulse-dot {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.3); opacity: 0.7; }
  }

  .sidebar__scroll {
    flex: 1; min-height: 0; overflow-y: auto;
    padding: 0 var(--space-2) var(--space-4);
    scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent;
  }

  .nav { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
  .nav__section { margin-top: var(--space-5); }
  .nav__heading {
    margin: 0 0 var(--space-1); padding: 0 var(--space-2);
    font-size: var(--text-xs); font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--fg-faint);
  }
  .nav__item {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2); border-radius: var(--radius-control);
    color: var(--fg-secondary); text-decoration: none; font-size: var(--text-sm);
  }
  .nav__item:hover { background: var(--bg-hover); color: var(--fg-primary); }
  .nav__item.is-active { background: var(--bg-selected); color: var(--fg-primary); font-weight: var(--weight-medium); }
  .nav__icon { flex: none; color: var(--fg-muted); }
  .nav__item.is-active .nav__icon { color: var(--accent-text); }
  .nav__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .nav__count {
    flex: none; min-width: 18px; padding: 0 5px; text-align: center;
    font-size: var(--text-xs); border-radius: var(--radius-pill);
    background: var(--accent-subtle); color: var(--accent-text);
  }
  .nav--threads { gap: 0; }
  /* ★ THE BUG A SCREENSHOT FOUND THAT `clientWidth` COULD NOT.
     `.nav--threads` is `display: grid`, and a grid track's automatic size is
     its widest item's CONTENT size unless told otherwise -- a grid item's
     default `min-width` is `auto`, which means "at least as wide as my
     content needs," not "at most as wide as the track." One long title with
     `white-space: nowrap` (needed so `truncateLabel()` has a single line to
     measure) has a content width equal to the WHOLE unwrapped sentence, so
     without an override the row -- and the grid track, and the whole rail --
     grew to fit it. Measured on a real page: `.sidebar__scroll` reported
     `scrollWidth: 316` against a `clientWidth` of `279`, and every
     `.nav__thread` inside it measured its OWN `clientWidth` at 286 -- wide
     enough to contain "how long do g-class sit on lots in tampa" outright,
     because the row had already grown to fit it before anything measured
     anything. `truncateLabel()` was correct and had nothing wrong to correct:
     the box it was told to fit inside had already expanded around the text.
     `min-width: 0` is the standard fix for exactly this shape of bug, and it
     has to sit on the ROW (the grid item) -- `.nav__thread` already had it
     one level down, which fixed nothing one level up. */
  .nav__thread-row { position: relative; display: flex; align-items: center; min-width: 0; }
  .nav__thread-row .nav__thread { flex: 1; min-width: 0; padding-right: 28px; padding-left: 18px; }
  .nav__thread-pin-mark {
    position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
    display: flex; color: var(--fg-faint); pointer-events: none;
  }
  /* The row still used by the all-chats index (`assistant.html`), which has
     no menu -- kept as its own rule rather than folded into `.thread-menu__item`
     so that page is untouched by this. */
  .nav__thread-del {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; padding: 0; border: 0; border-radius: var(--radius-control);
    background: transparent; color: var(--fg-faint); cursor: pointer;
    opacity: 0; pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out);
  }
  .nav__thread-row:hover .nav__thread-del,
  .nav__thread-row:focus-within .nav__thread-del {
    opacity: 1; pointer-events: auto;
  }
  .nav__thread-del:hover { background: var(--bg-raised); color: var(--fg-primary); }
  .nav__thread-del[data-action="delete-thread"]:hover { background: var(--danger-subtle); color: var(--danger-text); }
  @media (hover: none) {
    .nav__thread-del { opacity: 1; pointer-events: auto; }
  }

  /* ── Per-thread menu: rename, pin, delete behind one "…" ──────────────────
     Same recipe as `.account`/`.account__menu` below -- a floating panel off
     a `<details>`, raised ground, card corners, lg shadow -- because a second
     visual language for "a menu" in the same rail would read as a different
     product. Positioned to the row rather than the sidebar edge, so it opens
     next to whichever row was clicked instead of always in one corner. */
  .thread-menu { position: static; }
  .thread-menu__trigger {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; padding: 0; border-radius: var(--radius-control);
    background: transparent; color: var(--fg-faint); cursor: pointer; list-style: none;
    opacity: 0; pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out);
  }
  .thread-menu__trigger::-webkit-details-marker { display: none; }
  .thread-menu__trigger:hover { background: var(--bg-raised); color: var(--fg-primary); }
  .nav__thread-row:hover .thread-menu__trigger,
  .nav__thread-row:focus-within .thread-menu__trigger,
  .thread-menu[open] .thread-menu__trigger {
    opacity: 1; pointer-events: auto;
  }
  @media (hover: none) {
    .thread-menu__trigger { opacity: 1; pointer-events: auto; }
  }
  /* Opens DOWNWARD, unconditionally -- unlike `.account__menu`, which can
     assume it is always anchored at the bottom of the rail and always opens
     up. A thread row can be anywhere in a scrolling list, so there is no one
     direction that is always correct without measuring the row's position,
     which this does not do. The known trade-off: the menu on a row near the
     very bottom of the visible rail can be clipped by `.sidebar__scroll`'s
     own vertical overflow until scrolled a little further into view. Accepted
     rather than solved with a positioning library for three menu items. */
  .thread-menu__panel {
    position: absolute; top: calc(100% + 2px); right: 2px;
    inline-size: min(13rem, calc(100dvw - 2 * var(--space-2)));
    z-index: var(--z-popover); padding: var(--space-1); display: grid; gap: 2px;
    background: var(--bg-raised); border: 1px solid var(--border-default);
    border-radius: var(--radius-card); box-shadow: var(--shadow-lg);
  }
  .thread-menu__item {
    display: flex; align-items: center; gap: var(--space-2); width: 100%;
    min-block-size: 30px; padding: var(--space-1) var(--space-2);
    border: 0; border-radius: var(--radius-control); background: transparent;
    color: var(--fg-secondary); font: inherit; font-size: var(--text-sm);
    text-align: left; cursor: pointer;
  }
  .thread-menu__item:hover { background: var(--bg-hover); color: var(--fg-primary); }
  .thread-menu__item .icon { flex: none; color: var(--fg-faint); }
  .thread-menu__item:hover .icon { color: inherit; }
  .thread-menu__item--danger:hover { background: var(--danger-subtle); color: var(--danger-text); }
  .thread-menu__item--danger:hover .icon { color: var(--danger-text); }
  .thread-menu__sep { display: block; height: 1px; margin: 2px 0; background: var(--border-subtle); }

  /* The title, mid-rename: the same box as the link so the row does not jump. */
  .nav__thread-edit {
    width: 100%; padding: var(--space-1) var(--space-2);
    border: 1px solid var(--accent); border-radius: var(--radius-control);
    background: var(--bg-surface); color: var(--fg-primary);
    font: inherit; font-size: var(--text-sm);
  }

  .nav__thread {
    display: block; padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-control); font-size: var(--text-sm);
    color: var(--fg-muted); text-decoration: none;
    /* No `text-overflow: ellipsis` here on purpose: `threads.js`'s
       `truncateLabel()` measures the rendered font and cuts at the last WHOLE
       WORD that fits, appending its own "…" -- character-level CSS ellipsis
       has no notion of a word boundary and can (and did) cut mid-word. This
       stays as the safety net for the instant before JS has run, or if it
       never does: a hard clip with no trailing dots, never a double ellipsis. */
    white-space: nowrap; overflow: hidden;
  }
  .nav__thread:hover { background: var(--bg-hover); color: var(--fg-primary); }
  .nav__thread.is-active { background: var(--bg-selected); color: var(--fg-primary); }

  /* The animated reveal for a title `truncateLabel()` actually cut. Sibling
     combinator off the LINK's own hover/focus, keyed on `data-truncated` so a
     title that already fits gets no tooltip at all -- showing one over text
     that is already complete would be telling the truth in an annoying way.
     A short delay on the way IN only (hover-intent, so passing the mouse over
     several rows fast does not flash a tooltip per row); none on the way out. */
  .nav__thread-tip {
    position: absolute; left: var(--space-2); top: calc(100% + 2px);
    z-index: var(--z-popover); max-inline-size: min(22rem, calc(100dvw - 2 * var(--space-2)));
    padding: var(--space-1) var(--space-2); border-radius: var(--radius-control);
    background: var(--bg-raised); border: 1px solid var(--border-default);
    box-shadow: var(--shadow-md); color: var(--fg-primary); font-size: var(--text-xs);
    white-space: normal; overflow-wrap: break-word;
    opacity: 0; transform: translateY(2px); pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
  }
  .nav__thread[data-truncated="1"]:hover + .nav__thread-tip,
  .nav__thread[data-truncated="1"]:focus-visible + .nav__thread-tip {
    opacity: 1; transform: translateY(0); transition-delay: 220ms;
  }
  @media (prefers-reduced-motion: reduce) {
    .nav__thread-tip { transition-duration: 1ms; }
  }
  /* Known trade-off, same one `.thread-menu__panel` already accepts: a row
     near the very bottom of `.sidebar__scroll` can have its tooltip clipped
     by that container's own vertical overflow until scrolled into fuller
     view. Not solved with a positioning library for one tooltip. */
  .nav__more {
    display: block; padding: var(--space-1) var(--space-2); margin-top: var(--space-1);
    font-size: var(--text-xs); color: var(--fg-faint); text-decoration: none;
  }
  .nav__more:hover { color: var(--accent-text); }

  /* ── Account ───────────────────────────────────────────────────────────── */
  .account { position: relative; border-top: 1px solid var(--border-subtle); padding: var(--space-2); }
  .account__trigger {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2); border-radius: var(--radius-control); cursor: pointer;
    list-style: none;
  }
  .account__trigger::-webkit-details-marker { display: none; }
  .account__trigger:hover { background: var(--bg-hover); }
  .account__who { flex: 1; min-width: 0; display: grid; }
  .account__name { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--fg-primary);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 0; }
  .account__role { font-size: var(--text-xs); color: var(--fg-faint); margin: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Who is signed in is drawn by account.js with the page; until then the row
     shows nothing rather than an empty "?" (show-signed-in-person). */
  .account:not([data-drawn]) .account__trigger { visibility: hidden; }
  /* The third line: the person's one store with a pin, else their account (show-signed-in-person). */
  .account__place { display: flex; align-items: center; gap: 3px; min-width: 0; font-size: var(--text-xs); color: var(--fg-faint);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .account__place[hidden] { display: none; }
  .account__place[data-store="false"] .account__pin { display: none; }
  .account__pin { flex: none; }
  .account__caret { flex: none; color: var(--fg-faint); transition: transform var(--dur-fast) var(--ease-out); }
  .account[open] .account__caret { transform: rotate(180deg); }

  /* The menu is a PANEL, so it takes --bg-raised. --bg-overlay is the modal
     scrim — translucent by design — and using it here once made the sidebar
     show through the open menu. Width: wider than the rail on purpose; pinned
     left+right inside the 260px rail, the Appearance/Density rows clipped and
     (because overflow-y:auto forces the other axis to auto) grew a horizontal
     scrollbar. overflow-x stays hidden as the backstop. */
  .account__menu {
    position: absolute; bottom: calc(100% - var(--space-1)); left: var(--space-2);
    inline-size: min(19rem, calc(100dvw - 2 * var(--space-2)));
    z-index: var(--z-popover); max-height: 78dvh; overflow-y: auto; overflow-x: hidden;
    /* The one floating-panel recipe, shared with .modal: raised ground,
       default border, card corners, lg shadow. A popover that differs from
       the dialogs reads as a different product. */
    background: var(--bg-raised); border: 1px solid var(--border-default);
    border-radius: var(--radius-card); box-shadow: var(--shadow-lg);
  }
  /* Rows sit 2px apart in every section of the menu — same rhythm as the
     workspace and persona lists — so the panel reads as one list of doors.
     Density is the reference menu's: 4px section inset, 32px rows. */
  .account__group { padding: var(--space-1); border-bottom: 1px solid var(--border-subtle); display: grid; gap: 2px; }
  .account__group:last-child { border-bottom: 0; }
  .account__group--warn { background: var(--warning-subtle); }
  .account__group-title {
    margin: 0; padding: var(--space-1) var(--space-2) 2px;
    font-size: var(--text-xs); font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--fg-faint);
  }
  /* Segmented controls sit in a 21rem panel here, not a toolbar — slimmer
     buttons keep the devtools view-as pills on one line. */
  .account__menu .segmented > button { padding-inline: var(--space-2); }
  .account__link {
    display: flex; align-items: center; gap: var(--space-2); width: 100%;
    min-block-size: 32px; padding: var(--space-1) var(--space-2);
    border: 0; border-radius: var(--radius-control); background: transparent;
    color: var(--fg-secondary); font: inherit; font-size: var(--text-sm);
    text-align: left; text-decoration: none; cursor: pointer;
  }
  .account__link:hover { background: var(--bg-hover); color: var(--fg-primary); }
  .account__link--danger:hover { background: var(--danger-subtle); color: var(--danger-text); }
  /* A portal door before a portal is configured (A-SHELL, D19): says where it lives, opens nothing. */
  .account__link.is-disabled { color: var(--fg-muted); cursor: default; }
  .account__link.is-disabled:hover { background: none; color: var(--fg-muted); }
  .account__link .account__ext { margin-inline-start: auto; color: var(--fg-muted); }
  .account__note {
    margin: 0; padding: 2px var(--space-2) var(--space-1);
    font-size: var(--text-xs); color: var(--fg-faint); line-height: var(--lh-xs);
  }

  .account__workspaces, .account__demo { padding: var(--space-1); border-bottom: 1px solid var(--border-subtle); display: grid; gap: 2px; }
  .account__demo { background: var(--bg-inset); }
  .account__workspace {
    display: flex; align-items: center; gap: var(--space-2); width: 100%;
    min-block-size: 32px; padding: var(--space-1) var(--space-2);
    border: 0; border-radius: var(--radius-control);
    background: transparent; font: inherit; text-align: left; cursor: pointer;
    color: var(--fg-secondary);
  }
  .account__workspace:hover { background: var(--bg-hover); }
  .account__workspace.is-active { background: var(--bg-selected); color: var(--fg-primary); }
  .account__workspace-name { flex: 1; min-width: 0; font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* The meta must never win the width fight: unbounded, a long mono slug once
     squeezed the workspace name down to "B…". */
  .account__workspace-meta { flex: 0 1 auto; max-inline-size: 55%; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; font-size: var(--text-xs); color: var(--fg-faint); font-family: var(--font-mono); }
  /* Persona rows show a role label, not a slug — mono belongs to identifiers. */
  .account__demo .account__workspace-meta { font-family: inherit; }

  /* ── Topbar ────────────────────────────────────────────────────────────── */
  .topbar {
    display: flex; align-items: center; gap: var(--space-3); flex: none;
    min-height: var(--topbar-h); padding: var(--space-2) var(--space-8);
    border-bottom: 1px solid var(--border-subtle);
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur));
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
  }
  .topbar__menu { display: none; }
  .topbar__title { flex: 1; min-width: 0; }
  .topbar__identity { display: flex; align-items: center; gap: var(--space-2); }
  .topbar__heading { margin: 0; font-size: var(--text-md); font-weight: var(--weight-semibold); color: var(--fg-primary); }
  .topbar__agent-pill {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 7px;
    border-radius: var(--radius-pill);
    background: var(--accent-subtle);
    border: 1px solid var(--accent-border);
    color: var(--accent-text);
    font-size: 0.6875rem; font-weight: var(--weight-semibold);
    letter-spacing: 0.02em;
  }
  .topbar__agent-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: #10b981;
    box-shadow: 0 0 6px rgba(16, 185, 129, 0.8);
    animation: pulse-dot 2s infinite ease-in-out;
  }
  .topbar__desc { margin: 0; font-size: var(--text-xs); color: var(--fg-muted); }
  .topbar__actions { display: flex; align-items: center; gap: var(--space-2); flex: none; }

  /* ── Stat ──────────────────────────────────────────────────────────────── */
  .stat {
    display: grid; gap: var(--space-1); padding: var(--space-4);
    border: 1px solid var(--border-subtle); border-radius: var(--radius-card);
    background: var(--bg-surface); text-decoration: none; color: inherit;
  }
  .stat--link:hover { border-color: var(--border-strong); background: var(--bg-hover); }
  .stat__label { font-size: var(--text-xs); color: var(--fg-muted); }
  .stat__value { font-size: var(--text-2xl); line-height: var(--lh-2xl); font-weight: var(--weight-semibold);
    color: var(--fg-primary); font-variant-numeric: tabular-nums; }
  .stat__foot { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); }
  .stat__hint { color: var(--fg-faint); }
  .stat__delta--success { color: var(--success-text); }
  .stat__delta--danger  { color: var(--danger-text); }
  .stat__delta--warning { color: var(--warning-text); }
  .stat__delta--neutral { color: var(--fg-muted); }

  /* ── Toggle ────────────────────────────────────────────────────────────── */
  .toggle { display: flex; align-items: flex-start; gap: var(--space-2); cursor: pointer; }
  .toggle.is-disabled { opacity: .55; cursor: not-allowed; }
  .toggle__input { position: absolute; opacity: 0; width: 0; height: 0; }
  .toggle__track {
    flex: none; position: relative; width: 34px; height: 20px; margin-top: 1px;
    border-radius: var(--radius-pill); background: var(--bg-active);
    transition: background var(--dur-fast) var(--ease-out);
  }
  .toggle__thumb {
    position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
    border-radius: var(--radius-pill); background: var(--bg-surface);
    box-shadow: var(--shadow-xs);
    transition: transform var(--dur-fast) var(--ease-out);
  }
  .toggle__input:checked + .toggle__track { background: var(--accent); }
  .toggle__input:checked + .toggle__track .toggle__thumb { transform: translateX(14px); }
  .toggle__input:focus-visible + .toggle__track {
    outline: var(--focus-ring-width) solid var(--border-focus);
    outline-offset: var(--focus-ring-offset);
  }
  .toggle__text { display: grid; gap: 1px; }
  .toggle__label { font-size: var(--text-sm); color: var(--fg-primary); }
  .toggle__hint { font-size: var(--text-xs); color: var(--fg-faint); }

  /* ── Toasts ────────────────────────────────────────────────────────────── */
  /* One toast, one recipe: components.css owns .toast-region and .toast
     (raised ground, default border, tone edge). A second recipe used to
     live here — painted with --bg-overlay, the translucent modal scrim, the
     same misuse that once made the account menu see-through — and lost the
     cascade to the components layer on every property anyway. Dead weight
     that LOOKED like the toast's source of truth; removed, not kept in sync. */

  /* ── Sign in ───────────────────────────────────────────────────────────── */
  .bare { min-height: 100dvh; display: grid; place-items: center; padding: var(--space-6); background: var(--bg-sunken); }
  .signin { width: min(440px, 100%); }
  .signin__card {
    padding: var(--space-8); background: var(--bg-surface);
    border: 1px solid var(--border-subtle); border-radius: var(--radius-card);
    box-shadow: var(--shadow-md);
  }
  .signin__brand { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-6);
    font-weight: var(--weight-semibold); }
  .signin__title { margin: 0; font-size: var(--text-xl); color: var(--fg-primary); }
  .signin__sub { margin: var(--space-1) 0 var(--space-6); font-size: var(--text-sm); color: var(--fg-muted); }
  .signin__form { display: grid; gap: var(--space-4); }
  .signin__error {
    display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-4);
    padding: var(--space-2) var(--space-3); font-size: var(--text-sm);
    background: var(--danger-subtle); color: var(--danger-text);
    border: 1px solid var(--danger-border); border-radius: var(--radius-control);
  }
  .signin__demo { margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--border-subtle); }
  .signin__demo-title { margin: 0 0 var(--space-3); font-size: var(--text-xs);
    letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--fg-faint); }
  .signin__demo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
  .signin__persona {
    display: grid; gap: 2px; justify-items: start; padding: var(--space-3);
    border: 1px solid var(--border-subtle); border-radius: var(--radius-control);
    background: var(--bg-surface); cursor: pointer; font: inherit; text-align: left;
  }
  .signin__persona:hover { border-color: var(--accent-border); background: var(--bg-hover); }
  .signin__persona-name { font-size: var(--text-sm); color: var(--fg-primary); }
  .signin__persona-role { font-size: var(--text-xs); color: var(--fg-faint); }
  .signin__note { margin: var(--space-3) 0 0; font-size: var(--text-xs); color: var(--fg-faint); line-height: var(--lh-xs); }

  /* ── Responsive ────────────────────────────────────────────────────────── */
  @media (max-width: 900px) {
    .shell { grid-template-columns: minmax(0, 1fr); }
    .sidebar {
      position: fixed; inset: 0 auto 0 0; z-index: var(--z-drawer);
      width: var(--sidebar-w); transform: translateX(-100%);
      box-shadow: var(--shadow-lg);
    }
    :root[data-sidebar="open"] .sidebar { transform: translateX(0); }
    :root[data-sidebar="open"] .shell__scrim {
      display: block; position: fixed; inset: 0; z-index: calc(var(--z-drawer) - 1);
      background: rgb(0 0 0 / .38);
    }
    .topbar__menu { display: inline-flex; }
    .topbar, .surface { padding-inline: var(--space-4); }
    .signin__demo-grid { grid-template-columns: 1fr; }
  }
  @media (prefers-reduced-motion: reduce) {
    .sidebar, .toggle__track, .toggle__thumb, .account__caret { transition: none; }
  }

}

@layer layout {
  /* ── Breadcrumbs (the drill-down trail) ────────────────────────────────
     Rendered by _topbar.html whenever a page carries `breadcrumbs`. The list
     wraps rather than scrolls: a trail is capped upstream (dashboards/trail
     MAX_DEPTH), so it can afford to be fully visible, and a breadcrumb you
     have to scroll defeats its purpose. */
  .crumbs { margin-bottom: 2px; }
  .crumbs__list {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-05);
    font-size: var(--text-xs); line-height: var(--lh-xs);
  }
  .crumbs__item { display: inline-flex; align-items: center; gap: var(--space-05); min-width: 0; }
  .crumbs__link {
    color: var(--fg-muted); text-decoration: none;
    max-inline-size: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .crumbs__link:hover { color: var(--accent-text); text-decoration: underline; }
  .crumbs__here {
    color: var(--fg-faint);
    max-inline-size: 24ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .crumbs__sep { color: var(--fg-faint); display: inline-flex; }
}

@layer layout {
  /* Command-menu form of the account panel, opening the way Claude's
     profile menu does: quiet lowercase email, then the person on one tight
     line — avatar, name, role, check — at the workspace-row density of the
     reference. */
  .account__header {
    display: grid; gap: var(--space-2);
    padding: var(--space-3) var(--space-3) var(--space-2);
    border-bottom: 1px solid var(--border-subtle);
  }
  .account__email-line {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    padding-inline: var(--space-1);
    font-size: var(--text-xs); color: var(--fg-faint);
  }
  .account__self {
    display: flex; align-items: center; gap: var(--space-2); min-width: 0;
    padding: var(--space-1);
  }
  .account__self-name {
    flex: 1; min-width: 0;
    font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--fg-primary);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .account__self-role {
    flex: none; max-inline-size: 45%; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; font-size: var(--text-xs); color: var(--fg-faint);
  }
  .account__self-check { flex: none; color: var(--accent-text); }
  .account__link .account__kbd { margin-inline-start: auto; display: inline-flex; gap: 2px; }
  .account__link .badge { margin-inline-start: auto; }
  .account__link > span:first-of-type { flex: 1; min-width: 0; }
  /* Row icons read as wayfinding, not content — faint until the row wakes. */
  .account__link > .icon { flex: none; color: var(--fg-faint); }
  .account__link:hover > .icon { color: inherit; }
}

@layer components {
  /* Shortcut hints in a menu are hints, not content: the keycaps go quiet
     here while the Keyboard-shortcuts dialog keeps them at full weight.
     This variant restyles a component, so it lives in the components layer
     — from the layout layer it loses the cascade to components.css's base
     .kbd (layer order beats specificity) and the 2px keycap wins. shell.css
     loads after components.css, so later-in-layer source order settles it. */
  .account__kbd .kbd {
    background: transparent; border-color: var(--border-subtle);
    border-block-end-width: 1px; color: var(--fg-faint);
  }
}
