/* Copied unchanged from the PropertyAdverts project (resources/css/v3.css, 22 Oct 2026). Ticket-only rules live in tickets.css. */
/*
 * V3 staff dashboard — the whole stylesheet.
 *
 * Deliberately standalone. It imports nothing: not Tailwind, not app.css, not
 * dashboard.css. The current dashboards carry roughly 50,000 lines of CSS
 * between them, and cleaning that up has never been finishable because dead
 * rules are invisible — deleting one is a risk and leaving it costs nothing
 * today. This file starts empty of that history and stays honest by being
 * measured: `php artisan v3:css-audit` reports every class defined here that no
 * page uses, every class a page uses that is not defined here, and the size
 * against a budget. Run it before committing.
 *
 * The rules that keep it small:
 *
 *   1. No page-level CSS. A style that exists for one page is a component that
 *      has not been named yet.
 *   2. A modifier class must do something. An unstyled `--queued` is how the
 *      next person justifies adding a rule for it.
 *   3. Colour, spacing and radius come from the tokens below. A hex code inside
 *      a component is a bug.
 *   4. When markup stops using a rule, the rule goes in the same commit.
 *
 * Layout and behaviour follow the prototype at /v3, which was verified at 320,
 * 360, 390, 430, 768, 1024 and 1440.
 */

:root {
    --navy: #0f2a52;
    --navy-dark: #081a38;
    --navy-soft: rgb(15 42 82 / 0.06);
    --gold: #9b7424;
    --gold-dark: #765316;
    --gold-soft: rgb(155 116 36 / 0.12);
    --page: #f7f5f0;
    --card: #ffffff;
    --card-soft: #fbfaf6;
    --ink: #0a0e14;
    --body: #333d4d;
    --muted: #5c6471;
    --line: rgb(15 42 82 / 0.11);
    --line-strong: rgb(15 42 82 / 0.2);

    /* How wide the dashboard runs. Three things have to agree on this — the
       top bar, the page body and the customer context bar — and they were
       three separate literals. On a 1440px screen 1180 left the detail pages
       cramped, with two columns squeezed into less room than one list needed. */
    --shell: 1440px;

    --crit: #b3261e;
    --crit-bg: #fdecea;
    --warn: #a35a00;
    --warn-bg: #fdf1de;
    --ok: #1d7a44;
    --ok-bg: #e4f4ea;
    --info: #1a5fb4;
    --info-bg: #e8f0fb;

    --shadow-sm: 0 1px 2px rgb(15 42 82 / 0.05);
    --shadow: 0 10px 30px -18px rgb(15 42 82 / 0.45);
    --radius: 14px;
    --bar-h: 60px;
    --dock-h: 62px;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --navy: #0d1726;
        --navy-dark: #070f1a;
        --navy-soft: rgb(226 236 250 / 0.07);
        --gold: #d6a750;
        --gold-dark: #b98c32;
        --gold-soft: rgb(214 167 80 / 0.16);
        --page: #0b1220;
        --card: #131d2c;
        --card-soft: #18232f;
        --ink: #eef3fa;
        --body: #c3cede;
        --muted: #98a8bf;
        --line: rgb(226 236 250 / 0.12);
        --line-strong: rgb(226 236 250 / 0.22);
        --crit: #ff9c93; --crit-bg: #3b1a17;
        --warn: #efb765; --warn-bg: #3a2810;
        --ok: #7cd7a4; --ok-bg: #12301f;
        --info: #8fbcf5; --info-bg: #14283f;
        --shadow: 0 10px 30px -18px rgb(0 0 0 / 0.75);
    }
}



:root[data-theme="dark"] {
    --navy: #0d1726; --navy-dark: #070f1a; --navy-soft: rgb(226 236 250 / 0.07);
    --gold: #d6a750; --gold-dark: #b98c32; --gold-soft: rgb(214 167 80 / 0.16);
    --page: #0b1220; --card: #131d2c; --card-soft: #18232f;
    --ink: #eef3fa; --body: #c3cede; --muted: #98a8bf;
    --line: rgb(226 236 250 / 0.12); --line-strong: rgb(226 236 250 / 0.22);
    --crit: #ff9c93; --crit-bg: #3b1a17;
    --warn: #efb765; --warn-bg: #3a2810;
    --ok: #7cd7a4; --ok-bg: #12301f;
    --info: #8fbcf5; --info-bg: #14283f;
    --shadow: 0 10px 30px -18px rgb(0 0 0 / 0.75);
}

* { box-sizing: border-box; }

/*
 * These pages used to render inside the artifact viewer, which supplied its own
 * reset. Served as plain files they do not, and the omission was not cosmetic:
 * any class that sets `display` beats the browser's own `[hidden]` rule, so the
 * advert page showed all five states' action buttons at once while the plain
 * paragraphs around them hid correctly.
 */
[hidden] { display: none !important; }
html { scroll-padding-top: calc(var(--bar-h) + 12px); }
img { max-width: 100%; }

body {
    margin: 0;
    background: var(--page);
    color: var(--ink);
    font-family: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: 15px;
    line-height: 1.55;
    padding-bottom: calc(var(--dock-h) + env(safe-area-inset-bottom, 0px) + 12px);
}

@media (min-width: 900px) {
    body { padding-bottom: 0; }
}



a { color: inherit; }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; border-radius: 6px; }

/* ---------- top bar ----------
   White, like the portal this follows: the accent is spent on the active stop
   and on primary actions, not on a slab of colour across the top. */

.v3-topbar {
    position: sticky;
    top: env(safe-area-inset-top, 0px);
    z-index: 40;
    background: var(--card);
    color: var(--ink);
    border-bottom: 1px solid var(--line);
}

.v3-topbar__inner {
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: 16px;
    min-height: var(--bar-h);
    display: flex;
    align-items: center;
    gap: 14px;
}

.v3-brand {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-weight: 700;
    letter-spacing: -0.01em;
    text-decoration: none;
    white-space: nowrap;
}
.v3-brand__mark {
    width: 26px; height: 26px; flex: 0 0 auto;
    border: 2px solid var(--gold); transform: rotate(45deg); border-radius: 5px;
}
.v3-brand__b { color: var(--gold-dark); }
.v3-brand__div { color: var(--muted); font-weight: 600; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; padding-left: 10px; border-left: 1px solid var(--line); margin-left: 2px; }

.v3-stops { display: none; gap: 2px; margin-left: 6px; }
@media (min-width: 900px) { .v3-stops { display: flex; }
}



.v3-stop {
    appearance: none; background: none; border: 0; cursor: pointer;
    color: var(--body);
    font: inherit; font-size: 14px; font-weight: 600;
    padding: 8px 14px; border-radius: 999px;
    display: inline-flex; align-items: center; gap: 6px;
    text-decoration: none;
}
.v3-stop:hover { background: var(--navy-soft); color: var(--ink); }
.v3-stop[aria-expanded="true"] { background: var(--navy-soft); color: var(--ink); }
.v3-stop.is-current { background: var(--gold-soft); color: var(--gold-dark); }
.v3-stop__chev { opacity: 0.55; }

.v3-topbar__spacer { flex: 1 1 auto; }

.v3-search {
    position: relative;
    flex: 0 1 300px;
    display: none;
}
@media (min-width: 900px) { .v3-search { display: block; }
}


.v3-search input {
    width: 100%; font: inherit; font-size: 14px;
    padding: 9px 14px 9px 36px;
    border-radius: 999px; border: 1px solid var(--line-strong);
    background: var(--card-soft); color: var(--ink);
}
.v3-search input::placeholder { color: var(--muted); }
.v3-search__icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); }

.v3-iconbtn {
    appearance: none; border: 1px solid var(--line); background: var(--card);
    color: var(--body); width: 38px; height: 38px; border-radius: 999px;
    display: inline-grid; place-items: center; cursor: pointer; position: relative;
}
.v3-iconbtn:hover { background: var(--card-soft); color: var(--ink); }
.v3-iconbtn__badge {
    position: absolute; top: -4px; right: -4px;
    background: var(--crit); color: #fff;
    font-size: 10px; font-weight: 700; line-height: 1;
    padding: 3px 5px; border-radius: 999px;
}

/* ---------- fly-out ---------- */

