/* WebRoofers Chat, Stage 1 stylesheet.
   Tokens and rules come from design-reference/DESIGN.md and the approved mockups. */

:root {
    --wr-black: #111111;
    --wr-lime: #C2EC40;
    --wr-white: #FFFFFF;
    --wr-ground: #F1F1EE;
    --wr-thread: #F7F7F4;
    --wr-border: #DEDED9;
    --wr-border-strong: #BDBDB6;
    --wr-row: #EBEBE6;
    --wr-muted: #5B5B57;
    --wr-nav: #D6D6D0;

    --wr-ink-soft: #3A3A37;
    --wr-ink-faint: #A8A8A2;
    --wr-dash: #8A8A84;
    --wr-nav-card-border: #3A3A37;

    --wr-sans: 'IBM Plex Sans', 'Segoe UI', sans-serif;
    --wr-mono: 'IBM Plex Mono', Consolas, monospace;

    --wr-sidebar-width: 248px;
    --wr-radius-card: 14px;
    --wr-radius-input: 10px;
    --wr-pad-x: 36px;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    height: 100%;
}

body {
    margin: 0;
    font-family: var(--wr-sans);
    font-size: 14px;
    background: var(--wr-ground);
    color: var(--wr-black);
    overflow-x: hidden;
}

/* Alternate states are toggled with the hidden attribute, so it has to beat
   the display rules on the blocks that carry it. */
[hidden] {
    display: none !important;
}

a {
    color: var(--wr-black);
}

a:hover {
    color: var(--wr-ink-soft);
}

h1,
h2,
h3 {
    margin: 0;
}

@keyframes wrslide {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(260%); }
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ------------------------------------------------------------------ shell */

.shell {
    position: relative;
    display: flex;
    min-height: 100vh;
    background: var(--wr-ground);
    color: var(--wr-black);
}

.shell-main {
    flex-grow: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.shell-body {
    flex-grow: 1;
    min-height: 0;
    padding: 24px var(--wr-pad-x) var(--wr-pad-x) var(--wr-pad-x);
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* The Inbox is a full height screen: the thread scrolls, not the page. */
.shell-fill {
    height: 100vh;
    overflow: hidden;
}

/* ----------------------------------------------------------- top bar */

/* The slim black bar a Super Admin sees while looking at a customer panel. It
   sits above the shell rather than over it, so nothing is ever hidden behind it. */
.topbar {
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 0 20px;
    background: var(--wr-black);
    color: var(--wr-white);
}

.topbar-text {
    font-size: 13px;
    font-weight: 600;
}

.topbar .btn {
    min-height: 32px;
    padding: 0 16px;
    font-size: 13px;
}

/* With the bar above it, the shell and the sticky sidebar are both one bar
   shorter, so the page still fits the viewport exactly. */
.shell-topbar {
    min-height: calc(100vh - 44px);
}

.shell-topbar.shell-fill {
    height: calc(100vh - 44px);
}

.shell-topbar .sidebar {
    height: calc(100vh - 44px);
}

/* A full width notice above the page content, for example when the agent is
   paused. Outline style, because it needs attention rather than celebration. */
.panel-notice {
    margin: 0 var(--wr-pad-x);
    padding: 14px 18px;
    border: 1px solid var(--wr-border-strong);
    border-radius: var(--wr-radius-card);
    background: var(--wr-white);
    font-size: 14px;
    font-weight: 600;
}

/* ---------------------------------------------------------------- sidebar */

.sidebar {
    width: var(--wr-sidebar-width);
    flex-shrink: 0;
    align-self: flex-start;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    background: var(--wr-black);
    padding: 24px 16px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.logo {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 8px 20px 8px;
}

.logo-mark {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: var(--wr-radius-input);
    background: var(--wr-lime);
    color: var(--wr-black);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 15px;
    letter-spacing: -0.02em;
}

.logo-text {
    display: flex;
    flex-direction: column;
}

/* The monogram block is drawn on the black sidebar, on the black sign in panel
   and on light pages such as the review index, so the default here is the light
   background reading and the two dark surfaces override it below. Lime is never
   a text colour on a light background, so on light the accent line is the lime
   chip with #111111 on it that the rest of the product uses. */
.logo-name {
    font-size: 15px;
    font-weight: 600;
    color: var(--wr-black);
}

.logo-sub {
    font-size: 12px;
    font-weight: 500;
    color: var(--wr-black);
    background: var(--wr-lime);
    align-self: flex-start;
    padding: 1px 8px;
    border-radius: 999px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.sidebar .logo-name,
.login-panel .logo-name {
    color: var(--wr-white);
}

.sidebar .logo-sub,
.login-panel .logo-sub {
    color: var(--wr-lime);
    background: none;
    padding: 0;
}

.logo-lg .logo-mark {
    width: 44px;
    height: 44px;
    font-size: 16px;
}

.logo-lg .logo-name {
    font-size: 17px;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    padding: 0 12px;
    border-radius: var(--wr-radius-input);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    color: var(--wr-nav);
}

.nav-item:hover {
    color: var(--wr-white);
}

.nav-item.is-active,
.nav-item.is-active:hover {
    background: var(--wr-lime);
    color: var(--wr-black);
}

.nav-badge {
    margin-left: auto;
    min-width: 22px;
    height: 22px;
    border-radius: 999px;
    background: var(--wr-lime);
    color: var(--wr-black);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
}

.nav-item.is-active .nav-badge {
    background: var(--wr-black);
    color: var(--wr-white);
}

.sidebar-card {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 14px;
    border-radius: 12px;
    border: 1px solid var(--wr-nav-card-border);
}

.sidebar-card-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--wr-white);
}

.sidebar-card-note {
    font-size: 12px;
    color: var(--wr-lime);
    font-weight: 500;
}

.sidebar-card-link {
    font-size: 13px;
    color: var(--wr-nav);
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}

.sidebar-card-link:hover {
    color: var(--wr-white);
}

/* Signing out is a POST, so the link in the sidebar card is really a button and
   has to shed everything a browser gives a button by default. */
button.sidebar-card-link {
    appearance: none;
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.sidebar-card form {
    margin: 0;
}

/* ------------------------------------------------------------ page header */

.page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 28px var(--wr-pad-x) 0 var(--wr-pad-x);
}

.page-head-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.page-title {
    font-size: 26px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--wr-black);
}

.page-sub {
    font-size: 13px;
    color: var(--wr-muted);
}

.page-head-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* ---------------------------------------------------------------- buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 18px;
    border-radius: 999px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    border: 1px solid transparent;
}

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

.btn-lime {
    border-color: var(--wr-black);
    background: var(--wr-lime);
    color: var(--wr-black);
}

.btn-dark {
    border-color: var(--wr-black);
    background: var(--wr-black);
    color: var(--wr-white);
}

.btn-dark:hover {
    color: var(--wr-white);
}

.btn-ghost {
    border-color: var(--wr-border-strong);
    background: var(--wr-white);
    color: var(--wr-black);
}

.btn-grow {
    flex-grow: 1;
}

.btn-tall {
    min-height: 48px;
}

