/* Sonic Suisse AI — the shared shell: base, icons, the sidebar and the phone top bar that shell.js builds.
   Every page loads tokens.css + shell.css + theme.js + shell.js; the hub, the admin pages and the chats' pages add
   base.css for its components; apps keep their own component styles. Everything here is either global base or
   scoped to the shell (.shell, .topbar), so a page's own classes never collide with it. Breakpoint: 720px. */

/* ── base ──────────────────────────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: var(--fs-md); line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}
main { flex: 1; }
a { color: var(--accent); text-decoration: none; }
:focus-visible { outline: none; }   /* no focus ring at all, the browser's own included (Qing, 2026-10-28) */
img, svg { max-width: 100%; }
@media (hover: hover) {   /* links underline on hover, colour unchanged; only where a real pointer hovers */
  a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
}

/* an app's page column (<main class="column">): the reading width, flush left, as on every app and admin page; a page
   that ends in a chat's input has no room below it (.flush). One rule here since 2026-10-20 (it was copied into eight
   pages: LabGuide's four, Polyglot, the knowledge admin and chat pages, the no-access page); a page that needs more
   width says so itself (LabGuide Search, the admin's wide tables: max-width: none). */
main.column { width: 100%; max-width: var(--content-max); margin: 0; padding: var(--sp-5) var(--gutter) var(--sp-8); }
main.column.flush { padding-bottom: 0; }

/* a field's hint: one readable grey everywhere (2026-10-20: the browser's own, #757575, was 3.6-4:1 on dark fields) */
::placeholder { color: var(--muted); opacity: 1; }

/* page title of an app or document page: one size everywhere */
.page-title { font-size: var(--fs-xl); font-weight: 700; letter-spacing: -.01em; line-height: var(--lh-tight); color: var(--text-strong); margin: 0 0 var(--sp-2); }
.page-sub { color: var(--muted); font-size: 13.5px; line-height: 1.55; margin: 0 0 20px; }   /* the line under a page title: 8px below it on every page, then 20px to the content */
/* "?" beside a page's name: what the page or app is, in a bubble on hover, keyboard focus or a tap (shell.js; Escape
   dismisses it), instead of a line under the title; what must be read goes in it too (Polyglot's data rule, in bold; a
   chat's AI notice). The Idea Registry's design (/registry/: .help, .helpbtn, .helptip), shared here, its icon
   icons.svg#help; beside a title the bubble hangs from the title's left edge, so it never runs off a phone's screen. */
.page-title { position: relative; }
.help { position: relative; display: inline-flex; }
.page-title .help { position: static; vertical-align: -.03em; margin: -8px 0 -8px 4px; }   /* the icon's middle on the
   capitals' middle (measured, 24px title), and the 30px button adds nothing to the title's line height */
.helpbtn { background: transparent; border: 0; color: var(--muted); width: 30px; height: 30px; padding: 0; border-radius: 50%;
           display: inline-flex; align-items: center; justify-content: center; font-size: 19px; cursor: help; }
.helpbtn:hover, .helpbtn:focus-visible, .help.on .helpbtn { color: var(--text); }
.helptip { position: absolute; top: calc(100% + 8px); right: 0; width: min(420px, 80vw); background: var(--card);
           border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; font-size: .8rem; font-weight: 400;
           line-height: 1.5; color: var(--muted); box-shadow: var(--shadow-2); z-index: 200; opacity: 0; visibility: hidden;
           transform: translateY(-4px); transition: .15s; pointer-events: none; text-transform: none; letter-spacing: 0;
           text-align: left; white-space: normal; }
.page-title .helptip { left: 0; right: auto; width: min(420px, 100%); }
.helptip b, .helptip strong { color: var(--text); }   /* what must be read (Polyglot's data rule, Submit's who signs) */
.help:hover .helptip, .helpbtn:focus-visible + .helptip, .help.on .helptip { opacity: 1; visibility: visible; transform: none; }
.help.dismissed .helptip { opacity: 0; visibility: hidden; transform: translateY(-4px); }   /* Escape: shut until the pointer and the focus leave */
/* a ? whose text has a link (the knowledge admin's Access and Conversations tabs, 2026-10-20: the line under the tabs
   moved into it, its links too): the open bubble takes the pointer, over the gap under the ? too, so the pointer can
   reach the link; tabbing to the link keeps the bubble open */
