/* Label Hound chat page (the desk and manufacturers' portals): layout and
   chat rules. labelhound-theme.css loads AFTER this sheet and owns the
   colours and fonts (Sept 2026 design: white ground, Figtree, pill buttons,
   rounded cards): it redefines every name in the :root block below except
   --brand, so those values are retired. Most corner radii are set here. */

:root {
  /* The app runs cooler than the landing page: white ground + white panel,
     with the palette's warmth confined to cards, chips, and gold accents —
     otherwise the stacked cream tints read as a yellow cast. */
  --cream: #FFFFFF;         /* page ground */
  --card: #F4F6F1;          /* cool sage card */
  --paper: #FFFFFF;         /* chat panel, inputs, sub-cards */
  --green: #064B2E;
  --green-deep: #04361F;
  --gold: #C8952B;
  --gold-ink: #7A5A12;      /* eyebrows, mono labels */
  --gold-bright: #E7B34A;
  --body: #42513F;
  --muted: #5C6A57;

  --line-30: rgba(6, 75, 46, 0.09);
  --line-35: rgba(6, 75, 46, 0.12);
  --line-45: rgba(6, 75, 46, 0.16);
  --line-50: rgba(6, 75, 46, 0.18);
  --line-60: rgba(6, 75, 46, 0.24);

  --serif: 'Zilla Slab', Georgia, serif;
  --sans: 'Source Sans 3', system-ui, -apple-system, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Per-manufacturer accent seam (config brand_color still lands here via
     app.js). The platform design is green/gold and no longer paints UI with
     it — kept so a future tenant skin can opt back in deliberately. */
  --brand: var(--green);
}

* { box-sizing: border-box; margin: 0; }

html, body {
  height: 100%;
}

body {
  font-family: var(--sans);
  background: var(--cream);
  color: var(--body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.app {
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

a:focus-visible,
button:focus-visible,
select:focus-visible,
textarea:focus-visible,
input:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* Selected text takes the accent, not the browser's blue. */
::selection { background: color-mix(in srgb, var(--green) 22%, white); }
.msg.user .bubble::selection,
.msg.user .bubble ::selection { background: rgba(255, 255, 255, 0.32); }

/* Shared bits */
.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-ink);
}

/* Mono caps are for short metadata only (sender, time, "On shift", section
   labels, table headers). Medium weight and a tighter word gap make them
   read as set type; sentences are set in Figtree. */
.eyebrow,
.persona-line,
.msg .label,
.starter-label,
.drawer-sub,
.account-chip .chip-eyebrow,
.choices-cue,
.bubble th {
  font-weight: 500;
  word-spacing: -0.3em;
}

.eyebrow-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.eyebrow-row::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line-50);
}

.dot-gold {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  flex: none;
}

/* Gold corner brackets (top-left + bottom-right) */
.bracket {
  position: relative;
}
.bracket::before,
.bracket::after {
  content: '';
  position: absolute;
  width: 12px;
  height: 12px;
  pointer-events: none;
}
.bracket::before {
  top: -1px;
  left: -1px;
  border-top: 2px solid var(--gold);
  border-left: 2px solid var(--gold);
}
.bracket::after {
  bottom: -1px;
  right: -1px;
  border-bottom: 2px solid var(--gold);
  border-right: 2px solid var(--gold);
}

/* ---------- Header ---------- */
.header {
  flex: none;
  min-height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 22px;
  padding: 8px 32px;
  border-bottom: 1px solid var(--line-45);
  background: var(--cream);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.brand-logo {
  width: 36px;
  height: 36px;
  object-fit: contain;
  flex: none;
  display: block;
}

.wordmark {
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 600;
  color: var(--green);
  line-height: 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.wordmark .dot { color: var(--gold); }
.wordmark[hidden] { display: none; }

/* The desk wears the landing's lockup: heading green, one size down. */
body.desk .wordmark { color: var(--green-ink); }
@media (min-width: 600px) {
  body.desk .wordmark { font-size: 21px; }
}

/* Tenant letter badge (skinned header): the same mark the portal door
   shows, in the hound's place. */
.brand-chip {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 11px;
  background: var(--green);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: 800 18px/1 var(--sans);
}

/* "Jerry · digital CSR" under the manufacturer's name */
.persona-line {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-ink);
  line-height: 1.2;
  white-space: nowrap;
}
.persona-line[hidden] { display: none; }



.brand-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}






.header-actions {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}

.admin-link {
  font-size: 14px;
  font-weight: 500;
  color: var(--green);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, currentColor 40%, transparent);
  padding-bottom: 1px;
}

.admin-link:hover { color: var(--green-deep); }

.admin-link svg { display: none; }

.signed-in {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--body);
}

.signed-in[hidden] { display: none; }

.signed-in-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
}

/* Account-bound session chip (distributor feel, 2026-09-23) */
.account-chip .chip-eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.account-chip #account-chip-name {
  font-weight: 600;
  color: var(--green);
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.signed-in #signed-in-name {
  font-weight: 600;
  color: var(--green);
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sign-out {
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 14px;
  color: var(--muted);
}

.sign-out:hover { color: var(--green); }

/* Team sign-in: the only staff affordance a distributor sees (UX #9). */
.staff-link {
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 500;
  color: color-mix(in srgb, var(--body) 78%, white);
  text-decoration: none;
}

.staff-link:hover { color: var(--green); }
.staff-link[hidden] { display: none; }

.staff-controls {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}

.staff-controls[hidden] { display: none; }

/* Mode toggle — segmented control in the header */
.mode-toggle {
  display: flex;
  background: var(--card);
  border: 1px solid var(--line-45);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}

.mode-pill {
  border: none;
  background: none;
  cursor: pointer;
  padding: 6px 14px;
  border-radius: 999px;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}

.mode-pill:hover { color: var(--green); }

.mode-pill.active {
  background: var(--green);
  color: var(--cream);
}

.mode-lock { display: inline-block; }
.mode-lock[hidden] { display: none; }

/* ---------- Layout: toolbar | chat | drawer ---------- */
/* No side padding: the column gap on either side of the chat is its gutter
   (the drawer's track keeps its gap when the drawer is closed), so the panel
   sits centred on its stage and an open drawer runs to the window edge. */
.layout {
  flex: 1;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0 24px;
  min-height: 0;
  align-items: stretch;
}

/* Product toolbar */
.toolbar {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 8px;
  border-right: 1px solid var(--line-30);
  background: var(--paper);
  min-width: 86px;
}

