/* ==================================================================
   ManufactIQ CRM, interface stylesheet
   Built to ManufactIQ Brand Guidelines v1.0 (July 2026).

   Palette, type scale, radii and spacing all come straight from the
   guidelines. Two rules drive most of the decisions here:

     * One orange element per screen, the single most important
       action. Everything else is ink, steel or mist.
     * Roughly 70% ink and neutrals, 25% paper and white, 5% signal.

   Saira Semi Condensed is self-hosted: the Content-Security-Policy
   allows nothing from outside this site, so Google Fonts cannot be
   used. OFL.txt travels with the font files, as the licence requires.

   HOW THE FILE IS ARRANGED

     tokens        the palette as custom properties, light and dark
     base          type, links, focus, the utility classes
     shell         sidebar, top bar, page frame, phone layout
     overlays      menus, dialogs, the command palette, toasts
     components    cards, stats, tables, badges, buttons, forms,
                   tabs, chips, timeline, boards, pipeline, journey
     calendar      the diary views (unchanged in spirit)
     utilities     the 5% width and height steps the CSP forces on us
     print         A4

   Every colour is a token. The dark theme is those same tokens given
   other values under [data-theme="dark"], which is what lets one
   stylesheet serve both without a second set of rules - and why a new
   rule must never carry a hex colour of its own.
   ================================================================== */

/* ------------------------------------------------------------ type */

@font-face {
    font-family: "Saira Semi Condensed";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/saira-semi-condensed-400.woff2") format("woff2");
}
@font-face {
    font-family: "Saira Semi Condensed";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("../fonts/saira-semi-condensed-500.woff2") format("woff2");
}
@font-face {
    font-family: "Saira Semi Condensed";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/saira-semi-condensed-600.woff2") format("woff2");
}
@font-face {
    font-family: "Saira Semi Condensed";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/saira-semi-condensed-700.woff2") format("woff2");
}

/* ---------------------------------------------------------- tokens */

:root {
    color-scheme: light;

    /* Brand */
    --mq-ink:     #14171A;
    --mq-signal:  #F26430;
    --mq-paper:   #F7F6F2;
    --mq-steel:   #5B6068;
    --mq-mist:    #E4E2DC;
    --mq-white:   #FFFFFF;

    /* A step either side of paper and mist, for hover and hairlines. */
    --mq-paper-2: #FBFAF8;
    --mq-line-soft: #F0EEE9;
    --mq-mist-2:  #D6D3CB;

    /* System, interface only, never brand */
    --mq-success: #1E8E5A;
    --mq-warning: #C98A12;
    --mq-danger:  #C2382B;
    --mq-info:    #2F6FA8;

    /* Dark surfaces, per the guidelines */
    --mq-ink-card:   #1D2126;
    --mq-ink-border: #2C3238;

    /* Tints, derived only for hover and quiet fills */
    --mq-signal-dark: #D9542244;
    --mq-signal-hover: #DA5322;
    --mq-signal-wash: #FDEEE7;
    /* What a label on a signal-coloured fill is set in. A token rather
       than a literal white because a customer's own accent (see below)
       may be a pale colour, and white on pale yellow reads as nothing. */
    --mq-signal-text: #FFFFFF;
    /* The accent where it is *text on paper* rather than a fill: the lead
       figure on the dashboard, the asterisk on a required field. Darkened
       until it can be read, because a pale accent is fine on a button and
       invisible here. */
    --mq-signal-ink: var(--mq-signal);
    --mq-success-wash: #E6F2EC;
    --mq-warning-wash: #F9F0DC;
    --mq-danger-wash:  #F7E7E5;
    --mq-info-wash:    #E7EFF6;
    --mq-success-line: #BFDCCC;
    --mq-warning-line: #E8D3A0;
    --mq-danger-line:  #E9C2BD;
    --mq-info-line:    #C0D3E5;

    /* --------------------------------------------------------------
       The sidebar, as its own tokens rather than as the ink.

       These are what a customer on Premium replaces with their own brand
       colour, and they are separate from --mq-ink for one reason: --mq-ink
       is also the body text, every heading and every link. A company whose
       colour is a mid-blue wants a mid-blue sidebar, not mid-blue body copy
       on a paper background.

       The overrides are generated by crm/branding.py and served as a
       stylesheet by crm/blueprints/branding.py - never inline, so
       style-src stays 'self'.
       -------------------------------------------------------------- */
    --mq-nav:         var(--mq-ink);
    --mq-nav-surface: var(--mq-ink-card);
    --mq-nav-strong:  var(--mq-paper);
    --mq-nav-text:    #9CA2AA;
    --mq-nav-group:   var(--mq-steel);
    --mq-nav-line:    var(--mq-ink-border);

    /* ManufactIQ's own orange, pinned. The support bar is a warning to
       ManufactIQ staff that they are inside a customer's live data, so it
       is the one thing on the screen that must not take the customer's
       colours - it has to look the same in every tenant. */
    --mq-staff: #F26430;
    --mq-staff-wash: #FDEEE7;

    /* The avatar and the "current" fill on a chevron: ink on light, and
       a light plate on dark, so they read the same way on both. */
    --mq-plate: var(--mq-ink);
    --mq-plate-text: var(--mq-white);

    /* Radii, buttons 4, cards 8, tiles 22% */
    --r-button: 4px;
    --r-card:   8px;
    --r-tile:   22%;
    --r-pill:   999px;

    /* 4 px spacing grid */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
    --s5: 20px; --s6: 24px; --s8: 32px; --s10: 40px;

    --font: "Saira Semi Condensed", "Saira", "Roboto Condensed",
            "Segoe UI", Arial, sans-serif;
    --mono: Consolas, "Cascadia Mono", "Courier New", monospace;

    --shadow: 0 1px 2px rgba(20, 23, 26, 0.06);
    --shadow-md: 0 3px 10px rgba(20, 23, 26, 0.10);
    --shadow-lg: 0 8px 28px rgba(20, 23, 26, 0.16);
    --focus-ring: 0 0 0 3px rgba(20, 23, 26, 0.10);

    /* The shell's dimensions, in one place. */
    --sidebar-w: 236px;
    --sidebar-w-collapsed: 64px;
    --topbar-h: 56px;
}

/* The dark theme: the same tokens, other values. Chosen for a workshop
   office at six in the evening rather than for drama - paper becomes a
   near-black, white a lifted card, ink the light text, and the system
   colours brighten a step so they still read against it. The sidebar
   stays as it was; it was already dark. */
:root[data-theme="dark"] {
    color-scheme: dark;
    --mq-paper:   #14171A;
    --mq-paper-2: #191D21;
    --mq-white:   #1D2126;
    --mq-ink:     #F1EFEA;
    --mq-steel:   #A2A8B0;
    --mq-mist:    #2C3238;
    --mq-mist-2:  #3A414A;
    --mq-line-soft: #23282E;
    --mq-signal-wash: #3A241C;
    --mq-signal-ink: #FF8A5B;
    --mq-success: #4CC08A;
    --mq-warning: #E0A83A;
    --mq-danger:  #EF6B5E;
    --mq-info:    #6FA7E0;
    --mq-success-wash: #16302A;
    --mq-warning-wash: #33290F;
    --mq-danger-wash:  #3A1E1B;
    --mq-info-wash:    #16283A;
    --mq-success-line: #245A42;
    --mq-warning-line: #5A4713;
    --mq-danger-line:  #5E2A25;
    --mq-info-line:    #24405E;
    --mq-nav:         #0E1013;
    --mq-nav-surface: #1B1F24;
    --mq-nav-line:    #23282E;
    /* Pinned: in the light theme this is var(--mq-paper), which the dark
       theme turns near-black - and the sidebar's current item with it. */
    --mq-nav-strong:  #F7F6F2;
    --mq-staff-wash:  #3A241C;
    --mq-plate: #F1EFEA;
    --mq-plate-text: #14171A;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 3px 10px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 8px 28px rgba(0, 0, 0, 0.6);
    --focus-ring: 0 0 0 3px rgba(241, 239, 234, 0.14);
}

/* ------------------------------------------------------------- base */

* { box-sizing: border-box; }

html { font-size: 16px; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { transition: none !important; animation: none !important; }
}

body {
    margin: 0;
    font-family: var(--font);
    font-size: 15px;
    line-height: 24px;              /* Body 15 / 24: a step denser than print */
    font-weight: 400;
    color: var(--mq-ink);
    background: var(--mq-paper);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* Type scale. The guidelines' print sizes, tightened a step for an
   application that is read at arm's length all day. */
h1, .t-h1 { font-size: 30px; line-height: 36px; font-weight: 700;
             letter-spacing: -0.005em; margin: 0 0 var(--s2); color: var(--mq-ink); }
h2, .t-h2 { font-size: 22px; line-height: 28px; font-weight: 600;
             letter-spacing: 0; margin: 0 0 var(--s2); color: var(--mq-ink); }
h3, .t-h3 { font-size: 18px; line-height: 24px; font-weight: 600;
             margin: 0 0 var(--s2); color: var(--mq-ink); }
.t-display { font-size: 48px; line-height: 52px; font-weight: 700;
             letter-spacing: -0.01em; }

.small, .t-small { font-size: 13px; line-height: 20px; }

h4, .t-label, .eyebrow {
    font-size: 11.5px;
    line-height: 16px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mq-steel);
    margin: 0 0 var(--s2);
}
.eyebrow a { color: inherit; }

/* Orange is an accent, never body text, links stay ink. */
a { color: var(--mq-ink); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--mq-signal);
    outline-offset: 2px;
}

p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

.muted  { color: var(--mq-steel); }
.strong { font-weight: 600; }
.nowrap { white-space: nowrap; }
.num    { text-align: right; font-variant-numeric: tabular-nums;
          white-space: nowrap; }
.tabular { font-variant-numeric: tabular-nums; }
.mono   { font-family: var(--mono); font-size: 13px; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.right { text-align: right; }
.center { text-align: center; }
.flex { display: flex; align-items: center; gap: var(--s2); }
.flex--between { justify-content: space-between; }
.flex--wrap { flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.mt-0 { margin-top: 0 !important; }
.mb-0 { margin-bottom: 0 !important; }

/* Present for a screen reader, absent for everybody else. */
.visually-hidden {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* The icon set: strokes in the current text colour, sized to the type
   they sit beside. The sprite itself takes no room. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.icon {
    display: inline-block; width: 1.15em; height: 1.15em;
    vertical-align: -0.2em; flex: none;
    fill: none; stroke: currentColor; stroke-width: 1.75;
    stroke-linecap: round; stroke-linejoin: round;
}
.icon--sm { width: 1em; height: 1em; }
.icon--lg { width: 1.5em; height: 1.5em; }
.icon--xl { width: 2.25em; height: 2.25em; }

kbd {
    display: inline-block; min-width: 20px; padding: 0 5px;
    border: 1px solid var(--mq-mist-2); border-bottom-width: 2px;
    border-radius: 4px; background: var(--mq-white);
    font-family: var(--font); font-size: 11px; line-height: 18px;
    font-weight: 600; color: var(--mq-steel); text-align: center;
}

/* ================================================== the shell

   A dark sidebar down the left and a white bar across the top, per the
   ManufactIQ mockups. The sidebar carries the navigation because it does
   not fit in a row: five selling screens, three planning screens, four
   record lists, reports, a company's own tabs and two administration
   areas is more than one line can hold without turning into a wall of
   small type.

   The active item is marked by a 3 px signal-orange edge. That is the one
   place navigation is allowed the accent colour, and it is not a call to
   action competing with the page's primary button - it is a position
   marker, and it is the reason the guidelines' "one orange element" rule
   is still satisfied on every screen.

   The sidebar collapses to icons (html[data-nav="collapsed"]) for
   anybody who wants the width back; the choice is remembered per
   browser by static/js/theme.js.
   ------------------------------------------------------------------ */

.app {
    display: grid;
    grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
    min-height: 100vh;
    transition: grid-template-columns 160ms ease;
}
html[data-nav="collapsed"] .app {
    grid-template-columns: var(--sidebar-w-collapsed) minmax(0, 1fr);
}

.sidebar {
    background: var(--mq-nav);
    color: var(--mq-nav-text);
    display: flex; flex-direction: column;
    position: sticky; top: 0; align-self: start;
    height: 100vh; overflow: hidden;
}
.sidebar__brand {
    display: flex; align-items: center; gap: var(--s3);
    height: var(--topbar-h); padding: 0 var(--s4) 0 18px;
    border-bottom: 1px solid var(--mq-nav-line);
    color: var(--mq-nav-strong); flex: none;
}
.sidebar__brand:hover { text-decoration: none; }
.sidebar__mark {
    width: 30px; height: 30px; flex: none; border-radius: 7px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--mq-signal); color: var(--mq-signal-text);
    font-weight: 700; font-size: 14px; letter-spacing: 0.02em;
    overflow: hidden;
}
.sidebar__mark img { width: 30px; height: 30px; object-fit: contain; display: block; }

/* Logos sit on a chip that stays light in BOTH themes: the ManufactIQ
   wordmark is dark ink, and a customer's file may be anything, so the
   ground behind it is a fixed colour rather than the paper token (which
   goes dark with the theme and would swallow the mark). */
.sidebar__wordmark,
.sidebar__logo,
.sidebar__mark--collapsed-only { background: #FFFFFF; border-radius: 7px; }
.sidebar__wordmark { display: inline-flex; align-items: center; flex: none; padding: 5px 9px; }
.sidebar__wordmark img { height: 20px; width: auto; display: block; }
/* The customer's logo is letterboxed into the chip and never cropped:
   whatever its shape, the whole thing shows. */
.sidebar__logo { display: inline-flex; align-items: center; justify-content: center;
                 flex: none; height: 36px; max-width: 168px; padding: 4px 8px; }
.sidebar__logo img { display: block; max-height: 28px; max-width: 152px;
                     width: auto; height: auto; object-fit: contain; }
.sidebar__mark--collapsed-only { display: none; }
.sidebar__mark--collapsed-only img { width: 22px; height: 22px; object-fit: contain; }
.sidebar__name--tenant span { text-transform: none; letter-spacing: 0; font-size: 12px;
                              color: var(--mq-nav-strong); overflow: hidden;
                              text-overflow: ellipsis; white-space: nowrap; max-width: 90px; }
.sidebar__name {
    display: flex; flex-direction: column; min-width: 0; line-height: 1.1;
}
.sidebar__name b { font-size: 15px; font-weight: 700; color: var(--mq-nav-strong);
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar__name span { font-size: 11px; letter-spacing: 0.08em;
                      text-transform: uppercase; color: var(--mq-nav-group); }

.sidenav {
    flex: 1 1 auto; overflow-y: auto; overflow-x: hidden;
    padding: var(--s3) var(--s2) var(--s4);
    display: flex; flex-direction: column; gap: 1px;
    scrollbar-width: thin;
}
.sidenav__group {
    font-size: 11px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--mq-nav-group);
    padding: var(--s4) var(--s3) var(--s1);
    white-space: nowrap; overflow: hidden;
}
.sidenav__group:first-child { padding-top: var(--s1); }
.sidenav a {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 10px;
    border-radius: 6px;
    border-left: 3px solid transparent;
    margin-left: -3px;
    font-size: 14.5px; line-height: 22px; font-weight: 500;
    color: var(--mq-nav-text);
    white-space: nowrap; overflow: hidden;
    position: relative;
}
.sidenav a .icon { width: 19px; height: 19px; opacity: 0.85; }
.sidenav a:hover {
    background: var(--mq-nav-surface); color: var(--mq-nav-strong);
    text-decoration: none;
}
.sidenav a.is-active {
    background: var(--mq-nav-surface);
    border-left-color: var(--mq-signal);
    color: var(--mq-nav-strong);
    font-weight: 600;
}
.sidenav a.is-active .icon { opacity: 1; }
.sidenav__label { overflow: hidden; text-overflow: ellipsis; }
.sidenav__count {
    margin-left: auto; font-size: 11px; font-weight: 600;
    padding: 0 6px; border-radius: var(--r-pill);
    background: var(--mq-nav-surface); color: var(--mq-nav-text);
    border: 1px solid var(--mq-nav-line);
}

.sidebar__foot {
    flex: none; padding: var(--s2);
    border-top: 1px solid var(--mq-nav-line);
    display: flex; align-items: center; gap: var(--s2);
}
.sidebar__foot .iconbtn { color: var(--mq-nav-text); }
.sidebar__foot .iconbtn:hover { background: var(--mq-nav-surface);
                                color: var(--mq-nav-strong); }
.sidebar__version { font-size: 11px; color: var(--mq-nav-group);
                    letter-spacing: 0.06em; text-transform: uppercase;
                    margin-left: auto; padding-right: var(--s2); white-space: nowrap; }

/* Collapsed: icons, a tooltip on hover, nothing else. */
html[data-nav="collapsed"] .sidebar__name,
html[data-nav="collapsed"] .sidenav__label,
html[data-nav="collapsed"] .sidenav__count,
html[data-nav="collapsed"] .sidebar__version { display: none; }
html[data-nav="collapsed"] .sidebar__brand { justify-content: center; padding: 0; }
html[data-nav="collapsed"] .sidebar__wordmark { display: none; }
html[data-nav="collapsed"] .sidebar__mark--collapsed-only { display: inline-flex; }
/* Collapsed, the customer's logo shrinks to a square chip - still whole. */
html[data-nav="collapsed"] .sidebar__logo { width: 36px; max-width: 36px; padding: 3px; }
html[data-nav="collapsed"] .sidebar__logo img { max-width: 30px; max-height: 30px; }
html[data-nav="collapsed"] .sidenav__group {
    padding: var(--s3) 0 var(--s1); text-align: center;
    font-size: 0; height: 17px;
}
html[data-nav="collapsed"] .sidenav__group::after {
    content: ""; display: block; height: 1px; margin: 8px 14px 0;
    background: var(--mq-nav-line);
}
html[data-nav="collapsed"] .sidenav a { justify-content: center; padding: 8px 0;
                                        margin-left: 0; border-left-width: 0;
                                        border-right: 3px solid transparent; }
html[data-nav="collapsed"] .sidenav a.is-active { border-right-color: var(--mq-signal); }
html[data-nav="collapsed"] .sidebar__foot { justify-content: center; }
html[data-nav="collapsed"] .sidebar__foot .iconbtn--collapse .icon { transform: rotate(180deg); }

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

.shell__main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
    position: sticky; top: 0; z-index: 40;
    display: flex; align-items: center; gap: var(--s3);
    height: var(--topbar-h); padding: 0 var(--s5);
    background: var(--mq-white);
    border-bottom: 1px solid var(--mq-mist);
}
.topbar__crumb {
    display: flex; align-items: center; gap: var(--s2); min-width: 0;
    font-size: 13px; color: var(--mq-steel);
}
.topbar__crumb a { color: var(--mq-steel); }
.topbar__crumb b { color: var(--mq-ink); font-weight: 600;
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar__crumb .icon { width: 14px; height: 14px; color: var(--mq-mist-2); }

/* The search box is a button that opens the palette. It looks like an
   input because that is what people reach for, and it works as a plain
   link to /search with JavaScript off. */
.topbar__search {
    margin-left: auto;
    display: inline-flex; align-items: center; gap: var(--s2);
    width: min(420px, 38vw); height: 36px; padding: 0 var(--s3);
    border: 1px solid var(--mq-mist); border-radius: 8px;
    background: var(--mq-paper); color: var(--mq-steel);
    font-family: inherit; font-size: 14px; cursor: pointer;
    text-align: left;
}
.topbar__search:hover { border-color: var(--mq-mist-2); text-decoration: none;
                        background: var(--mq-paper-2); }
.topbar__search span { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis;
                       white-space: nowrap; }
.topbar__search .icon { color: var(--mq-steel); }
.topbar__actions { display: flex; align-items: center; gap: var(--s1); }

.iconbtn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; padding: 0;
    border: 1px solid transparent; border-radius: 8px;
    background: transparent; color: var(--mq-steel);
    font-family: inherit; cursor: pointer;
}
.iconbtn .icon { width: 20px; height: 20px; }
.iconbtn:hover { background: var(--mq-paper); color: var(--mq-ink);
                 text-decoration: none; }
.iconbtn--framed { border-color: var(--mq-mist); background: var(--mq-white); }

/* Theme toggle: the sun shows in dark, the moon in light. */
.theme-toggle .icon--moon { display: inline-block; }
.theme-toggle .icon--sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon--moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon--sun { display: inline-block; }

.usermenu > summary {
    display: inline-flex; align-items: center; gap: var(--s2);
    padding: 3px 8px 3px 3px; border-radius: 999px;
    border: 1px solid transparent; cursor: pointer; list-style: none;
}
.usermenu > summary::-webkit-details-marker { display: none; }
.usermenu > summary:hover { background: var(--mq-paper); border-color: var(--mq-mist); }
.usermenu__who { display: flex; flex-direction: column; line-height: 1.15;
                 text-align: left; }
.usermenu__name { font-size: 13.5px; font-weight: 600; color: var(--mq-ink); }
.usermenu__tenant {
    font-size: 11.5px; color: var(--mq-steel);
    max-width: 20ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; border-radius: 50%; flex: none;
    background: var(--mq-plate); color: var(--mq-plate-text);
    font-size: 12px; font-weight: 600; letter-spacing: 0.04em;
}
.avatar--sm { width: 24px; height: 24px; font-size: 10px; }
.avatar--lg { width: 40px; height: 40px; font-size: 15px; vertical-align: middle; margin-right: var(--s2); }

/* ----------------------------------------------- support session bar

   The one place the interface shouts. A platform administrator inside a
   customer's data needs to know it without looking, so this takes the
   signal colour outright rather than the usual single-accent restraint -
   it is a warning, not a call to action. */

.supportbar {
    display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
    padding: var(--s2) var(--s5);
    background: var(--mq-staff-wash);
    border-bottom: 2px solid var(--mq-staff);
    font-size: 13.5px; line-height: 20px;
}
.supportbar__label {
    font-size: 11px; line-height: 16px; font-weight: 700;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: #FFFFFF; background: var(--mq-staff);
    padding: 2px var(--s2); border-radius: var(--r-button); flex: none;
}
.supportbar__text { flex: 1 1 320px; color: var(--mq-ink); }

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

.page { flex: 1 1 auto; width: 100%; max-width: 1480px; margin: 0 auto;
        padding: var(--s5) var(--s6) var(--s8); }
.page--narrow { max-width: 980px; }
.page--wide { max-width: none; }

.page__head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s5);
}
.page__title { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.page__title h1 { margin: 0; font-size: 26px; line-height: 32px; }
.page__title h1 .muted { font-weight: 500; }
.page__title .small { color: var(--mq-steel); }
.page__actions { display: flex; gap: var(--s2); flex-wrap: wrap;
                 align-items: center; }

.site-foot {
    max-width: 1480px; margin: 0 auto; width: 100%;
    padding: var(--s3) var(--s6) var(--s6);
    font-size: 11px; line-height: 16px; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--mq-steel);
    display: flex; justify-content: space-between; gap: var(--s4); flex-wrap: wrap;
}

/* ------------------------------------------ narrow screens: the strip

   Below a laptop the sidebar becomes a strip across the top: a 236 px
   column out of a 700 px screen is most of the screen.

   ONE ROW, SCROLLING SIDEWAYS, not a wrapped block. Fourteen
   destinations plus a company's own tabs wrap into four rows of dark
   chips on a phone, which pushes the actual page below the fold and is
   the difference between a phone layout and a shrunken desktop. A single
   scrolling row keeps the page where the thumb expects it, and the
   active item is scrolled into view because it is the one that matters.

   The group headings stay, inline and quiet, because "Sell  Dashboard
   Pipeline … Plan  Calendar" is still easier to scan than an
   undifferentiated run of fourteen words. */