.helptip:has(a) { pointer-events: auto; }
.helptip:has(a)::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 9px; }
.help:not(.dismissed) .helptip:focus-within { opacity: 1; visibility: visible; transform: none; }
.page-title:where(:has(.help):not(:has(+ .page-sub))) { margin-bottom: 20px; }   /* the line under it is in its ?: the
   content 20px below, as below a line (2026-10-20: every page's line moved into its ?; it was set per page). :where:
   no more weight than .page-title, so a page's own rule wins (the chat's title in its row: margin 0) */
.page-title + .tabs { margin-top: 20px; }   /* no line under the title: the tabs sit 20px below it, as content does */

/* An allow-listed item on a page (the Apps page's rows of LabGuide and Dr Risch Chat): shown to everyone, signed out
   with its sign-in chip as any sign-in app (2026-10-21, Qing: it was hidden); its "on request" chip only for signed-in
   visitors not on its list (shell.js marks the row .shut), so nobody on it sees the chip flash by */
[data-listed]:not(.shut) .chip-ask { display: none; }
/* A page's own tabs, under its title and sub line (the admin's chats, LabGuide); the open one underlined */
.tabs { display: flex; gap: 4px; flex-wrap: wrap; margin: 0 0 18px; border-bottom: 1px solid var(--line); }
.tabs a { padding: 7px 12px; font-size: 13.5px; line-height: 1.55; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }   /* line-height: one row height on every page (the course's text is taller) */
.tabs a:hover { text-decoration: none; }
.tabs a.on { color: var(--text-strong); border-bottom-color: var(--text-strong); font-weight: 600; }
/* a count beside a tab (Access Control's Requests, a chat's Review, Documents …): a small pill raised to the label's
   top right like an exponent (Qing, 2026-10-21); relative, so the tab keeps its height. None while the count is 0 */
.tabs a .n { display: inline-block; position: relative; top: -.5em; min-width: 16px; height: 16px; box-sizing: border-box;
             padding: 0 5px; margin-left: 3px; border-radius: 8px; background: var(--accent-tint); color: var(--accent);
             font-size: 10.5px; font-weight: 600; line-height: 16px; text-align: center; font-variant-numeric: tabular-nums; }
.tabs a .n:empty { display: none; }
/* on a phone the tabs stay one row that scrolls sideways, the open one scrolled into view (shell.js), instead of
   wrapping into two or three rows with the open tab's line floating between them (Qing, 2026-10-20). The row's line is
   drawn inside it, where scrolling does not clip the open tab's line over it; the row stays as tall as before. */
@media (width <= 720px) {
  .tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; border-bottom: 0; box-shadow: inset 0 -1px 0 var(--line); }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs a { flex: none; white-space: nowrap; margin-bottom: 0; }
}