.tool-btn {
  border: none;
  background: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 10px 6px;
  color: color-mix(in srgb, var(--body) 78%, white);
  font-family: var(--sans);
  font-size: 12px;
  line-height: 1.2;
}

.tool-btn svg { display: block; }
.tool-btn:hover { color: var(--green); }
.tool-btn.active {
  color: var(--green);
  background: color-mix(in srgb, var(--green) 9%, transparent);
}

.tool-text { display: flex; flex-direction: column; align-items: center; gap: 1px; }
.tool-sub { display: none; }

/* Desk rail (2026-09-23): two entries deserve real buttons, not icons
   adrift in an 86px strip — wider rail, row-layout cards with sublabels.
   Desktop only; the phone layout keeps the compact strip. */
@media (min-width: 840px) {
  /* On a rail (not the phone strip) hover fills the item as well. */
  .tool-btn:hover:not(.active) { background: var(--card); }
  body.desk .toolbar { min-width: 210px; padding: 18px 12px; gap: 8px; }
  body.desk .tool-btn {
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    padding: 14px;
    font-size: 15px;
    border: 1px solid transparent;
    text-align: left;
    color: var(--nav);
  }
  body.desk .tool-btn:hover { color: var(--green); }
  body.desk .tool-btn svg { width: 22px; height: 22px; }
  body.desk .tool-btn .tool-text { align-items: flex-start; gap: 2px; }
  body.desk .tool-btn .tool-text > span:first-child { font-weight: 600; color: var(--ink); }
  body.desk .tool-sub { display: block; font-size: 12.5px; color: var(--muted); }
  body.desk .tool-btn.active .tool-sub { color: var(--green); }
}

/* Drawer panel */
.drawer {
  width: 300px;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--line-30);
  background: var(--paper);
  min-height: 0;
}

.drawer[hidden] { display: none; }

/* Entrance only; closing is instant. It plays when a drawer opens, not when
   one drawer is swapped for another. Phones raise it instead (see below). */
.drawer:not([hidden]) { animation: drawer-in 0.2s cubic-bezier(0.2, 0.7, 0.2, 1); }
@keyframes drawer-in {
  from { opacity: 0; transform: translateX(16px); }
}
@keyframes drawer-up {
  from { opacity: 0; transform: translateY(12px); }
}

.drawer-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--line-30);
}

.drawer-title {
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 600;
  color: var(--green);
  text-wrap: balance;
}

/* 32px circle; the negative margins keep the head's height and line the
   drawn x up with the drawer's text gutter. */
.drawer-close {
  flex: none;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--muted);
  width: 32px;
  height: 32px;
  margin: -4px -8px -4px 0;
  padding: 0;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.drawer-close svg { display: block; }
.drawer-close:hover { background: var(--card); color: var(--green); }

.drawer-body {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 14px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.drawer-sub {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-top: 6px;
}

.drawer-blurb {
  margin: 6px 0 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

.drawer-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }

/* "Start a new chat?" — shown in the drawer before it clears a conversation. */
.drawer-confirm { display: flex; flex-direction: column; gap: 8px; outline: none; }
.drawer-confirm-title { font-size: 16px; font-weight: 700; color: var(--green); }
.drawer-confirm .drawer-blurb { margin: 0 0 6px; }
.drawer-confirm .drawer-action {
  text-align: center;
  border-radius: 999px;
  padding: 8px 18px;
  min-height: 40px;
}

.drawer-action {
  cursor: pointer;
  text-align: left;
  background: var(--paper);
  border: 1px solid var(--line-60);
  border-radius: 16px;
  padding: 11px 14px;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 500;
  color: var(--body);
  line-height: 1.4;
  text-wrap: balance;
}
.drawer-action:hover { background: var(--card); border-color: var(--green); }
/* A drawn icon in front of the label (photo and PDF starts). */
.drawer-action.has-icon { display: flex; align-items: center; gap: 10px; }
.drawer-action.has-icon svg { flex: none; width: 18px; height: 18px; color: var(--green); }
/* The desk's rows wear the landing's question-row colours. */
body.desk .drawer-action { border-color: var(--green-line); color: var(--green-ink); }
body.desk .drawer-action:hover { background: var(--green-tint); border-color: var(--green); }

/* Find-a-manufacturer cards (desk): drawer-action look, anchor semantics. */
.partner-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-decoration: none;
}
/* The warm manufacturer panel. Platform tokens, so the desk only. */
body.desk .partner-card {
  background: var(--card-warm);
  border-color: var(--gold-line);
  padding: 12px 14px;
}
body.desk .partner-card:hover { background: var(--card-warm); border-color: var(--gold-accent); }
.partner-name { font-weight: 600; }
.partner-tag { font-size: 12.5px; color: var(--muted); }

/* Attached-PDF chip inside a message bubble */
.bubble-file {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  font-family: var(--sans);
  font-size: 13.5px;
  overflow-wrap: anywhere;
  border: 1px solid var(--line-45);
  border-radius: 10px;
  background: var(--paper);
  padding: 6px 10px;
  margin-bottom: 6px;
  color: inherit;
}
.bubble-file svg { flex: none; width: 16px; height: 16px; }
.msg.user .bubble-file { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.4); }

/* Every drawer form stacks, so a field is never squeezed beside its button. */
.drawer-form { display: flex; flex-direction: column; gap: 8px; }
.drawer-row { display: flex; align-items: center; gap: 6px; }
.drawer-x { color: var(--muted); }

/* Fields: single-line inputs and selects are pills; what a visitor types is
   body ink, never the accent. */
.drawer-form input,
.drawer-form select {
  width: 100%;
  min-width: 0;
  height: 44px;
  padding: 0 16px;
  border: 1.5px solid var(--line-input);
  border-radius: 999px;
  background-color: var(--paper);
  color: var(--body);
  font: inherit;
  font-size: 14px;
}
.drawer-form input::placeholder { color: var(--muted); opacity: 1; }
/* The browser's arrow gives way to a drawn chevron; a data URI cannot read a
   token, so it is one neutral grey on every skin. */
.drawer-form select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%236E6E6E' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.5 1.5 6 6l4.5-4.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
}

.drawer-go {
  flex: none;
  cursor: pointer;
  border: none;
  background: var(--green);
  color: #fff;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 11px 18px;
}
.drawer-go:hover { background: var(--green-deep); }
/* Under a form's fields the button is as tall as they are. */
.drawer-form .drawer-go { min-height: 44px; }