.btn-icon {
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border-radius: 999px;
    border: 1px solid var(--wr-border-strong);
    background: var(--wr-white);
    color: var(--wr-black);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

/* ------------------------------------------------------------------ chips */

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    border: 1px solid transparent;
}

.chip-lime {
    background: var(--wr-lime);
    color: var(--wr-black);
}

.chip-dark {
    background: var(--wr-black);
    color: var(--wr-white);
}

.chip-out {
    background: var(--wr-white);
    color: var(--wr-black);
    border: 1.5px solid var(--wr-black);
}

.chip-grey {
    background: var(--wr-ground);
    color: var(--wr-ink-soft);
    border-color: var(--wr-border);
}

/* ------------------------------------------------------------------ cards */

.card {
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
    border-radius: var(--wr-radius-card);
    overflow: hidden;
}

.card-pad {
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.card-pad-lg {
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 18px 20px;
}

.card-head-pad {
    padding: 20px;
}

.card-head-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.card-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--wr-black);
}

.card-note {
    font-size: 13px;
    color: var(--wr-muted);
}

.card-head-stack {
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.card-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 18px 20px;
    border-top: 1px solid var(--wr-row);
}

.card-row-tight {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 20px;
    border-top: 1px solid var(--wr-row);
}

.card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 20px;
}

.rule {
    height: 1px;
    background: var(--wr-row);
}

/* ------------------------------------------------------------------ stats */

.stat {
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
    border-radius: var(--wr-radius-card);
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.stat-label {
    font-size: 13px;
    color: var(--wr-muted);
}

.stat-value {
    font-size: 30px;
    font-weight: 600;
    letter-spacing: -0.02em;
}

.stat-note {
    font-size: 13px;
    color: var(--wr-muted);
}

/* ----------------------------------------------------------------- inputs */

.input {
    width: 100%;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid var(--wr-border-strong);
    border-radius: var(--wr-radius-input);
    background: var(--wr-white);
    font-family: inherit;
    font-size: 14px;
    color: var(--wr-black);
}

/* The same input, several lines tall. A textarea needs the padding the single
   line version puts only on the sides. */
textarea.input {
    padding: 12px 14px;
    line-height: 1.5;
    resize: vertical;
}

/* A number or a zip that is never more than a few characters wide. */
.input-narrow {
    width: 96px;
    flex-shrink: 0;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--wr-black);
}

.field-flat {
    display: flex;
}

.check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    font-size: 14px;
    font-weight: 400;
}

.check-wide {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    font-size: 14px;
    font-weight: 400;
}

.check input[type="checkbox"],
.check-wide input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--wr-black);
}

.range {
    width: 100%;
    min-height: 44px;
    accent-color: var(--wr-black);
}

.search-field {
    display: flex;
    align-items: center;
    width: 280px;
}

/* ----------------------------------------------------------------- tables */

.table-scroll {
    width: 100%;
    overflow-x: auto;
}

.table {
    width: 100%;
    border-collapse: collapse;
    min-width: 900px;
}

.table th {
    text-align: left;
    padding: 12px 16px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wr-muted);
    border-bottom: 1px solid var(--wr-border);
    white-space: nowrap;
}

.table-ruled th {
    border-top: 1px solid var(--wr-border);
}

.table td {
    padding: 14px 16px;
    font-size: 14px;
    color: var(--wr-black);
    border-bottom: 1px solid var(--wr-row);
    vertical-align: middle;
}

.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.tabular {
    font-variant-numeric: tabular-nums;
}

.cell-strong {
    font-weight: 600;
}

.cell-path {
    font-family: var(--wr-mono);
    font-size: 13px;
    color: var(--wr-ink-soft);
}

.cell-actions {
    text-align: right;
}

/* ----------------------------------------------------------------- layout */

.grid-4 {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
}

/* The Super Admin tiles, once the plan tile joined them. It is a desktop tool
   and there is room for five across. */
.grid-5 {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 16px;
}

.grid-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
}