/* icons: inline SVG symbols, sized in em; never capped by the global svg max-width (WebKit) */
.icon { width: 1em; height: 1em; max-width: none; max-height: none; vertical-align: -.125em; flex-shrink: 0;
        fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.icon.ext { width: .8em; height: .8em; margin-left: var(--sp-1); vertical-align: 0; color: var(--muted); }   /* a mark after a label: new tab, globe, lock */
html.signed-in .shell .icon.lock:not(.ask) { display: none; }   /* sign-in locks show only while signed out; an on-request lock stays */

/* the logo: the Sonic mark (fixed fills), a red "AI" and "LAB" in black or white per theme */
.brand { display: inline-flex; align-items: center; gap: 6px; font-weight: 900; font-size: 1.2rem; letter-spacing: -.01em; line-height: 1; color: var(--text-strong); white-space: nowrap; }
.brand:hover { text-decoration: none; }
.brand .ai { color: var(--brand-red); }
.brand-mark { width: 26px; height: 26px; max-width: none; flex-shrink: 0; }

/* ── the shell's own type, so no page's base styles can reach into it ──────────────────────────── */
.shell, .topbar { font-family: var(--font); font-size: var(--fs-md); line-height: 1.4; }
.shell a:hover, .topbar a:hover { text-decoration: none; }

/* ── sidebar ───────────────────────────────────────────────────────────────────────────────────── */
.shell { display: flex; flex-direction: column; gap: var(--sp-5); padding: var(--sp-5) var(--sp-4) var(--sp-2);
         background: var(--shell-bg); border-right: 1px solid var(--line); }
.shell-top { display: flex; align-items: center; min-height: var(--control-h-sm); padding-left: 7px; }   /* the mark sits on the icon column (x 36) in both states */

/* rows: top-level links, group headers, entries */
.shell .nav { display: flex; flex-direction: column; gap: 2px; }
.shell .nav > * { flex-shrink: 0; }   /* rows keep their height when the menu is long enough to scroll */
.shell .nav a, .shell .tree > summary {
  display: flex; align-items: center; height: var(--control-h-sm); padding: 0 var(--sp-3); border-radius: var(--radius-sm);
  font-size: var(--fs-sm); font-weight: 700; color: var(--text-strong); white-space: nowrap; overflow: hidden;
}
.shell .nav a > span, .shell .tree > summary > span { overflow: hidden; text-overflow: ellipsis; }
.shell .nav a > .nav-pill { flex: none; display: inline-flex; align-items: center; height: 18px; margin-left: var(--sp-2); padding: 0 7px;
  border-radius: var(--radius-pill); background: var(--neutral-tint); color: var(--muted); font-size: 11px; font-weight: 600; letter-spacing: .02em; }   /* "archived" after a page name, as the list's chip */
.shell .nav a.active, .shell .tree > summary.active { background: var(--nav-active); }   /* the current page: the bar only, same weight and colour */
.shell .nav-ico { width: 16px; height: 16px; margin-right: var(--sp-2); color: var(--muted); }
.shell .active > .nav-ico { color: var(--text-strong); }

/* groups (details.tree): the whole row toggles; only the chevron turns */
.shell .tree > summary { list-style: none; cursor: pointer; }
.shell .tree > summary::-webkit-details-marker { display: none; }
.shell .tree > summary > span { flex: 1; }
.shell .tree > summary > .icon:last-child { color: var(--muted); margin-right: var(--sp-2); transition: transform var(--dur) var(--ease); }
.shell .tree[open] > summary > .icon:last-child { transform: rotate(90deg); }
.shell .tree ul { list-style: none; margin: 2px 0 var(--sp-2) 20px; padding: 0 0 0 3px; border-left: 1px solid var(--line); }   /* the rule under the icon (x 36), entries on the label line (x 52) */
.shell .tree li { margin: 0; padding: 0; }
.shell .tree ul a { height: 30px; font-weight: 500; color: var(--text); }

/* a group in a group (details.tree.appnav, Admin › Chats): no rule; its entries line up with its name */
.shell .tree.appnav > ul { border-left-color: transparent; }
.shell .tree ul .tree > summary { height: 30px; }
.shell .tree ul .tree.appnav > ul { margin-left: 0; padding-left: 0; border-left: 0; }
.shell .nav .admin-nav { margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px solid var(--line); }   /* the Admin section, apart from the site map */

@media (hover: hover) {   /* a soft bar behind the hovered row, a stronger one behind the current page */
  .shell .nav a:hover, .shell .tree > summary:hover { background: var(--nav-hover); color: var(--text-strong); }
  .shell .tree ul a:hover { color: var(--text); }
  .shell .nav a.active:hover, .shell .tree > summary.active:hover { background: var(--nav-active); }
}
.shell .nav a:active, .shell .tree > summary:active { background: var(--nav-hover); }   /* touch: the bar while tapping */

/* bottom row: collapse · appearance · account, 8 + 32 + 8 */
.shell-bottom { margin-top: auto; padding-top: var(--sp-2); border-top: 1px solid var(--line); }
.shell-bottom .tools { display: flex; align-items: center; justify-content: space-between; padding: 0 4px; }   /* 32px buttons on the icon column (x 36) */
.shell-bottom .collapse-btn, .shell-bottom .settings-btn, .shell-bottom .auth .btn-icon {
  width: var(--control-h-sm); height: var(--control-h-sm); margin: 0; padding: 0; border: 0; border-radius: var(--radius-sm);
  display: inline-flex; align-items: center; justify-content: center; background: transparent; color: var(--muted); cursor: pointer; font: inherit;
}
.shell-bottom button .icon { width: 16px; height: 16px; stroke-width: 1.5; }   /* the same as the menu icons */
@media (hover: hover) { .shell-bottom button:not(:disabled):hover { background: var(--nav-hover); } }

/* drag handle on the right edge: drag to resize, double-click to reset */
.shell-resize { position: absolute; top: 0; right: 0; width: 6px; height: 100%; cursor: col-resize; z-index: 5; touch-action: none; }
.shell-resize::after { content: ""; position: absolute; top: 0; bottom: 0; right: 0; width: 2px; background: transparent; transition: background var(--dur) var(--ease); }
.shell-resize:hover::after, body.shell-resizing .shell-resize::after { background: var(--line-strong); }
body.shell-resizing { cursor: col-resize; user-select: none; }

/* ── appearance menu (light / dark / system) ───────────────────────────────────────────────────── */
.settings { position: relative; display: inline-flex; }
.settings-btn:disabled { color: var(--faint); cursor: default; }   /* a one-theme page: greyed out, same place (no extra opacity:
   --faint is the disabled colour, 5:1; with opacity .5 it was 2.2:1, 2026-10-20) */
.settings-btn .icon { display: none; }   /* the button shows the current choice (theme.js sets data-theme-choice; a locked page shows its theme) */
html[data-theme-choice="light"] .settings-btn .is-light, html[data-theme-choice="dark"] .settings-btn .is-dark,
html[data-theme-choice="system"] .settings-btn .is-system, html:not([data-theme-choice]) .settings-btn .is-system { display: inline-block; }
.settings-menu { display: none; position: absolute; z-index: 30; padding: 4px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-pill); box-shadow: var(--shadow-2); }
.settings.open .settings-menu { display: block; }
.shell .settings-menu { bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); }   /* sidebar: opens upward, centred over the button */
.topbar .settings-menu { top: calc(100% + 6px); left: 50%; transform: translateX(-50%); }    /* phone top bar: opens downward, centred under the button */
.theme-seg { display: inline-flex; align-items: center; }
.theme-seg button { width: 26px; height: 24px; padding: 0; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--muted); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.theme-seg button .icon { width: 13px; height: 13px; stroke-width: 2; }
.theme-seg button.active { background: var(--text-strong); color: var(--bg); }
@media (hover: hover) { .theme-seg button:not(.active):hover { color: var(--text-strong); } }

