/* ============================================================================
   Corporate Intelligence — application chrome and components
   ============================================================================

   the app's own surfaces, styled against the design-system tokens in theme.css.
   The split mirrors the design system's own (base.scss = shared system, global.scss =
   app chrome): anything here may consume --p-* / --app-* tokens, but must never
   hardcode a brand hex. If you reach for a literal colour, it probably belongs
   in theme.css instead.

   Layout note: the app is a header + centred-column app, not the design system's
   nav-rail shell, so this doesn't clone that structure. What it does take is
   the visual language — the gradient ground, the floating 16px content card,
   transparent chrome, Inter, and the borders-not-shadows dark mode.
   ============================================================================ */

/* ─── App ground ────────────────────────────────────────────────────────────
   The aqua→periwinkle wash lives on a fixed pseudo-element rather than on
   <body> so it stays put while the page scrolls, instead of stretching to the
   full document height and washing out. */

/* A fixed-height shell, same as the design system's .theme: the page itself never
   scrolls, each screen scrolls inside <main>. min-height would not do — it's a
   floor, so children stay free to grow and nothing can claim "the leftover
   viewport height". dvh so mobile browser chrome doesn't cost a strip. */
body {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-size: var(--app-text-sm);
  background: transparent;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--app-ground);
}

/* ─── Header ────────────────────────────────────────────────────────────────
   the design system's header is transparent over the ground with brand-blue glyphs —
   no solid bar. Text colour comes from --p-text-color, which flips to a near
   white in dark mode, so the same rules read correctly in both schemes. */

header {
  min-height: 64px;
  color: var(--p-text-color);
  padding: var(--app-space-8) var(--app-space-20);
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 100;
  background: transparent;
  gap: var(--app-space-12);
}

.header-left {
  display: flex;
  align-items: center;
  gap: var(--app-space-12);
}

/* The wordmark is two-tone: the aqua half is fixed, the other half is
   `currentColor` so it reads as brand blue on the light ground and near-white
   on the dark one. That's why it's inlined here rather than an <img> —
   currentColor can't cross into an <img>'s isolated SVG document. (The shared-
   conversation page in main.py still uses the plain white logo.svg, which is
   correct: its header stays a solid dark bar.) */
.header-logo {
  height: 30px;
  width: auto;
  color: var(--p-text-color);
  flex-shrink: 0;
}

header h1 {
  font-size: var(--app-text-xl);
  font-weight: var(--app-font-semibold);
  letter-spacing: -0.01em;
}

header .tagline {
  color: var(--p-brand-aqua-600);
  font-size: var(--app-text-xs);
  font-weight: var(--app-font-medium);
}

.header-right {
  display: flex;
  align-items: center;
  gap: var(--app-space-8);
  position: relative;
  min-width: 0;
}

/* The tab strip is the only part of the header allowed to run out of room.
   A superadmin sees ten tabs plus the theme toggle, username, role badge,
   Password and Logout; at 1366x768 that overflowed by 9px and clipped Logout,
   and the hamburger fallback only starts at 768px. Letting the tabs scroll
   inside their own track keeps the account controls pinned and reachable at
   any width. Scrollbar hidden — it would sit under the tabs in the header. */
/* Groups everything the mobile hamburger owns. `contents` means the wrapper
   contributes no box of its own on desktop — the tab strip, theme toggle and
   account menu lay out exactly as if it weren't here. It only becomes a real
   element inside the mobile media query. */
.header-menu {
  display: contents;
}

/* Wraps rather than scrolls. The hidden scrollbar meant a superadmin's tabs
   simply ran off the edge with nothing to show it: at 1280px "Admin" was
   gone entirely and "Mailboxes" was cut mid-word, which reads as a missing
   feature rather than as content out of view. Wrapping costs a second row
   on wide accounts and loses nothing. */
.nav-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-4);
  min-width: 0;
  scrollbar-width: none;
}

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

/* Tabs read as quiet text buttons until selected — the the design system "text
   secondary" treatment — so the header stays calm at eight-plus tabs. */
.nav-tab {
  padding: var(--app-space-8) var(--app-space-12);
  background: transparent;
  color: var(--p-text-color);
  border: 1px solid transparent;
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-medium);
  transition: background var(--app-duration-fast) var(--app-ease-standard),
    color var(--app-duration-fast) var(--app-ease-standard);
  white-space: nowrap;
}

/* Hover is a neutral wash, not the primary tint — the selected state owns the
   brand colour, so hover has to read as "reachable" without competing. 5% is
   tuned, not guessed: measured against the gradient behind the header it moves
   the background 15/255, where selected moves it 26. Weaker than selected but
   still legible. At 8% the two land 9 apart and are hard to tell apart; at 12%
   hover is louder than selected, which inverts the hierarchy. */
.nav-tab:hover {
  background: color-mix(in srgb, var(--p-text-color) 5%, transparent);
}

/* Selected: a tint rather than a solid aqua pill, at the stronger nav-specific
   opacity — enough on its own here, so no border. Weight does the rest.
   Text stays --p-text-color deliberately: aqua-on-tint measures ~2.5:1, which
   is unreadable, while brand blue holds ~7:1. */
.nav-tab.active {
  background: var(--app-nav-selected-background);
  color: var(--p-text-color);
  font-weight: var(--app-font-semibold);
}

/* ─── Account menu ──────────────────────────────────────────────────────────
   The username is the trigger; Password and Logout live behind it. With eleven
   tabs for a superadmin those two buttons overflowed the header at 1366px, and
   the hamburger fallback only starts at 768px. */

.user-menu-wrap {
  position: relative;
  flex-shrink: 0;
}

.user-info {
  display: flex;
  align-items: center;
  gap: var(--app-space-8);
  color: var(--p-text-color);
  font-size: var(--app-text-sm);
  /* It is a button now, so it needs the affordance the plain div never had. */
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--p-border-radius-md);
  padding: var(--app-space-4) var(--app-space-8);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--app-duration-fast) var(--app-ease-standard);
}

.user-info:hover,
.user-info[aria-expanded='true'] {
  background: color-mix(in srgb, var(--p-text-color) 5%, transparent);
}

.user-menu-caret {
  font-size: var(--app-text-2xs);
  color: var(--p-text-muted-color);
  line-height: var(--app-leading-none);
}

.user-menu {
  position: absolute;
  top: calc(100% + var(--app-space-4));
  right: 0;
  min-width: 180px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: var(--app-space-2);
  padding: var(--app-space-4);
  background: var(--p-overlay-background);
  border: 1px solid var(--p-overlay-border-color);
  border-radius: var(--p-border-radius-lg);
  box-shadow: var(--p-shadow-lg);
}

.user-menu button {
  appearance: none;
  background: transparent;
  border: none;
  border-radius: var(--p-border-radius-md);
  padding: var(--app-space-8) var(--app-space-12);
  text-align: left;
  color: var(--p-text-color);
  font-size: var(--app-text-sm);
  cursor: pointer;
  white-space: nowrap;
}

.user-menu button:hover,
.user-menu button:focus-visible {
  background: var(--p-selection-background);
  outline: none;
}

.user-role {
  padding: var(--app-space-2) var(--app-space-8);
  background: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
  border-radius: var(--p-border-radius-sm);
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Icon buttons in the header carry no outline — they sit on the ground, not on
   a surface, and a box around each one made the bar read as a toolbar. Hover
   supplies the affordance. The border stays as `transparent` rather than
   `none` so their box matches the account trigger beside them.
   (.btn-logout dropped from this group: the account menu replaced it and the
   class no longer appears in the markup.) */
.btn-theme,
.btn-nav-toggle {
  padding: var(--app-space-8) var(--app-space-12);
  background: transparent;
  color: var(--p-text-color);
  border: 1px solid transparent;
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-sm);
  line-height: 1;
  white-space: nowrap;
  transition: background var(--app-duration-fast) var(--app-ease-standard);
}

.btn-theme:hover,
.btn-nav-toggle:hover {
  background: color-mix(in srgb, var(--p-text-color) 5%, transparent);
}

.btn-nav-toggle {
  display: none;
}

/* Full-bleed, like the design system's shell — the ground reads as a frame around the
   content rather than a field beside it. A flex column so the active screen can
   claim the leftover viewport height; min-height:0 lets it shrink below its
   content so inner panes scroll instead of pushing the page taller. */
main {
  flex: 1;
  width: 100%;
  padding: 0 var(--app-space-16) var(--app-space-16);
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* Since <body> no longer scrolls, this is the scroll container for the
     content-sized screens (admin, dashboard). Chat sizes itself to fit, so it
     never triggers this. */
  overflow-y: auto;
}

/* ─── Surfaces ──────────────────────────────────────────────────────────────
   The floating card: 16px radius, shadow-md in light, and in dark a visible
   border instead (shadow tokens resolve to `none` there). */

/* The card is .chat-layout, not its children: the sidebar and the chat column
   are siblings inside it, and they have to read as one surface split by a
   divider rather than two floating panels. overflow:hidden is what lets the
   sidebar's square corners sit inside the 16px radius. */
.chat-layout,
.admin-container,
.login-container {
  background: var(--p-content-background);
  border-radius: var(--app-radius-card);
  box-shadow: var(--p-shadow-md);
}

/* The chat card is deliberately borderless — it fills the viewport, so its own
   size is the edge and a rule around it just adds noise. The other two are
   content-sized boxes floating on the ground and still need one, which is also
   what carries their elevation in dark mode where shadows resolve to none. */
.admin-container,
.login-container {
  border: 1px solid var(--p-content-border-color);
}

/* width:100% is load-bearing now that <main> is a flex column: the `auto`
   side margins that centre this also switch off the default cross-axis
   stretch, so without an explicit width the card shrink-wraps its content
   (311px) instead of filling to its 400px cap. */
.login-container {
  width: 100%;
  max-width: 400px;
  margin: var(--app-space-48) auto;
  padding: var(--app-space-32);
  flex-shrink: 0;
}

.login-container h2 {
  margin-bottom: var(--app-space-24);
  color: var(--p-text-color);
  font-size: var(--app-text-2xl);
  font-weight: var(--app-font-semibold);
}

/* Transparent — it's a column inside the .chat-layout card, not a card itself.
   The card went full-bleed, which is right for the card and wrong for prose:
   at 1293px the transcript hit 102 characters per line and it scales with the
   monitor. This gutter centres a fixed-width reading column inside the card —
   the scrollbar stays on the card edge, only the content is constrained. */
.chat-container {
  --chat-gutter: max(var(--app-space-24), calc((100% - 880px) / 2));
  background: transparent;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  min-width: 0;
}

.admin-container {
  padding: var(--app-space-24);
}

/* ─── Forms ─────────────────────────────────────────────────────────────────
   1px borders (Aura) rather than the old 2px, with the focus ring carrying the
   emphasis instead of a thicker edge. */

.form-group {
  margin-bottom: var(--app-space-16);
}

.form-group label {
  display: block;
  margin-bottom: var(--app-space-8);
  font-weight: var(--app-font-medium);
  font-size: var(--app-text-sm);
  color: var(--p-text-color);
}

.form-input,
.input-area textarea,
.filter-row select,
.source-typeahead input {
  width: 100%;
  padding: var(--app-space-8) var(--app-space-12);
  background: var(--p-form-field-background);
  color: var(--p-text-color);
  border: 1px solid var(--p-form-field-border-color);
  border-radius: var(--p-border-radius-md);
  font-size: var(--app-text-sm);
  outline: none;
  transition: border-color var(--app-duration-fast) var(--app-ease-standard),
    box-shadow var(--app-duration-fast) var(--app-ease-standard);
}

.form-input:hover,
.input-area textarea:hover {
  border-color: var(--p-form-field-hover-border-color);
}

.form-input:focus,
.input-area textarea:focus,
.filter-row select:focus,
.source-typeahead input:focus {
  border-color: var(--p-primary-color);
  box-shadow: 0 0 0 3px var(--p-selection-background);
}

.form-input::placeholder,
.input-area textarea::placeholder {
  color: var(--p-text-muted-color);
}

/* ─── Buttons ───────────────────────────────────────────────────────────────
   the design system's convention: solid primary = the CTA in a context; solid secondary
   = the dismissive partner in a dialog footer; danger = destructive. Aura's
   radius throughout — the old 3.75rem pills are what read least like the design system.
   Primary is aqua, not brand blue: blue is for text and secondary actions. */

.btn-primary,
.btn-add,
.btn-new-chat,
.btn-respond,
.btn-reopen {
  padding: var(--app-space-8) var(--app-space-16);
  background: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
  border: 1px solid var(--p-primary-color);
  border-radius: var(--p-border-radius-md);
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-medium);
  cursor: pointer;
  transition: background var(--app-duration-fast) var(--app-ease-standard),
    border-color var(--app-duration-fast) var(--app-ease-standard);
}

.btn-primary:hover,
.btn-add:hover,
.btn-new-chat:hover,
.btn-respond:hover,
.btn-reopen:hover {
  background: var(--p-primary-hover-color);
  border-color: var(--p-primary-hover-color);
}

/* The auth card's submit is the one deliberately full-width button: it's the
   only action on the card, so stretching reads as "end of the form". Scoped to
   .login-container (login + invite screens) rather than living on .btn-primary
   itself — the same class is the CTA in fifteen modal footers, where stretching
   is wrong and where a different font-size made it a different height from the
   Cancel button beside it. */
.login-container .btn-primary {
  width: 100%;
  padding: var(--app-space-8) var(--app-space-16);
  /* Same size as a dialog footer action — this is the same kind of control: the
     terminal decision on a card, not a toolbar button. */
  font-size: var(--app-text-base);
}

.btn-primary:disabled,
.btn-add:disabled,
.btn-new-chat:disabled {
  background: var(--p-surface-400);
  border-color: var(--p-surface-400);
  cursor: not-allowed;
}

/* Solid secondary — Cancel in a dialog footer. Brand blue, per the button
   conventions table. */
.btn-secondary,
.btn-edit,
.btn-close-fb {
  padding: var(--app-space-8) var(--app-space-16);
  background: var(--p-ci-blue-500);
  color: var(--p-content-background);
  border: 1px solid var(--p-ci-blue-500);
  border-radius: var(--p-border-radius-md);
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-medium);
  cursor: pointer;
  transition: opacity var(--app-duration-fast) var(--app-ease-standard);
}

/* No flex:1 — footer buttons hug their content. See .modal-actions. */

.btn-secondary:hover,
.btn-edit:hover,
.btn-close-fb:hover {
  opacity: 0.85;
}

/* In dark the brand blue is a near-white grey, so a solid secondary button
   glared. A quiet dark button with light text instead. */
body.dark .btn-secondary,
body.dark .btn-edit,
body.dark .btn-close-fb {
  background: var(--p-surface-700);
  color: var(--p-text-color);
  border-color: var(--p-surface-600);
}

.btn-delete {
  background: var(--p-danger-color);
  color: var(--p-danger-contrast-color);
  border: 1px solid var(--p-danger-color);
}

.btn-delete:hover {
  background: var(--p-danger-hover-color);
  border-color: var(--p-danger-hover-color);
}

/* A button that cannot be pressed looks it. Erase stayed red after a
   preview that found nothing, and a press did nothing. */
.btn-delete:disabled,
.btn-secondary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* A press still being answered shows on the thing pressed (dispatchAct in
   render.js), after a third of a second, so a quick answer never flickers.
   Four steps a second: a smooth fade draws sixty frames to say the same. */
[data-busy] {
  cursor: progress;
  animation: busy 1s steps(4) 0.3s infinite alternate;
}

@keyframes busy {
  to { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  [data-busy] { animation: none; opacity: 0.6; }
}

.btn-action {
  padding: var(--app-space-4) var(--app-space-8);
  border: none;
  border-radius: var(--p-border-radius-sm);
  cursor: pointer;
  font-size: var(--app-text-xs);
  font-weight: var(--app-font-medium);
  margin-right: var(--app-space-4);
}

/* Outlined secondary — available but dismissive. */
.btn-feedback {
  padding: var(--app-space-8) var(--app-space-12);
  background: transparent;
  color: var(--p-primary-color);
  border: 1px solid var(--p-primary-color);
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-medium);
  transition: background var(--app-duration-fast) var(--app-ease-standard);
  white-space: nowrap;
}

.btn-feedback:hover {
  background: var(--p-selection-background);
}

.btn-sm {
  padding: var(--app-space-4) var(--app-space-12);
  font-size: var(--app-text-xs);
}

/* Carries the same 1px border as the real buttons even though it's an anchor —
   without it this sits 2px shorter than the Close button beside it in the file
   viewer's footer. */
.download-btn {
  display: inline-block;
  padding: var(--app-space-8) var(--app-space-16);
  background: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
  text-decoration: none;
  border: 1px solid var(--p-primary-color);
  border-radius: var(--p-border-radius-md);
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-medium);
  transition: background var(--app-duration-fast) var(--app-ease-standard),
    border-color var(--app-duration-fast) var(--app-ease-standard);
}