@media (max-width: 1000px) {
    .app, html[data-nav="collapsed"] .app { display: block; }
    .sidebar { position: static; height: auto; overflow: visible; }
    .sidebar__brand { display: none; }
    .sidebar__foot { display: none; }
    .sidenav {
        width: auto; position: static; max-height: none;
        flex-direction: row; flex-wrap: nowrap; align-items: center;
        gap: 2px; padding: var(--s2) var(--s3);
        overflow-x: auto; overflow-y: hidden;
        /* Kinetic scrolling, and no scrollbar eating a line of type. */
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .sidenav::-webkit-scrollbar { display: none; }
    .sidenav__group, html[data-nav="collapsed"] .sidenav__group {
        padding: 0 var(--s2) 0 var(--s3); height: auto; font-size: 11px;
        flex: none; align-self: center;
        color: var(--mq-nav-group);
        border-left: 1px solid var(--mq-nav-line);
    }
    html[data-nav="collapsed"] .sidenav__group::after { display: none; }
    .sidenav__group:first-child { border-left: none; padding-left: 0; }
    .sidenav a, html[data-nav="collapsed"] .sidenav a {
        flex: none; white-space: nowrap; margin-left: 0;
        border-left: none; border-right: none;
        border-bottom: 3px solid transparent;
        padding: 4px var(--s3); font-size: 14px; border-radius: 6px 6px 0 0;
    }
    .sidenav a .icon { display: none; }
    .sidenav a.is-active, html[data-nav="collapsed"] .sidenav a.is-active {
        border-left: none; border-right: none;
        border-bottom-color: var(--mq-signal);
    }
    html[data-nav="collapsed"] .sidenav__label { display: inline; }
    .topbar { position: static; }
    .topbar__search { width: auto; flex: 1 1 200px; }
}

/* On a phone the top bar gives up everything but who you are and where
   you are, and the search gets its own full-width line. */
@media (max-width: 720px) {
    .topbar {
        height: auto; flex-wrap: wrap; gap: var(--s2);
        padding: var(--s2) var(--s3);
    }
    .topbar__crumb { display: none; }
    .topbar__search { flex: 1 1 100%; order: 3; height: 40px; font-size: 16px; }
    .usermenu__who { display: none; }
    .page { padding: var(--s4) var(--s3) var(--s6); }
    .page__title h1 { font-size: 22px; line-height: 28px; }
    .site-foot { padding: var(--s3); }
}

/* ============================================================ overlays */

/* A drop-down menu, built on <details> so it opens with no script and
   closes on a click outside with a little. The summary is styled like
   whatever button it stands in for. */
.menu { position: relative; display: inline-block; }
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.menu__list {
    position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
    min-width: 220px; padding: var(--s1);
    background: var(--mq-white); border: 1px solid var(--mq-mist);
    border-radius: var(--r-card); box-shadow: var(--shadow-lg);
}
.menu--left .menu__list { right: auto; left: 0; }
.menu--up .menu__list { top: auto; bottom: calc(100% + 6px); }
.menu__item, .menu__list a, .menu__list button {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 8px 10px; border: 0; border-radius: 6px;
    background: none; color: var(--mq-ink);
    font-family: inherit; font-size: 14px; line-height: 20px; font-weight: 500;
    text-align: left; cursor: pointer; white-space: nowrap;
}
.menu__list a:hover, .menu__list button:hover, .menu__item:hover {
    background: var(--mq-paper); text-decoration: none;
}
.menu__list .icon { width: 17px; height: 17px; color: var(--mq-steel); }
.menu__list .is-danger, .menu__list .is-danger .icon { color: var(--mq-danger); }
.menu__sep { height: 1px; margin: var(--s1) var(--s2); background: var(--mq-mist); }
.menu__head { padding: 6px 10px 2px; font-size: 11px; letter-spacing: 0.08em;
              text-transform: uppercase; color: var(--mq-steel); font-weight: 600; }
.menu__list form { margin: 0; }

/* Dialogs: quick-create forms and the palette. */
dialog.dialog {
    width: min(560px, calc(100vw - 32px)); padding: 0;
    border: 1px solid var(--mq-mist); border-radius: 12px;
    background: var(--mq-white); color: var(--mq-ink);
    box-shadow: var(--shadow-lg);
}
dialog.dialog::backdrop { background: rgba(20, 23, 26, 0.45);
                          backdrop-filter: blur(2px); }
.dialog__head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s3); padding: var(--s4) var(--s5);
    border-bottom: 1px solid var(--mq-mist);
}
.dialog__head h2 { margin: 0; font-size: 18px; line-height: 24px; }
.dialog__body { padding: var(--s5); }
.dialog__foot { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
                padding: var(--s3) var(--s5); border-top: 1px solid var(--mq-mist);
                background: var(--mq-paper); border-radius: 0 0 12px 12px; }
.dialog__errors { margin: 0 0 var(--s3); padding: var(--s2) var(--s3);
                  border-left: 3px solid var(--mq-danger); background: var(--mq-danger-wash);
                  border-radius: var(--r-button); font-size: 13.5px; }
.dialog__errors:empty { display: none; }

/* The command palette. One box, type anything, arrow keys and Enter. */
dialog.palette {
    width: min(640px, calc(100vw - 32px)); padding: 0; margin-top: 10vh;
    border: 1px solid var(--mq-mist); border-radius: 12px;
    background: var(--mq-white); color: var(--mq-ink);
    box-shadow: var(--shadow-lg); overflow: hidden;
}
dialog.palette::backdrop { background: rgba(20, 23, 26, 0.45); }
.palette__input {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s3) var(--s4); border-bottom: 1px solid var(--mq-mist);
}
.palette__input .icon { color: var(--mq-steel); width: 20px; height: 20px; }
.palette__input input {
    flex: 1 1 auto; border: 0; padding: 6px 0; background: none;
    font-size: 17px; line-height: 24px; color: var(--mq-ink); outline: none;
}
.palette__input input:focus { box-shadow: none; }
.palette__results { max-height: min(60vh, 520px); overflow-y: auto; padding: var(--s2); }
.palette__group { padding: var(--s2) var(--s2) 2px; font-size: 11px; letter-spacing: 0.08em;
                  text-transform: uppercase; color: var(--mq-steel); font-weight: 600; }
.palette__item {
    display: flex; align-items: center; gap: var(--s3);
    padding: 8px 10px; border-radius: 6px; color: var(--mq-ink);
    text-decoration: none; cursor: pointer;
}
.palette__item .icon { width: 18px; height: 18px; color: var(--mq-steel); flex: none; }
.palette__item:hover, .palette__item.is-active { background: var(--mq-paper);
                                                  text-decoration: none; }
.palette__item.is-active { box-shadow: inset 3px 0 0 var(--mq-signal); }
.palette__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.palette__title { font-size: 14.5px; font-weight: 500; overflow: hidden;
                  text-overflow: ellipsis; white-space: nowrap; }
.palette__sub { font-size: 12.5px; color: var(--mq-steel); overflow: hidden;
                text-overflow: ellipsis; white-space: nowrap; }
.palette__hint { display: flex; gap: var(--s4); flex-wrap: wrap;
                 padding: var(--s2) var(--s4); border-top: 1px solid var(--mq-mist);
                 background: var(--mq-paper); font-size: 12px; color: var(--mq-steel); }
.palette__empty { padding: var(--s6) var(--s4); text-align: center; color: var(--mq-steel); }

/* Toasts. The flashes still render in the page for anybody without
   scripting; with it, app.js lifts them into this stack, times them out
   and adds a close. Success fades; an error stays until dismissed. */
.flashes { margin-bottom: var(--s4); display: flex; flex-direction: column;
           gap: var(--s2); }
.flash {
    display: flex; align-items: flex-start; gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-radius: var(--r-card);
    border: 1px solid var(--mq-mist);
    border-left: 3px solid var(--mq-steel);
    background: var(--mq-white);
    font-size: 14px; line-height: 21px;
    box-shadow: var(--shadow);
}
.flash__body { flex: 1 1 auto; }
.flash__close { flex: none; margin: -4px -8px -4px 0; }
.flash--success { border-left-color: var(--mq-success); }
.flash--error   { border-left-color: var(--mq-danger); }
.flash--info    { border-left-color: var(--mq-info); }
.flash--warning { border-left-color: var(--mq-warning); }
.flash--success .flash__icon { color: var(--mq-success); }
.flash--error .flash__icon   { color: var(--mq-danger); }
.flash--info .flash__icon    { color: var(--mq-info); }
.flash--warning .flash__icon { color: var(--mq-warning); }
.flash__icon { flex: none; margin-top: 2px; }
.flashes--toasts {
    position: fixed; top: calc(var(--topbar-h) + 12px); right: var(--s4); z-index: 80;
    width: min(400px, calc(100vw - 32px)); margin: 0; pointer-events: none;
}
.flashes--toasts .flash { pointer-events: auto; box-shadow: var(--shadow-lg);
                          animation: toast-in 180ms ease-out; }
.flashes--toasts .flash.is-leaving { opacity: 0; transform: translateX(12px);
                                     transition: opacity 240ms, transform 240ms; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); }
                      to { opacity: 1; transform: none; } }
@media (max-width: 720px) {
    .flashes--toasts { top: var(--s2); right: var(--s2); left: var(--s2); width: auto; }
}

/* ========================================================== layout */

.grid { display: grid; gap: var(--s4); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Five figures in a row, or six: the platform console's totals. */
.grid--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.grid--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
/* A row of figures with cards beneath it: the same gap as between the cards. */
.grid--stats { margin-bottom: var(--s4); }
.grid--main  { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
.grid--aside { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); align-items: start; }
.grid--auto { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

@media (max-width: 1100px) {
    .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid--5, .grid--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .grid--3, .grid--main, .grid--aside { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
    .grid--2, .grid--4, .grid--5 { grid-template-columns: minmax(0, 1fr); }
    .grid--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.stack > * + * { margin-top: var(--s4); }
.stack--tight > * + * { margin-top: var(--s2); }
.stack > a { display: block; }
.divider { height: 1px; background: var(--mq-mist); margin: var(--s4) 0; }

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

.card {
    background: var(--mq-white);
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-card);
    margin-bottom: var(--s4);
    box-shadow: var(--shadow);
}
.card__head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s3); flex-wrap: wrap;
    padding: var(--s3) var(--s4);
    border-bottom: 1px solid var(--mq-mist);
}
.card__head h2, .card__head h3 { margin: 0; font-size: 16px; line-height: 24px;
                                 font-weight: 600; display: flex; align-items: center;
                                 gap: var(--s2); }
.card__head h2 .icon, .card__head h3 .icon { color: var(--mq-steel); }
.card__head .muted { font-size: 13px; }
.card__tools { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
               margin-left: auto; }
.card__body { padding: var(--s4); }
.card__body--flush { padding: 0; }
.card__body--flush + .card__foot { border-top: 1px solid var(--mq-mist); }
.card__foot {
    padding: var(--s3) var(--s4);
    border-top: 1px solid var(--mq-mist);
    background: var(--mq-paper);
    font-size: 13.5px; line-height: 20px;
    border-radius: 0 0 var(--r-card) var(--r-card);
}
.card__foot .totals { margin-bottom: var(--s2); }
.card--quiet { box-shadow: none; }
a.card:hover { border-color: var(--mq-mist-2); text-decoration: none;
               box-shadow: var(--shadow-md); }

/* Collapsible cards: a <details> with the head as its summary. */
details.card > summary.card__head { cursor: pointer; list-style: none; }
details.card > summary.card__head::-webkit-details-marker { display: none; }
details.card > summary.card__head::after {
    content: ""; width: 8px; height: 8px; flex: none; margin-left: auto;
    border-right: 1.75px solid var(--mq-steel); border-bottom: 1.75px solid var(--mq-steel);
    transform: rotate(45deg); transition: transform 120ms;
}
details.card[open] > summary.card__head::after { transform: rotate(-135deg); }
details.card:not([open]) > summary.card__head { border-bottom: none; }

/* ------------------------------------------------------ stat tiles */

.stat {
    background: var(--mq-white);
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-card);
    padding: var(--s4);
    display: block; color: inherit;
    box-shadow: var(--shadow);
    position: relative; min-width: 0;
}
a.stat:hover { border-color: var(--mq-mist-2); text-decoration: none;
               box-shadow: var(--shadow-md); }
.stat__label {
    font-size: 11.5px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--mq-steel);
    display: flex; align-items: center; gap: 6px;
}
.stat__label .icon { width: 15px; height: 15px; }
.stat__value {
    font-size: 28px; line-height: 34px; font-weight: 700;
    color: var(--mq-ink); margin-top: var(--s1);
    font-variant-numeric: tabular-nums;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stat__note { font-size: 13px; line-height: 20px; color: var(--mq-steel);
              margin-top: 2px; }
.stat__note a { font-weight: 500; }
.stat__spark { position: absolute; right: var(--s3); bottom: var(--s3);
               display: flex; align-items: flex-end; gap: 2px; height: 22px; }
.stat__spark i { width: 4px; background: var(--mq-mist-2); border-radius: 1px;
                 display: block; min-height: 2px; }
.stat__spark i.is-last { background: var(--mq-ink); }

/* The single orange element on a screen, where that is a figure
   rather than a button. Use once. */
.stat--lead .stat__value { color: var(--mq-signal-ink); }
.stat--danger .stat__value { color: var(--mq-danger); }
.stat--success .stat__value { color: var(--mq-success); }

/* A row of compact figures inside a card. */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        gap: var(--s3); }
.kpi { padding: var(--s2) var(--s3); border-left: 2px solid var(--mq-mist); }
.kpi__label { font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase;
              color: var(--mq-steel); font-weight: 600; }
.kpi__value { font-size: 20px; line-height: 26px; font-weight: 700;
              font-variant-numeric: tabular-nums; }
.kpi__note { font-size: 12.5px; color: var(--mq-steel); }

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

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.data { width: 100%; border-collapse: separate; border-spacing: 0;
             font-size: 14px; line-height: 20px; }
table.data th {
    text-align: left;
    padding: 10px var(--s4);
    background: var(--mq-paper);
    border-bottom: 1px solid var(--mq-mist);
    font-size: 11.5px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--mq-steel);
    white-space: nowrap;
    position: sticky; top: 0; z-index: 1;
}
table.data th a { color: inherit; }
table.data th a:hover { color: var(--mq-ink); text-decoration: none; }
table.data th.is-sorted a { color: var(--mq-ink); }
table.data td {
    padding: 10px var(--s4);
    border-bottom: 1px solid var(--mq-line-soft);
    vertical-align: top;
}
table.data tbody tr:last-child td { border-bottom: none; }
table.data tbody tr:hover td { background: var(--mq-paper-2); }
table.data td a { font-weight: 500; }
table.data td .small { line-height: 18px; }
table.data tr.is-muted td { color: var(--mq-steel); }
table.data td.actions { text-align: right; white-space: nowrap; }
table.data tr.is-done .row-title { text-decoration: line-through; color: var(--mq-steel); }
table.data td.actions form { display: inline; }
table.data tfoot th, table.data tfoot td { background: var(--mq-paper); position: static;
                                           border-top: 1px solid var(--mq-mist);
                                           border-bottom: none; }
table.data--tight th, table.data--tight td { padding: 7px var(--s3); }
table.data .row-title { font-weight: 600; }
table.data .row-sub { font-size: 12.5px; line-height: 17px; color: var(--mq-steel); }

/* A whole row that is one link: the first cell carries the anchor and
   the rest of the row is made clickable by app.js. */
table.data tr[data-href] { cursor: pointer; }

.empty { padding: var(--s8) var(--s4); text-align: center; color: var(--mq-steel); }
.empty__icon { color: var(--mq-mist-2); margin-bottom: var(--s2); }
.empty__icon .icon { width: 40px; height: 40px; stroke-width: 1.25; }
.empty__title { font-size: 16px; line-height: 24px; font-weight: 600;
                color: var(--mq-ink); margin-bottom: var(--s1); }
.empty__text { font-size: 14px; max-width: 46ch; margin: 0 auto; }
.empty__action { margin-top: var(--s4); }

/* ---------------------------------------------------------- badges */

.badge {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 1px 9px;
    border-radius: var(--r-pill);
    font-size: 12px; line-height: 18px; font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
    background: var(--mq-paper);
    color: var(--mq-steel);
    border: 1px solid var(--mq-mist);
    vertical-align: middle;
}
.badge--ink   { background: var(--mq-plate); color: var(--mq-plate-text);
                border-color: var(--mq-plate); }
.badge--steel { background: var(--mq-white); color: var(--mq-ink);
                border-color: var(--mq-steel); }
.badge--neutral { background: var(--mq-paper); color: var(--mq-steel); }
/* Status uses the system colours, never signal orange. */
.badge--success { background: var(--mq-success-wash); color: var(--mq-success);
                  border-color: var(--mq-success-line); }
.badge--warning { background: var(--mq-warning-wash); color: var(--mq-warning);
                  border-color: var(--mq-warning-line); }
.badge--danger  { background: var(--mq-danger-wash);  color: var(--mq-danger);
                  border-color: var(--mq-danger-line); }
.badge--info    { background: var(--mq-info-wash);    color: var(--mq-info);
                  border-color: var(--mq-info-line); }
.badge--dot::before {
    content: ""; width: 6px; height: 6px; border-radius: 50%;
    background: currentColor; flex: none;
}
.badge--lg { font-size: 13px; line-height: 22px; padding: 2px 11px; }
.badge .icon { width: 13px; height: 13px; }

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

.btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: 7px;
    min-height: 36px; padding: 6px 14px;
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-button);
    background: var(--mq-white);
    color: var(--mq-ink);
    font-family: inherit;
    font-size: 14px; line-height: 20px; font-weight: 600;
    cursor: pointer; white-space: nowrap; text-decoration: none;
    box-shadow: var(--shadow);
    transition: border-color 100ms, background 100ms, box-shadow 100ms;
}
.btn .icon { width: 17px; height: 17px; }
.btn:hover { border-color: var(--mq-mist-2); background: var(--mq-paper-2);
             text-decoration: none; }
.btn:active { box-shadow: none; }

/* The one orange element per screen. */
.btn--primary {
    background: var(--mq-signal);
    border-color: var(--mq-signal);
    color: var(--mq-signal-text);
}
.btn--primary:hover { background: var(--mq-signal-hover);
                      border-color: var(--mq-signal-hover); }
.btn--primary .icon { color: inherit; }

.btn--ink { background: var(--mq-plate); border-color: var(--mq-plate);
            color: var(--mq-plate-text); }
.btn--ink:hover { opacity: 0.92; background: var(--mq-plate); }
.btn--danger { color: var(--mq-danger); border-color: var(--mq-danger-line);
               background: var(--mq-white); }
.btn--danger:hover { background: var(--mq-danger-wash);
                     border-color: var(--mq-danger); }
.btn--success { color: var(--mq-success); border-color: var(--mq-success-line); }
.btn--success:hover { background: var(--mq-success-wash); border-color: var(--mq-success); }
.btn--ghost { background: transparent; border-color: transparent;
              color: var(--mq-steel); box-shadow: none; }
.btn--ghost:hover { background: var(--mq-mist); color: var(--mq-ink); }
.btn--sm { min-height: 28px; padding: 3px 9px; font-size: 12.5px; line-height: 18px; }
.btn--sm .icon { width: 14px; height: 14px; }
.btn--lg { min-height: 42px; padding: 9px 18px; font-size: 15px; }
.btn--block { width: 100%; justify-content: center; }
.btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.btn--icon { padding-left: 8px; padding-right: 8px; }

.btn-row { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }
.inline-form { display: inline; }
.inline-form .btn { vertical-align: middle; }

/* Segmented scope toggle, ink, not orange. */
.toggle { display: inline-flex; border: 1px solid var(--mq-mist);
          border-radius: var(--r-button); overflow: hidden; background: var(--mq-white); }
.toggle a, .toggle button {
    padding: 6px 12px; font-size: 13.5px; line-height: 20px; font-weight: 600;
    background: var(--mq-white); color: var(--mq-steel);
    border: 0; font-family: inherit; cursor: pointer;
}
.toggle a + a, .toggle button + button { border-left: 1px solid var(--mq-mist); }
.toggle a:hover, .toggle button:hover { background: var(--mq-paper); text-decoration: none; }
.toggle a.is-active, .toggle button.is-active { background: var(--mq-plate);
                                                 color: var(--mq-plate-text); }

/* Filter chips: the saved views along the top of a list. */
.chips { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }
.chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 12px; border-radius: var(--r-pill);
    border: 1px solid var(--mq-mist); background: var(--mq-white);
    color: var(--mq-steel); font-size: 13px; line-height: 18px; font-weight: 600;
    cursor: pointer;
}
.chip:hover { border-color: var(--mq-mist-2); color: var(--mq-ink); text-decoration: none; }
.chip.is-active { background: var(--mq-plate); border-color: var(--mq-plate);
                  color: var(--mq-plate-text); }
.chip__count { font-size: 11px; padding: 0 6px; border-radius: var(--r-pill);
               background: var(--mq-paper); color: var(--mq-steel); }
.chip.is-active .chip__count { background: rgba(255,255,255,0.18); color: inherit; }

/* --------------------------------------- editing from a queue

   An editable cell on a queue: a dropdown that saves as soon as it is
   changed, sitting in a table row without making the row taller than its
   neighbours.

   The `[hidden]` rule underneath is the important one, and it is general
   rather than specific to queues on purpose. The browser's own
   `[hidden] { display: none }` comes from the user-agent stylesheet,
   which ANY author `display` rule beats - so `.btn { display: inline-flex }`
   quietly made `button.hidden = true` do nothing at all, and the Save
   button that scripting is supposed to remove sat there under every
   dropdown. Anything in this file that sets `display` has the same trap
   waiting for it, so the fix belongs here and not in one component. */

[hidden] { display: none !important; }

.cell-edit { display: inline-flex; align-items: center; gap: var(--s1);
             margin: 0; max-width: 100%; }
.cell-edit select {
    width: auto; min-width: 7.5rem; max-width: 100%;
    min-height: 30px; padding: 3px 26px 3px 8px;
    font-size: 13.5px; line-height: 20px;
    box-shadow: none; border-color: transparent; background-color: transparent;
}
/* Reads as text until you go near it, so a column of dropdowns does not
   shout over the columns that are only being read. */
.cell-edit select:hover { border-color: var(--mq-mist);
                          background-color: var(--mq-white); }
.cell-edit select:focus { border-color: var(--mq-mist-2);
                          background-color: var(--mq-white); }
.cell-edit .btn { min-height: 30px; padding: 3px 10px; font-size: 13px; }
/* Saving, saved, refused. Three states and no layout shift between them:
   a cell that changes size when it saves makes the whole row jump, and a
   column of them makes the table dance. The mark is a left border that
   is always there and usually transparent. */