/* ── account menu (filled by theme.js from /auth/me) ───────────────────────────────────────────── */
.auth { position: relative; display: inline-flex; align-items: center; }
.auth-menu { display: none; position: absolute; z-index: 30; min-width: 220px; flex-direction: column; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4);
             background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-2); font-size: var(--fs-sm); }
.auth.open .auth-menu { display: flex; }
.shell-bottom { position: relative; }
.shell .auth { position: static; }
.shell .auth-menu { bottom: calc(100% + 6px); left: 0; right: 0; min-width: 0; }   /* opens upward across the bottom row, inside the sidebar */
.topbar .auth-menu { top: calc(100% + 8px); right: 0; }
.auth-user { color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.auth-out { font-weight: 700; }

/* ── phone top bar ─────────────────────────────────────────────────────────────────────────────── */
.topbar { position: sticky; top: 0; z-index: 20; border-bottom: 1px solid var(--line);
          background: color-mix(in srgb, var(--bg) 88%, transparent); -webkit-backdrop-filter: saturate(140%) blur(8px); backdrop-filter: saturate(140%) blur(8px); }
.topbar .container { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--sp-4); height: 60px; max-width: var(--content-max); margin: 0 auto; padding: 0 var(--gutter); }
.topbar .row { display: flex; align-items: center; justify-self: end; gap: var(--sp-2); }
/* its three buttons (appearance, account, menu) are one design, with or without base.css: 32px, an 18px icon
   (1.15em of the bar's 16px) with a 1.8 stroke, no ring (the account button's circle went 2026-10-28: the sidebar's has
   none; Qing), the hover a round fill */