/* ---------- Chat panel (hero) ---------- */
.chat-panel {
  align-self: stretch;
  justify-self: center;
  width: 100%;
  max-width: 760px;
  background: var(--paper);
  border: 1px solid var(--line-50);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-float);
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.chat-panel.bracket::before,
.chat-panel.bracket::after { width: 16px; height: 16px; }

.panel-top {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  border-bottom: 1px solid var(--line-30);
}

.mode-note {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--muted);
}

/* A closed desk takes "On shift" away; with nothing else to show, the bar
   goes with it rather than standing as an empty strip. */
.panel-top:has(.panel-status[hidden]):not(:has(.new-chat:not([hidden]), .help-btn:not([hidden]), .mode-note:not([hidden]))) {
  display: none;
}

.mode-note .dot-gold { width: 7px; height: 7px; }
.mode-note[hidden] { display: none; }

.panel-status {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* "On shift" live dot */
.dot-live {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--live);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--live) 18%, transparent);
  flex: none;
}

.panel-top-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

.help-btn {
  cursor: pointer;
  background: none;
  border: none;
  padding: 6px 0;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--muted);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  text-underline-offset: 3px;
}
.help-btn:hover { color: var(--green); }

.new-chat {
  cursor: pointer;
  background: var(--paper);
  border: 1px solid var(--line-60);
  padding: 6px 12px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--green);
}

.new-chat:hover { border-color: var(--green); background: var(--card); }
.new-chat[hidden] { display: none; }

.chat {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 28px 28px 8px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

/* Messages */
/* Consecutive bubbles from the assistant read as one turn: the follow-up
   drops its sender label and sits closer to the previous bubble. */
.msg.grouped .label { display: none; }
.msg.grouped { margin-top: -14px; }

.msg {
  max-width: 82%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.msg .label {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-ink);
  display: flex;
  align-items: center;
  gap: 8px;
}

.msg .label .label-logo {
  width: 18px;
  height: 18px;
  object-fit: contain;
  display: block;
}

.msg.ai { align-self: flex-start; }

.msg.ai .bubble {
  background: var(--card);
  border: 1px solid var(--line-30);
  color: var(--body);
  padding: 16px 18px;
  font-size: 16px;
  line-height: 1.5;
  text-wrap: pretty;
}

.msg.user {
  align-self: flex-end;
  align-items: flex-end;
  max-width: 480px;
}

.msg.user .label {
  color: var(--muted);
  justify-content: flex-end;
}

.msg.user .bubble {
  background: var(--green);
  color: var(--cream);
  padding: 12px 16px;
  font-size: 16px;
  line-height: 1.5;
  text-wrap: pretty;
  max-width: 100%;
}

/* A pasted URL or part code breaks wherever it must, and the visitor's
   bubble (sized to its text) never grows past its column. */
.bubble { overflow-wrap: anywhere; }

/* Block-level markdown inside bubbles */
.bubble p { margin: 0 0 10px; }
.bubble p:last-child { margin-bottom: 0; }
.bubble ul, .bubble ol { margin: 0 0 10px; padding-left: 20px; }
.bubble li { margin: 4px 0; padding-left: 2px; }
.bubble .md-h {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 17px;
  line-height: 1.3;
  color: var(--green);
  margin: 16px 0 6px;
}
.bubble .md-h:first-child { margin-top: 0; }
.bubble a {
  color: var(--green);
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  text-underline-offset: 3px;
}
.bubble a:hover { color: var(--green-deep); }
.bubble code {
  font-family: var(--mono);
  font-size: 0.88em;
  background: var(--paper);
  border: 1px solid var(--line-30);
  border-radius: 6px;
  padding: 1px 6px;
}
/* A table is one rounded card: the wrapper carries the outline (and clips
   the corners, since it scrolls), rows are ruled underneath only.
   A table wider than its card shades the edge it runs under: the two soft
   shadows stay put on the card, the two paper covers travel with the table
   and hide a shadow at the end it has reached. A table that fits shows none. */
.bubble .md-table {
  overflow-x: auto;
  margin: 10px 0 12px;
  border: 1px solid var(--line-45);
  border-radius: 12px;
  background:
    linear-gradient(to right, var(--paper) 40%, transparent) left / 32px 100% no-repeat local,
    linear-gradient(to left, var(--paper) 40%, transparent) right / 32px 100% no-repeat local,
    linear-gradient(to right, color-mix(in srgb, var(--ink) 16%, transparent), transparent) left / 14px 100% no-repeat scroll,
    linear-gradient(to left, color-mix(in srgb, var(--ink) 16%, transparent), transparent) right / 14px 100% no-repeat scroll,
    var(--paper);
  /* The shades stop inside the outline: under a skin the outline is
     translucent, and a shade behind it darkens the rounded corners. */
  background-clip: padding-box, padding-box, padding-box, padding-box, border-box;
}
.bubble table {
  border-collapse: collapse;
  width: 100%;
  min-width: 0;
  font-size: 14px;
  /* Cells keep their words whole: a table too wide for its card scrolls. */
  overflow-wrap: break-word;
}
.bubble th, .bubble td {
  border-bottom: 1px solid var(--line-30);
  padding: 9px 14px;
  text-align: left;
  vertical-align: top;
}
.bubble tbody tr:last-child td { border-bottom: 0; }
.bubble td { font-variant-numeric: tabular-nums; }
.bubble th {
  border-bottom-color: var(--line-45);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.msg.user .bubble a { color: var(--gold-bright); }

/* Welcome message headline */
.welcome-headline {
  font-family: var(--serif);
  font-size: 22px;
  font-weight: 500;
  color: var(--green);
  margin-bottom: 8px;
  line-height: 1.25;
  text-wrap: balance;
}

/* Starter prompts under the welcome message */
.starter-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.starter-label {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.starter-chips {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* The question row — one control on the landing (its chips and job
   questions), the desk (suggestion tiles) and a tenant portal (starter
   chips): the question, then a small arrow in the accent. */
.starter-chip,
.suggest-tile {
  cursor: pointer;
  background: var(--paper);
  border: 1px solid var(--line-60);
  border-radius: 16px;
  padding: 12px 14px;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--body);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  text-align: left;
  text-wrap: balance;
}

.starter-chip::after,
.suggest-tile::after {
  content: '';
  flex: none;
  width: 16px;
  height: 16px;
  background: var(--green);
  -webkit-mask: var(--arrow) center / contain no-repeat;
  mask: var(--arrow) center / contain no-repeat;
}

.starter-chip:hover,
.suggest-tile:hover { background: var(--card); border-color: var(--green); }

/* One-block welcome (2026-09-23): the standing introduction rides inside
   the welcome card as a quiet signature line, and survives the first send. */
.welcome-disclosure {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--line-35);
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
  text-wrap: pretty;
}

/* Desk suggestion tiles — conversational offers in the open chat area. */
.suggest-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 2px;
  max-width: 620px;
}

.suggest-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 8px;
}