.cell-edit > select, .cell-edit > input, .cell-edit > .checkbox {
    border-left: 2px solid transparent;
    transition: border-color 140ms ease, opacity 140ms ease;
}
.cell-edit[data-saving] { opacity: 0.6; }
.cell-edit[data-state="saved"] > select,
.cell-edit[data-state="saved"] > input,
.cell-edit[data-state="saved"] > .checkbox { border-left-color: var(--mq-success); }
.cell-edit[data-state="failed"] > select,
.cell-edit[data-state="failed"] > input,
.cell-edit[data-state="failed"] > .checkbox { border-left-color: var(--mq-danger); }

/* The tick box, which is a tick box and not a Yes/No dropdown: one bit,
   one click. */
.cell-edit .checkbox { display: inline-flex; padding: 4px 8px; }

@media (prefers-reduced-motion: reduce) {
    .cell-edit > select, .cell-edit > input, .cell-edit > .checkbox {
        transition: none;
    }
}

/* ----------------------------------------------------------- forms */

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
             gap: var(--s4); }
.form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.field--wide { grid-column: 1 / -1; }
@media (max-width: 720px) {
    .form-grid, .form-grid--3, .form-grid--4 { grid-template-columns: minmax(0, 1fr); }
}

.field { display: flex; flex-direction: column; gap: var(--s1); min-width: 0; }
.field label, .field .label {
    font-size: 11.5px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--mq-steel);
    display: flex; align-items: center; gap: var(--s2);
}
.field label .label__aside { margin-left: auto; text-transform: none;
                             letter-spacing: 0; font-weight: 500; }
/* Words to be typed exactly - a name to confirm with - shown as they must be typed. */
.field label .label__exact { text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--mq-ink); }
.field .hint, .hint { font-size: 13px; line-height: 19px;
                      color: var(--mq-steel); }
.required::after { content: " *"; color: var(--mq-signal-ink); }
.field--inline { flex-direction: row; align-items: center; gap: var(--s2); }
.field--inline label { text-transform: none; letter-spacing: 0; font-size: 14px;
                       font-weight: 500; color: var(--mq-ink); }

input[type="text"], input[type="email"], input[type="password"], input[type="url"],
input[type="number"], input[type="date"], input[type="datetime-local"],
input[type="search"], input[type="tel"], select, textarea {
    width: 100%;
    min-height: 38px;
    padding: 7px 10px;
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-button);
    background: var(--mq-white);
    font-family: inherit;
    font-size: 15px;
    line-height: 22px;
    color: var(--mq-ink);
    box-shadow: var(--shadow);
}
select { padding-right: 30px; appearance: none; -webkit-appearance: none;
         background-image: linear-gradient(45deg, transparent 50%, var(--mq-steel) 50%),
                           linear-gradient(135deg, var(--mq-steel) 50%, transparent 50%);
         background-position: calc(100% - 15px) 55%, calc(100% - 10px) 55%;
         background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
select[multiple] { background-image: none; }
textarea { resize: vertical; min-height: 84px; line-height: 24px; }
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--mq-ink);
    box-shadow: var(--focus-ring);
}
input[readonly], input[disabled], select[disabled] {
    background: var(--mq-paper); color: var(--mq-steel); box-shadow: none;
}
input::placeholder, textarea::placeholder { color: var(--mq-mist-2); }
:root[data-theme="dark"] input::placeholder,
:root[data-theme="dark"] textarea::placeholder { color: #5B6068; }
.checkbox { flex-direction: row; align-items: center; gap: var(--s2); }
.checkbox input { width: 18px; height: 18px; min-height: 0; accent-color: var(--mq-ink);
                  box-shadow: none; margin: 0; }
.checkbox label { text-transform: none; letter-spacing: 0; font-size: 14px;
                  font-weight: 500; color: var(--mq-ink); }
input[type="checkbox"], input[type="radio"] { accent-color: var(--mq-ink); }

/* A switch, for the settings pages: a checkbox drawn as a toggle. */
.switch { display: inline-flex; align-items: center; gap: var(--s3); cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switch__track { width: 38px; height: 22px; border-radius: 11px; background: var(--mq-mist-2);
                 position: relative; transition: background 120ms; flex: none; }
.switch__track::after { content: ""; position: absolute; top: 3px; left: 3px;
                        width: 16px; height: 16px; border-radius: 50%;
                        background: var(--mq-white); transition: transform 120ms;
                        box-shadow: var(--shadow); }
.switch input:checked + .switch__track { background: var(--mq-success); }
.switch input:checked + .switch__track::after { transform: translateX(16px); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--mq-signal);
                                               outline-offset: 2px; }
.switch__text { font-size: 14px; font-weight: 500; }

.filters { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: flex-end; }
.filters .field { min-width: 150px; }
.filters .field--grow { flex: 1 1 240px; }
.filters .checkbox { min-height: 38px; }
.filters .btn { min-height: 38px; }

/* A picker with a "+ New" beside it: the select grows, the button stays. */
.picker { display: flex; gap: var(--s2); align-items: stretch; }
.picker select { flex: 1 1 auto; min-width: 0; }
.picker .btn { flex: none; }

/* File uploads. The picker is the browser's own - restyling it costs more
   than it returns - so only its surround is brought into line. */
input[type="file"] {
    width: 100%;
    padding: 6px 8px;
    border: 1px dashed var(--mq-mist-2);
    border-radius: var(--r-button);
    background: var(--mq-white);
    font-family: inherit;
    font-size: 13.5px; line-height: 20px;
    color: var(--mq-steel);
}
input[type="file"]:focus { outline: none; border-color: var(--mq-ink);
                           border-style: solid; }
.upload { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: flex-end; }
.upload__file { flex: 2 1 260px; }
.upload__note { flex: 3 1 220px; }

/* Line editors (quotes, orders, invoices, enquiry items). */
table.lines { width: 100%; border-collapse: collapse; font-size: 14px; }
table.lines th {
    text-align: left; padding: var(--s2) var(--s2);
    background: var(--mq-paper);
    border-bottom: 1px solid var(--mq-mist);
    font-size: 11.5px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase; color: var(--mq-steel);
    white-space: nowrap;
}
table.lines td { padding: var(--s1) 5px; border-bottom: 1px solid var(--mq-line-soft);
                 vertical-align: middle; }
table.lines tbody tr:hover td { background: var(--mq-paper-2); }
table.lines input, table.lines select { padding: 5px 8px; font-size: 14px;
                                         line-height: 20px; min-height: 34px;
                                         box-shadow: none; }
table.lines input.small { margin-top: 3px; font-size: 12.5px; min-height: 30px; }
table.lines td.num input { text-align: right; }
table.lines .btn--sm { min-height: 30px; }
.line-total { font-variant-numeric: tabular-nums; font-weight: 600;
              white-space: nowrap; }

.totals { margin-left: auto; width: min(340px, 100%); }
.totals dl { display: grid; grid-template-columns: 1fr auto;
             gap: var(--s1) var(--s4); margin: 0; font-size: 14px;
             line-height: 21px; }
.totals dt { color: var(--mq-steel); }
.totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.totals .grand { font-size: 20px; line-height: 28px; font-weight: 700;
                 color: var(--mq-ink); padding-top: var(--s2);
                 border-top: 1px solid var(--mq-mist); }

/* ------------------------------------------------------ pagination */

.pagination { display: flex; align-items: center; gap: var(--s1);
              flex-wrap: wrap; padding: var(--s3) var(--s4);
              border-top: 1px solid var(--mq-mist); }
.pagination a, .pagination span {
    padding: 3px 9px;
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-button);
    font-size: 13px;
    background: var(--mq-white);
}
.pagination a:hover { border-color: var(--mq-mist-2); text-decoration: none; }
.pagination .is-current { background: var(--mq-plate); border-color: var(--mq-plate);
                          color: var(--mq-plate-text); }
.pagination .is-disabled { color: var(--mq-mist-2); background: var(--mq-paper); }
.pagination__count { margin-left: auto; color: var(--mq-steel);
                     border: none !important; background: none !important; }

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

   The sections of a record page, one at a time. Without scripting every
   panel shows, one below the other, which is what the page was before.
   With it (html.js) the nav picks one. */

.tabs__nav {
    display: flex; gap: var(--s1); flex-wrap: wrap;
    margin-bottom: var(--s4); padding: 0 0 0;
    border-bottom: 1px solid var(--mq-mist);
}
.tabs__nav a {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 12px 10px; margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--mq-steel); font-size: 14px; font-weight: 600; white-space: nowrap;
}
.tabs__nav a:hover { color: var(--mq-ink); text-decoration: none; }
.tabs__nav a.is-active { color: var(--mq-ink); border-bottom-color: var(--mq-ink); }
.tabs__nav .tab__count { font-size: 11px; padding: 0 6px; border-radius: var(--r-pill);
                         background: var(--mq-paper); border: 1px solid var(--mq-mist);
                         color: var(--mq-steel); font-weight: 600; line-height: 16px; }
html.js .tabs__panel:not(.is-active) { display: none; }
html:not(.js) .tabs__nav { display: none; }
.tabs__panel > .card:last-child { margin-bottom: 0; }

/* -------------------------------------------------------- timeline */

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
    position: relative;
    padding: var(--s3) var(--s4) var(--s3) 44px;
    border-bottom: 1px solid var(--mq-line-soft);
}
.timeline li:last-child { border-bottom: none; }
.timeline li::before {
    content: "";
    position: absolute;
    left: 19px; top: 21px;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--mq-steel);
    box-shadow: 0 0 0 3px var(--mq-white);
}
.timeline li::after {
    content: ""; position: absolute; left: 22px; top: 32px; bottom: -4px;
    width: 2px; background: var(--mq-line-soft);
}
.timeline li:last-child::after { display: none; }
.timeline li[data-type="call"]::before       { background: var(--mq-info); }
.timeline li[data-type="meeting"]::before    { background: var(--mq-success); }
.timeline li[data-type="site_visit"]::before { background: var(--mq-success); }
.timeline li[data-type="email"]::before      { background: var(--mq-info); }
.timeline li[data-type="note"]::before       { background: var(--mq-mist-2); }
.timeline__meta { font-size: 12px; line-height: 18px; color: var(--mq-steel);
                  display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.timeline__body { margin-top: var(--s1); font-size: 14px; line-height: 21px;
                  color: var(--mq-steel); }

/* The quick note box above a timeline. One line until it is clicked. */
.quicknote { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--mq-mist);
             background: var(--mq-paper-2); }
.quicknote__row { display: flex; gap: var(--s2); align-items: flex-start; }
.quicknote__row select { flex: 0 0 130px; }
.quicknote__row input, .quicknote__row textarea { flex: 1 1 auto; }
.quicknote__more { display: flex; gap: var(--s2); align-items: center;
                   margin-top: var(--s2); flex-wrap: wrap; }
.quicknote__more textarea { min-height: 60px; }
html.js .quicknote:not(.is-open) .quicknote__more { display: none; }

/* ----------------------------------------------------------- board */

.board { display: flex; gap: var(--s3); overflow-x: auto;
         padding-bottom: var(--s2); align-items: flex-start; }
.board__col {
    flex: 0 0 292px;
    background: var(--mq-paper-2);
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-card);
    display: flex; flex-direction: column;
    max-height: calc(100vh - 220px); min-height: 160px;
}
.board__col.is-over { border-color: var(--mq-ink); box-shadow: var(--focus-ring); }
.board__head { padding: var(--s3) var(--s4);
               border-bottom: 1px solid var(--mq-mist); display: flex;
               align-items: baseline; justify-content: space-between; gap: var(--s2);
               flex: none; }
.board__title { font-size: 11.5px; line-height: 16px; font-weight: 600;
                letter-spacing: 0.08em; text-transform: uppercase;
                color: var(--mq-ink); }
.board__sub { font-size: 13px; line-height: 20px; color: var(--mq-steel);
              font-variant-numeric: tabular-nums; white-space: nowrap; }
.board__list { padding: var(--s2); display: flex; flex-direction: column;
               gap: var(--s2); min-height: 56px; overflow-y: auto; flex: 1 1 auto; }
.board__card {
    display: block;
    background: var(--mq-white);
    border: 1px solid var(--mq-mist);
    border-radius: 6px;
    padding: var(--s3);
    color: inherit;
    box-shadow: var(--shadow);
}
.board__card:hover { border-color: var(--mq-mist-2); text-decoration: none;
                     box-shadow: var(--shadow-md); }
.board__card .ref { font-size: 12px; line-height: 18px; color: var(--mq-steel);
                    display: flex; justify-content: space-between; gap: var(--s2); }
.board__card .title { font-weight: 600; font-size: 14px; line-height: 20px;
                      margin: 2px 0; }
.board__card .meta { display: flex; justify-content: space-between;
                     font-size: 12.5px; line-height: 18px;
                     color: var(--mq-steel); gap: var(--s2);
                     font-variant-numeric: tabular-nums; margin-top: 4px; }
.board__card[draggable="true"] { cursor: grab; }
.board__card.is-dragging { opacity: 0.5; }
.board__more { font-size: 13px; padding: var(--s1) var(--s2); }

/* A card you can move. The anchor keeps the whole card clickable; the
   move control sits below it, outside the link, because a select inside
   an anchor is a trap for a keyboard and for a thumb. */
.board__card--movable > a { display: block; color: inherit; }
.board__card--movable > a:hover { text-decoration: none; }
.board__move { display: flex; gap: var(--s1); margin-top: var(--s2);
               padding-top: var(--s2); border-top: 1px solid var(--mq-line-soft); }
.board__move select { flex: 1 1 auto; min-width: 0; font-size: 12.5px;
                      padding: 2px 24px 2px var(--s2); min-height: 28px; height: 28px;
                      box-shadow: none; }
.board__move .btn { padding: 2px var(--s2); min-height: 28px; line-height: 22px; }
.board__warn { color: var(--mq-danger); font-weight: 600; }
/* Dragging is an addition, never the only way: the select stays for a
   keyboard and for a thumb on a phone, where there is no drag. */

/* ------------------------------------------------------ charts */

.bars { display: flex; align-items: flex-end; gap: var(--s1); height: 168px;
        padding-top: var(--s2); }
.bars__item { flex: 1 1 0; display: flex; flex-direction: column;
              align-items: center; justify-content: flex-end; height: 100%;
              gap: var(--s1); min-width: 0; }
.bars__bar { width: 100%; background: var(--mq-ink); border-radius: 3px 3px 0 0;
             min-height: 2px; }
.bars__item:hover .bars__bar { background: var(--mq-steel); }
.bars__item .small { font-size: 11px; white-space: nowrap; overflow: hidden;
                     text-overflow: ellipsis; max-width: 100%; }
.bars__label { font-size: 11px; line-height: 16px; color: var(--mq-steel);
               white-space: nowrap; }

.meter { height: 6px; background: var(--mq-mist); border-radius: 3px;
         overflow: hidden; }
.meter__fill { height: 100%; background: var(--mq-ink); border-radius: 3px; }
.meter--success .meter__fill { background: var(--mq-success); }
.meter--warning .meter__fill { background: var(--mq-warning); }
.meter--danger .meter__fill { background: var(--mq-danger); }

/* Horizontal bars with labels: pipeline by stage and the like. */
.hbars { display: flex; flex-direction: column; gap: var(--s2); }
.hbar { display: grid; grid-template-columns: minmax(110px, 1fr) minmax(0, 2fr) auto;
        gap: var(--s3); align-items: center; font-size: 13.5px; }
.hbar__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hbar__label a { font-weight: 500; }
.hbar__value { font-variant-numeric: tabular-nums; white-space: nowrap;
               color: var(--mq-steel); text-align: right; }
.hbar .meter { height: 10px; border-radius: 5px; }

/* -------------------------------------------------- pipeline track
   The stage timeline on an enquiry: a row of chevrons, each one a
   submit button that moves the enquiry to that stage.

   Orange is not used here, it belongs to the primary action on the
   page. Progress is carried by ink and mist, and the closed states use
   the system colours, as the guidelines require for status.
   ------------------------------------------------------------------ */

.pipeline {
    display: flex;
    list-style: none;
    margin: 0;
    padding: 0;
    gap: 2px;
    overflow-x: auto;
}
.pipeline__step { flex: 1 1 0; min-width: 118px; display: flex; }
.pipeline__step form { flex: 1; display: flex; }

.pipeline__btn {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 1px;
    min-height: 50px;
    padding: 6px 10px 6px 26px;
    border: 0;
    background: var(--mq-paper);
    color: var(--mq-steel);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    /* Arrow on the right, notch on the left. */
    clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%,
                       calc(100% - 13px) 100%, 0 100%, 13px 50%);
}
.pipeline__step:first-child .pipeline__btn {
    padding-left: 14px; border-radius: 6px 0 0 6px;
    clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%,
                       calc(100% - 13px) 100%, 0 100%);
}
.pipeline__step:last-child .pipeline__btn {
    border-radius: 0 6px 6px 0;
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 13px 50%);
}
.pipeline__step:only-child .pipeline__btn {
    padding-left: 14px;
    clip-path: none;
}
.pipeline__btn:hover { filter: brightness(0.94); }
:root[data-theme="dark"] .pipeline__btn:hover { filter: brightness(1.2); }
/* The closed outcome is rendered as a span, a state, not a control. */
span.pipeline__btn { cursor: default; }
span.pipeline__btn:hover { filter: none; }
.pipeline__btn:focus-visible { outline: 2px solid var(--mq-signal);
                               outline-offset: -3px; }

.pipeline__name {
    font-size: 11.5px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.06em; text-transform: uppercase;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pipeline__meta { font-size: 12px; line-height: 14px; opacity: 0.75;
                  font-weight: 400; white-space: nowrap; }

/* Stages already passed. */
.pipeline__step.is-done .pipeline__btn {
    background: var(--mq-mist); color: var(--mq-ink);
}
/* Where the enquiry is now. */
.pipeline__step.is-current .pipeline__btn {
    background: var(--mq-plate); color: var(--mq-plate-text);
}
.pipeline__step.is-won .pipeline__btn {
    background: var(--mq-success); color: #FFFFFF;
}
.pipeline__step.is-lost .pipeline__btn {
    background: var(--mq-danger); color: #FFFFFF;
}

.pipeline-foot {
    display: flex; align-items: flex-end; gap: var(--s3);
    flex-wrap: wrap; margin-top: var(--s4);
}
.pipeline-foot .field { flex: 1 1 260px; }

.pipeline-outcome {
    display: flex; align-items: center; gap: var(--s3);
    margin-top: var(--s4); padding-top: var(--s4);
    border-top: 1px solid var(--mq-mist);
    flex-wrap: wrap;
}
/* As a fold-out: the summary is the one line that shows when closed. */
details.pipeline-outcome { display: block; }
details.pipeline-outcome > summary { cursor: pointer; list-style: none; }
details.pipeline-outcome > summary::-webkit-details-marker { display: none; }
details.pipeline-outcome > summary::before { content: "▸ "; color: var(--mq-mist-2); }
details.pipeline-outcome[open] > summary::before { content: "▾ "; }
details.pipeline-outcome[open] > summary { margin-bottom: var(--s3); }
details.card__foot > summary { cursor: pointer; list-style: none; font-weight: 600;
                               color: var(--mq-steel); }
details.card__foot > summary::-webkit-details-marker { display: none; }
details.card__foot > summary::before { content: "▸ "; color: var(--mq-mist-2); }
details.card__foot[open] > summary::before { content: "▾ "; }
details.card__foot[open] > summary { margin-bottom: var(--s3); }

/* Compact progress track for list rows. */
.track { display: flex; gap: 2px; margin-top: 5px; min-width: 68px; }
.track i { flex: 1 1 0; height: 3px; border-radius: 2px;
           background: var(--mq-mist); }
.track i.is-done { background: var(--mq-ink); }
.track.is-won  i.is-done { background: var(--mq-success); }
.track.is-lost i.is-done { background: var(--mq-danger); }

/* ------------------------------------------------------ definition */

.deflist { display: grid; grid-template-columns: minmax(110px, auto) 1fr;
           gap: var(--s2) var(--s4); font-size: 14px; line-height: 21px;
           margin: 0; }
.deflist dt { color: var(--mq-steel); }
.deflist dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.deflist--tight { gap: var(--s1) var(--s3); font-size: 13.5px; }

/* ======================================================= the journey

   Enquiry > Quote > Order > Invoice: the four stations a job passes
   through, drawn the same way at the top of all four record pages.

   Each station says what it is, which record stands there, and where it
   has got to. The one you are on is filled ink; the ones not raised yet
   are dashed, because an outline that is not there yet should not look
   like a link; a lost or cancelled one is red, a late one amber.
   ------------------------------------------------------------------ */

.journey {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--s2); margin-bottom: var(--s5);
}
.journey__step {
    display: flex; align-items: center; gap: var(--s3);
    padding: 10px 14px; min-width: 0;
    border: 1px solid var(--mq-mist); border-radius: var(--r-card);
    background: var(--mq-white); color: var(--mq-ink);
    position: relative; box-shadow: var(--shadow);
}
a.journey__step:hover { border-color: var(--mq-mist-2); text-decoration: none;
                        box-shadow: var(--shadow-md); }
.journey__step::after {
    /* The arrow between stations. */
    content: ""; position: absolute; right: -9px; top: 50%; z-index: 1;
    width: 10px; height: 10px; transform: translateY(-50%) rotate(45deg);
    border-top: 1px solid var(--mq-mist); border-right: 1px solid var(--mq-mist);
    background: var(--mq-white);
}
.journey__step:last-child::after { display: none; }
.journey__icon {
    width: 34px; height: 34px; flex: none; border-radius: 8px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--mq-paper); color: var(--mq-steel);
}
.journey__icon .icon { width: 18px; height: 18px; }
.journey__text { min-width: 0; display: flex; flex-direction: column; }
.journey__name { font-size: 11px; line-height: 14px; font-weight: 600;
                 letter-spacing: 0.08em; text-transform: uppercase; color: var(--mq-steel); }