.download-btn:hover {
  background: var(--p-primary-hover-color);
  border-color: var(--p-primary-hover-color);
}

.error-msg {
  color: var(--p-danger-color);
  font-size: var(--app-text-sm);
  margin-top: var(--app-space-16);
}

/* ─── Chat ──────────────────────────────────────────────────────────────────
   Sent bubbles take the design system's periwinkle (the subtle primary tint) rather than a
   solid brand-blue fill, so the transcript stays legible as dark-on-light in
   both schemes instead of flipping to white-on-blue. */

/* min-height:0 is what actually makes this scroll. It has had overflow-y:auto
   since before the redesign, but a flex item won't shrink below its content
   without this, so the transcript used to push the whole page taller instead
   of scrolling in place. */
.messages {
  flex: 1;
  min-height: 0;
  padding: var(--app-space-24) var(--chat-gutter);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--app-space-16);
}

/* Everything below the transcript keeps its natural height — only the message
   list absorbs the slack. */
.saved-queries,
.shared-queries,
.examples,
.input-area {
  flex-shrink: 0;
}

.message {
  /* Bounded by measure, not just by percentage: 80% of the reading column is
     still ~94 characters, past the ~75-90 where lines get hard to track back
     from. `ch` keeps that true if the type scale ever moves. */
  max-width: min(80%, 72ch);
  padding: var(--app-space-12) var(--app-space-16);
  border-radius: var(--p-border-radius-xl);
  line-height: var(--app-leading-relaxed);
  font-size: var(--app-text-sm);
}

.message.user {
  background: color-mix(in srgb, var(--p-primary-color) 10%, var(--p-content-background));
  color: var(--p-text-color);
  align-self: flex-end;
  border: 1px solid color-mix(in srgb, var(--p-primary-color) 30%, transparent);
  position: relative;
}

/* An answer is a sheet of paper: white, one hairline, no shadow. */
.message.assistant {
  background: var(--p-content-background);
  color: var(--p-text-color);
  align-self: flex-start;
  border: 1px solid var(--p-content-border-color);
  position: relative;
}

/* The welcome line carries the friendly colour. */
.messages > .message.assistant:first-child {
  border-left: 3px solid var(--app-friendly-color);
}

/* A wide table scrolls inside the answer instead of being cut. */
.message table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
}

/* The sources folded into the answer. */
.document-refs-inline {
  margin-top: var(--app-space-12);
  border-top: 1px solid var(--p-content-border-color);
  padding-top: var(--app-space-8);
}

.document-refs-inline .document-list {
  border: none;
  padding: 0;
  margin: 0;
  background: transparent;
}

/* Where the answer came from, as a small badge at the end of its row. */
.backend-badge {
  margin-left: auto;
  align-self: center;
  font-size: var(--app-text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--p-text-muted-color);
  border: 1px solid var(--p-content-border-color);
  padding: 1px var(--app-space-8);
}

.message pre {
  background: var(--p-content-background);
  border: 1px solid var(--p-content-border-color);
  padding: var(--app-space-12);
  border-radius: var(--p-border-radius-md);
  overflow-x: auto;
  margin: var(--app-space-8) 0;
  font-size: var(--app-text-xs);
}

.message.loading {
  color: var(--p-text-muted-color);
  font-style: italic;
}

.generated-file {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--app-space-8);
}

.generated-file .file-icon {
  font-size: var(--app-text-3xl);
}

.generated-file .file-name {
  font-weight: var(--app-font-medium);
  color: var(--p-text-color);
}

/* ─── Source / document references ──────────────────────────────────────── */

.document-list {
  background: var(--p-content-background);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-lg);
  padding: var(--app-space-12);
  margin-top: var(--app-space-8);
}

.document-list-header {
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
  margin-bottom: var(--app-space-8);
  font-size: var(--app-text-sm);
  cursor: pointer;
  list-style: none;
}

.document-list-header::-webkit-details-marker {
  display: none;
}

.document-list-header::before {
  content: '▶ ';
  font-size: var(--app-text-2xs);
}

details[open] > .document-list-header::before {
  content: '▼ ';
}

.document-item {
  display: flex;
  align-items: flex-start;
  gap: var(--app-space-8);
  padding: var(--app-space-4) 0;
  border-bottom: 1px solid var(--p-content-border-color);
}

.document-item:last-child {
  border-bottom: none;
}

.doc-icon {
  font-size: var(--app-text-base);
  flex-shrink: 0;
  line-height: var(--app-leading-normal);
}

/* subject + meta stacked; min-width:0 lets the subject wrap inside the flex row */
.doc-body {
  display: flex;
  flex-direction: column;
  gap: var(--app-space-2);
  min-width: 0;
  flex: 1;
}

.doc-link {
  color: var(--app-link-color);
  text-decoration: none;
  font-weight: var(--app-font-medium);
  white-space: normal;
  overflow-wrap: anywhere;
}

.doc-link:hover {
  text-decoration: underline;
  color: var(--app-link-hover-color);
}

/* date · sender line under each source; wraps instead of truncating */
.doc-meta {
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  white-space: normal;
  overflow-wrap: anywhere;
}

.doc-path {
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Markdown tables in chat answers */
.md-table-wrap {
  overflow-x: auto;
  margin: var(--app-space-8) 0;
}

.md-table {
  border-collapse: collapse;
  font-size: var(--app-text-xs);
}

.md-table th,
.md-table td {
  border: 1px solid var(--p-content-border-color);
  padding: var(--app-space-4) var(--app-space-8);
  text-align: left;
  white-space: nowrap;
}

/* The by-source brief: source on the left, what happened on the right, the
   shape of the organisation's own meeting minutes. Its second cell is a paragraph,
   so it has to wrap; nowrap sent it straight off the pane. */
.md-table-prose {
  width: 100%;
  table-layout: fixed;
}

.md-table-prose th,
.md-table-prose td {
  white-space: normal;
  overflow-wrap: anywhere;
}

.md-table-prose th:first-child,
.md-table-prose td:first-child {
  width: 9.5rem;
}

/* A cell holding a sentence wraps, in a table of any width. On one line it
   ran off the side of the answer, and the bar to scroll by shows on hover
   alone. */
.md-table td.md-long {
  white-space: normal;
  min-width: 16rem;
}

.md-table th {
  background: var(--p-surface-200);
  color: var(--p-text-color);
  font-weight: var(--app-font-semibold);
}

.md-table tr:nth-child(even) td {
  background: var(--p-surface-100);
}

/* surface.700, not surface.800 — the assistant bubble these tables sit inside
   is already surface.800, so a matching header row would vanish into it and the
   table would lose its header entirely in dark mode. */
body.dark .md-table th {
  background: var(--p-surface-700);
}

body.dark .md-table tr:nth-child(even) td {
  background: var(--p-surface-950);
}

/* ─── Composer ──────────────────────────────────────────────────────────── */

.input-area {
  padding: var(--app-space-16) var(--chat-gutter);
  background: var(--p-content-background);
  border-top: 1px solid var(--p-content-border-color);
  display: flex;
  gap: var(--app-space-8);
  align-items: flex-end;
}

.input-area textarea {
  flex: 1;
  font-family: inherit;
  resize: none;
  overflow: hidden;
  min-height: 40px;
  max-height: 10rem;
  line-height: var(--app-leading-normal);
}

.input-btn {
  width: 40px;
  height: 40px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-base);
  flex-shrink: 0;
  transition: all var(--app-duration-fast) var(--app-ease-standard);
  border: 1px solid transparent;
}

.input-btn.primary {
  background: var(--p-primary-color);
  border-color: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
}

.input-btn.primary:hover {
  background: var(--p-primary-hover-color);
  border-color: var(--p-primary-hover-color);
}

.input-btn.primary:disabled {
  background: var(--p-surface-400);
  border-color: var(--p-surface-400);
  cursor: not-allowed;
}

.input-btn.ghost {
  background: transparent;
  color: var(--p-text-muted-color);
  border-color: var(--p-content-border-color);
}

.input-btn.ghost:hover {
  color: var(--p-primary-color);
  border-color: var(--p-primary-color);
  background: var(--p-selection-background);
}

/* ─── Example prompts ───────────────────────────────────────────────────── */

.examples {
  padding: var(--app-space-8) var(--chat-gutter) var(--app-space-12);
}

.examples h3 {
  font-size: var(--app-text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--app-font-semibold);
  color: var(--p-text-muted-color);
  margin-bottom: var(--app-space-8);
}

.examples ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-8);
}

.examples li {
  background: var(--p-content-background);
  border: 1px solid var(--p-content-border-color);
  padding: var(--app-space-4) var(--app-space-12);
  border-radius: var(--app-radius-pill);
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  cursor: pointer;
  transition: all var(--app-duration-fast) var(--app-ease-standard);
}

.examples li:hover {
  border-color: var(--p-primary-color);
  color: var(--p-primary-color);
  background: var(--p-selection-background);
}

.examples-more {
  margin-top: var(--app-space-8);
  font-size: var(--app-text-xs);
}

.examples-more a {
  color: var(--app-link-color);
  text-decoration: none;
}

.examples-more a:hover {
  text-decoration: underline;
}

/* ─── Admin ─────────────────────────────────────────────────────────────── */

.admin-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--app-space-24);
  padding-bottom: var(--app-space-16);
  border-bottom: 1px solid var(--p-content-border-color);
}

.admin-header h2 {
  color: var(--p-text-color);
  font-size: var(--app-text-xl);
  font-weight: var(--app-font-semibold);
}

.users-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--app-text-sm);
}

.users-table th,
.users-table td {
  padding: var(--app-space-12) var(--app-space-16);
  text-align: left;
  border-bottom: 1px solid var(--p-content-border-color);
}

.users-table th {
  background: var(--p-surface-200);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

body.dark .users-table th {
  background: var(--p-surface-800);
}

.users-table tr:hover {
  background: var(--p-selection-background);
}

.role-badge {
  padding: var(--app-space-2) var(--app-space-8);
  border-radius: var(--p-border-radius-sm);
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.role-admin {
  background: var(--p-ci-blue-500);
  color: var(--p-content-background);
}

body.dark .role-admin {
  background: var(--p-surface-700);
  color: var(--p-text-color);
}

.role-manager {
  background: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
}

.role-user {
  background: var(--p-surface-400);
  color: var(--p-surface-950);
}

.permissions-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-4);
}

.things-register {
  display: block;
  margin-top: var(--app-space-4);
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  white-space: nowrap;
}

.permission-tag {
  background: var(--p-surface-200);
  color: var(--p-text-color);
  padding: var(--app-space-2) var(--app-space-8);
  border-radius: var(--p-border-radius-sm);
  font-size: var(--app-text-2xs);
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  display: flex;
  align-items: center;
  gap: var(--app-space-4);
}

body.dark .permission-tag {
  background: var(--p-surface-800);
}

.permission-tag .remove,
.source-tag .remove {
  cursor: pointer;
  color: var(--p-danger-color);
  font-weight: var(--app-font-bold);
}

.source-tag {
  background: var(--p-ci-purple-subtle);
  color: var(--p-text-color);
  padding: var(--app-space-2) var(--app-space-8);
  border-radius: var(--p-border-radius-sm);
  font-size: var(--app-text-2xs);
  display: flex;
  align-items: center;
  gap: var(--app-space-4);
}

/* fixed, not absolute: it is positioned from getBoundingClientRect (viewport
   coords) and <body> no longer scrolls, so absolute + window.scrollY would be
   right only by coincidence. */
.source-typeahead {
  position: fixed;
  z-index: 1000;
  background: var(--p-overlay-background);
  border: 1px solid var(--p-overlay-border-color);
  border-radius: var(--p-border-radius-lg);
  box-shadow: var(--p-shadow-lg);
  width: 260px;
  max-height: 280px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.source-typeahead input {
  border: none;
  border-bottom: 1px solid var(--p-content-border-color);
  border-radius: 0;
  padding: var(--app-space-8);
}

.source-typeahead input:focus {
  box-shadow: none;
  border-color: var(--p-content-border-color);
  border-bottom-color: var(--p-primary-color);
}

.source-typeahead .vt-results {
  overflow-y: auto;
  max-height: 220px;
}

.source-typeahead .vt-item {
  padding: var(--app-space-8) var(--app-space-12);
  cursor: pointer;
  font-size: var(--app-text-sm);
  border-radius: var(--p-border-radius-md);
  margin: var(--app-space-2) var(--app-space-4);
}

.source-typeahead .vt-item:hover {
  background: var(--p-selection-background);
  color: var(--p-text-color);
}

.source-typeahead .vt-empty {
  padding: var(--app-space-8);
  color: var(--p-text-muted-color);
  font-size: var(--app-text-sm);
  text-align: center;
}

/* ─── Modals ────────────────────────────────────────────────────────────── */

.modal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal.show {
  display: flex;
}

/* Actions: a proposal's status and the draft it carries; a decision's status. */
.status-chip {
  padding: var(--app-space-2) var(--app-space-8);
  border-radius: var(--app-radius-pill);
  font-size: var(--app-text-xs);
  white-space: nowrap;
  background: color-mix(in srgb, var(--p-text-muted-color) 15%, transparent);
  color: var(--p-text-muted-color);
}

.status-chip.is-proposed {
  background: color-mix(in srgb, var(--p-warning-color) 18%, transparent);
  color: var(--p-warning-color);
}

/* A source that is on: the friendly green, so it never reads as a button. */
.status-chip.is-on {
  background: var(--app-friendly-soft);
  color: var(--app-friendly-color);
}

.proposal-body {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: var(--app-text-sm);
  margin: var(--app-space-8) 0;
  max-height: 12rem;
  overflow-y: auto;
}

.status-select,
.backend-select {
  width: auto;
  padding: var(--app-space-2) var(--app-space-8);
  font-size: var(--app-text-xs);
}

/* The item viewer opens from the Map, from Watches and from search, so it
   must stack above whichever modal opened it; the thread view opens from
   the item viewer and is the leaf. */
#item-viewer-modal {
  z-index: 1100;
}

#thread-modal {
  z-index: 1200;
}

/* A dialog taller than the window scrolls inside itself. Centred by the
   overlay's flex, an uncapped one overflows at both ends: the connector
   form lost its heading off the top and its Save button off the bottom,
   with no way to reach either. The cap is on the dialog rather than on a
   body element inside it, since each dialog writes its own markup. */
.modal-content {
  background: var(--p-overlay-background);
  color: var(--p-text-color);
  border: 1px solid var(--p-overlay-border-color);
  padding: var(--app-space-24);
  border-radius: var(--app-radius-card);
  box-shadow: var(--p-shadow-xl);
  max-width: 450px;
  width: 90%;
  max-height: calc(100vh - 2 * var(--app-space-24));
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* The buttons stay reachable while the form scrolls behind them. */
.modal-content > .modal-actions {
  position: sticky;
  bottom: calc(-1 * var(--app-space-24));
  background: var(--p-overlay-background);
  padding-block: var(--app-space-12);
  margin-bottom: calc(-1 * var(--app-space-24));
}

.modal-content h3 {
  margin-bottom: var(--app-space-24);
  color: var(--p-text-color);
  font-size: var(--app-text-xl);
  font-weight: var(--app-font-semibold);
}

/* A long dialog in parts. Each part starts at a hairline with its name in
   the display face: at the size of a field label, "My Overview" was passed
   by a reader looking for it. */
.modal-part {
  margin: var(--app-space-24) 0 var(--app-space-12);
  padding-top: var(--app-space-12);
  border-top: 1px solid var(--p-content-border-color);
  color: var(--p-text-color);
  font-family: var(--app-font-display);
  font-size: var(--app-text-lg);
}

/* Dialog footer. Buttons hug their content and sit bottom-right, dismissive
   first and affirmative last, so the action the dialog is for is the closest
   thing to the user's cursor. They are not a segmented control — stretching
   them to fill the dialog gives a 200px "Close" that reads as important as the
   CTA beside it. Every control here inherits the same font-size, padding and
   1px border, so they come out the same height without anyone setting one. */
.modal-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--app-space-8);
  margin-top: var(--app-space-24);
}

/* `a` as well as `button` — the file viewer's download action is an anchor. */
.modal-actions > button,
.modal-actions > a {
  flex: 0 0 auto;
  width: auto;
  /* A step up from the app's default `sm` — dialog actions are the terminal
     decision on a modal surface and carry more weight than a toolbar button. */
  font-size: var(--app-text-base);
  /* Without this a two-word label ("Send & Close") wraps inside its own box and
     comes out taller than its neighbours, which is the height inconsistency
     wearing a different hat. */
  white-space: nowrap;
}

/* ─── Email viewer ──────────────────────────────────────────────────────── */

.item-link {
  color: var(--app-link-color);
  text-decoration: underline;
  cursor: pointer;
  font-weight: var(--app-font-medium);
}

.item-link:hover,
.message.assistant .item-link:hover {
  color: var(--app-link-hover-color);
}