/* A closed desk takes no questions in the chat, so it offers no starters:
   the leave-a-question form is the one way in. Keyed to the closed composer,
   which stays closed after the form has been sent and gone. */
.chat-panel:has(.input-bar[hidden]) .suggest-block { display: none; }

/* The tiles are the desk's alone, so they take the landing's colours. */
body.desk .suggest-tile { border-color: var(--green-line); color: var(--green-ink); }
body.desk .suggest-tile:hover { background: var(--green-tint); border-color: var(--green); }

@media (max-width: 680px) {
  .suggest-grid { grid-template-columns: 1fr; }
  .suggest-tile { min-height: 44px; }
}

/* Message entrance */
.msg, .tool-status { animation: msg-in 0.22s ease-out; }
/* The answer that replaces the thinking bubble does not enter twice. */
.msg.no-enter { animation: none; }
/* What arrives after the answer (tap answers, thumbs) eases in the same way. */
.choices, .feedback { animation: msg-in 0.18s ease-out; }
@keyframes msg-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* Thinking indicator — running hound + pulsing dots + status */
.bubble.thinking {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  align-self: flex-start;
}

.think-hound {
  width: 34px;
  height: 22px;
  object-fit: contain;
  display: block;
  animation: hh-run 0.6s ease-in-out infinite;
}

.think-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  animation: think-pulse 1.2s ease-in-out infinite;
}

/* Staggered by position among the dots (a tenant's bubble has no hound in front). */
.think-dot + .think-dot { animation-delay: 0.2s; }
.think-dot + .think-dot + .think-dot { animation-delay: 0.4s; }

.think-status {
  font-family: var(--sans);
  font-size: 13.5px;
  color: var(--muted);
}

@keyframes hh-run {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}

@keyframes think-pulse {
  0%, 80%, 100% { opacity: 0.25; transform: scale(0.8); }
  40% { opacity: 1; transform: scale(1); }
}

/* Failure bubble + one-tap retry (UX #11) */
.msg.msg-error .bubble { border-color: color-mix(in srgb, var(--error) 28%, transparent); }

.retry-btn {
  align-self: flex-start;
  cursor: pointer;
  background: var(--green);
  color: var(--cream);
  border: none;
  padding: 11px 18px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.retry-btn:hover { background: var(--green-deep); }

/* Leave-a-question form (DESK-SPEND): stands in for an answer when the desk is closed */
/* As wide as the message it sits under; the email is a pill, the question a
   rounded box. Rules name the two real fields, never the honeypot. */
.leave-q { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.leave-q textarea,
.leave-q input[type="email"] {
  width: 100%;
  padding: 12px 18px;
  border: 1.5px solid var(--line-input);
  border-radius: 18px;
  background: var(--paper);
  color: var(--body);
  font: inherit;
  font-size: 15px;
}
.leave-q input[type="email"] { height: 46px; padding: 0 18px; border-radius: 999px; }
.leave-q textarea { min-height: 84px; resize: vertical; border-bottom-right-radius: 6px; }
.leave-q textarea::placeholder, .leave-q input[type="email"]::placeholder { color: var(--muted); opacity: 1; }
.leave-q-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.leave-q-note { font-size: 13px; color: var(--muted); min-height: 1em; }
.leave-q button:disabled { opacity: 0.6; cursor: default; }

/* Tool status line — the agent is doing something server-side */
/* Sits closer to the answer it leads into than to the message above. */
.tool-status {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--sans);
  font-size: 13.5px;
  color: var(--muted);
  padding: 0 2px;
  margin: -6px 0 -10px;
}
/* A neutral anchor, the same on every skin. */
.tool-status::before {
  content: '';
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--muted);
  opacity: 0.5;
}

/* ---------- Composer ---------- */
.composer {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 24px calc(16px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line-30);
  background: var(--paper);
}

/* A pill at one line, a rounded box once the draft wraps; camera and send
   stay on the bottom row. */
.input-bar {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  background: var(--paper);
  border: 1.5px solid var(--line-input);
  border-radius: 28px;
  box-shadow: 0 8px 24px -16px color-mix(in srgb, var(--green) 40%, transparent);
  padding: 6px 6px 6px 8px;
}
/* No attach button (config says uploads are off): the text keeps a pill's inset. */
body.cfg-ready .input-bar:has(> .attach-btn[hidden]) { padding-left: 18px; }

/* One focus look for every field: the accent border and a soft halo. It
   stands in for the outline other controls get, which would double it. */
.input-bar:focus-within,
.drawer-form input:focus,
.drawer-form select:focus,
.leave-q textarea:focus,
.leave-q input[type="email"]:focus,
.modal input:focus {
  border-color: var(--green);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--green) 14%, transparent);
  /* Unseen here; forced-colors mode paints it, where border and halo are lost. */
  outline: 2px solid transparent;
  outline-offset: 2px;
}
/* A closed desk swaps the composer for the leave-a-question form (DESK-SPEND). */
.input-bar[hidden], .panel-status[hidden] { display: none; }
/* Bot check (R-SPEND-08): empty unless Cloudflare needs a click. */
.bot-check:empty { display: none; }
.bot-check { margin-bottom: 8px; }

/* The bar itself signals focus — the textarea inside must not draw a
   second gold box (double-outline fix, 2026-09-22). */
.input-bar .input:focus-visible { outline: none; }