.journey__label { font-size: 14px; line-height: 20px; font-weight: 600;
                  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.journey__sub { font-size: 12.5px; line-height: 17px; color: var(--mq-steel);
                overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.journey__step--here { background: var(--mq-plate); color: var(--mq-plate-text);
                       border-color: var(--mq-plate); }
.journey__step--here::after { background: var(--mq-plate); border-color: var(--mq-plate); }
.journey__step--here .journey__icon { background: rgba(255,255,255,0.14); color: inherit; }
:root[data-theme="dark"] .journey__step--here .journey__icon { background: rgba(0,0,0,0.12); }
.journey__step--here .journey__name, .journey__step--here .journey__sub { color: inherit;
                                                                          opacity: 0.75; }
.journey__step--todo { border-style: dashed; background: transparent; box-shadow: none; }
.journey__step--todo::after { border-style: dashed; background: var(--mq-paper); }
.journey__step--todo .journey__icon { background: transparent;
                                      border: 1px dashed var(--mq-mist-2); }
.journey__step--todo .journey__label { color: var(--mq-steel); font-weight: 500; }
.journey__step--done .journey__icon { background: var(--mq-success-wash); color: var(--mq-success); }
.journey__step--lost .journey__icon { background: var(--mq-danger-wash); color: var(--mq-danger); }
.journey__step--lost .journey__sub { color: var(--mq-danger); }
.journey__step--late .journey__icon { background: var(--mq-warning-wash); color: var(--mq-warning); }
.journey__step--late .journey__sub { color: var(--mq-warning); font-weight: 600; }

@media (max-width: 900px) {
    .journey { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .journey__step::after { display: none; }
}

/* Legacy trail (kept for any page not yet on the journey strip). */
.trail {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: var(--s1) var(--s2);
    margin-bottom: var(--s2);
    font-size: 12px; line-height: 18px; font-weight: 600;
    letter-spacing: 0.02em;
}
.trail__step {
    display: inline-block; padding: 1px 8px;
    border-radius: var(--r-button);
    border: 1px solid var(--mq-mist);
    background: var(--mq-white); color: var(--mq-steel);
    text-decoration: none; white-space: nowrap;
}
a.trail__step:hover, a.trail__step:focus-visible {
    border-color: var(--mq-steel); color: var(--mq-ink);
}
.trail__step--here { background: var(--mq-plate); border-color: var(--mq-plate);
                     color: var(--mq-plate-text); }
.trail__step--todo { border-style: dashed; background: transparent;
                     color: var(--mq-steel); opacity: 0.75; }
.trail__none { font-weight: 400; font-style: italic; }
.trail__arrow { color: var(--mq-mist); font-size: 14px; }

/* ======================================================= next steps

   The one action that moves a job along, said plainly, with the two or
   three that make sense beside it. Drawn from crm/journey.py. The first
   action is the page's single orange element; nothing else on the page
   may be.
   ------------------------------------------------------------------ */

.nextsteps {
    display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap;
    padding: var(--s4) var(--s5);
    border: 1px solid var(--mq-mist); border-left: 3px solid var(--mq-signal);
    border-radius: var(--r-card);
    background: var(--mq-white); box-shadow: var(--shadow);
    margin-bottom: var(--s4);
}
.nextsteps--quiet { border-left-color: var(--mq-mist-2); }
.nextsteps__text { flex: 1 1 260px; min-width: 0; }
.nextsteps__eyebrow { font-size: 11px; line-height: 16px; font-weight: 600;
                      letter-spacing: 0.08em; text-transform: uppercase;
                      color: var(--mq-steel); display: flex; align-items: center; gap: 6px; }
.nextsteps__title { font-size: 17px; line-height: 24px; font-weight: 600; margin: 2px 0 0; }
.nextsteps__hint { font-size: 13.5px; line-height: 20px; color: var(--mq-steel); margin: 2px 0 0; }
.nextsteps__actions { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.nextsteps__actions form { margin: 0; }

/* The won and lost forms fold out of the panel. */
.nextsteps__form { flex: 1 1 100%; padding-top: var(--s3); border-top: 1px solid var(--mq-mist); }
.nextsteps__form .form-grid { gap: var(--s3); }
html.js .nextsteps__form:not(.is-open) { display: none; }
.nextsteps__form .btn-row { margin-top: var(--s3); }

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

.attention { list-style: none; margin: 0; padding: 0; }
.attention__item { display: flex; align-items: center; gap: var(--s3);
                   padding: 10px var(--s4); border-bottom: 1px solid var(--mq-line-soft);
                   color: inherit; }
.attention__item:last-child { border-bottom: none; }
.attention__item:hover { background: var(--mq-paper-2); text-decoration: none; }
.attention__icon { width: 32px; height: 32px; flex: none; border-radius: 8px;
                   display: inline-flex; align-items: center; justify-content: center;
                   background: var(--mq-paper); color: var(--mq-steel); }
.attention__icon .icon { width: 17px; height: 17px; }
.attention__item--danger .attention__icon { background: var(--mq-danger-wash); color: var(--mq-danger); }
.attention__item--warning .attention__icon { background: var(--mq-warning-wash); color: var(--mq-warning); }
.attention__item--info .attention__icon { background: var(--mq-info-wash); color: var(--mq-info); }
.attention__text { flex: 1 1 auto; min-width: 0; }
.attention__title { font-size: 14px; line-height: 20px; font-weight: 600;
                    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attention__sub { font-size: 12.5px; line-height: 17px; color: var(--mq-steel);
                  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attention__go { color: var(--mq-mist-2); flex: none; }

/* A record's header row of facts: customer, contact, owner, dates. */
.facts { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5); font-size: 13.5px;
         color: var(--mq-steel); align-items: center; }
.facts b { color: var(--mq-ink); font-weight: 600; }
.facts .icon { width: 15px; height: 15px; vertical-align: -3px; margin-right: 3px; }

/* The settings pages: a section heading with its own save button. */
.settings-section { scroll-margin-top: calc(var(--topbar-h) + 12px); }
.settings-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
                 gap: var(--s3) var(--s4); }
@media (max-width: 720px) { .settings-grid { grid-template-columns: minmax(0, 1fr); } }
.settings-row { display: grid; grid-template-columns: minmax(140px, 1fr) minmax(0, 1fr) minmax(0, 1fr);
                gap: var(--s3); align-items: center; padding: var(--s2) 0;
                border-bottom: 1px solid var(--mq-line-soft); }
.settings-row:last-child { border-bottom: none; }
.settings-row__name { font-weight: 600; font-size: 14px; }
.settings-row__name .small { display: block; font-weight: 400; color: var(--mq-steel); }
@media (max-width: 720px) { .settings-row { grid-template-columns: minmax(0, 1fr); } }
.example { font-family: var(--mono); font-size: 13px; background: var(--mq-paper);
.settings-row .field--wide { grid-column: span 2; }
.example--big { font-size: 18px; padding: 6px 12px; letter-spacing: 0.04em; }
           padding: 2px 6px; border-radius: 4px; border: 1px solid var(--mq-mist); }

/* Suggestion chips under a text box. */
.suggest { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.suggest button { border: 1px solid var(--mq-mist); background: var(--mq-white);
                  border-radius: var(--r-pill); font-family: inherit; font-size: 12px;
                  padding: 1px 9px; color: var(--mq-steel); cursor: pointer; }
.suggest button:hover { color: var(--mq-ink); border-color: var(--mq-mist-2); }

/* --------------------------------------------------- section sub-nav

   Used inside the administration area. Ink and steel only, it is
   navigation, not the one important action on the page. */

.subnav {
    display: flex; gap: var(--s1); flex-wrap: wrap;
    margin: calc(var(--s5) * -1 + var(--s1)) 0 var(--s5);
    padding-bottom: var(--s2);
    border-bottom: 1px solid var(--mq-mist);
}
.subnav a {
    color: var(--mq-steel);
    padding: 5px 11px;
    border-radius: var(--r-button);
    font-size: 13.5px; line-height: 20px; font-weight: 600;
    display: inline-flex; align-items: center; gap: 6px;
}
.subnav a:hover { background: var(--mq-mist); color: var(--mq-ink);
                  text-decoration: none; }
.subnav a.is-active { background: var(--mq-plate); color: var(--mq-plate-text); }

/* ----------------------------------------------------------- login
   Ink flood, as used for covers and the app splash screen. */

.login-page {
    min-height: 100vh;
    display: flex; align-items: center; justify-content: center;
    background: #14171A;
    padding: var(--s6);
}
.login-card {
    width: min(408px, 100%);
    background: #FFFFFF; color: #14171A;
    border-radius: var(--r-card);
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}
.login-card__head { padding: var(--s8) var(--s8) var(--s5); }
.login-card__head img { width: 208px; max-width: 100%; height: auto;
                        display: block; }
.login-card__rule { width: 64px; height: 3px; background: var(--mq-signal);
                    margin-top: var(--s5); }
.login-card__body { padding: 0 var(--s8) var(--s8); }
/* The pages reached from an emailed link: a heading, then the form. */
.login-card__title { font-size: 22px; line-height: 28px; margin: 0 0 var(--s2); }
.offer-points { margin: var(--s3) 0 var(--s4); padding-left: 1.1em; font-size: 14px;
                line-height: 1.5; color: var(--mq-ink); }
.offer-points li + li { margin-top: var(--s1); }
.offer-later { margin-top: var(--s2); }
.offer-later + .hint { margin-top: var(--s3); }
.login-card__foot { padding: var(--s3) var(--s8); background: #F7F6F2;
                    border-top: 1px solid #E4E2DC;
                    font-size: 14px; line-height: 21px; color: #5B6068; }

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

.tag-row { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center;
           font-size: 14px; }
/* The outcome panel's won-only fields. `hidden` is set by app.js, and
   is spelled out here rather than trusted to the UA stylesheet -
   a display rule further up this file would otherwise beat it. */
.won-only > * + * { margin-top: var(--s4); }
.won-only[hidden] { display: none; }

/* The "if you are marking this won" block on an enquiry. Set apart from
   the note field above it so it is plainly conditional, without a border
   heavy enough to read as its own card. */
.outcome-won {
    border-left: 2px solid var(--mq-mist);
    padding-left: var(--s3);
    margin-top: var(--s3);
}
.outcome-won > * + * { margin-top: var(--s3); }
.outcome-won .hint { margin: 0 0 var(--s2); }

/* ------------------------------------------------------------------
   Notes and activity above the tabs (partials/_notes_card.html).
   ------------------------------------------------------------------ */
.notes-card { margin-bottom: var(--s4); }
.notes-card .quicknote { border-bottom: 0; }
.notes-card__recent { border-top: 1px solid var(--mq-mist); }
.notes-card__recent .timeline li { padding-top: var(--s2); padding-bottom: var(--s2); }
.notes-card__recent .timeline__body { max-height: 66px; overflow: hidden; }
.notes-card__more { padding: var(--s2) var(--s4) var(--s3); }
@media print { .notes-card { display: none; } }

/* ------------------------------------------------------------------
   @mentions in notes.
   ------------------------------------------------------------------ */
.mention { font-weight: 600; color: var(--mq-signal-ink, var(--mq-ink)); background: var(--mq-signal-wash, var(--mq-paper));
           border-radius: 4px; padding: 0 4px; }
.mention-menu { position: relative; z-index: 5; margin-top: 4px; padding: 4px; display: flex; flex-direction: column;
                background: var(--mq-white); border: 1px solid var(--mq-mist); border-radius: 8px;
                box-shadow: var(--shadow-lg); max-width: 320px; }
.mention-menu__item { display: flex; align-items: center; gap: 8px; text-align: left; padding: 6px 10px;
                      border: 0; background: transparent; border-radius: 6px; font: inherit; color: var(--mq-ink); cursor: pointer; }
.mention-menu__item .icon { width: 14px; height: 14px; color: var(--mq-steel); }
.mention-menu__item:hover, .mention-menu__item.is-active { background: var(--mq-paper); }

/* ------------------------------------------------------------------
   "Already here?" - duplicate warnings on the company and contact forms.
   ------------------------------------------------------------------ */
.dupe-warning { margin: var(--s4) var(--s5) 0; padding: var(--s3) var(--s4);
                border-left: 3px solid var(--mq-warning); background: var(--mq-warning-wash);
                border-radius: var(--r-button); }
.dupe-warning--dialog { margin: 0 0 var(--s3); }
.dupe-warning:empty { display: none; }
.dupe-warning__head { margin-bottom: var(--s2); line-height: 22px; }
.dupe-list { list-style: none; margin: 0 0 var(--s3); padding: 0; }
.dupe-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 4px 0;
                border-top: 1px solid rgba(0, 0, 0, 0.06); }
.dupe-list li:first-child { border-top: 0; }
.dupe-list a { font-weight: 600; }
.dupe-hint { margin-top: 6px; padding: var(--s2) var(--s3); font-size: 13px; line-height: 20px;
             border-left: 3px solid var(--mq-warning); background: var(--mq-warning-wash);
             border-radius: var(--r-button); }
.dupe-hint a { font-weight: 600; }
.dupe-hint__why { color: var(--mq-steel); font-size: 12px; }
.dupe-empty { padding: var(--s4) var(--s5); margin: 0; }

/* ------------------------------------------------------------------
   Two-step sign-in (auth/verify.html, two_factor_setup.html, account).
   ------------------------------------------------------------------ */
.check { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer;
         text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--mq-ink); }
.check input[type="checkbox"] { width: 16px; height: 16px; margin: 0; }
.twofa-setup { display: flex; gap: var(--s4); align-items: flex-start; flex-wrap: wrap; }
.twofa-qr { width: 220px; height: 220px; flex: 0 0 auto; padding: 8px; background: #fff;
            border: 1px solid var(--mq-mist); border-radius: 8px; }
.twofa-setup > div { flex: 1 1 220px; }
.twofa-key { font-size: 15px; letter-spacing: 0.08em; word-break: break-all; margin: 0;
             padding: var(--s2) var(--s3); background: var(--mq-paper); border-radius: var(--r-button); }
.twofa-codes { list-style: none; margin: 0; padding: 0; columns: 2; font-size: 18px; line-height: 34px;
               letter-spacing: 0.06em; }
@media print { .twofa-codes { columns: 1; } }

/* ------------------------------------------------------------------
   The customer's copy of a quotation (quotes/print.html).
   ------------------------------------------------------------------ */
.doc__letterhead { text-align: right; }
.doc__intro { margin: var(--s4) 0 0; line-height: 22px; }
.doc__closing { margin: var(--s4) 0 0; line-height: 22px; }
.doc__foot { display: flex; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; }
.doc__credit { margin-left: auto; }
.doc-switches { margin-top: var(--s3); }
.send-options { display: flex; gap: var(--s4); flex-wrap: wrap; }
.send-options .check { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer;
                       text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--mq-ink); }
.send-options .check input { width: 16px; height: 16px; margin: 0; }
@media print {
    .doc__foot { border-top: 1px solid var(--mq-mist); }
}

/* ------------------------------------------------------------------
   Importing quote lines from a spreadsheet (quotes/form.html dialog).
   ------------------------------------------------------------------ */
dialog.dialog--wide { width: min(920px, calc(100vw - 32px)); }

.dropzone {
    position: relative; display: flex; flex-direction: column; align-items: center;
    gap: var(--s1); padding: var(--s5) var(--s4); text-align: center; cursor: pointer;
    border: 2px dashed var(--mq-mist); border-radius: 12px; background: var(--mq-paper);
    transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone:hover, .dropzone:focus-within, .dropzone.is-over {
    border-color: var(--mq-plate); background: var(--mq-paper-2);
}
.dropzone.is-over { border-style: solid; }
/* The real file box stays in the page for the keyboard and the browser's
   own chooser; the label is what people see. */
.dropzone input[type="file"] {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); border: 0; opacity: 0;
}
.dropzone__icon .icon { width: 30px; height: 30px; color: var(--mq-steel); }
.dropzone__title { font-weight: 600; font-size: 15px; }
.dropzone__hint { font-size: 13px; line-height: 19px; color: var(--mq-steel); max-width: 56ch; }

.import-help { margin-top: var(--s4); }
.import-help p { margin: 0 0 var(--s2); }
.import-busy { margin: var(--s5) 0; text-align: center; color: var(--mq-steel); }
.import-summary { margin: 0 0 var(--s3); line-height: 22px; }

.import-notices:empty { display: none; }
.import-notice { margin: 0 0 var(--s2); padding: var(--s2) var(--s3); border-radius: var(--r-button);
                 font-size: 13.5px; line-height: 19px; border-left: 3px solid var(--mq-info);
                 background: var(--mq-info-wash); }
.import-notice--warning { border-left-color: var(--mq-warning); background: var(--mq-warning-wash); }

.import-preview { max-height: 44vh; overflow: auto; border: 1px solid var(--mq-mist); border-radius: 8px; }
.import-preview table.data { margin: 0; font-size: 13.5px; }
.import-preview table.data th { position: sticky; top: 0; z-index: 1; background: var(--mq-white); }
.import-preview tr.is-error td { background: var(--mq-danger-wash); }
.import-preview td:nth-child(2), .import-preview td:nth-child(4), .import-preview td:nth-child(6), .import-preview td:nth-child(7) { white-space: nowrap; }
.import-preview td:nth-child(8) { min-width: 200px; }
.import-preview .notes { margin-top: 3px; font-size: 12.5px; line-height: 17px; color: var(--mq-steel); }

.import-mode { margin: var(--s3) 0 0; padding: var(--s2) var(--s4) var(--s3);
               border: 1px solid var(--mq-mist); border-radius: 8px;
               display: flex; gap: var(--s4); flex-wrap: wrap; }
.import-mode legend { padding: 0 6px; font-size: 13px; font-weight: 600; color: var(--mq-steel); }
.import-mode label { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
.import-mode input[type="radio"] { width: 16px; height: 16px; margin: 0; }

@media print { .trail, .journey, .nextsteps { display: none; } }
.error-page { max-width: 520px; margin: 80px auto; text-align: center; }
.error-page__code { font-size: 56px; line-height: 59px; font-weight: 700;
                    letter-spacing: -0.01em; color: var(--mq-mist-2); }

/* Keyboard shortcut help. */
.shortcuts { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
             gap: var(--s2) var(--s5); }
.shortcuts div { display: flex; justify-content: space-between; align-items: center;
                 gap: var(--s3); padding: 6px 0; border-bottom: 1px solid var(--mq-line-soft);
                 font-size: 14px; }

/* A skeleton line for the palette while it loads. */
.skeleton { display: inline-block; height: 12px; border-radius: 6px;
            background: linear-gradient(90deg, var(--mq-mist) 25%, var(--mq-paper) 50%, var(--mq-mist) 75%);
            background-size: 200% 100%; animation: shimmer 1.2s infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }


/* ========================================================= calendar

   An Outlook-shaped diary: month grid, timed week and day, agenda list.
   Read-only, so nothing here is draggable and nothing looks as though it
   ought to be.

   Two rules from the guidelines drive the colour. Signal orange is NOT
   used for events - it belongs to the one important action on the page,
   and a diary of thirty orange chips would read as thirty alarms. Events
   take the system colours through a 3 px left bar, which is enough to
   tell a promised order from a task at a glance and still leaves the page
   mostly ink, steel and mist.

   Positions come out of crm/calendarview.py as integers, because the
   Content-Security-Policy allows no inline styles: an appointment cannot
   be placed with style="top:214px". The .cal-at-*, .cal-for-*, .cal-of-*
   and .cal-lane-* classes below are the whole of that translation.
   ------------------------------------------------------------------ */

:root {
    /* One half-hour row. Also the unit the week grid is built from. */
    --cal-slot: 22px;
    --cal-gutter: 56px;
    /* A month cell tall enough for three chips and the date. */
    --cal-cell: 118px;
}

.cal__bar { flex-wrap: wrap; gap: var(--s3); }
.cal__move { display: flex; gap: var(--s1); }
.cal__period {
    /* The one thing on the bar somebody reads from across the desk. */
    margin: 0; font-size: 22px; line-height: 28px; font-weight: 600;
    flex: 1 1 auto; text-align: center;
}
.cal__views { flex: none; }

/* ------------------------------------------------- calendar filters */

.cal__filters { border-bottom: 1px solid var(--mq-mist); }
.cal__filters .filters { align-items: flex-start; }

.cal__kinds {
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-button);
    padding: var(--s2) var(--s3) var(--s3);
    margin: 0;
    display: flex; flex-wrap: wrap; gap: var(--s1) var(--s4);
    flex: 1 1 520px; min-width: 0;
}
.cal__kinds legend { padding: 0 var(--s1); }
.cal__kind {
    display: flex; align-items: center; gap: var(--s2);
    font-size: 14px; line-height: 21px; cursor: pointer;
    white-space: nowrap;
}
.cal__kind input { width: auto; accent-color: var(--mq-ink); margin: 0; }
.cal__swatch {
    width: 10px; height: 10px; flex: none; border-radius: 2px;
    background: var(--mq-ink);
}
.cal__swatch--info    { background: var(--mq-info); }
.cal__swatch--success { background: var(--mq-success); }
.cal__swatch--warning { background: var(--mq-warning); }
.cal__swatch--danger  { background: var(--mq-danger); }
.cal__swatch--steel   { background: var(--mq-steel); }
.cal__swatch--mist    { background: var(--mq-mist);
                        border: 1px solid var(--mq-steel); }
.cal__count {
    font-variant-numeric: tabular-nums; color: var(--mq-steel);
    font-weight: 600; font-size: 12px;
}

/* ------------------------------------------------------- the chip

   One line, ellipsised, with the colour carried on a left bar rather
   than a fill: a grid of filled blocks is louder than the information
   in it, and the bar still groups by kind at a glance. */

.cal-chip {
    display: flex; align-items: baseline; gap: var(--s1);
    min-width: 0;
    padding: 1px var(--s1) 1px 5px;
    border-left: 3px solid var(--mq-ink);
    background: var(--mq-paper);
    border-radius: 0 2px 2px 0;
    font-size: 13px; line-height: 18px;
    color: var(--mq-ink);
    overflow: hidden; white-space: nowrap;
}
.cal-chip:hover { background: var(--mq-mist); text-decoration: none; }
.cal-chip__time { font-weight: 600; font-variant-numeric: tabular-nums;
                  flex: none; }
.cal-chip__text { overflow: hidden; text-overflow: ellipsis; }
.cal-chip__who  { color: var(--mq-steel); font-size: 12px;
                  overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; }

.cal-chip--info    { border-left-color: var(--mq-info); }
.cal-chip--success { border-left-color: var(--mq-success); }
.cal-chip--warning { border-left-color: var(--mq-warning); }
.cal-chip--danger  { border-left-color: var(--mq-danger); }
.cal-chip--steel   { border-left-color: var(--mq-steel); }
.cal-chip--mist    { border-left-color: var(--mq-mist); }

/* Late is the one thing worth shouting about, and it is a fact rather
   than a category, so it overrides the kind's own colour. */
.cal-chip.is-late {
    border-left-color: var(--mq-danger);
    background: var(--mq-danger-wash);
}
.cal-chip.is-late .cal-chip__text { font-weight: 600; }
/* Finished work stays visible but stops competing. */
.cal-chip.is-done { opacity: 0.62; }
.cal-chip.is-done .cal-chip__text { text-decoration: line-through; }

.cal-more {
    display: block; padding: 1px var(--s1) 1px 5px;
    font-size: 12px; line-height: 18px; font-weight: 600;
    color: var(--mq-steel);
}
.cal-more:hover { color: var(--mq-ink); }

/* --------------------------------------------------------- month */

.cal-month__dow {
    display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
    border-bottom: 1px solid var(--mq-mist);
    background: var(--mq-paper);
}
.cal-month__dow span {
    padding: var(--s2) var(--s2);
    font-size: 12px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--mq-steel);
}
.cal-month__grid {
    display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
}
.cal-day {
    min-height: var(--cal-cell);
    border-right: 1px solid var(--mq-mist);
    border-bottom: 1px solid var(--mq-mist);
    padding: var(--s1);
    display: flex; flex-direction: column; gap: 2px;
    min-width: 0; background: var(--mq-white);
}
.cal-day:nth-child(7n) { border-right: none; }
.cal-day.is-weekend { background: var(--mq-paper); }
.cal-day.is-outside { background: var(--mq-paper-2); }
.cal-day.is-outside .cal-day__num { color: var(--mq-steel); font-weight: 400; }
.cal-day.is-today { background: var(--mq-white);
                    box-shadow: inset 0 0 0 2px var(--mq-ink); }

.cal-day__date { display: flex; align-items: baseline; gap: var(--s1);
                 padding: 0 2px; }
.cal-day__date:hover { text-decoration: none; }
.cal-day__date:hover .cal-day__num { text-decoration: underline; }
.cal-day__num {
    font-size: 15px; line-height: 20px; font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.cal-day.is-today .cal-day__num {
    background: var(--mq-ink); color: var(--mq-paper);
    border-radius: 3px; padding: 0 5px;
}
.cal-day__month { font-size: 12px; font-weight: 600; color: var(--mq-steel);
                  text-transform: uppercase; letter-spacing: 0.06em; }
.cal-day__items { display: flex; flex-direction: column; gap: 2px;
                  min-width: 0; }

/* ------------------------------------------------ week and day

   A CSS grid per day column, one row per half-hour. Rows are implicit
   (grid-auto-rows) so the row count lives in calendarview.py and
   nowhere else - change the working band there and this follows. */

.cal-week { overflow-x: auto; }
.cal-week__row {
    display: grid;
    grid-template-columns: var(--cal-gutter) repeat(7, minmax(96px, 1fr));
}
.cal-week--single .cal-week__row {
    grid-template-columns: var(--cal-gutter) minmax(240px, 1fr);
}
.cal-week__gutter { border-right: 1px solid var(--mq-mist); }
.cal-week__allday .cal-week__gutter {
    padding: var(--s1) var(--s2); text-align: right; margin: 0;
}

.cal-week__head { background: var(--mq-paper);
                  border-bottom: 1px solid var(--mq-mist); }
.cal-week__dow {
    display: flex; align-items: baseline; gap: var(--s1);
    padding: var(--s2);
    border-right: 1px solid var(--mq-mist);
    font-size: 14px; color: var(--mq-steel);
}
.cal-week__dow:hover { text-decoration: none; background: var(--mq-mist); }
.cal-week__dow b { font-size: 12px; font-weight: 600; letter-spacing: 0.08em;
                   text-transform: uppercase; }
.cal-week__daynum { font-size: 18px; line-height: 22px; font-weight: 600;
                    color: var(--mq-ink); font-variant-numeric: tabular-nums; }
.cal-week__month { font-size: 12px; }
.cal-week__dow.is-today { background: var(--mq-ink); color: var(--mq-paper); }
.cal-week__dow.is-today .cal-week__daynum { color: var(--mq-white); }

.cal-week__allday { border-bottom: 2px solid var(--mq-mist);
                    background: var(--mq-white); }
.cal-week__adcol {
    border-right: 1px solid var(--mq-mist);
    padding: 3px; min-height: 34px; min-width: 0;
    display: flex; flex-direction: column; gap: 2px;
}
.cal-week__adcol.is-today { background: var(--mq-paper); }
.cal-week__none { color: var(--mq-mist); font-size: 14px; text-align: center; }

.cal-week__times {
    display: grid; grid-auto-rows: var(--cal-slot);
    border-right: 1px solid var(--mq-mist);
}
.cal-time {
    grid-column: 1; text-align: right; padding-right: var(--s2);
    font-size: 12px; line-height: var(--cal-slot); color: var(--mq-steel);
    font-variant-numeric: tabular-nums;
}
.cal-time.is-hour { font-weight: 600; }

.cal-week__col {
    display: grid;
    grid-auto-rows: var(--cal-slot);
    /* Twelve so a slot divides evenly by one, two, three or four. */
    grid-template-columns: repeat(12, minmax(0, 1fr));
    border-right: 1px solid var(--mq-mist);
    position: relative;
}
.cal-week__col.is-today { background: var(--mq-paper); }
.cal-week__rule {
    grid-column: 1 / -1;
    border-top: 1px solid var(--mq-line-soft);
}
.cal-week__rule.is-hour { border-top-color: var(--mq-mist); }
.cal-week__over { grid-column: 1 / -1; align-self: end; }

/* The appointment itself. Same colour language as the chip.

   A half-hour appointment is one row tall - about 20 px - which is not
   room for three stacked lines, so a short one lays itself out along the
   line instead and an hour or more stacks. That is the difference between
   a grid you can read and a grid of clipped first lines. */
.cal-ev {
    margin: 1px;
    padding: 1px var(--s1) 1px 5px;
    border-left: 3px solid var(--mq-ink);
    background: var(--mq-white);
    box-shadow: var(--shadow);
    border-radius: 0 2px 2px 0;
    font-size: 13px; line-height: 18px;
    overflow: hidden; min-width: 0;
    display: flex;
    flex-direction: row; align-items: baseline; gap: var(--s1);
}
.cal-ev:not(.cal-for-1) {
    flex-direction: column; align-items: stretch; gap: 0;
}
/* Along the line there is room for the customer only if the title is
   short, so let it give way rather than push the title out. */
.cal-ev.cal-for-1 .cal-ev__time { flex: none; }
.cal-ev.cal-for-1 .cal-ev__text { flex: 0 1 auto; }
.cal-ev.cal-for-1 .cal-ev__who  { flex: 0 1 auto; }
.cal-ev:hover { text-decoration: none; box-shadow: var(--shadow-lg);
                background: var(--mq-paper); }
.cal-ev__time { font-weight: 600; font-variant-numeric: tabular-nums;
                font-size: 12px; }
.cal-ev__text { font-weight: 600; overflow: hidden; text-overflow: ellipsis;
                white-space: nowrap; }
.cal-ev__who  { color: var(--mq-steel); font-size: 12px; overflow: hidden;
                text-overflow: ellipsis; white-space: nowrap; }
.cal-ev--info    { border-left-color: var(--mq-info); }
.cal-ev--success { border-left-color: var(--mq-success); }
.cal-ev--warning { border-left-color: var(--mq-warning); }
.cal-ev--danger  { border-left-color: var(--mq-danger); }
.cal-ev--steel   { border-left-color: var(--mq-steel); }
.cal-ev--mist    { border-left-color: var(--mq-mist); }

/* --------------------------------- grid placement, CSP-safe

   Row start and row span, one class each, produced by
   calendarview.slot_of() and lay_out(). Twenty-six rows covers 07:00 to
   20:00 at half-hour slots; the list is generated to match
   calendarview.slot_count() and both change together. */

.cal-at-1{grid-row-start:1}   .cal-at-2{grid-row-start:2}
.cal-at-3{grid-row-start:3}   .cal-at-4{grid-row-start:4}
.cal-at-5{grid-row-start:5}   .cal-at-6{grid-row-start:6}
.cal-at-7{grid-row-start:7}   .cal-at-8{grid-row-start:8}
.cal-at-9{grid-row-start:9}   .cal-at-10{grid-row-start:10}
.cal-at-11{grid-row-start:11} .cal-at-12{grid-row-start:12}
.cal-at-13{grid-row-start:13} .cal-at-14{grid-row-start:14}
.cal-at-15{grid-row-start:15} .cal-at-16{grid-row-start:16}
.cal-at-17{grid-row-start:17} .cal-at-18{grid-row-start:18}
.cal-at-19{grid-row-start:19} .cal-at-20{grid-row-start:20}
.cal-at-21{grid-row-start:21} .cal-at-22{grid-row-start:22}
.cal-at-23{grid-row-start:23} .cal-at-24{grid-row-start:24}
.cal-at-25{grid-row-start:25} .cal-at-26{grid-row-start:26}

.cal-for-1{grid-row-end:span 1}   .cal-for-2{grid-row-end:span 2}
.cal-for-3{grid-row-end:span 3}   .cal-for-4{grid-row-end:span 4}
.cal-for-5{grid-row-end:span 5}   .cal-for-6{grid-row-end:span 6}
.cal-for-7{grid-row-end:span 7}   .cal-for-8{grid-row-end:span 8}
.cal-for-9{grid-row-end:span 9}   .cal-for-10{grid-row-end:span 10}
.cal-for-11{grid-row-end:span 11} .cal-for-12{grid-row-end:span 12}
.cal-for-13{grid-row-end:span 13} .cal-for-14{grid-row-end:span 14}
.cal-for-15{grid-row-end:span 15} .cal-for-16{grid-row-end:span 16}
.cal-for-17{grid-row-end:span 17} .cal-for-18{grid-row-end:span 18}
.cal-for-19{grid-row-end:span 19} .cal-for-20{grid-row-end:span 20}
.cal-for-21{grid-row-end:span 21} .cal-for-22{grid-row-end:span 22}
.cal-for-23{grid-row-end:span 23} .cal-for-24{grid-row-end:span 24}
.cal-for-25{grid-row-end:span 25} .cal-for-26{grid-row-end:span 26}

/* Overlapping appointments share the width of the column. Twelve
   columns divide evenly by one to four, so two side by side are exactly
   half each rather than one being a pixel wider. */
.cal-of-1.cal-lane-1 { grid-column: 1 / 13; }
.cal-of-2.cal-lane-1 { grid-column: 1 / 7; }
.cal-of-2.cal-lane-2 { grid-column: 7 / 13; }
.cal-of-3.cal-lane-1 { grid-column: 1 / 5; }
.cal-of-3.cal-lane-2 { grid-column: 5 / 9; }
.cal-of-3.cal-lane-3 { grid-column: 9 / 13; }
.cal-of-4.cal-lane-1 { grid-column: 1 / 4; }
.cal-of-4.cal-lane-2 { grid-column: 4 / 7; }
.cal-of-4.cal-lane-3 { grid-column: 7 / 10; }
.cal-of-4.cal-lane-4 { grid-column: 10 / 13; }

/* -------------------------------------------------------- agenda */

.cal-agenda { list-style: none; margin: 0; padding: 0; }
.cal-agenda__day {
    display: grid; grid-template-columns: 88px minmax(0, 1fr);
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-bottom: 1px solid var(--mq-mist);
}
.cal-agenda__day:last-child { border-bottom: none; }
.cal-agenda__day.is-today { background: var(--mq-paper); }
.cal-agenda__day.is-past .cal-agenda__num { color: var(--mq-steel); }
.cal-agenda__when {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
}
.cal-agenda__num { font-size: 30px; line-height: 32px; font-weight: 700;
                   font-variant-numeric: tabular-nums; }
.cal-agenda__dow, .cal-agenda__month {
    font-size: 12px; line-height: 16px; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase; color: var(--mq-steel);
}
.cal-agenda__items { display: flex; flex-direction: column; }

.cal-row {
    display: grid;
    grid-template-columns: 54px 104px minmax(0, 2fr) minmax(0, 1.4fr)
                           minmax(0, 1fr) 100px minmax(0, 1fr);
    gap: var(--s3);
    align-items: baseline;
    padding: 5px var(--s2) 5px 9px;
    border-left: 3px solid var(--mq-ink);
    border-bottom: 1px solid var(--mq-mist);
    font-size: 14px; line-height: 21px;
}
.cal-row:last-child { border-bottom: none; }
.cal-row:hover { background: var(--mq-paper); text-decoration: none; }
.cal-row__time { font-weight: 600; font-variant-numeric: tabular-nums; }
.cal-row__kind { margin: 0; }
.cal-row__title { font-weight: 600; overflow: hidden;
                  text-overflow: ellipsis; white-space: nowrap; }
.cal-row__who, .cal-row__state, .cal-row__owner {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cal-row--info    { border-left-color: var(--mq-info); }
.cal-row--success { border-left-color: var(--mq-success); }
.cal-row--warning { border-left-color: var(--mq-warning); }
.cal-row--danger  { border-left-color: var(--mq-danger); }
.cal-row--steel   { border-left-color: var(--mq-steel); }
.cal-row--mist    { border-left-color: var(--mq-mist); }
.cal-row.is-late  { border-left-color: var(--mq-danger);
                    background: var(--mq-danger-wash); }
.cal-row.is-done .cal-row__title { text-decoration: line-through;
                                   font-weight: 400; color: var(--mq-steel); }

/* ------------------------------------------- calendar, narrow screens

   Below a tablet the month grid stops being readable at seven columns of
   90 px, so the chips give up their company name and the cells shrink to
   the date plus a count. The week view scrolls sideways instead, which is
   what a week of appointments actually needs. */

@media (max-width: 1100px) {
    :root { --cal-cell: 96px; }
    .cal-chip__who { display: none; }
    .cal-row {
        grid-template-columns: 48px minmax(0, 2fr) minmax(0, 1fr);
    }
    .cal-row__kind, .cal-row__state, .cal-row__owner { display: none; }
}
@media (max-width: 720px) {
    :root { --cal-cell: 64px; }
    .cal__period { flex: 1 1 100%; order: -1; text-align: left; }
    .cal-month__dow span { padding: var(--s1); font-size: 11px; }
    .cal-day { padding: 2px; }
    .cal-week { -webkit-overflow-scrolling: touch; }

    /* A month cell on a phone is about 50 px wide, which fits four
       characters of a chip - so the month view stops trying to spell
       anything and becomes density instead: one coloured bar per item,
       the same colours as everywhere else. Tapping a bar still opens its
       record, and tapping the date opens the day, which is where the
       words are. This is what every phone calendar does, and for the
       same reason.

       Scoped to .cal-month: the all-day band in the day view has the
       full width of the screen and keeps its text. */
    .cal-month .cal-day__items { gap: 2px; }
    .cal-month .cal-chip {
        display: block; height: 5px; padding: 0;
        border-left: none; border-radius: 2px;
        background: var(--mq-ink);
    }
    .cal-month .cal-chip > * { display: none; }
    .cal-month .cal-chip--info    { background: var(--mq-info); }
    .cal-month .cal-chip--success { background: var(--mq-success); }
    .cal-month .cal-chip--warning { background: var(--mq-warning); }
    .cal-month .cal-chip--danger  { background: var(--mq-danger); }
    .cal-month .cal-chip--steel   { background: var(--mq-steel); }
    .cal-month .cal-chip--mist    { background: var(--mq-mist); }
    .cal-month .cal-chip.is-late  { background: var(--mq-danger); }
    .cal-month .cal-chip.is-done  { opacity: 0.4; }
    .cal-month .cal-more { padding: 0; font-size: 11px; line-height: 14px; }
}

/* ------------------------------------------- calendar, on paper

   The agenda is the view that prints. The month grid prints too, but the
   week's timed grid does not: half a metre of half-hour rules is not
   something anybody wants on A4. */

@media print {
    .cal__bar, .cal__filters, .cal-more { display: none !important; }
    .cal-day { min-height: 84px; }
    .cal-chip, .cal-row { break-inside: avoid; }
    .cal-week__body { display: none; }
}

/* ----------------------------------------------- sizing utilities
   The Content-Security-Policy forbids inline styles, so bar and meter
   sizes use these fixed 5% steps rather than style="width:…".
   ------------------------------------------------------------------ */
.h-0{height:0}      .h-5{height:5%}    .h-10{height:10%}  .h-15{height:15%}
.h-20{height:20%}   .h-25{height:25%}  .h-30{height:30%}  .h-35{height:35%}
.h-40{height:40%}   .h-45{height:45%}  .h-50{height:50%}  .h-55{height:55%}
.h-60{height:60%}   .h-65{height:65%}  .h-70{height:70%}  .h-75{height:75%}
.h-80{height:80%}   .h-85{height:85%}  .h-90{height:90%}  .h-95{height:95%}
.h-100{height:100%}

.w-0{width:0}       .w-5{width:5%}     .w-10{width:10%}   .w-15{width:15%}
.w-20{width:20%}    .w-25{width:25%}   .w-30{width:30%}   .w-35{width:35%}
.w-40{width:40%}    .w-45{width:45%}   .w-50{width:50%}   .w-55{width:55%}
.w-60{width:60%}    .w-65{width:65%}   .w-70{width:70%}   .w-75{width:75%}
.w-80{width:80%}    .w-85{width:85%}   .w-90{width:90%}   .w-95{width:95%}
.w-100{width:100%}
.fw-regular{font-weight:400}
.section-title { font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em;
                 color: var(--mq-steel); margin: var(--s5) 0 var(--s3); }

/* ----------------------------------------------------------- print */

/* --------------------------------------------------- printed reports */

.print-actions { display: flex; gap: var(--s3); align-items: center;
                 flex-wrap: wrap; margin-bottom: var(--s5); }
.report-head { display: flex; justify-content: space-between; gap: var(--s4);
               align-items: flex-start; flex-wrap: wrap;
               padding-bottom: var(--s3); margin-bottom: var(--s4);
               border-bottom: 2px solid var(--mq-ink); }
.report-head__meta { text-align: right; }
.report-foot { margin-top: var(--s5); padding-top: var(--s3);
               border-top: 1px solid var(--mq-mist); }

@media print {
    /* A4 with a sensible margin. Landscape suits the wider tables, but
       the reader chooses that in the dialogue rather than having it
       forced on them. */
    @page { size: A4; margin: 14mm 12mm; }

    body { background: var(--mq-white); font-size: 10pt; line-height: 1.4; }
    .topbar, .sidebar, .sidenav, .site-foot, .page__actions, .supportbar,
    .filters, .pagination, .no-print, .journey, .nextsteps, .tabs__nav,
    .quicknote, .flashes, .sprite, dialog { display: none !important; }
    html.js .tabs__panel { display: block !important; }
    .app { display: block; }
    :root { color-scheme: light; }
    body, .card, .stat, .journey__step { background: #FFFFFF !important;
                                        color: #14171A !important; }
    .page { max-width: none; padding: 0; }
    .card { border: none; margin: 0 0 var(--s4); }
    .card__head { padding-left: 0; padding-right: 0; border-bottom-width: 1px; }
    .card__body, .card__body--flush, .card__foot {
        padding-left: 0; padding-right: 0; background: none; border-top: none;
    }
    table.data th { background: none; }
    a { color: inherit; text-decoration: none; }

    /* A table split across a page break is unreadable and a heading
       stranded at the foot of a page is worse. */
    .card { break-inside: avoid; page-break-inside: avoid; }
    table { break-inside: auto; }
    tr { break-inside: avoid; page-break-inside: avoid; }
    thead { display: table-header-group; }
    tfoot { display: table-footer-group; }
    h1, h2, h3 { break-after: avoid; page-break-after: avoid; }

    /* The stat tiles are a screen device; in print they should read as
       plain figures rather than boxes. */
    .stat { border: none; padding: 0 var(--s3) 0 0; }
    .grid--6, .grid--5, .grid--4, .grid--3, .grid--2 { display: flex; gap: var(--s5); }

    /* The table-wrap scroller must not clip a printed table. */
    .table-wrap { overflow: visible !important; }
}

/* ------------------------------------------------------- import log */

/* A long, plain, monospaced record of what an import did. Scrolls in its
   own box so a thousand lines cannot stretch the page. */
.log {
    font-family: Consolas, "Courier New", monospace;
    font-size: 12px; line-height: 18px;
    white-space: pre-wrap; word-break: break-word;
    max-height: 60vh; overflow-y: auto;
    background: var(--mq-paper);
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-button);
    padding: var(--s3);
    margin: 0;
}

/* --------------------------------------------------------- branding */

/* A company's own logo on their own paperwork. Capped rather than sized,
   because what arrives is whatever shape their designer drew: a wide
   lockup lands on the width and a square mark lands on the height, and
   neither is stretched. 44 px is roughly two lines of the letterhead
   beside it, which is what stops a logo dominating a quotation. */
.doc-logo {
    display: block;
    max-width: 200px; max-height: 44px;
    width: auto; height: auto;
    margin: 0 0 var(--s2) auto;
}

/* The styling page: what the two chosen colours actually produce.

   Swatches read from the live custom properties rather than from an
   inline style attribute, so they show exactly what is in force and the
   Content-Security-Policy stays as strict as it is everywhere else. That
   is also why the page shows the *saved* palette and not a live preview:
   a preview would have to write colours into the page. */
.swatches { display: flex; flex-wrap: wrap; gap: var(--s3); margin: 0; padding: 0; }
.swatch {
    flex: 0 0 auto; width: 108px;
    list-style: none;
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-button);
    overflow: hidden;
    background: var(--mq-white);
}
.swatch__chip { display: block; height: 44px; }
.swatch__name {
    display: block; padding: var(--s1) var(--s2);
    font-size: 12px; line-height: 16px; color: var(--mq-steel);
}
.swatch__chip--nav      { background: var(--mq-nav); }
.swatch__chip--surface  { background: var(--mq-nav-surface); }
.swatch__chip--signal   { background: var(--mq-signal); }
.swatch__chip--hover    { background: var(--mq-signal-hover); }
.swatch__chip--wash     { background: var(--mq-signal-wash); }

/* The logo as it will appear in the bar, on the bar's own white. */
.logo-preview {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s3) var(--s4);
    background: var(--mq-white);
    border: 1px solid var(--mq-mist);
    border-radius: var(--r-button);
}
.logo-preview img { height: 26px; width: auto; max-width: 260px; display: block; }

/* A colour picker beside the box that holds the value. Only ever added by
   app.js - the text box is the field that posts, and it is the only one
   that can be cleared, so the page works exactly as well without it. */
.colour-pair { display: flex; align-items: center; gap: var(--s2); }
.colour-pair input[type="text"] { flex: 1 1 auto; }
.colour-pair input[type="color"] {
    flex: none; width: 40px; height: 38px; padding: 2px;
    border: 1px solid var(--mq-mist); border-radius: var(--r-button);
    background: var(--mq-white); cursor: pointer;
}

/* ------------------------------------------------------------------
   Captured email: the reader

   Used in two places and identical in both - expanded inside a record's
   Emails tab, and on the message's own page. The iframe is where an HTML
   message goes; it is sandboxed with no allowances, so it needs its own
   background rather than inheriting one it cannot be trusted with.
   ------------------------------------------------------------------ */
.email-reader { padding: var(--s3) 0; }

.email-reader__head {
    display: flex; flex-wrap: wrap; gap: var(--s2);
    align-items: baseline; justify-content: space-between;
    margin-bottom: var(--s1);
}

.email-reader__people { margin-bottom: var(--s3); }
.email-reader__people .strong { display: inline-block; min-width: 32px; }

/* Grows with its content where the browser allows it, and is never
   taller than a screenful: an HTML newsletter is otherwise three metres
   of page between one message and the next. */
.email-reader__html {
    display: block; width: 100%; min-height: 120px; max-height: 60vh;
    border: 1px solid var(--mq-mist); border-radius: var(--r-button);
    background: var(--mq-white);
}

.email-reader__text { white-space: pre-wrap; overflow-wrap: break-word; }

.email-reader__plain { margin-top: var(--s3); }
.email-reader__plain summary { cursor: pointer; color: var(--mq-slate, inherit); }

.email-reader__files {
    margin-top: var(--s4); padding-top: var(--s3);
    border-top: 1px solid var(--mq-mist);
}
.email-reader__files .file-list {
    list-style: none; margin: var(--s2) 0 0; padding: 0;
}
.email-reader__files .file-list li {
    display: flex; flex-wrap: wrap; gap: var(--s2);
    align-items: baseline; padding: var(--s1) 0;
}

.email-reader__foot {
    margin-top: var(--s3); padding-top: var(--s2);
    border-top: 1px solid var(--mq-mist);
}

/* The row the reader is put into when a message is opened in place. */
.email-row__body > td { background: var(--mq-paper-2); }

/* The subject, as a control rather than only a link. */
a[data-email][aria-expanded="true"] { font-weight: 600; }


/* ------------------------------------------------- reports & charts
   Inline SVG drawn from crm/charts.py. Shapes carry classes; the
   colours live here so the light theme, the dark theme and print each
   decide for themselves. The current period is ink, the period it is
   compared with a quiet grey, and the ranks on the customer share bar
   are steps of grey - never the accent, which is reserved for the one
   action on the screen. */
:root {
    --mq-ch-prev:  #B4B8BE;
    --mq-ch-rank2: #3A414A;
    --mq-ch-rank3: #5B6068;
    --mq-ch-rank4: #7C828A;
    --mq-ch-rank5: #9CA2AA;
}
:root[data-theme="dark"] {
    --mq-ch-prev:  #4A5158;
    --mq-ch-rank2: #C9CDD2;
    --mq-ch-rank3: #A2A8B0;
    --mq-ch-rank4: #7C828A;
    --mq-ch-rank5: #5B6068;
}

.chart { min-width: 0; }
.chart svg, .share { width: 100%; height: auto; display: block; overflow: visible; }
.ch-cur   { fill: var(--mq-ink); }
.ch-prev  { fill: var(--mq-ch-prev); }
.ch-rank2 { fill: var(--mq-ch-rank2); }
.ch-rank3 { fill: var(--mq-ch-rank3); }
.ch-rank4 { fill: var(--mq-ch-rank4); }
.ch-rank5 { fill: var(--mq-ch-rank5); }
.ch-bar { transition: opacity 0.12s; }
.ch-row:hover .ch-bar, .chart a:hover .ch-bar, .ch-hit:hover + .ch-bar { opacity: 0.72; }
.ch-hit { fill: transparent; }
.ch-grid { stroke: var(--mq-line-soft); stroke-width: 1; }
.ch-axis { stroke: var(--mq-mist-2); stroke-width: 1; }
.ch-text { fill: var(--mq-steel); font-family: var(--font); font-size: 11px; }
.ch-text--value { fill: var(--mq-ink); font-weight: 600; font-size: 11.5px; }
.ch-text--label { fill: var(--mq-ink); font-size: 12px; }
.ch-text--inside { fill: var(--mq-white); font-weight: 600; }
.ch-line { fill: none; stroke: var(--mq-ink); stroke-width: 2;
           stroke-linejoin: round; stroke-linecap: round; }
.ch-line.ch-prev { stroke: var(--mq-ch-prev); }
.ch-dot { fill: var(--mq-ink); stroke: var(--mq-white); stroke-width: 2; }
.ch-dot.ch-prev { fill: var(--mq-ch-prev); }
.ch-spark { fill: none; stroke: var(--mq-steel); stroke-width: 1.5; stroke-linejoin: round; }
.ch-empty { padding: var(--s6) 0; text-align: center; }
.chart a { text-decoration: none; }
.share { height: 18px; margin-bottom: var(--s2); }

.ch-legend { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s4); margin-top: var(--s2);
             font-size: 12.5px; color: var(--mq-steel); }
.ch-legend__item { display: inline-flex; align-items: center; gap: 6px; color: inherit; }
.ch-legend__item .muted { margin-left: 2px; }
.ch-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px;
             background: var(--mq-ink); flex: none; }