.topbar .row > button, .topbar .row > span > button {
  width: var(--control-h-sm); height: var(--control-h-sm); margin: 0; padding: 0; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: var(--radius-pill); background: transparent; color: var(--text-strong); font: inherit; line-height: 1;
  cursor: pointer; transition: none;
}
.topbar .row > button .icon, .topbar .row > span > button .icon { width: 1.15em; height: 1.15em; stroke-width: 1.8; }
.topbar .row > span > button:disabled { color: var(--faint); }
@media (hover: hover) { .topbar .row > button:hover, .topbar .row > span > button:not(:disabled):hover { background: var(--nav-hover); } }

/* every page starts at the same left edge; on a phone too, where auto margins would shrink a main.container to its
   content in the flex column of the body */
body.has-shell > main.container, body.has-shell > main .container { margin-left: 0; margin-right: 0; }

/* ── wide screens: sidebar beside the page ────────────────────────────────────────────────────── */
@media (width > 720px) {
  body.has-shell { display: grid; grid-template-columns: var(--shell-w) minmax(0, 1fr); }
  body.has-shell > .topbar { display: none; }
  body.has-shell > .shell { position: sticky; top: 0; z-index: 20; height: 100vh; height: 100dvh; overflow: hidden; }   /* its own layer above the page, so the rail's floating menus are never covered */
  body.has-shell > .shell > .nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; scrollbar-gutter: stable; }   /* only the menu scrolls; its scrollbar's room is kept */
  body.has-shell > main { grid-column: 2; min-width: 0; }

  /* collapsed rail: icons only, labels as tooltips; the rail's menus float beside their button (shell.js sets top) */
  body.has-shell.nav-collapsed { grid-template-columns: 72px minmax(0, 1fr); }
  body.nav-collapsed .shell-top .brand .name,
  body.nav-collapsed .shell .nav a > span, body.nav-collapsed .shell .tree > summary > span,
  body.nav-collapsed .shell .tree > summary > .icon:last-child, body.nav-collapsed .shell .tree ul,
  body.nav-collapsed .shell-resize { display: none; }
  body.nav-collapsed .shell .nav-ico { margin-right: 0; }
  body.nav-collapsed .shell .tree > summary.inside { background: var(--nav-active); }   /* the group icon shows where you are */
  body.nav-collapsed .shell-bottom .tools { flex-direction: column; align-items: flex-start; gap: var(--sp-2); }
  body.nav-collapsed .shell-bottom .auth { order: 1; }
  body.nav-collapsed .shell-bottom .settings { order: 2; }
  body.nav-collapsed .shell-bottom .collapse-btn { order: 3; }   /* collapse stays where it was pressed */
  body.nav-collapsed .shell .auth-menu, body.nav-collapsed .shell .settings-menu { position: fixed; left: 80px; right: auto; bottom: auto; transform: none; }
}

/* ── phones: the top bar, the sidebar as an overlay ───────────────────────────────────────────── */
@media (width <= 720px) {
  .shell { display: none; }
  .shell.open { display: flex; position: fixed; inset: 60px 0 0 0; z-index: 25; overflow-y: auto; border-right: 0; }
  body.shell-open { overflow: hidden; }
  .shell-top, .shell-bottom, .shell-resize { display: none; }   /* the top bar carries the logo, appearance and account */
}