.v3-flyout {
    /* Fixed, not absolute: the coordinates come from getBoundingClientRect(),
       which is viewport-relative, and the trigger lives in a sticky bar. An
       absolutely positioned panel would drift down the page as it scrolled. */
    position: fixed; z-index: 60;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 10px; min-width: 268px;
}
.v3-flyout__title { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); font-weight: 700; padding: 6px 8px 8px; }
.v3-flyout a {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 9px 10px; border-radius: 9px; text-decoration: none;
}
.v3-flyout a:hover { background: var(--navy-soft); }
.v3-flyout a strong { display: block; font-size: 14px; font-weight: 600; }
.v3-flyout a small { display: block; color: var(--muted); font-size: 12.5px; }
.v3-flyout__count {
    margin-left: auto; align-self: center;
    background: var(--crit-bg); color: var(--crit);
    font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
}

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

.v3-wrap { max-width: var(--shell); margin-inline: auto; padding-inline: 16px; padding-block: 22px 40px; }

.v3-pagehead { display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: flex-end; margin-bottom: 20px; }
.v3-pagehead h1 { margin: 0; font-size: clamp(22px, 3.6vw, 30px); letter-spacing: -0.02em; text-wrap: balance; }
.v3-pagehead p { margin: 4px 0 0; color: var(--muted); max-width: 62ch; }

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

.v3-cards { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(310px, 100%), 1fr)); align-items: start; }

.v3-card {
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.v3-card__head { display: flex; align-items: center; gap: 10px; padding: 14px 16px 0; }
.v3-card__head h2 { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
.v3-card__n { margin-left: auto; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
.v3-card--crit .v3-card__n { color: var(--crit); }
.v3-card--warn .v3-card__n { color: var(--warn); }
.v3-card__sub { margin: 2px 16px 0; color: var(--muted); font-size: 13px; }
.v3-card__rows { list-style: none; margin: 12px 0 0; padding: 0; border-top: 1px solid var(--line); }
.v3-card__rows li + li { border-top: 1px solid var(--line); }
.v3-card__rows a { display: block; padding: 11px 16px; text-decoration: none; }
.v3-card__rows a:hover { background: var(--card-soft); }
.v3-card__rowtop { display: flex; gap: 8px; align-items: baseline; }
.v3-card__rowtop strong { font-size: 14px; font-weight: 600; }
.v3-card__age { margin-left: auto; font-size: 12px; color: var(--muted); white-space: nowrap; }
.v3-card__rowsub { display: block; color: var(--muted); font-size: 12.5px; margin-top: 1px; }
.v3-card__foot { padding: 11px 16px; border-top: 1px solid var(--line); background: var(--card-soft); }
.v3-card__foot a { font-size: 13px; font-weight: 600; color: var(--gold-dark); text-decoration: none; }

.v3-pill {
    display: inline-block; font-size: 11.5px; font-weight: 700;
    padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
.v3-pill--crit { background: var(--crit-bg); color: var(--crit); }
.v3-pill--warn { background: var(--warn-bg); color: var(--warn); }
.v3-pill--ok { background: var(--ok-bg); color: var(--ok); }
.v3-pill--info { background: var(--info-bg); color: var(--info); }

/* ---------- all clear ---------- */

.v3-allclear {
    background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 34px 24px; text-align: center; box-shadow: var(--shadow-sm);
}
.v3-allclear h2 { margin: 0 0 4px; font-size: 19px; }
.v3-allclear p { margin: 0 auto; color: var(--muted); max-width: 46ch; }

/* ---------- dock (phones) ---------- */

.v3-dock {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    background: var(--card); color: var(--ink);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 20px -14px rgb(15 42 82 / 0.4);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    display: flex;
}
@media (min-width: 900px) { .v3-dock { display: none; }
}


.v3-dock a, .v3-dock button {
    flex: 1 1 0; appearance: none; background: none; border: 0; cursor: pointer;
    color: var(--muted); font: inherit; font-size: 10.5px; font-weight: 600;
    height: var(--dock-h); display: grid; place-items: center; gap: 3px; text-decoration: none;
    position: relative;
}
.v3-dock a.is-current { color: var(--gold-dark); }
.v3-dock a.is-current::before {
    content: ""; position: absolute; inset: 6px 10px auto; height: 34px;
    border-radius: 12px; background: var(--gold-soft); z-index: -1;
}

/* ---------- sheet (phones) ---------- */

.v3-scrim { position: fixed; inset: 0; z-index: 55; background: rgb(8 26 56 / 0.5); border: 0; }
.v3-sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 56;
    background: var(--card); color: var(--ink);
    border-radius: 18px 18px 0 0; box-shadow: var(--shadow);
    padding: 8px 10px calc(14px + env(safe-area-inset-bottom, 0px));
    max-height: 78vh; overflow: auto;
}
.v3-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; }
}



/* ---------- More drawer ---------- */

.v3-drawer {
    position: fixed; top: 0; right: 0; bottom: 0; left: auto;
    width: min(420px, 100%);
    border-radius: 0; border-width: 0 0 0 1px;
    padding: 0 10px calc(20px + env(safe-area-inset-bottom, 0px));
    overflow: auto;
}
.v3-drawer__head {
    position: sticky; top: 0; background: var(--card); z-index: 1;
    display: flex; gap: 12px; align-items: flex-start;
    padding: 18px 8px 14px; border-bottom: 1px solid var(--line); margin-bottom: 6px;
}
.v3-drawer__head h2 { margin: 2px 0 0; font-size: 21px; letter-spacing: -0.02em; }
.v3-drawer__eyebrow { margin: 0; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold-dark); font-weight: 700; }
.v3-drawer__sub { margin: 2px 0 0; color: var(--muted); font-size: 13px; }
.v3-drawer__head .v3-iconbtn { margin-left: auto; }

/* ---------- home: eyebrow, quiet queues, demo states ---------- */

.v3-eyebrow { margin: 0 0 2px; font-size: 11px; letter-spacing: 0.11em; text-transform: uppercase; color: var(--gold-dark); font-weight: 700; }

.v3-quiet { padding: 0; }

/* ---------- dark + accent cards ---------- */