.ch-swatch.ch-prev  { background: var(--mq-ch-prev); }
.ch-swatch.ch-rank2 { background: var(--mq-ch-rank2); }
.ch-swatch.ch-rank3 { background: var(--mq-ch-rank3); }
.ch-swatch.ch-rank4 { background: var(--mq-ch-rank4); }
.ch-swatch.ch-rank5 { background: var(--mq-ch-rank5); }

/* KPI tiles: a stat with its change and a twelve-month trend. */
.kpi-grid { margin-bottom: var(--s4); }
.tile .stat__value { font-variant-numeric: normal; }
.tile--spark .stat__label, .tile--spark .stat__value { padding-right: 104px; }
.tile__spark { position: absolute; right: var(--s3); top: var(--s3); width: 96px; height: 28px; }
.tile__spark .spark { width: 96px; height: 28px; display: block; }
.tile__note { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; }
.tile__hint { margin-top: 2px; }
.tile__now { font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
             font-weight: 600; color: var(--mq-info); }
.delta { display: inline-flex; align-items: center; gap: 3px; font-weight: 600;
         font-size: 12.5px; line-height: 18px; padding: 0 7px; border-radius: var(--r-pill);
         white-space: nowrap; }
.delta--good { color: var(--mq-success); background: var(--mq-success-wash); }
.delta--bad  { color: var(--mq-danger);  background: var(--mq-danger-wash); }
.delta--flat { color: var(--mq-steel);   background: var(--mq-paper); }
table.data .delta { font-size: 12px; }