@media print {
  .topbar, .shell { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ── the chat panel (shell.js, site.json "chat") ───────────────────────────────────────────────── */
/* An orb in the bottom right corner opens the chat on the right: beside the page on a wide screen, over it on a
   medium one; it hides while the panel is open (the panel's own close is there), and on a page that has a chat of its
   own (Dr Risch Chat, LabGuide's Chat tab), whose input it would cover. On a phone the same, the panel over the whole
   screen (2026-10-28, Qing: as on a computer; before, a chat icon in the top bar opened the chat's page). Bottom right
   and 44px since 2026-10-20 (Qing): at the top right (from 2026-10-15,
   32px, as Copilot in Outlook) it covered the buttons at the top right of a page (New chat, Download as Word). */
body:has(main [data-kn-chat]) .chat-orb { display: none; }
.chat-orb { position: fixed; right: 24px; bottom: 24px; z-index: 30; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%;
            background: transparent; color: var(--text-strong); cursor: pointer; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .25));
            transition: transform .15s ease; }   /* its halo in grey, as dark as the navy one was (Qing, 2026-10-28: no blue) */
.chat-orb svg { display: block; width: 100%; height: 100%; }
.chat-orb:hover { transform: scale(1.08); }
body.chat-open .chat-orb { display: none; }
.chat-panel { display: none; }
body.chat-open .chat-panel { position: fixed; top: 0; right: 0; bottom: 0; z-index: 25; display: flex; flex-direction: column;
            width: var(--chat-w, 440px); max-width: 100vw; background: var(--bg); border-left: 1px solid var(--line); }   /* a line, like the sidebar's */
.chat-panel-resize { position: absolute; top: 0; left: -3px; width: 6px; height: 100%; cursor: col-resize; z-index: 5; touch-action: none; }
.chat-panel-resize::after { content: ""; position: absolute; top: 0; bottom: 0; left: 2px; width: 2px; background: transparent; transition: background var(--dur) var(--ease); }
.chat-panel-resize:hover::after, body.chat-resizing .chat-panel-resize::after { background: var(--line-strong); }
body.chat-resizing { cursor: col-resize; user-select: none; }
.chat-panel-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
            height: 52px; padding: 0 var(--sp-2) 0 var(--sp-4); border-bottom: 1px solid var(--line); }
.chat-panel-title { font-weight: 600; color: var(--text-strong); }
.chat-panel-lead { display: flex; align-items: center; min-width: 0; }   /* the chat's name and its ? */
.chat-panel-head { position: relative; }   /* the ? bubble spans the panel under its header */
.chat-panel-head .help { position: static; flex: none; margin-left: 2px; }
.chat-panel-head .helpbtn { width: 28px; height: 28px; border-radius: 8px; }   /* as the header's New chat and × */
.chat-panel-head .helptip { left: var(--sp-4); right: var(--sp-2); width: auto; }
.chat-panel-tools { flex: none; display: inline-flex; align-items: center; gap: 0; }     /* the two icons read as one group, 13px apart */
.chat-panel-new, .chat-panel-close { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 0;
            border-radius: 8px; background: transparent; color: var(--muted); font: inherit; cursor: pointer; }