.grid-2-tight {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

.grid-side-380 {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 20px;
    align-items: start;
}

.grid-side-360 {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 20px;
    align-items: start;
}

.grid-side-wide {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 28px;
    align-items: start;
}

.stack-16 {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.stack-12 {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.stack-2 {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.stack-4 {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

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

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

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

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

.stack-6 {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.row-end-12 {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
}

.filters {
    display: flex;
    gap: 8px;
}

.grow {
    flex-grow: 1;
    min-width: 0;
}

.shrink-0 {
    flex-shrink: 0;
}

.mt-8 {
    margin-top: 8px;
}

.note {
    font-size: 13px;
    color: var(--wr-muted);
}

.note-strong {
    font-size: 14px;
    font-weight: 600;
}

.note-strong-sm {
    font-size: 13px;
    font-weight: 600;
}

.eyebrow {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wr-muted);
}

/* ------------------------------------------------------------- list items */

.item-title {
    font-size: 14px;
    font-weight: 600;
}

.item-sub {
    font-size: 13px;
    color: var(--wr-muted);
}

.truncate {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

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

.item-time {
    font-size: 13px;
    color: var(--wr-muted);
    width: 72px;
    text-align: right;
    flex-shrink: 0;
}

.chat-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 20px;
    border-top: 1px solid var(--wr-row);
    text-decoration: none;
    color: var(--wr-black);
    min-height: 44px;
}

.avatar {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--wr-ground);
    border: 1px solid var(--wr-border);
    display: flex;
    align-items: center;
    justify-content: center;
}

.doc-icon {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    border-radius: var(--wr-radius-input);
    background: var(--wr-ground);
    border: 1px solid var(--wr-border);
    display: flex;
    align-items: center;
    justify-content: center;
}

.step-num {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border-radius: 999px;
    border: 1.5px solid var(--wr-black);
    background: var(--wr-white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 700;
}

.step-num-done {
    background: var(--wr-lime);
}

.order-num {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--wr-black);
    color: var(--wr-white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
}

.drag-handle {
    color: var(--wr-dash);
    display: inline-flex;
}

.kv {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 32px;
}

.kv-key {
    font-size: 13px;
    color: var(--wr-muted);
}

.kv-value {
    font-size: 14px;
    font-weight: 600;
    text-align: right;
}

.line {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 44px;
}

.line-left {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
}

.line-text {
    font-size: 14px;
}

/* -------------------------------------------------------------- progress */

.progress {
    height: 8px;
    border-radius: 999px;
    background: var(--wr-row);
    overflow: hidden;
}

.progress-strong {
    background: var(--wr-border);
}

.progress-bar {
    width: 40%;
    height: 8px;
    border-radius: 999px;
    background: var(--wr-black);
    animation: wrslide 1.2s linear infinite;
}

.progress-block {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 240px;
}

.soft-panel {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px 16px;
    border-radius: 12px;
    background: var(--wr-ground);
}

.soft-panel-checks {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 14px 16px;
    border-radius: 12px;
    background: var(--wr-ground);
}

/* Stage 2: the business details the crawler lifted off the website, shown as a
   compact row of neutral chips under the pages table. */

.fact-row {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px 20px;
    border-top: 1px solid var(--wr-row);
}

.chip-wrap {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.chip-wrap .chip {
    white-space: normal;
}

/* ----------------------------------------------------------------- modal */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(17, 17, 17, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    overflow: auto;
    z-index: 20;
}

.modal {
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
    border-radius: var(--wr-radius-card);
    width: 640px;
    max-width: 100%;
    padding: 28px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* The dialog is a real form now, so the antiforgery field must not take a gap of
   its own in the column. */
.modal > input[type="hidden"] {
    display: none;
}

.modal-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.modal-title {
    font-size: 22px;
    font-weight: 600;
}

/* ----------------------------------------------------------------- login */

.login {
    display: flex;
    min-height: 100vh;
    background: var(--wr-white);
    color: var(--wr-black);
}

.login-panel {
    width: 620px;
    flex-shrink: 0;
    background: var(--wr-black);
    padding: 56px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 40px;
}

.login-pitch {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.login-headline {
    font-size: 44px;
    line-height: 1.1;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--wr-white);
}

.login-sub {
    font-size: 16px;
    line-height: 1.5;
    color: var(--wr-nav);
}

.login-foot {
    font-size: 13px;
    color: var(--wr-ink-faint);
}

.login-form-side {
    flex-grow: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px;
}

.login-form {
    width: 400px;
    max-width: 100%;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.login-title {
    font-size: 30px;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.login-link {
    font-size: 14px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}

/* --------------------------------------------------------- dashboard alert */

.alert-card {
    border-radius: var(--wr-radius-card);
    background: var(--wr-black);
    color: var(--wr-white);
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.alert-eyebrow {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--wr-lime);
}

.alert-dot {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--wr-lime);
}

.alert-headline {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.25;
}

.alert-note {
    font-size: 14px;
    color: var(--wr-nav);
}

/* ------------------------------------------------------------- inbox page */

.inbox-card {
    flex-grow: 1;
    min-height: 0;
    display: flex;
}

.inbox-list {
    width: 320px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--wr-border);
    overflow-y: auto;
}

.inbox-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 14px 16px;
}

.conv {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
    padding: 14px 16px;
    border: none;
    border-top: 1px solid var(--wr-row);
    text-align: left;
    font-family: inherit;
    cursor: pointer;
    color: var(--wr-black);
    background: var(--wr-white);

    /* Choosing a chat is a real address now, so the row is a link. */
    text-decoration: none;
}

.conv.is-selected {
    background: var(--wr-ground);
}

.conv-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.conv-name {
    font-size: 14px;
    font-weight: 600;
}

.conv-time {
    font-size: 12px;
    color: var(--wr-muted);
}

.conv-preview {
    font-size: 13px;
    color: var(--wr-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.inbox-group {
    padding: 12px 16px;
    border-top: 1px solid var(--wr-row);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wr-muted);
}

.conv-pane {
    flex-grow: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.side-pane {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.thread-pane {
    flex-grow: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--wr-thread);
}

.thread-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 20px;
    background: var(--wr-white);
    border-bottom: 1px solid var(--wr-border);
}

.thread-head-name {
    font-size: 16px;
    font-weight: 600;
}

.thread {
    flex-grow: 1;
    min-height: 0;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    overflow-y: auto;
}

.bubble-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.bubble-group-agent {
    align-items: flex-end;
}

.bubble-group-visitor {
    align-items: flex-start;
}

.bubble-author {
    font-size: 12px;
    font-weight: 600;
    color: var(--wr-muted);
}

.bubble {
    box-sizing: content-box;
    max-width: 72%;
    padding: 10px 14px;
    border-radius: 14px;
    font-size: 14px;
    line-height: 1.45;
}

.bubble-agent {
    border-top-right-radius: 4px;
    background: var(--wr-black);
    color: var(--wr-white);
}

.bubble-visitor {
    border-top-left-radius: 4px;
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
}

/* The small grey mark under an AI reply. It says which of the two wrote the
   line and nothing else: what a reply cost is the Super Admin's business, and
   never the customer's. */
.bubble-mark {
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--wr-ground);
    border: 1px solid var(--wr-border);
    color: var(--wr-muted);
    font-size: 11px;
    font-weight: 600;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.bubble-group:hover .bubble-mark,
.bubble-group:focus-within .bubble-mark {
    opacity: 1;
}

/* No hover on a touch screen, so the mark is simply always there. */
@media (hover: none) {
    .bubble-mark {
        opacity: 1;
    }
}

/* The visitor is typing, shown to whoever is working the chat. */
.thread-typing {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 10px 14px;
    align-self: flex-start;
    border-radius: 14px;
    border-top-left-radius: 4px;
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
}

.thread-typing span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--wr-dash);
    animation: wr-dot 1.2s infinite ease-in-out;
}

.thread-typing span:nth-child(2) {
    animation-delay: 0.15s;
}

.thread-typing span:nth-child(3) {
    animation-delay: 0.3s;
}

@keyframes wr-dot {
    0%, 60%, 100% {
        opacity: 0.3;
    }

    30% {
        opacity: 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    .thread-typing span {
        animation: none;
        opacity: 0.6;
    }
}

.thread-system {
    display: flex;
    justify-content: center;
}

.thread-system span {
    padding: 5px 12px;
    border-radius: 999px;
    background: var(--wr-lime);
    color: var(--wr-black);
    font-size: 12px;
    font-weight: 600;
}

.thread-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 20px;
    background: var(--wr-white);
    border-top: 1px solid var(--wr-border);
}

.thread-bar-reply {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 20px;
    background: var(--wr-white);
    border-top: 1px solid var(--wr-border);
}

.inbox-side {
    width: 300px;
    flex-shrink: 0;
    border-left: 1px solid var(--wr-border);
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    overflow-y: auto;
}

.fact {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 40px;
}

.fact-mark {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--wr-lime);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.fact-mark-empty {
    background: transparent;
    border: 1.5px dashed var(--wr-dash);
}

.fact-text {
    display: flex;
    flex-direction: column;
}

.fact-label {
    font-size: 12px;
    color: var(--wr-muted);
}

.fact-value {
    font-size: 14px;
    font-weight: 600;
}

/* ------------------------------------------------------------- agent page */

.swatches {
    display: flex;
    gap: 14px;
    padding: 4px;
}

.swatch {
    width: 44px;
    height: 44px;
    border-radius: 999px;
    border: none;
    cursor: pointer;
    box-shadow: 0 0 0 1px var(--wr-border-strong);
}

.swatch-lime {
    background: var(--wr-lime);
}

.swatch-black {
    background: var(--wr-black);
}

.swatch-green {
    background: #1F5F3A;
}

.swatch-red {
    background: #B3261E;
}

.swatch.is-selected {
    box-shadow: 0 0 0 3px var(--wr-white), 0 0 0 5px var(--wr-black);
}

/* The same two round holders, now that a real logo can be in them. */
img.logo-drop,
img.preview-logo {
    object-fit: cover;
    border-style: solid;
    border-color: var(--wr-border);
}

.logo-drop {
    width: 72px;
    height: 72px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--wr-ground);
    border: 1.5px dashed var(--wr-dash);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 600;
    color: var(--wr-muted);
}

.preview-col {
    display: flex;
    flex-direction: column;
    gap: 12px;
    position: sticky;
    top: 0;
}

.preview {
    width: 380px;
    max-width: 100%;
    border-radius: 18px;
    overflow: hidden;
    border: 1px solid var(--wr-border);
    background: var(--wr-white);
    display: flex;
    flex-direction: column;
    box-shadow: 0 18px 40px rgba(17, 17, 17, 0.12);
}

.preview-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    background: var(--wr-black);
    color: var(--wr-white);
}

.preview-logo {
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--wr-lime);
    color: var(--wr-black);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 14px;
}

.preview-name {
    font-size: 15px;
    font-weight: 600;
}

.preview-sub {
    font-size: 12px;
    color: var(--wr-nav);
}

.preview-thread {
    padding: 16px;
    background: var(--wr-thread);
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 300px;
}

.preview-bubble {
    box-sizing: content-box;
    max-width: 80%;
    padding: 10px 14px;
    border-radius: 14px;
    font-size: 14px;
    line-height: 1.45;
}

.preview-bubble-agent {
    align-self: flex-start;
    border-top-left-radius: 4px;
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
}

.preview-bubble-visitor {
    align-self: flex-end;
    border-top-right-radius: 4px;
    background: var(--wr-lime);
    color: var(--wr-black);
}

.preview-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-top: 1px solid var(--wr-border);
}

.preview-input {
    flex-grow: 1;
    min-height: 44px;
    display: flex;
    align-items: center;
    padding: 0 14px;
    border-radius: 999px;
    background: var(--wr-ground);
    font-size: 14px;
    color: var(--wr-muted);
}

.preview-send {
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--wr-lime);
    color: var(--wr-black);
    display: flex;
    align-items: center;
    justify-content: center;
}