.attach-btn {
  flex: none;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Until config has answered (body.cfg-ready, set in app.js) the hidden
   camera keeps its slot, so the hint does not jump when the button shows;
   only a config that leaves uploads off takes the slot away. */
.attach-btn[hidden] { display: inline-flex; visibility: hidden; }
body.cfg-ready .attach-btn[hidden] { display: none; }
.attach-btn:hover { background: var(--card); color: var(--green); }

.attach-btn svg { display: block; }

.input {
  flex: 1;
  min-width: 0;
  resize: none;
  max-height: 120px;
  border: none;
  background: transparent;
  color: var(--body);
  font-family: var(--sans);
  font-size: 16px;
  /* One line is as tall as the send button (22 + 18 = 40px). */
  line-height: 22px;
  padding: 9px 4px;
  outline: none;
}

/* While the bar is empty a long hint ends in an ellipsis instead of wrapping
   out of its one line, at every width. */
.input::placeholder { color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.input:placeholder-shown { white-space: nowrap; text-overflow: ellipsis; }

.send-btn {
  flex: none;
  cursor: pointer;
  border: none;
  background: var(--green);
  color: var(--cream);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 16px 11px 18px;
}

.send-btn:hover:not(:disabled) { background: var(--green-deep); }

.send-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* The landing's ask button, arrow included. */
.send-btn .send-arrow { display: block; flex: none; }

/* Composer foot: platform credit left, demo-data chip right */
.composer-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px 10px;
  flex-wrap: wrap;
}

/* A sentence on the desk (the name and the tagline), so it is set in
   Figtree like every other sentence, on both surfaces. */
.platform-credit {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  /* The parts are flex items: this gap is the word space between them. */
  gap: 0.25em;
  font-family: var(--sans);
  font-size: 12.5px;
  font-weight: 500;
  /* The line the mono label had, so the composer keeps its height. */
  line-height: 18px;
  color: var(--muted);
  white-space: nowrap;
}

.platform-credit img {
  width: 16px;
  height: 16px;
  margin-right: 3px;
  object-fit: contain;
}

.demo-chip[hidden] { display: none; }

.demo-chip {
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--muted);
  display: inline-flex;
  align-items: flex-start;
  gap: 6px;
  border: 1px dashed var(--line-60);
  border-radius: 14px;
  padding: 3px 10px;
}

/* A caution dot: stays amber on every tenant (the skin never remaps
   --gold-accent), so it never reads as a brand-coloured alarm light. The
   top margin centres it on the first line, so it holds when the note wraps. */
.demo-chip::before {
  content: '';
  width: 5px;
  height: 5px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--gold-accent);
  flex: none;
}

/* Photo attach preview */
.attach-preview {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--line-35);
  background: var(--card);
  font-size: 13px;
  color: var(--muted);
}

.attach-preview[hidden] { display: none; }

.attach-preview img {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: 10px;
}

/* "Photo attached", or a drawn page and the PDF's name. */
.attach-preview .attach-note {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  overflow-wrap: anywhere;
}
.attach-preview .attach-note svg { flex: none; width: 16px; height: 16px; }

.attach-preview button {
  flex: none;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.attach-preview button:hover { background: var(--paper); color: var(--green); }

/* A sent photo: the bubble is a thin frame that hugs it, the caption wraps
   underneath. Never cropped — the visitor sent it to be looked at. */
.bubble-photo {
  display: block;
  width: 240px;
  max-width: 100%;
  height: auto;
  border-radius: 14px;
}
.msg.user .bubble:has(> .bubble-photo) { padding: 6px; max-width: 252px; }
.bubble-photo + div { padding: 8px 10px 6px; }

/* ---------- Resolution prompt, feedback, toast ---------- */
.csat-card {
  align-self: center;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--muted);
  background: var(--card);
  border: 1px solid var(--line-35);
  border-radius: 18px;
  padding: 8px 18px;
  animation: msg-in 0.22s ease-out;
}
/* With its two buttons the card hugs them on the right. */
.csat-card:has(.csat-btn) { padding-right: 10px; }
.csat-actions { flex: none; display: flex; gap: 10px; }

.csat-btn {
  border: 1px solid var(--line-45);
  background: var(--paper);
  color: var(--green);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 6px 14px;
  white-space: nowrap;
  cursor: pointer;
}

.csat-btn:hover { border-color: var(--green); background: var(--card); }

.verified-toast {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--green);
  color: var(--cream);
  font-size: 14px;
  font-weight: 600;
  /* As wide as its words, up to the page gutters: a pill at one line, a
     rounded box if a phone wraps it. */
  width: max-content;
  max-width: calc(100% - 32px);
  text-align: center;
  text-wrap: balance;
  border-radius: 22px;
  padding: 10px 18px;
  box-shadow: var(--shadow-float);
  z-index: 40;
  animation: toast-in 0.25s ease-out;
}
/* Its own entrance: msg-in would drop the centring transform while it plays. */
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, -6px); }
}

/* Tap-to-answer buttons (R-TAP-01..06): the answers to the agent's question,
   inside its bubble under a hairline and a one-line cue. White pills on the
   tinted bubble with a brand-colour outline, filling solid on hover and
   press. Theme tokens only, so a tenant skin carries through. Entrance,
   transitions and reduced motion come from the sheet's shared rules. */
.choices {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-60);
}