.message.assistant .item-link {
  color: var(--app-link-color);
}

.item-modal .modal-content {
  max-width: 800px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}

/* On a wide screen a source opens as a card beside the answer, not over it:
   the reader checks a sentence against its source with both in view. The
   card sits under the header, and the screen and any other open dialog
   narrow to the space left of it. A narrower screen keeps the dialog. */
@media (min-width: 1100px) {
  body {
    --item-beside: min(45vw, 760px);
  }

  #item-viewer-modal.show {
    inset: 64px 0 0 auto;
    width: var(--item-beside);
    background: transparent;
    padding: 0 var(--app-space-16) var(--app-space-16) 0;
    align-items: stretch;
  }

  #item-viewer-modal .modal-content {
    max-width: none;
    width: 100%;
    max-height: 100%;
  }

  body:has(#item-viewer-modal.show) main {
    margin-right: var(--item-beside);
    width: auto;
  }

  body:has(#item-viewer-modal.show) .modal.show:not(#item-viewer-modal) {
    right: var(--item-beside);
  }
}

/* A mail to sixty people has a To list taller than the screen. The list
   scrolls inside its own row, and the header block as a whole yields to the
   body, so the text is always reachable. */
.item-meta {
  flex-shrink: 1;
  min-height: 0;
  max-height: 45vh;
  overflow-y: auto;
}
.item-meta-value {
  max-height: 7.5em;
  overflow-y: auto;
}

/* The source popup is where a user decides whether to trust an answer, so the
   header has to be scannable: subject first, then who and when, with the labels
   quiet enough to disappear. */
.item-header {
  border-bottom: 1px solid var(--p-content-border-color);
  padding: 0 0 var(--app-space-16) var(--app-space-12);
  margin-bottom: var(--app-space-16);
  border-left: 3px solid var(--p-primary-color);
}

.item-header h3 {
  margin-bottom: var(--app-space-8);
  color: var(--p-text-color);
  font-size: var(--app-text-lg);
  font-weight: var(--app-font-semibold);
  line-height: var(--app-leading-tight);
}

.item-meta {
  display: flex;
  flex-direction: column;
  gap: var(--app-space-2);
  font-size: var(--app-text-sm);
}

.item-meta-row {
  display: flex;
  align-items: baseline;
  gap: var(--app-space-12);
}

.item-meta-row.hidden {
  display: none;
}

.item-meta-label {
  flex: 0 0 3.2rem;
  color: var(--p-text-muted-color);
  font-size: var(--app-text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--app-font-semibold);
}

.item-meta-value {
  color: var(--p-text-color);
  min-width: 0;
  overflow-wrap: anywhere;
}

.item-addr {
  color: var(--p-text-color);
}

.item-container-chip {
  display: inline-block;
  background: var(--p-selection-background);
  color: var(--p-primary-color);
  border-radius: var(--app-radius-pill);
  padding: var(--app-space-2) var(--app-space-8);
  font-size: var(--app-text-xs);
  font-weight: var(--app-font-medium);
}

.item-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--app-space-16);
  background: var(--p-surface-200);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-lg);
  white-space: pre-wrap;
  font-size: var(--app-text-sm);
  line-height: var(--app-leading-relaxed);
  max-height: 50vh;
}

body.dark .item-body {
  background: var(--p-surface-950);
}

/* Replied-to text is context, not the message. Dimming it makes the new
   content in a long chain obvious at a glance. */
.item-quote {
  display: block;
  color: var(--p-text-muted-color);
  border-left: 2px solid var(--p-content-border-color);
  padding-left: var(--app-space-12);
  margin: var(--app-space-2) 0 var(--app-space-8) var(--app-space-2);
}

.item-sep {
  display: block;
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  margin-top: var(--app-space-8);
}

.item-empty {
  color: var(--p-text-muted-color);
  font-style: italic;
}

.item-attach-block {
  margin-top: var(--app-space-16);
  padding-top: var(--app-space-12);
  border-top: 1px dashed var(--p-content-border-color);
}

.item-attach-title {
  font-size: var(--app-text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--app-font-semibold);
  color: var(--p-primary-color);
  margin-bottom: var(--app-space-8);
}

.item-loading {
  text-align: center;
  padding: var(--app-space-32);
  color: var(--p-text-muted-color);
}

/* ─── Thread view ───────────────────────────────────────────────────────── */

.modal-large .modal-content {
  max-width: 900px;
}

.thread-view {
  display: flex;
  flex-direction: column;
  gap: var(--app-space-16);
  max-height: 60vh;
  overflow-y: auto;
  padding: var(--app-space-16);
}

.thread-item {
  border-left: 3px solid var(--p-ci-blue-300);
  padding: var(--app-space-16);
  margin-left: var(--app-space-16);
  background: var(--p-surface-200);
  border-radius: 0 var(--p-border-radius-lg) var(--p-border-radius-lg) 0;
}

body.dark .thread-item {
  background: var(--p-surface-950);
}

.thread-item.root {
  margin-left: 0;
  border-left-color: var(--p-primary-color);
}

.thread-item-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: var(--app-space-8);
}

.thread-item-from {
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
}

.thread-item-date,
.thread-item-title,
.thread-count {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
}

.thread-item-title {
  font-size: var(--app-text-sm);
  margin-bottom: var(--app-space-8);
}

.thread-count {
  font-size: var(--app-text-sm);
  margin-bottom: var(--app-space-16);
}

.thread-item-body {
  font-size: var(--app-text-sm);
  line-height: var(--app-leading-relaxed);
  white-space: pre-wrap;
  color: var(--p-text-color);
}

/* ─── File viewer ───────────────────────────────────────────────────────── */

.file-type-badge {
  display: inline-block;
  padding: var(--app-space-2) var(--app-space-8);
  border-radius: var(--p-border-radius-sm);
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  /* allow-hex: vendor file-format colours (Adobe / Microsoft), not brand */
  color: #ffffff;
}

/* allow-hex: canonical file-format brand colours */
.file-type-pdf {
  background: #e74c3c;
}
.file-type-docx {
  background: #2b5797;
}
.file-type-xlsx {
  background: #217346;
}
.file-type-pptx {
  background: #d04423;
}
.file-type-txt,
.file-type-md {
  background: var(--p-surface-600);
}

.file-link {
  color: var(--app-link-color);
  text-decoration: underline;
  cursor: pointer;
  font-weight: var(--app-font-medium);
}

.file-link:hover {
  color: var(--app-link-hover-color);
}

/* ─── Badges ────────────────────────────────────────────────────────────── */

.nav-tab-wrapper {
  position: relative;
  display: inline-flex;
}

.notification-badge,
.alert-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  color: var(--p-danger-contrast-color);
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-bold);
  min-width: 16px;
  height: 16px;
  border-radius: var(--app-radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--app-space-4);
}

.notification-badge {
  background: var(--p-danger-color);
}

.alert-badge {
  background: var(--p-warning-color);
}

/* ─── Dashboard ─────────────────────────────────────────────────────────── */

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--app-space-16);
  margin-bottom: var(--app-space-24);
}

.stat-card,
.usage-stat,
.chart-container,
.feedback-item {
  background: var(--p-content-background);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-card);
  box-shadow: var(--p-shadow-sm);
}

.stat-card {
  padding: var(--app-space-20);
  text-align: center;
}

.stat-card .stat-value {
  font-size: var(--app-text-3xl);
  font-weight: var(--app-font-bold);
  color: var(--p-primary-color);
  line-height: var(--app-leading-tight);
}

.stat-card .stat-label,
.usage-stat .stat-label {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: var(--app-space-4);
}

.charts-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--app-space-24);
  margin-bottom: var(--app-space-24);
}

@media (max-width: 768px) {
  .charts-row {
    grid-template-columns: 1fr;
  }
}

.chart-container {
  padding: var(--app-space-20);
}

/* Chart.js sizes a responsive canvas from its parent, so the parent has to own
   the height. Without this the charts keep `maintainAspectRatio`, which ties
   height to container width — fine while <main> was capped at 1100px, but the
   card is full-bleed now, so on a 2560px display each column is ~1250px wide
   and the doughnut would render ~1250px tall. Fixed height instead; the design system's
   own <app-chart> wrapper does the same thing for the same reason. */
.chart-canvas {
  position: relative;
  height: 280px;
}

.chart-container h3 {
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
  margin-bottom: var(--app-space-16);
}

.dashboard-section {
  margin-bottom: var(--app-space-24);
}

.dashboard-section h3 {
  color: var(--p-text-color);
  margin-bottom: var(--app-space-16);
  font-size: var(--app-text-base);
  font-weight: var(--app-font-semibold);
}

.filter-row {
  display: flex;
  gap: var(--app-space-12);
  align-items: center;
  margin-bottom: var(--app-space-16);
}

.filter-row select {
  width: auto;
}

.usage-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--app-space-16);
  margin-bottom: var(--app-space-24);
}

.usage-stat {
  padding: var(--app-space-16);
  text-align: center;
}

.usage-stat .stat-value {
  font-size: var(--app-text-2xl);
  font-weight: var(--app-font-bold);
  color: var(--p-primary-color);
}

/* ─── Feedback ──────────────────────────────────────────────────────────── */

.feedback-tabs {
  display: flex;
  gap: var(--app-space-8);
  margin-bottom: var(--app-space-16);
}

.feedback-tab {
  padding: var(--app-space-8) var(--app-space-16);
  background: var(--p-content-background);
  color: var(--p-text-color);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-sm);
  transition: all var(--app-duration-fast) var(--app-ease-standard);
}

.feedback-tab.active {
  background: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
  border-color: var(--p-primary-color);
}

.feedback-item {
  padding: var(--app-space-16);
  margin-bottom: var(--app-space-12);
}

.feedback-meta {
  display: flex;
  align-items: center;
  gap: var(--app-space-8);
  margin-bottom: var(--app-space-8);
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
}

.feedback-category {
  padding: var(--app-space-2) var(--app-space-8);
  border-radius: var(--p-border-radius-sm);
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--p-primary-contrast-color);
}

.category-bug {
  background: var(--p-danger-color);
}
.category-feature {
  background: var(--p-info-color);
}
.category-comment {
  background: var(--p-success-color);
}
.category-general {
  background: var(--p-surface-500);
}

.feedback-message {
  font-size: var(--app-text-sm);
  line-height: var(--app-leading-relaxed);
  margin-bottom: var(--app-space-8);
}

.feedback-picture {
  display: inline-block;
  max-width: 320px;
  max-height: 240px;
  margin: 0 var(--app-space-8) var(--app-space-8) 0;
  border: 1px solid var(--p-content-border-color);
  vertical-align: top;
}

.feedback-voice {
  display: block;
  max-width: 320px;
  margin-bottom: var(--app-space-8);
}

.feedback-response {
  background: var(--p-surface-200);
  border-left: 3px solid var(--p-primary-color);
  padding: var(--app-space-12);
  margin-top: var(--app-space-8);
  border-radius: 0 var(--p-border-radius-md) var(--p-border-radius-md) 0;
  font-size: var(--app-text-sm);
}

body.dark .feedback-response {
  background: var(--p-surface-950);
}

.feedback-actions {
  display: flex;
  gap: var(--app-space-8);
  margin-top: var(--app-space-12);
}

.feedback-actions button {
  padding: var(--app-space-4) var(--app-space-12);
  border: none;
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-xs);
  font-weight: var(--app-font-medium);
}

/* ─── Sidebar ───────────────────────────────────────────────────────────── */

/* Claims the leftover viewport height rather than sizing to its content.
   min-height:0 is load-bearing: a flex item defaults to min-height:auto, which
   refuses to shrink below its content, so without it the card would grow past
   the viewport and overflow:hidden would clip the transcript out of reach. */
.chat-layout {
  display: flex;
  gap: 0;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* Width is a variable so the drag handle can set it; 380px is the default and
   what you get with no stored preference. Clamps live in the JS alongside the
   drag, so there is one source of truth for the bounds. */
.sidebar {
  width: var(--sidebar-width, 380px);
  background: transparent;
  border-right: 1px solid var(--p-content-border-color);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  flex-shrink: 0;
}

/* Straddles the divider: 5px of grab area, pulled back 2px each side so it
   occupies 1px of layout and the sidebar's border still reads as the line. */
.sidebar-resizer {
  flex: 0 0 5px;
  margin: 0 -2px;
  position: relative;
  z-index: 2;
  cursor: col-resize;
  background: transparent;
  touch-action: none;
}

.sidebar-resizer::after {
  content: '';
  position: absolute;
  inset: 0 2px;
  background: var(--p-primary-color);
  opacity: 0;
  transition: opacity var(--app-duration-fast) var(--app-ease-standard);
}

.sidebar-resizer:hover::after,
.sidebar-resizer:focus-visible::after,
.sidebar-resizer.dragging::after {
  opacity: 1;
}

.sidebar-resizer:focus-visible {
  outline: none;
}

/* Kills text selection and the I-beam cursor while dragging across the app. */
body.resizing-sidebar {
  user-select: none;
  cursor: col-resize;
}

.sidebar-header {
  padding: var(--app-space-16);
  border-bottom: 1px solid var(--p-content-border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--app-space-8);
}

.sidebar-header h3 {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--app-font-semibold);
}

.btn-new-chat {
  font-size: var(--app-text-xs);
  padding: var(--app-space-4) var(--app-space-12);
}

.sidebar-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--app-space-8);
}

.sidebar-group-label {
  font-size: var(--app-text-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--p-text-muted-color);
  padding: var(--app-space-8) var(--app-space-8) var(--app-space-4);
  font-weight: var(--app-font-semibold);
  display: flex;
  align-items: center;
  gap: var(--app-space-4);
  cursor: pointer;
  user-select: none;
  border-radius: var(--p-border-radius-md);
}

.sidebar-group-label:hover {
  color: var(--p-text-color);
}

.sidebar-caret {
  font-size: var(--app-text-2xs);
  line-height: var(--app-leading-none);
  width: 0.6rem;
}

/* The count is why collapsing is safe: a folded group still says how much is
   in it. */
.sidebar-group-count {
  margin-left: auto;
  background: var(--p-surface-200);
  color: var(--p-text-muted-color);
  border-radius: var(--app-radius-pill);
  padding: 0 var(--app-space-8);
  font-size: var(--app-text-2xs);
}

body.dark .sidebar-group-count {
  background: var(--p-surface-800);
}

.sidebar-group-items.hidden {
  display: none;
}

.sidebar-item {
  padding: var(--app-space-8) var(--app-space-12);
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-sm);
  color: var(--p-text-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--app-space-8);
  white-space: nowrap;
  overflow: hidden;
}

.sidebar-item:hover {
  background: var(--p-selection-background);
}

/* Selected rows use the shared selection tint rather than a solid fill — the
   the design system pattern, so the label keeps its normal colour. */
.sidebar-item.active {
  background: var(--p-selection-background);
  color: var(--p-text-color);
  font-weight: var(--app-font-medium);
}

.sidebar-item-title {
  /* Two lines, then an ellipsis: a question is rarely short. */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal;
  text-overflow: ellipsis;
  flex: 1;
}

.sidebar-item .sidebar-delete {
  display: none;
  background: none;
  border: none;
  color: var(--p-danger-color);
  cursor: pointer;
  font-size: var(--app-text-sm);
  padding: 0;
  flex-shrink: 0;
}

.sidebar-item:hover .sidebar-delete,
.sidebar-item.active .sidebar-delete {
  display: inline;
}

.sidebar-item .sidebar-rename {
  display: none;
  background: none;
  border: none;
  color: var(--p-text-muted-color);
  cursor: pointer;
  font-size: var(--app-text-sm);
  padding: 0 var(--app-space-4) 0 0;
  flex-shrink: 0;
}

.sidebar-item:hover .sidebar-rename,
.sidebar-item.active .sidebar-rename {
  display: inline;
}

.btn-load-more {
  width: calc(100% - var(--app-space-16));
  margin: var(--app-space-8);
  padding: var(--app-space-8);
  background: transparent;
  color: var(--p-primary-color);
  border: 1px dashed var(--p-content-border-color);
  border-radius: var(--p-border-radius-md);
  cursor: pointer;
  font-size: var(--app-text-xs);
}

.btn-load-more:hover {
  background: var(--p-selection-background);
}

/* ─── Saved / shared prompt chips ───────────────────────────────────────── */

.saved-queries,
.shared-queries {
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-8);
  padding: var(--app-space-8) var(--chat-gutter) 0;
}

.saved-chip {
  background: var(--p-ci-blue-500);
  color: var(--p-content-background);
  padding: var(--app-space-4) var(--app-space-12);
  border-radius: var(--app-radius-pill);
  font-size: var(--app-text-xs);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--app-space-4);
  transition: opacity var(--app-duration-fast) var(--app-ease-standard);
  max-width: 220px;
  position: relative;
}

.saved-chip:hover {
  opacity: 0.85;
}

body.dark .saved-chip {
  background: var(--p-surface-700);
  color: var(--p-text-color);
}