.preview-foot {
    padding: 8px;
    text-align: center;
    font-size: 12px;
    color: var(--wr-muted);
}

/* ----------------------------------------------------------- install page */

.step-card {
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
    border-radius: var(--wr-radius-card);
    padding: 22px;
    display: flex;
    gap: 16px;
}

.step-card .step-num {
    background: var(--wr-lime);
}

.step-body {
    flex-grow: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.step-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--wr-black);
    min-height: 36px;
    display: flex;
    align-items: center;
}

.snippet {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    border-radius: 12px;
    background: var(--wr-black);
}

.snippet code {
    flex-grow: 1;
    min-width: 0;
    font-family: var(--wr-mono);
    font-size: 13px;
    line-height: 1.6;
    color: var(--wr-lime);
    word-break: break-all;
}

/* The same block holding a whole message rather than one line of code, so the
   line breaks the operator is about to send are the ones they can see. */
.snippet-message {
    align-items: flex-start;
}

.snippet-message code {
    white-space: pre-wrap;
    word-break: normal;
}

.body-text {
    font-size: 14px;
    line-height: 1.5;
}

.code-inline {
    font-family: var(--wr-mono);
    font-size: 13px;
    background: var(--wr-ground);
    padding: 2px 6px;
    border-radius: 6px;
}

/* ------------------------------------------------------------- index page */

.review-index {
    max-width: 760px;
    margin: 0 auto;
    padding: 56px 24px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.review-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px 0;
}

.review-list a {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    padding: 0 12px;
    border-radius: var(--wr-radius-input);
    font-weight: 600;
    text-decoration: none;
}

.review-list a:hover {
    background: var(--wr-ground);
}

.review-list span {
    font-weight: 400;
    color: var(--wr-muted);
}

/* -------------------------------------------------------------- demo page */

.demo-page {
    min-height: 100vh;
    background: #E9E9E4;
}

.demo-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 24px 40px 0 40px;
}

.demo-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 24px 40px 80px 40px;
}

.block {
    border-radius: 6px;
    background: #CFCFC8;
}

.block-faint {
    background: #DADAD4;
}

.demo-logo {
    width: 160px;
    height: 22px;
}

.demo-nav {
    width: 120px;
    height: 40px;
    border-radius: 999px;
}

.demo-head-1 {
    width: 46%;
    min-width: 280px;
    height: 34px;
}

.demo-head-2 {
    width: 34%;
    min-width: 220px;
    height: 34px;
}

.demo-line-1 {
    width: 62%;
    height: 14px;
}

.demo-line-2 {
    width: 54%;
    height: 14px;
}

.demo-line-3 {
    width: 44%;
    height: 14px;
}

.demo-tiles {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    padding: 18px 0;
}

.demo-tile {
    height: 180px;
    border-radius: 12px;
}

/* ------------------------------------------------- 1200px wide and narrower */

@media (max-width: 1320px) {
    :root {
        --wr-pad-x: 24px;
    }

    .grid-side-380,
    .grid-side-360,
    .grid-side-wide {
        grid-template-columns: minmax(0, 1fr) 320px;
    }

    .preview {
        width: 100%;
    }

    .inbox-list {
        width: 280px;
    }

    .inbox-side {
        width: 260px;
    }
}

/* ================================================================== stage 5

   Everything below is either a piece the phone layout needs, or the phone
   layout itself. The desktop rules above are untouched: the panel at 900px and
   wider is the same panel it was, to the pixel.

   One stylesheet, the same tokens, the same classes. There is no second set of
   pages and no second set of addresses: what changes under 900px is which of
   the same blocks are drawn and how they are stacked. */

/* --------------------------------------------------- pieces both sizes use */

/* A small link to a map, under a name or beside a location. It is a link
   rather than a button because it leaves the product, and it opens in its own
   tab so nobody loses the chat they were reading. */
.map-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    padding: 0 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--wr-ink-soft);
    text-decoration: none;
    white-space: nowrap;
}

.map-link:hover {
    color: var(--wr-black);
}

/* In the Inbox list the map link sits under the row rather than inside it,
   because a link inside a link is not a thing a browser will draw. */
.conv-wrap {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--wr-row);
}

.conv-wrap .conv {
    border-top: none;
}

.conv-wrap .map-link-conv {
    min-height: 36px;
    padding: 0 16px 10px 16px;
}

.conv-place {
    font-size: 13px;
    font-weight: 500;
    color: var(--wr-ink-soft);
}

/* Today's chats: the row is a link, and the map link beside it is another one,
   so the row is a holder with two links in it rather than one link inside
   another. */
.chat-row {
    flex-wrap: wrap;
}

.chat-row-main {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-grow: 1;
    min-width: 0;
    text-decoration: none;
    color: var(--wr-black);
}