/* The hub's sections and the strip that jumps between them. */
.section-nav { display: flex; flex-wrap: wrap; gap: var(--s1); margin: 0 0 var(--s4);
               position: sticky; top: var(--topbar-h); z-index: 5;
               background: var(--mq-paper); padding: var(--s2) 0; }
.section-nav a { padding: 3px 12px; border-radius: var(--r-pill); border: 1px solid var(--mq-mist);
                 background: var(--mq-white); font-size: 13px; font-weight: 500; }
.section-nav a:hover { border-color: var(--mq-mist-2); text-decoration: none; }
.report-section { margin-bottom: var(--s10); scroll-margin-top: calc(var(--topbar-h) + 56px); }
.report-section__head { display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap;
                        margin-bottom: var(--s4); padding-bottom: var(--s2);
                        border-bottom: 2px solid var(--mq-ink); }
.report-section__head h2 { margin: 0; }
.card__head--sub { border-top: 1px solid var(--mq-mist); }
.card__head--sub h3 { margin: 0; font-size: 15px; }
.report-table td, .report-table th { white-space: nowrap; }
.report-table td:first-child, .report-table th:first-child { white-space: normal; }

/* The report builder: the settings panel down the left, the report on
   the right. The panel sticks while the report scrolls, so the controls
   stay in reach; on a narrow screen it sits above the report. */
.builder-layout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: var(--s4);
                  align-items: start; }
.builder-layout__result { min-width: 0; }
.panel { position: sticky; top: calc(var(--topbar-h) + var(--s4)); margin-bottom: 0;
         max-height: calc(100vh - var(--topbar-h) - var(--s6)); overflow-y: auto; }
.panel__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2);
               padding: var(--s3) var(--s4); border-bottom: 1px solid var(--mq-mist); }
.panel__head h2 { margin: 0; font-size: 15px; line-height: 22px; }
.panel__step { display: flex; flex-direction: column; gap: var(--s2);
               padding: var(--s3) var(--s4); border-bottom: 1px solid var(--mq-line-soft); }
.panel__label { display: flex; align-items: center; gap: var(--s2); font-size: 13.5px;
                line-height: 20px; font-weight: 600; color: var(--mq-ink); }
.panel__num { display: inline-flex; align-items: center; justify-content: center; flex: none;
              width: 20px; height: 20px; border-radius: 50%; font-size: 11.5px; font-weight: 700;
              background: var(--mq-plate); color: var(--mq-plate-text); }
.panel__step .field { gap: 3px; }
.panel__step .hint { margin: 0; }
.panel__more > summary { list-style: none; cursor: pointer; font-size: 13px; font-weight: 600;
                         color: var(--mq-steel); padding: 2px 0; }
.panel__more > summary::-webkit-details-marker { display: none; }
.panel__more > summary::before { content: "+ "; }
.panel__more > summary:hover { color: var(--mq-ink); }
.panel__more[open] > summary { margin-bottom: var(--s2); }
.panel__lights > summary { list-style: none; cursor: pointer; }
.panel__lights > summary::-webkit-details-marker { display: none; }
.panel__lights > summary::after {
    content: ""; margin-left: auto; width: 7px; height: 7px;
    border-right: 1.75px solid var(--mq-steel); border-bottom: 1.75px solid var(--mq-steel);
    transform: rotate(45deg); transition: transform 120ms;
}
.panel__lights[open] > summary::after { transform: rotate(-135deg); }
.panel__foot { padding: var(--s3) var(--s4); }
.builder__daterow { display: flex; gap: var(--s1); }
.builder__daterow input { min-width: 0; flex: 1 1 0; }
.builder__dates { flex: 1 1 250px; }
@media (max-width: 1000px) {
    .builder-layout { grid-template-columns: minmax(0, 1fr); }
    .panel { position: static; max-height: none; overflow: visible; }
}
.menu__list--form { min-width: 320px; padding: var(--s3); }
.menu__list--form .field { margin-bottom: var(--s2); }
.menu__list--form button.btn { display: inline-flex; width: auto; padding: 6px 14px;
                               background: var(--mq-plate); color: var(--mq-plate-text); }
.menu__list--form form + .menu__sep + form button.btn { background: transparent; color: var(--mq-danger); }
.menu__list--form .btn-row { margin-top: var(--s2); }
.menu__list--form button.btn--ghost { background: transparent; color: var(--mq-ink); }
.menu__list--form .hint { margin-top: var(--s2); }

/* Starting points on the builder's first page: ready-made reports by
   the question they answer, and the datasets for starting from scratch. */
.starters__group { padding: var(--s2) var(--s4) 4px; font-size: 11.5px; letter-spacing: 0.06em;
                   text-transform: uppercase; font-weight: 600; color: var(--mq-steel);
                   background: var(--mq-paper); border-top: 1px solid var(--mq-line-soft);
                   border-bottom: 1px solid var(--mq-line-soft); }
.starters { list-style: none; margin: 0; padding: 0; }
.starters li + li { border-top: 1px solid var(--mq-line-soft); }
.starter { display: block; padding: var(--s2) var(--s4); color: inherit; }
.starter:hover { background: var(--mq-paper-2); text-decoration: none; }
.starter__title { display: block; font-weight: 600; }
.starter__blurb { display: block; font-size: 13px; line-height: 18px; color: var(--mq-steel); }
.picks { list-style: none; margin: 0; padding: 0; }
.picks__lead { margin: 0; padding: var(--s3) var(--s4) var(--s1); }
.picks li + li { border-top: 1px solid var(--mq-line-soft); }
.pick { display: flex; gap: var(--s3); align-items: center; padding: var(--s2) var(--s4); color: inherit; }
.pick:hover { background: var(--mq-paper-2); text-decoration: none; }
.pick > .icon { width: 22px; height: 22px; color: var(--mq-steel); flex: none; }
.pick > span { display: flex; flex-direction: column; min-width: 0; }
.howto { list-style: none; margin: 0; padding: 0; display: grid;
         grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4); }
.howto__step { display: flex; gap: var(--s3); align-items: flex-start; font-size: 14px; }
.howto__step .panel__num { margin-top: 2px; }
@media (max-width: 720px) { .howto { grid-template-columns: minmax(0, 1fr); } }

/* What stands out: a few sentences read from the figures. */
.insights__list { list-style: none; margin: 0; padding: 0; }
.insight { display: flex; gap: var(--s3); padding: var(--s2) var(--s4); font-size: 14px;
           line-height: 21px; border-bottom: 1px solid var(--mq-line-soft); }
.insight:last-child { border-bottom: none; }
.insight__mark { flex: none; width: 8px; height: 8px; border-radius: 50%; margin-top: 7px;
                 background: var(--mq-mist-2); }
.insight--good .insight__mark { background: var(--mq-success); }
.insight--bad .insight__mark { background: var(--mq-danger); }
.insight--tip .insight__mark { background: var(--mq-info); }

/* Nothing in the period: the ways out, as buttons. */
.fixes { display: flex; flex-wrap: wrap; gap: var(--s2); justify-content: center; margin-top: var(--s3); }

/* The wizard: two questions, each a row of choices to tick. */
.choices { display: grid; gap: var(--s3); }
.choices--grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.choices--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.choice { display: flex; gap: var(--s3); align-items: flex-start; padding: var(--s3) var(--s4);
          border: 1px solid var(--mq-mist); border-radius: var(--r-card); background: var(--mq-white);
          cursor: pointer; font-size: 14px; line-height: 20px; }
.choice:hover { border-color: var(--mq-mist-2); background: var(--mq-paper-2); }
.choice:has(input:checked) { border-color: var(--mq-ink); box-shadow: inset 0 0 0 1px var(--mq-ink); }
.choice input { margin: 3px 0 0; flex: none; }
.choice__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.choice__title { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; color: var(--mq-ink); }
.choice__title .icon { width: 18px; height: 18px; color: var(--mq-steel); flex: none; }
.choice__blurb { font-size: 13px; line-height: 18px; color: var(--mq-steel); }
.wizard__foot { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.howto--stack { grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
@media (max-width: 720px) { .choices--2 { grid-template-columns: minmax(0, 1fr); } }

/* The list builder: the field picker, and the list itself. */
.panel__aside { margin-left: auto; font-size: 12.5px; font-weight: 500; }
.fields__group { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 600;
                 color: var(--mq-steel); margin-top: var(--s1); }
.fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--s2); }
.fields__item { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px;
                color: var(--mq-ink); cursor: pointer; min-width: 0; }
.fields__item input { margin: 0; flex: none; }
.toggle--sm { align-self: flex-start; }
.toggle--sm a, .toggle--sm button { padding: 2px 10px; font-size: 12.5px; line-height: 18px; }
.list-summary { margin-bottom: var(--s4); }
.list-table th, .list-table td { white-space: nowrap; }
.list-table td.list-table__text { white-space: normal; min-width: 10rem; max-width: 28rem; }
.list-table th a { color: inherit; }
.list-table th.is-sorted a { color: var(--mq-ink); }

/* ------------------------------------------------- the dashboard grid
   Twelve columns; every box spans data-w of them and data-h row units.
   The grid is what keeps boxes from overlapping - the script only ever
   reorders elements and changes those two attributes. A box taller than
   its content leaves room; one shorter scrolls inside, like a window. */
.dash { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-auto-rows: 88px;
        grid-auto-flow: row; gap: var(--s4); align-items: stretch; }
.dash__item { margin: 0; min-width: 0; min-height: 0; display: flex; flex-direction: column;
              overflow: hidden; position: relative; }
.dash__item[data-w="3"] { grid-column: span 3; }
.dash__item[data-w="4"] { grid-column: span 4; }
.dash__item[data-w="6"] { grid-column: span 6; }
.dash__item[data-w="8"] { grid-column: span 8; }
.dash__item[data-w="9"] { grid-column: span 9; }
.dash__item[data-w="12"] { grid-column: span 12; }
.dash__item[data-h="1"] { grid-row: span 1; }
.dash__item[data-h="2"] { grid-row: span 2; }
.dash__item[data-h="3"] { grid-row: span 3; }
.dash__item[data-h="4"] { grid-row: span 4; }
.dash__item[data-h="5"] { grid-row: span 5; }
.dash__item[data-h="6"] { grid-row: span 6; }
.dash__item[data-h="7"] { grid-row: span 7; }
.dash__item[data-h="8"] { grid-row: span 8; }
.dash__item > .card__body, .dash__item > .card__body--flush { flex: 1 1 auto; min-height: 0; overflow: auto; }
.dash__item > .card__foot { flex: none; }
.dash__head { flex: none; flex-wrap: nowrap; }
.dash__head h2 { min-width: 0; flex: 1 1 auto; }
.dash__head h2 .icon { flex: none; }
.dash__title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash__head .card__tools { flex: none; flex-wrap: nowrap; }
.dash__item[data-w="3"] .dash__sub, .dash__item[data-w="4"] .dash__sub { display: none; }
.dash__sub { max-width: 16rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash__empty { grid-column: span 12; }
.dash-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s3); }
.dash-tiles .stat { box-shadow: none; }
.dash-figure { display: flex; flex-direction: column; justify-content: center; flex: 1 1 auto; gap: 2px; }
.dash-figure__value { font-size: 34px; line-height: 40px; font-weight: 700; color: var(--mq-ink);
                      font-variant-numeric: tabular-nums; }
.dash-figure__label { font-size: 13px; color: var(--mq-steel); }
.dash-figure__note { margin-top: var(--s1); }

/* Arranging: the handle, the corner and the menu appear in edit mode,
   and always without scripting, where they are the only way. */
.dash__grip, .dash__resize, .dash__menu { display: none; }
.dash.is-editing .dash__grip { display: inline-flex; align-items: center; cursor: grab; color: var(--mq-steel);
                               touch-action: none; user-select: none; padding: 2px; }
.dash.is-editing .dash__grip .icon { width: 18px; height: 18px; }
.dash.is-editing .dash__menu, html:not(.js) .dash__menu { display: inline-block; }
.dash.is-editing .dash__resize {
    display: block; position: absolute; right: 0; bottom: 0; width: 28px; height: 28px;
    cursor: nwse-resize; touch-action: none; z-index: 2;
    background: linear-gradient(135deg, transparent 0 55%, var(--mq-mist-2) 55% 68%,
                                transparent 68% 78%, var(--mq-mist-2) 78% 91%, transparent 91%);
}
.dash.is-editing .dash__head { cursor: grab; touch-action: none; user-select: none; }
.dash.is-editing .dash__head:hover { background: var(--mq-paper-2); }
.dash.is-editing .dash__head a, .dash.is-editing .dash__head button,
.dash.is-editing .dash__head summary { cursor: pointer; }
.dash__edge { display: none; }
.dash.is-editing .dash__edge { display: block; position: absolute; touch-action: none; z-index: 1; }
.dash.is-editing .dash__edge--e { top: 0; right: 0; width: 10px; height: 100%; cursor: ew-resize; }
.dash.is-editing .dash__edge--s { left: 0; bottom: 0; height: 10px; width: 100%; cursor: ns-resize; }
.dash.is-editing .dash__edge:hover { background: var(--mq-signal-wash); }
.dash.is-editing .dash__item { outline: 1px dashed var(--mq-mist-2); outline-offset: 2px; }
.dash.is-editing .dash__item:hover { outline-color: var(--mq-steel); }
/* While dragging: a ghost of the box rides under the pointer (appended
   to the body, so the grid never counts it) and the box itself stays in
   the grid as a dimmed placeholder showing where it will land. */
.dash__ghost { position: fixed; left: 0; top: 0; z-index: 80; pointer-events: none; opacity: 0.95;
               display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--shadow-lg);
               will-change: transform; }
.dash__ghost .dash__head { cursor: grabbing; }
.dash__ghost > .card__body, .dash__ghost > .card__body--flush { flex: 1 1 auto; min-height: 0; overflow: hidden; }
.dash__item.is-dragging { opacity: 0.35; outline: 2px dashed var(--mq-steel) !important; }
.dash__item.is-resizing { outline: 2px solid var(--mq-ink) !important; }
.dash.is-arranging, .dash.is-arranging * { cursor: grabbing !important; user-select: none; }
.dash-bar__body { display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
                  flex-wrap: wrap; position: relative; }
.dash-bar__hint { font-size: 13.5px; line-height: 20px; color: var(--mq-steel); max-width: 64ch; }
.dash-bar__hint b { color: var(--mq-ink); }
html.js .dash-bar__nojs { display: none; }
.dash-bar__actions { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.dash-bar__actions form { margin: 0; }
.dash-bar__status { min-width: 3.5em; text-align: right; }
.dash-bar__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
                  flex-wrap: wrap; }
.dash-bar__foot form { margin: 0; }

/* The Layout choice at the top of the page. */
.dash-switch { display: inline-flex; align-items: center; gap: var(--s2); }
.dash-switch__label { font-size: 12.5px; font-weight: 600; color: var(--mq-steel); }
.dash-switch select { min-width: 11rem; min-height: 34px; padding-top: 4px; padding-bottom: 4px; width: auto; }
html:not(.js) .dash-bar[hidden] { display: block; }

/* Add a box: a panel that hangs from the bar, as wide as the bar allows,
   with a search box at the top and a real button on every row. */
.dash-add { position: static; }
.dash-add__list { width: min(600px, 100%); max-height: 70vh; overflow: auto; padding: var(--s2) 0; }
.dash-add__search { display: block; width: calc(100% - 2 * var(--s3)); margin: var(--s1) var(--s3) var(--s2);
                    min-height: 34px; }
.dash-add__section { padding: 0 var(--s2); }
.dash-add__section + .dash-add__section { border-top: 1px solid var(--mq-line-soft); margin-top: var(--s2);
                                          padding-top: var(--s1); }
.dash-add__group { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 600;
                   color: var(--mq-steel); margin: var(--s2) 10px 2px; }
.dash-add__item { display: flex; align-items: center; gap: var(--s3); padding: 6px 10px; margin: 0;
                  border-radius: var(--r-button); }
.dash-add__item:hover { background: var(--mq-paper-2); }
.dash-add__icon { flex: none; display: inline-flex; color: var(--mq-steel); }
.dash-add__icon .icon { width: 18px; height: 18px; }
.dash-add__text { flex: 1 1 auto; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.dash-add__text b { font-size: 13.5px; line-height: 18px; }
.dash-add__text .small { line-height: 16px; }
.dash-add__buttons { display: flex; gap: var(--s1); flex: none; }
.menu__list .dash-add__buttons button.btn { display: inline-flex; width: auto; min-height: 28px; padding: 3px 10px;
    justify-content: center; border: 1px solid var(--mq-mist); border-radius: var(--r-button);
    background: var(--mq-white); box-shadow: var(--shadow); font-size: 12.5px; line-height: 18px; font-weight: 600; }
.menu__list .dash-add__buttons button.btn:hover { border-color: var(--mq-mist-2); background: var(--mq-paper-2); }
.menu__list .dash-add__buttons button.btn--ghost { background: transparent; border-color: transparent; box-shadow: none; }
.menu__list .dash-add__buttons button.btn--ghost:hover { background: var(--mq-mist); }
.dash-add__none { margin: var(--s1) 10px; }
.dash__item.is-new { outline: 2px solid var(--mq-signal); outline-offset: 2px; }
}