.saved-chip.shared {
  background: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
}

.saved-chip .chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.saved-chip:hover .chip-tooltip {
  display: block;
}

.chip-tooltip {
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--p-surface-900);
  /* allow-hex: white on a permanently dark tooltip, theme-agnostic */
  color: #ffffff;
  padding: var(--app-space-8) var(--app-space-12);
  border-radius: var(--p-border-radius-md);
  font-size: var(--app-text-xs);
  white-space: normal;
  /* From main: an absolutely positioned child sizes against its containing
     block, so without this it collapsed to the chip's own width and rendered as
     a ~90px column of single words. */
  width: max-content;
  max-width: 340px;
  z-index: 100;
  pointer-events: none;
  box-shadow: var(--p-shadow-md);
}

body.dark .chip-tooltip {
  background: var(--p-surface-700);
}

.saved-chip .chip-remove,
.saved-chip .chip-share {
  font-size: var(--app-text-2xs);
  opacity: 0.7;
  cursor: pointer;
  line-height: var(--app-leading-none);
}

.saved-chip .chip-remove:hover,
.saved-chip .chip-share:hover,
.saved-chip .chip-share.on {
  opacity: 1;
}

/* Prompts a colleague shared, kept below a line so your own row stays yours.
   Hidden entirely when nobody has shared anything. */
.shared-queries {
  margin-top: var(--app-space-8);
  border-top: 1px solid var(--p-content-border-color);
}

.shared-queries.hidden {
  display: none;
}

.shared-queries .shared-label {
  width: 100%;
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  margin-bottom: var(--app-space-2);
}

/* ─── The row of actions under a message ───────────────────────────────── */

.msg-actions {
  display: flex;
  align-items: center;
  gap: var(--app-space-2);
  margin-top: var(--app-space-8);
  opacity: 0.35;
  transition: opacity var(--app-duration-fast) var(--app-ease-standard);
}

.message.assistant > .msg-actions {
  padding-top: var(--app-space-8);
  border-top: 1px solid var(--p-content-border-color);
}

.message.user > .msg-actions {
  justify-content: flex-end;
  margin-top: var(--app-space-4);
}

/* Lit under the newest answer, under the pointer, and wherever the
   keyboard is. A touch screen has no pointer, so there every row is lit. */
.message.is-latest > .msg-actions,
.message:hover > .msg-actions,
.message:focus-within > .msg-actions {
  opacity: 1;
}

@media (hover: none) {
  .msg-actions { opacity: 1; }
}

.msg-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--p-border-radius-sm);
  padding: var(--app-space-4);
  cursor: pointer;
  color: inherit;
  opacity: 0.75;
}

.msg-action:hover,
.msg-action:focus-visible {
  opacity: 1;
  border-color: var(--p-content-border-color);
}

.msg-action:disabled { cursor: default; }

/* The click lands on the button, never on the drawing inside it, so a
   disabled thumb swallows it rather than handing it to the page. */
.msg-action-icon {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

/* The states come after the hover, so the hover never hides them. */
/* allow-hex: gold star is a fixed affordance colour, not a brand token */
.msg-action.msg-star.saved { color: #ffc233; opacity: 1; }
.msg-action.msg-star.saved .msg-action-icon { fill: currentColor; }
.msg-action.msg-delete:hover { color: var(--p-danger-color); }
.msg-action.done { color: var(--app-friendly-color); opacity: 1; }
.msg-action.failed { color: var(--app-attention-color); opacity: 1; }
.msg-action.msg-rate.selected-up { color: var(--app-friendly-color); opacity: 1; }
.msg-action.msg-rate.selected-down { color: var(--app-attention-color); opacity: 1; }

/* ─── Digests ───────────────────────────────────────────────────────────── */

.digest-item,
.alert-item {
  padding: var(--app-space-12);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-lg);
  margin-bottom: var(--app-space-8);
}

.digest-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.digest-item-info {
  flex: 1;
}

.digest-item-info .digest-name {
  font-weight: var(--app-font-medium);
}

.digest-item-info .digest-schedule {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
}

.digest-actions {
  display: flex;
  gap: var(--app-space-8);
  align-items: center;
}

.toggle-switch {
  position: relative;
  width: 40px;
  height: 22px;
}

.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background: var(--p-surface-400);
  border-radius: var(--app-radius-pill);
  transition: background var(--app-duration-base) var(--app-ease-standard);
}

.toggle-slider:before {
  content: '';
  position: absolute;
  height: 16px;
  width: 16px;
  left: 3px;
  bottom: 3px;
  /* allow-hex: the knob stays white on both the off and on track */
  background: #ffffff;
  border-radius: 50%;
  transition: transform var(--app-duration-base) var(--app-ease-standard);
}

.toggle-switch input:checked + .toggle-slider {
  background: var(--p-primary-color);
}

.toggle-switch input:checked + .toggle-slider:before {
  transform: translateX(18px);
}

/* ─── Alerts ────────────────────────────────────────────────────────────── */

.alert-item-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--app-space-4);
}

.alert-item-name {
  font-weight: var(--app-font-medium);
}

.alert-item-query {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  margin-bottom: var(--app-space-8);
}

.alert-item-footer {
  display: flex;
  gap: var(--app-space-8);
  align-items: center;
}

.alert-pending {
  background: color-mix(in srgb, var(--p-warning-color) 18%, transparent);
  color: var(--p-warning-color);
  padding: var(--app-space-2) var(--app-space-8);
  border-radius: var(--app-radius-pill);
  font-size: var(--app-text-xs);
  font-weight: var(--app-font-semibold);
}

.alert-narrow {
  color: var(--p-text-muted-color);
}

.alert-form-row {
  display: flex;
  gap: var(--app-space-12);
}

.alert-form-row .form-group {
  flex: 1;
}

.alert-hits {
  margin-top: var(--app-space-8);
  border-top: 1px solid var(--p-content-border-color);
  padding-top: var(--app-space-8);
}

.alert-hit {
  display: flex;
  gap: var(--app-space-8);
  align-items: baseline;
  font-size: var(--app-text-xs);
  padding: var(--app-space-2) 0;
  color: var(--p-text-muted-color);
}

.alert-hit.is-new .alert-hit-title {
  font-weight: var(--app-font-semibold);
}

.alert-hit-date {
  flex: none;
  font-variant-numeric: tabular-nums;
}

.alert-hit-title {
  color: var(--p-text-color);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.alert-hit-title:hover {
  text-decoration: underline;
}

.alert-hit-author {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.alert-hit-tag {
  flex: none;
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-pill);
  padding: 0 var(--app-space-8);
}

/* ─── Prompt library ────────────────────────────────────────────────────── */

.library-modal-content {
  max-width: 780px;
  width: 92%;
}

.library-intro,
.hub-summary,
.lib-admin-note,
.lib-admin-body {
  font-size: var(--app-text-sm);
  color: var(--p-text-muted-color);
}

.library-intro {
  margin-bottom: var(--app-space-12);
}

.hub-summary {
  margin: 0 0 var(--app-space-16);
}

.hub-summary .hub-down {
  color: var(--p-warning-color);
}

.library-body {
  max-height: 60vh;
  overflow-y: auto;
  padding-right: var(--app-space-4);
}

.lib-cat {
  margin-bottom: var(--app-space-20);
}

.lib-cat h4 {
  font-size: var(--app-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: var(--app-font-semibold);
  color: var(--p-primary-color);
  margin: 0 0 var(--app-space-8);
}

.lib-item {
  display: flex;
  gap: var(--app-space-12);
  align-items: flex-start;
  padding: var(--app-space-8) 0;
  border-bottom: 1px solid var(--p-content-border-color);
}

.lib-item-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--app-space-2);
}

.lib-item-main strong {
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
}

.lib-body {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
}

.lib-desc {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  font-style: italic;
}

.lib-item-actions {
  display: flex;
  gap: var(--app-space-4);
  flex-shrink: 0;
}

.lib-admin-note {
  margin: 0 0 var(--app-space-16);
  max-width: 60ch;
}

.lib-admin-note code {
  background: var(--p-surface-200);
  padding: 0 var(--app-space-4);
  border-radius: var(--p-border-radius-sm);
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
}

body.dark .lib-admin-note code {
  background: var(--p-surface-800);
}

.lib-admin-body {
  margin-top: var(--app-space-2);
  max-width: 55ch;
}

.lib-retired {
  opacity: 0.55;
}

.lib-runs {
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
}

.lib-actions {
  white-space: nowrap;
}

.lib-actions .btn-sm {
  margin-right: var(--app-space-4);
}

/* ─── Responsive ────────────────────────────────────────────────────────── */

@media (max-width: 768px) {
  header {
    padding: var(--app-space-12) var(--app-space-16);
    flex-wrap: nowrap;
    gap: var(--app-space-8);
  }

  header h1 {
    font-size: var(--app-text-lg);
  }

  header .tagline {
    display: none;
  }

  .btn-nav-toggle {
    display: inline-block;
    font-size: var(--app-text-lg);
  }

  /* ── One panel behind one button ─────────────────────────────────────────
     Tabs, theme and account actions all live in the menu here. The history
     had a drawer behind a second button; it is the chat screen itself now. */
  .header-menu {
    display: none;
  }

  .header-right.nav-open .header-menu {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--app-space-2);
    position: absolute;
    top: 100%;
    right: 0;
    min-width: 210px;
    max-width: min(280px, calc(100vw - var(--app-space-16)));
    padding: var(--app-space-8);
    background: var(--p-overlay-background);
    border: 1px solid var(--p-overlay-border-color);
    border-radius: var(--p-border-radius-lg);
    box-shadow: var(--p-shadow-lg);
    z-index: 200;
  }

  /* The tab strip is a plain stack in here — no horizontal scroll track. */
  .header-right.nav-open .nav-tabs {
    display: flex;
    flex-direction: column;
    gap: var(--app-space-2);
    overflow: visible;
    min-width: 0;
  }

  .header-right.nav-open .nav-tab,
  .header-right.nav-open .btn-theme,
  .header-right.nav-open .user-menu button {
    width: 100%;
    text-align: left;
    justify-content: flex-start;
    padding: var(--app-space-8) var(--app-space-12);
  }

  /* Badges are positioned against the tab wrapper, which is now full width. */
  .header-right.nav-open .nav-tab-wrapper {
    display: block;
    position: relative;
  }

  .header-right.nav-open .btn-theme {
    display: block;
    border: none;
    background: transparent;
    font-size: var(--app-text-sm);
  }

  /* Account section: a labelled group at the foot of the panel rather than a
     nested dropdown, which on a touch screen is a trap. */
  .header-right.nav-open .user-menu-wrap {
    display: flex;
    flex-direction: column;
    width: 100%;
    border-top: 1px solid var(--p-content-border-color);
    margin-top: var(--app-space-4);
    padding-top: var(--app-space-4);
  }

  .header-right.nav-open .user-info {
    pointer-events: none;
    background: transparent;
    padding: var(--app-space-4) var(--app-space-12);
    color: var(--p-text-muted-color);
    font-size: var(--app-text-xs);
    min-width: 0;
  }

  /* A long username has to ellipsis rather than widen the panel. */
  .header-right.nav-open #username-display {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .header-right.nav-open .user-menu-caret {
    display: none;
  }

  /* Beats .hidden — both carry !important, so specificity decides, and this is
     three classes to its one. The panel owns visibility here, not the trigger. */
  .header-right.nav-open .user-menu {
    display: flex !important;
    position: static;
    min-width: 0;
    padding: 0;
    background: transparent;
    border: none;
    box-shadow: none;
  }

  /* A count sits beside its own label here: pinned to the corner, it
     floated up against the row above. */
  .header-right.nav-open .nav-tab .alert-badge {
    position: static;
    display: inline-flex;
    margin-left: var(--app-space-8);
    vertical-align: middle;
  }

  /* The bar paints its tabs and buttons white on navy, and the panel is a
     light sheet inside the bar, so in light mode every tab but the active
     one was white on white. */
  body:not(.dark) .header-right.nav-open .nav-tab,
  body:not(.dark) .header-right.nav-open .btn-theme,
  body:not(.dark) .header-right.nav-open .user-info {
    color: var(--p-text-color);
  }

  body:not(.dark) .header-right.nav-open .nav-tab:hover {
    background: var(--p-selection-background);
    color: var(--p-text-color);
  }

  body:not(.dark) .header-right.nav-open .nav-tab.active {
    background: var(--app-attention-color);
    color: var(--p-primary-contrast-color);
  }

  /* The strip wraps: the heading and its close on one line, then what is
     wrong, then the button. In one row the list was squeezed to a word a
     line under the button. */
  .health-notice {
    flex-wrap: wrap;
    gap: var(--app-space-8);
    padding: var(--app-space-8) var(--app-space-16);
  }

  .health-notice-head {
    flex: 1 1 100%;
    justify-content: space-between;
  }

  .health-notice-head strong {
    white-space: normal;
  }

  .health-notice ul {
    flex: 1 1 100%;
  }

  /* Edge to edge on a phone — a gutter here only narrows the reading column
     without the ground being visible enough to earn it. */
  main {
    padding: 0;
  }

  /* The card meets the bottom and side edges, so only the top corners are a
     real corner. Squaring the bottom stops the ground showing through in two
     small wedges under the composer. */
  .chat-layout {
    border-radius: var(--app-radius-card) var(--app-radius-card) 0 0;
  }

  .chat-container {
    min-height: 60vh;
  }

  .message {
    max-width: 95%;
  }

  .input-area {
    padding: var(--app-space-8);
    gap: var(--app-space-8);
  }

  .admin-container {
    overflow-x: auto;
  }

  .users-table {
    font-size: var(--app-text-xs);
  }

  .modal-content {
    margin: var(--app-space-8);
    max-height: 90vh;
    overflow-y: auto;
  }

  /* One half of the chat screen at a time: the list, or a conversation over it. */
  .sidebar {
    width: 100%;
    border-right: none;
  }

  /* A row is a touch target here, so it gets a finger's height. */
  .sidebar-item {
    padding-block: var(--app-space-12);
  }

  .chat-layout.chat-open .sidebar,
  .chat-layout:not(.chat-open) .chat-container {
    display: none;
  }

  /* Nothing to drag against when the list is the whole screen. */
  .sidebar-resizer {
    display: none;
  }

}

.hidden {
  display: none !important;
}

/* ─── Ported from main ──────────────────────────────────────────────────────
   Components that landed on main while this branch was open. They were written
   against older variables inside the inline <style> this branch
   removed, so they are re-expressed here against tokens rather than merged.

   Several referenced variables that were never defined anywhere (gray-500,
   gray-700, radius-full, font-medium) and so silently fell back to inherit or
   nothing; those get real values here. */

/* Chat toolbar — repeats the PDF/share actions above the transcript, because on
   a long answer the pair beside the composer is a full scroll away. */
.chat-toolbar {
  display: flex;
  align-items: center;
  gap: var(--app-space-8);
  padding: var(--app-space-8) var(--chat-gutter);
  border-bottom: 1px solid var(--p-content-border-color);
  flex-shrink: 0;
}

/* Empty until a conversation exists, and the way back is a phone's alone. */
.chat-toolbar.is-empty,
.chat-toolbar.is-empty > .input-btn:not(.chat-back),
.chat-back {
  display: none;
}

.chat-back {
  font-size: var(--app-text-xl);
}

/* On a phone the way back shows before there is anything to export. After
   the rules above, since a media block earlier in the file loses to them. */
@media (max-width: 768px) {
  .chat-toolbar {
    padding-inline: var(--app-space-8);
  }

  .chat-toolbar.is-empty,
  .chat-back {
    display: flex;
  }

  /* The bar is the frame, so its buttons carry no outline. */
  .chat-toolbar .input-btn {
    border-color: transparent;
  }
}