.cell-stack {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* The location row in the lead details panel: a mark with no tick in it. */
.fact-mark-plain {
    background: transparent;
    border: 1px solid var(--wr-border-strong);
    color: var(--wr-muted);
}

/* One row of "On the website now". */
.presence-row {
    gap: 12px;
}

.presence-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

/* The card under the tiles on free human only chat: the chats nobody got to
   this month, and what would have answered them. It is never drawn at zero. */
.missed-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.missed-count {
    font-size: 40px;
    font-weight: 700;
    line-height: 1;
}

/* The line the four setting up screens carry on a phone. The stylesheet is what
   decides it exists, so there is one page either way. */
.desk-notice {
    display: none;
    padding: 14px 16px;
    border: 1px solid var(--wr-border-strong);
    border-radius: var(--wr-radius-card);
    background: var(--wr-white);
    font-size: 14px;
    font-weight: 600;
}

/* ------------------------------------------------------------ offline page */

.offline {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 32px 24px;
    padding-top: calc(32px + env(safe-area-inset-top));
    padding-bottom: calc(32px + env(safe-area-inset-bottom));
    text-align: center;
}

.offline-mark {
    width: 64px;
    height: 64px;
    border-radius: 18px;
    background: var(--wr-black);
    color: var(--wr-lime);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 22px;
}

/* The offline page is the one screen with no sidebar and no sign in panel, so
   the product names itself here in plain dark text on the light page. */
.offline-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--wr-muted);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.offline-title {
    font-size: 26px;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.offline-note {
    margin: 0;
    max-width: 380px;
    font-size: 14px;
    color: var(--wr-muted);
}

/* --------------------------------------------- the phone's own furniture */

/* All six are drawn on every page and shown only under 900px, so nothing about
   them can reach the desktop layout. */

.mobile-top,
.tabbar,
.sheet-backdrop,
.install-bar,
.thread-back,
.lead-details {
    display: none;
}

/* ------------------------------------------------- under 900px: the phone */

@media (max-width: 899px) {
    :root {
        --wr-pad-x: 16px;
        --wr-top-bar: 56px;
        --wr-tab-bar: 64px;
    }

    /* A slim black bar with the company name and one button. It is fixed so the
       name is still there halfway down a long list. */
    .mobile-top {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 30;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        height: calc(var(--wr-top-bar) + env(safe-area-inset-top));
        padding: env(safe-area-inset-top) calc(12px + env(safe-area-inset-right)) 0
                 calc(16px + env(safe-area-inset-left));
        background: var(--wr-black);
        color: var(--wr-white);
    }

    .mobile-top-name {
        font-size: 15px;
        font-weight: 600;
        min-width: 0;
    }

    .mobile-menu {
        width: 44px;
        height: 44px;
        flex-shrink: 0;
        border: none;
        border-radius: var(--wr-radius-input);
        background: transparent;
        color: var(--wr-white);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
    }

    /* The bar a Super Admin sees sits under the phone's own bar rather than
       above it, so neither one covers the other. */
    .topbar {
        position: fixed;
        top: calc(var(--wr-top-bar) + env(safe-area-inset-top));
        left: 0;
        right: 0;
        z-index: 29;
        padding: 0 calc(16px + env(safe-area-inset-right)) 0 calc(16px + env(safe-area-inset-left));
    }

    .sidebar {
        display: none;
    }

    .shell,
    .shell-topbar {
        min-height: 100dvh;
        padding-top: calc(var(--wr-top-bar) + env(safe-area-inset-top));
        padding-bottom: calc(var(--wr-tab-bar) + env(safe-area-inset-bottom));
    }

    .shell-topbar,
    .shell-topbar.shell-fill {
        padding-top: calc(var(--wr-top-bar) + 44px + env(safe-area-inset-top));
    }

    /* dvh, not vh: the on screen keyboard shrinks the visible area and vh does
       not notice, which is how a reply box ends up under a keyboard. */
    .shell-fill,
    .shell-topbar.shell-fill {
        height: 100dvh;
    }

    .page-head {
        padding: 16px var(--wr-pad-x) 0 var(--wr-pad-x);
        flex-wrap: wrap;
        gap: 12px;
    }

    .page-title {
        font-size: 20px;
    }

    .page-head-actions {
        width: 100%;
        flex-wrap: wrap;
    }

    .page-head-actions .btn {
        flex-grow: 1;
    }

    .shell-body {
        padding: 16px var(--wr-pad-x) var(--wr-pad-x) var(--wr-pad-x);
        gap: 16px;
    }

    .panel-notice {
        margin: 0 var(--wr-pad-x);
    }

    .desk-notice {
        display: block;
    }

    /* Every side by side layout becomes one column, and the stat tiles become
       two by two rather than four across. */
    .grid-4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .grid-2,
    .grid-2-tight,
    .grid-side-380,
    .grid-side-360,
    .grid-side-wide {
        grid-template-columns: minmax(0, 1fr);
        gap: 16px;
    }

    .stat {
        padding: 16px;
    }

    .stat-value {
        font-size: 24px;
    }

    .card,
    .step-card,
    .preview {
        width: 100%;
    }

    .search-field {
        width: 100%;
    }

    .filters {
        flex-wrap: wrap;
    }

    .modal-backdrop {
        padding: 16px;
        padding-bottom: calc(16px + env(safe-area-inset-bottom));
    }

    .modal {
        padding: 20px;
    }

    /* A row of controls that would run off the side becomes a column of them. */
    .row-10,
    .row-12,
    .row-16,
    .row-end-12,
    .card-head,
    .card-foot {
        flex-wrap: wrap;
    }

    .preview-col {
        position: static;
    }

    /* Nothing may push the page sideways at 360px. A button keeps its pill and
       its 44px, and wraps its words instead of growing past the screen, and a
       long web address breaks rather than carrying the layout with it. */
    .btn {
        white-space: normal;
        text-align: center;
    }

    .line,
    .line-left {
        flex-wrap: wrap;
    }

    .line-text,
    .item-title,
    .item-sub,
    .card-note,
    .body-text,
    .kv-value,
    .code-inline {
        min-width: 0;
        overflow-wrap: anywhere;
    }

    /* The numbered steps stack, so the step body gets the whole width. */
    .step-card {
        flex-direction: column;
    }

    /* ------------------------------------------------------- signing in

       The panel is installed to a home screen from the sign in page, so the
       sign in page has to work on the phone doing the installing. The pitch
       panel sits above the form rather than beside it. */

    .login {
        flex-direction: column;
        min-height: 100dvh;
    }

    .login-panel {
        width: 100%;
        flex-shrink: 1;
        gap: 20px;
        padding: calc(24px + env(safe-area-inset-top))
                 calc(20px + env(safe-area-inset-right)) 24px
                 calc(20px + env(safe-area-inset-left));
    }

    .login-headline {
        font-size: 28px;
    }

    .login-sub {
        font-size: 14px;
    }

    .login-form-side {
        padding: 24px calc(20px + env(safe-area-inset-right))
                 calc(24px + env(safe-area-inset-bottom)) calc(20px + env(safe-area-inset-left));
    }

    .login-form {
        width: 100%;
    }

    .login-title {
        font-size: 24px;
    }

    /* ------------------------------------------------ tables become cards */

    .table-scroll {
        overflow-x: visible;
    }

    .table {
        display: block;
        min-width: 0;
    }

    .table thead {
        display: none;
    }

    .table tbody,
    .table tr,
    .table td {
        display: block;
        width: 100%;
    }

    .table tr {
        margin: 0 0 12px 0;
        padding: 4px 14px;
        border: 1px solid var(--wr-border);
        border-radius: var(--wr-radius-card);
        background: var(--wr-white);
    }

    .table td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 12px;
        padding: 10px 0;
        border-bottom: 1px solid var(--wr-row);
        text-align: left;
    }

    .table td:last-child {
        border-bottom: none;
    }

    .table td[data-label]::before {
        content: attr(data-label);
        flex-shrink: 0;
        font-size: 12px;
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--wr-muted);
    }

    .table td.num {
        text-align: left;
    }

    /* The primary action on a stacked row is a full width button. */
    .table td[data-cell="action"] {
        display: block;
        padding: 12px 0;
    }

    .table td[data-cell="action"] .btn {
        width: 100%;
    }

    .table td[data-cell="action"] .row-end-12 {
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
    }

    .table td[data-cell="action"] form {
        display: block;
    }

    /* ------------------------------------------------------- bottom tabs */

    .tabbar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 30;
        display: flex;
        height: calc(var(--wr-tab-bar) + env(safe-area-inset-bottom));
        padding-bottom: env(safe-area-inset-bottom);
        background: var(--wr-black);
        border-top: 1px solid var(--wr-nav-card-border);
    }

    .tab {
        flex: 1 1 0;
        min-width: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 4px;
        min-height: 44px;
        text-decoration: none;
        color: var(--wr-nav);
    }

    .tab.is-active,
    .tab.is-active:hover {
        color: var(--wr-lime);
    }

    .tab-label {
        font-size: 12px;
        font-weight: 600;
    }

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

    .tab-badge {
        position: absolute;
        top: -6px;
        right: -10px;
        min-width: 18px;
        height: 18px;
        padding: 0 4px;
        border-radius: 999px;
        background: var(--wr-lime);
        color: var(--wr-black);
        font-size: 11px;
        font-weight: 700;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* --------------------------------------------------------- the sheet */

    .sheet-backdrop {
        position: fixed;
        inset: 0;
        z-index: 40;
        display: flex;
        align-items: flex-end;
        background: rgba(17, 17, 17, 0.6);
    }

    .sheet {
        width: 100%;
        max-height: 88dvh;
        overflow-y: auto;
        padding: 16px calc(16px + env(safe-area-inset-right))
                 calc(16px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left));
        border-radius: 18px 18px 0 0;
        background: var(--wr-white);
        display: flex;
        flex-direction: column;
        gap: 2px;
    }

    .sheet-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 16px;
        padding-bottom: 4px;
    }

    .sheet-title {
        font-size: 18px;
        font-weight: 600;
    }

    .sheet-note {
        font-size: 13px;
        color: var(--wr-muted);
        padding-bottom: 8px;
    }

    .sheet-hint {
        font-size: 13px;
        color: var(--wr-muted);
        padding: 0 8px 8px 8px;
    }

    .sheet-item {
        display: flex;
        align-items: center;
        gap: 12px;
        width: 100%;
        min-height: 52px;
        padding: 0 8px;
        border: none;
        border-radius: var(--wr-radius-input);
        background: none;
        font-family: inherit;
        font-size: 15px;
        font-weight: 600;
        text-align: left;
        text-decoration: none;
        color: var(--wr-black);
        cursor: pointer;
    }

    .sheet form {
        margin: 0;
    }

    /* --------------------------------------------------- the install bar */

    .install-bar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: calc(var(--wr-tab-bar) + env(safe-area-inset-bottom));
        z-index: 35;
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 12px calc(12px + env(safe-area-inset-right)) 12px calc(16px + env(safe-area-inset-left));
        background: var(--wr-lime);
        color: var(--wr-black);
        border-top: 1px solid var(--wr-black);
    }

    .install-text {
        flex-grow: 1;
        min-width: 0;
        font-size: 14px;
        font-weight: 600;
    }

    .install-actions {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-shrink: 0;
    }

    .install-bar .btn-lime {
        background: var(--wr-black);
        color: var(--wr-lime);
    }

    .install-bar .btn-icon {
        background: transparent;
        border-color: var(--wr-black);
    }

    /* ------------------------------------------------ the inbox, two views */

    .inbox-card {
        flex-direction: column;
        border: none;
        border-radius: 0;
        background: transparent;
        overflow: visible;
    }

    .inbox-list {
        width: 100%;
        border-right: none;
        border: 1px solid var(--wr-border);
        border-radius: var(--wr-radius-card);
        background: var(--wr-white);
    }

    /* Which of the two is showing comes from the address, so the back button is
       an ordinary link and the two views are two ordinary pages. */
    .inbox-card[data-view="thread"] .inbox-list,
    .inbox-card[data-view="list"] .thread-pane,
    .inbox-card[data-view="list"] > .inbox-side {
        display: none;
    }

    .inbox-card[data-view="thread"] .thread-pane {
        flex-grow: 1;
        min-height: 0;
        border: 1px solid var(--wr-border);
        border-radius: var(--wr-radius-card);
        overflow: hidden;
    }

    .thread-back {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        flex-shrink: 0;
        margin-left: -8px;
        border-radius: 999px;
        color: var(--wr-black);
    }

    /* The Inbox is the one full height screen, and on a phone the page header
       above it is a title the phone's own bar already carries. Giving those
       ninety pixels to the thread is what keeps the reply box on screen when
       the keyboard is up. */
    .shell-fill .page-head {
        display: none;
    }

    .thread-head {
        flex-wrap: wrap;
        gap: 8px;
        padding: 8px 12px;
    }

    .thread-head .card-note {
        display: none;
    }

    /* The name takes what is left rather than what it wants, so the controls
       stay on the same line as it instead of wrapping onto their own. */
    .thread-head .grow {
        flex: 1 1 0;
    }

    .thread-head-name {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* The controls stay beside the name rather than taking a row each, because
       a header that is a third of the screen is a header nobody wanted. */
    .thread-head .row-10 {
        flex-wrap: nowrap;
        gap: 8px;
    }

    .thread-head .chip {
        display: none;
    }

    /* Narrower and a touch smaller in the type, and still 44px tall, because
       nothing anybody taps is ever allowed to be smaller than that. */
    .thread-head .btn {
        flex-grow: 0;
        padding: 0 12px;
        font-size: 13px;
        white-space: nowrap;
    }

    .thread {
        padding: 12px;
    }

    .bubble {
        max-width: 84%;
    }

    /* The right hand panel, folded up. The panel itself is moved in here by the
       screen's own script, so there is one of it rather than two. */
    .lead-details {
        display: block;
        border-bottom: 1px solid var(--wr-border);
        background: var(--wr-white);
    }

    .lead-details-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        min-height: 48px;
        padding: 0 14px;
        font-size: 14px;
        font-weight: 600;
        cursor: pointer;
        list-style: none;
    }

    .lead-details-head::-webkit-details-marker {
        display: none;
    }

    .lead-details-body {
        max-height: 50dvh;
        overflow-y: auto;
        padding: 0 14px 14px 14px;
    }

    .inbox-side {
        width: 100%;
        border-left: none;
        padding: 0;
        overflow: visible;
    }

    /* The reply bar stays above the home bar, and dvh is what keeps it above
       the keyboard as well. */
    .thread-bar,
    .thread-bar-reply {
        flex-wrap: wrap;
        padding: 10px 12px calc(10px + env(safe-area-inset-bottom)) 12px;
    }

    /* The reply box and its button share one row whatever else wraps, so the
       bar is one control tall and stays above the keyboard. */
    .thread-bar-reply {
        flex-wrap: nowrap;
        gap: 8px;
    }

    .thread-bar-reply .input {
        flex-grow: 1;
        min-width: 0;
    }

    .thread-bar-reply .btn {
        flex-grow: 0;
        flex-shrink: 0;
        white-space: nowrap;
    }

    .thread-bar .btn,
    .thread-bar .card-note {
        width: 100%;
    }

    /* ------------------------------------------------- on the website now */

    .presence-row,
    .chat-row-main {
        flex-wrap: wrap;
    }

    .presence-actions {
        width: 100%;
    }

    .presence-actions .btn {
        flex-grow: 1;
    }

    .chat-row-main {
        gap: 10px;
    }

    .chat-row .item-time {
        width: auto;
    }
}