.choices-cue {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.choices-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.choice-btn {
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  text-align: left;
  color: var(--green);
  background: var(--paper);
  border: 1.5px solid color-mix(in srgb, var(--green) 55%, transparent);
  border-radius: 999px;
  padding: 11px 18px;
  min-height: 44px;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(20, 20, 20, 0.08);
}

.choice-btn:hover { background: var(--green); border-color: var(--green); color: var(--cream); }
.choice-btn:active { background: var(--green-deep); border-color: var(--green-deep); color: var(--cream); transform: translateY(1px); }

/* Thumbs: quiet icon buttons. The left margin lines the drawn thumb up with
   the bubble's edge; the vote that was cast keeps a fill. */
.feedback {
  display: flex;
  gap: 2px;
  margin: -2px 0 0 -8px;
}

.fb-btn {
  border: none;
  background: transparent;
  color: var(--muted);
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.fb-btn svg { width: 16px; height: 16px; stroke-width: 2; }
.fb-down svg { transform: scaleY(-1); }
.fb-btn:hover:not(:disabled) { background: var(--card); color: var(--green); }
.fb-btn:disabled { cursor: default; }
.fb-btn.chosen { background: color-mix(in srgb, var(--green) 12%, transparent); color: var(--green); }
.fb-btn:disabled:not(.chosen) { opacity: 0.35; }

/* Persona avatar chip (skinned tenants) */
.avatar-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  flex: none;
}

/* ---------- Tenant skin (full custom branding, 2026-09-23) ----------
   applySkin() remaps --green/--gold to the tenant's brand color; these
   rules retire the remaining platform marks. Only the faint credit
   stays, in neutral grey per Hayden. */
/* A portal learns whose it is from /api/config. Until that has answered
   (app.js sets cfg-ready, on failure too), everything on the page that
   carries a name, a greeting or an accent colour stays out of sight, so a
   manufacturer's page does not open in the platform's colours; the bare
   shell holds the layout. The desk knows itself at load and is exempt. If
   the script never gets that far, it all shows after five seconds. Only
   what is on the page during the wait is listed: a drawer or the team
   sign-in opens later, from controls that are themselves held. */
body:not(.desk):not(.cfg-ready) :is(.brand, .header-actions, .toolbar, .chat-panel > *, #name-modal, .verified-toast) {
  visibility: hidden;
  animation: show-late 0s linear 5s forwards;
}
/* The intake card's own entrance waits too, so it plays when the hold lifts. */
body:not(.desk):not(.cfg-ready) #name-modal .modal { animation: none; }
@keyframes show-late {
  to { visibility: visible; }
}
.skinned .brand-logo { display: none; }
/* One brand stripe on the top edge of the page; the header keeps its hairline. */
.skinned .header { box-shadow: inset 0 3px 0 var(--green); }
.skinned .wordmark { color: var(--ink); }
.skinned .think-dot { background: var(--green); }
/* Tokens the skin derives rather than sets: the ink/tint/line greens follow
   the brand colour applySkin() wrote to --green, and the shadows drop the
   platform's green cast. */
body.skinned {
  --green-ink: color-mix(in srgb, var(--green) 72%, black);
  --green-tint: color-mix(in srgb, var(--green) 10%, white);
  --green-line: color-mix(in srgb, var(--green) 23%, white);
  --shadow-card: 0 1px 2px rgba(20, 20, 20, 0.05), 0 24px 50px -32px rgba(20, 20, 20, 0.22);
  --shadow-float: 0 1px 2px rgba(20, 20, 20, 0.06), 0 30px 70px -28px rgba(20, 20, 20, 0.26);
}
/* The composer's resting shadow is neutral too, not a brand-coloured glow. */
.skinned .input-bar:not(:focus-within) { box-shadow: 0 8px 24px -16px rgba(20, 20, 20, 0.3); }
.skinned .platform-credit img { display: none; }
.skinned .platform-credit:hover { color: var(--gold-ink); }
/* The brand colour is for fills, the stripe, arrows and answer headings.
   What a visitor reads on a control or a title is neutral ink; hover still
   brings the brand colour in, and a pressed answer keeps its light text. */
.skinned .new-chat,
.skinned .choice-btn,
.skinned .csat-btn { color: var(--body); }
.skinned .choice-btn:hover,
.skinned .choice-btn:active { color: var(--cream); }
.skinned .drawer-title,
.skinned .drawer-confirm-title,
.skinned #account-chip-name,
.skinned #signed-in-name,
.skinned .admin-link:not(:hover) { color: var(--ink); }
/* A focused field is ringed in ink: in a brand colour (a red, say) the ring
   reads as a failed entry. */
.skinned .input-bar:focus-within,
.skinned .drawer-form input:focus,
.skinned .drawer-form select:focus,
.skinned .modal input:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 4px rgba(20, 20, 20, 0.1);
}
/* Status dots stay amber, like the demo-data dot (--gold-accent is never
   remapped), not a brand-coloured alarm light. */
.skinned .signed-in-dot,
.skinned .dot-gold { background: var(--gold-accent); }

/* ---------- Modals ---------- */
/* The same card as the doors: a quiet neutral scrim, a soft blur, pill
   fields, an ink heading. It fades and rises in. */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(18, 32, 26, 0.36);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 20;
  padding: 16px;
  animation: scrim-in 0.18s ease-out;
}
.skinned .modal-backdrop { background: rgba(20, 20, 20, 0.45); }

.modal-backdrop[hidden] { display: none; }

.modal {
  background: var(--paper);
  border: 1px solid var(--line-45);
  box-shadow: var(--shadow-float);
  padding: 32px 32px 28px;
  max-width: 440px;
  width: 100%;
  /* Never taller than the window: on a short phone it scrolls inside. */
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  position: relative;
  animation: modal-in 0.22s cubic-bezier(0.2, 0.7, 0.2, 1);
}

@keyframes scrim-in {
  from { opacity: 0; }
}
@keyframes modal-in {
  from { opacity: 0; transform: translateY(8px); }
}

.modal h2 {
  margin: 0 0 10px;
  font-family: var(--sans);
  font-size: 26px;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-wrap: balance;
}

.modal p { margin: 0 0 20px; font-size: 15px; line-height: 1.55; color: var(--muted); text-wrap: pretty; }

.modal input {
  width: 100%;
  height: 44px;
  padding: 0 18px;
  border: 1.5px solid var(--line-input);
  border-radius: 999px;
  background: var(--paper);
  color: var(--body);
  font: inherit;
  margin-bottom: 10px;
}

.modal input::placeholder { color: var(--muted); opacity: 1; }

.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 10px; }

.modal-error {
  color: var(--error);
  font-size: 0.85rem;
  margin: -2px 0 12px;
}

.modal-error[hidden] { display: none; }

.btn-primary,
.btn-secondary {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 12px 20px;
  cursor: pointer;
}

.btn-primary {
  border: none;
  background: var(--green);
  color: var(--cream);
}

.btn-primary:hover { background: var(--green-deep); }

.btn-secondary {
  border: 1px solid var(--line-45);
  background: transparent;
  color: var(--muted);
}

.btn-secondary:hover { color: var(--green); border-color: var(--green); background: var(--card); }

/* ---------- States and motion ----------
   One layer for the whole chat. Colour changes ease; an outlined control
   presses one step deeper than its hover fill; a solid button gives a
   little. Both tokens are switched off under reduced motion (end of sheet). */
:root {
  --state: 0.15s ease;
  --press: 0.97;
}

.tool-btn, .mode-pill, .staff-link, .help-btn, .new-chat,
.suggest-tile, .starter-chip, .choice-btn, .fb-btn, .csat-btn,
.drawer-action, .drawer-close, .drawer-go, .retry-btn,
.attach-btn, .attach-preview button, .send-btn, .input-bar,
.drawer-form input, .drawer-form select,
.leave-q textarea, .leave-q input[type="email"], .modal input,
.btn-primary, .btn-secondary {
  transition: background-color var(--state), border-color var(--state), color var(--state),
    box-shadow var(--state), opacity var(--state), transform var(--state);
}