/* The source a chat is about, beside its title and on its History row. */
.chat-toolbar-about,
.sidebar-source {
  flex-shrink: 0;
  font-size: var(--app-text-2xs);
  color: var(--p-text-muted-color);
  border: 1px solid var(--p-content-border-color);
  padding: 0 var(--app-space-4);
  white-space: nowrap;
  max-width: 12em;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-toolbar-title {
  flex: 1;
  min-width: 0;
  font-size: var(--app-text-sm);
  color: var(--p-text-muted-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Form help text under an input. */
.field-hint {
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  margin: var(--app-space-4) 0 0;
  line-height: var(--app-leading-normal);
}

.field-hint code {
  background: var(--p-surface-200);
  padding: 0 var(--app-space-4);
  border-radius: var(--p-border-radius-sm);
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
}

body.dark .field-hint code {
  background: var(--p-surface-800);
}

/* Indexing-filter preview (tenant admin: what a folder rule would exclude). */
.filter-preview {
  margin: var(--app-space-12) 0 var(--app-space-4);
  padding: var(--app-space-12);
  background: var(--p-surface-200);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-lg);
  font-size: var(--app-text-sm);
}

body.dark .filter-preview {
  background: var(--p-surface-950);
}

.filter-preview.hidden {
  display: none;
}

.filter-count {
  color: var(--p-text-color);
  margin-bottom: var(--app-space-4);
}

.filter-warn {
  color: var(--p-warning-color);
  font-weight: var(--app-font-medium);
  margin-bottom: var(--app-space-4);
}

.filter-samples {
  list-style: none;
  margin: var(--app-space-4) 0 0;
  padding: 0;
  max-height: 11rem;
  overflow-y: auto;
}

.filter-samples li {
  padding: var(--app-space-4) 0;
  border-top: 1px solid var(--p-content-border-color);
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
}

.filter-sample-from {
  color: var(--p-text-color);
  margin-right: var(--app-space-4);
}

.filter-sample-date {
  color: var(--p-text-muted-color);
  margin-left: var(--app-space-4);
}

/* Deactivated users in the admin table. */
.inactive-tag {
  display: inline-block;
  margin-left: var(--app-space-8);
  padding: 0 var(--app-space-8);
  border-radius: var(--app-radius-pill);
  background: var(--p-surface-300);
  color: var(--p-surface-800);
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-medium);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

body.dark .inactive-tag {
  background: var(--p-surface-700);
  color: var(--p-surface-100);
}

.user-inactive td {
  opacity: 0.55;
}

/* ---------------------------------------------------------------------------
   Mailbox page

   Two columns: what changes on the left (calendar, findings, chat), what she
   simply is on the right (particulars). Reference data does not deserve the
   reading position. Collapses to one column below 900px, particulars first,
   because on a phone the identity check is what you came for.
   --------------------------------------------------------------------------- */

.source-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--app-space-24);
  align-items: start;
}

@media (max-width: 900px) {
  .source-layout { grid-template-columns: minmax(0, 1fr); }
  .source-aside { order: -1; }
}

.source-picker {
  display: flex;
  align-items: center;
  gap: var(--app-space-12);
  flex-wrap: wrap;
  margin-bottom: var(--app-space-20);
}

.source-picker input {
  flex: 1 1 260px;
  min-width: 0;
}

/* A count in a row of controls sits on the row's middle line: its own
   bottom margin lifted it six pixels above the buttons beside it. */
.source-picker .source-hint { margin: 0; }

.source-card {
  background: var(--p-surface-0);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-card);
  padding: var(--app-space-16);
  margin-bottom: var(--app-space-16);
}

body.dark .source-card { background: var(--p-surface-800); }

.source-card h3 {
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-muted-color);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin: 0 0 var(--app-space-12);
}

.source-facts { width: 100%; border-collapse: collapse; }

.source-facts th,
.source-facts td {
  text-align: left;
  padding: var(--app-space-4) 0;
  font-size: var(--app-text-sm);
  vertical-align: top;
}

.source-facts th {
  color: var(--p-text-muted-color);
  font-weight: var(--app-font-regular);
  padding-right: var(--app-space-12);
  white-space: nowrap;
}

.source-facts td { color: var(--p-text-color); font-weight: var(--app-font-medium); }

/* One row per entry, grouped under its month. A grid rather than a month
   grid on purpose: a source's year is sparse, and empty squares for the 340
   days when nothing happens tell the user nothing. */
.cal-month {
  font-size: var(--app-text-xs);
  font-weight: var(--app-font-semibold);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--p-text-muted-color);
  margin: var(--app-space-16) 0 var(--app-space-8);
  padding-bottom: var(--app-space-4);
  border-bottom: 1px solid var(--p-content-border-color);
}

.cal-month:first-child { margin-top: 0; }

.cal-entry {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: var(--app-space-12);
  padding: var(--app-space-8) 0;
  border-bottom: 1px solid var(--p-surface-100);
}

.cal-entry:last-child { border-bottom: none; }

.cal-date {
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
  white-space: nowrap;
}

.cal-title { font-size: var(--app-text-sm); color: var(--p-text-color); }
.cal-detail { font-size: var(--app-text-xs); color: var(--p-text-muted-color); margin-top: 2px; }

/* An overdue obligation is the one thing on this page that is already a
   problem, so it is the only thing allowed to use the danger colour. */
.cal-entry.is-past .cal-date { color: var(--p-danger-color); }

/* The list runs from the recent past into next year, so it needs to say where
   "now" falls as plainly as the grid does. */
.cal-entry.is-today { background: var(--p-brand-aqua-50); }
body.dark .cal-entry.is-today { background: var(--p-brand-aqua-950); }

.cal-entry.is-today .cal-date {
  color: var(--p-primary-color);
  font-weight: var(--app-font-bold);
}

.cal-today-rule {
  display: flex;
  align-items: center;
  gap: var(--app-space-8);
  margin: var(--app-space-12) 0;
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-semibold);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--p-primary-color);
}

.cal-today-rule::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--p-primary-color);
}

.cal-tag {
  display: inline-block;
  font-size: var(--app-text-2xs);
  padding: 1px 6px;
  border-radius: var(--app-radius-pill);
  margin-left: var(--app-space-8);
  vertical-align: 1px;
  border: 1px solid transparent;
}

/* A register date is a fact; an extracted one is a reading of someone's
   prose. They must never look alike, or the guess borrows the fact's
   authority. */
.cal-tag.from-register {
  background: var(--p-surface-100);
  color: var(--p-text-muted-color);
}

body.dark .cal-tag.from-register { background: var(--p-surface-700); }

.cal-tag.from-mail {
  background: transparent;
  border-color: var(--p-warning-color);
  color: var(--p-warning-color);
}

/* A date written in the item itself: found by a rule, no reading involved.
   Quieter than both the register and the model's readings. */
.cal-tag.from-text {
  background: transparent;
  border-color: var(--p-surface-400);
  color: var(--p-text-muted-color);
}

.cal-entry.is-stated .cal-title { color: var(--p-text-muted-color); }

.cal-chip.from-text {
  background: var(--p-surface-100);
  color: var(--p-text-muted-color);
  border: 1px dashed var(--p-surface-400);
}

body.dark .cal-chip.from-text { background: var(--p-surface-800); }

.cal-legend {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  margin-bottom: var(--app-space-8);
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-4) var(--app-space-12);
  align-items: center;
}
.cal-legend .cal-tag { margin-left: 0; }

.source-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--app-space-12);
  margin-bottom: var(--app-space-8);
  flex-wrap: wrap;
}

.source-section-head h3 { margin: 0; font-size: var(--app-text-lg); }

.source-hint {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  margin: 0 0 var(--app-space-12);
}

.source-empty {
  font-size: var(--app-text-sm);
  color: var(--p-text-muted-color);
  padding: var(--app-space-16) 0;
}

.source-chat-log {
  max-height: 420px;
  overflow-y: auto;
  margin-bottom: var(--app-space-12);
}

/* A source name in the admin list is a way into its source page. Styled as a
   link rather than left as bold text, or nobody discovers it is clickable. */
.source-open-link {
  color: var(--p-primary-color);
  font-weight: var(--app-font-semibold);
  text-decoration: none;
}

.source-open-link:hover { text-decoration: underline; }

/* Mailbox selector. Hand-built rather than a <datalist>: Firefox filters those
   on the option label, which held the address, so typing a source's name matched
   nothing. Chrome filters on the value and looked correct. */
.source-combo {
  position: relative;
  flex: 1 1 260px;
  min-width: 0;
}

.source-combo .form-input { width: 100%; }

.source-options {
  position: absolute;
  z-index: 30;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 320px;
  overflow-y: auto;
  margin: 0;
  padding: var(--app-space-4);
  list-style: none;
  background: var(--p-surface-0);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-card);
  box-shadow: var(--p-shadow-lg);
}

.source-option {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--app-space-12);
  padding: var(--app-space-8) var(--app-space-12);
  border-radius: var(--p-border-radius-sm);
  font-size: var(--app-text-sm);
  cursor: pointer;
}

.source-option:hover,
.source-option.is-active {
  background: var(--p-surface-100);
}

body.dark .source-options { background: var(--p-overlay-background); border-color: var(--p-overlay-border-color); }
body.dark .source-option:hover,
body.dark .source-option.is-active { background: var(--p-surface-700); }

.source-option-address {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  white-space: nowrap;
}

.source-option.is-empty {
  color: var(--p-text-muted-color);
  cursor: default;
}

.source-option.is-empty:hover { background: transparent; }

/* Leaving a source page returns to the list it was opened from. */
.btn-back {
  background: none;
  border: none;
  padding: 0;
  margin-bottom: var(--app-space-16);
  color: var(--p-primary-color);
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-medium);
  cursor: pointer;
}

.btn-back:hover { text-decoration: underline; }

/* Opt a note out of the 60ch measure. The class was already on three of them
   in the markup but had never been defined, so they kept wrapping at 60ch and
   looked narrower than the form beneath them. */
.full-width {
  max-width: none;
}

/* ---- Calendar: list / month switch ---------------------------------- */

.cal-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--app-space-12);
  flex-wrap: wrap;
  margin-bottom: var(--app-space-12);
}

.cal-views { display: flex; gap: var(--app-space-2); }

.cal-view-btn {
  background: none;
  border: 1px solid var(--p-content-border-color);
  color: var(--p-text-muted-color);
  padding: var(--app-space-4) var(--app-space-12);
  font-size: var(--app-text-sm);
  cursor: pointer;
}

.cal-view-btn:first-child {
  border-radius: var(--p-border-radius-sm) 0 0 var(--p-border-radius-sm);
}

.cal-view-btn:last-child {
  border-radius: 0 var(--p-border-radius-sm) var(--p-border-radius-sm) 0;
  border-left: none;
}

.cal-view-btn.is-on {
  background: var(--p-primary-color);
  border-color: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
}

.cal-stepper { display: flex; align-items: center; gap: var(--app-space-8); }

.cal-stepper-label {
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  min-width: 11ch;
  text-align: center;
}

.cal-step {
  background: none;
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-sm);
  color: var(--p-text-color);
  cursor: pointer;
  font-size: var(--app-text-lg);
  line-height: 1;
  padding: 0 var(--app-space-8);
}

.cal-step:hover { background: var(--p-surface-100); }

.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--p-content-border-color);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-card);
  overflow: hidden;
}

.cal-dow {
  background: var(--p-surface-100);
  color: var(--p-text-muted-color);
  font-size: var(--app-text-2xs);
  font-weight: var(--app-font-semibold);
  text-transform: uppercase;
  letter-spacing: .06em;
  padding: var(--app-space-4) var(--app-space-8);
}

.cal-cell {
  background: var(--p-surface-0);
  min-height: 92px;
  padding: var(--app-space-4);
}

.cal-cell.is-blank { background: var(--p-surface-50); }
.cal-cell.is-weekend { background: var(--p-surface-50); }

/* The low end of the surface ramp is near-white in BOTH schemes, so every
   light surface above needs a dark counterpart or the whole grid renders as
   a white slab on the dark page. The is-today override below was already
   dark, which is what gave the miss away. Cells sit at content background,
   the ones that recede go under it, and the header rises above. */
body.dark .cal-dow { background: var(--p-surface-800); }
body.dark .cal-cell { background: var(--p-surface-900); }
body.dark .cal-cell.is-blank,
body.dark .cal-cell.is-weekend { background: var(--p-surface-950); }
body.dark .cal-step:hover { background: var(--p-surface-700); }

/* Today needs to be findable at a glance, which a 2px rule was not. The cell
   gets a tint and the date itself becomes a filled marker. Both are drawn in
   the brand aqua, well away from the red an overdue item uses, so a day that
   is both still reads correctly. */
.cal-cell.is-today {
  background: var(--p-brand-aqua-50);
  box-shadow: inset 0 0 0 2px var(--p-primary-color);
}

body.dark .cal-cell.is-today { background: var(--p-brand-aqua-950); }

.cal-cell-day {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  margin-bottom: 2px;
}

.cal-cell.is-today .cal-cell-day {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: var(--app-radius-pill);
  background: var(--p-primary-color);
  color: var(--p-primary-contrast-color);
  font-weight: var(--app-font-semibold);
}

.cal-chip {
  font-size: var(--app-text-2xs);
  line-height: var(--app-leading-tight);
  padding: 2px 4px;
  margin-bottom: 2px;
  border-radius: var(--p-border-radius-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

/* Same distinction the list makes: a register date is a fact, a date read out
   of prose is a reading of one. */
.cal-chip.from-register {
  background: var(--p-surface-200);
  color: var(--p-text-color);
}

/* surface.200 against text-color is 1.3:1 in dark: a chip you cannot read. */
body.dark .cal-chip.from-register { background: var(--p-surface-700); }

.cal-chip.from-mail {
  background: transparent;
  border: 1px solid var(--p-warning-color);
  color: var(--p-warning-color);
}

.cal-chip:hover { text-decoration: underline; }

@media (max-width: 700px) {
  .cal-cell { min-height: 64px; }
  .cal-chip { font-size: 9px; }
}

/* ---- Guided tour ---------------------------------------------------- */

/* Below the dialogs, not above them. At 3000 over a modal's 1000 a tour
   left open covered every dialog: it looked normal and took no clicks,
   and only a reload cleared it. The tour rings page furniture, which
   carries no stacking of its own, so it needs nothing above the dialogs. */
.tour-overlay {
  position: fixed;
  inset: 0;
  z-index: 900;
}

/* The dim is painted by the ring's own outer shadow, so the highlighted
   element stays fully lit and clickable-looking without cloning it. */
.tour-ring {
  position: fixed;
  border-radius: var(--p-border-radius-md);
  box-shadow: 0 0 0 9999px rgba(2, 64, 90, 0.55),  /* allow-hex: scrim over an arbitrary page */
              0 0 0 2px var(--p-primary-color);
  transition: top var(--app-duration-base) var(--app-ease-standard),
              left var(--app-duration-base) var(--app-ease-standard),
              width var(--app-duration-base) var(--app-ease-standard),
              height var(--app-duration-base) var(--app-ease-standard);
  pointer-events: none;
}

/* With no element to ring, the scrim has to come from the overlay itself. */
.tour-overlay:has(.tour-ring[style*="display: none"]) {
  background: rgba(2, 64, 90, 0.55);  /* allow-hex: same scrim, no cut-out */
}

.tour-card {
  position: fixed;
  width: 340px;
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  background: var(--p-content-background);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-card);
  box-shadow: var(--p-shadow-xl);
  padding: var(--app-space-20);
}

.tour-card h3 {
  margin: 0 0 var(--app-space-8);
  font-size: var(--app-text-lg);
  color: var(--p-text-color);
}

.tour-card p {
  margin: 0 0 var(--app-space-16);
  font-size: var(--app-text-sm);
  line-height: var(--app-leading-relaxed);
  color: var(--p-text-muted-color);
}

.tour-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--app-space-12);
}

.tour-count {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
}

.tour-buttons { display: flex; gap: var(--app-space-8); }

.btn-tour-skip,
.btn-tour-back {
  background: none;
  border: none;
  color: var(--p-text-muted-color);
  font-size: var(--app-text-sm);
  cursor: pointer;
  padding: var(--app-space-4) var(--app-space-8);
}

.btn-tour-skip:hover,
.btn-tour-back:hover { color: var(--p-text-color); }

.btn-tour-next {
  padding: var(--app-space-4) var(--app-space-16);
  font-size: var(--app-text-sm);
}

/* ---- User guide ----------------------------------------------------- */

.guide-modal-content {
  max-width: 760px;
  width: calc(100vw - 32px);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
}

.guide-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--app-space-12);
}

.guide-head h3 { margin: 0; }

#guide-body {
  overflow-y: auto;
  margin: var(--app-space-16) 0;
  padding-right: var(--app-space-8);
}

.guide-section { margin-bottom: var(--app-space-32); }

.guide-section h3 {
  margin: 0 0 var(--app-space-4);
  font-size: var(--app-text-lg);
  color: var(--p-primary-color);
}

.guide-intro {
  margin: 0 0 var(--app-space-12);
  font-size: var(--app-text-sm);
  color: var(--p-text-muted-color);
  line-height: var(--app-leading-relaxed);
}

.guide-list { margin: 0; }

.guide-list dt {
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
  margin-top: var(--app-space-12);
}

/* Where to find it matters as much as what it is: the commonest failure is
   knowing a feature exists and not knowing which screen holds it. */
.guide-where {
  font-weight: var(--app-font-regular);
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  background: var(--p-surface-100);
  border-radius: var(--app-radius-pill);
  padding: 1px 8px;
  margin-left: var(--app-space-4);
  white-space: nowrap;
}

.guide-list dd {
  margin: 2px 0 0;
  font-size: var(--app-text-sm);
  color: var(--p-text-muted-color);
  line-height: var(--app-leading-relaxed);
}

.guide-cats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-4);
  margin-top: var(--app-space-16);
}

.guide-cat {
  font-size: var(--app-text-xs);
  background: var(--p-surface-100);
  border-radius: var(--app-radius-pill);
  padding: 2px 10px;
  color: var(--p-text-muted-color);
}