/* A sheet that is open holds the page behind it still, so a thumb on the sheet
   does not scroll the list underneath. */
html.is-sheet-open,
html.is-sheet-open body {
    overflow: hidden;
}

/* Nothing on a touch screen may be reachable by hover alone, because there is
   no hover to reach it with. */
@media (hover: none) {
    .nav-item:hover,
    .tab:hover {
        color: inherit;
    }
}

/* ============================================================== fix pass

   The setup page's two columns, the Inbox's three filters, the lead details
   panel filling in live, and the panel's own alerts. The same tokens and the
   same kinds of block as everything above. */

/* A notice inside the page body rather than above it, so it lines up with the
   cards under it. */
.panel-notice-inline {
    margin: 0;
}

/* The Super Admin setup page: a flexible left column and a right column of
   exactly 380px at every desktop width. It is a desktop tool. */
.grid-setup {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 20px;
    align-items: start;
}

.setup-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
}

.stat-compact {
    padding: 14px;
    gap: 4px;
}

.stat-compact .stat-label {
    font-size: 12px;
}

.stat-compact .stat-value {
    font-size: 24px;
}

.stat-compact .stat-note {
    font-size: 12px;
}

/* The last AI error, in full, wrapping rather than cut. */
.setup-error {
    padding: 10px 12px;
    border: 1px solid var(--wr-border-strong);
    border-radius: var(--wr-radius-input);
    background: var(--wr-thread);
    font-size: 13px;
    line-height: 1.5;
    overflow-wrap: anywhere;
}