.v3-card--dark { background: var(--navy-dark); color: #fff; border-color: transparent; }
.v3-card--dark .v3-card__head h2 { color: rgb(255 255 255 / 0.78); font-size: 13px; font-weight: 600; letter-spacing: 0.02em; }

.v3-card--accent { background: var(--gold-soft); border-color: rgb(155 116 36 / 0.3); padding: 14px 16px 16px; }
.v3-card--accent .v3-eyebrow { margin-bottom: 4px; }
.v3-card--accent .v3-card__sub { margin: 0; }

/* ---------- phone search ---------- */

.v3-iconbtn--search { display: inline-grid; }
@media (min-width: 900px) { .v3-iconbtn--search { display: none; }
}



/*
 * Search opens from the TOP on a phone, never the bottom. A bottom sheet puts
 * the field directly above the on-screen keyboard, so the keyboard covers the
 * results the moment you start typing - you type blind and see nothing until
 * you dismiss it. Anchored under the top bar, the field sits under your thumb's
 * reach but the results fill the space the keyboard does not take.
 */
.v3-sheet {
    position: fixed; left: 0; right: 0; bottom: auto;
    top: calc(var(--bar-h) + env(safe-area-inset-top, 0px));
    border-radius: 0 0 18px 18px; border-width: 0 0 1px;
    max-height: calc(100dvh - var(--bar-h) - 24px); overflow: auto;
    padding: 12px 10px 14px;
}
@media (min-width: 900px) {
    .v3-sheet { left: auto; right: 16px; top: calc(var(--bar-h) + 10px); width: 360px; border-radius: var(--radius); border-width: 1px; }
}


.v3-sheet__input {
    width: 100%; font: inherit; font-size: 16px;
    padding: 11px 14px; margin-bottom: 4px;
    border-radius: 11px; border: 1px solid var(--line-strong);
    background: var(--card-soft); color: var(--ink);
}

/* ---------- menu icons ---------- */

/*
 * Every menu row carries an icon. It is not decoration: on a menu of ten
 * near-identical two-line rows the icon is what you actually navigate by, so
 * you stop reading the list after the second or third visit and start aiming
 * at a shape.
 */
.v3-mi { flex: none; width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; background: var(--navy-soft); color: var(--navy); }
.v3-mi svg { width: 16px; height: 16px; }
.v3-mi--gold { background: var(--gold-soft); color: var(--gold-dark); }
.v3-mi--crit { background: var(--crit-bg); color: var(--crit); }
.v3-mi--ok   { background: var(--ok-bg);   color: var(--ok); }
.v3-mi--warn { background: var(--warn-bg); color: var(--warn); }
.v3-flyout a { align-items: center; }
.v3-flyout a > span:not([class]) { min-width: 0; }

/* ---------- fly-outs on a phone ---------- */

/*
 * A menu opened from the dock opens UPWARDS, sitting on top of the dock with a
 * caret aimed at the button that opened it, and that button stays lit for as
 * long as the menu is open. A panel that opens with no visible tie to its
 * trigger leaves you guessing which button you pressed, and one that covers the
 * dock hides the fact that you are still in a menu at all.
 */
/* Opened from the dock: sits on the dock, caret aimed at the button. */
.v3-flyout.is-dockmenu {
    position: fixed; left: 8px; right: 8px; top: auto; min-width: 0;
    bottom: calc(var(--dock-h) + env(safe-area-inset-bottom, 0px) + 11px);
    max-height: calc(100dvh - var(--dock-h) - var(--bar-h) - 40px);
    overflow: auto;
}
.v3-flyout.is-dockmenu::after {
    content: ""; position: absolute; bottom: -7px; left: var(--caret-x, 50%);
    width: 14px; height: 14px; transform: translateX(-50%) rotate(45deg);
    background: var(--card);
    border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}

/*
 * Opened from the top bar on a phone - notifications, the account menu - drops
 * from the top for the same reason search does: it is anchored to a control you
 * can see, and nothing it shows can end up behind the keyboard.
 */
.v3-flyout.is-topmenu {
    position: fixed; left: 8px; right: 8px; bottom: auto; min-width: 0;
    top: calc(var(--bar-h) + env(safe-area-inset-top, 0px) + 6px);
    max-height: calc(100dvh - var(--bar-h) - 80px); overflow: auto;
    width: auto;
}
.v3-flyout.is-topmenu::after {
    content: ""; position: absolute; top: -7px; left: var(--caret-x, 50%);
    width: 14px; height: 14px; transform: translateX(-50%) rotate(45deg);
    background: var(--card);
    border-left: 1px solid var(--line); border-top: 1px solid var(--line);
}
.v3-flyout.is-topmenu .v3-notif__list { max-height: none; }

.v3-iconbtn.is-open { background: var(--gold-soft); color: var(--gold-dark); }

.v3-dock .is-current, .v3-dock .is-open { color: var(--gold-dark); }
.v3-dock .is-current::before, .v3-dock .is-open::before {
    content: ""; position: absolute; inset: 6px 10px auto; height: 34px;
    border-radius: 12px; background: var(--gold-soft); z-index: -1;
}

/* ---------- notifications ---------- */

.v3-notif { width: min(384px, calc(100vw - 16px)); padding: 0; }
.v3-notif__head { display: flex; align-items: center; gap: 10px; padding: 13px 14px 11px; border-bottom: 1px solid var(--line); }
.v3-notif__head h2 { margin: 0; font-size: 15px; }
.v3-notif__list { max-height: min(60vh, 460px); overflow: auto; padding: 6px; }
.v3-notif__list a { align-items: flex-start; padding: 10px; }

/* ---------- account menu ---------- */

.v3-acct { width: min(300px, calc(100vw - 16px)); }
.v3-acct__who { display: flex; gap: 11px; align-items: center; padding: 6px 8px 12px; border-bottom: 1px solid var(--line); margin-bottom: 8px; }
.v3-acct__av { flex: none; width: 40px; height: 40px; border-radius: 50%; background: var(--navy); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 14px; }
.v3-acct__who strong { display: block; font-size: 14.5px; }
.v3-acct__who small { display: block; color: var(--muted); font-size: 12.5px; }
.v3-acct__rule { height: 1px; background: var(--line); margin: 8px 6px; }

/* ---------- account avatar in the bar ---------- */

.v3-iconbtn__av { width: 27px; height: 27px; border-radius: 50%; background: var(--navy); color: #fff; display: grid; place-items: center; font-size: 11px; font-weight: 700; letter-spacing: 0.02em; }
.v3-iconbtn--me.is-open .v3-iconbtn__av { outline: 2px solid var(--gold); outline-offset: 2px; }
.v3-quiet--pad { padding: 18px 12px; text-align: center; }

/* ---------- card and panel title icons ---------- */

/*
 * A dashboard of eight cards that differ only in their wording is read left to
 * right, every time, by everyone. An icon on the title gives each card a shape,
 * so after a week staff aim at the shape and read the words only to confirm.
 * The icon takes the card's own severity, so nothing ever says two things.
 */
.v3-card__ico {
    flex: none; width: 30px; height: 30px; border-radius: 9px;
    display: grid; place-items: center;
    background: var(--navy-soft); color: var(--navy);
}
.v3-card__ico svg { width: 16px; height: 16px; }
.v3-card--crit .v3-card__ico { background: var(--crit-bg); color: var(--crit); }
.v3-card--warn .v3-card__ico { background: var(--warn-bg); color: var(--warn); }
.v3-card--ok   .v3-card__ico { background: var(--ok-bg);   color: var(--ok); }
.v3-card--info .v3-card__ico { background: var(--info-bg); color: var(--info); }
.v3-card--dark .v3-card__ico { background: rgb(255 255 255 / 0.14); color: #fff; }
.v3-card--accent .v3-card__ico { background: var(--gold-soft); color: var(--gold-dark); }
.v3-allclear .v3-card__ico { width: 46px; height: 46px; border-radius: 50%; margin: 0 auto 12px; background: var(--ok-bg); color: var(--ok); }
.v3-allclear .v3-card__ico svg { width: 23px; height: 23px; }

/* When a customer is open, their dock replaces the global one. */

/* ---------- caret ---------- */

/*
 * The caret is its own element rather than a pseudo-element on the panel: a
 * scrolling panel needs overflow, and overflow clips anything drawn outside it,
 * which is why the first attempt at this pointed at nothing.
 */
.v3-caret { position: fixed; z-index: 61; width: 14px; height: 14px; transform: translateX(-50%) rotate(45deg); background: var(--card); }
.v3-caret--up { border-left: 1px solid var(--line); border-top: 1px solid var(--line); }
.v3-caret--down { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.v3-flyout.is-dockmenu::after, .v3-flyout.is-topmenu::after { content: none; }
.v3-flyout__title { display: block; }

/* ---------- narrow phones ---------- */

/*
 * At 320px the bar's own contents were what refused to shrink: the wordmark,
 * the STAFF label and three 38px buttons come to more than the screen. The
 * label is decorative and the wordmark survives as the diamond, so both give
 * way before anything is allowed to push the layout wider than the device.
 */
@media (max-width: 400px) {
    .v3-brand__div { display: none; }
    .v3-topbar__inner { gap: 10px; padding-inline: 12px; }
}


@media (max-width: 340px) {
    .v3-brand span:last-child { display: none; }
    .v3-iconbtn { width: 34px; height: 34px; }
}



/*
 * Nothing may widen the page. `overflow-x: clip` rather than `hidden`, because
 * `hidden` makes the element a scroll container and silently stops every
 * `position: sticky` descendant working - it took the top bar and the customer
 * context bar with it the first time. `clip` cuts the overflow without
 * creating a scroller, so the sticky bars survive.
 */
body { max-width: 100%; overflow-x: clip; }
@keyframes pulse { 50% { opacity: 0.45; } }
/* The version switch, in the account menu.
   Worded as what it does rather than as a version number, and it returns you to
   the page you were on: a switch that drops you at a home page is one nobody
   uses twice, and comparing old and new on the same record is the whole point
   of running both. */
.v3-verswitch {
    appearance: none; cursor: pointer; font: inherit; text-align: left; width: 100%;
    display: flex; gap: 10px; align-items: center;
    padding: 9px 10px; border-radius: 9px; border: 0; background: none; color: inherit;
}
.v3-verswitch:hover { background: var(--gold-soft); }
.v3-verswitch strong { display: block; font-size: 14px; font-weight: 600; }
.v3-verswitch small { display: block; color: var(--muted); font-size: 12.5px; }

/* ---------- list pages ---------- */


.v3-mono { font-family: "IBM Plex Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; }

/* ---------- state selector ---------- */

/*
 * The state selector is the spine of every list page. Adverts, customers and
 * orders all mean something different in each state, and staff arrive at these
 * pages already knowing which state they came for - so state is the first
 * control, carries its own count, and survives as the page heading rather than
 * hiding inside a filter panel.
 */
.v3-states { margin: 0 0 4px; }
.v3-state {
    appearance: none; cursor: pointer; font: inherit; white-space: nowrap;
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 13px; font-weight: 600; padding: 7px 13px;
    border-radius: 999px; border: 1px solid var(--line-strong);
    background: var(--card); color: var(--body);
}
.v3-state:hover { border-color: var(--navy); }
.v3-state b { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--muted); }
.v3-state[aria-selected="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }
.v3-state[aria-selected="true"] b { color: rgb(255 255 255 / 0.72); }
.v3-state--crit .v3-state__led { background: var(--crit); }
.v3-state--warn .v3-state__led { background: var(--warn); }
.v3-state--ok   .v3-state__led { background: var(--ok); }
.v3-state[aria-selected="true"] .v3-state__led { box-shadow: 0 0 0 2px rgb(255 255 255 / 0.25); }

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

.v3-list { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); overflow: hidden; }

.v3-li { display: grid; gap: 3px 13px; padding: 13px 14px; border-top: 1px solid var(--line); text-decoration: none; color: inherit; grid-template-columns: 46px minmax(0, 1fr) auto; align-items: start; }
.v3-list > .v3-li:first-of-type { border-top: 0; }
.v3-li:hover { background: var(--navy-soft); }
.v3-li__meta .v3-mono { font-size: 12px; }

@media (max-width: 559px) {
    .v3-li { grid-template-columns: 38px minmax(0, 1fr); }
    .v3-li > .v3-thumb { width: 38px; height: 38px; }
}


.v3-states__strip {
    display: flex; gap: 7px; overflow-x: auto; padding: 3px 16px 11px;
    margin-inline: -16px; scrollbar-width: none;
}
.v3-states__strip::-webkit-scrollbar { display: none; }

.v3-states__note { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; margin: 0 0 14px; color: var(--muted); font-size: 13.5px; }
.v3-states__note strong { color: var(--ink); font-size: 15px; }
.v3-list__head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 11px 14px; border-bottom: 1px solid var(--line); background: var(--card-soft); }
.v3-list__head p { margin: 0; font-size: 13px; color: var(--muted); font-weight: 600; }
.v3-li__thumb { grid-row: span 3; width: 46px; height: 46px; border-radius: 10px; background: var(--navy-soft); color: var(--navy); display: grid; place-items: center; }
.v3-li__thumb svg { width: 19px; height: 19px; }
/* A photo in a list row occupies the same cell the icon did: the first column,
   spanning title, meta and tags. Without the span it sat on one row and pushed
   the meta line into the 46px icon column, where it wrapped to nothing. */
.v3-li > .v3-thumb { grid-row: span 3; width: 46px; height: 46px; }
.v3-li__thumb--crit { background: var(--crit-bg); color: var(--crit); }
.v3-li__thumb--warn { background: var(--warn-bg); color: var(--warn); }
.v3-li__thumb--ok   { background: var(--ok-bg);   color: var(--ok); }
.v3-li__thumb--info { background: var(--info-bg); color: var(--info); }
.v3-li__title { margin: 0; font-size: 14.5px; font-weight: 650; letter-spacing: -0.01em; }
.v3-li__tags { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.v3-li__right { grid-row: span 2; text-align: right; display: grid; gap: 3px; justify-items: end; }
.v3-li__amount { font-size: 14.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.v3-li__age { font-size: 12px; color: var(--muted); font-weight: 600; white-space: nowrap; }

@media (max-width: 559px) {
    .v3-li { grid-template-columns: 38px minmax(0, 1fr); }
    .v3-li__thumb { width: 38px; height: 38px; grid-row: span 2; }
    .v3-li__right { grid-row: auto; justify-items: start; text-align: left; grid-auto-flow: column; gap: 9px; align-items: baseline; margin-top: 2px; }
    /* Everything except the thumbnail sits in the second column. Without this
       the meta line auto-places into the 38px thumbnail column and wraps one
       word per line, which looks like a content problem and is a grid one. */
    .v3-li__title, .v3-li__right, .v3-li__meta, .v3-li__tags { grid-column: 2; }
}



.v3-list__empty { padding: 42px 20px; text-align: center; }
.v3-list__empty .v3-mi { margin: 0 auto 10px; width: 42px; height: 42px; }
.v3-list__empty h3 { margin: 0 0 4px; font-size: 16px; }
.v3-list__empty p { margin: 0 auto; color: var(--muted); max-width: 42ch; font-size: 14px; }

/* Desktop has room to show every state at once; a strip that scrolls off the
   edge hides half the book of work behind a gesture nobody makes with a mouse. */
@media (min-width: 900px) {
    .v3-states__strip { flex-wrap: wrap; overflow: visible; }
}


/* ---------- detail pages ---------- */

.v3-pagehead__actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.v3-btn {
    appearance: none; cursor: pointer; font: inherit; font-size: 14px; font-weight: 600;
    padding: 9px 15px; border-radius: 10px; border: 1px solid transparent;
    display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
}
.v3-btn--ghost { background: var(--card); border-color: var(--line-strong); color: var(--ink); }
.v3-btn--ghost:hover { background: var(--card-soft); }

/* ---------- customer workbench ---------- */

.v3-layout { display: grid; gap: 16px; }
@media (min-width: 900px) { .v3-layout { grid-template-columns: minmax(0, 1fr) 318px; }
}
/* Past this the aside can hold a full key-value pair per row rather than
   wrapping every value onto its own line. */
@media (min-width: 1280px) { .v3-layout { grid-template-columns: minmax(0, 1fr) 380px; }
}



.v3-panel { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.v3-panel__head { padding: 14px 16px; border-bottom: 1px solid var(--line); display: flex; gap: 10px; align-items: center; }
.v3-panel__head h2 { margin: 0; font-size: 15px; font-weight: 700; }
.v3-panel__head .v3-btn { margin-left: auto; }
.v3-panel__body { padding: 14px 16px; }

.v3-checklist { list-style: none; margin: 0; padding: 0; }
.v3-checklist li { display: flex; gap: 11px; align-items: flex-start; padding: 11px 16px; }
.v3-checklist li + li { border-top: 1px solid var(--line); }
.v3-checklist__icon { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; flex: 0 0 auto; margin-top: 1px; }
.v3-checklist__icon--ok { background: var(--ok-bg); color: var(--ok); }
.v3-checklist__icon--no { background: var(--crit-bg); color: var(--crit); }
.v3-checklist__icon--wait { background: var(--warn-bg); color: var(--warn); }
.v3-checklist strong { display: block; font-size: 14px; font-weight: 600; }
.v3-checklist small { color: var(--muted); font-size: 12.5px; }
.v3-checklist .v3-btn { margin-left: auto; align-self: center; }

/* ---------- misc ---------- */

.v3-crumb { font-size: 13px; color: var(--muted); margin-bottom: 8px; display: flex; gap: 7px; align-items: center; flex-wrap: wrap; }
.v3-crumb a { text-decoration: none; font-weight: 600; color: var(--gold-dark); }
.v3-notif__head .v3-btn { margin-left: auto; }

/* ---------- card and panel title icons ---------- */

/*
 * A dashboard of eight cards that differ only in their wording is read left to
 * right, every time, by everyone. An icon on the title gives each card a shape,
 * so after a week staff aim at the shape and read the words only to confirm.
 * The icon takes the card's own severity, so nothing ever says two things.
 */
.v3-card__ico, .v3-panel__head .v3-card__ico {
    flex: none; width: 30px; height: 30px; border-radius: 9px;
    display: grid; place-items: center;
    background: var(--navy-soft); color: var(--navy);
}
.v3-panel__head { display: flex; align-items: center; gap: 10px; }

/* A publish button that is gated has to look gated. It carried the `disabled`
   attribute and a tooltip explaining why, but rendered identically to a live
   one, which is worse than no gate at all. */
.v3-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.v3-panel__body > textarea { font: inherit; font-size: 14px; width: 100%; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--line-strong); background: var(--card); color: var(--ink); resize: vertical; }
.v3-grow { flex: 1; min-width: 0; }
.v3-kv { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr)); gap: 12px 16px; }
.v3-kv div { min-width: 0; }
.v3-kv dt { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 700; margin: 0; }
.v3-kv dd { margin: 2px 0 0; font-size: 14.5px; font-weight: 600; overflow-wrap: anywhere; }

/* ---------- customer context ---------- */

.v3-btn--sm { padding: 6px 11px; font-size: 13px; }

/* ---------- customer context bar ---------- */

.v3-ctxbar { background: var(--card); border-bottom: 1px solid var(--line); position: sticky; top: calc(var(--bar-h) + env(safe-area-inset-top, 0px)); z-index: 30; }
.v3-ctxbar__inner { max-width: var(--shell); margin-inline: auto; padding: 9px 16px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.v3-ctxbar__who { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; background: var(--gold-soft); color: var(--gold-dark); padding: 5px 10px 5px 5px; border-radius: 999px; }
.v3-ctxbar__who a { text-decoration: none; opacity: 0.6; font-size: 17px; line-height: 1; padding: 0 2px; }
.v3-ctxbar__who a:hover { opacity: 1; }
.v3-ctxbar__initial { width: 22px; height: 22px; border-radius: 50%; background: var(--gold); color: #fff; display: grid; place-items: center; font-size: 12px; }
.v3-ctxbar__nav { display: flex; gap: 2px; overflow-x: auto; }
.v3-ctxbar__nav a { font-size: 14px; font-weight: 600; color: var(--body); text-decoration: none; padding: 6px 12px; border-radius: 999px; white-space: nowrap; }
.v3-ctxbar__nav a:hover { background: var(--navy-soft); color: var(--ink); }
.v3-ctxbar__nav a.is-current { background: var(--navy); color: #fff; }

/* ---------- customer context ---------- */

/*
 * A page inside a customer must never be mistakable for the same page across
 * the whole system: "Adverts" here means four, everywhere else it means 1,134.
 * The gold rail down the left of the context bar, the customer's name in a gold
 * chip and the visible way out are all doing that one job.
 */
.v3-ctxbar { box-shadow: inset 4px 0 0 var(--gold); }
.v3-ctxbar__n { display: inline-block; margin-left: 6px; font-size: 11.5px; font-weight: 700; padding: 1px 6px; border-radius: 999px; background: var(--navy-soft); color: var(--muted); font-variant-numeric: tabular-nums; }
.v3-ctxbar__nav a.is-current .v3-ctxbar__n { background: rgb(255 255 255 / 0.2); color: #fff; }
.v3-ctxbar__actions { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.v3-ctxbar__actions .v3-btn { display: inline-flex; align-items: center; gap: 6px; }
.v3-ctxbar__actions .v3-btn svg { width: 15px; height: 15px; }
.v3-btn--gold { background: var(--gold-soft); border-color: transparent; color: var(--gold-dark); }
.v3-btn--gold:hover { background: var(--gold); color: #fff; }
.v3-ctxbar__state { margin: 0; padding: 0 16px 9px; max-width: 1180px; margin-inline: auto; font-size: 12.5px; color: var(--muted); }
.v3-ctxbar__state b { color: var(--warn); font-weight: 700; }

/* When a customer is open, their dock replaces the global one. */
body:has(.v3-dock--ctx) .v3-dock:not(.v3-dock--ctx) { display: none; }
.v3-dock--ctx { box-shadow: inset 0 3px 0 var(--gold), 0 -6px 20px -14px rgb(15 42 82 / 0.4); }
.v3-dock__leave { color: var(--gold-dark) !important; }

@media (max-width: 899px) {
    /* On a phone the second-tier nav would eat a third of the screen, so the
       bar keeps only who you are inside and the way out; the sections move to
       the dock, where they are reachable one-handed. */
    .v3-ctxbar__nav, .v3-ctxbar__actions { display: none; }
    .v3-ctxbar__inner { padding: 8px 16px; }
    .v3-ctxbar__state { padding-bottom: 8px; }
}


/* ---------- context stop menus ---------- */

.v3-ctxbar__nav button {
    appearance: none; cursor: pointer; font: inherit; border: 0; background: none;
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 14px; font-weight: 600; color: var(--body);
    padding: 6px 12px; border-radius: 999px; white-space: nowrap;
}
.v3-ctxbar__nav button:hover { background: var(--navy-soft); color: var(--ink); }
.v3-ctxbar__nav button.is-current, .v3-ctxbar__nav button.is-open { background: var(--navy); color: #fff; }
.v3-ctxbar__nav .v3-stop__chev { opacity: 0.55; }

/* A menu inside a customer wears the same gold rail as the bar it came from,
   so a list of that customer's adverts never reads as the whole system's. */
.v3-flyout--ctx { box-shadow: inset 4px 0 0 var(--gold), var(--shadow); }
.v3-flyout--ctx .v3-flyout__title { color: var(--gold-dark); }
/* ---------- standing queues band ---------- */


/* ---------- standing queues band ---------- */

.v3-band { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(min(258px, 100%), 1fr)); margin-bottom: 18px; }
.v3-band__item { display: flex; gap: 11px; align-items: center; padding: 12px 14px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); box-shadow: var(--shadow-sm); text-decoration: none; color: inherit; }
.v3-band__item:hover { border-color: var(--line-strong); }
.v3-band__item strong { display: block; font-size: 14.5px; font-weight: 650; }
.v3-band__item small { display: block; font-size: 12.5px; color: var(--muted); margin-top: 1px; }
.v3-band__item--crit { box-shadow: inset 3px 0 0 var(--crit), var(--shadow-sm); }
.v3-band__item--warn { box-shadow: inset 3px 0 0 var(--warn), var(--shadow-sm); }
/* ---------- advert editor ---------- */


/* ---------- advert editor ---------- */

/*
 * A step rail rather than tabs: tabs say "look at another part of the same
 * thing", steps say "this part is finished and that one is not", which is the
 * question staff are actually holding while they work an advert towards going
 * live. Each step therefore carries its own state mark, not just a label.
 */
.v3-steps { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); margin-bottom: 18px; }
.v3-step { display: flex; gap: 10px; align-items: center; padding: 10px 12px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); text-decoration: none; color: inherit; box-shadow: var(--shadow-sm); }
.v3-step:hover { border-color: var(--line-strong); }
.v3-step__n { flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: 12.5px; font-weight: 700; background: var(--navy-soft); color: var(--muted); }
.v3-step__text { min-width: 0; }
.v3-step__text strong { display: block; font-size: 13.5px; font-weight: 650; }
.v3-step__text small { display: block; font-size: 12px; color: var(--muted); }
.v3-step.is-current { border-color: var(--gold); box-shadow: inset 3px 0 0 var(--gold), var(--shadow-sm); }

.v3-editor { display: grid; gap: 16px; align-items: start; }
@media (min-width: 900px) { .v3-editor { grid-template-columns: minmax(0, 1fr) 318px; }
}


.v3-form { display: grid; align-items: start; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr)); padding: 14px 16px; }
.v3-field { display: grid; gap: 5px; min-width: 0; }
.v3-field--wide { grid-column: 1 / -1; }
.v3-field label { font-size: 12.5px; font-weight: 650; color: var(--muted); }
.v3-field input, .v3-field textarea {
    font: inherit; font-size: 14px; width: 100%; padding: 9px 11px;
    border-radius: 10px; border: 1px solid var(--line-strong);
    background: var(--card); color: var(--ink);
}
.v3-field input:disabled { background: var(--card-soft); color: var(--muted); }
.v3-field textarea { resize: vertical; }

.v3-editor__foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 16px; border-top: 1px solid var(--line); background: var(--card-soft); }
.v3-editor__saved { flex: 1; min-width: 140px; font-size: 12.5px; color: var(--muted); text-align: center; }

.v3-editor__gate { margin: 0; padding: 12px 16px; font-size: 13.5px; color: var(--muted); border-bottom: 1px solid var(--line); }
.v3-editor__gate strong { display: block; color: var(--crit); margin-bottom: 2px; }
.v3-minichecks { list-style: none; margin: 0; padding: 8px 16px 14px; display: grid; gap: 7px; font-size: 13.5px; }
.v3-minichecks li { display: flex; gap: 9px; align-items: center; }

/* ---------- editor: fields, media, toggles ---------- */

.v3-field select {
    font: inherit; font-size: 14px; width: 100%; padding: 9px 11px;
    border-radius: 10px; border: 1px solid var(--line-strong);
    background: var(--card); color: var(--ink);
}
.v3-field__hint { display: block; font-size: 12px; color: var(--muted); }
.v3-toggle { display: flex; gap: 10px; align-items: center; padding: 10px 12px; border-radius: 11px; border: 1px solid var(--line); background: var(--card-soft); cursor: pointer; }
.v3-toggle input { flex: none; width: 17px; height: 17px; accent-color: var(--gold); }
.v3-toggle strong { display: block; font-size: 13.5px; font-weight: 650; }
.v3-toggle small { display: block; font-size: 12.5px; color: var(--muted); }
/* A validation message replaces the hint rather than sitting beside it: two
   lines under one field, one of them now wrong, is worse than one. */
.v3-field__error { display: block; font-size: 12px; font-weight: 600; color: var(--crit); }
.v3-field input[aria-invalid="true"],
.v3-field select[aria-invalid="true"],
.v3-field textarea[aria-invalid="true"] { border-color: var(--crit); }

/* The step's main action. `--gold` is the muted treatment used for secondary
   gold actions like Impersonate; on a form footer it read as disabled. */
.v3-btn--primary { background: var(--gold); border-color: var(--gold); color: #fff; }
.v3-btn--primary:hover:not(:disabled) { background: var(--gold-dark); border-color: var(--gold-dark); }

/* ---------- search results ---------- */

/*
 * The desktop results hang under the field. They are a panel, not a page: you
 * are looking for one thing and the fastest outcome is recognising it and
 * clicking, so the list stays dense and the grouping does the sorting.
 */
.v3-search { position: relative; }
.v3-search__results {
    position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 60;
    max-height: min(70vh, 520px); overflow: auto;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 8px;
}
.v3-search__results a {
    display: flex; gap: 10px; align-items: center;
    padding: 9px 10px; border-radius: 9px; text-decoration: none;
}
.v3-search__results a:hover { background: var(--navy-soft); }
.v3-search__results a strong { display: block; font-size: 14px; font-weight: 600; }
.v3-search__results a small { display: block; color: var(--muted); font-size: 12.5px; }
.v3-flyout__title .v3-flyout__count { margin-left: 8px; }

/* ---------- evidence rows and drawer ---------- */

/*
 * A row that leads somewhere is entirely clickable and says so with a chevron.
 * A button at the end of an otherwise dead row makes people aim, and aiming is
 * the thing a dashboard should never ask for.
 */
.v3-rows { list-style: none; margin: 0; padding: 0; }
.v3-rows > li + li { border-top: 1px solid var(--line); }
.v3-row {
    display: flex; gap: 11px; align-items: center; width: 100%;
    padding: 12px 16px; text-align: left; color: inherit; text-decoration: none;
    font: inherit; background: none; border: 0;
}
.v3-row strong { display: block; font-size: 14px; font-weight: 650; }
.v3-row small { display: block; font-size: 12.5px; color: var(--muted); margin-top: 1px; }
.v3-row--link { cursor: pointer; }
.v3-row--link:hover { background: var(--navy-soft); }
.v3-rows__chev { flex: none; color: var(--muted); }
.v3-row--link:hover .v3-rows__chev { color: var(--ink); }

.v3-drawer--evidence { width: min(520px, 100%); }
.v3-drawer__body { padding: 4px 8px 20px; }
.v3-drawer__body .v3-kv { padding: 8px 8px 14px; }

/* ---------- key features ---------- */

.v3-features { list-style: none; margin: 0 0 10px; padding: 0; display: grid; gap: 6px; }
.v3-feature {
    display: flex; gap: 8px; align-items: center;
    padding: 6px 8px; border-radius: 10px;
    border: 1px solid var(--line); background: var(--card-soft);
}
.v3-feature.is-over { border-color: var(--gold); background: var(--gold-soft); }
.v3-feature.is-dragging { opacity: 0.5; }
.v3-feature__grip { flex: none; color: var(--muted); cursor: grab; display: grid; place-items: center; }
.v3-feature__n { flex: none; width: 22px; height: 22px; border-radius: 6px; display: grid; place-items: center; font-size: 11.5px; font-weight: 700; background: var(--navy-soft); color: var(--muted); font-variant-numeric: tabular-nums; }
.v3-feature input { flex: 1; min-width: 0; font: inherit; font-size: 14px; padding: 7px 10px; border-radius: 8px; border: 1px solid var(--line-strong); background: var(--card); color: var(--ink); }
.v3-feature__acts { flex: none; display: flex; gap: 3px; }
.v3-iconbtn--sm { width: 30px; height: 30px; }
.v3-iconbtn--danger:hover { background: var(--crit-bg); color: var(--crit); border-color: var(--crit); }
.v3-iconbtn:disabled { opacity: 0.35; cursor: not-allowed; }

@media (max-width: 559px) {
    /* The row wraps rather than squeezing the input to nothing. */
    .v3-feature { flex-wrap: wrap; }
    .v3-feature input { flex: 1 1 100%; order: 3; }
}

/* The field is a grid, so a bare button stretches the full width and reads as
   a text input rather than an action. */
.v3-features__add { display: block; }

/* ---------- conversations ---------- */


.v3-message { margin: 0; font-size: 15px; line-height: 1.6; max-width: 62ch; }
.v3-message mark { background: var(--warn-bg); color: var(--warn); font-weight: 650; padding: 1px 3px; border-radius: 4px; }
.v3-message__meta { margin: 10px 0 0; font-size: 12.5px; color: var(--muted); }

/* ---------- ticket thread ---------- */

/*
 * Four kinds of entry share this thread and only three of them were ever seen
 * by the customer. An internal note or an assistant attempt that looks like a
 * sent message is how someone eventually says something to a customer they
 * thought was private, so each kind is marked twice: a rail colour and a word.
 */
.v3-thread { list-style: none; margin: 0; padding: 0; }
.v3-msg { display: flex; gap: 11px; padding: 14px 16px; border-top: 1px solid var(--line); }
.v3-thread > .v3-msg:first-child { border-top: 0; }
.v3-msg__body { min-width: 0; flex: 1; }
.v3-msg__who { margin: 0 0 4px; display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.v3-msg__who strong { font-size: 14px; font-weight: 650; }
.v3-msg__tag { font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; padding: 2px 7px; border-radius: 999px; background: var(--navy-soft); color: var(--muted); }
.v3-msg__when { margin-left: auto; font-size: 12px; color: var(--muted); }
.v3-msg__text { margin: 0; font-size: 14px; line-height: 1.55; max-width: 62ch; }
.v3-msg__note { margin: 6px 0 0; font-size: 12px; color: var(--muted); font-style: italic; }
.v3-msg--us .v3-msg__tag { background: var(--navy); color: #fff; }
.v3-msg--ai .v3-msg__tag { background: var(--info-bg); color: var(--info); }
.v3-msg--ai .v3-msg__text { color: var(--muted); }
.v3-msg--note .v3-msg__tag { background: var(--warn); color: #fff; }
/*
 * A flex item will not shrink below its own content unless it is told it may,
 * so one long ticket subject pushed the whole page 4px past the screen — which
 * widens the layout viewport and takes the fixed dock with it. `min-width: 0`
 * on the growing cell is the fix; letting long references break is the belt.
 */
.v3-msg__body { min-width: 0; }
.v3-row strong, .v3-row small, .v3-msg__text { overflow-wrap: anywhere; }
.v3-row .v3-li__amount, .v3-row .v3-li__age { flex: none; }

@media (max-width: 559px) {
    /* Status and date drop under the text rather than squeezing it. */
    .v3-row { flex-wrap: wrap; }
    .v3-row .v3-grow { flex: 1 1 100%; }
    .v3-row .v3-li__amount, .v3-row .v3-li__age { font-size: 12px; }
}

/* ---------- tables of figures ---------- */

/*
 * A bar drawn behind the first cell answers "which of these is biggest" without
 * giving up a readable, selectable, screen-reader-usable table. Only tables may
 * scroll sideways; the page itself never does.
 */
.v3-tablewrap { overflow-x: auto; }
.v3-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.v3-table th {
    text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--muted); font-weight: 700; padding: 10px 16px; white-space: nowrap;
    border-bottom: 1px solid var(--line); background: var(--card-soft);
}
.v3-table td { padding: 11px 16px; border-bottom: 1px solid var(--line); position: relative; }
.v3-table tr:last-child td { border-bottom: 0; }
.v3-table .is-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.v3-table__bar {
    position: absolute; left: 0; top: 4px; bottom: 4px; z-index: 0;
    background: var(--gold-soft); border-radius: 0 4px 4px 0;
}
.v3-table td > *:not(.v3-table__bar) { position: relative; z-index: 1; }

/* ---------- report tiles ---------- */

.v3-tiles { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr)); margin: 0 0 16px; }
.v3-tile { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); padding: 13px 15px; }
.v3-tile dt { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.v3-tile dd { margin: 3px 0 0; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.v3-tile small { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.v3-reports { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); align-items: start; }

/* ---------- resolving something from a drawer ---------- */

/*
 * A drawer that shows a problem and offers nothing is a dead end: staff see it,
 * then have to go and find the place it can actually be dealt with, which is
 * how a blocker sits for weeks. Everything needed to resolve it lives here.
 */
.v3-drawer__act { display: grid; gap: 6px; padding: 4px 8px 14px; }
.v3-drawer__act .v3-btn { width: fit-content; display: inline-flex; align-items: center; gap: 7px; }
.v3-drawer__act small { font-size: 12.5px; color: var(--muted); }
.v3-drawer__form { display: grid; gap: 12px; padding: 12px 8px 4px; }
.v3-drawer__foot { display: flex; gap: 8px; justify-content: flex-end; padding-top: 4px; }
.v3-drawer .v3-actions { padding: 8px 8px 4px; }
.v3-drawer .v3-field textarea { font: inherit; font-size: 14px; width: 100%; padding: 9px 11px; border-radius: 10px; border: 1px solid var(--line-strong); background: var(--card); color: var(--ink); resize: vertical; }

/* ---------- decision buttons ---------- */
.v3-actions { display: grid; gap: 8px; padding: 12px 16px 16px; }
.v3-action {
    appearance: none; cursor: pointer; font: inherit; text-align: left;
    display: flex; gap: 11px; align-items: center; padding: 11px 13px;
    border-radius: 11px; border: 1px solid var(--line); background: var(--card); color: inherit;
}
.v3-action:hover { border-color: var(--line-strong); background: var(--card-soft); }
.v3-action strong { display: block; font-size: 14px; font-weight: 650; }
.v3-action small { display: block; font-size: 12.5px; color: var(--muted); margin-top: 1px; }
.v3-action--primary { border-color: var(--gold); box-shadow: inset 3px 0 0 var(--gold); }
.v3-action--primary strong { color: var(--gold-dark); }

/* ---------- active filters ---------- */

.v3-filters { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: -6px 0 14px; font-size: 13px; color: var(--muted); }
.v3-filter {
    appearance: none; cursor: pointer; font: inherit; font-size: 12.5px;
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 9px; border-radius: 999px;
    border: 1px solid var(--gold); background: var(--gold-soft); color: var(--gold-dark);
}
.v3-filter:hover { background: var(--gold); color: #fff; }
.v3-filter strong { font-weight: 700; }
.v3-filter--clear { border-color: var(--line-strong); background: var(--card); color: var(--muted); }
.v3-filter--clear:hover { background: var(--card-soft); color: var(--ink); }

/*
 * A metric is a number and a way in, not a queue. Drawn as a card with an empty
 * body it reads as a list that failed to load — which is exactly how it was
 * read. Tiles say "this is a figure, and here is where it comes from".
 */
.v3-tile--link { display: block; position: relative; text-decoration: none; color: inherit; }
.v3-tile--link:hover { border-color: var(--line-strong); background: var(--card-soft); }
.v3-tile dt { display: flex; align-items: center; gap: 8px; }
.v3-tile dt .v3-mi { width: 24px; height: 24px; border-radius: 7px; }
.v3-tile__chev { position: absolute; top: 14px; right: 13px; color: var(--muted); }
.v3-tile--link:hover .v3-tile__chev { color: var(--ink); }

/* Queue-card rows are links too, and say so. */
.v3-card__rows a { position: relative; padding-right: 32px; }
.v3-card__chev { position: absolute; top: 50%; right: 12px; transform: translateY(-50%); color: var(--muted); }
.v3-card__rows a:hover .v3-card__chev { color: var(--ink); }

/* Every list row is a link, so every list row says so. */
.v3-li { position: relative; padding-right: 34px; }
.v3-li::after {
    content: ""; position: absolute; top: 50%; right: 14px; width: 8px; height: 8px;
    border-right: 2px solid var(--muted); border-top: 2px solid var(--muted);
    transform: translateY(-50%) rotate(45deg); border-radius: 1px;
}
.v3-li:hover::after { border-color: var(--ink); }

/* ---------- business rules ---------- */

.v3-rules { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); margin-bottom: 16px; overflow: hidden; }
/* Shut, this is one quiet row; open, it grows a divider under the heading. */
.v3-rules__head {
    appearance: none; cursor: pointer; font: inherit; text-align: left; width: 100%;
    display: flex; gap: 10px; align-items: center;
    padding: 11px 14px; border: 0; background: var(--card-soft); color: inherit;
}
.v3-rules__head:hover { background: var(--navy-soft); }
.v3-rules__head strong { display: block; font-size: 14px; font-weight: 650; }
.v3-rules__head small { display: block; font-size: 12.5px; color: var(--muted); }
.v3-rules.is-open .v3-rules__head { border-bottom: 1px solid var(--line); }

.v3-rule + .v3-rule { border-top: 1px solid var(--line); }
.v3-rule__title { padding: 12px 14px 2px; }
.v3-rule__title strong { display: block; font-size: 13.5px; font-weight: 650; }
.v3-rule__title small { display: block; font-size: 12.5px; color: var(--muted); }
.v3-rule__chev { flex: none; color: var(--muted); transition: transform 0.15s; }
.v3-rule__chev.is-open { transform: rotate(180deg); }

.v3-rule__body { padding: 2px 14px 14px; }
.v3-stages { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; counter-reset: stage; }
.v3-stages li { display: flex; gap: 10px; align-items: flex-start; }
.v3-stage__who { display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.v3-stage__text { display: block; font-size: 13.5px; line-height: 1.5; max-width: 70ch; }
.v3-stages .v3-pill { margin-top: 4px; }
.v3-rule__links { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: baseline; margin: 12px 0 0; font-size: 13px; color: var(--muted); }
.v3-rule__links a { font-weight: 600; color: var(--gold-dark); }

/*
 * Checklist rows carry pills now — whose job it is, and whether it blocks — and
 * a flex item still will not shrink below its content unless told. Same failure
 * as the list rows: 6px of overflow widens the layout viewport and takes the
 * fixed dock with it.
 */
.v3-checklist li { flex-wrap: wrap; }
.v3-checklist strong, .v3-checklist small { overflow-wrap: anywhere; }
.v3-checklist .v3-pill { white-space: normal; }

/* A panel that is telling you something is wrong, rather than listing data. */
.v3-panel--decide { box-shadow: inset 4px 0 0 var(--warn), var(--shadow-sm); }

/* ---------- ticket reply ---------- */

.v3-replytabs { display: flex; gap: 4px; margin-bottom: 9px; }
.v3-replytab { appearance: none; cursor: pointer; font: inherit; font-size: 13px; font-weight: 600; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--muted); }
.v3-replytab[aria-selected="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }
.v3-replybar { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 9px; }

/* ---------- confirmation modal ----------
   One pattern for every irreversible action. Centred rather than attached to
   an edge, because unlike a drawer this is not "more about that row" — it is a
   question that has to be answered before anything else happens. */
.v3-modal { position: fixed; z-index: 60; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(420px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); overflow-y: auto; display: grid; gap: 10px; padding: 20px; border-radius: 16px; border: 1px solid var(--line); background: var(--card); box-shadow: 0 24px 60px rgb(8 26 56 / 0.28); text-align: center; justify-items: center; }
.v3-modal h2 { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.v3-modal__body { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.v3-modal__body strong { color: var(--ink); font-weight: 650; }
.v3-modal__ico { display: grid; place-items: center; width: 42px; height: 42px; border-radius: 12px; }
.v3-modal__ico--crit { background: var(--crit-bg); color: var(--crit); }
.v3-modal__ico--gold { background: var(--gold-soft); color: var(--gold-dark); }
.v3-modal__act { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
.v3-btn--danger { background: var(--crit); border-color: var(--crit); color: #fff; }
.v3-btn--danger:hover:not(:disabled) { filter: brightness(0.92); }

/* On a phone the modal meets the bottom edge, like every other overlay here. */
@media (max-width: 719px) {
    .v3-modal { top: auto; bottom: 0; left: 0; width: 100%; max-width: none; transform: none; border-radius: 16px 16px 0 0; padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
}

/* A quiet line of supporting text: who wrote a note, when a score was worked
   out, what a count is counting. */
.v3-subtle { margin: 0 0 4px; font-size: 12.5px; color: var(--muted); }

/* ---------- condition card ----------
   The one card on a detail page that is allowed to carry colour. Named `cond`
   rather than `state` because `.v3-state` is already the state-selector pill on
   every list page — and that pill sets `white-space: nowrap`, which this card
   inherited, which made its one-sentence summary un-wrappable and widened the
   whole advert page to 581px on a 320px phone. It answers
   "what is going on here" before anything is read, which is the whole reason
   an operations dashboard exists — so it gets a tinted head, a rail down the
   left edge, and a dot that reads at a glance across a desk. */
.v3-cond { overflow: hidden; }
.v3-cond__head { display: flex; gap: 10px; align-items: flex-start; padding: 13px 15px; border-bottom: 1px solid var(--line); border-left: 4px solid var(--muted); background: var(--card-soft); }
.v3-cond__head h2 { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
.v3-cond__head p { margin: 3px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.v3-cond__dot { flex: none; width: 10px; height: 10px; margin-top: 5px; border-radius: 50%; background: var(--muted); }
.v3-cond__act { padding: 0 15px 14px; }

.v3-cond--ok .v3-cond__head { border-left-color: var(--ok); background: var(--ok-bg); }
.v3-cond--ok .v3-cond__dot { background: var(--ok); }
.v3-cond--ok .v3-cond__head h2 { color: var(--ok); }

.v3-cond--warn .v3-cond__head { border-left-color: var(--warn); background: var(--warn-bg); }
.v3-cond--warn .v3-cond__dot { background: var(--warn); }
.v3-cond--warn .v3-cond__head h2 { color: var(--warn); }

.v3-cond--crit .v3-cond__head { border-left-color: var(--crit); background: var(--crit-bg); }
.v3-cond--crit .v3-cond__dot { background: var(--crit); }
.v3-cond--crit .v3-cond__head h2 { color: var(--crit); }

.v3-cond--flat .v3-cond__head { border-left-color: var(--line-strong); }

/* ---------- chips ----------
   Multi-select where the options are few and each one is a real audience. A
   row of toggles reads faster than a multi-select box and works on a phone,
   where a native multiple-select is close to unusable. */
.v3-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.v3-chip {
    appearance: none; cursor: pointer; font: inherit; font-size: 13px; font-weight: 600;
    display: inline-flex; align-items: center; gap: 6px; min-height: 36px;
    padding: 7px 13px; border-radius: 999px;
    border: 1px solid var(--line-strong); background: var(--card); color: var(--body);
}
.v3-chip:hover { border-color: var(--navy); }
.v3-chip[aria-pressed="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }
.v3-field__legend { font-size: 12.5px; font-weight: 650; color: var(--muted); }

/* ---------- preview ---------- */
.v3-gallery { display: grid; gap: 8px; padding: 12px 14px; grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
.v3-gallery figure { margin: 0; display: grid; gap: 4px; min-width: 0; }
.v3-gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 10px; background: var(--card-soft); }
.v3-gallery figcaption { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.v3-lede { margin: 0 0 10px; font-size: 15px; line-height: 1.5; font-weight: 600; }
.v3-prose p { margin: 0 0 10px; font-size: 14px; line-height: 1.6; max-width: 70ch; }
.v3-prose p:last-child { margin-bottom: 0; }

/* ---------- picking one record out of thousands ---------- */
.v3-rows--picker { max-height: 320px; overflow-y: auto; border: 1px solid var(--line); border-radius: 11px; margin-top: 6px; }
.v3-picked { display: flex; gap: 10px; align-items: center; padding: 10px 12px; border-radius: 11px; border: 1px solid var(--ok); background: var(--ok-bg); }
.v3-picked strong { display: block; font-size: 13.5px; font-weight: 650; }
.v3-picked small { display: block; font-size: 12.5px; color: var(--muted); }

/* A group of permission toggles inside the role drawer. */
.v3-perms { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }

/* ---------- rendered email preview ---------- */
.v3-preview { margin-top: 8px; border: 1px solid var(--line-strong); border-radius: 11px; overflow: hidden; background: #fff; }
.v3-preview__subject { margin: 0; padding: 9px 12px; font-size: 13px; font-weight: 650; color: #1b2433; background: #f4f6fa; border-bottom: 1px solid rgb(15 42 82 / 0.12); }
.v3-preview__frame { display: block; width: 100%; height: 380px; border: 0; background: #fff; }

/* ---------- property thumbnails ----------
   A photo is recognised before an address is read, so it is the fastest way to
   find one advert in a list of eighty. The frame keeps the state tint whether
   it holds a photo or the fallback icon, so the colour reads either way. */
.v3-thumb { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 10px; overflow: hidden; background: var(--card-soft); color: var(--muted); border: 1px solid var(--line); }
.v3-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.v3-thumb--lg { width: 64px; height: 64px; border-radius: 12px; }
.v3-thumb--crit { border-color: var(--crit); background: var(--crit-bg); color: var(--crit); }
.v3-thumb--warn { border-color: var(--warn); background: var(--warn-bg); color: var(--warn); }
.v3-thumb--ok   { border-color: var(--ok);   background: var(--ok-bg);   color: var(--ok); }
/* A photo carries its own colour, so the tint becomes a rail rather than a wash. */
.v3-thumb--photo { background: var(--card-soft); }
.v3-thumb--photo.v3-thumb--crit { box-shadow: inset 0 0 0 2px var(--crit); }
.v3-thumb--photo.v3-thumb--warn { box-shadow: inset 0 0 0 2px var(--warn); }
.v3-thumb--photo.v3-thumb--ok   { box-shadow: inset 0 0 0 2px var(--ok); }

/* The state on a list row, in words and in colour. */
.v3-li__state { font-size: 12px; font-weight: 700; }
.v3-li__state--ok   { color: var(--ok); }
.v3-li__state--warn { color: var(--warn); }
.v3-li__state--crit { color: var(--crit); }

/* The photo beside a detail page's heading. */
.v3-pagehead__thumb { flex: none; display: block; text-decoration: none; border-radius: 12px; }
.v3-pagehead__thumb:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------- work queues ----------
   The count is the point of the row, so it is set larger than the label and
   takes the severity colour. A queue at zero never appears here — it drops to
   the quiet line at the foot. */
.v3-queue__n { flex: none; font-size: 17px; font-weight: 750; font-variant-numeric: tabular-nums; }
.v3-queue__n--crit { color: var(--crit); }
.v3-queue__n--warn { color: var(--warn); }
.v3-queue__n--info { color: var(--info); }
.v3-queue__n--ok { color: var(--ok); }
/* Quiet queues: shut by default, opened when somebody wants to check that a
   queue really is clear rather than missing. */
.v3-quiet__toggle { cursor: pointer; list-style: none; display: flex; gap: 10px; align-items: center; padding: 11px 16px; border-top: 1px solid var(--line); background: var(--card-soft); }
.v3-quiet__toggle::-webkit-details-marker { display: none; }
.v3-quiet__toggle:hover { background: var(--navy-soft); }
.v3-quiet__toggle strong { display: block; font-size: 13.5px; font-weight: 650; }
.v3-quiet__toggle small { display: block; font-size: 12.5px; color: var(--muted); }
.v3-quiet__toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.v3-quiet__chev { flex: none; color: var(--muted); transition: transform 0.15s; }
.v3-quiet[open] .v3-quiet__chev { transform: rotate(180deg); }

/* A section heading on the work page, set below the page title. */
.v3-work__heading { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }

/* A card with nothing in it still says so, rather than collapsing: a card that
   vanishes when it is empty is indistinguishable from one that never loaded. */
.v3-card__none { margin: 0; padding: 4px 16px 14px; font-size: 13px; color: var(--muted); }

/* The reply box under a conversation. */
.v3-reply { border-top: 1px solid var(--line); padding: 14px 8px 4px; background: var(--card-soft); }