body.dark .guide-where,
body.dark .guide-cat { background: var(--p-surface-800); }

.guide-cat b { color: var(--p-text-color); margin-left: 4px; }

.guide-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--app-space-8);
  border-top: 1px solid var(--p-content-border-color);
  padding-top: var(--app-space-16);
}

/* ---- Data sources --------------------------------------------------- */

.connector-props {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  max-width: 340px;
  overflow-wrap: anywhere;
}

.connector-props em { color: var(--p-text-color); font-style: normal; }

/* The test result is the gate on Save, so it has to read as a verdict
   rather than as another line of help text. */
.connector-test {
  font-size: var(--app-text-sm);
  min-height: 1.4em;
  margin: var(--app-space-8) 0;
}

.connector-test.is-ok { color: var(--p-success-color); }
.connector-test.is-bad { color: var(--p-danger-color); }

.muted { color: var(--p-text-muted-color); }
.opt { color: var(--p-text-muted-color); font-weight: var(--app-font-regular); }

/* A failing feed has to be visible at a glance in the list; the message
   itself sits in the tooltip so the column stays narrow. */
.src-bad { color: var(--p-danger-color); font-weight: var(--app-font-semibold); }
.src-ok { color: var(--p-text-muted-color); font-size: var(--app-text-xs); }

/* ---- Feed health ----------------------------------------------------- */

/* A dot rather than a count: the number of broken feeds is not the point,
   the fact that one is broken is. Amber for overdue, red for stopped. */
.health-dot {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 9px;
  height: 9px;
  border-radius: var(--app-radius-pill);
  background: var(--p-warning-color);
  border: 2px solid var(--p-content-background);
  box-sizing: content-box;
}

.health-dot.is-error { background: var(--p-danger-color); }

/* Feed health: a strip between the bar and the page. It takes its own
   row, so it never covers a button or a menu; the detail is on hover and
   the whole story is under Admin. */
.health-notice {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--app-space-16);
  padding: var(--app-space-8) var(--app-space-24);
  background: var(--app-attention-soft);
  border-bottom: 2px solid var(--app-attention-color);
  font-size: var(--app-text-sm);
}

.health-notice.hidden { display: none; }

.health-notice-head { display: flex; align-items: center; gap: var(--app-space-8); }
.health-notice-head strong { white-space: nowrap; }

.health-notice-close {
  background: none;
  border: none;
  font-size: var(--app-text-lg);
  cursor: pointer;
  color: var(--p-text-muted-color);
  order: 3;
  margin-left: var(--app-space-8);
}

.health-notice ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-4) var(--app-space-16);
  margin: 0;
  padding: 0;
  flex: 1;
  min-width: 0;
}

.health-notice li { color: var(--p-text-color); cursor: help; }
.health-notice li strong { font-weight: var(--app-font-medium); }

.health-notice-actions { display: flex; }
.health-notice-actions .btn-primary { padding: var(--app-space-4) var(--app-space-12); font-size: var(--app-text-sm); }

/* ---- Source setup guidance ------------------------------------------ */

/* Collapsed by default: an admin adding their fifth source should not have
   to scroll past it, and one adding their first has to be able to find it. */
.connector-setup {
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-md);
  background: var(--p-surface-50);
  padding: var(--app-space-8) var(--app-space-12);
  margin-bottom: var(--app-space-16);
}

body.dark .connector-setup { background: var(--p-surface-800); }

.connector-setup > summary {
  cursor: pointer;
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
  list-style-position: inside;
}

.connector-setup[open] > summary { margin-bottom: var(--app-space-8); }

.connector-setup ol {
  margin: 0;
  /* The reset clears list styling globally, and these are a sequence: the
     numbers are how an admin keeps their place while switching to Entra and
     back. */
  list-style: decimal outside;
  padding-left: var(--app-space-20);
  font-size: var(--app-text-sm);
  color: var(--p-text-muted-color);
  line-height: var(--app-leading-relaxed);
}

.connector-setup li { margin-bottom: var(--app-space-4); }

.connector-setup a {
  display: inline-block;
  margin-top: var(--app-space-8);
  font-size: var(--app-text-xs);
  color: var(--p-primary-color);
}

/* The explanation behind the dot, on the page rather than in a tooltip. */
.health-panel {
  border: 1px solid var(--p-content-border-color);
  border-left: 3px solid var(--p-warning-color);
  border-radius: var(--app-radius-card);
  background: var(--p-surface-50);
  padding: var(--app-space-16) var(--app-space-20);
  margin-bottom: var(--app-space-24);
}

body.dark .health-panel { background: var(--p-surface-800); }

.health-panel.is-error { border-left-color: var(--p-danger-color); }
/* A note, not a fault: a source nothing feeds any more is history,
   and a red bar every morning teaches the reader to skip the panel. */
.health-panel.is-note { border-left-color: var(--p-content-border-color); }

.health-panel h3 {
  margin: 0 0 var(--app-space-8);
  font-size: var(--app-text-base);
  color: var(--p-text-color);
}

.health-issue { margin-bottom: var(--app-space-8); font-size: var(--app-text-sm); }
.health-issue:last-child { margin-bottom: 0; }
.health-issue b { display: block; color: var(--p-text-color); }
.health-issue span { color: var(--p-text-muted-color); line-height: var(--app-leading-relaxed); }

/* The brief itself, on the screen where you edit how it reads. Collapsed by
   default: an admin who came to change one line should not have to scroll
   past yesterday's whole brief to reach the box. */
.brief-latest {
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-md);
  background: var(--p-surface-50);
  padding: var(--app-space-8) var(--app-space-12);
  margin-bottom: var(--app-space-16);
  max-width: 56rem;
}

.brief-latest > summary {
  cursor: pointer;
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
  list-style-position: inside;
}

/* surface.50 is near-white in BOTH schemes, so a panel that uses it needs a
   dark step here or it lands white-on-white: summary text is text-color
   (#ebf0f2 dark), which against #f7f8f8 is a 1.1:1 contrast. Raised panels
   step to surface.800, same as .message.assistant. */
body.dark .brief-latest { background: var(--p-surface-800); }

.brief-latest[open] > summary { margin-bottom: var(--app-space-12); }

/* Shared by the stored brief and the preview, so what you are shown before
   saving is laid out the same as what went out. */
.brief-body {
  max-width: 56rem;
  margin-bottom: var(--app-space-16);
  font-size: var(--app-text-sm);
  /* text, not text-muted: the brief is the content here, not a caption.
     Muted lands at 3.35:1 on this panel in light mode, under the 4.5:1 the
     project requires for body text. */
  color: var(--p-text-color);
  line-height: var(--app-leading-relaxed);
}

.brief-body h2,
.brief-body h3 {
  font-size: var(--app-text-base);
  color: var(--p-text-color);
  margin: var(--app-space-16) 0 var(--app-space-4);
}

.brief-body ul { list-style: disc outside; padding-left: var(--app-space-20); }
.brief-body li { margin-bottom: var(--app-space-4); }
.brief-body a { color: var(--p-primary-color); }

/* The composed instruction, shown verbatim. Pre-wrap rather than a scrolling
   line: an editor reading what the brief is told to do should not have to
   drag a horizontal bar to reach the end of a rule. Capped in height so it
   cannot push the box it is meant to inform off the screen. */
.brief-prompt-text {
  margin: 0;
  max-height: 22rem;
  overflow-y: auto;
  padding: var(--app-space-12);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-md);
  background: var(--p-form-field-background);
  color: var(--p-text-color);
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  font-size: var(--app-text-xs);
  line-height: var(--app-leading-relaxed);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

#brief-prompt-note { margin-bottom: var(--app-space-8); }

/* The prompt is edited as text, so it gets a text editor's affordances:
   monospace so the bullet structure lines up, and tall enough to see a whole
   rule without scrolling mid-sentence. */
.brief-prompt-input {
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  font-size: var(--app-text-xs);
  line-height: var(--app-leading-relaxed);
  min-height: 18rem;
  resize: vertical;
}

/* Brief folds: sections collapse to their heading, hyperlist style */
.brief-fold {
  margin: var(--app-space-1) 0;
}
.brief-fold summary {
  cursor: pointer;
  color: var(--p-primary-color);
  font-weight: var(--app-font-semibold);
  padding: var(--app-space-1) 0;
}
.brief-fold summary:hover {
  color: var(--p-primary-hover-color);
}

/* Swap the brief between its layouts, one button for each other one.
   They sit under the brief they belong to, so a scrolled-back brief
   keeps its own control. */
.brief-layout-btn {
  display: block;
  margin-top: var(--app-space-4);
  padding: var(--app-space-2) var(--app-space-4);
  font-size: var(--app-text-sm);
}

/* Organisation switcher inside the user menu. Links, not buttons: each organisation is
   its own instance on its own host, so this is navigation. */
.user-menu-label {
  padding: 0 var(--app-space-12) var(--app-space-2);
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
#org-switch-list {
  display: flex;
  flex-direction: column;
  gap: var(--app-space-2);
}
.org-switch-item {
  display: block;
  border-radius: var(--p-border-radius-md);
  padding: var(--app-space-8) var(--app-space-12);
  color: var(--p-text-color);
  font-size: var(--app-text-sm);
  text-decoration: none;
  white-space: nowrap;
}
.org-switch-item:hover,
.org-switch-item:focus-visible {
  background: var(--p-selection-background);
  outline: none;
}
.user-menu-sep {
  margin: var(--app-space-2) 0;
  border: none;
  border-top: 1px solid var(--p-content-border-color);
}

/* Which organisation this instance serves. Sits left of the user's name, quieter
   than the role badge: it is orientation, not status. */
.org-chip {
  padding: var(--app-space-2) var(--app-space-8);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-md);
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  white-space: nowrap;
}

.item-attach-note {
  margin-top: var(--app-space-2);
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
}

/* Original attachment files, fetched on request from the archive. */
.link-button {
  appearance: none;
  background: transparent;
  border: none;
  padding: 0;
  color: var(--app-link-color);
  font-size: var(--app-text-sm);
  text-decoration: underline;
  cursor: pointer;
}
.attach-link {
  display: block;
  padding: var(--app-space-2) 0;
  color: var(--app-link-color);
  font-size: var(--app-text-sm);
}

/* The backlog is five tables, so it needs more width than the guide's
   prose. Each table still scrolls inside its own wrapper on a phone. */
.backlog-modal-content {
  max-width: 1040px;
}
.backlog-modal-content .md-table {
  font-size: var(--app-text-sm);
}
/* The list is long enough to run off the screen, and the shell's
   max-height only helps if the body inside it scrolls. Without this the
   delivered table ran past the bottom of the window with no way down.
   `min-height: 0` is the flexbox part: a flex child will not shrink below
   its content otherwise, so overflow never engages. */
#backlog-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  margin: var(--app-space-16) 0 0;
  padding-right: var(--app-space-8);
}

/* ─── Organisation at a glance ──────────────────────────────────────────────────
   The board-level rough cut above the source list. Cards rather than a table:
   the point is one number per question, read across a room from a shared
   screen, so each figure gets its own tile and its own comparison. */
.overview-summary {
  margin-bottom: var(--app-space-24);
}

.overview-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--app-space-12);
  flex-wrap: wrap;
}

.overview-head h2 {
  margin: 0;
  font-size: var(--app-text-lg);
  color: var(--p-text-color);
}

.overview-period {
  display: flex;
}

.overview-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--app-space-12);
  margin: var(--app-space-16) 0;
}

.overview-card {
  background: var(--p-surface-0);
  border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-card);
  padding: var(--app-space-16);
}

body.dark .overview-card { background: var(--p-surface-800); }

.overview-card-label {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.overview-card-value {
  font-size: var(--app-text-3xl);
  font-weight: var(--app-font-semibold);
  color: var(--p-primary-color);
  line-height: 1.2;
  margin: var(--app-space-4) 0;
}

.overview-card-sub {
  font-size: var(--app-text-xs);
  color: var(--p-text-muted-color);
}

.overview-sub {
  margin: 0 0 var(--app-space-8);
  font-size: var(--app-text-base);
  color: var(--p-text-color);
}

.overview-list {
  margin: 0 0 var(--app-space-16);
  padding-left: var(--app-space-20);
  font-size: var(--app-text-sm);
  color: var(--p-text-color);
}

/* A card with something behind it. The cue is the pointer and the hover
   lift; no extra icon, because eight cards with an icon each read as a
   toolbar rather than a set of figures. */
.overview-card.is-open {
  cursor: pointer;
  transition: border-color var(--app-duration-fast) var(--app-ease-standard),
              transform var(--app-duration-fast) var(--app-ease-standard);
}

.overview-card.is-open:hover,
.overview-card.is-open:focus-visible {
  border-color: var(--p-primary-color);
  transform: translateY(-1px);
}

.overview-source-link {
  color: var(--p-primary-color);
  font-weight: var(--app-font-semibold);
  cursor: pointer;
}

.overview-source-link:hover {
  text-decoration: underline;
}

.overview-drill-body {
  overflow-y: auto;
  max-height: 60vh;
}

.overview-drill-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.overview-drill-row {
  display: flex;
  justify-content: space-between;
  gap: var(--app-space-12);
  padding: var(--app-space-8) 0;
  border-bottom: 1px solid var(--p-content-border-color);
  cursor: pointer;
  font-size: var(--app-text-sm);
}

.overview-drill-row:hover .overview-drill-subject {
  color: var(--p-primary-color);
}

.overview-drill-subject {
  color: var(--p-text-color);
}

.overview-drill-meta {
  color: var(--p-text-muted-color);
  font-size: var(--app-text-xs);
  white-space: nowrap;
}


/* ─── Entities: what the rules found in an item ───────────────────────── */

.item-entities {
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-4);
  margin-top: var(--app-space-8);
}
.item-entities.hidden { display: none; }

.entity-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--app-space-4);
  padding: 2px var(--app-space-8);
  border-radius: var(--app-radius-pill);
  border: 1px solid var(--p-content-border-color);
  background: var(--p-surface-100);
  color: var(--p-text-color);
  font-size: var(--app-text-xs);
  font-family: inherit;
  cursor: pointer;
  transition: background var(--app-duration-fast) var(--app-ease-standard);
}
.entity-chip:hover { background: var(--p-surface-200); }
body.dark .entity-chip { background: var(--p-surface-800); }
body.dark .entity-chip:hover { background: var(--p-surface-700); }

.entity-chip .entity-kind {
  font-size: var(--app-text-2xs);
  color: var(--p-text-muted-color);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.entity-chip.chip-reference { border-color: var(--p-primary-color); }
.entity-chip.chip-date { border-color: var(--p-warning-color); }

/* ─── Admin: AI purposes and reference patterns ───────────────────────── */

.admin-subhead {
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-text-color);
  margin: var(--app-space-24) 0 var(--app-space-8);
}

.purpose-list { display: flex; flex-direction: column; gap: var(--app-space-8); }

.purpose-row {
  display: flex;
  align-items: center;
  gap: var(--app-space-12);
  font-size: var(--app-text-sm);
  cursor: pointer;
}
.purpose-row.is-fixed { cursor: default; color: var(--p-text-muted-color); }
.purpose-row .toggle-switch { flex: none; display: inline-block; }

.pattern-row {
  display: flex;
  gap: var(--app-space-8);
  margin-bottom: var(--app-space-8);
  align-items: center;
}
.pattern-row input[data-field="label"] { width: 140px; flex: none; }
.pattern-row .pattern-input { flex: 1; font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace; }

/* The Map: hubs and links, unfolded one hop at a time. */
/* The guide's last line: what this is and which class it stands on. */
.guide-foot { margin-top: var(--app-space-24); font-size: var(--app-text-xs); color: var(--p-text-muted-color); text-align: right; }

/* As of a date: a quiet field beside Catch-up; strong when set. */
.as-of { display: inline-flex; align-items: center; gap: 6px; margin-left: var(--app-space-12); font-size: var(--app-text-xs); color: var(--p-text-muted-color); }
.as-of input { font: inherit; padding: 2px 4px; border: 1px solid var(--p-content-border-color); border-radius: var(--p-border-radius-sm); background: var(--p-form-field-background); color: var(--p-text-color); }
.as-of.is-set { color: var(--app-attention-color); }
.as-of.is-set input { border-color: var(--app-attention-color); }

/* How I found this: folded under the answer, plain words. */
.trail { margin-top: var(--app-space-8); font-size: var(--app-text-xs); color: var(--p-text-muted-color); }
.trail summary { cursor: pointer; list-style: none; }
.trail summary::before { content: '▸ '; }
.trail[open] summary::before { content: '▾ '; }
.trail ul { margin: var(--app-space-4) 0 0 var(--app-space-16); padding: 0; }
.trail-n { opacity: 0.7; }