/* A small table that fits its card rather than scrolling sideways. */
.table-fit {
    min-width: 0;
    table-layout: fixed;
}

.table-fit th,
.table-fit td {
    padding: 10px 8px;
}

.table-fit th:first-child,
.table-fit td:first-child {
    padding-left: 0;
}

.table-fit th:last-child,
.table-fit td:last-child {
    padding-right: 0;
}

/* A step's text keeps a readable width. When its buttons do not fit beside
   it they drop underneath, on the right, rather than squeezing the words. */
.grid-setup .card-row {
    flex-wrap: wrap;
}

.grid-setup .card-row > .grow {
    flex-basis: 240px;
}

.grid-setup .card-row > .shrink-0 {
    flex-wrap: wrap;
    justify-content: flex-end;
    margin-left: auto;
}

/* Numbers line up on the right in the small table, headers included. */
.table-fit th.num {
    text-align: right;
}

/* On a screen tall enough to hold them, the Plan and Limits cards stay in view
   beside the longer left column rather than leaving it to scroll on its own. */
@media (min-height: 800px) {
    .grid-setup > :last-child {
        position: sticky;
        top: 24px;
    }
}

/* The black sidebar runs the full height of the page at any length: the
   sidebar itself is sticky and one viewport tall, and this strip behind it is
   as tall as the page, so no length of page ever shows the ground beneath it. */
.shell::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: var(--wr-sidebar-width);
    background: var(--wr-black);
}

/* An input with its button beside it. Both are 44px, so they line up. */
.setup-inline {
    display: flex;
    align-items: flex-end;
    gap: 10px;
}

.setup-inline .btn {
    flex-shrink: 0;
}

/* A button that fills its row, and a form that lets it. */
.btn-block {
    width: 100%;
}

form.btn-grow {
    display: flex;
    min-width: 0;
}

/* Where nobody knows where a chat is: said, in muted text, with no map link. */
.conv-place-unknown,
.fact-value-unknown,
.item-sub-unknown,
.cell-muted {
    color: var(--wr-muted);
    font-weight: 400;
}

.cell-muted {
    font-size: 13px;
}

.conv-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* An empty mark keeps its tick, hidden, so an answer arriving over the socket
   only has to change the class. */
.fact-mark-empty svg {
    visibility: hidden;
}

/* A returning visitor's earlier chats, in the lead details panel. */
.previous-chat {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-height: 44px;
    padding: 8px 12px;
    border: 1px solid var(--wr-row);
    border-radius: var(--wr-radius-input);
    font-size: 13px;
    text-decoration: none;
    color: var(--wr-black);
}

.previous-chat:hover {
    border-color: var(--wr-border-strong);
}

/* A row that has just changed, once. */
@keyframes wrflash {
    0% { background-color: var(--wr-lime); }
    100% { background-color: transparent; }
}

.is-flash {
    animation: wrflash 1.6s ease-out;
    border-radius: var(--wr-radius-input);
}

@media (prefers-reduced-motion: reduce) {
    .is-flash {
        animation: none;
        outline: 2px solid var(--wr-lime);
    }
}

/* The panel's own alert: top right on a desktop. */
.toast-stack {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 380px;
    max-width: calc(100vw - 32px);
    pointer-events: none;
}

.toast {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 14px 14px 18px;
    border-radius: var(--wr-radius-card);
    background: var(--wr-black);
    color: var(--wr-white);
}

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

.toast-title {
    font-size: 14px;
    font-weight: 600;
}

.toast-note {
    font-size: 13px;
    color: var(--wr-nav);
}

.toast-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.toast .btn-icon {
    background: transparent;
    color: var(--wr-white);
    border-color: var(--wr-nav-card-border);
}

/* On a phone: across the top, under the phone's own top bar. There is no
   sidebar under 900px, so there is no strip behind one either. */
@media (max-width: 899px) {
    .shell::before {
        display: none;
    }

    .toast-stack {
        top: calc(var(--wr-top-bar) + env(safe-area-inset-top) + 8px);
        left: calc(16px + env(safe-area-inset-left));
        right: calc(16px + env(safe-area-inset-right));
        width: auto;
        max-width: none;
    }
}

/* ============================================================== free plan

   The free human only plan, the quiet Dashboard and the reliable alerts. The
   same tokens and the same kinds of block as everything above. */

/* The title and the pill beside it. */
.page-title-row {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

/* A tile that opens the page behind its figure. It is a link, so it gets a
   pointer, and a focus ring anybody using a keyboard can see. */
.stat-link {
    text-decoration: none;
    cursor: pointer;
}

.stat-link:hover {
    border-color: var(--wr-border-strong);
    color: var(--wr-black);
}

.stat-link:focus-visible {
    outline: 3px solid var(--wr-lime);
    outline-offset: 2px;
    border-color: var(--wr-black);
}

/* "On the website now": a small dot, the count and four words, in one pill
   that takes no vertical space of its own. Grey and still at zero, lime with
   a soft pulse above zero. */
.presence-pill-wrap {
    position: relative;
}

.presence-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 32px;
    padding: 0 12px 0 10px;
    border-radius: 999px;
    border: 1px solid var(--wr-border-strong);
    background: var(--wr-white);
    color: var(--wr-muted);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.presence-pill:focus-visible {
    outline: 3px solid var(--wr-lime);
    outline-offset: 2px;
}

.presence-dot {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--wr-dash);
}