@media (max-width: 1000px) {
    .dash { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
    .dash__item[data-w] { grid-column: auto; }
    .dash__item[data-h] { grid-row: auto; }
    .dash__item { overflow: visible; }
    .dash__item > .card__body, .dash__item > .card__body--flush { overflow: visible; }
    .dash.is-editing .dash__resize { display: none; }
}
@media print {
    .dash { display: block; }
    .dash__item { overflow: visible; margin-bottom: var(--s4); break-inside: avoid; }
    .dash__item > .card__body, .dash__item > .card__body--flush { overflow: visible; }
    .dash-bar, .dash-switch, .dash__grip, .dash__resize, .dash__edge, .dash__menu { display: none !important; }
}
.linklist { list-style: none; margin: 0; padding: 0; }
.linklist li { padding: var(--s2) var(--s4); border-bottom: 1px solid var(--mq-line-soft);
               display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.linklist li:last-child { border-bottom: none; }
.linklist a { font-weight: 500; }
.compare__title { margin-bottom: var(--s3); }
.compare__title h2 { margin-bottom: 0; }
.compare__side { min-width: 0; }

@media print {
    .section-nav, .tile__spark, .ch-hit { display: none !important; }
    .report-section { break-inside: auto; margin-bottom: var(--s6); }
    .report-section__head { border-color: #14171A; }
    .ch-cur, .ch-dot { fill: #14171A !important; }
    .ch-prev { fill: #B4B8BE !important; }
    .ch-line { stroke: #14171A !important; }
    .ch-line.ch-prev { stroke: #B4B8BE !important; }
    .ch-dot { stroke: #FFFFFF !important; }
    .ch-text { fill: #5B6068 !important; }
    .ch-text--value, .ch-text--label { fill: #14171A !important; }
    .ch-grid { stroke: #E4E2DC !important; }
    .delta--good { color: #1E8E5A !important; }
    .delta--bad { color: #C2382B !important; }
    .stat.tile { border: 1px solid #E4E2DC; padding: var(--s3); }
    .kpi-grid { display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* ------------------------------------------------- the chart gallery
   crm/chart_types.py draws every kind from the same primitives; these
   are the classes it hands them. Ranked segments step down a grey ramp
   (ch-s1 darkest), which reads as one ordered set rather than a
   rainbow; the system green and red appear only where a change is
   good or bad news. */
:root {
    --mq-ch-s1: #14171A; --mq-ch-s2: #33383E; --mq-ch-s3: #4E545B; --mq-ch-s4: #6A7078;
    --mq-ch-s5: #878D95; --mq-ch-s6: #A4A9B0; --mq-ch-s7: #C0C4C9; --mq-ch-s8: #DADDE1;
}
:root[data-theme="dark"] {
    --mq-ch-s1: #F1EFEA; --mq-ch-s2: #D3D2CF; --mq-ch-s3: #B5B5B4; --mq-ch-s4: #979899;
    --mq-ch-s5: #7A7C7F; --mq-ch-s6: #5E6166; --mq-ch-s7: #45494F; --mq-ch-s8: #33383E;
}
.ch-s1 { fill: var(--mq-ch-s1); } .ch-s2 { fill: var(--mq-ch-s2); } .ch-s3 { fill: var(--mq-ch-s3); }
.ch-s4 { fill: var(--mq-ch-s4); } .ch-s5 { fill: var(--mq-ch-s5); } .ch-s6 { fill: var(--mq-ch-s6); }
.ch-s7 { fill: var(--mq-ch-s7); } .ch-s8 { fill: var(--mq-ch-s8); }
.ch-swatch.ch-s1 { background: var(--mq-ch-s1); } .ch-swatch.ch-s2 { background: var(--mq-ch-s2); }
.ch-swatch.ch-s3 { background: var(--mq-ch-s3); } .ch-swatch.ch-s4 { background: var(--mq-ch-s4); }
.ch-swatch.ch-s5 { background: var(--mq-ch-s5); } .ch-swatch.ch-s6 { background: var(--mq-ch-s6); }
.ch-swatch.ch-s7 { background: var(--mq-ch-s7); } .ch-swatch.ch-s8 { background: var(--mq-ch-s8); }
.ch-s1-stroke { stroke: var(--mq-ch-s1); } .ch-s2-stroke { stroke: var(--mq-ch-s2); }
.ch-s3-stroke { stroke: var(--mq-ch-s3); } .ch-s4-stroke { stroke: var(--mq-ch-s4); }
.ch-s5-stroke { stroke: var(--mq-ch-s5); } .ch-s6-stroke { stroke: var(--mq-ch-s6); }
.ch-s7-stroke { stroke: var(--mq-ch-s7); } .ch-s8-stroke { stroke: var(--mq-ch-s8); }

.ch-good { fill: var(--mq-success); } .ch-bad { fill: var(--mq-danger); }
.ch-swatch.ch-good { background: var(--mq-success); } .ch-swatch.ch-bad { background: var(--mq-danger); }
.ch-good-stroke { stroke: var(--mq-success) !important; } .ch-bad-stroke { stroke: var(--mq-danger) !important; }
.ch-track { fill: var(--mq-mist); }
.ch-marker { fill: var(--mq-steel); } .ch-swatch.ch-marker { background: var(--mq-steel); width: 3px; }
.ch-marker-line { stroke: var(--mq-steel); stroke-width: 3; stroke-linecap: round; }
.ch-stem { stroke: var(--mq-mist-2); stroke-width: 2; }
.ch-link { stroke: var(--mq-mist-2); stroke-width: 3; stroke-linecap: round; }
.ch-connector { stroke: var(--mq-mist-2); stroke-width: 1; }
.ch-dot--prev { fill: var(--mq-white); stroke: var(--mq-ch-prev); stroke-width: 2.5; }
.ch-slope { stroke: var(--mq-mist-2); stroke-width: 2; stroke-linecap: round; }
.ch-guide { stroke: var(--mq-steel); stroke-width: 1; }
.ch-ring { fill: none; stroke: var(--mq-mist); stroke-width: 1; }
.ch-ring-circle { fill: none; stroke: var(--mq-mist); stroke-width: 1; }
.ch-radar { fill: var(--mq-ink); stroke: var(--mq-ink); stroke-width: 2; stroke-linejoin: round; }
.ch-radar--prev { fill: var(--mq-ch-prev); stroke: var(--mq-ch-prev); }
.ch-bubble { fill: var(--mq-ink); stroke: var(--mq-white); stroke-width: 2; }
.ch-heat { fill: var(--mq-ink); }
.ch-area { stroke: none; fill: var(--mq-ink); fill-opacity: 0.1; }
.ch-area.ch-prev { fill: var(--mq-ch-prev); }
.ch-area-fill { stroke: var(--mq-white); stroke-width: 1; }
.ch-bump { fill: none; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.ch-cell, .ch-slice { stroke: none; }
.ch-slice:hover, .ch-cell:hover, .ch-bubble:hover { opacity: 0.8; }
.ch-text--inside-soft { fill: var(--mq-white); fill-opacity: 0.85; }
.ch-text--heat { fill: var(--mq-white); font-weight: 600; }
.ch-text--big { fill: var(--mq-ink); font-size: 22px; font-weight: 700; }
.ch-text--hero { fill: var(--mq-ink); font-size: 34px; font-weight: 700; }
:root[data-theme="dark"] .ch-text--inside, :root[data-theme="dark"] .ch-text--inside-soft,
:root[data-theme="dark"] .ch-text--heat { fill: var(--mq-paper); }
:root[data-theme="dark"] .ch-s7 + .ch-text--inside, :root[data-theme="dark"] .ch-bubble { stroke: var(--mq-paper); }

/* The picker: "Show as" and one select in the chart card's head, every
   kind grouped by what it is for, the ones that do not suit this data
   left in but disabled and told why. */
.chart-picker { display: inline-flex; align-items: center; gap: var(--s2); flex: none; }
.chart-picker label { font-size: 12.5px; font-weight: 600; color: var(--mq-steel); white-space: nowrap; }
.chart-picker select { width: auto; min-width: 12rem; max-width: 18rem; min-height: 30px;
                       padding-top: 3px; padding-bottom: 3px; font-size: 13px; }

@media print {
    .chart-picker { display: none !important; }
    .ch-s1 { fill: #14171A !important; } .ch-s2 { fill: #33383E !important; }
    .ch-s3 { fill: #4E545B !important; } .ch-s4 { fill: #6A7078 !important; }
    .ch-s5 { fill: #878D95 !important; } .ch-s6 { fill: #A4A9B0 !important; }
    .ch-s7 { fill: #C0C4C9 !important; } .ch-s8 { fill: #DADDE1 !important; }
    .ch-radar, .ch-heat, .ch-bubble, .ch-area { fill: #14171A !important; }
    .ch-text--big, .ch-text--hero { fill: #14171A !important; }
}


/* --------------------------------------------------- traffic lights
   A report can be set to colour every figure of its first measure by
   which band it falls into, with the boundaries and the colour of each
   band chosen by the company (crm/rag.py). Each `.rag-*` class carries
   its colour and its wash as custom properties, so the cell, the tile
   and the swatch all read the same two values; the SVG marks need a
   real `fill` and so have their own `.ch-rag-*` classes.

   The brand accent is deliberately not among them: orange marks the one
   action on a screen, and a chart full of it would swallow that. */
:root {
    --mq-teal:   #0F7B76;
    --mq-purple: #6B4FA8;
    --mq-teal-wash:   #E3F1F0;
    --mq-purple-wash: #EEE9F7;
}
:root[data-theme="dark"] {
    --mq-teal:   #4FC3BC;
    --mq-purple: #A98CE0;
    --mq-teal-wash:   #16302F;
    --mq-purple-wash: #241E38;
}

.rag-green  { --rag-colour: var(--mq-success); --rag-wash: var(--mq-success-wash); }
.rag-amber  { --rag-colour: var(--mq-warning); --rag-wash: var(--mq-warning-wash); }
.rag-red    { --rag-colour: var(--mq-danger);  --rag-wash: var(--mq-danger-wash); }
.rag-blue   { --rag-colour: var(--mq-info);    --rag-wash: var(--mq-info-wash); }
.rag-teal   { --rag-colour: var(--mq-teal);    --rag-wash: var(--mq-teal-wash); }
.rag-purple { --rag-colour: var(--mq-purple);  --rag-wash: var(--mq-purple-wash); }
.rag-grey   { --rag-colour: var(--mq-steel);   --rag-wash: var(--mq-paper); }

/* A figure in a table: washed, with its colour as a rule down the edge
   so the band survives a colourblind reading as a position, not a hue
   alone - the figure itself is always there to be read. */
table.data td.rag-cell, table.data th.rag-cell {
    background: var(--rag-wash);
    box-shadow: inset 3px 0 0 var(--rag-colour);
}
/* The headline tile takes the colour on the figure itself. */
.rag-lead .stat__value { color: var(--rag-colour); }
.rag-lead { border-color: var(--rag-colour); }

.ch-rag-green  { fill: var(--mq-success); }
.ch-rag-amber  { fill: var(--mq-warning); }
.ch-rag-red    { fill: var(--mq-danger); }
.ch-rag-blue   { fill: var(--mq-info); }
.ch-rag-teal   { fill: var(--mq-teal); }
.ch-rag-purple { fill: var(--mq-purple); }
.ch-rag-grey   { fill: var(--mq-steel); }
.ch-swatch.ch-rag-green  { background: var(--mq-success); }
.ch-swatch.ch-rag-amber  { background: var(--mq-warning); }
.ch-swatch.ch-rag-red    { background: var(--mq-danger); }
.ch-swatch.ch-rag-blue   { background: var(--mq-info); }
.ch-swatch.ch-rag-teal   { background: var(--mq-teal); }
.ch-swatch.ch-rag-purple { background: var(--mq-purple); }
.ch-swatch.ch-rag-grey   { background: var(--mq-steel); }
/* A dot on a line chart keeps its ring, whatever colour it has taken. */
circle.ch-rag-green, circle.ch-rag-amber, circle.ch-rag-red, circle.ch-rag-blue,
circle.ch-rag-teal, circle.ch-rag-purple, circle.ch-rag-grey {
    stroke: var(--mq-white); stroke-width: 2;
}

.rag-legend { margin: 0 0 var(--s2); }

@media print {
    .rag-green  { --rag-colour: #1E8E5A; --rag-wash: #E6F2EC; }
    .rag-amber  { --rag-colour: #C98A12; --rag-wash: #F9F0DC; }
    .rag-red    { --rag-colour: #C2382B; --rag-wash: #F7E7E5; }
    .rag-blue   { --rag-colour: #2F6FA8; --rag-wash: #E7EFF6; }
    .rag-teal   { --rag-colour: #0F7B76; --rag-wash: #E3F1F0; }
    .rag-purple { --rag-colour: #6B4FA8; --rag-wash: #EEE9F7; }
    .rag-grey   { --rag-colour: #5B6068; --rag-wash: #F7F6F2; }
    table.data td.rag-cell, table.data th.rag-cell {
        background: var(--rag-wash) !important;
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
    .ch-rag-green  { fill: #1E8E5A !important; }
    .ch-rag-amber  { fill: #C98A12 !important; }
    .ch-rag-red    { fill: #C2382B !important; }
    .ch-rag-blue   { fill: #2F6FA8 !important; }
    .ch-rag-teal   { fill: #0F7B76 !important; }
    .ch-rag-purple { fill: #6B4FA8 !important; }
    .ch-rag-grey   { fill: #5B6068 !important; }
    /* The builder's panel, the picker and the ways out of an empty
       period are for the screen; every tab of the hub prints. */
    .panel, .chart-picker, .fixes, .tabs__nav { display: none !important; }
    .builder-layout { display: block; }
    html.js .tabs__panel:not(.is-active) { display: block !important; }
}

/* The pipeline switcher on the boards: a select and its neighbours, in a row. */
.pipeline-switch { display: inline-flex; align-items: center; gap: var(--s2); }
.pipeline-switch select { min-width: 12rem; }

/* Sizes on a quote or order line. One control under the description:
   "Size  L [1200] × W [450] mm" - labelled segments, the × drawn between
   the boxes that are showing, the unit said once. Hidden until a product
   sold in sizes is picked, or a size is already on the line. */
.dims { display: flex; align-items: center; gap: 6px; margin-top: 6px; flex-wrap: nowrap; white-space: nowrap; }
.dims.is-empty { display: none; }
.dims__label, .dims__unit { font-size: 11px; line-height: 16px; letter-spacing: 0.04em;
    text-transform: uppercase; color: var(--mq-steel); }
.dims__box { display: inline-flex; align-items: stretch; height: 30px;
    border: 1px solid var(--mq-mist); border-radius: var(--r-button); background: var(--mq-white); overflow: hidden; }
.dims__box:focus-within { border-color: var(--mq-ink); box-shadow: var(--focus-ring); }
.dims__box label { display: inline-flex; align-items: center; padding: 0 7px; font-size: 11px;
    font-weight: 700; color: var(--mq-steel); background: var(--mq-paper); border-right: 1px solid var(--mq-mist); }
table.lines .dims__box input, .dims__box input { border: 0; box-shadow: none; border-radius: 0; height: 100%;
    min-height: 0; width: 4rem; padding: 0 6px; font-size: 13px; text-align: right;
    font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.dims__box input::-webkit-outer-spin-button, .dims__box input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.dims__box input:focus { outline: none; box-shadow: none; }
/* A × between two boxes that are both showing. */
.dims__box:not([hidden]) ~ .dims__box:not([hidden])::before { content: "×"; display: inline-flex; align-items: center;
    padding: 0 3px 0 0; color: var(--mq-steel); background: var(--mq-white); }

/* What a website's visitor sees after the enquiry form: one card, the
   company's colours, nothing of ours. */
.web-result { max-width: 560px; margin: 8vh auto; padding: 0 var(--s4); }
.web-result__body h1 { font-size: 26px; margin: var(--s3) 0 var(--s2); }
.web-result__body p, .web-result__body ul { font-size: 15px; line-height: 1.5; color: var(--mq-ink); }

/* ------------------------------------------ website enquiry form

   Administration > Website form: each question off, optional or
   required, as one segmented control of three radio buttons - the same
   look as .toggle, ink rather than orange. Then the approval queue and
   the page that completes a website enquiry (enquiries/approve.html). */
.questions__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s2) var(--s4);
                  align-items: center; padding: var(--s3) 0; border-bottom: 1px solid var(--mq-mist); }
.questions__row:first-child { padding-top: 0; }
.questions__row:last-child { border-bottom: none; }
.questions__name { font-weight: 600; font-size: 14px; }
.questions__name .small { display: block; font-weight: 400; color: var(--mq-steel); }
@media (max-width: 560px) { .questions__row { grid-template-columns: minmax(0, 1fr); } }

.segmented { display: inline-flex; border: 1px solid var(--mq-mist); border-radius: var(--r-button);
             overflow: hidden; background: var(--mq-white); }
.segmented input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.segmented label { margin: 0; padding: 5px 12px; font-size: 13px; line-height: 20px; font-weight: 600;
                   text-transform: none; letter-spacing: 0; color: var(--mq-steel); cursor: pointer;
                   background: var(--mq-white); }
.segmented label:not(:first-of-type) { border-left: 1px solid var(--mq-mist); }
.segmented label:hover { background: var(--mq-paper); color: var(--mq-ink); }
.segmented input:checked + label { background: var(--mq-plate); color: var(--mq-plate-text); }
.segmented input:focus-visible + label { outline: 2px solid var(--mq-signal); outline-offset: -2px; }

/* Who is emailed when one arrives: a switch per person, their address
   beside the name, or a warning where mail to them cannot arrive. */
.people-switches { margin: var(--s2) 0; }
/* Inside a .field, whose labels are small capitals: these are sentences. */
.field .people-switches label.switch { font-size: 14px; line-height: 20px; font-weight: 500;
                                        letter-spacing: 0; text-transform: none; color: var(--mq-ink); }
.people-switches .text-warning { color: var(--mq-warning); font-weight: 500; }

.email-wording { margin: var(--s3) 0; }
.email-placeholders { margin-top: var(--s4); }
.email-placeholders code { font-size: 12px; }

.approval-message { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 14px; line-height: 1.55;
                    color: var(--mq-ink); }
.approval-message + .hint { margin-top: var(--s3); }
.approval-excerpt { min-width: 220px; max-width: 460px; }
.approval-form__foot { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center;
                       justify-content: space-between; }
.approval-form .section-title { margin: 0 0 var(--s3); }
.approval-strip { border-color: var(--mq-warning); }
.approval-notice { margin-bottom: var(--s4); align-items: center; }
/* On a phone the queue keeps who, what and the button; the full message
   is one tap away on the enquiry itself. */
@media (max-width: 560px) { .approval-table .approval-wide { display: none; } }

/* ============================================================ pipeline

   The Pipeline tab (dashboard/pipeline.html and pipeline/*.html): the
   view switcher and filters, the figures strip, the board and forecast
   columns, the cards, Won and Lost under the board, the list, the summary
   and the owner lanes. Tokens only, so the dark theme follows. */

.ptoolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
            gap: var(--s3); margin-bottom: var(--s3); }
.pviews { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px; max-width: 100%;
          background: var(--mq-white); border: 1px solid var(--mq-mist); border-radius: 10px;
          box-shadow: var(--shadow); }
.pviews__item { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
                border-radius: 7px; font-size: 13.5px; font-weight: 600; line-height: 20px;
                color: var(--mq-steel); white-space: nowrap; }
.pviews__item .icon { width: 16px; height: 16px; }
.pviews__item:hover { background: var(--mq-paper); color: var(--mq-ink); text-decoration: none; }
.pviews__item.is-active { background: var(--mq-plate); color: var(--mq-plate-text); }
.pviews__item.is-active .icon { color: inherit; }
.psort { display: inline-flex; align-items: center; gap: var(--s2); font-size: 13px; color: var(--mq-steel); }
.psort label { white-space: nowrap; }
.psort select { min-height: 34px; height: 34px; padding-top: 4px; padding-bottom: 4px; font-size: 13.5px; }

.pfilters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s3);
            padding: var(--s3) var(--s4); margin-bottom: var(--s4);
            background: var(--mq-white); border: 1px solid var(--mq-mist);
            border-radius: var(--r-card); box-shadow: var(--shadow); }
.pfilters .field { min-width: 150px; flex: 0 1 190px; }
.pfilters .pfilters__search { flex: 1 1 260px; }
.pfilters__actions { display: flex; gap: var(--s2); }

.pkpis { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s3);
         margin-bottom: var(--s4); }
.pkpi { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: var(--s3) var(--s4);
        background: var(--mq-white); border: 1px solid var(--mq-mist); border-radius: var(--r-card);
        box-shadow: var(--shadow); color: inherit; }
a.pkpi:hover { border-color: var(--mq-mist-2); text-decoration: none; box-shadow: var(--shadow-md); }
.pkpi__label { font-size: 11.5px; line-height: 16px; font-weight: 600; letter-spacing: 0.08em;
               text-transform: uppercase; color: var(--mq-steel); }
.pkpi__value { font-size: 24px; line-height: 30px; font-weight: 700; color: var(--mq-ink);
               font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden;
               text-overflow: ellipsis; }
.pkpi__note { font-size: 12.5px; line-height: 18px; color: var(--mq-steel); }
.pkpi--warn { border-color: var(--mq-warning-line); background: var(--mq-warning-wash); }
.pkpi--warn .pkpi__value { color: var(--mq-warning); }

/* The board and the forecast: columns that share the width, and scroll
   inside their own frame - never the page. */
.pboard-wrap { min-width: 0; overflow-x: auto; padding-bottom: var(--s2); margin-bottom: var(--s3);
               scroll-snap-type: x proximity; }
.pboard { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(220px, 1fr);
          gap: var(--s3); align-items: start; }
.pcol { display: flex; flex-direction: column; min-width: 0; max-height: calc(100vh - 150px);
        background: var(--mq-paper-2); border: 1px solid var(--mq-mist); border-radius: 10px;
        scroll-snap-align: start; transition: border-color 0.12s, box-shadow 0.12s, background 0.12s; }
.pcol.is-over { border-color: var(--mq-ink); box-shadow: var(--focus-ring); background: var(--mq-white); }
.pcol__head { flex: none; padding: var(--s3) var(--s3) var(--s2); border-bottom: 1px solid var(--mq-mist); }
.pcol__top { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); }
.pcol__name { margin: 0; font-size: 14px; line-height: 20px; font-weight: 700; color: var(--mq-ink);
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pcol__count { flex: none; min-width: 26px; padding: 0 8px; border-radius: var(--r-pill);
               background: var(--mq-white); border: 1px solid var(--mq-mist); font-size: 12px;
               font-weight: 600; line-height: 20px; text-align: center; color: var(--mq-ink);
               font-variant-numeric: tabular-nums; }
.pcol__sub { font-size: 12px; line-height: 16px; color: var(--mq-steel); }
.pcol__figures { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px var(--s2); margin-top: 4px;
                 font-size: 12.5px; color: var(--mq-steel); font-variant-numeric: tabular-nums; }
.pcol__figures b { font-size: 15px; color: var(--mq-ink); }
.pcol__odds { margin-left: auto; font-size: 11.5px; font-weight: 600; }
.pcol__bar { height: 4px; margin-top: var(--s2); border-radius: 2px; background: var(--mq-mist); overflow: hidden; }
.pcol__bar i { display: block; height: 100%; background: var(--mq-ink); border-radius: 2px; }
.pcol__warn { display: inline-block; margin-top: 6px; font-size: 12px; font-weight: 600; color: var(--mq-warning); }
.pcol__list { display: flex; flex-direction: column; gap: var(--s2); padding: var(--s2);
              overflow-y: auto; flex: 1 1 auto; min-height: 72px; }
.pcol__empty { margin: var(--s4) 0; text-align: center; font-size: 13px; line-height: 19px; color: var(--mq-steel); }
.pcol__more { flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
              padding: var(--s2) var(--s3); border-top: 1px solid var(--mq-mist);
              font-size: 13px; font-weight: 600; color: var(--mq-ink); }
.pcol__more .icon { width: 14px; height: 14px; }
.pcol--late .pcol__head { box-shadow: inset 0 3px 0 var(--mq-warning); border-radius: 10px 10px 0 0; }
.pcol--late .pcol__bar i { background: var(--mq-warning); }
.pcol--none .pcol__bar i { background: var(--mq-mist-2); }

/* A card: the whole of it opens the enquiry; the corner menu acts on it. */
.pcard { position: relative; flex: none; background: var(--mq-white); border: 1px solid var(--mq-mist);
         border-radius: 8px; box-shadow: var(--shadow);
         transition: box-shadow 0.12s, border-color 0.12s, opacity 0.12s; }
.pcard:hover { border-color: var(--mq-mist-2); box-shadow: var(--shadow-md); }
.pcard[draggable="true"] { cursor: grab; }
.pcard.is-dragging { opacity: 0.45; }
.pcard__link { display: flex; flex-direction: column; gap: 3px; padding: var(--s3); color: inherit; }
.pcard__link:hover { text-decoration: none; }
.pcard__title { font-size: 14px; line-height: 19px; font-weight: 600; color: var(--mq-ink);
                display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pcard__company { font-size: 12.5px; line-height: 17px; color: var(--mq-steel);
                  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pcard__money { display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
                margin-top: 4px; font-size: 14px; font-variant-numeric: tabular-nums; }
.pcard__money b { color: var(--mq-ink); }
.pcard__prob { flex: none; max-width: 55%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
               font-size: 11.5px; font-weight: 600; line-height: 18px; padding: 0 7px;
               border-radius: var(--r-pill); background: var(--mq-paper); color: var(--mq-steel); }
.pcard__prob.is-warn { background: var(--mq-warning-wash); color: var(--mq-warning); }
.pcard__foot { display: flex; align-items: center; flex-wrap: wrap; gap: 4px var(--s2); margin-top: 6px;
               padding-top: 8px; border-top: 1px solid var(--mq-line-soft); font-size: 12px; color: var(--mq-steel); }
.pcard__who, .pwho { display: inline-flex; align-items: center; justify-content: center; flex: none;
                     width: 22px; height: 22px; border-radius: 50%; background: var(--mq-plate);
                     color: var(--mq-plate-text); font-size: 10px; font-weight: 700; letter-spacing: 0.02em; }
.pcard__who.is-nobody, .pwho.is-nobody { background: none; color: var(--mq-steel); border: 1px dashed var(--mq-mist-2); }
.pwho--lg { width: 34px; height: 34px; font-size: 12.5px; }
.pcard__date, .pcard__quotes { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
.pcard__date .icon, .pcard__quotes .icon { width: 13px; height: 13px; }
.pcard__date.is-overdue, .pdate.is-overdue { color: var(--mq-danger); font-weight: 600; }
.pcard__date.is-soon, .pdate.is-soon { color: var(--mq-warning); font-weight: 600; }
.pcard__quiet { padding: 0 6px; border-radius: var(--r-pill); background: var(--mq-warning-wash);
                color: var(--mq-warning); font-weight: 600; line-height: 18px; white-space: nowrap; }
.pcard__ref { padding-right: 28px; font-size: 11.5px; line-height: 16px; color: var(--mq-steel);
              font-variant-numeric: tabular-nums; }
.pcard__menu { position: absolute; top: 6px; right: 6px; }
/* As wide as its words, not the usual 220px: a column scrolls, and would cut off a menu wider than its card. */
.pcard__menu .menu__list { min-width: 0; }
.pcard__more { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
               border-radius: 6px; color: var(--mq-steel); }
.pcard__more:hover, .pcard__menu[open] .pcard__more { background: var(--mq-paper); color: var(--mq-ink); }
.pcard__more .icon { width: 18px; height: 18px; }
.pcard--mini .pcard__link { padding: var(--s2); gap: 1px; }
.pcard--mini .pcard__title { padding-right: 22px; font-size: 13px; line-height: 17px; -webkit-line-clamp: 1; }
.pcard--mini .pcard__company { font-size: 12px; }
.pcard--mini .pcard__money { margin-top: 2px; font-size: 12.5px; }
.pcard--mini .pcard__menu { top: 3px; right: 3px; }

/* Won and Lost, under the board: always there, bigger while a card is
   being dragged, lit when one is over them. */
.poutcomes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); margin-bottom: var(--s2); }
.poutcome { display: flex; align-items: center; justify-content: center; gap: var(--s2); min-height: 52px;
            padding: var(--s2) var(--s4); border: 2px dashed var(--mq-mist-2); border-radius: 10px;
            font-size: 13.5px; transition: min-height 0.15s, box-shadow 0.12s, border-style 0.12s; }
.poutcome .icon { width: 18px; height: 18px; flex: none; }
.poutcome--won { border-color: var(--mq-success-line); color: var(--mq-success); background: var(--mq-success-wash); }
.poutcome--lost { border-color: var(--mq-danger-line); color: var(--mq-danger); background: var(--mq-danger-wash); }
.is-dragging-card .poutcome { min-height: 76px; }
.poutcome.is-over { border-style: solid; box-shadow: var(--focus-ring); }
.pboard-hint { margin: 0 0 var(--s4); }

/* The list. */
.pchips { margin-bottom: var(--s3); }
.plist .row-title { font-weight: 600; }
.plist__stage { display: flex; gap: var(--s1); margin: 0; }
.plist__stage select { min-height: 30px; height: 30px; max-width: 190px; padding: 2px 26px 2px 8px;
                       font-size: 13px; box-shadow: none; }
.plist tr.is-overdue > td:first-child { box-shadow: inset 3px 0 0 var(--mq-danger); }
.plist .pwho { margin-right: 4px; vertical-align: middle; }
.psorter { color: inherit; white-space: nowrap; }
.psorter.is-sorted { color: var(--mq-ink); }
.plist__menu { position: relative; top: auto; right: auto; }
.plist__phone { display: none; }

/* The summary. */
.pshare-legend { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5); margin: var(--s3) 0 0; padding: 0;
                 list-style: none; font-size: 13px; color: var(--mq-steel); }
.pshare-legend li { display: inline-flex; align-items: center; gap: 6px; }
.pshare-legend b { color: var(--mq-ink); }
.pcallouts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s3); margin-top: var(--s4); }
.pcallout { display: flex; flex-direction: column; gap: 2px; padding: var(--s3); color: inherit;
            border: 1px solid var(--mq-mist); border-radius: var(--r-card); background: var(--mq-paper); }
a.pcallout:hover { text-decoration: none; border-color: var(--mq-mist-2); }
.pcallout__label { font-size: 11.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--mq-steel); }
.pcallout b { font-size: 16px; line-height: 22px; color: var(--mq-ink); }
.pcallout span:last-child { font-size: 12.5px; color: var(--mq-steel); }
.pcallout--warn { border-color: var(--mq-warning-line); background: var(--mq-warning-wash); }
.pcallout--warn b { color: var(--mq-warning); }
/* Figures line up under their headings, in the pipeline's own tables. */
.plist th.num, .psummary__table th.num { text-align: right; }
.psummary__total td { font-weight: 700; color: var(--mq-ink); background: var(--mq-paper);
                      border-top: 1px solid var(--mq-mist); }
/* Drawn at its own size, never blown up to the card's width; the table
   beneath carries the same figures, which is all a phone needs. */
.psummary .chart { max-width: 760px; }
.psummary .share { height: auto; }
@media (max-width: 560px) { .psummary .chart { display: none; } }

/* By owner: a lane per person; the stages run across and scroll with the
   lanes, the person staying put at the left. */
.plane-wrap { min-width: 0; overflow-x: auto; margin-bottom: var(--s3); }
.plane { display: grid; grid-template-columns: 200px; grid-auto-flow: column; grid-auto-columns: minmax(170px, 1fr);
         gap: var(--s2); min-width: min-content; padding: var(--s2); margin-bottom: var(--s2);
         background: var(--mq-white); border: 1px solid var(--mq-mist); border-radius: 10px; box-shadow: var(--shadow); }
.plane--head { padding-top: 0; padding-bottom: 0; margin-bottom: var(--s1); background: none; border: 0; box-shadow: none; }
.plane__stage { padding: 0 var(--s1); font-size: 11.5px; font-weight: 600; letter-spacing: 0.08em;
                text-transform: uppercase; color: var(--mq-steel); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plane__who { position: sticky; left: 0; z-index: 1; display: flex; gap: var(--s2); align-items: flex-start;
              padding: var(--s2); background: var(--mq-white); }
.plane--head .plane__who { background: none; }
.plane__name { font-size: 14px; font-weight: 700; color: var(--mq-ink); }
.plane__figures { font-size: 12.5px; line-height: 18px; color: var(--mq-steel); font-variant-numeric: tabular-nums; }
.plane__figures b { color: var(--mq-ink); }
.plane__warn { display: inline-block; margin-top: 4px; font-size: 12px; font-weight: 600; color: var(--mq-warning); }
.plane__cell { display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: var(--s1);
               border-radius: 8px; background: var(--mq-paper-2); }
.plane__cellhead { display: none; font-size: 11.5px; font-weight: 600; color: var(--mq-steel); }
.plane__none { padding: var(--s2) 0; text-align: center; color: var(--mq-mist-2); }
.plane__more { padding: 2px var(--s1); font-size: 12.5px; font-weight: 600; }

@media (max-width: 900px) {
    .pkpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .pkpis > :last-child { grid-column: 1 / -1; }
}
@media (max-width: 720px) {
    .pviews { flex-wrap: nowrap; overflow-x: auto; width: 100%; }
    .pviews__item { padding: 6px 10px; }
    .pboard { grid-auto-columns: minmax(84vw, 1fr); }
    .pcol { max-height: none; }
    .pfilters { padding: var(--s3); gap: var(--s2); }
    .pfilters .pfilters__search { flex: 1 1 100%; min-width: 0; }
    .pfilters .field { flex: 1 1 calc(50% - var(--s2)); min-width: 0; }
    .pfilters__actions { flex: 1 1 calc(50% - var(--s2)); }
    .pfilters__actions .btn { flex: 1 1 auto; justify-content: center; }
    .plist .plist__narrow { display: none; }
    .plist .plist__phone { display: block; }
    .pcallouts { grid-template-columns: minmax(0, 1fr); }
    .plane--head { display: none; }
    .plane { grid-template-columns: minmax(0, 1fr); grid-auto-flow: row; min-width: 0; }
    .plane__who { position: static; }
    .plane__cellhead { display: block; }
    .plane__cell--empty { display: none; }
}

/* ---------------------------------------------------------- roles

   Administration > Roles: which tabs each kind of person sees. The
   editor is the tab switches on the left and, beside them, the menu as
   somebody with the role will see it and the people who hold it. */
.roles-table .role-tabs { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.roles-start { background: var(--mq-white); }
.roles-start p { margin: 0 0 var(--s1); }
.roles-start .choices { margin-top: var(--s3); }
.roles-start__item { display: flex; margin: 0; }
.roles-start .choice { width: 100%; text-align: left; font: inherit; color: inherit; }

.role-editor { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
               gap: var(--s4); align-items: start; }
.role-editor__main, .role-editor__aside { display: flex; flex-direction: column; gap: var(--s4);
                                          min-width: 0; }
.role-editor__name, .role-new__name { max-width: 420px; }
.card__head-actions { margin-left: auto; display: inline-flex; gap: var(--s1); }
.role-status { align-self: center; min-width: 4.5em; text-align: right; }

.role-groups { display: flex; flex-direction: column; gap: var(--s4); }
.role-group { border: 0; margin: 0; padding: 0; min-width: 0; }
.role-group__name { padding: 0; margin-bottom: var(--s2); font-size: 11px; letter-spacing: 0.06em;
                    text-transform: uppercase; font-weight: 600; color: var(--mq-steel); }
.role-group__tabs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); }
.role-tab { display: flex; gap: var(--s3); align-items: flex-start; padding: var(--s3);
            border: 1px solid var(--mq-mist); border-radius: var(--r-card); background: var(--mq-white);
            cursor: pointer; transition: border-color 120ms, box-shadow 120ms; }
.role-tab:hover { border-color: var(--mq-mist-2); }
.role-tab:has(input:checked) { border-color: var(--mq-success); box-shadow: inset 0 0 0 1px var(--mq-success); }
.role-tab .switch { margin-top: 1px; }
.role-tab__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.role-tab__name { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; line-height: 20px;
                  font-weight: 600; color: var(--mq-ink); }
.role-tab__name .icon { width: 16px; height: 16px; color: var(--mq-steel); flex: none; }
.role-tab__hint { font-size: 12.5px; line-height: 18px; color: var(--mq-steel); }
.role-tab__note { display: inline-flex; align-items: center; gap: 4px; margin-top: 2px;
                  font-size: 12px; line-height: 16px; font-weight: 600; color: var(--mq-warning); }

.role-preview__menu { display: flex; flex-direction: column; gap: 2px; }
.role-preview__group { margin-top: var(--s2); font-size: 11px; letter-spacing: 0.06em;
                       text-transform: uppercase; font-weight: 600; color: var(--mq-steel); }
.role-preview__group:first-child { margin-top: 0; }
.role-preview__item { display: flex; align-items: center; gap: var(--s2); padding: 5px var(--s2);
                      border-radius: var(--r-button); background: var(--mq-paper);
                      font-size: 14px; line-height: 20px; color: var(--mq-ink); }
.role-preview__item .icon { width: 16px; height: 16px; color: var(--mq-steel); flex: none; }
.role-preview__foot { margin: var(--s3) 0 0; }

.role-people { list-style: none; margin: 0; padding: 0; }
.role-person { display: flex; align-items: center; gap: var(--s3); padding: var(--s2) var(--s4);
               border-bottom: 1px solid var(--mq-mist); }
.role-person:last-child { border-bottom: 0; }
.role-person__who { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.role-person__name { font-size: 14px; line-height: 20px; font-weight: 600; color: var(--mq-ink); }
.role-person__email { font-size: 12.5px; line-height: 18px; color: var(--mq-steel);
                      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.role-person__move { flex: none; }
.role-person__move select { max-width: 11rem; }
.role-people__foot { display: flex; flex-direction: column; gap: var(--s2); align-items: stretch; }
.role-people__foot p { margin: 0; }
.role-add > summary { list-style: none; display: inline-flex; align-self: flex-start; }
.role-add > summary::-webkit-details-marker { display: none; }
.role-add__form { display: flex; flex-direction: column; gap: var(--s2); align-items: flex-start;
                  margin-top: var(--s2); }
.role-add__list { display: flex; flex-direction: column; gap: 2px; width: 100%; max-height: 260px;
                  overflow-y: auto; padding: var(--s1); border: 1px solid var(--mq-mist);
                  border-radius: var(--r-button); background: var(--mq-white); }
.role-add__person { display: flex; align-items: center; gap: var(--s2); padding: 4px var(--s1);
                    border-radius: var(--r-button); font-size: 14px; line-height: 20px; cursor: pointer; }
.role-add__person:hover { background: var(--mq-paper); }
.role-add__person input { margin: 0; flex: none; }
.role-add__person .muted { margin-left: auto; white-space: nowrap; }
.role-picker select { min-width: 9.5rem; }

@media (max-width: 1100px) {
    .role-editor { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
    .role-group__tabs { grid-template-columns: minmax(0, 1fr); }
    .role-person { flex-wrap: wrap; }
    .role-person__move { width: 100%; padding-left: 42px; }
    .role-person__move select { max-width: none; width: 100%; }
    .card__head-actions { margin-left: 0; }
}
.role-status:empty { display: none; }
.role-new__starts { border: 0; margin: var(--s5) 0 0; padding: 0; min-width: 0; }
.role-new__legend { padding: 0; margin-bottom: var(--s2); font-size: 11.5px; line-height: 16px;
                    font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
                    color: var(--mq-steel); }
.role-new__tabs { margin-top: 2px; }

/* ------------------------------------------------------ automations */
/* Administration > Automations. The builder is the role editor's shape:
   the three cards - When, Only if, Then - down the left, and the
   automation in plain English, the test and the log down the right. */
.auto-editor { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
               gap: var(--s4); align-items: start; }
.auto-editor__main, .auto-editor__aside { display: flex; flex-direction: column; gap: var(--s4);
                                          min-width: 0; }
.auto-name { max-width: 520px; }
.auto-switch { display: inline-flex; align-items: center; gap: var(--s2); margin: 0; }
.auto-plan .card__body p { margin: 0 0 var(--s1); }
.auto-plan .card__body p:last-child { margin-bottom: 0; }
.auto-plan .icon { vertical-align: -3px; }

.auto-card .card__head h2 { display: flex; align-items: center; gap: var(--s2); }
.auto-num { display: inline-flex; align-items: center; justify-content: center; flex: none;
            width: 22px; height: 22px; border-radius: 50%; font-size: 12px; font-weight: 700;
            background: var(--mq-plate); color: var(--mq-plate-text); }

/* When: the sentence, one box after another, wrapping as it must. */
.auto-sentence { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s4); align-items: flex-end; }
.auto-sentence .field { flex: 1 1 200px; min-width: 0; }
.auto-sentence .auto-days { flex: 0 0 100px; }

/* Only if: a row per condition. */
.auto-match { margin-bottom: var(--s3); }
.auto-match select { max-width: 280px; }
.auto-rows { list-style: none; margin: 0 0 var(--s3); padding: 0; display: flex;
             flex-direction: column; gap: var(--s2); }
.auto-row { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1.2fr) auto;
            gap: var(--s2); align-items: center; padding: var(--s2);
            border: 1px solid var(--mq-line-soft); border-radius: var(--r-card); background: var(--mq-paper); }
.auto-row .field { gap: 0; min-width: 0; }
.auto-row__remove { grid-column: -2 / -1; justify-self: end; }
.auto-inline { display: flex; align-items: center; gap: var(--s2); }
.auto-inline input { max-width: 120px; }
.auto-empty { margin: 0 0 var(--s3); }

/* Then: a block per step, numbered, with its own tools. */
.auto-steps { list-style: none; margin: 0 0 var(--s4); padding: 0; display: flex;
              flex-direction: column; gap: var(--s3); }
.auto-step { border: 1px solid var(--mq-mist); border-radius: var(--r-card); background: var(--mq-white); }
.auto-step__head { display: flex; align-items: center; gap: var(--s2); padding: var(--s2) var(--s3);
                   border-bottom: 1px solid var(--mq-line-soft); background: var(--mq-paper);
                   border-radius: var(--r-card) var(--r-card) 0 0; }
.auto-step__num { display: inline-flex; align-items: center; justify-content: center; flex: none;
                  width: 22px; height: 22px; border-radius: 50%; font-size: 12px; font-weight: 700;
                  border: 1.5px solid var(--mq-ink); color: var(--mq-ink); }
.auto-step__kind { flex: 1 1 auto; min-width: 0; max-width: 320px; font-weight: 600; }
.auto-step__tools { margin-left: auto; display: inline-flex; gap: 2px; flex: none; }
.auto-step__body { padding: var(--s3); display: flex; flex-direction: column; gap: var(--s2); }
.auto-step__body .hint { margin: 0; }
.auto-fields { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: flex-end; }
.auto-fields .field { flex: 1 1 180px; min-width: 0; }
.auto-fields .auto-fields__wide { flex-basis: 100%; }
.auto-checks { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); padding-top: 2px; }
.auto-check { display: inline-flex; align-items: center; gap: var(--s2); font-size: 14px; line-height: 20px;
              font-weight: 500; color: var(--mq-ink); cursor: pointer; }
.auto-check input { margin: 0; }
/* Inside a .field, whose labels are small capitals: these are choices. */
.field .auto-check { text-transform: none; letter-spacing: 0; font-size: 14px;
                     line-height: 20px; font-weight: 500; color: var(--mq-ink); }
.auto-warn { display: flex; gap: var(--s2); align-items: flex-start; }
.auto-warn .icon { flex: none; margin-top: 2px; }
.auto-add { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.auto-add label { font-size: 13.5px; font-weight: 600; color: var(--mq-ink); }
.auto-add select { width: auto; min-width: 240px; max-width: 100%; }
.auto-record { display: flex; flex-direction: column; gap: var(--s2); }
.auto-record__row { display: grid; grid-template-columns: minmax(120px, 0.8fr) minmax(0, 1fr) minmax(0, 1.2fr);
                    gap: var(--s2); align-items: center; }
.auto-record__row .field { gap: 0; min-width: 0; }
.auto-record__label { font-size: 14px; line-height: 20px; font-weight: 500; color: var(--mq-ink); }

/* The wording that can be filled in, folded away under a box. */
.auto-help > summary { list-style: none; cursor: pointer; font-size: 13px; font-weight: 600;
                       color: var(--mq-steel); padding: 2px 0; }
.auto-help > summary::-webkit-details-marker { display: none; }
.auto-help > summary::before { content: "+ "; }
.auto-help[open] > summary::before { content: "- "; }
.auto-help > summary:hover { color: var(--mq-ink); }
.auto-help .hint { margin: var(--s1) 0; }
.auto-help__list { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 2px var(--s3);
                   margin: 0; font-size: 13px; line-height: 19px; }
.auto-help__list dt, .auto-help__list dd { margin: 0; }
.auto-help__list dd { color: var(--mq-steel); }
.auto-help code, .auto-step__body .hint code { font-size: 12.5px; }

/* In short. */
.auto-summary__body p { margin: 0 0 var(--s2); }
.auto-summary__when { font-size: 16px; line-height: 24px; font-weight: 600; color: var(--mq-ink); }
.auto-summary__then { margin-bottom: 4px !important; }
.auto-summary__steps { margin: 0 0 var(--s3); padding-left: 20px; }
.auto-summary__steps li + li { margin-top: 4px; }
.auto-problems { border-left: 3px solid var(--mq-warning); background: var(--mq-warning-wash);
                 padding: var(--s2) var(--s3); border-radius: 0 var(--r-button) var(--r-button) 0;
                 font-size: 13.5px; line-height: 20px; }
.auto-problems p { margin: 0 !important; }
.auto-problems ul { margin: 4px 0 0; padding-left: 18px; }
.auto-ready { display: flex; gap: 6px; align-items: center; color: var(--mq-success);
              font-size: 13.5px; font-weight: 600; }
.auto-offreason { display: flex; gap: 6px; align-items: flex-start; color: var(--mq-warning);
                  font-size: 13.5px; line-height: 20px; margin: var(--s1) 0 0; }
.auto-offreason .icon { flex: none; margin-top: 2px; }

/* Test it. */
.auto-test__pick { display: flex; flex-direction: column; gap: var(--s2); }
.auto-test { margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--mq-line-soft);
             font-size: 14px; line-height: 20px; }
.auto-test p { margin: 0 0 var(--s2); }
.auto-test__checks { list-style: none; margin: 0 0 var(--s2); padding: 0; display: flex;
                     flex-direction: column; gap: 4px; }
.auto-test__checks li { display: flex; gap: 6px; align-items: flex-start; }
.auto-test__checks .icon { flex: none; margin-top: 2px; }
.auto-test__checks .is-yes .icon { color: var(--mq-success); }
.auto-test__checks .is-no { color: var(--mq-steel); }
.auto-test__checks .is-no .icon { color: var(--mq-danger); }
.auto-test__steps { margin: 0; padding-left: 20px; }
.auto-test__steps li + li { margin-top: 4px; }
.auto-test__failed { color: var(--mq-danger); }
.auto-test__nothing { color: var(--mq-steel); }

/* The log. */
.auto-runs { list-style: none; margin: 0; padding: 0; }
.auto-run { padding: var(--s2) 0; border-bottom: 1px solid var(--mq-line-soft); }
.auto-run:first-child { padding-top: 0; }
.auto-run:last-child { border-bottom: 0; padding-bottom: 0; }
.auto-run__head { display: flex; flex-wrap: wrap; gap: 4px var(--s2); align-items: center; }
.auto-run__record { font-size: 14px; line-height: 20px; font-weight: 600; }
.auto-run__summary { margin-top: 2px; color: var(--mq-ink); }
.auto-run__failures { list-style: none; margin: 4px 0 0; padding: 0; color: var(--mq-danger); }
.auto-run__failures .icon { width: 13px; height: 13px; vertical-align: -2px; }

/* The list, and the ready-made ones. */
.auto-table__on { width: 64px; }
.auto-table__on .switch { margin: 0; }
.auto-table__sentence { max-width: 72ch; margin-top: 2px; }
.auto-table .badge { margin-top: 4px; }
.auto-table__meta { display: none; margin-top: 2px; }
p + .auto-starters { margin-top: var(--s3); }
.auto-starters__item { margin: 0; }
.auto-starters .choice { width: 100%; height: 100%; text-align: left; font: inherit; color: inherit; }
.auto-starters .choice[disabled] { opacity: 0.55; cursor: not-allowed; }
.auto-new { align-items: start; }

@media (max-width: 1100px) {
    .auto-editor { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
    .auto-row { grid-template-columns: minmax(0, 1fr) auto; }
    .auto-row .field { grid-column: 1 / 2; }
    .auto-row__remove { grid-column: 2 / 3; grid-row: 1; }
    .auto-record__row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
    .auto-step__kind { max-width: none; }
    .auto-add select { min-width: 0; width: 100%; }
    .auto-sentence .auto-days { flex: 1 1 100%; }
    .auto-table__wide { display: none; }
    .auto-table__meta { display: block; }
}