/* It asks you: one card, one click. */
.ask-card { border-left: 3px solid var(--app-friendly-color); }
.ask-card-label { font-size: var(--app-text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--app-friendly-color); margin-bottom: var(--app-space-4); }
.ask-card-actions { display: flex; gap: var(--app-space-8); margin-top: var(--app-space-8); font-size: var(--app-text-sm); color: var(--p-text-muted-color); }

/* Ask next: a quiet row of chips under an answer. */
.next-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--app-space-8); margin-top: var(--app-space-12); }
.next-chips-label { font-size: var(--app-text-xs); color: var(--p-text-muted-color); text-transform: uppercase; letter-spacing: 0.04em; }
.next-chips .saved-chip { border: 0; font: inherit; font-size: var(--app-text-xs); }
.sidebar-item:focus-visible { outline: 2px solid var(--p-primary-color); outline-offset: -2px; }

/* A screen, like Sources: it takes the height left under the bar. */
.map-screen { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.map-toolbar { display: flex; align-items: center; gap: var(--app-space-16); flex-wrap: wrap; margin-bottom: var(--app-space-8); }
.map-toolbar label { font-size: 0.85rem; color: var(--p-text-muted-color); display: flex; align-items: center; gap: 6px; }
.map-status { font-size: 0.85rem; color: var(--p-text-muted-color); margin-left: auto; }
.map-body { display: grid; grid-template-columns: 1fr 280px; gap: var(--app-space-16); flex: 1; min-height: 0; }
.map-svg { width: 100%; height: 100%; min-height: 50vh; background: var(--p-content-background); border: 1px solid var(--p-content-border-color); border-radius: var(--app-radius-card); }
.map-edge { stroke: var(--p-content-border-color); cursor: pointer; }
.map-edge:hover { stroke: var(--p-primary-color); }
.map-edge.dim { opacity: 0.15; }
.map-node { cursor: pointer; }
.map-node circle { fill: var(--p-primary-color); stroke: var(--p-content-background); stroke-width: 1.5; }
.map-node.reference circle { fill: var(--p-brand-aqua-500); }
.map-node.focus circle { stroke: var(--p-text-color); stroke-width: 3; }
.map-node.dim { opacity: 0.2; }
.map-node text { font-size: 11px; fill: var(--p-text-color); text-anchor: middle; pointer-events: none;
  paint-order: stroke; stroke: var(--p-content-background); stroke-width: 3px; }
/* Hovering lifts the node to the front and grows its label, so a crowded
   corner still reads one name at a time. */
.map-node:hover text { font-size: 16px; font-weight: 600; stroke-width: 5px; }
.map-node:hover circle { stroke: var(--p-text-color); stroke-width: 2.5; }
.map-proof { overflow-y: auto; min-height: 0; max-height: 100%; font-size: 0.9rem; }
.map-proof h4 { margin: 0 0 var(--app-space-8); font-size: 0.95rem; }
.map-proof-list { list-style: none; padding: 0; margin: 0; }
.map-proof-list li { padding: 4px 0; border-bottom: 1px solid var(--p-content-border-color); display: flex; justify-content: space-between; gap: 8px; }
.map-proof-date { color: var(--p-text-muted-color); white-space: nowrap; font-size: 0.8rem; }
@media (max-width: 900px) { .map-body { grid-template-columns: 1fr; } }


/* ─── Paper and ink ──────────────────────────────────────────────────────────
   Headings in the display face, like the product's own pages. */
.header-left h1,
.admin-header h2,
.admin-subhead,
.modal-content > h3,
.login-container h1,
.login-container h2 {
  font-family: var(--app-font-display);
  font-weight: 400;
  letter-spacing: 0;
}

.header-left h1 { font-style: italic; }

/* Something under Admin needs attention: an orange dot on the Admin item,
   the issues as its tooltip. The strip under the bar tells the rest. */
.user-menu .health-dot,
.user-menu .health-dot.is-error {
  position: static;
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-left: var(--app-space-8);
  vertical-align: middle;
  background: var(--app-attention-color);
  border-radius: 50%;
}

.user-menu .health-dot.hidden { display: none; }
.user-menu .notification-badge { margin-left: var(--app-space-4); }

/* The Overview, always at the bottom left. */
.examples-more {
  display: flex;
  align-items: center;
  gap: var(--app-space-16);
}

.btn-overview {
  font: inherit;
  font-size: var(--app-text-sm);
  font-weight: var(--app-font-semibold);
  color: var(--p-primary-contrast-color);
  background: var(--p-primary-color);
  border: 1px solid var(--p-primary-color);
  padding: var(--app-space-4) var(--app-space-12);
  cursor: pointer;
}

.btn-overview:hover { background: var(--p-primary-hover-color); }

/* Hints and a thumbs-up carry the friendly colour. */
.examples li:hover {
  border-color: var(--app-friendly-color);
  background: var(--app-friendly-soft);
}

/* Admin sections fold; only the summary shows until opened. */
details.admin-section { border-top: 1px solid var(--p-content-border-color); }
details.admin-section > summary { list-style: none; cursor: pointer; }
details.admin-section > summary::-webkit-details-marker { display: none; }
details.admin-section > summary .admin-header { margin: 0 !important; padding: var(--app-space-12) 0; border-bottom: none; }
details.admin-section[open] { padding-bottom: var(--app-space-24); }
details.admin-section > summary .admin-header h2::before {
  content: '▸';
  display: inline-block;
  width: 1.1em;
  color: var(--p-text-muted-color);
}
details.admin-section[open] > summary .admin-header h2::before { content: '▾'; }


/* ─── Profile ───────────────────────────────────────────────────────────── */
.user-info .avatar,
.user-info .avatar-initial {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  margin-right: var(--app-space-4);
  vertical-align: middle;
  object-fit: cover;
}

.user-info .avatar-initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--p-text-color);
  color: var(--p-content-background);
  font-size: var(--app-text-xs);
  font-weight: var(--app-font-semibold);
}

.user-info .avatar.hidden,
.user-info .avatar-initial.hidden { display: none; }

.profile-avatar-row {
  display: flex;
  gap: var(--app-space-16);
  align-items: flex-start;
  margin-bottom: var(--app-space-16);
}

.profile-avatar-preview {
  width: 96px;
  height: 96px;
  flex-shrink: 0;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--p-text-color);
  color: var(--p-content-background);
  font-family: var(--app-font-display);
  font-size: var(--app-text-display);
}

.profile-avatar-preview img { width: 100%; height: 100%; object-fit: cover; }

.user-menu .alert-badge {
  position: static;
  display: inline-block;
  margin-left: var(--app-space-8);
  vertical-align: middle;
}

.user-menu .alert-badge.hidden { display: none; }


/* The menu under the name: five groups, every other one on a faint tint. */
.user-menu-group { display: flex; flex-direction: column; padding: var(--app-space-4) 0; }
.user-menu-group > span { display: contents; }
.user-menu-group + .user-menu-group { border-top: 1px solid var(--p-content-border-color); }
.user-menu-group:nth-child(even) { background: color-mix(in srgb, var(--p-text-color) 4%, transparent); }

/* Catch-up sits beside the Overview, quieter. */
.btn-overview.is-quiet {
  color: var(--p-primary-color);
  background: transparent;
  border-color: var(--p-primary-color);
}

.btn-overview.is-quiet:hover { background: color-mix(in srgb, var(--p-primary-color) 10%, transparent); }


/* The history pane is a different sheet from the chat, in both modes. */
.sidebar {
  background: color-mix(in srgb, var(--p-text-color) 5%, var(--p-content-background));
}

/* Light mode: the bar is ink, so it stands apart from the paper the way the
   dark bar does. The menu that drops from it keeps its own colours. */
body:not(.dark) header {
  background: var(--p-brand-blue-500);
  color: #ffffff;
}

body:not(.dark) header .header-left h1,
body:not(.dark) header .user-info,
body:not(.dark) header .btn-theme,
body:not(.dark) header .btn-nav-toggle,
body:not(.dark) header .user-menu-caret {
  color: #ffffff;
}