.chat-panel-head .helpbtn svg, .chat-panel-tools .icon { width: 15px; height: 15px; }   /* the header's three icons: one size */
.chat-panel-head .helpbtn:hover, .chat-panel-new:hover, .chat-panel-close:hover { background: var(--nav-hover); color: var(--text-strong); }
.chat-panel.chat-empty .chat-panel-new { visibility: hidden; }   /* as the page's "New chat": nothing to start afresh yet */
.chat-panel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--sp-4) var(--sp-4) 0; }
@media (width > 1100px) { body.has-shell.chat-open { margin-right: var(--chat-w, 440px); } }   /* the page beside it */
@media (width <= 720px) {   /* a phone: the orb clear of the home bar, the panel over the whole screen and the page still under it */
  .chat-orb { right: max(16px, env(safe-area-inset-right, 0px)); bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
  body.chat-open .chat-panel { left: 0; width: auto; max-width: none; border-left: 0; z-index: 40;
            padding-top: env(safe-area-inset-top, 0px); padding-bottom: env(safe-area-inset-bottom, 0px); }
  .chat-panel-resize { display: none; }
  html:has(body.chat-open) { overflow: hidden; }
}
@media (prefers-reduced-motion: reduce) { .chat-orb { transition: none; } }
@media print { .chat-orb, .chat-panel { display: none !important; } }

/* A tour (2026-10-20 on Home; shared 2026-10-21, LabGuide's too): a button at the end of a title's row, and the tour in
   a dialog over the page (tour.js). The row: the title and the button, as tall as the title, the button's middle on the
   title's middle; the title's "?" bubble spans the row. The button is base.css's .btn.btn-ghost.btn-sm, written out for
   the pages without base.css (LabGuide). Signed out it carries the sidebar's sign-in lock (.icon.lock, shell.js LOCK_TIP).
   The dialog is the tour alone, no header or title; its x is the chat panel's own (.chat-panel-tools > .chat-panel-close),
   where the chat panel has it: 12px down, 8px in (Qing, 2026-10-20) */
.title-row { position: relative; display: flex; align-items: flex-start; gap: var(--sp-4); }
.title-row .page-title { position: static; flex: 1; min-width: 0; margin: 0; }
.title-row + .tabs { margin-top: 20px; }   /* as .page-title + .tabs */
.tour-btn { flex: none; display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
            height: var(--control-h-sm); padding: 0 var(--sp-3); margin-block: calc((var(--fs-xl) * var(--lh-tight) - var(--control-h-sm)) / 2);
            border-radius: var(--radius-pill); border: 1px solid var(--text-strong); background: transparent; color: var(--text-strong);
            font: inherit; font-size: var(--fs-sm); font-weight: 700; line-height: 1; cursor: pointer; white-space: nowrap;
            transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.tour-btn .icon { width: 14px; height: 14px; stroke-width: 2; }
.tour-btn .tour-lock { width: 12px; height: 12px; margin-left: -2px; color: var(--muted); }
html.signed-in .tour-lock { display: none; }   /* on any tour's button: Home's, a Tours card */
@media (hover: hover) { .tour-btn:hover { background: var(--nav-hover); } }
.tour-dlg { width: min(1320px, calc(100vw - 48px)); height: min(980px, calc(100dvh - 48px)); max-width: none; max-height: none; padding: 0;
            border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--bg); color: var(--text); box-shadow: var(--shadow-2); overflow: hidden; }
.tour-dlg[open] { display: flex; flex-direction: column; }
.tour-dlg::backdrop { background: rgba(0, 0, 0, .45); }
.tour-dlg iframe { flex: 1; min-height: 0; display: block; width: 100%; border: 0; background: var(--bg); }
.tour-dlg > .chat-panel-tools { position: absolute; top: 10.5px; right: 7px; z-index: 1; }   /* 11.5 and 8px from the corner, as in the chat panel (less the 1px border) */
.tour-dlg:focus, .tour-dlg iframe:focus { outline: none; box-shadow: none; }   /* the focus goes into the tour on opening: no ring around it */
html:has(.tour-dlg[open]) { overflow: hidden; }
/* the tours' play disc (the Tours page's cards), with the sprite's play-solid */
.tour-play { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 50%;
             background: var(--text-strong); color: var(--bg); }
.tour-play .icon { width: 18px; height: 18px; }
@media (width <= 720px) {
  .tour-dlg { width: 100vw; height: 100dvh; border: 0; border-radius: 0; }   /* a phone: the whole screen */
  .tour-dlg > .chat-panel-tools { top: 11.5px; right: 8px; }   /* no border here */
}