/* The browser's square tap flash goes only where a pressed state replaces it. */
.tool-btn, .staff-link, .help-btn, .new-chat,
.suggest-tile, .starter-chip, .choice-btn, .fb-btn, .csat-btn,
.drawer-action, .drawer-close, .drawer-go, .retry-btn,
.attach-btn, .attach-preview button, .send-btn,
.btn-primary, .btn-secondary {
  -webkit-tap-highlight-color: transparent;
}

/* Outlined controls. The desk's own hover rules are named so this outranks them. */
.new-chat:active,
.suggest-tile:active,
.starter-chip:active,
.drawer-action:active,
.csat-btn:active,
.btn-secondary:active,
body.desk .suggest-tile:active,
body.desk .drawer-action:active {
  background: color-mix(in srgb, var(--green) 14%, var(--paper));
  border-color: var(--green);
}
body.desk .partner-card:active { background: var(--gold-tint); border-color: var(--gold-accent); }

/* Rail and icon buttons: the fill a selected item wears. */
.tool-btn:not(.active):active,
.drawer-close:active,
.attach-btn:active,
.attach-preview button:active,
.fb-btn:active:not(:disabled) {
  background: color-mix(in srgb, var(--green) 12%, transparent);
  color: var(--green);
}

.staff-link:active,
.help-btn:active { color: var(--green-deep); }

/* Solid buttons. */
.send-btn:active:not(:disabled),
.retry-btn:active:not(:disabled),
.drawer-go:active,
.btn-primary:active {
  background: var(--green-deep);
  transform: scale(var(--press));
}

/* ---------- Responsive ---------- */
/* The chat is an object: from 840px up the panel floats on a tinted stage
   with all four corners showing; header, rail and drawer stay white.
   Phones stay edge to edge. Nothing here clips the panel or the composer
   (the bot-check frame mounts inside the composer). */
@media (min-width: 840px) {
  /* Clipped sideways: the drawer enters from just past the window edge, and
     that must not flash a scrollbar. */
  .layout { background: var(--card); overflow-x: clip; }
  .chat-panel { margin: 20px 0 24px; }
  /* One top-bar height, with or without "New chat"; one 28px gutter. */
  .panel-top { min-height: 60px; padding: 0 28px; }
  .chat { padding-bottom: 20px; }
  /* The tiles and starter rows end where the welcome bubble ends. */
  .suggest-block, .starter-block { max-width: 82%; }
  .composer {
    padding: 14px 28px calc(14px + env(safe-area-inset-bottom));
    border-radius: 0 0 calc(var(--r-card) - 1px) calc(var(--r-card) - 1px);
  }
  /* The 36px camera sits centred on the 40px send button. */
  .attach-btn { margin-bottom: 2px; }
}

@media (min-width: 840px) and (max-height: 760px) {
  .chat-panel { margin: 12px 0 16px; }
}

@media (max-width: 1279px) {
  .layout { gap: 0 16px; }
  .drawer { width: 272px; }
}

/* A drawer open in a narrow window leaves the composer a phone's width, so
   the send button takes the phone's shape: a circle, arrow only. */
@media (min-width: 840px) and (max-width: 1023px) {
  .layout:has(.drawer:not([hidden])) .send-btn { padding: 0; width: 40px; height: 40px; }
  .layout:has(.drawer:not([hidden])) .send-btn .send-word { display: none; }
}

@media (max-width: 839px) {
  /* The chat IS the page on a phone: toolbar as a strip under the header,
     composer pinned to the bottom, drawers as a full overlay. */
  .layout { display: flex; flex-direction: column; gap: 0; }
  /* Header and strip read as one block: one rule, under the strip. */
  .header { border-bottom-color: transparent; }
  .toolbar {
    flex-direction: row;
    justify-content: space-around;
    min-width: 0;
    padding: 2px 8px;
    border-right: none;
    border-bottom: 1px solid var(--line-30);
    overflow-x: auto;
    /* Phone polish (POLISH-02 #12): the strip scrolls, but a chunky
       scrollbar under the icons reads as broken chrome — the cut-off
       last entry already signals there's more to the right. */
    scrollbar-width: none;
  }
  .toolbar::-webkit-scrollbar { display: none; }
  .tool-btn { padding: 8px 8px; min-width: 46px; flex: none; }
  .drawer {
    position: fixed;
    inset: 0;
    z-index: 30;
    width: auto;
    border-left: none;
    padding-top: env(safe-area-inset-top);
  }
  .drawer:not([hidden]) { animation-name: drawer-up; }
  /* A full page here: the chat's 16px gutters, 48px rows, the intro set
     apart from the list under it. */
  .drawer-head { padding: 16px 16px 12px; }
  .drawer-close { width: 44px; height: 44px; margin: -10px -14px -10px 0; }
  .drawer-body { padding: 18px 16px 24px; gap: 10px; }
  .drawer-blurb { margin: 0 0 6px; }
  .drawer-group { gap: 8px; margin-bottom: 12px; }
  .drawer-sub { margin-top: 8px; }
  .drawer-action, body.desk .partner-card { min-height: 48px; padding: 12px 16px; }
  .drawer-go, .retry-btn, .drawer-confirm .drawer-action { min-height: 44px; }
  .chat-panel { flex: 1; max-width: none; border: none; border-radius: 0; box-shadow: none; }
  .chat-panel.bracket::before, .chat-panel.bracket::after { display: none; }
  /* One height with or without "New chat", so the first send moves nothing. */
  .panel-top { padding: 6px 16px; min-height: 45px; }
  /* A sender label belongs to the bubble under it: wider between turns,
     tighter inside one. */
  .chat { padding: 16px 16px 8px; gap: 18px; }
  .msg { max-width: 92%; gap: 6px; }
  /* The tiles end where the welcome bubble ends. */
  .suggest-block, .starter-block { max-width: 92%; }
  .msg.user { max-width: min(86%, 480px); }
  .msg.grouped { margin-top: -10px; }
  .msg.ai .bubble, .msg.user .bubble { font-size: 15px; }
  .welcome-headline { font-size: 19px; }
  .starter-chip { min-height: 44px; }
  /* Tap answers share the row's width, so two or three line up as equals. */
  .choices-row { gap: 10px; }
  .choice-btn { flex: 1 1 auto; }
  /* Thumbs and the photo-remove x get a full tap target; the negative
     margins keep the row's height and the icon's place. */
  .feedback { margin: -6px 0 -8px -13px; }
  .fb-btn { width: 44px; height: 44px; }
  /* The two targets overlap a little so the thumbs read as a pair. */
  .fb-btn + .fb-btn { margin-left: -8px; }
  .fb-btn svg { width: 18px; height: 18px; }
  .attach-preview button { width: 44px; height: 44px; margin-right: -6px; }
  .tool-status { padding: 0; margin: -2px 0 -8px; }
  .bubble th, .bubble td { padding: 8px; }
  .csat-btn { min-height: 36px; }
  /* Composer: camera and send are full 44px targets; one line of text is
     44px tall too. */
  .composer { padding: 10px 16px calc(14px + env(safe-area-inset-bottom)); }
  .input-bar { gap: 2px; padding: 3px 3px 3px 5px; }
  .attach-btn { width: 44px; height: 44px; }
  .input { padding: 11px 2px; }
  .send-btn { min-height: 44px; }
}