.presence-pill[data-live="on"] {
    border-color: var(--wr-black);
    color: var(--wr-black);
}

.presence-pill[data-live="on"] .presence-dot {
    background: var(--wr-lime);
    box-shadow: 0 0 0 0 rgba(194, 236, 64, 0.7);
    animation: wr-pulse 2s ease-out infinite;
}

.presence-pill[data-live="off"] .presence-words::after {
    content: ", live view unavailable";
    font-weight: 400;
}

@keyframes wr-pulse {
    0% { box-shadow: 0 0 0 0 rgba(194, 236, 64, 0.7); }
    70% { box-shadow: 0 0 0 8px rgba(194, 236, 64, 0); }
    100% { box-shadow: 0 0 0 0 rgba(194, 236, 64, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .presence-pill[data-live="on"] .presence-dot {
        animation: none;
    }
}

/* The small panel the pill opens, over the page rather than in it. */
.presence-panel {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    z-index: 25;
    width: 420px;
    max-width: calc(100vw - 32px);
    max-height: 60vh;
    overflow-y: auto;
    background: var(--wr-white);
    border: 1px solid var(--wr-border);
    border-radius: var(--wr-radius-card);
    box-shadow: 0 18px 40px rgba(17, 17, 17, 0.14);
}

.presence-panel-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 14px 16px;
}

.presence-empty {
    padding: 14px 16px;
    border-top: 1px solid var(--wr-row);
    font-size: 13px;
    color: var(--wr-muted);
}

.presence-panel .presence-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-top: 1px solid var(--wr-row);
}

/* One compact row about the widget, so a quiet Dashboard is the tiles and the
   table and very little else. */
.dash-strip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 20px;
}

.dash-strip-text {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.dash-strip-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

/* The visitors table: every row opens the chat. */
.table-visitors {
    min-width: 760px;
}

.row-link {
    cursor: pointer;
}

.row-link:hover td {
    background: var(--wr-thread);
}

.row-link-main {
    text-decoration: none;
    color: var(--wr-black);
}

.row-link-main:focus-visible {
    outline: 3px solid var(--wr-lime);
    outline-offset: 2px;
}

/* The status block at the top of the Alerts page: exactly one of four lines,
   each with the one thing that fixes it. */
.alert-status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 20px;
}

.alert-status-text {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.alert-status-dot {
    width: 10px;
    height: 10px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--wr-dash);
}

.alert-status[data-state="on"] .alert-status-dot {
    background: var(--wr-lime);
}

.alert-status[data-state="off"] .alert-status-dot,
.alert-status[data-state="blocked"] .alert-status-dot {
    background: var(--wr-black);
}

/* The delivery log: a small table that fits its card. */
.delivery-error {
    font-size: 13px;
    color: var(--wr-muted);
    overflow-wrap: anywhere;
}

@media (max-width: 899px) {
    .presence-panel {
        position: fixed;
        top: calc(var(--wr-top-bar) + env(safe-area-inset-top) + 8px);
        left: 16px;
        right: 16px;
        width: auto;
        max-width: none;
    }

    .presence-panel .presence-row {
        flex-wrap: wrap;
    }

    .dash-strip {
        flex-direction: column;
        align-items: stretch;
    }

    .dash-strip-actions {
        flex-wrap: wrap;
    }

    .dash-strip-actions .btn {
        flex-grow: 1;
    }

    .table-visitors {
        min-width: 0;
    }

    .alert-status {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ------------------------------------------------ human chat, unread rows

   A chat with visitor messages nobody has opened since they arrived is bold
   with a lime dot in front of the name. Opening it takes both off. */

.conv.is-unread .conv-name,
.conv.is-unread .conv-preview {
    font-weight: 700;
    color: var(--wr-black);
}

.conv-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--wr-lime);
    border: 1px solid var(--wr-black);
    vertical-align: middle;
}

/* Who is handling the chat, above the reply bar, when it is somebody else. */
.thread-handling {
    padding: 10px 20px;
    font-size: 13px;
    font-weight: 500;
    color: var(--wr-muted);
    background: var(--wr-ground);
    border-top: 1px solid var(--wr-border);
}

/* ------------------------------------------------------ the locked card */

.card-locked .card-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

.lock-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--wr-ground);
    border: 1px solid var(--wr-border);
    color: var(--wr-black);
}

/* ------------------------------------------------ the Super Admin switch */

.switch {
    position: relative;
    width: 48px;
    height: 28px;
    padding: 0;
    border-radius: 999px;
    border: 1px solid var(--wr-border-strong);
    background: var(--wr-white);
    cursor: pointer;
    min-height: 44px;
    min-width: 48px;
    height: 44px;
    display: inline-flex;
    align-items: center;
}

.switch-knob {
    position: absolute;
    left: 3px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--wr-border-strong);
    transition: left 0.15s ease, background 0.15s ease;
}

.switch.is-on {
    background: var(--wr-black);
    border-color: var(--wr-black);
}

.switch.is-on .switch-knob {
    left: 21px;
    background: var(--wr-lime);
}

/* ------------------------------------------------- lead capture and profile

   The three way setting on the Lead capture page, and the quick actions on a
   visitor message in the Inbox. Both are built from the same pieces the rest of
   the panel uses: pill shapes, the lime for what is chosen, and nothing else. */

.choice {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 16px;
    border-radius: 999px;
    border: 1px solid var(--wr-border-strong);
    background: var(--wr-white);
    font-size: 14px;
    cursor: pointer;
}

.choice input {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--wr-black);
}

.choice:has(input:checked) {
    background: var(--wr-lime);
    border-color: var(--wr-black);
    font-weight: 600;
}

/* The preview of the form the widget shows before a chat starts. */
.preview-send-wide {
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--wr-lime);
    border: 1px solid var(--wr-black);
    font-size: 14px;
    font-weight: 600;
    color: var(--wr-black);
}

/* "Save as name", "Save as phone", "Save as email" on one of the visitor's own
   messages. It is closed until somebody wants it, so a thread reads as a thread. */
.quick-actions {
    align-self: flex-start;
}

.quick-actions-open {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 28px;
    padding: 0 10px;
    border-radius: 999px;
    border: 1px solid var(--wr-border-strong);
    background: var(--wr-white);
    font-size: 12px;
    color: var(--wr-muted);
    cursor: pointer;
    list-style: none;
}

.quick-actions-open::-webkit-details-marker {
    display: none;
}

.quick-actions-menu {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 6px;
    padding: 8px;
    border-radius: 12px;
    border: 1px solid var(--wr-border);
    background: var(--wr-white);
}

.quick-action {
    min-height: 44px;
    padding: 0 12px;
    border-radius: 10px;
    border: 1px solid var(--wr-border);
    background: var(--wr-white);
    font-family: inherit;
    font-size: 13px;
    color: var(--wr-black);
    text-align: left;
    cursor: pointer;
}

.quick-action:hover,
.quick-action:focus {
    background: var(--wr-ground);
}