body:not(.dark) header .nav-tab { color: color-mix(in srgb, #ffffff 88%, transparent); }
body:not(.dark) header .nav-tab:hover { background: color-mix(in srgb, #ffffff 12%, transparent); color: #ffffff; }
body:not(.dark) header .nav-tab.active { background: var(--app-attention-color); color: #ffffff; }
body:not(.dark) header .user-info:hover,
body:not(.dark) header .user-info[aria-expanded='true'] { background: color-mix(in srgb, #ffffff 12%, transparent); }
body:not(.dark) header .org-chip { color: color-mix(in srgb, #ffffff 80%, transparent); border-color: color-mix(in srgb, #ffffff 35%, transparent); }
body:not(.dark) header .avatar-initial { background: #ffffff; color: var(--p-brand-blue-500); }

/* ─── Find as the inbox, and the reply box ─────────────────────────────── */
.nav-tab { position: relative; }
/* The dot is a button: eight pixels to look at, sixteen to press. */
.find-dot { display: inline-block; box-sizing: content-box; width: 8px; height: 8px; padding: 0; border: 4px solid transparent;
            border-radius: 50%; background: var(--p-primary-color); background-clip: padding-box; margin: 0 2px 0 -4px;
            vertical-align: middle; cursor: pointer; }
.find-dot:hover, .find-dot:focus-visible { background-color: var(--app-link-color); outline: none; border-color: var(--p-content-border-color); }
.find-unread { display: flex; align-items: center; gap: 6px; font-size: 0.9rem; color: var(--p-text-muted-color); white-space: nowrap; }
.view-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--app-space-8); margin: var(--app-space-8) 0; }
.view-chip { font: inherit; font-size: var(--app-text-xs); padding: 2px 10px; border: 1px solid var(--p-content-border-color); border-radius: var(--app-radius-pill); background: var(--p-content-background); color: var(--p-text-color); cursor: pointer; }
.view-chip.is-on { border-color: var(--p-primary-color); color: var(--p-primary-color); }

/* The Overview's lists, side by side where there is room. */
.brief-lists {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--app-space-12);
  max-width: 760px;
}
.brief-lists .form-group { margin-bottom: 0; }

/* The prompt library's group tabs: one per group with its count, All in
   front. The row wraps and never scrolls sideways: with overlay
   scrollbars a scrolling row clips the sixth tab with nothing to say
   more exist. */
#library-search { margin-bottom: var(--app-space-8); }
.lib-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--app-space-4);
  margin-bottom: var(--app-space-12);
}
.lib-tab {
  font: inherit;
  font-size: var(--app-text-xs);
  padding: 2px 10px;
  border: 1px solid var(--p-content-border-color);
  border-radius: 0;
  background: var(--p-content-background);
  color: var(--p-text-color);
  cursor: pointer;
}
.lib-tab.is-on { border-color: var(--p-primary-color); color: var(--p-primary-color); }
.lib-tab.is-empty { color: var(--p-text-muted-color); cursor: default; }
.lib-tab-count { color: var(--p-text-muted-color); }
.emoji-strip { display: flex; flex-wrap: wrap; gap: 2px; margin-bottom: var(--app-space-4); }
.emoji-btn { font: inherit; font-size: 1.1rem; background: none; border: 0; cursor: pointer; padding: 2px 4px; border-radius: var(--app-radius-card); }
.emoji-btn:hover { background: var(--p-content-border-color); }
.reply-text { width: 100%; min-height: 12rem; resize: vertical; font: inherit; }
.reply-files { display: flex; flex-wrap: wrap; align-items: center; gap: var(--app-space-8); margin-top: var(--app-space-8); }
.reply-attach { cursor: pointer; }
.reply-file { font-size: var(--app-text-xs); border: 1px solid var(--p-content-border-color); border-radius: var(--app-radius-pill); padding: 2px 8px; }
.reply-status { margin-top: var(--app-space-8); padding: var(--app-space-8) var(--app-space-12); border-left: 3px solid var(--p-content-border-color); font-size: 0.95rem; }
.reply-status.is-ok { border-left-color: var(--app-friendly-color, var(--p-success-color)); }
.reply-status.is-wait { border-left-color: var(--p-warning-color); }
.reply-status.is-fail { border-left-color: var(--p-danger-color); color: var(--p-danger-color); }

/* ─── A thing's page ────────────────────────────────────────────────────── */
.thing-meta { display: flex; align-items: center; gap: var(--app-space-12); margin-top: var(--app-space-4); }
.thing-seen { font-size: var(--app-text-xs); color: var(--p-text-muted-color); }
.thing-body { overflow-y: auto; max-height: 60vh; padding: var(--app-space-4) 0; }
.thing-section { margin-bottom: var(--app-space-16); }
.thing-section h4 { margin: 0 0 var(--app-space-8); font-size: var(--app-text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--p-text-muted-color); }
.thing-story, .thing-list { list-style: none; margin: 0; padding: 0; }
.thing-story li, .thing-list li { padding: 3px 0; border-bottom: 1px solid var(--p-content-border-color); display: flex; gap: var(--app-space-8); align-items: baseline; flex-wrap: wrap; }
.thing-story li:last-child, .thing-list li:last-child { border-bottom: 0; }
.thing-date { font-size: var(--app-text-xs); color: var(--p-text-muted-color); white-space: nowrap; min-width: 5.5rem; }
.thing-who { font-size: var(--app-text-xs); color: var(--p-text-muted-color); }
.thing-chips { display: flex; flex-wrap: wrap; gap: var(--app-space-8); }
.thing-count { font-size: var(--app-text-2xs); color: var(--p-text-muted-color); margin-left: 4px; }
.map-proof-hint { font-size: 0.9rem; color: var(--p-text-muted-color); }
.thing-section h4 .thing-of { text-transform: none; letter-spacing: 0; font-weight: var(--app-font-normal); }

/* Where this question may look: one chip per place the organisation
   answers from, shown only when there is more than one.
   Aligned on the chat gutter like the input above it and the prompts
   below, since a row starting at the container edge under a centred box
   is what made this look bolted on. Pills, and the weight of the "Try
   asking" ones: this is a quiet per-question control, not an action. On
   is the normal state, so an off chip is the one that reads as changed. */
.ask-places {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--app-space-8);
  padding: var(--app-space-8) var(--chat-gutter) 0;
}
.ask-places-label { font-size: var(--app-text-2xs); text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--p-text-muted-color); }
.ask-place {
  font: inherit; font-size: var(--app-text-xs); padding: var(--app-space-4) var(--app-space-12);
  cursor: pointer; border: 1px solid var(--p-content-border-color);
  border-radius: var(--app-radius-pill); background: var(--p-content-background);
  color: var(--p-text-color);
  transition: all var(--app-duration-fast) var(--app-ease-standard);
}
.ask-place:hover { border-color: var(--p-primary-color); }
/* Off reads as struck out and faded, so the changed one is the one that
   catches the eye rather than the three normal ones. */
.ask-place:not(.is-on) {
  color: var(--p-text-muted-color); text-decoration: line-through; opacity: 0.65;
}

/* Pages read from the web, listed apart from the organisation's own
   items. Open by default: a reader has to see that an answer leaned on
   something a stranger published. */
.web-refs .document-list-header { color: var(--app-attention-color); }
.web-refs .doc-meta { word-break: break-all; }

/* An address written in an answer. Shown, never clickable: a link is how
   data walks out, and the answer is written by a model that has just read
   other people's mail. The sources and pages under the answer are the
   links, and the server builds those. */
.bare-url { color: var(--p-text-muted-color); font-size: 0.92em; word-break: break-all; }

/* Picking several conversations to delete. The tick only appears in that
   mode: the list is for opening one, and a box beside every row invites
   the wrong click on the common action. */
.btn-sidebar-select {
  font: inherit; font-size: var(--app-text-xs); padding: 2px 8px; margin-left: auto; margin-right: 6px;
  cursor: pointer; border: 1px solid var(--p-content-border-color);
  border-radius: var(--p-border-radius-sm); background: transparent; color: var(--p-text-muted-color);
}
.sidebar-selection {
  display: flex; align-items: center; gap: 6px; padding: 6px var(--app-space-12);
  font-size: var(--app-text-xs); color: var(--p-text-muted-color);
  border-bottom: 1px solid var(--p-content-border-color);
}
.sidebar-selection span { margin-right: auto; }
.sidebar-item.is-picking { cursor: pointer; }
.sidebar-item.is-picked { background: var(--p-highlight-background); }
.sidebar-tick { margin-right: 8px; flex: none; }

/* A small button beside a row: the arrows that reorder where answers come
   from, and the pair on the picking bar. It had no rule at all, so those
   arrows drew as raw browser buttons. */
.btn-small {
  font: inherit; font-size: var(--app-text-xs); line-height: 1; padding: 3px 7px; cursor: pointer;
  border: 1px solid var(--p-content-border-color); border-radius: var(--p-border-radius-sm);
  background: var(--p-form-field-background); color: var(--p-text-color);
}
.btn-small:hover:not(:disabled) { border-color: var(--app-link-color); color: var(--app-link-color); }
.btn-small:disabled { opacity: 0.4; cursor: default; }
.btn-small.btn-danger { color: var(--p-danger-color); border-color: var(--p-danger-color); }
.btn-small.btn-danger:disabled { color: var(--p-text-muted-color); border-color: var(--p-content-border-color); }

/* Actions answers one question: is there anything for me to do? The
   answer goes first, and the finished work folds away under it. */
.actions-head { margin: 0 0 var(--app-space-12); font-size: var(--app-text-sm); color: var(--p-text-muted-color); }
.actions-head.is-waiting { color: var(--app-attention-color); font-weight: var(--app-font-semibold); }
.actions-settled { margin-top: var(--app-space-16); }
.actions-settled summary {
  cursor: pointer; font-size: var(--app-text-xs); color: var(--p-text-muted-color);
  padding: var(--app-space-4) 0;
}

/* Sign in with a provider: one button per provider under the form. */
.btn-sso {
  display: flex; align-items: center; justify-content: center; gap: var(--app-space-8);
  padding: var(--app-space-12); background: var(--p-content-background);
  border: 1px solid var(--p-content-border-color); border-radius: var(--p-border-radius-md);
  color: var(--p-text-color); text-decoration: none; font-weight: var(--app-font-medium);
  transition: border-color 0.2s;
}
.btn-sso:hover { border-color: var(--p-primary-color); }

/* Where an answer came from, as a mark on the rating row. */
.vendor-mark svg {
  height: 16px;
  width: auto;
  vertical-align: -3px;
}

/* The organisation's own name and mark, when the admin set them. */
.brand-logo {
  height: 22px;
  width: auto;
  flex-shrink: 0;
}

.brand-login {
  margin-bottom: var(--app-space-16);
}

.brand-logo-login,
.brand-logo-preview {
  max-height: 48px;
  max-width: 100%;
  width: auto;
  display: block;
  margin-bottom: var(--app-space-8);
}

.brand-login strong {
  display: block;
  font-size: var(--app-text-lg);
}

/* A secret shown once: a token, the recovery codes. */
.secret-once {
  margin: var(--app-space-8) 0;
  padding: var(--app-space-8);
  border: 1px solid var(--p-content-border-color);
  background: var(--p-surface-200);
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;
  font-size: var(--app-text-xs);
  word-break: break-all;
  white-space: pre-wrap;
}

.secret-once code {
  display: block;
  margin-bottom: var(--app-space-8);
}

/* One area a role may hold: a name and what it covers. */
.role-area {
  display: block;
  margin: var(--app-space-4) 0;
  font-weight: normal;
}

/* The question's length, shown from 80 % of what the server takes. */
.query-count { margin: 0.25rem 0 0; text-align: right; }
.query-count.is-over { color: var(--p-danger-color); }

/* ─── The Agenda ──────────────────────────────────────────────────────────────
   A person's own tasks and events. Each area has one of six colours, --a,
   carried by a dot, a bar or a card's left edge. */
.agenda-c0 { --a: var(--app-friendly-color); }
.agenda-c1 { --a: var(--p-primary-color); }
.agenda-c2 { --a: var(--app-attention-color); }
.agenda-c3 { --a: var(--p-brand-purple-400); }
.agenda-c4 { --a: var(--p-danger-color); }
.agenda-c5 { --a: var(--p-text-muted-color); }
.agenda-none { --a: var(--p-content-border-color); }
.agenda-screen { --agenda-wash: color-mix(in srgb, var(--p-text-color) 4%, transparent);
  --agenda-tint: color-mix(in srgb, var(--p-primary-color) 9%, transparent); }
/* The Agenda's own buttons start bare; the page's btn- buttons keep their look. */
:where(.agenda-screen button:not([class*="btn-"])) { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.agenda-top { display: flex; align-items: baseline; gap: var(--app-space-12); flex-wrap: wrap; }
.agenda-top h2 { margin: 0; font-family: var(--app-font-display); }
.agenda-date { color: var(--p-text-muted-color); }
.agenda-views { margin-left: auto; display: flex; border: 1px solid var(--p-form-field-border-color); align-self: center; }
.agenda-screen .agenda-views button { padding: 6px 16px; }
.agenda-screen .agenda-views button + button { border-left: 1px solid var(--p-form-field-border-color); }
.agenda-screen .agenda-views button.on { background: var(--p-primary-color); color: var(--p-primary-contrast-color); font-weight: 600; }
.agenda-chips { display: flex; gap: var(--app-space-8); margin: 14px 0 12px; overflow-x: auto; padding-bottom: 2px; }
.agenda-screen .agenda-chip { display: flex; align-items: center; gap: 7px; padding: 6px 12px; border: 1px solid var(--p-form-field-border-color); white-space: nowrap; }
.agenda-screen .agenda-chip:hover { background: var(--agenda-wash); }
.agenda-screen .agenda-chip.on { border-color: var(--a, var(--p-primary-color)); background: color-mix(in srgb, var(--a, var(--p-primary-color)) 11%, transparent); font-weight: 600; }
.agenda-dot { width: 9px; height: 9px; background: var(--a, var(--p-text-muted-color)); display: inline-block; flex: none; }
.agenda-n { color: var(--p-text-muted-color); font-size: var(--app-text-xs); font-variant-numeric: tabular-nums; font-weight: 400; }
.agenda-add { display: flex; align-items: center; border: 1px solid var(--p-form-field-border-color); background: var(--p-form-field-background); }
.agenda-add:focus-within { border-color: var(--p-primary-color); outline: 1px solid var(--p-primary-color); }
.agenda-plus { padding: 0 4px 0 12px; color: var(--p-primary-color); font-size: 18px; font-weight: 700; }
.agenda-add input { flex: 1; border: 0; padding: 11px 10px; background: transparent; color: var(--p-text-color); outline: none; font: inherit; font-size: 15px; min-width: 0; }
.agenda-preview { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; padding: 8px 12px; background: var(--agenda-tint); border: 1px solid var(--p-content-border-color); border-top: 0; }
.agenda-what { font-weight: 600; }
.agenda-save { margin-left: auto; }
.agenda-screen .agenda-area-pick { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; border: 1px solid var(--a); font-size: var(--app-text-xs); font-weight: 600; }
.agenda-label { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; font-weight: 700; color: var(--p-text-muted-color); margin: 18px 0 6px; display: flex; gap: 8px; align-items: baseline; }
.agenda-label.late { color: var(--p-danger-color); }
.agenda-label .agenda-n { text-transform: none; letter-spacing: 0; }
.agenda-found-row { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border: 1px dashed var(--p-form-field-border-color); margin-bottom: 6px; flex-wrap: wrap; }
.agenda-screen .agenda-from { color: var(--app-link-color); font-size: var(--app-text-xs); margin-right: auto; text-align: left; }
.agenda-btns { display: flex; gap: 6px; }
.agenda-screen .btn-small.agenda-primary { background: var(--p-primary-color); color: var(--p-primary-contrast-color); border: 1px solid var(--p-primary-color); }
.agenda-row { display: grid; grid-template-columns: 24px 140px minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 8px 4px; border-bottom: 1px solid var(--p-content-border-color); cursor: pointer; }
.agenda-row:hover { background: var(--agenda-wash); }
.agenda-row.past, .agenda-mchip.past { opacity: .55; }
.agenda-screen .agenda-check { width: 18px; height: 18px; border: 1.5px solid var(--p-form-field-border-color); display: grid; place-items: center; color: var(--p-primary-contrast-color); font-size: 12px; padding: 0; }
.agenda-screen .agenda-check:hover { border-color: var(--app-friendly-color); }
.agenda-screen .agenda-check.on { background: var(--app-friendly-color); border-color: var(--app-friendly-color); }
.agenda-bar { width: 4px; height: 20px; background: var(--a); margin-left: 7px; }
.agenda-time { color: var(--p-text-muted-color); font-variant-numeric: tabular-nums; font-size: var(--app-text-sm); }
.agenda-time.late, .agenda-late { color: var(--p-danger-color); font-weight: 600; }
.agenda-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agenda-row.done .agenda-title, .agenda-card.done .agenda-kt, .agenda-wk.done .agenda-title { text-decoration: line-through; color: var(--p-text-muted-color); }
.agenda-src { font-size: 10.5px; font-weight: 650; text-transform: uppercase; letter-spacing: .05em; color: var(--p-text-muted-color); border: 1px solid var(--p-form-field-border-color); padding: 1px 6px; white-space: nowrap; }
.agenda-atag { display: flex; align-items: center; gap: 6px; font-size: var(--app-text-xs); color: var(--p-text-muted-color); }
.agenda-empty { color: var(--p-text-muted-color); padding: 18px 4px; }
.agenda-navbar { display: flex; align-items: center; gap: 6px; margin-top: 16px; }
.agenda-navbar b { font-family: var(--app-font-display); font-size: 18px; margin: 0 8px; }
.agenda-navbar b .agenda-n { font-family: inherit; margin-left: 6px; }
.agenda-screen .agenda-arrow { width: 32px; height: 32px; border: 1px solid var(--p-form-field-border-color); font-size: 20px; line-height: 1; }
.agenda-screen .agenda-arrow:hover { background: var(--agenda-wash); }
.agenda-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-top: 1px solid var(--p-content-border-color); border-left: 1px solid var(--p-content-border-color); margin-top: 10px; }
.agenda-day { border-right: 1px solid var(--p-content-border-color); border-bottom: 1px solid var(--p-content-border-color); min-height: 240px; padding: 8px 7px; min-width: 0; }
.agenda-day.today, .agenda-mday.today { background: var(--app-attention-soft); }
.agenda-day h4 { font-size: var(--app-text-xs); color: var(--p-text-muted-color); font-weight: 600; margin: 0 0 6px; }
.agenda-day.today h4 { color: var(--app-attention-color); }
.agenda-screen .agenda-wk { display: block; width: 100%; text-align: left; border-left: 3px solid var(--a); padding: 4px 6px; margin-bottom: 5px; background: color-mix(in srgb, var(--a) 9%, transparent); font-size: var(--app-text-xs); }
.agenda-screen .agenda-wk.task { background: transparent; border: 1px solid var(--p-form-field-border-color); border-left: 3px solid var(--a); }
.agenda-t { color: var(--p-text-muted-color); font-size: 11px; }
.agenda-wk .agenda-t, .agenda-wk .agenda-title { display: block; white-space: normal; }
.agenda-month { display: grid; grid-template-columns: 34px repeat(7, minmax(0, 1fr)); border-top: 1px solid var(--p-content-border-color); border-left: 1px solid var(--p-content-border-color); margin-top: 10px; }
.agenda-mhead { padding: 6px 7px; font-size: var(--app-text-xs); font-weight: 600; color: var(--p-text-muted-color); border-right: 1px solid var(--p-content-border-color); border-bottom: 1px solid var(--p-content-border-color); }
.agenda-mhead.weekend, .agenda-mday.weekend .agenda-mnum { color: var(--app-attention-color); }
.agenda-screen .agenda-wkno { font-size: 11px; color: var(--p-text-muted-color); border-right: 1px solid var(--p-content-border-color); border-bottom: 1px solid var(--p-content-border-color); padding-top: 7px; text-align: center; }
.agenda-screen button.agenda-wkno:hover { background: var(--agenda-wash); color: var(--p-text-color); }
.agenda-mday { min-height: 104px; padding: 4px 5px 6px; border-right: 1px solid var(--p-content-border-color); border-bottom: 1px solid var(--p-content-border-color); min-width: 0; }
.agenda-mday.weekend { background: var(--agenda-wash); }
.agenda-mday.out .agenda-mnum { opacity: .45; }
.agenda-screen .agenda-mnum { font-size: var(--app-text-xs); font-weight: 600; padding: 1px 5px; margin-bottom: 3px; }
.agenda-screen .agenda-mnum:hover { background: var(--agenda-tint); }
.agenda-mday.today .agenda-mnum { background: var(--app-attention-color); color: var(--p-primary-contrast-color); }
.agenda-screen .agenda-mchip { display: block; width: 100%; text-align: left; font-size: var(--app-text-xs); padding: 2px 5px; margin-bottom: 2px; border-left: 3px solid var(--a); background: color-mix(in srgb, var(--a) 9%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.agenda-screen .agenda-mchip.task { background: transparent; box-shadow: inset 0 0 0 1px var(--p-form-field-border-color); }
.agenda-screen .agenda-more { font-size: 11.5px; color: var(--app-link-color); padding: 0 5px; }
.agenda-board-bar { display: flex; align-items: center; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.agenda-hint { color: var(--p-text-muted-color); font-size: var(--app-text-xs); margin-right: auto; }
.agenda-board { overflow-x: auto; margin-top: 10px; }
.agenda-grid { display: grid; grid-template-columns: repeat(var(--cols), minmax(190px, 1fr)); }
.agenda-colhead { padding: 8px 10px; font-weight: 700; border-bottom: 2px solid var(--p-text-color); display: flex; justify-content: space-between; gap: 8px; }
.agenda-screen .agenda-lanehead { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; padding: 12px 4px 6px; font-weight: 700; border-bottom: 1px solid var(--p-content-border-color); text-align: left; }
.agenda-caret { width: 14px; color: var(--p-text-muted-color); }
.agenda-cell { min-height: 84px; padding: 6px; border-right: 1px dashed var(--p-content-border-color); background: var(--agenda-wash); }
.agenda-cell:last-child { border-right: 0; }
.agenda-cell.over { background: var(--agenda-tint); outline: 1px dashed var(--p-primary-color); outline-offset: -1px; }
.agenda-card { display: block; background: var(--p-content-background); border: 1px solid var(--p-form-field-border-color); border-left: 3px solid var(--a); padding: 8px 9px; margin-bottom: 6px; cursor: grab; }
.agenda-card:hover { border-color: var(--p-primary-color); border-left-color: var(--a); }
.agenda-card.dragging { opacity: .4; }
.agenda-meta { display: flex; justify-content: space-between; gap: 6px; margin-top: 6px; font-size: 11.5px; color: var(--p-text-muted-color); }
.agenda-detail { position: fixed; top: 0; right: 0; bottom: 0; width: 380px; background: var(--p-content-background); border-left: 1px solid var(--p-form-field-border-color);
  padding: 20px 22px; transform: translateX(105%); transition: transform var(--app-duration-base) var(--app-ease-standard), visibility var(--app-duration-base); z-index: 900; overflow: auto; visibility: hidden; }
.agenda-detail.open { transform: none; visibility: visible; }
.agenda-detail .modal-close { float: right; }
.agenda-kind { font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--a); margin-bottom: 10px; }
.agenda-field { display: block; margin-bottom: 14px; }
.agenda-field > span { display: block; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--p-text-muted-color); margin-bottom: 5px; }
.agenda-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.agenda-seg { display: flex; flex-wrap: wrap; border: 1px solid var(--p-form-field-border-color); }
.agenda-screen .agenda-seg button { flex: 1; padding: 6px 4px; display: flex; gap: 6px; align-items: center; justify-content: center; white-space: nowrap; }
.agenda-screen .agenda-seg button + button { border-left: 1px solid var(--p-form-field-border-color); }
.agenda-screen .agenda-seg button.on { background: color-mix(in srgb, var(--a) 14%, transparent); font-weight: 600; }
.agenda-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.agenda-screen .agenda-remove { color: var(--p-danger-color); }
.agenda-toast { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 1100; max-width: calc(100vw - 32px);
  background: var(--p-text-color); color: var(--p-content-background); padding: 10px 14px; font-size: var(--app-text-sm); }
.agenda-edit-row { display: flex; gap: 6px; margin-bottom: 6px; align-items: center; }
.agenda-edit-row .form-input { flex: 1; min-width: 0; margin: 0; }
.agenda-edit-row .btn-small:disabled { opacity: .35; }
.agenda-radios { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; }
.agenda-radios label { display: flex; gap: 6px; align-items: center; cursor: pointer; }

@media (max-width: 768px) {
  .agenda-views { margin-left: 0; width: 100%; }
  .agenda-screen .agenda-views button { flex: 1; padding: 6px 4px; }
  .agenda-row { grid-template-columns: 24px 96px minmax(0, 1fr) auto; }
  .agenda-row .agenda-atag { display: none; }
  .agenda-week { grid-template-columns: 1fr; }
  .agenda-day { min-height: 0; }
  .agenda-month { grid-template-columns: 22px repeat(7, minmax(0, 1fr)); }
  .agenda-mhead { padding: 4px 0; text-align: center; font-size: 11px; }
  .agenda-mday { min-height: 56px; padding: 3px 2px; }
  .agenda-screen .agenda-mchip { font-size: 0; height: 5px; padding: 0; border-left: 0; background: var(--a); box-shadow: none; }
  .agenda-screen .agenda-mchip.task { background: color-mix(in srgb, var(--a) 45%, transparent); }
  .agenda-screen .agenda-more { font-size: 10px; padding: 0; }
  .agenda-detail { top: auto; left: 0; width: auto; max-height: 82vh; border-left: 0; border-top: 1px solid var(--p-form-field-border-color); transform: translateY(105%); }
}