/* 16px in every field a phone can focus, or iOS zooms the page in. A phone
   held sideways is wider than the phone layout, hence the pointer test. */
@media (max-width: 839px), (pointer: coarse) {
  .drawer-form input, .drawer-form select,
  .leave-q textarea, .leave-q input[type="email"] { font-size: 16px; }
}

@media (max-width: 599px) {
  /* All six desk tools fit a 375px screen; the narrowest stays a 46px target. */
  .toolbar { padding: 2px 4px; gap: 0; }
  .tool-btn { padding: 8px 3px; }
  /* Answers carry the tables and lists, so they get the full width, and the
     tiles with them. */
  .msg.ai, .suggest-block, .starter-block { max-width: 100%; }
  /* Full width; where the question and its two answers cannot share a row,
     the answers drop under it together. */
  .csat-card { align-self: stretch; flex-wrap: wrap; }
  .csat-card > span:first-child { flex: 1 1 9em; }
  .composer-foot { gap: 8px 10px; }
  /* Status-row items never break inside; with staff controls showing, the
     actions move to a second line as a group. */
  .panel-top { flex-wrap: wrap; gap: 4px 12px; }
  .panel-top-actions { flex-wrap: wrap; justify-content: flex-end; row-gap: 4px; margin-left: auto; }
  .panel-status, .mode-note, .help-btn, .new-chat { white-space: nowrap; }
  .header { position: relative; padding: 12px 16px; gap: 10px 12px; }
  /* Stack the wordmark over the persona line beside the logo. */
  .brand {
    display: grid;
    grid-template-columns: 34px auto;
    column-gap: 10px;
    row-gap: 2px;
    align-items: center;
  }
  .brand-logo, .brand-chip { width: 34px; height: 34px; grid-row: 1 / span 2; }
  /* Skinned: the letter badge takes the logo column, the text gets the rest. */
  .skinned .brand { grid-template-columns: 34px minmax(0, 1fr); }
  .wordmark { font-size: 20px; }
  /* The persona line may be the desk's D-21 disclosure chrome
     (R-DESK-05: "AI label co-pilot" stays on screen for the life
     of the session) — WRAP it at phone width, never truncate it
     (POLISH-02 #12). Stays at the 12px label minimum. */
  .persona-line { white-space: normal; letter-spacing: 0.06em; max-width: 100%; }
  .header { flex-wrap: nowrap; }
  .header:has(.staff-controls:not([hidden])) { flex-wrap: wrap; }
  /* An account-bound session: the account chip and the sign-in link take
     the row under the brand, never the same one. */
  .header:has(.account-chip:not([hidden])) { flex-wrap: wrap; }
  .header:has(.account-chip:not([hidden])) .header-actions { width: 100%; justify-content: space-between; }
  .staff-controls { gap: 12px; width: 100%; justify-content: space-between; }
  .header-actions { gap: 10px; }
  /* A size down so the link clears the wordmark on a 320px screen. */
  .staff-link { font-size: 14px; }
  .signed-in { gap: 6px; font-size: 12px; }
  .signed-in #signed-in-name { max-width: 70px; }
  .mode-pill { padding: 6px 12px; }
  /* A 44px circle, arrow only, pointing up. */
  .send-btn { padding: 0; width: 44px; height: 44px; }
  .send-btn .send-word { display: none; }
  .send-btn .send-arrow { width: 18px; height: 18px; transform: rotate(-90deg); }
  /* Typed text stays 16px (see the fields above); only the hint is smaller. */
  .input::placeholder { font-size: 14px; }
  /* The intake card on a short phone: tighter, so it fits before it scrolls. */
  .modal { padding: 24px 22px 22px; }
  .modal h2 { font-size: 23px; }
}

/* 360px (the common Android width): the desk's six tools fit with the strip
   and its buttons a pixel or two tighter; targets stay 46px or more. */
@media (max-width: 374px) {
  body.desk .toolbar { padding: 2px 1px; }
  body.desk .tool-btn { padding: 8px 2px; }
}

/* Scrollbars: a thin rounded thumb in the transcript and the drawer. */
.chat::-webkit-scrollbar,
.drawer-body::-webkit-scrollbar { width: 8px; }
.chat::-webkit-scrollbar-track,
.drawer-body::-webkit-scrollbar-track { background: transparent; }
.chat::-webkit-scrollbar-thumb,
.drawer-body::-webkit-scrollbar-thumb { background: var(--line-60); border-radius: 999px; }
.chat::-webkit-scrollbar-thumb:hover,
.drawer-body::-webkit-scrollbar-thumb:hover { background: var(--line-input); }
/* Browsers without those parts take the standard properties (setting both
   would switch the rounded thumb off where it works). */
@supports not selector(::-webkit-scrollbar) {
  .chat, .drawer-body { scrollbar-width: thin; scrollbar-color: var(--line-60) transparent; }
}

/* The desk's "Your manufacturer portal" link stays on one line at phone widths. */
#portal-link{white-space:nowrap}

/* Reduced motion. Last in the sheet, so it outranks every animation above;
   the two tokens switch off every transition and press in the state layer. */
@media (prefers-reduced-motion: reduce) {
  :root { --state: 0s; --press: 1; }
  .msg, .tool-status, .choices, .feedback, .csat-card, .verified-toast { animation: none; }
  .think-hound, .think-dot { animation: none; }
  .modal-backdrop, .modal, .drawer:not([hidden]) { animation: none; }
}
