/* QuoteNod app styles — built on branding/tokens.css values */
:root {
  --navy-900: #0b1626;
  --navy-800: #10203a;
  --navy-700: #1a3050;
  --accent: #17c96f;
  --accent-strong: #0fb35f;
  --accent-tint: #e3f9ee;
  --on-accent: #06231a;
  --bg: #ffffff;
  --bg-raised: #f6f8fa;
  --bg-inset: #eceff3;
  --text: #12233c;
  --text-muted: #4d5e72;
  --text-faint: #5b6b7d;
  --border: #cdd5de;
  --border-soft: #e2e7ec;
  /* Three names that newer blocks reach for. They are aliases, not new
     colours: a rule that asks for an undefined custom property is thrown
     away whole and in silence, which is how a card lost its left border and
     a toolbar its tint without anything looking broken enough to notice.
     Aliases rather than a find-and-replace so both names keep working, and
     they resolve per theme because the tokens behind them do. */
  --brand: var(--accent);
  --bg-card: var(--bg-raised);
  --line: var(--border);
  --focus: #1864ab;
  --ok: #128a52;
  --ok-bg: #e3f9ee;
  --warn: #b26a00;
  --warn-bg: #fdf1dc;
  --danger: #c92a2a;
  --danger-bg: #fbe9e9;
  /* Links. The browser's blue is the one colour on the page that belongs to
     nobody — it says "web document", not "this app". These are the same green
     the rest of the design is built on, darkened for white paper so a
     sentence with a link in it still reads: 5.4:1 against white, and 8:1 the
     other way round. --focus stays blue, because a focus ring is meant to
     stand apart from everything it lands on. */
  --link: #0b7a44;
  --link-hover: #00663a;
  /* The accent as text on light paper. The bright green is a surface colour —
     2.2:1 against white — so words in it get this darker cut (5.4:1); dark
     paper flips it back to the bright one. */
  --accent-text: #0b7a44;
  --radius: 10px;
  --radius-lg: 16px;
  --shadow-1: 0 1px 3px rgb(11 22 38 / 0.1);
  /* One typeface for everything, named once. Onest is served from here and
     declared at the foot of this file; the system stack stands in for the
     moment before it arrives. */
  --font: 'Onest', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* The arrow on a dropdown. A picture rather than the browser's own, so it is
     the same shape everywhere; held in a variable because a colour cannot be
     read from a custom property inside a data URI, so each theme names its
     own. */
  --chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234d5e72' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg: #0b1626;
    --bg-raised: #10203a;
    --bg-inset: #0e1b2f;
    --text: #edf2f7;
    --text-muted: #9fb0c3;
    --text-faint: #8fa1b6;
    --accent-text: #17c96f;
    --border: #2c405c;
    --border-soft: #1d3049;
    --focus: #74b6ff;
    --ok: #2be080;
    --ok-bg: #10321f;
    --warn: #ffc963;
    --warn-bg: #3a2c10;
    --danger: #ff8787;
    --danger-bg: #3d1a1a;
    --accent-tint: #10321f;
    --shadow-1: 0 1px 3px rgb(0 0 0 / 0.4);
    --link: #4ee08f;
    --link-hover: #8cf0bb;
    --chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239fb0c3' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  }
}
:root[data-theme='dark'] {
  --bg: #0b1626;
  --bg-raised: #10203a;
  --bg-inset: #0e1b2f;
  --text: #edf2f7;
  --text-muted: #9fb0c3;
  --text-faint: #8fa1b6;
  --accent-text: #17c96f;
  --border: #2c405c;
  --border-soft: #1d3049;
  --focus: #74b6ff;
  --ok: #2be080;
  --ok-bg: #10321f;
  --warn: #ffc963;
  --warn-bg: #3a2c10;
  --danger: #ff8787;
  --danger-bg: #3d1a1a;
  --accent-tint: #10321f;
  --shadow-1: 0 1px 3px rgb(0 0 0 / 0.4);
  --link: #4ee08f;
  --link-hover: #8cf0bb;
  --chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239fb0c3' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
}

* {
  box-sizing: border-box;
}
/* hidden means hidden.
   The browser's own rule for it is in the user-agent stylesheet, which any
   rule written here outranks however plain it is — so the moment a component
   is given a display of its own, its hidden attribute quietly stops working
   and a script that sets it is talking to nobody. That is how the compose
   window ended up permanently showing "Drop to attach". Ten components were
   one display rule away from the same fault; this is the rule that means
   there is no eleventh. */
[hidden] {
  display: none !important;
}
html {
  -webkit-text-size-adjust: 100%;
  /* Painted before the body exists, and it is what shows behind the status bar
     and the home indicator once the app is installed to a home screen. Without
     it those strips stay the browser's white whatever the theme is. */
  background: var(--bg);
}
/* Tells the browser which way round its own furniture goes: form controls,
   scrollbars, and the canvas it paints before this stylesheet has arrived. */
:root[data-theme='dark'] {
  color-scheme: dark;
}
:root[data-theme='light'] {
  color-scheme: light;
}
:root:not([data-theme]) {
  color-scheme: light dark;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 1rem/1.5 var(--font);
}
/* The pages anybody may read without signing in — the Terms, the Privacy
   Notice, the other policies, sign-in and sign-up — are scaled up on a screen
   wider than 1920px the way the public site is (marketing.css, "a very wide
   screen"): a tenth for every 192px, so a TV across the room can be read.
   The app a trader works in keeps its own size. */
@media (min-width: 2112px) {
  body.auth-shell {
    zoom: 1.1;
  }
}
@media (min-width: 2304px) {
  body.auth-shell {
    zoom: 1.2;
  }
}
@media (min-width: 2496px) {
  body.auth-shell {
    zoom: 1.3;
  }
}
@media (min-width: 2688px) {
  body.auth-shell {
    zoom: 1.4;
  }
}
@media (min-width: 2880px) {
  body.auth-shell {
    zoom: 1.5;
  }
}
@media (min-width: 3072px) {
  body.auth-shell {
    zoom: 1.6;
  }
}
@media (min-width: 3264px) {
  body.auth-shell {
    zoom: 1.7;
  }
}
@media (min-width: 3456px) {
  body.auth-shell {
    zoom: 1.8;
  }
}
@media (min-width: 3648px) {
  body.auth-shell {
    zoom: 1.9;
  }
}
@media (min-width: 3840px) {
  body.auth-shell {
    zoom: 2;
  }
}
@media (min-width: 4608px) {
  body.auth-shell {
    zoom: 2.4;
  }
}
@media (min-width: 5376px) {
  body.auth-shell {
    zoom: 2.8;
  }
}
a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.16em;
}
a:hover {
  color: var(--link-hover);
}
/* Anything already dressed as something else — a button, a card, a row in a
   list — keeps the colour it was given. This is for links in a sentence. */
a.btn,
a.btn-quiet,
a.btn-compact,
a.btn-big,
a.linklike,
a.chip,
a.rb-btn,
a.sr-link,
a.sr-new,
a.sr-brand,
a.qa-link,
a.mail-tab,
a.ib-row,
a.ib-folder,
a.quote-card,
a.help-card,
a.mail-ask,
a.word {
  color: inherit;
}
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* The bar a screen gets when it is too narrow for the rail beside it.
   It used to wrap: run out of room and whole items moved to a second row, then
   a third, until the top of the page was three lines of small grey words and
   the page itself started halfway down. The bar now keeps one line and lets
   the links slide sideways under a finger, divided into the same groups the
   rail uses — somebody who has learnt one has learnt the other. */
.topbar {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border-soft);
  background: var(--bg);
  position: sticky;
  top: 0;
  z-index: 10;
}
/* Only the phone has a drawer, so only the phone has anything to dim. */
.tb-scrim {
  display: none;
}
.tb-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  text-decoration: none;
  color: var(--text);
}
.tb-spacer {
  flex: 0 0 0;
}
.tb-links {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  gap: 0;
  overflow-x: auto;
  /* Sideways only. Naming a scroll on one axis turns the other from visible
     into auto, and a strip that can be dragged a few pixels up and down is a
     strip whose labels drift off-centre under the thumb meant to move it. */
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.tb-links::-webkit-scrollbar {
  display: none;
}
.tb-group {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  padding: 0 14px;
  /* The divider, and the reason the groups exist. Drawn on the left of each
     group but the first, so there is never a stray rule at either end. */
  border-left: 1px solid var(--border-soft);
}
.tb-grouphead {
  margin: 0;
}
.tb-menu {
  display: contents;
}
/* A tablet: each headed group in the strip is a heading that drops its
   links down when pressed, so the strip is five words rather than twenty.
   The menu is fixed to the window (the strip clips anything that hangs out
   of it) and placed under its heading by the drawer script. */
@media (min-width: 768px) and (max-width: 999px) {
  .tb-group > .tb-grouphead {
    padding: 8px 6px;
    font: 600 0.875rem var(--font);
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
    border-radius: 8px;
  }
  .tb-group > .tb-grouphead::after {
    content: ' ▾';
    font-size: 0.6875rem;
  }
  .tb-group > .tb-grouphead:hover,
  .tb-group.is-open > .tb-grouphead {
    background: var(--bg-raised);
    color: var(--text);
  }
  .tb-group > .tb-menu {
    display: none;
  }
  .tb-group.is-open > .tb-menu {
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: fixed;
    top: var(--tb-menu-top, 56px);
    left: var(--tb-menu-left, 12px);
    z-index: 60;
    min-width: 180px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--bg);
    box-shadow: 0 14px 36px rgb(0 0 0 / 0.22);
  }
  .tb-group.is-open > .tb-menu .linklike {
    padding: 10px 12px;
    border-radius: 8px;
    text-align: left;
  }
}
.tb-group:first-child {
  border-left: 0;
  padding-left: 0;
}
.tb-group:last-child {
  padding-right: 0;
}
.tb-group form {
  margin: 0;
  display: flex;
}
.topbar .mark {
  width: 28px;
  height: 28px;
  flex: none;
}
.topbar .word {
  font-weight: 800;
  font-size: 1.1875rem;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  flex: none;
}
.topbar .word b {
  color: var(--accent-text);
  font-weight: 800;
}
.topbar .tb-spacer {
  margin-left: 0;
}
.trial-chip {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--warn);
  background: var(--warn-bg);
  border-radius: 999px;
  padding: 4px 10px;
}
.topbar .trial-chip {
  white-space: nowrap;
  flex: none;
}
.topbar .linklike {
  white-space: nowrap;
  flex: none;
}
.topbar form {
  margin: 0;
}
.linklike {
  background: none;
  border: none;
  color: var(--text-muted);
  font: 600 0.875rem var(--font);
  cursor: pointer;
  padding: 8px;
}

.wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: 20px 16px 120px;
}
.wrap-narrow {
  max-width: 440px;
}
/* Something to read — the terms, the privacy notice, the fee schedule. A
   phone-width column on a desktop is a strip down the middle of a wide blank
   screen; a book-width column is what a long document wants. */
.wrap-read {
  max-width: 800px;
}
.wrap-read .policy-body,
.wrap-read .policy-md p,
.wrap-read .policy-body p {
  max-width: 72ch;
}
.wrap-read h1 {
  font-size: 1.875rem;
}
.hc-hint {
  margin: 4px 0 10px;
}
/* Pages that are a list or a table rather than something to read: they earn
   the width a wide screen has going spare, where a form does not. A text box
   1500px across is harder to use, not easier. */
.wrap-wide {
  max-width: 720px;
}

/* ---------- the shape of a wide screen ----------

   Below this width nothing changes: the bar across the top, the page in a
   column under it, exactly as a phone has always had it. At and above it the
   bar is replaced by a rail down the left — the same links, all visible at
   once — and the page gets the rest of the display instead of sitting in a
   720px column with the wallpaper either side of it.

   Both navigations are always in the markup and neither is built by script,
   so every destination is reachable at every width and with JavaScript off. */
.siderail {
  display: none;
}
@media (min-width: 1000px) {
  .shell {
    display: grid;
    grid-template-columns: 232px minmax(0, 1fr);
    align-items: start;
    min-height: 100vh;
  }
  .shell-main {
    min-width: 0;
  }
  .topbar {
    display: none;
  }
  .siderail {
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    padding: 14px 12px 16px;
    border-right: 1px solid var(--border-soft);
    background: var(--bg);
  }
  .sr-brand {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px 12px;
    text-decoration: none;
  }
  .sr-brand .mark {
    width: 26px;
    height: 26px;
    flex: none;
    color: var(--text);
  }
  .sr-word {
    font-weight: 800;
    font-size: 1.125rem;
    letter-spacing: -0.02em;
    color: var(--text);
    white-space: nowrap;
  }
  .sr-word b {
    color: var(--accent-text);
    font-weight: 800;
  }
  .sr-new {
    display: block;
    margin: 0 0 12px;
    padding: 9px 12px;
    border-radius: 8px;
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 700;
    font-size: 0.875rem;
    text-align: center;
    text-decoration: none;
  }
  .sr-new:hover {
    filter: brightness(1.06);
  }
  .sr-group {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px 0;
    border-top: 1px solid var(--border-soft);
  }
  .sr-group:first-of-type {
    border-top: 0;
    padding-top: 0;
  }
  .siderail .sr-link {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: none;
  }
  .siderail .sr-link:hover {
    background: var(--bg-raised);
    color: var(--text);
  }
  .siderail .sr-link[aria-current='page'] {
    background: var(--accent-tint);
    color: var(--link);
  }
  /* a group of pages behind one heading; the caret turns when it is open */
  .sr-fold {
    display: block;
  }
  .sr-fold > summary {
    list-style: none;
    cursor: pointer;
    user-select: none;
  }
  .sr-fold > summary::-webkit-details-marker {
    display: none;
  }
  .sr-caret {
    margin-left: auto;
    opacity: 0.7;
    transition: transform 0.15s ease;
  }
  .sr-fold[open] > summary .sr-caret {
    transform: rotate(180deg);
  }
  .sr-fold-body {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 2px 0 4px 16px;
  }
  .sr-fold-body .sr-link {
    padding: 6px 10px;
    font-size: 0.84375rem;
  }
  .sr-fold-body .sr-link .nav-ico {
    width: 16px;
    height: 16px;
  }
  .sr-spacer {
    flex: 1 1 auto;
    min-height: 12px;
  }
  /* The owner's own two, held at the foot and named, so they read as a place
     apart rather than as two more sections of the app everyone has. */
  .sr-mine {
    border-top: 1px solid var(--border-soft);
  }
  .sr-grouphead {
    margin: 2px 0 4px;
    padding: 0 10px;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
  .sr-trial {
    align-self: flex-start;
    margin: 0 10px 8px;
  }
  .sr-out {
    margin: 0;
    padding: 0 2px;
  }
  .sr-out .linklike {
    padding: 8px;
  }
  /* Something to read or fill in stays a comfortable column; a list or a
     table spreads out. Both are wider than they were, because the rail has
     taken the place of the empty margin rather than adding to it. */
  .wrap {
    max-width: 880px;
    padding: 28px 32px 120px;
  }
  .wrap-wide {
    max-width: 1500px;
  }
  .wrap-narrow {
    max-width: 440px;
  }
  /* The working pages — enquiries, tasks, projects, the team, HR, messages,
     the social posts — are lists of cards. On a phone they are a column; on
     a desktop they were the same column, 760 pixels of it, with the rest of
     the display blank either side. Now they take the width a list wants, and
     the cards on them sit in a grid rather than a single tall stack. */
  .wrap.wrap-site {
    max-width: 1280px;
  }
  .wrap-site .enq-cards,
  .wrap-site .site-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 12px;
    align-items: start;
  }
  .wrap-site .enq-cards > .enq-card {
    margin-bottom: 0;
  }
  /* Choosing a package: the three packages across the page, the way to pay
     and the code beside each other, and the add-ons three abreast. */
  .wrap-billing {
    max-width: 1100px;
  }
  .wrap-billing .bill-choose {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 14px 24px;
    align-items: start;
  }
  .wrap-billing .bill-choose > .pkg-grid,
  .wrap-billing .bill-choose > .bill-founding,
  .wrap-billing .bill-choose > .bill-note {
    grid-column: 1 / -1;
  }
  .wrap-billing .bill-choose > .bill-note {
    margin-top: 0;
  }
  .wrap-billing .code-box {
    margin-top: 0;
  }
  .wrap-billing .addon-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    align-items: stretch;
  }
  .wrap-billing .addon-grid > .addon-card {
    margin-bottom: 0;
    height: 100%;
    box-sizing: border-box;
  }
  /* Once the rail has taken the phone-width margin, a page keeps its
     bottom padding for the tab bar it no longer has: less of it here. */
  .shell-main > .page-main > .wrap {
    padding-top: 40px;
    padding-bottom: 56px;
  }
  /* The width on a list page is for the list. A search box or a picker
     stretched to fifteen hundred pixels is not easier to use, it is a stripe
     across the screen with three words in it, so the controls keep a size a
     control should be. */
  .wrap-wide input,
  .wrap-wide select {
    max-width: 520px;
  }
  .wrap-wide textarea {
    max-width: 900px;
  }
  /* Same reasoning for the button at the foot of a page: full width is right
     under a thumb and absurd under a mouse, so it takes its natural size and
     sits at the end of the line where a "next" belongs. */
  .actionbar {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
  }
  .actionbar .btn,
  .actionbar .btn-quiet,
  .actionbar .btn-secondary {
    width: auto;
    min-width: 180px;
    padding-left: 28px;
    padding-right: 28px;
    white-space: nowrap;
  }
  /* A field takes the size of what goes in it. Full width is right on a phone,
     where full width is a thumb's reach; a name box eight hundred pixels
     across is a stripe with a word in it and makes a form harder to read, not
     easier. Fields that are a column of something wider — a line item's
     description, a table cell, anything a grid has already sized — say so
     below and keep their column. */
  .shell-main .wrap input[type='text'],
  .shell-main .wrap input[type='email'],
  .shell-main .wrap input[type='tel'],
  .shell-main .wrap input[type='url'],
  .shell-main .wrap input[type='number'],
  .shell-main .wrap input[type='search'],
  .shell-main .wrap input[type='date'],
  .shell-main .wrap select {
    max-width: 560px;
  }
  /* Matched through .wrap as well, so these weigh the same as the rule above
     and win by coming after it rather than by accident. */
  .shell-main .wrap .item-row input,
  .shell-main .wrap .desc-cell input,
  .shell-main .wrap table input,
  .shell-main .wrap table select,
  .shell-main .wrap .two-up input,
  .shell-main .wrap .two-up select,
  .shell-main .wrap .field-pair input,
  .shell-main .wrap .field-pair select {
    max-width: none;
  }
  /* Two buttons at the foot of a form sit side by side once there is room:
     stacked is a phone's answer to a narrow screen. */
  .actionbar .btn-row {
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    margin-top: 0;
  }
  /* Admin brings its own list of sections and its own column. It was capped
     at a width that suited a page with a bar across the top; with the rail
     taking the place of that bar there is more to work with, and the tables
     in there are the widest thing in the app. */
  /* Named through the shell so it outranks the plain .admin rule, which is
     further down the stylesheet than this block and would otherwise win. */
  .shell-main .admin {
    max-width: 1800px;
    padding-left: var(--qa-pad);
    padding-right: var(--qa-pad);
  }
}
h1 {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 8px 0 16px;
}
h2 {
  font-size: 1.125rem;
  font-weight: 700;
  margin: 24px 0 8px;
}
p {
  max-width: 66ch;
}
.muted {
  color: var(--text-muted);
}
.small {
  font-size: 0.875rem;
}
.mono {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.85em;
  word-break: break-all;
}

/* Forms */
label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  margin: 16px 0 6px;
}
input[type='text'],
input[type='email'],
input[type='password'],
input[type='tel'],
input[type='number'],
input[type='search'],
input[type='url'],
input[type='date'],
input[type='datetime-local'],
input[type='time'],
input[type='month'],
textarea,
select {
  width: 100%;
  font: 400 1.0625rem var(--font);
  color: var(--text);
  background: var(--bg);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
  min-height: 48px;
}
textarea {
  min-height: 88px;
  resize: vertical;
}
input:focus,
textarea:focus,
select:focus {
  border-color: var(--focus);
  outline: none;
}
/* A dropdown draws its own arrow, in the browser's grey, at whatever size the
   platform likes — three different shapes across three machines. This is the
   app's own, in the app's colour, in the same place every time. */
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: var(--chevron);
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 18px 18px;
  padding-right: 42px;
}
/* The list a dropdown opens takes its colours from the options, not from the
   page. Left unsaid it opens white against the navy, whatever the theme. */
option {
  background: var(--bg-raised);
  color: var(--text);
}

/* Tick boxes and radios, drawn rather than left to the operating system.
   The browser's own are a white square with a blue tick — the one thing on
   the screen that belongs to Windows rather than to this app, and on a navy
   background they read as holes punched in the page. */
input[type='checkbox'],
input[type='radio'] {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  display: inline-grid;
  place-content: center;
  width: 20px;
  height: 20px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 1.5px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  cursor: pointer;
  vertical-align: -4px;
  transition:
    background-color 0.12s,
    border-color 0.12s;
}
input[type='radio'] {
  border-radius: 50%;
}
input[type='checkbox']:hover,
input[type='radio']:hover {
  border-color: var(--text-faint);
}
input[type='checkbox']:checked,
input[type='radio']:checked,
input[type='checkbox']:indeterminate {
  background: var(--accent);
  border-color: var(--accent);
}
/* The tick is drawn from two borders rather than fetched as a picture, so it
   takes the ink colour the theme sets for anything sitting on accent green. */
input[type='checkbox']:checked::after {
  content: '';
  width: 5px;
  height: 9px;
  margin-top: -2px;
  border: solid var(--on-accent);
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg);
}
/* Some, but not all — the bar above a list of messages says so with a dash. */
input[type='checkbox']:indeterminate::after {
  content: '';
  width: 10px;
  height: 2.5px;
  border-radius: 2px;
  background: var(--on-accent);
}
input[type='radio']:checked::after {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--on-accent);
}
input[type='checkbox']:focus-visible,
input[type='radio']:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
input[type='checkbox']:disabled,
input[type='radio']:disabled {
  opacity: 0.55;
  cursor: default;
}

/* A date box draws its own calendar button, and the browser colours it to
   match what the page has said it is — which the theme sets on the root. All
   that was missing was the box around it: without a rule of its own it kept
   the browser's grey slab in the middle of a navy form. */
input[type='date']::-webkit-calendar-picker-indicator,
input[type='datetime-local']::-webkit-calendar-picker-indicator,
input[type='time']::-webkit-calendar-picker-indicator,
input[type='month']::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.75;
}
input[type='date']::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}
input[type='date']::-webkit-datetime-edit-fields-wrapper,
input[type='datetime-local']::-webkit-datetime-edit-fields-wrapper,
input[type='time']::-webkit-datetime-edit-fields-wrapper,
input[type='month']::-webkit-datetime-edit-fields-wrapper {
  padding: 0;
}

/* Choosing a file. The button inside this control is the operating system's,
   and on Windows it is a small grey slab with a hairline — the giveaway that
   a page was never dressed. It is a control like any other here. */
input[type='file'] {
  width: 100%;
  min-height: 48px;
  padding: 9px 12px;
  border: 1.5px dashed var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text-muted);
  font: 400 0.9375rem var(--font);
  cursor: pointer;
}
input[type='file']:hover {
  border-color: var(--text-faint);
}
input[type='file']::file-selector-button,
input[type='file']::-webkit-file-upload-button {
  margin: 0 12px 0 0;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-raised);
  color: var(--text);
  font: 600 0.875rem var(--font);
  cursor: pointer;
}
input[type='file']::file-selector-button:hover,
input[type='file']::-webkit-file-upload-button:hover {
  background: var(--bg-inset);
  border-color: var(--text-faint);
}

.check-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 16px 0;
  font-size: 0.9375rem;
}
.check-row input {
  width: 22px;
  height: 22px;
  margin-top: 2px;
}

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 56px;
  background: var(--accent);
  color: var(--on-accent);
  font: 600 1.0625rem var(--font);
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
}
.btn:active {
  background: var(--accent-strong);
}
/*
 * A disabled button has to stop looking like a button you can press.
 *
 * Dimming a saturated green with opacity is not enough on a dark background:
 * it stays green, stays the brightest thing in its column, and reads as the
 * main action while doing nothing when tapped. So the colour goes entirely and
 * what is left is plainly inert.
 */
.btn[disabled],
.btn-big:disabled,
.bc-send .btn-big:disabled {
  background: var(--bg-inset);
  color: var(--text-faint);
  border: 1px solid var(--border-soft);
  cursor: not-allowed;
  opacity: 1;
}
.btn-quiet {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  background: transparent;
  color: var(--text);
  font: 600 0.9375rem var(--font);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
}
.btn-danger-quiet {
  color: var(--danger);
  border-color: var(--danger);
}
.btn-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 20px;
}
/* The quotes page's head row: the search on the left, and on a wide screen
   the one button the page is for on the right of it — above the list rather
   than under it, which is where somebody looks for it when the list is long
   enough to scroll.

   The button is drawn here and again at the foot of the page, and exactly one
   of the two is ever displayed. display:none rather than visibility or a
   clipping trick, because it takes the hidden one out of the accessibility
   tree as well: a screen reader finds one New quote link, not two. */
.q-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.q-search {
  flex: 1 1 auto;
  margin: 0;
}
@media (min-width: 1000px) {
  /* The search form must not stretch.
     Its input is capped at 560px by the field rule above, so a form set to
     grow leaves several hundred pixels of invisible stretched form between
     the box a person can see and the button — which is why New quote sat out
     at the far edge of a wide screen. Hugging its input puts the two
     together, wherever the window ends. */
  .q-search {
    flex: 0 1 auto;
  }
  .q-search input {
    width: 560px;
    max-width: 100%;
  }
}

/* The bar at the foot of a page, and the room it leaves for Nod.
   The chat button is fixed to the bottom-right corner, and this bar sticks to
   the bottom of the page — so on a phone, where the button inside it runs the
   full width, the two ended up on top of each other. 58px of button, 18px
   from the edge, and a gap: the bar stops short of it. */
.actionbar {
  position: sticky;
  bottom: 0;
  background: linear-gradient(transparent, var(--bg) 30%);
  padding: 20px 0 max(16px, env(safe-area-inset-bottom));
  margin-top: 24px;
}
/* Two buttons in the foot bar on a phone: the quote takes the room, the
   enquiry sits beside it at its own width. */
.q-foot {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.q-foot .btn:first-child {
  flex: 1;
}
.q-foot .btn-quiet {
  flex: 0 0 auto;
  width: auto;
  min-width: 0;
  white-space: nowrap;
  margin: 0;
}
/* Below a thousand pixels the button in this bar runs the full width, so
   taking 84px off one end alone never moved it out from under the chat
   button — it only stopped the button being centred, leaving a thumb's worth
   of dead space down the right-hand side. The bar keeps its full width here
   and stands off the corner instead: 58px of button, 18px from the edge, and
   a gap above it. */
body:has(.qn-fab) .actionbar {
  padding-bottom: calc(88px + env(safe-area-inset-bottom, 0px));
}
@media (min-width: 1000px) {
  /* Wide enough that the button takes its natural size at the right-hand end
     of the line, which is exactly where the chat button sits. Here the room
     does have to come off the side. */
  body:has(.qn-fab) .actionbar {
    padding-right: 84px;
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }
}

/* A reason under the box it is about, rather than one line at the top of a
   long form. Reserves no room when empty: it is hidden, so a form with
   nothing wrong with it is laid out exactly as it was. */
.field-err {
  margin: 4px 0 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--danger);
}
.field-err[hidden] {
  display: none;
}
input[aria-invalid='true'],
input[aria-invalid='true']:focus {
  border-color: var(--danger);
}

.flash-error {
  background: var(--danger-bg);
  color: var(--danger);
  border-radius: var(--radius);
  padding: 12px 16px;
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 0 0 16px;
}
/* Not a failure — something the app decided to stop doing on purpose. */
.flash-warn {
  background: var(--warn-bg);
  color: var(--warn);
  border-radius: var(--radius);
  padding: 12px 16px;
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 0 0 16px;
}
/* The beta's ending line: a phone shows its first two sentences only. */
@media (max-width: 599px) {
  .flash-warn .beta-more {
    display: none;
  }
}
.flash-ok {
  background: var(--ok-bg);
  color: var(--ok);
  border-radius: var(--radius);
  padding: 12px 16px;
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 0 0 16px;
}

/* Dashboard */
.filters {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 4px 0 12px;
  -webkit-overflow-scrolling: touch;
  /* branded slim scrollbar (Firefox) */
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}
/* branded slim scrollbar (Chrome/Edge/Safari) */
.filters::-webkit-scrollbar {
  height: 5px;
}
.filters::-webkit-scrollbar-track {
  background: var(--border-soft);
  border-radius: 999px;
}
.filters::-webkit-scrollbar-thumb {
  background: var(--accent);
  border-radius: 999px;
}
.filters::-webkit-scrollbar-thumb:hover {
  background: var(--accent-strong);
}
.filters a {
  flex: none;
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--text-muted);
  background: var(--bg-inset);
  padding: 8px 14px;
  border-radius: 999px;
}
.filters a.active {
  background: var(--navy-800);
  color: #fff;
}
.filters-gap {
  flex: 1 1 auto;
}
.filters-dl-form {
  flex: none;
  margin: 0;
}
.filters .filters-dl {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: 600 0.875rem var(--font);
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--accent);
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
}
.filters .filters-dl svg {
  color: var(--accent);
}
.filters .filters-dl:hover,
.filters .filters-dl:focus-visible {
  background: var(--accent);
  color: var(--on-accent);
}
.filters .filters-dl:hover svg,
.filters .filters-dl:focus-visible svg {
  color: var(--on-accent);
}
.quote-card {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 14px 16px 14px 20px;
  margin-bottom: 10px;
  overflow: hidden;
  text-decoration: none;
  color: var(--text);
  background: var(--bg);
  box-shadow: var(--shadow-1);
}
.quote-card .who {
  min-width: 0;
}
.quote-card .who b {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.quote-card .who span {
  font-size: 0.8125rem;
  color: var(--text-faint);
}
.quote-card .amt {
  margin-left: auto;
  text-align: right;
  flex: none;
}
.quote-card .amt b {
  font-size: 1.125rem;
  font-variant-numeric: tabular-nums;
}
.chip {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--bg-inset);
  color: var(--text-muted);
}
.chip.ok {
  background: var(--ok-bg);
  color: var(--ok);
}
.chip.warn {
  background: var(--warn-bg);
  color: var(--warn);
}
.chip.danger {
  background: var(--danger-bg);
  color: var(--danger);
}
.empty {
  color: var(--text-muted);
  padding: 40px 4px;
  text-align: center;
}
.empty p {
  margin-left: auto;
  margin-right: auto;
}

/* Builder */
.item-row {
  display: grid;
  grid-template-columns: 1fr 72px 96px 32px;
  gap: 8px;
  align-items: start;
  margin-bottom: 8px;
}
.item-row input {
  min-height: 48px;
  padding: 10px 10px;
}
/* As tall as the boxes beside it at any text size: a line of their text,
   which is 1.3rem in this typeface, and their 26px of padding and border. */
.item-row .rm {
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 1.375rem;
  cursor: pointer;
  min-height: max(48px, calc(1.3rem + 26px));
}
/* What the star does, said once above the rows rather than left to be worked
   out from a tooltip that a phone never shows. */
.li-key {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin: -2px 0 10px;
}
.li-key-star {
  color: var(--accent-text);
  font-size: 0.9375rem;
  line-height: 1;
}

/* A field with its unit inside it: "25" and "%" in the same box, because the
   number alone means two different things. */
.unit-field {
  position: relative;
  display: block;
  min-width: 0;
}
.unit-field input {
  width: 100%;
  padding-right: 30px;
}
/* The stepper arrows go: they sit exactly where the unit does, and nobody
   nudges a deposit up by one hundredth of a percent at a time. The field is
   still type=number, so a phone still offers the number keypad. */
.unit-field input::-webkit-outer-spin-button,
.unit-field input::-webkit-inner-spin-button {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
}
.unit-field input[type='number'] {
  -moz-appearance: textfield;
  appearance: textfield;
}
.unit-mark {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  font-weight: 600;
  pointer-events: none;
}
.unit-mark:empty {
  display: none;
}

/* The description box carries its own save-for-next-time star, inside the
   field rather than in a fifth column: on a phone the row has no width to
   spare, and the star belongs to the words it keeps. */
.desc-cell {
  position: relative;
  display: block;
  min-width: 0;
}
.desc-cell input {
  width: 100%;
  padding-right: 40px;
}
.item-star {
  position: absolute;
  right: 2px;
  top: 24px;
  transform: translateY(-50%);
  background: none;
  border: 0;
  padding: 6px 8px;
  font-size: 1.125rem;
  line-height: 1;
  color: var(--text-faint);
  cursor: pointer;
}
.item-star.is-on {
  color: var(--accent-strong);
}
.item-star:focus-visible {
  outline: 2px solid var(--focus);
  border-radius: 6px;
}
/* Suggestions. Placed on the page rather than in the row so the grid never
   has to make room for them, and so they sit above the line below. */
.sug {
  position: absolute;
  z-index: 60;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px rgb(11 22 38 / 0.18);
  max-height: 262px;
  overflow-y: auto;
  padding: 4px;
  margin: 0;
  list-style: none;
}
.sug-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 10px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9375rem;
}
.sug-row.is-on,
.sug-row:hover {
  background: var(--bg-inset);
}
.sug-desc {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sug-price {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.sug-kept {
  color: var(--accent-strong);
}
/* Saved items in Settings: description takes the room, numbers stay narrow. */
.saved-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.saved-row form:first-child {
  display: grid;
  grid-template-columns: 1fr 64px 86px 86px 92px auto;
  gap: 6px;
  align-items: center;
  flex: 1;
  min-width: 0;
}
.saved-head {
  display: grid;
  grid-template-columns: 1fr 64px 86px 86px 92px auto;
  gap: 6px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 96px 4px 0;
}
.saved-margin {
  grid-column: 1 / -1;
  min-height: 0;
}
.saved-margin:empty {
  display: none;
}
@media (max-width: 700px) {
  .saved-row form:first-child,
  .saved-head {
    grid-template-columns: 1fr 1fr 1fr;
  }
  .saved-head {
    display: none;
  }
  .saved-row form:first-child input[name='description'] {
    grid-column: 1 / -1;
  }
}
.saved-row input {
  min-height: 44px;
  padding: 8px;
}
.saved-del {
  color: var(--danger);
}
.builder-head {
  display: grid;
  grid-template-columns: 1fr 72px 96px 32px;
  gap: 8px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 6px;
}
/* On a phone a line is stacked: the description across the whole width, then
   quantity, price and the × beneath, each box under its own small heading. */
@media (max-width: 480px) {
  .builder-head span:not(:first-child) {
    display: none;
  }
  .item-row {
    grid-template-columns: 1fr 1fr 32px;
    margin-bottom: 16px;
  }
  .item-row .desc-cell {
    grid-area: 1 / 1 / auto / -1;
  }
  .item-row::before,
  .item-row::after {
    grid-row: 2;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
  .item-row::before {
    content: 'Qty';
    grid-column: 1;
  }
  .item-row::after {
    content: 'Price £';
    grid-column: 2 / -1;
  }
  .item-row > input[name='item_qty[]'] {
    grid-area: 3 / 1;
  }
  .item-row > input[name='item_price[]'] {
    grid-area: 3 / 2;
  }
  .item-row .rm {
    grid-area: 3 / 3;
  }
  .item-short {
    grid-row: 4;
  }
}
.totals {
  border-top: 1px solid var(--border-soft);
  margin-top: 16px;
  padding-top: 12px;
  font-variant-numeric: tabular-nums;
}
.totals .row {
  display: flex;
  justify-content: space-between;
  padding: 3px 0;
  font-size: 0.9375rem;
  color: var(--text-muted);
}
.totals .grand {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.totals .grand b {
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* Approval page */
.approval-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px;
}
.approval-brand .biz {
  font-weight: 700;
  font-size: 1.0625rem;
}
.approval-brand .via {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--text-faint);
}
.quote-doc {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 20px;
  box-shadow: var(--shadow-1);
}
.quote-doc .qhead {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.qitems {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
.qitems td {
  padding: 9px 0;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: top;
}
.qitems td:last-child {
  text-align: right;
  white-space: nowrap;
}
.qitems .qty {
  color: var(--text-faint);
  font-size: 0.875rem;
}
.qtotals {
  margin-top: 10px;
  font-variant-numeric: tabular-nums;
}
.qtotals .row {
  display: flex;
  justify-content: space-between;
  font-size: 0.9375rem;
  color: var(--text-muted);
  padding: 2px 0;
}
.qtotals .grand {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  column-gap: 12px;
  margin-top: 6px;
}
.qtotals .grand b {
  margin-left: auto;
  font-size: 2.125rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.qterms {
  font-size: 0.8125rem;
  color: var(--text-muted);
  border-top: 1px solid var(--border-soft);
  margin-top: 14px;
  padding-top: 12px;
  white-space: pre-wrap;
}

.sigpad-wrap {
  margin-top: 8px;
}
.sigpad {
  width: 100%;
  height: 190px;
  border: 1.5px dashed var(--border);
  border-radius: var(--radius);
  background: #fffdf5;
  touch-action: none;
  display: block;
}
.sigpad.signed {
  border-style: solid;
  border-color: var(--accent);
}
.sig-tools {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 6px;
}
.sig-hint {
  font-size: 0.8125rem;
  color: var(--text-faint);
}

.confirm-hero {
  text-align: center;
  padding: 40px 16px 16px;
}
.confirm-hero .tickring {
  width: 96px;
  height: 96px;
  margin: 0 auto 16px;
}
.confirm-hero h1 {
  font-size: 1.625rem;
}
@media (prefers-reduced-motion: no-preference) {
  .tickring .draw {
    stroke-dasharray: 60;
    stroke-dashoffset: 60;
    animation: qn-draw 0.45s ease-out 0.15s forwards;
  }
  @keyframes qn-draw {
    to {
      stroke-dashoffset: 0;
    }
  }
}

/* Detail page */
.share-box {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 16px;
  margin: 16px 0;
}
.share-box .link {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 0.8125rem;
  word-break: break-all;
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 10px;
  margin: 10px 0;
}
.timeline {
  list-style: none;
  padding: 0;
  margin: 12px 0;
}
.timeline li {
  display: flex;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-soft);
  font-size: 0.9375rem;
}
.timeline .when {
  color: var(--text-faint);
  font-size: 0.8125rem;
  flex: none;
  width: 130px;
}
.doc-list {
  list-style: none;
  padding: 0;
}
.doc-list li {
  margin: 8px 0;
}
.sig-preview {
  background: #fffdf5;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 8px;
  max-width: 320px;
}
.sig-preview img {
  max-width: 100%;
  display: block;
}
.integrity-ok {
  color: var(--ok);
  font-weight: 600;
  font-size: 0.875rem;
}
.integrity-bad {
  color: var(--danger);
  font-weight: 700;
  font-size: 0.875rem;
}

/* The deletion page is written as markup rather than run through mdLite, so it
   must not inherit the pre-wrap the policy documents need — that rule is what
   turns a template literal's own indentation into visible ragged text. */
.dd-body {
  font-size: 0.9375rem;
  line-height: 1.6;
  max-width: 68ch;
}
.dd-body h2 {
  font-size: 1.0625rem;
  margin: 22px 0 6px;
}
.dd-body p {
  margin: 0 0 12px;
}

.policy-body {
  white-space: pre-wrap;
  font-size: 0.9375rem;
  line-height: 1.6;
  max-width: 68ch;
}
footer.legal {
  margin-top: 48px;
  padding-top: 16px;
  border-top: 1px solid var(--border-soft);
  font-size: 0.8125rem;
  color: var(--text-faint);
}
footer.legal a {
  color: var(--text-faint);
}

.deposit-strip {
  margin-top: 12px;
  background: var(--accent-tint);
  color: var(--text);
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}
.deposit-strip .muted {
  display: block;
  font-size: 0.8125rem;
}
.contract-box {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin-top: 16px;
}
.contract-box summary {
  cursor: pointer;
  font-weight: 700;
  font-size: 0.9375rem;
}

.contract-h {
  font-size: 0.875rem;
  font-weight: 700;
  margin: 14px 0 0;
}

.policy-md h2 {
  font-size: 1.125rem;
  margin: 20px 0 6px;
}
.policy-md h3 {
  font-size: 0.9375rem;
  margin: 16px 0 4px;
}
.policy-md p {
  margin: 8px 0;
  max-width: 68ch;
}

.pay-choice {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 16px 14px;
  margin: 20px 0 4px;
}
.pay-choice legend {
  font-size: 0.875rem;
  font-weight: 700;
  padding: 0 6px;
}
.pay-option {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 10px 8px;
  margin: 4px 0;
  border-radius: var(--radius);
  cursor: pointer;
  font-weight: 400;
  font-size: 0.9375rem;
}
.pay-option:has(input:checked) {
  background: var(--accent-tint);
}
.pay-option input {
  width: 22px;
  height: 22px;
  margin-top: 2px;
  flex: none;
}

/* in-app tour */
.tour-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  /* The dimming is a BACKGROUND, not a spread shadow: an outer box-shadow is
     never painted inside its own box, and this box is the whole viewport — so
     the old `box-shadow: 0 0 0 9999px` painted nothing at all and the
     spotlight lit nothing. The clip-path below cuts the hole.
     Black rather than the navy it used to name: the navy was the dark theme's
     own page colour, so even once it was painted it changed nothing there. */
  background: rgb(0 0 0 / 0.6);
  clip-path: polygon(
    0 0,
    100% 0,
    100% 100%,
    0 100%,
    0 0,
    var(--hx) var(--hy),
    var(--hx) calc(var(--hy) + var(--hh)),
    calc(var(--hx) + var(--hw)) calc(var(--hy) + var(--hh)),
    calc(var(--hx) + var(--hw)) var(--hy),
    var(--hx) var(--hy)
  );
}
.tour-bubble {
  position: fixed;
  left: 16px;
  right: 16px;
  max-width: 420px;
  margin: 0 auto;
  z-index: 95;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  box-shadow: 0 8px 32px rgb(11 22 38 / 0.35);
}
.tour-bubble b {
  font-size: 1rem;
}
.tour-bubble p {
  margin: 6px 0 12px;
  font-size: 0.9375rem;
  color: var(--text-muted);
}
.tour-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.tour-skip {
  background: none;
  border: none;
  color: var(--text-faint);
  font: 600 0.875rem var(--font);
  cursor: pointer;
  padding: 10px;
}
.tour-next {
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: var(--radius);
  font: 600 0.9375rem var(--font);
  padding: 10px 22px;
  min-height: 44px;
  cursor: pointer;
}

/* The phone: the logo opens the navigation, the same way the mail app does.
   Eleven links across the top of a phone were two rows of eight-point grey
   before the page began, and sliding them sideways only moves the problem —
   what is off the side of a strip is as hidden as what is behind a door, and
   a door at least says it is a door. So below this the links are a panel that
   slides in over the page, and the mark and wordmark are what opens it. */
@media (max-width: 767px) {
  .topbar {
    gap: 8px;
    padding: 10px 12px;
  }
  .topbar .word {
    font-size: 1.125rem;
  }
  .tb-spacer {
    flex: 1 1 auto;
  }
  .topbar .trial-chip {
    font-size: 0.75rem;
    padding: 3px 8px;
    /* Out of the way of the chat button, which sits in this corner here. */
    margin-right: 46px;
    flex: 0 1 auto;
    min-width: 0;
    white-space: normal;
    text-wrap: balance;
    text-align: center;
    line-height: 1.25;
  }
  .tb-links {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: min(84vw, 320px);
    z-index: 70;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 64px 12px calc(20px + env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--bg) 96%, #000);
    border-right: 1px solid var(--border-soft);
    box-shadow: 0 0 60px rgba(0, 0, 0, 0.5);
    transform: translateX(-105%);
    transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
  }
  .topbar.is-open .tb-links {
    transform: none;
  }
  .tb-group {
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 10px 0;
    border-left: 0;
    /* Groups still read as groups; the line between them simply turns with
       them, because a vertical rule down a vertical list divides nothing. */
    border-top: 1px solid var(--border-soft);
  }
  .tb-group:first-child {
    border-top: 0;
    padding-top: 0;
  }
  .tb-group .linklike {
    text-align: left;
    padding: 12px 10px;
    font-size: 1rem;
    border-radius: 8px;
    width: 100%;
  }
  .tb-grouphead {
    margin: 2px 0 2px;
    padding: 0 10px;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-faint);
  }
  .tb-menu {
    display: contents;
  }
  .tb-group .linklike:hover {
    background: var(--bg-raised);
  }
  .tb-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 65;
    background: rgba(0, 0, 0, 0.55);
  }
  .tb-scrim[hidden] {
    display: none;
  }
}
/* The narrowest phones. The links used to be shrunk to twelve point here to
   fit eleven of them across the top; they are in a drawer now, where they have
   a whole screen and shrinking them would only make them harder to hit. All
   that is left to do is take a little air out of the header itself. */
@media (max-width: 360px) {
  .topbar {
    gap: 6px;
    padding: 10px 10px;
  }
  .topbar .word {
    font-size: 1.0625rem;
  }
}

/* customer-view preview banner */
.preview-banner {
  background: var(--warn-bg);
  color: var(--warn);
  font-size: 0.8125rem;
  font-weight: 600;
  padding: 10px 16px;
  text-align: center;
  position: sticky;
  top: 0;
  z-index: 20;
}

/* ---- add-to-home-screen card (first sign-in on a phone/tablet browser) ---- */
.install-card {
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  padding: 16px;
  margin: 12px 0 16px;
  background: var(--bg-raised);
}
.install-card > b {
  font-size: 1.0625rem;
}
.install-card .ic-sub {
  color: var(--text-muted);
  font-size: 0.875rem;
  margin: 4px 0 14px;
}
.ic-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.ic-label {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  text-align: center;
  margin-bottom: 6px;
}
.ic-step {
  font-size: 0.78125rem;
  color: var(--text-muted);
  text-align: center;
  margin: 8px 0 0;
}
.ins-phone {
  position: relative;
  height: 172px;
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  background: var(--bg);
  overflow: hidden;
  margin: 0 auto;
  max-width: 150px;
}
.ip-bar {
  position: absolute;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 8px;
  background: var(--bg-inset);
  font-size: 0.625rem;
  color: var(--text-faint);
}
.ins-phone.and .ip-bar {
  top: 0;
}
.ins-phone.ios .ip-bar {
  bottom: 0;
  justify-content: center;
}
.ip-dots,
.ip-share {
  position: relative;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--text);
  line-height: 1;
}
.ip-tap {
  position: absolute;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  right: 2px;
  top: -6px;
  opacity: 0;
  animation: ipTap 5.5s infinite;
}
.ins-phone.ios .ip-tap {
  right: auto;
  left: 50%;
  margin-left: -13px;
  top: auto;
  bottom: -1px;
}
@keyframes ipTap {
  0%,
  8% {
    opacity: 0;
    transform: scale(0.4);
  }
  14% {
    opacity: 1;
    transform: scale(0.8);
  }
  22% {
    opacity: 0;
    transform: scale(1.25);
  }
  100% {
    opacity: 0;
  }
}
.ip-menu,
.ip-sheet {
  position: absolute;
  left: 8px;
  right: 8px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 9px;
  padding: 6px;
  opacity: 0;
  box-shadow: 0 6px 18px rgb(11 22 38 / 0.18);
}
.ip-menu {
  top: 30px;
  transform: translateY(-8px);
  animation: ipMenu 5.5s infinite;
}
.ip-sheet {
  bottom: 30px;
  transform: translateY(12px);
  animation: ipMenu 5.5s infinite;
}
@keyframes ipMenu {
  0%,
  20% {
    opacity: 0;
  }
  28%,
  72% {
    opacity: 1;
    transform: none;
  }
  80%,
  100% {
    opacity: 0;
  }
}
.ip-row {
  height: 9px;
  border-radius: 5px;
  background: var(--bg-inset);
  margin: 5px 2px;
}
.ip-row.hl {
  height: auto;
  background: var(--accent-tint);
  color: var(--text);
  font-size: 0.59375rem;
  font-weight: 700;
  padding: 4px 6px;
  animation: ipHl 5.5s infinite;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .ip-row.hl {
    background: rgb(23 201 111 / 0.18);
  }
}
@keyframes ipHl {
  0%,
  34% {
    box-shadow: none;
  }
  42%,
  62% {
    box-shadow: 0 0 0 2px var(--accent);
  }
  70%,
  100% {
    box-shadow: none;
  }
}
.ip-home {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 30px;
  display: grid;
  place-items: center;
}
.ins-phone.ios .ip-home {
  top: 0;
  bottom: 30px;
}
.ip-icon {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--navy-800);
  color: var(--accent-text);
  display: grid;
  place-items: center;
  font-size: 1.0625rem;
  font-weight: 800;
  transform: scale(0);
  animation: ipIcon 5.5s infinite;
}
@keyframes ipIcon {
  0%,
  74% {
    transform: scale(0);
  }
  82% {
    transform: scale(1.15);
  }
  88%,
  96% {
    transform: scale(1);
  }
  100% {
    transform: scale(0);
  }
}
.install-card .btn-quiet {
  margin-top: 12px;
}
/* never show inside the installed app */
@media (display-mode: standalone) {
  .install-card {
    display: none !important;
  }
}
@media (prefers-reduced-motion: reduce) {
  .install-card * {
    animation: none !important;
  }
  .ip-menu,
  .ip-sheet {
    opacity: 1;
    transform: none;
  }
  .ip-icon {
    transform: scale(1);
  }
  .ip-tap {
    display: none;
  }
}

/* ---- one-time cookies/policies notice ---- */
.cookie-bar {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--navy-800);
  color: #edf2f7;
  border-radius: 14px;
  padding: 12px 14px;
  box-shadow: 0 10px 34px rgb(11 22 38 / 0.35);
  max-width: 680px;
  margin: 0 auto;
}
.cookie-bar p {
  margin: 0;
  font-size: 0.84375rem;
  line-height: 1.45;
}
.cookie-bar a {
  color: var(--accent);
  text-decoration: underline;
}
.cookie-bar button {
  flex: none;
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: 9px;
  font: 700 0.875rem var(--font);
  padding: 10px 18px;
  cursor: pointer;
}

/* ---- feedback / support desk ---- */
.fb-card {
  border: 1.5px solid var(--border-soft);
  border-radius: 12px;
  padding: 14px;
  margin: 12px 0;
  background: var(--bg-raised);
}
.fb-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.fb-reply {
  border-left: 3px solid var(--accent);
  background: var(--bg);
  border-radius: 0 8px 8px 0;
  padding: 8px 12px;
  margin-top: 10px;
}
.filters a.active-filter {
  background: var(--navy-800);
  color: #fff;
}

/* ---- setup wizard ---- */
.wiz-progress {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 20px 0 4px;
}
.wiz-dot {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 0.875rem;
  font-weight: 700;
  background: var(--bg-inset);
  color: var(--text-faint);
  border: 2px solid var(--border-soft);
}
.wiz-dot.now {
  background: var(--navy-800);
  color: #fff;
  border-color: var(--navy-800);
}
.wiz-dot.done {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}

/* ---- help centre: animated numbered demos ---- */
/* Every demo is 3 rows on one shared 6s loop: the cursor visits row 1, 2, 3;
   each row's number pops and its content activates in the same window. */
.demo {
  position: relative;
  background: var(--bg);
  border: 2px solid #fff;
  box-shadow:
    0 0 0 1.5px var(--border),
    var(--shadow-1);
  border-radius: 14px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden;
  margin: 14px 0 20px;
  max-width: 430px;
}
.demo-row > div {
  position: relative;
}
.demo-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-raised);
  border: 1.5px solid var(--border-soft);
  border-radius: 10px;
  padding: 10px 12px;
  min-height: 54px;
  font-size: 0.84375rem;
}
.demo-row .demo-num {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 800;
  font-size: 0.75rem;
  display: grid;
  place-items: center;
  flex: none;
  transform: scale(0);
}
.demo .r1 .demo-num {
  animation: dPop1 6s infinite;
}
.demo .r2 .demo-num {
  animation: dPop2 6s infinite;
}
.demo .r3 .demo-num {
  animation: dPop3 6s infinite;
}
@keyframes dPop1 {
  0%,
  5% {
    transform: scale(0);
  }
  9% {
    transform: scale(1.25);
  }
  12%,
  93% {
    transform: scale(1);
  }
  98%,
  100% {
    transform: scale(0);
  }
}
@keyframes dPop2 {
  0%,
  35% {
    transform: scale(0);
  }
  39% {
    transform: scale(1.25);
  }
  42%,
  93% {
    transform: scale(1);
  }
  98%,
  100% {
    transform: scale(0);
  }
}
@keyframes dPop3 {
  0%,
  65% {
    transform: scale(0);
  }
  69% {
    transform: scale(1.25);
  }
  72%,
  93% {
    transform: scale(1);
  }
  98%,
  100% {
    transform: scale(0);
  }
}
.demo .r1 {
  animation: dGlow1 6s infinite;
}
.demo .r2 {
  animation: dGlow2 6s infinite;
}
.demo .r3 {
  animation: dGlow3 6s infinite;
}
@keyframes dGlow1 {
  8%,
  32% {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-tint);
  }
  0%,
  5%,
  38%,
  100% {
    border-color: var(--border-soft);
  }
}
@keyframes dGlow2 {
  38%,
  62% {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-tint);
  }
  0%,
  35%,
  68%,
  100% {
    border-color: var(--border-soft);
  }
}
@keyframes dGlow3 {
  68%,
  93% {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-tint);
  }
  0%,
  65%,
  98%,
  100% {
    border-color: var(--border-soft);
  }
}
/* content that appears when its row activates */
.demo .r1 .on {
  opacity: 0;
  animation: dOn1 6s infinite;
}
.demo .r2 .on {
  opacity: 0;
  animation: dOn2 6s infinite;
}
.demo .r3 .on {
  opacity: 0;
  animation: dOn3 6s infinite;
}
@keyframes dOn1 {
  0%,
  9% {
    opacity: 0;
  }
  13%,
  93% {
    opacity: 1;
  }
  98%,
  100% {
    opacity: 0;
  }
}
@keyframes dOn2 {
  0%,
  39% {
    opacity: 0;
  }
  43%,
  93% {
    opacity: 1;
  }
  98%,
  100% {
    opacity: 0;
  }
}
@keyframes dOn3 {
  0%,
  69% {
    opacity: 0;
  }
  73%,
  93% {
    opacity: 1;
  }
  98%,
  100% {
    opacity: 0;
  }
}
/* .on text that REPLACES the .off text overlays it exactly (no side-by-side wrap) */
.demo-row .on.swap {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  background: var(--bg-raised);
  box-shadow: 0 0 0 3px var(--bg-raised);
}
/* inline glyph swap: ☐→☑ / ◯→⦿ tick in place, sentence stays put */
.demo-row .dswap {
  position: relative;
  display: inline-block;
}
/* stacked reveal: dim label on top, the result appears underneath it */
.demo-row .dstack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
}
/* content that disappears when its row activates (swapped out) */
.demo .r1 .off {
  animation: dOff1 6s infinite;
}
.demo .r2 .off {
  animation: dOff2 6s infinite;
}
.demo .r3 .off {
  animation: dOff3 6s infinite;
}
@keyframes dOff1 {
  0%,
  9% {
    opacity: 1;
  }
  13%,
  93% {
    opacity: 0.25;
  }
  98%,
  100% {
    opacity: 1;
  }
}
@keyframes dOff2 {
  0%,
  39% {
    opacity: 1;
  }
  43%,
  93% {
    opacity: 0.25;
  }
  98%,
  100% {
    opacity: 1;
  }
}
@keyframes dOff3 {
  0%,
  69% {
    opacity: 1;
  }
  73%,
  93% {
    opacity: 0.25;
  }
  98%,
  100% {
    opacity: 1;
  }
}
/* the moving cursor with click pulses at each stop */
.demo-cursor {
  position: absolute;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--navy-800);
  border: 2.5px solid #fff;
  box-shadow: 0 2px 8px rgb(11 22 38 / 0.45);
  z-index: 5;
  top: -30px;
  left: 60%;
  animation: dCursor 6s infinite;
  pointer-events: none;
}
@keyframes dCursor {
  0% {
    top: -30px;
    left: 60%;
    opacity: 0;
    transform: scale(1);
  }
  6% {
    top: 16%;
    left: 84%;
    opacity: 1;
    transform: scale(1);
  }
  9% {
    transform: scale(0.65);
  }
  12% {
    transform: scale(1);
  }
  34% {
    top: 16%;
    left: 84%;
  }
  38% {
    top: 48%;
    left: 84%;
  }
  40% {
    transform: scale(0.65);
  }
  43% {
    transform: scale(1);
  }
  64% {
    top: 48%;
    left: 84%;
  }
  68% {
    top: 80%;
    left: 84%;
  }
  70% {
    transform: scale(0.65);
  }
  73% {
    transform: scale(1);
  }
  92% {
    top: 80%;
    left: 84%;
    opacity: 1;
  }
  100% {
    top: 80%;
    left: 84%;
    opacity: 0;
  }
}
/* demo garnish */
.dchip {
  display: inline-block;
  background: var(--bg-inset);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 0.75rem;
  font-weight: 600;
  margin-right: 4px;
}
.dchip.ok {
  background: var(--ok-bg);
  color: var(--ok);
}
.dchip.warn {
  background: var(--warn-bg);
  color: var(--warn);
}
.dbtn {
  display: inline-block;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  font-size: 0.78125rem;
  border-radius: 8px;
  padding: 7px 12px;
}
.dsig {
  stroke: var(--text);
  stroke-width: 2.5;
  fill: none;
  stroke-linecap: round;
  stroke-dasharray: 160;
  stroke-dashoffset: 160;
}
.demo .r2 .dsig {
  animation: dDraw2 6s infinite;
}
@keyframes dDraw2 {
  0%,
  40% {
    stroke-dashoffset: 160;
  }
  60%,
  93% {
    stroke-dashoffset: 0;
  }
  98%,
  100% {
    stroke-dashoffset: 160;
  }
}
@media (prefers-reduced-motion: reduce) {
  .demo * {
    animation: none !important;
  }
  .demo .demo-num {
    transform: scale(1);
  }
  .demo .on {
    opacity: 1 !important;
  }
  .demo .off {
    opacity: 0.25 !important;
  }
  .demo .dsig {
    stroke-dashoffset: 0;
  }
  .demo-cursor {
    display: none;
  }
}

/* ---- help centre: search hero, nav buttons, steps ---- */
.help-hero {
  text-align: center;
  padding: 18px 0 6px;
}
.help-hero h1 {
  font-size: 1.75rem;
  margin: 8px 0 4px;
}
.help-hero p {
  margin: 0 auto;
  color: var(--text-muted);
}
.help-search-wrap {
  position: relative;
  max-width: 560px;
  margin: 18px auto 6px;
}
.help-search-wrap svg {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  color: var(--text-faint);
  pointer-events: none;
}
#help-search {
  width: 100%;
  min-height: 58px;
  font-size: 1.125rem;
  padding: 14px 18px 14px 50px;
  border: 2px solid var(--border);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text);
}
#help-search:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.btn-compact {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: auto;
  min-height: 42px;
  padding: 0 16px;
  background: transparent;
  color: var(--text);
  font: 600 0.875rem var(--font);
  border: 1.5px solid var(--border);
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
}
.btn-compact.primary {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}
.help-nav {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 0 0;
}
.help-nav .spacer {
  margin-left: auto;
}
.help-steps {
  list-style: none;
  counter-reset: hstep;
  padding: 0;
  margin: 16px 0;
}
.help-steps li {
  counter-increment: hstep;
  position: relative;
  padding: 0 0 18px 44px;
}
.help-steps li::before {
  content: counter(hstep);
  position: absolute;
  left: 0;
  top: -2px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 800;
  font-size: 0.875rem;
  display: grid;
  place-items: center;
}
.help-steps li:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 13px;
  top: 30px;
  bottom: 2px;
  width: 2px;
  background: var(--border-soft);
}

.faq-item {
  border: 1.5px solid var(--border-soft);
  background: var(--bg-raised);
  border-radius: 12px;
  padding: 14px 16px;
  margin: 0 0 10px;
  transition:
    transform 0.16s ease,
    border-color 0.16s ease,
    box-shadow 0.16s ease;
}
.faq-item:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 6px 18px rgb(11 22 38 / 0.16);
}
.faq-item summary {
  font-weight: 700;
  cursor: pointer;
  font-size: 1rem;
  transition: color 0.16s ease;
}
/* "Still stuck?" at the foot of a help page. It used to be a line of small
   grey print, which is where somebody looks last. Drawn like the questions
   above it, in the accent, it is somewhere to press. */
.help-ask {
  margin-top: 22px;
  border-color: var(--accent);
}
.help-ask > summary {
  color: var(--accent-text);
}
.help-ask-body {
  margin-top: 10px;
}
.help-ask-body .btn {
  width: auto;
  min-width: 200px;
  min-height: 46px;
}
.help-ask-form .btn-row {
  flex-direction: row;
  margin-top: 14px;
}
.faq-item:hover summary {
  color: var(--accent-text);
}
.faq-item p {
  margin: 10px 0 0;
}

/* help cards + quote cards: lively hover */
.help-card,
.quote-card {
  transition:
    transform 0.16s ease,
    border-color 0.16s ease,
    box-shadow 0.16s ease;
}
.help-card:hover,
.quote-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 6px 18px rgb(11 22 38 / 0.16);
}
.help-card:hover .who b {
  color: var(--accent-text);
}
.btn-compact {
  transition:
    border-color 0.15s ease,
    background 0.15s ease,
    transform 0.15s ease;
}
.btn-compact:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}
@media (prefers-reduced-motion: reduce) {
  .help-card,
  .quote-card,
  .faq-item,
  .btn-compact {
    transition: none;
  }
  .help-card:hover,
  .quote-card:hover,
  .faq-item:hover,
  .btn-compact:hover {
    transform: none;
  }
}

/* ---- what's new: pop-up + updates log ---- */
.upd-overlay {
  position: fixed;
  inset: 0;
  z-index: 95;
  background: rgb(11 22 38 / 0.6);
  backdrop-filter: blur(3px);
  display: grid;
  place-items: center;
  padding: 16px;
  overflow-y: auto;
}
.upd-modal {
  background: var(--bg);
  border: 1.5px solid var(--border-soft);
  border-radius: 18px;
  box-shadow: 0 18px 60px rgb(0 0 0 / 0.4);
  padding: 20px;
  max-width: 460px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  animation: updIn 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.15);
}
@keyframes updIn {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.upd-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.upd-head b {
  font-size: 1.125rem;
}
.upd-badge {
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.75rem;
  font-weight: 800;
  border-radius: 999px;
  padding: 4px 12px;
  white-space: nowrap;
}
.upd-badge.draft {
  background: var(--warn-bg);
  color: var(--warn);
}
.upd-items {
  list-style: none;
  padding: 0;
  margin: 12px 0 16px;
}
.upd-items li {
  position: relative;
  padding: 0 0 10px 26px;
  font-size: 0.9375rem;
}
.upd-items li::before {
  content: '✓';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--accent-text);
  font-weight: 800;
}
.upd-card {
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  padding: 16px;
  margin: 14px 0;
  background: var(--bg-raised);
}
/* owner-only Published / Private switch, top right of each release card */
.upd-pub {
  margin-left: auto;
}
.upd-switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 0;
  font: inherit;
  font-size: 0.78125rem;
  font-weight: 800;
  color: var(--text-muted);
}
.upd-switch .upd-track {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
  border-radius: 999px;
  background: var(--border);
  transition: background 0.18s ease;
}
.upd-switch .upd-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.35);
  transition: left 0.18s ease;
}
.upd-switch.on {
  color: var(--accent-text);
}
.upd-switch.on .upd-track {
  background: var(--accent);
}
.upd-switch.on .upd-knob {
  left: 21px;
}
@media (prefers-reduced-motion: reduce) {
  .upd-modal {
    animation: none;
  }
  .upd-switch .upd-track,
  .upd-switch .upd-knob {
    transition: none;
  }
}

/* the install demo panel reuses the animated phones, no cursor/rows */
.demo-install {
  display: block;
}

/* The page's own content is a main landmark for screen readers; display:
   contents keeps it out of the layout, so the rail, the centring and the
   fade see exactly what they saw before. */
.page-main {
  display: contents;
}
/* The footer stays at the foot of the window, however short the page.

   The column is a flex stack as tall as the window: the page comes first,
   the footer is pushed to the bottom by its own top margin, and a page that
   is longer than the window scrolls exactly as before. The rules that were
   meant to do this named children the column no longer has — the page sits
   inside its main landmark, and the footer's class had changed — so on
   every short page the footer sat directly under the last line, with the
   rest of the window empty beneath it. */
.shell-main {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}
.shell-main > .page-main > .wrap {
  width: 100%;
  box-sizing: border-box;
}
.shell-main > .qn-foot {
  margin-top: auto;
  width: 100%;
  box-sizing: border-box;
}
/* Pages without the navigation — signing in, a customer's quote — have the
   footer straight in the body; the same stack, on the body itself. */
body:has(> .page-main) {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
body > .qn-foot {
  margin-top: auto;
  width: 100%;
  box-sizing: border-box;
}
/* On a phone the tab bar floats over the foot of the page, so the footer
   ends above it rather than under it. */
@media (max-width: 767px) {
  .shell-main {
    min-height: calc(100vh - var(--nav-h) - env(safe-area-inset-bottom, 0px));
    min-height: calc(100dvh - var(--nav-h) - env(safe-area-inset-bottom, 0px));
  }
  .shell-main > .qn-foot {
    padding-bottom: 24px;
  }
  .shell-main > .page-main > .wrap {
    padding-bottom: 40px;
  }
}
/* ---- between pages: a short fade out and in ----
   Opacity on the body only, which the compositor handles without touching
   layout, so it costs nothing however long the page is. The fade out never
   delays the navigation: it plays while the next page is fetched. */
body > *:not(.qn-loader):not(.page-main),
body > .page-main > * {
  animation: qnPageIn 0.14s ease-out both;
}
html.is-leaving body > *:not(.qn-loader):not(.page-main),
html.is-leaving body > .page-main > * {
  opacity: 0;
  transition: opacity 0.1s ease-in;
}
@keyframes qnPageIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  body > *:not(.qn-loader),
  body > .page-main > * {
    animation: none;
  }
  html.is-leaving body > *:not(.qn-loader),
  html.is-leaving body > .page-main > * {
    opacity: 1;
    transition: none;
  }
}

/* ---- between-pages loading screen: the mark, the name, and a sweeping bar ----
   The same screen the Mail app shows as it opens: the mark and the name held
   still, and a green light sweeping along a thin track underneath, 1.23s a
   pass. The light moves on a transform inside a clipped track of fixed
   width, so it relays out nothing and costs nothing to draw.

   There is deliberately no @view-transition here. It cross-faded one page
   into the next and looked right, but the browser snapshots the whole
   document rather than the visible window, twice per navigation, so the cost
   grew with the length of the page — measured at +91ms a click on the long
   ones under a modest CPU, and enough texture to lock a machine up. What
   removes the flash is below and costs nothing: the cover simply waits long
   enough that an ordinary page never shows it. */
.qn-loader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-content: center;
  justify-items: center;
  background: var(--bg);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.qn-loader.go {
  visibility: visible;
  /* Only a page that is genuinely slow earns the loading screen. A normal
     page is here well inside 0.7s, so it never sees this. */
  animation: qlShow 0.3s ease 0.7s both;
}
@keyframes qlShow {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.ql-logo {
  width: 58px;
  color: var(--text);
}
.ql-word {
  margin-top: 16px;
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
  color: var(--text);
}
.ql-bar {
  position: relative;
  overflow: hidden;
  width: 150px;
  height: 3px;
  margin-top: 26px;
  border-radius: 3px;
  background: var(--border);
}
.ql-bar i {
  position: absolute;
  inset: 0 auto 0 0;
  width: 50px;
  background: linear-gradient(90deg, transparent, #17c96f, transparent);
  transform: translateX(-50px);
}
.qn-loader.go .ql-bar i {
  animation: qlSweep 1.23s linear 0.7s infinite both;
}
@keyframes qlSweep {
  0% {
    transform: translateX(-50px);
  }
  53%,
  100% {
    transform: translateX(150px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .qn-loader.go .ql-bar i {
    animation: none;
    transform: translateX(50px);
  }
}

/* ---- payment plan builder (quote editor) ---- */
.plan-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.plan-grid label {
  margin-top: 10px;
}
.plan-crow {
  display: flex;
  gap: 8px;
  margin: 6px 0;
  align-items: center;
}
.plan-crow input {
  min-height: 44px;
}
.plan-crow-del {
  background: none;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  color: var(--danger);
  width: 40px;
  min-height: 44px;
  cursor: pointer;
  flex: none;
}
.btn-quiet.plan-add {
  width: auto;
  min-height: 40px;
  padding: 0 16px;
  margin-top: 4px;
}
.plan-preview {
  background: var(--bg-raised);
  border: 1.5px solid var(--accent);
  border-radius: 12px;
  padding: 12px 14px;
  margin-top: 12px;
  font-size: 0.875rem;
}
.plan-preview b {
  display: block;
  margin-bottom: 6px;
}
.plan-line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
}
.plan-line.now {
  font-weight: 700;
}
.plan-note {
  margin-top: 6px;
  font-size: 0.78125rem;
}
.plan-ok {
  color: var(--ok);
  font-weight: 700;
}
.plan-bad {
  color: var(--danger);
  font-weight: 700;
}

/* ---- payments on the quote page ---- */
.pay-row {
  border: 1.5px solid var(--border-soft);
  border-radius: 12px;
  padding: 12px 14px;
  margin: 10px 0;
  background: var(--bg-raised);
}
.pay-row.paid {
  border-color: var(--accent);
}
.pay-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.pay-amount {
  font-weight: 800;
}
/* "Mark as paid" on a payment that has a live bank link: greyed until the
   trader says they were paid another way, then the ordinary green button */
.btn-compact.primary.pay-locked {
  background: var(--bg-raised);
  color: var(--text-muted);
  border-color: var(--border);
  cursor: help;
}
.pay-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.pay-actions form {
  margin: 0;
}

/* ---- expenses ---- */
.expense-list {
  list-style: none;
  padding: 0;
  margin: 0 0 10px;
}
.expense-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-soft);
}
.expense-list li > span:first-child {
  flex: 1;
  min-width: 0;
}
.expense-amt {
  font-weight: 700;
  color: var(--danger);
}
.expense-list form {
  margin: 0;
}
.expense-del {
  background: none;
  border: none;
  color: var(--text-faint);
  cursor: pointer;
  font-size: 0.9375rem;
  padding: 4px 8px;
}
.expense-del:hover {
  color: var(--danger);
}
.expense-form {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.expense-form input[name='expense_desc'] {
  flex: 2;
  min-width: 11em;
}
.expense-form input[name='expense_amount'] {
  flex: 1;
  min-width: 90px;
  max-width: 140px;
}

/* ---- trading hours ---- */
.day-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 12px;
}
.day-pick {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1.5px solid var(--border-soft);
  border-radius: 8px;
  padding: 6px 10px;
  font-weight: 400;
  margin: 0;
  cursor: pointer;
}
.day-pick:has(input:checked) {
  border-color: var(--accent);
  background: var(--bg-raised);
}
.day-pick input {
  margin: 0;
}

/* ---- internal notes ---- */
.note-list {
  list-style: none;
  padding: 0;
  margin: 0 0 10px;
}
.note-list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-soft);
}
.note-list li > div {
  flex: 1;
  min-width: 0;
}
.note-body {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.note-form {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: flex-end;
}
.note-form textarea {
  flex: 1;
  min-width: 220px;
}

/* ---- customer payment page ---- */
.doc-badge {
  display: inline-block;
  background: var(--bg-raised);
  border: 1.5px solid var(--border-soft);
  border-radius: 999px;
  padding: 6px 16px;
  font-weight: 800;
  margin: 8px 0 0;
}
.pay-bank {
  background: var(--bg-raised);
  border: 1.5px solid var(--accent);
  border-radius: 14px;
  padding: 16px;
  margin: 16px 0 0;
  text-align: left;
}
.pay-bank table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 8px;
}
.pay-bank td {
  padding: 5px 0;
  border-bottom: 1px solid var(--border-soft);
}
.pay-bank td:first-child {
  color: var(--text-muted);
  width: 45%;
  padding-right: 0.75em;
}
.pay-schedule {
  background: var(--bg-raised);
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  padding: 14px 16px;
  margin-top: 16px;
  text-align: left;
  font-size: 0.875rem;
}
.pay-schedule > b {
  display: block;
  margin-bottom: 6px;
}
.pay-paid {
  color: var(--ok);
}
.pay-late {
  color: var(--danger);
  font-weight: 700;
}

/* ---- finance page ---- */
.fin-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 6px;
}
.fin-card {
  background: var(--bg-raised);
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  padding: 14px;
}
.fin-card span {
  display: block;
  font-size: 0.8125rem;
  color: var(--text-muted);
  font-weight: 600;
}
.fin-card b {
  font-size: clamp(1.125rem, 4.5vw, 1.625rem);
  letter-spacing: -0.01em;
}
.fin-card.profit {
  border-color: var(--accent);
}
.fin-card.profit b {
  color: var(--accent-text);
}
/* A negative profit is a loss, and must never wear the profit colour. */
.fin-card.loss {
  border-color: var(--danger);
}
.fin-card.loss b {
  color: var(--danger);
}
.neg {
  color: var(--danger);
}
.fin-table {
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  overflow: hidden;
}
.fin-row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-soft);
  text-decoration: none;
  color: var(--text);
  font-size: 0.90625rem;
  align-items: center;
}
.fin-row:last-child {
  border-bottom: none;
}
.fin-row.fin-head {
  background: var(--bg-raised);
  font-size: 0.71875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 700;
}
a.fin-row:hover {
  background: var(--bg-raised);
}
.fin-row.overdue {
  background: var(--danger-bg);
}
.fin-overdue {
  color: var(--danger);
}
@media (max-width: 560px) {
  .fin-cards {
    grid-template-columns: 1fr;
  }
  .fin-row {
    font-size: 0.78125rem;
    padding: 10px 10px;
    gap: 6px;
  }
}

/* ---- plan change proposal box on the quote page ---- */
.plan-change-box {
  margin: 12px 0 0;
}
.plan-change-box > summary {
  display: inline-flex;
  list-style: none;
  cursor: pointer;
}
.plan-change-box > summary::-webkit-details-marker {
  display: none;
}
.plan-change-box[open] > summary {
  border-color: var(--accent);
}

/* ---- admin: where registrations came from ---- */
.src-table {
  margin: 14px 0 6px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  overflow: hidden;
}
.src-head,
.src-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 9px 14px;
  font-size: 0.875rem;
}
.src-head {
  background: var(--bg-raised);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.src-row + .src-row,
.src-head + .src-row {
  border-top: 1px solid var(--border-soft);
}
.src-row span:last-child {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.src-table p {
  padding: 0 14px 12px;
}

/* ---- marketing dashboard (owner only) ---- */
.mk-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin: 16px 0 10px;
}
.mk-card {
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  padding: 14px 16px;
  background: var(--bg-raised);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.mk-card span {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.mk-card b {
  font-size: 1.875rem;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.mk-card i {
  font-style: normal;
}
.mk-card.full b {
  color: var(--warn);
}
.mk-search {
  display: flex;
  gap: 8px;
  margin: 10px 0 14px;
  flex-wrap: wrap;
}
.mk-search input {
  flex: 1 1 220px;
  min-height: 44px;
  padding: 10px 14px;
  border: 1.5px solid var(--border);
  border-radius: 10px;
  font: 400 1rem var(--font);
  color: var(--text);
  background: var(--bg);
}
.mk-list {
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  overflow: hidden;
}
.mk-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
}
.mk-row + .mk-row {
  border-top: 1px solid var(--border-soft);
}
.mk-place {
  flex: 0 0 auto;
  min-width: 52px;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  font-size: 0.8125rem;
}
.mk-who {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.mk-who b,
.mk-who span {
  overflow-wrap: anywhere;
}
.mk-del {
  border: 1.5px solid var(--border);
  background: var(--bg);
  color: var(--danger, #c92a2a);
  border-radius: 999px;
  padding: 6px 14px;
  font: 600 0.8125rem var(--font);
  cursor: pointer;
  min-height: 36px;
}
.mk-del:hover {
  border-color: var(--danger, #c92a2a);
}
.mk-msgs {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.mk-msg {
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent);
  border-radius: 12px;
  padding: 14px 16px;
}
.mk-msg.done {
  border-left-color: var(--border);
  opacity: 0.72;
}
.mk-msg-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.mk-msg-body {
  white-space: pre-wrap;
  margin: 0 0 12px;
  line-height: 1.55;
  overflow-wrap: anywhere;
}

/* ---- broadcast composer ---- */
.bc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  align-items: start;
  margin-top: 18px;
}
@media (max-width: 900px) {
  .bc-grid {
    grid-template-columns: 1fr;
  }
}
.bc-form label {
  display: block;
  font-size: 0.875rem;
  font-weight: 700;
  margin: 14px 0 6px;
}
.bc-form input[type='text'],
.bc-form select,
.bc-form textarea {
  width: 100%;
  font: 400 1rem var(--font);
}
.bc-form textarea {
  min-height: 340px;
  line-height: 1.55;
  resize: vertical;
}
.bc-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 16px;
}
.bc-preview {
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-inset);
  position: sticky;
  top: 12px;
}
.bc-pvbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 9px 13px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  font-size: 0.8125rem;
  font-weight: 600;
}
.bc-pvnote {
  margin-left: auto;
  font-weight: 400;
  color: var(--text-muted);
  font-size: 0.75rem;
}
.bc-views {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 7px;
  overflow: hidden;
}
.bc-view {
  padding: 4px 11px;
  border: 0;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  font: 600 0.75rem var(--font);
}
.bc-view + .bc-view {
  border-left: 1px solid var(--border);
}
.bc-view:hover {
  color: var(--text);
}
.bc-view.is-on {
  background: var(--accent);
  color: var(--on-accent);
}
.bc-view:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.bc-scale {
  overflow: hidden;
  background: #eef2f6;
}
.bc-preview iframe {
  display: block;
  width: 640px;
  height: 700px;
  border: 0;
  background: #eef2f6;
  transform-origin: top left;
}
/* The invitation folds to any width, so its frame takes the whole box and grows to the email's height. */
#beta-frame,
#ep-frame {
  width: 100%;
  transform: none;
}
/* Admin → Emails: the live preview's picker sits with the view switches; a phone width centres the frame. */
.ep-preview .bc-pvbar {
  flex-wrap: wrap;
  gap: 8px;
}
.ep-preview select {
  flex: 1 1 220px;
  min-width: 0;
  font: 500 0.8rem var(--font);
}
.ep-preview .bc-scale {
  text-align: center;
}
#ep-frame {
  margin: 0 auto;
  max-width: 100%;
}
.bc-send {
  margin-top: 26px;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 12px;
  background: var(--bg);
}
.btn-big {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 60px;
  background: var(--accent);
  color: var(--on-accent);
  font: 700 1.125rem var(--font);
  border: none;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
}
.btn-big:active {
  background: var(--accent-strong);
}
/* the disabled look is set once, up with .btn — see the note there */
.crumb {
  margin: 0 0 6px;
  font-size: 0.875rem;
}

.bc-import {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin: 16px 0 0;
  padding: 14px 16px;
  border: 1px dashed var(--border);
  border-radius: 12px;
  background: var(--bg);
}
.bc-import > div {
  flex: 1 1 260px;
}
.bc-import input[type='file'] {
  font: 400 0.875rem var(--font);
  max-width: 100%;
}

.bc-inserts {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 10px 0 0;
}
.bc-size {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 10px 0 0;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
}
.bc-size[hidden] {
  display: none;
}
.bc-size label {
  margin: 0;
  font-size: 0.84375rem;
  font-weight: 600;
  color: var(--text);
}
.bc-size label b {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 600;
}
.bc-size input[type='range'] {
  flex: 1 1 120px;
  min-width: 100px;
  accent-color: var(--accent);
}
.bc-size output {
  font:
    600 0.8125rem ui-monospace,
    SFMono-Regular,
    Menlo,
    monospace;
  color: var(--text-muted);
  min-width: 44px;
  text-align: right;
  flex: 0 0 auto;
}
.bc-size label {
  flex: 0 0 auto;
}
/* the dialog's own colours must be set explicitly — the browser default is a
   white canvas, which is invisible against dark-mode text */
.bc-modal {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 0;
  max-width: min(760px, 94vw);
  width: 100%;
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.45);
}
.bc-modal::backdrop {
  background: rgb(4 10 20 / 0.62);
}
.bc-modalbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--text);
}
.bc-modalbar b {
  font-size: 1.0625rem;
  color: var(--text);
}
.bc-modalbar .small {
  color: var(--text-muted);
}
.bc-modalbar button {
  margin-left: auto;
}
.bc-modalfoot {
  margin: 0;
  padding: 12px 18px 16px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  background: var(--bg-raised);
}
.bc-lib {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
  padding: 16px 18px;
  max-height: 60vh;
  overflow: auto;
  background: var(--bg);
}
.bc-tile {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  overflow: hidden;
}
.bc-tile.is-gone {
  opacity: 0.55;
}
.bc-tile:hover {
  border-color: var(--accent);
}
.bc-tile-pick {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  text-align: left;
  font: inherit;
}
.bc-tile-pick:disabled {
  cursor: not-allowed;
}
.bc-tile-pick:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.bc-tile-pick img {
  display: block;
  width: 100%;
  height: 104px;
  object-fit: cover;
  object-position: top;
  background: var(--bg-inset);
  border-bottom: 1px solid var(--border);
}
.bc-tile-pick span {
  display: block;
  padding: 9px 10px 7px;
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--text);
}
.bc-tile-del {
  margin: 0 10px 10px;
  padding: 6px 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  font: 600 0.75rem var(--font);
  color: var(--text-muted);
  cursor: pointer;
}
.bc-tile-del:hover {
  border-color: var(--danger);
  color: var(--danger);
}
.bc-tile-del:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---- marketing sections ---- */
.mk-sec {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg);
  margin: 16px 0 0;
  overflow: hidden;
}
.mk-sec > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.mk-sec > summary::-webkit-details-marker {
  display: none;
}
.mk-sec > summary::before {
  content: '';
  width: 8px;
  height: 8px;
  flex: none;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
  margin-left: 2px;
}
.mk-sec[open] > summary::before {
  transform: rotate(45deg);
}
.mk-sec > summary:hover {
  background: var(--bg-raised);
}
.mk-sec > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.mk-sectitle {
  font-size: 1.125rem;
  font-weight: 700;
}
.mk-seccount {
  margin-left: auto;
  font: 600 0.8125rem var(--font);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
  min-width: 34px;
  text-align: center;
}
.mk-seccount.flag {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}
.mk-sec > *:not(summary) {
  padding-left: 18px;
  padding-right: 18px;
}
.mk-sec > *:last-child {
  padding-bottom: 18px;
}
.mk-sub {
  font-size: 0.9375rem;
  font-weight: 700;
  margin: 16px 0 8px;
}
@media (prefers-reduced-motion: reduce) {
  .mk-sec > summary::before {
    transition: none;
  }
}

/* ---- the beta week ---- */
.bt-stage {
  font-size: 0.75rem;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  border: 1px solid var(--border);
  background: var(--bg-inset);
  color: var(--text-muted);
}
.bt-stage.ok {
  border-color: var(--accent);
  color: var(--accent-text);
  background: transparent;
}
.bt-stage.soft {
  color: var(--text-faint);
}
.bt-survey label {
  display: block;
  font-size: 0.9375rem;
  font-weight: 700;
  margin: 20px 0 2px;
}
.bt-survey .bt-hint {
  margin: 0 0 6px;
}
.bt-survey textarea {
  width: 100%;
  font: 400 1rem var(--font);
  line-height: 1.55;
  resize: vertical;
}

/* ---- the floating helper ---- */
.qn-fab {
  position: fixed;
  right: 18px;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  width: 58px;
  height: 58px;
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: var(--on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
  z-index: 60;
}
/* Nod, in the header rather than the bottom corner, on a phone.
   A chat button floating over the foot of a phone screen sits on top of
   whatever is at the foot of the page — which on most of these is the button
   the page is for. Up here it is beside the logo, out of the way of
   everything, and still one tap.

   Written immediately after the rule it overrides rather than with the rest of
   the phone layout further up the file. Same specificity, so whichever comes
   last wins: up there `bottom: auto` lost, and the button only landed in the
   right place because top, bottom and height together are over-constrained and
   the browser happened to drop the one this needed dropped. That is a thing
   that works until it doesn't. */
@media (max-width: 767px) {
  .qn-fab {
    top: 8px;
    right: 12px;
    bottom: auto;
    width: 40px;
    height: 40px;
    z-index: 71;
    box-shadow: none;
  }
  .qn-fab svg {
    width: 22px;
    height: 22px;
  }
  /* And with it up there, the bar at the foot of a page has nothing to clear. */
  body:has(.qn-fab) .actionbar {
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }
}

.qn-fab:hover {
  filter: brightness(1.06);
}
.qn-fab:active {
  background: var(--accent-strong);
}
.qn-fab:focus-visible {
  outline: 3px solid var(--text);
  outline-offset: 3px;
}

.qn-help {
  position: fixed;
  right: 18px;
  bottom: calc(88px + env(safe-area-inset-bottom, 0px));
  width: min(380px, calc(100vw - 36px));
  max-height: min(560px, calc(100vh - 130px));
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.3);
  z-index: 61;
  overflow: hidden;
}
.qn-help[hidden] {
  display: none;
}
.qn-grab {
  display: none;
}
.qn-help.is-dragging {
  transition: none;
}
.qn-help-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}
.qn-help-head b {
  font-size: 1rem;
}
/* The conversation's reference, sat next to Nod's name.
   Monospaced digits so it is read back correctly over a phone, and quiet
   enough that it is a label rather than a thing to press. */
.qn-help-ref {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  background: var(--bg-inset);
  border-radius: 999px;
  padding: 3px 9px;
  white-space: nowrap;
  user-select: all; /* one click selects the whole thing to copy */
}

/* The line that names the reference, said once under the first answer. It is
   not a message from Nod, so it is not a bubble. */
.qn-refnote {
  margin: 2px 0 6px;
  font-size: 0.78125rem;
  line-height: 1.5;
  color: var(--text-faint);
  border-left: 2px solid var(--border-soft);
  padding-left: 10px;
}

.qn-help-link {
  margin-left: auto;
  border: 0;
  background: none;
  color: var(--text-muted);
  font: 600 0.8125rem var(--font);
  cursor: pointer;
  text-decoration: underline;
}
.qn-help-link:hover {
  color: var(--text);
}
.qn-help-x {
  border: 0;
  background: none;
  color: var(--text-muted);
  font-size: 1.375rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.qn-help-x:hover {
  color: var(--text);
}
.qn-help-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 14px;
}
.qn-help-intro {
  margin: 0 0 8px;
  font-size: 0.90625rem;
  color: var(--text-muted);
  line-height: 1.5;
}
.qn-help-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-bottom: 8px;
}
.qn-help-presets[hidden] {
  display: none;
}
.qn-chip {
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  border-radius: 999px;
  padding: 7px 13px;
  font: 600 0.84375rem var(--font);
  cursor: pointer;
}
.qn-chip:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}
.qn-chip-other {
  border-style: dashed;
  color: var(--text-muted);
}
.qn-help-log {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.qn-msg {
  max-width: 88%;
  padding: 10px 13px;
  border-radius: 14px;
  font-size: 0.9375rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.qn-msg-user {
  align-self: flex-end;
  background: var(--accent);
  color: var(--on-accent);
  border-bottom-right-radius: 5px;
}
.qn-msg-assistant {
  align-self: flex-start;
  background: var(--bg-inset);
  color: var(--text);
  border: 1px solid var(--border-soft);
  border-bottom-left-radius: 5px;
}
.qn-msg-wait {
  color: var(--text-muted);
  font-style: italic;
}
.qn-msg-actions {
  align-self: flex-start;
}
.qn-help-foot {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 10px 12px 4px;
  border-top: 1px solid var(--border);
  background: var(--bg);
}
.qn-help-foot[hidden] {
  display: none;
}
.qn-help-foot textarea {
  flex: 1 1 auto;
  resize: none;
  min-height: 42px;
  max-height: 120px;
  padding: 10px 12px;
  font: 400 0.9375rem var(--font);
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-raised);
  color: var(--text);
}
.qn-help-send {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border: none;
  border-radius: 12px;
  background: var(--accent);
  color: var(--on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.qn-help-send:active {
  background: var(--accent-strong);
}
.qn-help-foot-note {
  margin: 0;
  padding: 4px 12px 10px;
  background: var(--bg);
  font-size: 0.71875rem;
  color: var(--text-faint);
  text-align: center;
}
.qn-help-foot-note summary {
  cursor: pointer;
  list-style: none;
}
.qn-help-foot-note summary::-webkit-details-marker {
  display: none;
}
.qn-help-foot-note summary::after {
  content: ' ▾';
}
.qn-help-foot-note[open] summary::after {
  content: ' ▴';
}
.qn-help-foot-note p {
  margin: 4px 0 0;
}
.qn-help.is-ticket .qn-help-body,
.qn-help.is-ticket .qn-help-foot-note {
  display: none;
}
/* the form is taller than a conversation; give it the room rather than making
   people scroll past the note to find the send button */
.qn-help.is-ticket {
  max-height: min(640px, calc(100vh - 110px));
}
.qn-help-ticket {
  flex: 1 1 auto;
  border-top: 1px solid var(--border);
  background: var(--bg);
  padding: 12px 14px 14px;
  overflow-y: auto;
}
.qn-help-ticket[hidden] {
  display: none;
}
.qn-help-tickethead {
  margin: 0 0 8px;
  font-size: 0.9375rem;
}
.qn-help-ticket label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 700;
  margin: 10px 0 4px;
}
.qn-help-opt {
  font-weight: 400;
  color: var(--text-faint);
}
.qn-help-ticket textarea {
  width: 100%;
  resize: vertical;
  padding: 8px 10px;
  font: 400 0.90625rem var(--font);
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  color: var(--text);
}
.qn-help-note {
  margin: 10px 0 0;
  font-size: 0.75rem;
  color: var(--text-faint);
  line-height: 1.45;
}
.qn-help-trow {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  /* the panel is short and the form is not — keep the buttons in view rather
     than at the end of a scroll most people will not make */
  position: sticky;
  bottom: -14px;
  padding: 10px 0 4px;
  background: var(--bg);
}

/* the dimmed page behind the overlay; only ever visible on a phone */
.qn-scrim {
  position: fixed;
  inset: 0;
  background: rgba(6, 12, 22, 0.55);
  backdrop-filter: blur(2px);
  z-index: 59;
  opacity: 0;
  transition: opacity 0.24s ease;
}
.qn-scrim[hidden] {
  display: none;
}
.qn-scrim.is-in {
  opacity: 1;
}

/**
 * On a phone Nod is not a box floating over the page — it is the screen.
 *
 * The panel fills it, the page behind is dimmed and frozen, and the whole
 * thing grows out of the green button rather than appearing: the button
 * becomes the panel, which is why the transform origin is the bottom right
 * corner where the button sits.
 */
@media (max-width: 520px) {
  .qn-scrim {
    display: block;
  }
  .qn-help {
    right: 0;
    left: 0;
    top: 0;
    bottom: 0;
    width: auto;
    max-width: none;
    max-height: none;
    border-radius: 0;
    border: 0;
    /* the visual viewport keeps the panel above the keyboard on iOS, where
       100vh is the window and not what you can actually see */
    height: 100dvh;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    box-shadow: none;
    transform-origin: calc(100% - 44px) calc(100% - 44px);
    transition:
      transform 0.26s cubic-bezier(0.2, 0.9, 0.3, 1),
      opacity 0.16s ease;
  }
  .qn-help.is-ticket {
    max-height: none;
  }
  /* something to pull down on, and a hint that pulling down works */
  .qn-grab {
    display: block;
    flex: 0 0 auto;
    padding: 8px 0 2px;
    touch-action: none;
    cursor: grab;
  }
  .qn-grab::before {
    content: '';
    display: block;
    width: 40px;
    height: 4px;
    margin: 0 auto;
    border-radius: 999px;
    background: var(--border);
  }
  /* the close control moves to where a thumb actually reaches */
  .qn-help-head {
    padding: 14px 12px 14px 16px;
  }
  .qn-help-x {
    font-size: 1.875rem;
    padding: 0 10px;
    min-height: 44px;
    min-width: 44px;
  }
  .qn-help-body {
    padding-bottom: 20px;
  }
  .qn-sugg {
    bottom: auto;
    top: auto;
  }
  /* the button hides under its own panel rather than sitting on top of it */
  body.qn-help-open .qn-fab {
    opacity: 0;
    pointer-events: none;
    animation: none;
  }
  /* On the narrowest phones the button used to be tucked a little tighter
     into the bottom corner. It is not in the bottom corner any more — it sits
     in the header beside the logo — so all that is left of this is the fade,
     and naming `bottom` here would put it back down there: this rule is
     further down the file than the one that moved it, and at the same
     specificity the last one wins. */
  .qn-fab {
    right: 14px;
    transition: opacity 0.18s ease;
  }
}

/* the page behind must not move while the overlay is up */
body.qn-locked {
  position: fixed;
  left: 0;
  right: 0;
  overflow: hidden;
  width: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .qn-help,
  .qn-scrim {
    transition: none !important;
  }
}

.qn-help-down {
  border-top: 1px solid var(--border);
  background: var(--bg-inset);
  padding: 14px;
}
.qn-help-down[hidden] {
  display: none;
}
.qn-help.is-ticket .qn-help-down {
  display: none;
}
.qn-help.is-down .qn-help-foot-note {
  display: none;
}
.qn-help-downhead {
  margin: 0 0 4px;
  font-size: 0.9375rem;
}
.qn-help-downbody {
  margin: 0 0 12px;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* ---- Nod: the logo, read as a face ---- */
.qn-bot-strip {
  flex: 0 0 auto;
  padding: 10px 14px 4px;
  background: var(--bg-raised);
  color: var(--text); /* the tick is currentColor, exactly as in the logo */
}
.qn-bot {
  display: flex;
  justify-content: center;
  padding: 0 0 4px;
}
/* Where Nod's left eye lives when he is not winking.
   The logo has the green dot out at the edge; on a face the pair belongs
   centred over the smile, seven units in. The scripts that animate him set
   this on the element itself, which wins over this rule — this is so he is
   right before one runs, and on the screens where none does. */
#qn-eye-l,
#qnm-eye-l,
#qnp-eye-l {
  transform: translate(7px, 0);
}
.qn-bot-svg {
  display: block;
  overflow: visible;
  animation: qn-float 4s ease-in-out infinite;
}
.qn-bot #qn-eye-l,
.qn-bot #qn-eye-r {
  transition: transform 0.12s ease-out;
}
.qn-bot #qn-eye-l-dot,
.qn-bot #qn-eye-r-dot {
  transition:
    transform 0.09s ease-in,
    opacity 0.18s ease;
}
.qn-bot #qn-eye-r-arc {
  transition: opacity 0.18s ease;
}
.qn-bot[data-mood='thinking'] .qn-bot-svg {
  animation: qn-bob 0.9s ease-in-out infinite;
}
.qn-bot[data-mood='sad'] .qn-bot-svg {
  animation: none;
  transform: translateY(2px) rotate(-2deg);
}
#qn-bot-head.is-spin {
  animation: qn-spin 0.9s cubic-bezier(0.3, 0.7, 0.3, 1) 1;
}
#qn-bot-head.is-nod {
  animation: qn-nod 0.6s ease-in-out 1;
}
/* mid-conversation Nod steps to the corner and keeps out of the way */
.qn-help.is-chatting .qn-bot-strip {
  padding: 6px 14px 0;
}
.qn-help.is-chatting .qn-bot {
  justify-content: flex-start;
  padding: 0;
}
.qn-help.is-chatting .qn-bot-svg {
  width: 60px;
  height: 60px;
}
.qn-help.is-ticket .qn-bot-strip {
  display: none;
}
.qn-help-sound {
  margin-left: auto;
  border: 0;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px 4px;
  display: flex;
  align-items: center;
}
.qn-help-sound:hover {
  color: var(--text);
}
.qn-help-sound .qn-snd-off {
  display: none;
}
.qn-help-sound.is-off .qn-snd-off {
  display: block;
}
.qn-help-sound.is-off .qn-snd-wave {
  display: none;
}
.qn-help-sound + .qn-help-link {
  margin-left: 4px;
}

.qn-help-cols {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}
.qn-help-main {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
}
.qn-help-expand {
  display: none;
  align-items: center;
  border: 0;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px 4px;
}
.qn-help-expand:hover {
  color: var(--text);
}
.qn-help-expand .qn-exp-in,
.qn-help.is-wide .qn-help-expand .qn-exp-out {
  display: none;
}
.qn-help.is-wide .qn-help-expand .qn-exp-in {
  display: block;
}
.qn-glance {
  display: none;
  flex: 0 0 300px;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  border-left: 1px solid var(--border);
  background: var(--bg);
  overflow-y: auto;
}
.qn-glance-h {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.qn-glance-tiles {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.qn-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
}
a.qn-tile:hover {
  border-color: var(--accent);
}
.qn-tile b {
  font-size: 1.375rem;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.qn-tile span {
  font-size: 0.78125rem;
  color: var(--text-muted);
}
.qn-tile-wide {
  grid-column: 1 / -1;
}
.qn-tile.is-danger b {
  color: var(--danger);
}
.qn-tile.is-danger,
a.qn-tile.is-danger:hover {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}
.qn-glance-sec h3 {
  margin: 0 0 8px;
  font-size: 0.875rem;
}
.qn-glance-list {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.qn-glance-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.84375rem;
}
.qn-glance-part {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qn-glance-qty {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.qn-pill {
  flex: 0 0 auto;
  padding: 2px 8px;
  border-radius: 999px;
  font: 700 0.6875rem var(--font);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.qn-pill-out {
  background: var(--danger-bg);
  color: var(--danger);
}
.qn-pill-low {
  background: var(--warn-bg);
  color: var(--warn);
}
.qn-glance-more {
  font-size: 0.8125rem;
  color: var(--link);
}
.qn-glance-social {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.qn-glance-social .qn-tile {
  padding: 8px 10px;
}
.qn-glance-social .qn-tile b {
  font-size: 1.0625rem;
}
.qn-glance-sub {
  margin: 10px 0 6px;
  font-size: 0.78125rem;
  color: var(--text-muted);
}
.qn-glance-bars {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.qn-bar {
  display: grid;
  grid-template-columns: 72px 1fr 40px;
  align-items: center;
  gap: 8px;
  font-size: 0.78125rem;
}
.qn-bar-track {
  height: 10px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
}
.qn-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}
.qn-bar-fill.is-before {
  background: var(--text-faint);
}
.qn-bar b {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.qn-glance-acts {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.qn-glance-acts .qn-chip {
  text-align: center;
  text-decoration: none;
}
.qn-glance-acts .qn-chip[hidden] {
  display: none;
}
.qn-glance-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 2px 14px 8px;
  background: var(--bg-raised);
}
.qn-glance-chips[hidden],
.qn-help.is-ticket .qn-glance-chips {
  display: none;
}
.qn-gchip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--text);
  font: 600 0.78125rem var(--font);
  text-decoration: none;
  white-space: nowrap;
}
.qn-gchip:hover {
  border-color: var(--accent);
}
.qn-gchip::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.qn-gchip.is-danger::before {
  background: var(--danger);
}
.qn-gchip.is-warn::before {
  background: var(--warn);
}
@media (min-width: 1100px) {
  .qn-help-expand {
    display: flex;
  }
  .qn-help.is-wide {
    top: 50%;
    right: 24px;
    bottom: auto;
    translate: 0 -50%;
    width: min(1040px, calc(100vw - 48px));
    height: min(760px, calc(100vh - 48px));
    max-height: none;
  }
  .qn-help.is-wide .qn-glance {
    display: flex;
  }
  .qn-help.is-wide .qn-glance-chips {
    display: none;
  }
}
@keyframes qn-float {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-3px);
  }
}
@keyframes qn-bob {
  0%,
  100% {
    transform: translateY(0) rotate(0);
  }
  50% {
    transform: translateY(-2px) rotate(3deg);
  }
}
@keyframes qn-spin {
  from {
    transform: rotate(0);
  }
  to {
    transform: rotate(360deg);
  }
}
@keyframes qn-nod {
  0%,
  100% {
    transform: translateY(0) rotate(0);
  }
  30% {
    transform: translateY(3px) rotate(-5deg);
  }
  65% {
    transform: translateY(-1px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .qn-bot-svg,
  .qn-bot[data-mood='thinking'] .qn-bot-svg,
  #qn-bot-head.is-spin,
  #qn-bot-head.is-nod {
    animation: none !important;
  }
}

/* suggestions, floating above the box you type in */
.qn-sugg {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 96px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-raised);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
  z-index: 2;
  max-height: 260px;
  overflow-y: auto;
}
.qn-sugg[hidden] {
  display: none;
}
.qn-sugg-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  border: 0;
  background: none;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  color: var(--text);
  font: 400 0.875rem var(--font);
}
.qn-sugg-item:hover,
.qn-sugg-item:focus-visible {
  background: var(--bg-inset);
  outline: none;
}
.qn-sugg-q {
  font-weight: 600;
  font-size: 0.84375rem;
  line-height: 1.35;
}
.qn-sugg-item.is-known .qn-sugg-q::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  margin-right: 7px;
  vertical-align: 1px;
}
.qn-sugg-a {
  font-size: 0.78125rem;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* did that help? */
.qn-rate {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78125rem;
  color: var(--text-muted);
  margin-top: -4px;
}
.qn-rate-btn {
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  border-radius: 999px;
  padding: 3px 10px;
  font: 600 0.75rem var(--font);
  cursor: pointer;
}
.qn-rate-btn:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}
.qn-rate-done {
  font-style: italic;
}

/* Nod's opening line for the page */
.qn-msg-greet {
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.qn-greet-q {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.qn-greet-q .qn-chip {
  font-size: 0.78125rem;
  padding: 5px 10px;
  white-space: normal;
  text-align: left;
}

/* the return from the spin: eyes and mouth ease back together */
#qn-bot-head.is-settling #qn-eye-l,
#qn-bot-head.is-settling #qn-eye-r {
  transition: transform 0.38s cubic-bezier(0.3, 0.8, 0.3, 1);
}
#qn-bot-head.is-settling #qn-eye-r-dot {
  transition:
    transform 0.28s cubic-bezier(0.3, 0.8, 0.3, 1) 0.05s,
    opacity 0.2s ease;
}
.qn-bot #qn-lips,
.qn-bot #qn-mouth {
  transition: opacity 0.08s linear;
}
.qn-link {
  color: var(--accent-text);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* the return from the spin: eyes and mouth ease back together */
#qn-bot-head.is-settling #qn-eye-l,
#qn-bot-head.is-settling #qn-eye-r {
  transition: transform 0.38s cubic-bezier(0.3, 0.8, 0.3, 1);
}
#qn-bot-head.is-settling #qn-eye-r-dot {
  transition:
    transform 0.28s cubic-bezier(0.3, 0.8, 0.3, 1) 0.05s,
    opacity 0.2s ease;
}
.qn-bot #qn-lips,
.qn-bot #qn-mouth {
  transition: opacity 0.08s linear;
}
.qn-link {
  color: var(--accent-text);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---- appearance picker (Settings) ----
   Three submit buttons in one form: pressing one saves it. No JavaScript, so
   it works on the first paint and cannot get out of step with what is stored. */
.theme-pick {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  margin: 0 0 18px;
}
.theme-opt {
  display: block;
  text-align: left;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.theme-opt:hover {
  border-color: var(--text-faint);
}
.theme-opt.is-on {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.theme-opt b {
  display: block;
  margin: 8px 0 1px;
}
.theme-opt .small {
  display: block;
  line-height: 1.35;
}
.theme-swatch {
  display: block;
  width: 100%;
  height: 26px;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.theme-swatch-dark {
  background: linear-gradient(105deg, #0b1626 0 62%, #10203a 62% 84%, #17c96f 84% 100%);
}
.theme-swatch-light {
  background: linear-gradient(105deg, #ffffff 0 62%, #f6f8fa 62% 84%, #17c96f 84% 100%);
}
.theme-swatch-system {
  background: linear-gradient(105deg, #ffffff 0 50%, #0b1626 50% 84%, #17c96f 84% 100%);
}

/* ---- Nod's scrollbars ----
   The browser's default is a pale grey bar with arrow buttons on the ends,
   which on a navy panel reads as a piece of somebody else's software sitting
   inside ours. Same green thumb and same slim track as the filter row on the
   dashboard, so the two scrollbars in the app match each other. */
.qn-help-body,
.qn-help-ticket,
.qn-sugg {
  scrollbar-width: thin;
  scrollbar-color: var(--accent) var(--border-soft);
}
.qn-help-body::-webkit-scrollbar,
.qn-help-ticket::-webkit-scrollbar,
.qn-sugg::-webkit-scrollbar {
  width: 6px;
}
.qn-help-body::-webkit-scrollbar-track,
.qn-help-ticket::-webkit-scrollbar-track,
.qn-sugg::-webkit-scrollbar-track {
  background: var(--border-soft);
  border-radius: 999px;
}
.qn-help-body::-webkit-scrollbar-thumb,
.qn-help-ticket::-webkit-scrollbar-thumb,
.qn-sugg::-webkit-scrollbar-thumb {
  background: var(--accent);
  border-radius: 999px;
}
.qn-help-body::-webkit-scrollbar-thumb:hover,
.qn-help-ticket::-webkit-scrollbar-thumb:hover,
.qn-sugg::-webkit-scrollbar-thumb:hover {
  background: var(--accent-strong);
}
/* the little arrow buttons at each end are not part of the design */
.qn-help-body::-webkit-scrollbar-button,
.qn-help-ticket::-webkit-scrollbar-button,
.qn-sugg::-webkit-scrollbar-button {
  display: none;
  width: 0;
  height: 0;
}

/* ---- the email schedule ---- */
.sch-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 6px 0 0;
}
.sch-row {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.sch-row.is-done {
  border-left-color: var(--border);
  opacity: 0.72;
}
.sch-when {
  flex: 0 0 auto;
  min-width: 250px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sch-what {
  flex: 1 1 220px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sch-row form {
  margin: 0;
  flex: 0 0 auto;
}
.sch-add {
  max-width: 520px;
}
.sch-when-in {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.sch-tunes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px 20px;
}
.sch-tune label {
  margin-bottom: 4px;
}
.sch-tune-in {
  display: flex;
  align-items: center;
  gap: 10px;
}
.sch-tune-in input {
  width: 92px;
  flex: 0 0 auto;
}
/* ---- saved replies ----
   The picker sits under the reply box, close enough to read as part of it. */
.tmpl-pick {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 6px;
}
.tmpl-pick select {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}
.tmpl-pick a {
  flex: 0 0 auto;
  white-space: nowrap;
}
.tmpl {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin: 0 0 12px;
  background: var(--bg-raised);
}
.tmpl-top {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.tmpl-top input {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-weight: 600;
}
.tmpl-top .small {
  flex: 0 0 auto;
  white-space: nowrap;
}
.tmpl textarea {
  font-family: inherit;
  white-space: pre-wrap;
}
.tmpl-keys {
  display: grid;
  gap: 4px;
  font-size: 0.84375rem;
  color: var(--text-muted);
  border-left: 3px solid var(--border);
  padding: 2px 0 2px 12px;
  margin: 0 0 18px;
}

/* ---- the account-not-set-up card ----
   Shown on the quotes list and on any quote asking for money up front. Not
   dismissible: it is a job that is not done, and it takes itself away the
   moment the account is confirmed. Warm rather than alarming — nothing is
   broken, there is just money going the slow way round. */
/* The card is drawn round what is in it rather than across the page.
   Paragraphs are held to 66ch everywhere so they stay readable, but the card
   was a plain block and took the full width of the column — so on a wide
   screen the green ran a foot past the last word in it. */
.paycard {
  width: fit-content;
  max-width: 100%;
  border: 1px solid var(--accent);
  border-left: 4px solid var(--accent);
  background: var(--accent-tint);
  border-radius: var(--radius);
  padding: 13px 15px;
  margin: 0 0 14px;
}
.paycard > b {
  display: block;
  color: var(--text);
}
.paycard p {
  margin: 5px 0 10px;
  color: var(--text-muted);
}

/* ---- index tables ----
   A long list of short lines with nothing between them reads as one block of
   text: the eye loses which "goes to" belongs to which email. So every row
   gets a rule under it, the head gets a heavier one, and the row under the
   pointer lifts — which is also how you keep your place on a phone. */
.idx {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.idx th,
.idx td {
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border-soft);
}
.idx thead th {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.idx tbody tr:last-child td {
  border-bottom: 0;
}
.idx tbody tr:hover td {
  background: var(--bg-raised);
}
.idx td:first-child {
  width: 1%;
  white-space: nowrap;
  font-weight: 600;
}
.sch-table td:last-child {
  white-space: normal;
}
@media (max-width: 520px) {
  .sch-when {
    min-width: 0;
  }
}

/* ---- campaigns ---- */
.cmp-grid {
  display: grid;
  grid-template-columns: minmax(260px, 340px) 1fr;
  gap: 26px;
  align-items: start;
}
@media (max-width: 760px) {
  .cmp-grid {
    grid-template-columns: 1fr;
  }
}
.cmp-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cmp-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
}
.cmp-card:hover {
  border-color: var(--text-faint);
}
.cmp-card.is-open {
  border-left-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.cmp-steps {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cmp-step {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.cmp-step-when {
  flex: 0 0 auto;
  min-width: 150px;
  display: flex;
  flex-direction: column;
}
.cmp-step-what {
  flex: 1 1 200px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.cmp-step form {
  margin: 0;
}
.cmp-two {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.cmp-new,
.cmp-add,
.cmp-run {
  max-width: 520px;
}

/* ---- crowding warnings ---- */
.crowd {
  border: 1px solid var(--warn);
  border-left: 3px solid var(--warn);
  background: var(--warn-bg);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 0 0 16px;
}
.crowd.is-pending {
  border-color: var(--danger);
  border-left-color: var(--danger);
  background: var(--danger-bg);
}
.crowd-head {
  display: block;
  color: var(--text);
  margin-bottom: 8px;
}
.crowd-row {
  padding: 8px 0;
  border-top: 1px solid var(--border-soft);
}
.crowd-row:first-of-type {
  border-top: 0;
  padding-top: 0;
}
.crowd-row p {
  margin: 0;
  color: var(--text);
}
.crowd-row.is-tight p:first-child {
  font-weight: 600;
}
.crowd-acts {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.crowd-acts form {
  margin: 0;
}
.aud-note {
  display: block;
  margin-top: 2px;
}

/* ---- the referral card ---- */
.ref-card {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 18px 20px 20px;
  margin: 0 0 22px;
}
.ref-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.ref-stamp {
  width: 62px;
  height: 62px;
  border-radius: 50%;
  border: 2px dashed var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-faint);
  opacity: 0.35;
  transition:
    opacity 0.3s ease,
    color 0.3s ease,
    border-color 0.3s ease,
    background 0.3s ease;
}
.ref-stamp svg {
  width: 34px;
  height: 34px;
  display: block;
}
.ref-stamp.is-on {
  opacity: 1;
  color: var(--accent-text);
  border-style: solid;
  border-color: var(--accent);
  background: var(--accent-tint);
}
.ref-count {
  margin: 12px 0 0;
  font-size: 0.9375rem;
}
.ref-count b {
  font-size: 1.0625rem;
}
.ref-link {
  font-family: ui-monospace, monospace;
  font-size: 0.875rem;
}
.ref-closed {
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--bg-inset);
  border: 1px solid var(--border);
}
@media (max-width: 420px) {
  .ref-stamp {
    width: 52px;
    height: 52px;
  }
  .ref-stamp svg {
    width: 28px;
    height: 28px;
  }
}

/* the trader's QuoteNod number */
.acct-id {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 0 0 18px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
}
.acct-id b {
  font-family: ui-monospace, monospace;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
}

/* support desk search */
.desk-search {
  display: flex;
  gap: 8px;
  margin: 10px 0 4px;
  max-width: 560px;
}
.desk-search input {
  flex: 1 1 auto;
  margin: 0;
}
.desk-id {
  font-family: ui-monospace, monospace;
  font-weight: 600;
}
.desk-also {
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-faint);
  border-radius: var(--radius);
  background: var(--bg-raised);
  padding: 12px 14px;
  margin: 0 0 14px;
}
.desk-also-row {
  padding: 8px 0;
  border-top: 1px solid var(--border-soft);
}
.desk-also-row:first-of-type {
  border-top: 0;
}
.desk-also-row p {
  margin: 2px 0 0;
  white-space: pre-wrap;
}

/* ---- the logo uploader: a live preview of the document header ---- */
.logo-current {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  margin: 0 0 10px;
}
.logo-current img {
  max-height: 48px;
  max-width: 180px;
  display: block;
}
.logo-stage {
  margin: 14px 0 0;
  display: grid;
  gap: 12px;
}
/* the preview is white because paper is white, whatever theme the app is in */
.logo-doc {
  background: #ffffff;
  color: #12233c;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px 20px;
  box-shadow: var(--shadow-1);
}
.logo-doc-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.logo-doc-head img {
  display: block;
  object-fit: contain;
  margin-bottom: 6px;
}
.logo-doc-name {
  font-weight: 700;
  font-size: 0.9375rem;
}
.logo-doc-sub {
  font-size: 0.6875rem;
  color: #6b7e95;
}
.logo-doc-type {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6b7e95;
  flex: none;
}
.logo-doc-rule {
  height: 2px;
  background: #12233c;
  margin: 14px 0 12px;
}
.logo-doc-lines {
  display: grid;
  gap: 7px;
}
.logo-doc-lines span {
  height: 7px;
  border-radius: 3px;
  background: #eceff3;
}
.logo-doc-lines span:nth-child(2) {
  width: 76%;
}
.logo-doc-lines span:nth-child(3) {
  width: 54%;
}
.logo-verdict {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.logo-verdict p {
  margin: 0;
}
.logo-verdict p + p {
  margin-top: 4px;
}
.logo-nod {
  flex: none;
  width: 40px;
  height: 40px;
  color: var(--text);
}
.logo-nod svg {
  width: 40px;
  height: 40px;
  display: block;
}
.logo-stage[data-verdict='words-too-small'] .logo-verdict,
.logo-stage[data-verdict='low-resolution'] .logo-verdict {
  border-left-color: var(--warn);
  background: var(--warn-bg);
}
.logo-stage[data-verdict='tight'] .logo-verdict {
  border-left-color: var(--ok);
}

/* ---------- getting paid: the one status a trader needs to read ---------- */
/* Four states, one shape. The colour carries the meaning at a glance and the
   sentence underneath carries it properly; neither is load-bearing alone. */
.payout {
  margin: 10px 0 0;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.payout-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.payout-pill {
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 3px 10px;
  background: var(--border-soft);
  color: var(--text);
}
.payout-live {
  border-left-color: var(--ok);
  background: var(--ok-bg);
}
.payout-live .payout-pill {
  background: var(--ok);
  color: var(--ok-bg);
}
.payout-needs-confirm,
.payout-rejected {
  border-left-color: var(--warn);
  background: var(--warn-bg);
}
.payout-needs-confirm .payout-pill,
.payout-rejected .payout-pill {
  background: var(--warn);
  color: var(--warn-bg);
}
/* "waiting on us" is not the trader's problem to solve, so it stays calm */
.payout-waiting-on-us {
  border-left-color: var(--accent);
}

/* The confirmation reads as a thing you stop and do, not another form row. */
.payout-confirm {
  margin: 12px 0 0;
  padding: 12px 14px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
}
.payout-confirm .check-row label {
  line-height: 1.45;
}

/* ---------- the owner's portal ------------------------------------------------
   One shell for every admin page: a rail of areas down the left on a wide
   screen (drawn in the trader's rail's place), a bar across the top of the page
   that says where you are and lists the pages inside the area as tabs, and the
   page under that. Below 1000px the rail becomes a row of chips; the tabs stay. */
/* The admin pages use the width of the screen they are on, like the site:
   a tablet or a PC gets the room, capped only so a very wide monitor does
   not stretch a table across a metre of glass. The side padding grows with
   the screen, and the sticky head bleeds by the same amount. */
.admin {
  --qa-pad: clamp(20px, 3vw, 48px);
  display: block;
  max-width: 1800px;
  margin: 0;
  padding: 0 var(--qa-pad) 120px;
}
.qa-main {
  min-width: 0; /* without this a wide table stretches the grid instead of scrolling */
}
/* the pages inside supply their own .wrap; inside the shell it should not
   re-centre or re-pad, it is already in the right column */
.qa-main .wrap {
  max-width: none;
  margin: 0;
  padding: 0;
}
.qa-main > h1:first-child,
.qa-main > .wrap > h1:first-child {
  margin-top: 4px;
}

/* the bar at the top of every page: where you are, and the area's pages */
.qa-head {
  position: sticky;
  top: 0;
  z-index: 4;
  margin: 0 calc(-1 * var(--qa-pad)) 18px;
  padding: 12px var(--qa-pad) 0;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-soft);
}
.qa-crumbs {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8125rem;
  color: var(--text-muted);
  padding-bottom: 10px;
  white-space: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.qa-crumbs::-webkit-scrollbar {
  display: none;
}
.qa-crumbs a {
  color: var(--text-muted);
  text-decoration: none;
}
.qa-crumbs a:hover {
  color: var(--text);
  text-decoration: underline;
}
.qa-crumbs [aria-current='page'] {
  color: var(--text);
  font-weight: 700;
}
.qa-sep {
  color: var(--text-faint);
}
.qa-tabs {
  display: flex;
  gap: 2px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  margin-bottom: -1px;
}
.qa-tabs::-webkit-scrollbar {
  display: none;
}
.qa-tab {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 12px 11px;
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.875rem;
  text-decoration: none;
  white-space: nowrap;
  transition:
    color 0.12s ease,
    border-color 0.12s ease;
}
.qa-tab:hover {
  color: var(--text);
}
.qa-tab.is-on {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.qa-tab .qa-badge {
  min-width: 19px;
  height: 19px;
  font-size: 0.6875rem;
}

/* the rail: areas, grouped */
.qa-portal {
  margin-left: auto;
  font-size: 0.65625rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 999px;
  padding: 3px 8px;
}
.qa-find {
  margin: 0 0 12px;
}
.qa-find input {
  width: 100%;
  min-height: 38px;
  padding: 7px 12px;
  font-size: 0.875rem;
  border-radius: 10px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
}
.qa-find input:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.qa-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 0 4px;
}
.qa-grouphead {
  font-size: 0.65625rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 6px 0 4px 12px;
}
.qa-top {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.qa-link {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 12px;
  border-radius: var(--radius);
  color: var(--text-muted);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.90625rem;
  line-height: 1.2;
  border: 1px solid transparent;
  transition:
    background 0.12s ease,
    color 0.12s ease;
}
.qa-link:hover {
  background: var(--bg-raised);
  color: var(--text);
}
.qa-link.is-on {
  background: var(--accent-tint);
  border-color: var(--accent);
  color: var(--text);
}
.qa-ico {
  width: 19px;
  height: 19px;
  flex: 0 0 auto;
  opacity: 0.85;
  overflow: visible;
}
.qa-link.is-on .qa-ico {
  opacity: 1;
  color: var(--accent-strong);
}
.qa-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* the way out, set apart at the foot so it does not read as another area */
.qa-out {
  font-weight: 500;
  font-size: 0.875rem;
}
.qa-out .qa-ico {
  opacity: 0.5;
}

/* The green circle. Only ever drawn when there is something in it, so there is
   no empty-state to design and nothing that sits at zero being ignored. */
.qa-badge {
  flex: 0 0 auto;
  min-width: 21px;
  height: 21px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.75rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* the home page: queues to work down, figures, things to do */
.qa-home {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
.qa-hello {
  grid-column: 1 / -1;
}
.qa-hello h1 {
  margin: 4px 0 4px;
}
.qa-hello p {
  margin: 0;
}
.qa-alarm {
  color: var(--danger);
}
.qa-panel {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  padding: 16px 18px 18px;
}
.qa-panel h2 {
  margin: 0 0 10px;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
}
.qa-panel:first-of-type {
  grid-row: span 2;
}
.qa-queue {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.qa-queue a {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  grid-template-areas:
    'ico label count'
    'ico blurb count';
  column-gap: 12px;
  align-items: center;
  padding: 9px 12px;
  border-radius: 10px;
  text-decoration: none;
  color: var(--text);
  border: 1px solid transparent;
  transition:
    background 0.12s ease,
    border-color 0.12s ease;
}
.qa-queue a:hover {
  background: var(--bg);
  border-color: var(--border-soft);
}
.qa-queue .qa-ico {
  grid-area: ico;
  opacity: 0.6;
}
.qa-qlabel {
  grid-area: label;
  font-weight: 700;
  font-size: 0.90625rem;
}
.qa-qblurb {
  grid-area: blurb;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.qa-qcount {
  grid-area: count;
  min-width: 34px;
  height: 34px;
  padding: 0 10px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
  background: var(--bg);
  border: 1px solid var(--border-soft);
}
.qa-queue .is-waiting .qa-qcount {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}
.qa-queue .is-waiting .qa-ico {
  opacity: 1;
  color: var(--accent-strong);
}
.qa-queue li:not(.is-waiting) .qa-qlabel {
  color: var(--text-muted);
  font-weight: 600;
}
.qa-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.qa-action {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border-radius: 10px;
  border: 1px solid var(--border-soft);
  background: var(--bg);
  color: var(--text);
  font-weight: 600;
  font-size: 0.84375rem;
  text-decoration: none;
  transition:
    border-color 0.12s ease,
    background 0.12s ease;
}
.qa-action:hover {
  border-color: var(--accent);
  background: var(--accent-tint);
}
.qa-action .qa-ico {
  width: 18px;
  height: 18px;
  color: var(--accent-strong);
}

@media (min-width: 1000px) {
  .admin > .qa-rail {
    display: none;
  }
  .sr-admin .qa-out {
    padding: 9px 12px;
    border-radius: var(--radius);
  }
}
@media (max-width: 1023px) {
  .admin {
    padding: 0 0 120px;
  }
  .qa-rail {
    position: static;
    padding: 10px 0 0;
  }
  .qa-top {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 6px;
    overflow-x: auto;
    /* full-bleed so the row can run off both edges rather than stopping
       short of them, which reads as "that is all there is" */
    padding: 2px 16px 10px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scroll-padding: 0 16px;
  }
  .qa-top::-webkit-scrollbar {
    display: none;
  }
  .qa-link {
    position: relative;
    flex: 0 0 auto;
    scroll-snap-align: start;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 8px 14px;
    border: 1px solid var(--border-soft);
    background: var(--bg-raised);
    font-size: 0.875rem;
  }
  .qa-link.is-on {
    border-color: var(--accent);
    background: var(--accent-tint);
  }
  .qa-label {
    flex: 0 1 auto;
  }
  .qa-out {
    font-weight: 600;
    font-size: 0.875rem;
  }
  .qa-head {
    position: static;
    margin: 0 0 14px;
    padding: 0 16px;
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .qa-main {
    padding: 0 16px;
  }
  .qa-home {
    grid-template-columns: minmax(0, 1fr);
  }
  .qa-panel:first-of-type {
    grid-row: auto;
  }
}

@media (max-width: 420px) {
  .qa-top {
    padding-left: 12px;
    padding-right: 12px;
    scroll-padding: 0 12px;
  }
  .qa-link {
    gap: 6px;
    padding-left: 11px;
    padding-right: 11px;
    font-size: 0.8125rem;
  }
  .qa-ico {
    width: 17px;
    height: 17px;
  }
  .qa-badge {
    min-width: 18px;
    height: 18px;
    font-size: 0.6875rem;
    padding: 0 5px;
  }
  .qa-head,
  .qa-main {
    padding-left: 12px;
    padding-right: 12px;
  }
  .qa-actions {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- admin overview figures ----------
   Each one is a link to the page that shows the working behind the number,
   so the figure is the way in rather than a thing to read and then go and
   find. They are also used, as plain divs, on the Social page.          */
.qa-figs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin: 14px 0 0;
}
.qa-fig {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 12px 14px;
  background: var(--bg-raised);
}
.qa-fig b {
  display: block;
  font-size: 1.625rem;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.qa-fig span {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.qa-fig.waiting b {
  color: var(--accent-strong);
}
/* a failure is not a queue — green would read as "all good, three of them" */
.qa-fig.alarm b {
  color: var(--danger);
}
/* only the ones that are links get the affordance — a div that lifts on hover
   promises something it cannot do */
a.qa-fig {
  display: block;
  text-decoration: none;
  color: inherit;
  transition:
    border-color 0.12s ease,
    background 0.12s ease,
    transform 0.12s ease;
}
a.qa-fig:hover,
a.qa-fig:focus-visible {
  border-color: var(--accent);
  background: var(--accent-tint);
  transform: translateY(-1px);
}
a.qa-fig:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
a.qa-fig:active {
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  a.qa-fig {
    transition: none;
  }
  a.qa-fig:hover,
  a.qa-fig:focus-visible {
    transform: none;
  }
}

/* ---------- a Nod conversation, looked up by its reference ---------- */
.desk-chat {
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--bg-raised);
  padding: 13px 15px;
  margin: 6px 0 14px;
}
.desk-chat-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border-soft);
}
.desk-chat-head b {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9375rem;
}
/* Indented one side, plain the other: the shape alone says who spoke, which is
   what makes a long transcript skimmable for the moment it went wrong. */
.desk-line {
  margin-top: 11px;
}
.desk-line p {
  margin: 3px 0 0;
  white-space: pre-wrap;
  line-height: 1.5;
  font-size: 0.875rem;
}
.desk-line-who {
  font-size: 0.71875rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.desk-line-user p {
  border-left: 3px solid var(--accent);
  padding-left: 11px;
}
.desk-line-assistant {
  padding-left: 14px;
}
.desk-line-assistant p {
  color: var(--text-muted);
}
.desk-ref {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 700;
}

/* the microphone, drawn only when the browser can listen and the person is
   inner circle — a button that does nothing is worse than no button */
.qn-help-mic {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.qn-help-mic:hover {
  color: var(--text);
  background: var(--bg-raised);
}
.qn-help-mic.is-listening {
  color: var(--accent-strong);
  background: var(--accent-tint);
  animation: qn-listen 1.1s ease-in-out infinite;
}
@keyframes qn-listen {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(23, 201, 111, 0.35);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(23, 201, 111, 0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .qn-help-mic.is-listening {
    animation: none;
  }
}

/* ---------- the picture-or-video drop zone ----------
   Deliberately large: a target you have to aim at is not a drop target, and
   this is the one control on the page that decides whether a post can go to
   Instagram at all.                                                        */
.dropzone {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  min-height: 190px;
  padding: 22px;
  margin-top: 4px;
  border: 2px dashed var(--border);
  border-radius: 14px;
  background: var(--bg-raised);
  cursor: pointer;
  text-align: center;
  transition:
    border-color 0.14s ease,
    background 0.14s ease;
}
.dropzone:hover {
  border-color: var(--accent);
}
.dropzone:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* the state while a file is over it — unmistakable, because a drop that lands
   nowhere looks identical to one that worked */
.dropzone.is-over {
  border-color: var(--accent);
  border-style: solid;
  background: var(--accent-tint);
}
.dropzone.is-busy {
  opacity: 0.6;
  cursor: progress;
}
.dz-label {
  display: block;
  margin-top: 14px;
}
.dz-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--text-muted);
  pointer-events: none;
}
.dz-empty b {
  font-size: 1rem;
  color: var(--text);
}
.dz-or {
  font-size: 0.875rem;
}
.dz-hint {
  font-size: 0.78125rem;
  color: var(--text-faint);
}
.dz-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  width: 100%;
}
.dz-preview img,
.dz-preview video {
  max-width: 100%;
  max-height: 260px;
  border-radius: 10px;
  display: block;
}
.dz-swap {
  font-size: 0.78125rem;
  color: var(--text-faint);
}
.dz-busy[hidden] {
  display: none;
}
.dz-busy {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: var(--accent-strong);
  background: var(--bg-raised);
  border-radius: 12px;
}
/* the input is the mechanism, the zone is the interface */
input[type='file'].dz-input {
  position: absolute;
  left: 0;
  width: 1px;
  height: 1px;
  min-height: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

/* ---------- accounts ---------- */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
}
.qa-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.qa-table th,
.qa-table td {
  padding: 10px 14px;
  text-align: left;
  vertical-align: top;
}
.qa-table thead th {
  background: var(--bg-raised);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}
.qa-table tbody tr + tr td {
  border-top: 1px solid var(--border-soft);
}
.qa-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.qa-table .num.strong {
  font-weight: 800;
  color: var(--accent-strong);
}

/* the box around the one action that cannot be undone — red enough to be read
   as a warning, quiet enough that it is not decoration */
.danger-box {
  border: 1px solid var(--danger);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--bg-raised);
  padding: 15px 17px;
  margin: 10px 0 0;
}
.danger-box label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 5px;
}

/* ---------- failed jobs ---------- */
.qa-jobs {
  display: grid;
  gap: 10px;
  margin: 14px 0 0;
}
.qa-job {
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--danger);
  border-radius: var(--radius);
  background: var(--bg-raised);
  padding: 13px 15px;
}
.qa-job-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.qa-job-err {
  margin: 8px 0 0;
  font-size: 0.84375rem;
  line-height: 1.45;
  color: var(--danger);
  word-break: break-word;
}
/* the payload is evidence, not prose — kept readable but visibly secondary */
.qa-job-payload {
  margin: 6px 0 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  color: var(--text-faint);
  word-break: break-all;
}
.qa-job-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin: 12px 0 0;
}
.qa-job-acts {
  display: flex;
  gap: 8px;
  margin-top: 11px;
}

/* the count on the top-bar Admin link — same circle, sitting inline in text */
.nav-badge {
  margin-left: 6px;
  min-width: 18px;
  height: 18px;
  font-size: 0.6875rem;
  vertical-align: 1px;
}

/* Reply and Mark handled sit side by side — .btn-row stacks, which is right
   for a form and wrong for two small actions on a message card. */
.msg-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 10px;
}
.msg-actions > * {
  flex: 0 0 auto;
}

/* ---------- social composer ---------- */
.soc-why {
  margin: 10px 0 18px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-raised);
  padding: 10px 14px;
}
.soc-why summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.875rem;
}
.soc-why p {
  margin: 8px 0 2px;
  color: var(--text-muted);
}
.soc-picks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 4px 0 14px;
}
.soc-pick {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  padding: 8px 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.875rem;
  cursor: pointer;
  user-select: none;
}
.soc-pick input {
  width: 16px;
  height: 16px;
  margin: 0;
}
.soc-pick:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-tint);
  color: var(--text);
}

.soc-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
}
.soc-card {
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
  padding: 13px 15px;
}
.soc-card.over {
  border-left-color: var(--warn);
}
.soc-card-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.soc-card-head b {
  font-size: 1rem;
}
.soc-count {
  margin-left: auto;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-faint);
}
.soc-count.over {
  color: var(--warn);
  font-weight: 700;
}
.soc-spec {
  margin: 3px 0 8px;
  font-size: 0.75rem;
  color: var(--text-faint);
}
/* the caption is the thing being copied, so it is shown exactly as it will
   paste — line breaks and all — rather than reflowed into a paragraph */
.soc-caption {
  margin: 0;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  font:
    400 0.84375rem/1.5 ui-monospace,
    monospace;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 220px;
  overflow-y: auto;
}
.soc-fold,
.soc-bio,
.soc-warn,
.soc-note {
  margin: 8px 0 0;
  font-size: 0.78125rem;
  line-height: 1.45;
}
.soc-fold,
.soc-bio {
  color: var(--text-muted);
}
.soc-bio code {
  word-break: break-all;
}
.soc-warn {
  color: var(--warn);
}
.soc-note {
  color: var(--text-faint);
}
.soc-table td:nth-child(3),
.soc-table td:nth-child(4) {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  text-align: right;
  white-space: nowrap;
}
.soc-table th:nth-child(3),
.soc-table th:nth-child(4) {
  text-align: right;
}
/* the shared .idx rule squeezes the first column to its content, which is
   right for an id and wrong for a post title */
.soc-table td:first-child {
  width: auto;
  min-width: 220px;
}
.soc-table td:last-child,
.soc-table th:last-child {
  width: 1%;
  white-space: nowrap;
}

/* ---------- social: scheduling, publish state, per-post figures ---------- */
.soc-when {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 4px;
}
.soc-media {
  margin: 14px 0 0;
}
.soc-pubs {
  display: grid;
  gap: 8px;
}
.soc-pub {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 13px;
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  font-size: 0.90625rem;
}
.soc-pub.is-published {
  border-left-color: var(--ok);
}
.soc-pub.is-failed {
  border-left-color: var(--danger);
}
.soc-pub-status {
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.soc-pub.is-published .soc-pub-status {
  color: var(--ok);
}
.soc-pub.is-failed .soc-pub-status {
  color: var(--danger);
}
.soc-pub-err {
  flex: 1 1 100%;
  color: var(--danger);
  font-size: 0.84375rem;
}

/* one card per post — a table cannot hold six figures, a bar and three links
   without becoming something you scroll sideways to read */
.soc-posts {
  display: grid;
  gap: 12px;
}
.soc-post {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-raised);
  padding: 15px 17px;
}
.soc-post-head {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.soc-post-head h3 {
  margin: 0;
  font-size: 1.0625rem;
}
.soc-post-sub {
  margin: 4px 0 0;
  font-size: 0.875rem;
  color: var(--text-muted);
  line-height: 1.45;
  max-width: 62ch;
}
.soc-post-when {
  margin-left: auto;
  text-align: right;
  font-size: 0.8125rem;
  white-space: nowrap;
}
.soc-post-when b {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.soc-post-when span {
  color: var(--text-muted);
}

.soc-figs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 8px;
  margin: 14px 0 0;
  /* the boxes are as tall as their figure, not as tall as the card */
  align-content: start;
  align-items: start;
}
.soc-fig {
  padding: 6px 10px;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  background: var(--bg);
  min-height: 0;
}
.soc-fig b {
  display: block;
  font-size: 1.1875rem;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.soc-fig span {
  font-size: 0.71875rem;
  color: var(--text-faint);
}
.soc-fig.is-new {
  border-color: var(--accent);
}
.soc-seen {
  margin: 4px 0 0;
}
.soc-new {
  font: 700 0.71875rem var(--font, inherit);
  color: var(--accent-text);
  background: none;
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 2px 8px;
  cursor: pointer;
}
.soc-delta {
  display: block;
  font-style: normal;
  font-size: 0.71875rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.soc-delta.is-up {
  color: var(--accent-text);
}
.soc-delta.is-down {
  color: var(--danger);
}
.soc-delta.is-none {
  color: var(--text-faint);
}
/* the headline figures for a period, under "Your posts" */
.soc-kpis {
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.soc-kpis-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin: 0 0 10px;
}
.soc-kpi-periods {
  margin-left: auto;
  display: flex;
  gap: 4px;
}
.soc-kpi-periods a {
  font-size: 0.8125rem;
  font-weight: 700;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-muted);
  text-decoration: none;
}
.soc-kpi-periods a.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: #06231a;
}
.soc-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 8px;
}
.soc-kpi {
  padding: 8px 10px;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  background: var(--bg);
}
.soc-kpi-label {
  display: block;
  font-size: 0.71875rem;
  color: var(--text-faint);
}
.soc-kpi b {
  display: block;
  font-size: 1.375rem;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
/* a tile is a button: over it, a few words fade in saying where the figure
   came from; pressed, it opens the pop-up with the posts behind it */
button.soc-kpi {
  position: relative;
  display: block;
  width: 100%;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
button.soc-kpi:hover,
button.soc-kpi:focus-visible {
  border-color: var(--accent);
}
.soc-kpi-tip {
  position: absolute;
  left: 0;
  top: calc(100% + 8px);
  z-index: 30;
  display: grid;
  gap: 5px;
  width: max-content;
  min-width: 100%;
  max-width: min(280px, 86vw);
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: 0 14px 34px rgb(0 0 0 / 0.35);
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--text);
  opacity: 0;
  visibility: hidden;
  translate: 0 -4px;
  pointer-events: none;
}
.soc-kpi-grid > .soc-kpi:nth-last-child(-n + 2) .soc-kpi-tip {
  left: auto;
  right: 0;
}
button.soc-kpi:hover .soc-kpi-tip,
button.soc-kpi:focus-visible .soc-kpi-tip {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition:
    opacity 0.7s ease 0.2s,
    translate 0.7s ease 0.2s,
    visibility 0s linear 0.2s;
}
@media (prefers-reduced-motion: reduce) {
  button.soc-kpi:hover .soc-kpi-tip,
  button.soc-kpi:focus-visible .soc-kpi-tip {
    translate: none;
    transition: none;
  }
}
.soc-kpi-tip-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
}
.soc-kpi-tip-n {
  font-weight: 700;
}
.soc-kpi-tip-line {
  color: var(--text-muted);
}
.soc-kpi-tip-foot {
  padding-top: 5px;
  border-top: 1px solid var(--border-soft);
  font-size: 0.71875rem;
  color: var(--text-faint);
}
/* the followers tile under the figure tiles: one column a connected platform,
   the count on the same line as the figure tiles' */
.soc-followers {
  margin-top: 8px;
}
.soc-followers-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin-top: 4px;
}
.soc-follower {
  display: grid;
  grid-template-rows: 1.3em 2em 1.3em 1.3em;
  align-content: start;
  min-width: 0;
}
.soc-follower-name {
  font-size: 0.86em;
  color: var(--text-muted);
}
.soc-follower-when,
.soc-follower-none {
  font-size: 0.78em;
  color: var(--text-faint);
}
.soc-follower-none {
  align-self: end;
}
/* the platforms' colours in the chart: one each, the same wherever it is drawn */
:root {
  --kp-facebook: #2a78d6;
  --kp-instagram: #d55181;
  --kp-tiktok: #b26a00;
  --kp-linkedin: #6d4fd0;
  --kp-other: #6b7b8e;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --kp-facebook: #3987e5;
    --kp-instagram: #d55181;
    --kp-tiktok: #c98500;
    --kp-linkedin: #9b85ee;
    --kp-other: #7f90a6;
  }
}
:root[data-theme='dark'] {
  --kp-facebook: #3987e5;
  --kp-instagram: #d55181;
  --kp-tiktok: #c98500;
  --kp-linkedin: #9b85ee;
  --kp-other: #7f90a6;
}
.kp-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: var(--kp-other);
}
.kp-dot.is-facebook,
.kp-seg.is-facebook {
  background: var(--kp-facebook);
}
.kp-dot.is-instagram,
.kp-seg.is-instagram {
  background: var(--kp-instagram);
}
.kp-dot.is-tiktok,
.kp-seg.is-tiktok {
  background: var(--kp-tiktok);
}
.kp-dot.is-linkedin,
.kp-seg.is-linkedin {
  background: var(--kp-linkedin);
}
.kp-seg {
  display: block;
  min-width: 3px;
  height: 100%;
  border-radius: 4px;
  background: var(--kp-other);
}
.soc-kpi-pop {
  max-width: min(820px, 94vw);
}
.kp-body {
  max-height: min(72vh, 760px);
  overflow: auto;
  padding: 18px 20px 20px;
}
.kp-lead {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 0;
  color: var(--text-muted);
}
.kp-lead b {
  font-size: 2.125rem;
  line-height: 1;
  color: var(--text);
}
.kp-note {
  margin: 8px 0 0;
}
.kp-h {
  margin: 20px 0 8px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.kp-stack {
  display: flex;
  gap: 2px;
  height: 14px;
  margin: 0 0 10px;
}
.kp-stack .kp-seg {
  flex-basis: 0;
}
.kp-legend,
.kp-kinds,
.kp-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.kp-legend,
.kp-kinds {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
}
.kp-legend li,
.kp-kinds li {
  display: flex;
  align-items: baseline;
  gap: 7px;
}
.kp-legend .kp-dot {
  align-self: center;
}
.kp-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1.1fr) minmax(90px, 1fr) minmax(2.5em, auto);
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--border-soft);
}
.kp-row:first-child {
  border-top: none;
}
.kp-thumb {
  position: relative;
  display: grid;
  place-items: center;
  width: 36px;
  height: 48px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-inset);
  color: var(--text-faint);
  font-size: 0.75rem;
}
.kp-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.kp-thumb.is-film::after {
  content: '▶';
  position: absolute;
  color: #fff;
  text-shadow: 0 1px 4px rgb(0 0 0 / 0.7);
}
.kp-what {
  display: grid;
  gap: 2px;
  min-width: 0;
}
.kp-what b,
.kp-what span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kp-bar {
  display: flex;
  gap: 2px;
  height: 12px;
}
.kp-n {
  text-align: right;
}
@media (max-width: 560px) {
  .kp-row {
    grid-template-columns: 36px minmax(0, 1fr) auto;
  }
  .kp-bar {
    grid-column: 2 / span 2;
    grid-row: 2;
  }
}
.soc-alert-comments {
  margin: 0 0 10px;
  border-color: var(--accent);
}
.soc-alert-comments button {
  align-self: flex-start;
}

.soc-strength {
  margin: 14px 0 0;
}
.soc-bar {
  height: 9px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
  border: 1px solid var(--border-soft);
}
.soc-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width 0.3s ease;
}
/* no score yet reads as absent, not as zero — a full red bar would say
   "this post failed" when what it says is "we do not know yet" */
.soc-bar-none {
  display: block;
  height: 100%;
  width: 100%;
  background: repeating-linear-gradient(115deg, var(--border-soft) 0 6px, transparent 6px 12px);
}
.soc-strength-txt {
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
  margin-top: 7px;
}
.soc-strength-txt b {
  font-size: 0.875rem;
}

.soc-post-foot {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
  font-size: 0.84375rem;
}
.soc-post-foot form {
  margin: 0;
}
.soc-post-when.is-stopped b,
.soc-upload-count .is-stopped {
  color: var(--danger);
}
.soc-post-upload {
  display: block;
  margin-top: 4px;
}
.soc-stop {
  color: var(--danger);
  border-color: var(--danger);
}

/* ---------- the Social page: one screen ----------

   The page is one layout rather than a stack of sections. A header carries
   the months; under it the headline figures sit beside the way a plan comes
   in; then the month's posts run down the left with everything else — best
   times, lessons, films, sources, accounts, reviews — as cards down the
   right. It takes the whole width of the screen, and its type grows with
   the screen, because it is something to read. */
.admin:has(.soc-page) {
  max-width: none;
}
.soc-page {
  font-size: clamp(0.9375rem, 0.65rem + 0.36vw, 1.125rem);
}
.sx {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px 28px;
  align-items: start;
}
.sx > * {
  grid-column: 1 / -1;
  min-width: 0;
  margin: 0;
}
@media (min-width: 1360px) {
  .sx {
    grid-template-columns: minmax(0, 1fr) clamp(320px, 24vw, 470px);
  }
  .sx > .sx-band,
  .sx > .sx-main {
    grid-column: 1;
  }
  .sx > .sx-plans,
  .sx > .sx-rail {
    grid-column: 2;
  }
  .sx > .sx-band,
  .sx > .sx-plans {
    align-self: stretch;
  }
}

/* the header: the name of the page, the months, and the one thing to press */
.sx-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 26px;
}
.sx-title h1 {
  margin: 0;
  font-size: 1.9em;
  line-height: 1.1;
}
.sx-title p {
  margin: 4px 0 0;
  font-size: 0.92em;
}
.sx-write {
  margin-left: auto;
}
.mo-tabs {
  display: flex;
  gap: 8px 18px;
  flex-wrap: wrap;
  align-items: flex-start;
}
/* each year heads its own months */
.mo-yr {
  display: grid;
  gap: 6px;
  justify-items: start;
}
.mo-yr-head {
  display: flex;
  align-items: center;
  min-height: 1.9em;
}
.mo-yr-label {
  font-weight: 800;
  font-size: 0.85em;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  padding: 0 0.3em;
}
.mo-yr-head .mo-year-btn {
  font-size: 0.85em;
  padding: 0.3em 0.9em;
}
.mo-yr-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.mo-tab,
.mo-year-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.95em;
  padding: 0.55em 1.15em;
  border-radius: 999px;
  border: 1.5px solid var(--border);
  background: var(--bg-raised);
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
}
.mo-tab:hover,
.mo-year-btn:hover {
  color: var(--text);
  border-color: var(--accent);
}
.mo-tab.is-on,
.mo-year.is-on > .mo-year-btn {
  background: var(--accent);
  border-color: var(--accent);
  color: #06231a;
}
/* the months that do not have a tab of their own, under their year */
.mo-year {
  position: relative;
}
.mo-year-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  user-select: none;
}
.mo-year-btn::-webkit-details-marker {
  display: none;
}
.mo-year-btn::after {
  content: '';
  width: 0.42em;
  height: 0.42em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  margin-top: -0.2em;
}
.mo-year-menu {
  position: absolute;
  z-index: 6;
  top: calc(100% + 6px);
  left: 0;
  min-width: 100%;
  display: grid;
  gap: 4px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-raised);
  box-shadow: 0 14px 34px rgb(0 0 0 / 0.35);
}
.mo-year-menu .mo-tab {
  border-color: transparent;
  background: none;
  text-align: left;
  border-radius: 9px;
}
.mo-year-menu .mo-tab:hover {
  background: var(--bg);
}
.mo-year-menu .mo-tab.is-on {
  background: var(--accent);
}

/* the headline figures */
.sx-band,
.sx-card,
.sx-panel {
  border: 1px solid var(--border-soft);
  border-radius: 16px;
  background: var(--bg-raised);
}
.sx-band {
  padding: 14px 18px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sx-eyebrow,
.sx-card-title {
  margin: 0;
  font-size: 0.74em;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.sx-band .soc-kpis {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
.sx-band .soc-kpis-head {
  font-size: 1em;
  margin: 0 0 10px;
}
.sx-band .soc-kpis-head > b {
  font-size: 1.12em;
}
.sx-band .soc-kpi-periods a {
  font-size: 0.82em;
  padding: 0.3em 0.9em;
}
.sx-band .soc-kpi-grid {
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 10px;
}
.sx-band .soc-kpi {
  padding: 0.5em 0.85em 0.55em;
  border-radius: 12px;
}
.sx-band .soc-kpi-label {
  font-size: 0.78em;
  color: var(--text-muted);
}
.sx-band .soc-kpi b {
  font-size: 1.75em;
  line-height: 1.1;
}
.sx-band .soc-delta {
  font-size: 0.74em;
}
.sx-band .soc-followers {
  margin-top: 10px;
}
.sx-band .soc-extract {
  margin: 0;
  padding: 10px 0 0;
  border: 0;
  border-top: 1px solid var(--border-soft);
  border-radius: 0;
  background: none;
  align-items: center;
  gap: 8px 12px;
  font-size: 0.86em;
}
.sx-band .soc-extract > div {
  flex-direction: row;
  align-items: center;
  gap: 6px;
}
.sx-band .soc-extract input {
  width: 9.6em;
  min-height: 36px;
  padding: 4px 8px;
  font-size: 1em;
}
.sx-band .soc-extract .btn-compact {
  min-height: 36px;
}
@media (max-width: 900px) {
  .sx-band .soc-kpi-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .sx-band .soc-kpi-grid > .soc-kpi:not(:nth-child(3n)) .soc-kpi-tip {
    left: 0;
    right: auto;
  }
  .sx-band .soc-kpi-grid > .soc-kpi:nth-child(3n) .soc-kpi-tip {
    left: auto;
    right: 0;
  }
}
@media (max-width: 480px) {
  .sx-band .soc-kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .sx-band .soc-kpi-grid > .soc-kpi:nth-child(odd) .soc-kpi-tip {
    left: 0;
    right: auto;
  }
  .sx-band .soc-kpi-grid > .soc-kpi:nth-child(even) .soc-kpi-tip {
    left: auto;
    right: 0;
  }
}

/* a card in the side column */
.sx-rail {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  align-items: start;
}
@media (min-width: 1360px) {
  .sx-rail {
    grid-template-columns: minmax(0, 1fr);
  }
}
.sx-card {
  padding: 0;
  font-size: 0.9em;
  min-width: 0;
}
.sx-card > summary {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding: 13px 16px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.sx-card > summary::-webkit-details-marker {
  display: none;
}
.sx-card > summary::after {
  content: '';
  margin-left: auto;
  align-self: center;
  width: 0.5em;
  height: 0.5em;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
.sx-card[open] > summary::after {
  transform: rotate(45deg);
}
.sx-card .sx-card-title {
  font-size: 0.84em;
  color: var(--text);
}
.sx-card-note {
  font-size: 0.86em;
  color: var(--text-muted);
}
.sx-warn {
  color: #f5c945;
}
.sx-card-body {
  padding: 0 16px 16px;
  min-width: 0;
}
.sx-card-body > :first-child {
  margin-top: 0;
}
.sx-card-body h3 {
  margin: 14px 0 4px;
  font-size: 1em;
}
.sx-sum {
  margin: 0 0 12px;
  color: var(--text-muted);
  line-height: 1.5;
}
.sx-how {
  margin: 10px 0 0;
  color: var(--text-muted);
}
.sx-how > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--text-muted);
}
.sx-how p {
  margin: 8px 0 0;
  line-height: 1.5;
}
.sx-plans {
  padding: 13px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sx-plans .sx-card-title {
  color: var(--text);
  font-size: 0.76em;
}
.sx-plans .soc-planfile {
  margin: 0;
  flex: 1 1 auto;
  display: flex;
}
.sx-plans .dropzone {
  flex: 1 1 auto;
  margin: 0;
  min-height: 92px;
  background: var(--bg);
  font-size: 1.05em;
}
.sx-plan-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
}
.sx-plan-acts form {
  margin: 0;
}
/* what the cards hold, fitted to a narrow column */
.sx-card .soc-times-head,
.sx-card .soc-times-row {
  grid-template-columns: 5.6em repeat(2, minmax(0, 1fr));
  padding: 8px 10px;
  font-size: 0.95em;
}
.sx-card .soc-times.has-tiktok .soc-times-head,
.sx-card .soc-times.has-tiktok .soc-times-row {
  grid-template-columns: 5.6em repeat(3, minmax(0, 1fr));
}
@media (max-width: 760px) {
  .sx-card .soc-times.has-tiktok .soc-times-head,
  .sx-card .soc-times.has-tiktok .soc-times-row {
    gap: 6px;
  }
  .sx-card .soc-times.has-tiktok .soc-times-head > span {
    letter-spacing: 0;
    text-transform: none;
  }
}
.sx-card .soc-lessons-grid {
  grid-template-columns: minmax(0, 1fr);
  gap: 4px;
}
.sx-card .soc-lessons {
  font-size: 1em;
}
.sx-card .soc-note-form {
  margin-top: 10px;
}
.sx-card .qa-figs {
  margin: 0 0 6px;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
}
.sx-card .qa-fig {
  padding: 9px 11px;
  background: var(--bg);
}
.sx-card .qa-fig b {
  font-size: 1.5em;
}
.sx-card .empty {
  padding: 10px 0;
  text-align: left;
}
.sx-card .src-table {
  margin: 6px 0;
  background: var(--bg);
}
.sx-card .src-head,
.sx-card .src-row {
  padding: 8px 11px;
  font-size: 0.95em;
}
.sx-card .mk-sub {
  margin: 14px 0 4px;
}
.sx-card .soc-links {
  margin: 0 0 14px;
}
.sx-card .soc-link,
.sx-card .soc-bio-row,
.sx-card .soc-shelf-row,
.sx-card .soc-line {
  background: var(--bg);
}
.sx-card .soc-bios {
  margin: 8px 0 0;
}
.sx-card .soc-bio-row {
  grid-template-columns: minmax(0, 1fr) max-content;
  padding: 9px 12px;
}
.sx-card .soc-bio-row b {
  grid-column: 1 / -1;
}
.sx-card .soc-line-review {
  grid-template-columns: minmax(0, 1fr);
}
/* the films: the cover beside the name, the buttons under them; the shelf
   scrolls inside the card rather than running the column down the page */
.sx-card .soc-shelf {
  max-height: 460px;
  overflow: auto;
  margin-top: 10px;
}
.sx-card .soc-shelf-row {
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px 10px;
  font-size: 0.95em;
}
.sx-card .soc-shelf-row code {
  white-space: normal;
  word-break: break-all;
}
.sx-card .soc-shelf-acts {
  grid-column: 1 / -1;
  justify-content: flex-start;
  gap: 6px;
}
.sx-card .soc-shelf-acts .btn-compact,
.sx-card .soc-line-status .btn-compact {
  min-height: 34px;
  padding: 0 12px;
  font-size: 0.8125rem;
}
.sx-card .soc-cover {
  width: 40px;
  height: 71px;
}
.sx-card .soc-alert {
  font-size: 0.95em;
}
.sx-card .soc-sum {
  margin: 10px 0 8px;
}

/* the composer, opened from the header or from a post's Open button */
.sx-panel {
  padding: 16px 18px 18px;
}
.sx-panel[hidden] {
  display: none;
}
.sx-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 4px;
}
.sx-panel-head h2 {
  margin: 0;
  font-size: 1.35em;
}
.sx-compose {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px 28px;
  align-items: start;
}
@media (min-width: 1200px) {
  .sx-compose:has(> div + div) {
    grid-template-columns: minmax(0, 560px) minmax(0, 1fr);
  }
  .sx-compose:not(:has(> div + div)) {
    max-width: 760px;
  }
}

/* ---------- the month ---------- */
.sx-month-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin: 2px 0 12px;
}
.sx-month-head h2 {
  margin: 0;
  font-size: 1.7em;
  line-height: 1.15;
}
#month-counts {
  font-size: 0.95em;
}
#month-slot.is-loading {
  opacity: 0.5;
}
/* the plans in this month: under review, and scheduled */
.mo-plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: 10px;
  margin: 0 0 14px;
}
.mo-review {
  display: flex;
  gap: 8px 12px;
  align-items: center;
  flex-wrap: wrap;
  padding: 11px 14px;
  border: 1px solid var(--border-soft);
  border-left: 3px solid #f5c945;
  border-radius: 12px;
  background: var(--bg-raised);
}
.mo-review.mo-upload {
  border-left-color: var(--accent);
}
.mo-review > b {
  font-size: 1.05em;
}
.mo-review form {
  margin: 0;
}
.mo-review .btn-compact {
  min-height: 36px;
}
.mo-upload .is-stopped {
  color: var(--danger);
}
/* the filters as dropdowns along one row, with finding a post beside them */
.mo-filters {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  padding: 0 0 14px;
  border-bottom: 1px solid var(--border-soft);
}
.mo-f-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}
.mo-f-find {
  margin-left: auto;
  gap: 8px;
}
.mo-f {
  font: inherit;
  font-weight: 700;
  font-size: 0.82em;
  padding: 0.42em 0.95em;
  border-radius: 999px;
  border: 1.5px solid var(--border);
  background: var(--bg-raised);
  color: var(--text-muted);
  cursor: pointer;
}
.mo-f span {
  font-weight: 500;
  opacity: 0.8;
  margin-left: 2px;
}
.mo-dd {
  position: relative;
  min-width: 0;
}
.mo-dd-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.82em;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  max-width: 100%;
  min-height: 38px;
  padding: 0.42em 0.95em;
  border-radius: 999px;
  border: 1.5px solid var(--border);
  background: var(--bg-raised);
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
}
.mo-dd-btn b {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
}
.mo-dd-k {
  font-weight: 500;
}
.mo-dd-btn::after {
  content: '';
  flex: none;
  width: 0.42em;
  height: 0.42em;
  margin: -0.2em 0 0 0.2em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}
.mo-dd-btn[aria-expanded='true']::after {
  margin-top: 0.25em;
  transform: rotate(225deg);
}
.mo-dd-btn:hover,
.mo-dd-btn[aria-expanded='true'] {
  color: var(--text);
  border-color: var(--accent);
}
.mo-dd.is-set > .mo-dd-btn {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.mo-dd.is-set > .mo-dd-btn b {
  color: inherit;
}
.mo-dd-panel {
  position: absolute;
  z-index: 6;
  top: calc(100% + 6px);
  left: 0;
  min-width: max(100%, 13em);
  display: grid;
  gap: 3px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-raised);
  box-shadow: 0 14px 34px rgb(0 0 0 / 0.35);
}
.mo-dd-panel .mo-f {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  text-align: left;
  white-space: nowrap;
  min-height: 36px;
  border-color: transparent;
  background: none;
  border-radius: 9px;
}
.mo-dd-panel .mo-f:hover {
  background: var(--bg);
}
.mo-dd-sep {
  height: 1px;
  margin: 3px 4px;
  background: var(--border-soft);
}
.mo-f-clear {
  font-size: 0.86em;
  font-weight: 700;
  padding: 0 4px;
  min-height: 38px;
}
.mo-f.is-empty:not(.is-on) {
  opacity: 0.45;
}
.mo-f:hover {
  color: var(--text);
  border-color: var(--accent);
}
.mo-f.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: #06231a;
}
.mo-f.is-on.is-facebook {
  background: #5aa9ff;
  border-color: #5aa9ff;
}
.mo-f.is-on.is-instagram {
  background: #f06ba6;
  border-color: #f06ba6;
}
.mo-f.is-on.is-linkedin {
  background: #a896f5;
  border-color: #a896f5;
}
.mo-f.is-on.is-tiktok {
  background: var(--kp-tiktok);
  border-color: var(--kp-tiktok);
}
.mo-search {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  margin: 0;
}
.mo-search input {
  width: 17em;
  max-width: 46vw;
  min-height: 38px;
  padding: 5px 12px;
  font-size: 0.9em;
}
.mo-search .btn-compact,
.mo-step .btn-compact {
  min-height: 38px;
}
.mo-f-count {
  font-size: 0.86em;
  color: var(--text-muted);
  white-space: nowrap;
}
.mo-step {
  display: inline-flex;
  gap: 4px;
}
.mo-step .btn-compact {
  padding: 0 13px;
  font-size: 1.1em;
}
.mo-step .btn-compact[disabled] {
  opacity: 0.35;
  cursor: default;
}
.mo-pager {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
  margin: 20px 0 4px;
  font-size: 0.95em;
}
.mo-pager .is-on {
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--accent);
  color: #06231a;
}
.mo-pager .linklike {
  padding: 4px 10px;
}
.mo-day {
  margin-top: 22px;
}
.mo-day h3 {
  margin: 0;
  padding: 0 0 8px;
  font-size: 1.3em;
  border-bottom: 2px solid var(--border);
}
/* one post: when and where, what it says, what it brought in, what it shows */
.mo-post {
  display: grid;
  --th: 190px;
  grid-template-columns: 9.4em minmax(0, 1fr) var(--th);
  grid-template-areas:
    'meta body thumb'
    'meta figs thumb';
  grid-template-rows: auto 1fr;
  gap: 10px 1.3em;
  padding: 1.15em 0;
  border-top: 1px solid var(--border-soft);
}
.mo-day h3 + .mo-post {
  border-top: 0;
}
.mo-meta {
  grid-area: meta;
  display: flex;
  flex-direction: column;
  gap: 7px;
  align-items: flex-start;
  min-width: 0;
}
.mo-body {
  grid-area: body;
  min-width: 0;
}
.mo-figs {
  grid-area: figs;
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
  align-items: stretch;
  align-self: start;
}
.mo-th {
  grid-area: thumb;
}
/* on a very wide screen the figures stand beside the caption, two abreast */
@media (min-width: 2100px) {
  .mo-post {
    grid-template-columns: 9.4em minmax(0, 1fr) 15.5em var(--th);
    grid-template-areas: 'meta body figs thumb';
    grid-template-rows: auto;
  }
  .mo-figs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-content: start;
  }
  .mo-figs > .mo-view,
  .mo-figs > .mo-seen {
    grid-column: 1 / -1;
  }
}
.mo-plat {
  font-weight: 700;
  font-size: 0.82em;
  padding: 0.25em 0.8em;
  border-radius: 999px;
  border: 1.5px solid var(--accent);
  color: var(--accent);
  text-align: center;
}
.mo-post.p-facebook .mo-plat {
  border-color: #5aa9ff;
  color: #5aa9ff;
}
.mo-post.p-instagram .mo-plat {
  border-color: #f06ba6;
  color: #f06ba6;
}
.mo-post.p-linkedin .mo-plat {
  border-color: var(--kp-linkedin);
  color: var(--kp-linkedin);
}
.mo-post.p-tiktok .mo-plat {
  border-style: dashed;
  border-color: var(--text-muted);
  color: var(--text);
}
.mo-time {
  font-variant-numeric: tabular-nums;
  font-size: 1.12em;
  font-weight: 700;
}
.mo-from {
  font-size: 0.8em;
  line-height: 1.35;
}
.mo-state {
  font-size: 0.72em;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-faint);
}
.mo-state.s-scheduled {
  color: var(--accent);
}
.mo-state.s-stopped,
.mo-state.s-past {
  color: var(--danger);
}
.mo-state.s-posted {
  color: var(--text-muted);
}
.mo-state.s-open,
.mo-state.s-not-reviewed {
  color: #f5c945;
}
.mo-state.s-redo {
  color: #f5c945;
}
.mo-tick {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 12px 4px 5px;
  border-radius: 999px;
  border: 1.5px solid var(--border);
  background: var(--bg);
  font: inherit;
  font-size: 0.82em;
  font-weight: 700;
  color: var(--text-muted);
  cursor: pointer;
}
.mo-tick .box {
  width: 22px;
  height: 22px;
  border-radius: 7px;
  border: 1.5px solid var(--border);
  display: grid;
  place-items: center;
}
.mo-tick .box svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 9;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
}
.mo-tick.is-done {
  border-color: var(--accent);
  color: var(--accent);
}
.mo-tick.is-done .box {
  background: var(--accent);
  border-color: var(--accent);
}
.mo-tick.is-done .box svg {
  stroke: #06231a;
  opacity: 1;
}
.mo-post.s-posted .mo-body h4,
.mo-post.s-posted .mo-cap,
.mo-post.s-posted .mo-th {
  opacity: 0.62;
}
.mo-body h4 {
  margin: 0 0 3px;
  font-size: 1.22em;
  line-height: 1.25;
}
.mo-media {
  margin: 0 0 8px;
  color: var(--text-muted);
  font-size: 0.88em;
}
.mo-cap {
  margin: 0;
  max-width: 80ch;
  white-space: pre-wrap;
  font: inherit;
  line-height: 1.5;
  color: var(--text);
}
.mo-tags {
  color: var(--accent);
}
.mo-fig {
  min-width: 5.6em;
  padding: 0.45em 0.8em;
  border-radius: 10px;
  border: 1px solid var(--border-soft);
  background: var(--bg-raised);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.mo-fig b {
  font-size: 1.12em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.mo-fig span {
  font-size: 0.72em;
  color: var(--text-muted);
  white-space: nowrap;
}
.mo-fig.is-new {
  border-color: var(--accent);
}
.mo-fig.is-new span {
  color: var(--accent);
}
.mo-fig .soc-delta {
  font-size: 0.66em;
  white-space: nowrap;
}
.mo-figs.is-waiting .mo-fig {
  opacity: 0.4;
}
.mo-view {
  align-self: center;
  font-size: 0.86em;
  margin-left: 4px;
}
.mo-seen {
  align-self: center;
}
.mo-ref {
  font-size: 0.72em;
  color: var(--text-faint);
  word-break: break-all;
}
.mo-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 12px 0 0;
}
.mo-actions .btn-compact,
.mo-seen .btn-compact {
  min-height: 38px;
}
.mo-actions form,
.mo-act {
  margin: 0;
}
.mo-th {
  margin: 0;
  font-size: 0.74em;
  color: var(--text-muted);
  min-width: 0;
}
.mo-th img {
  display: block;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #0b1626;
}
.mo-th.cover img,
.mo-th.cover video {
  width: 150px;
  height: 267px;
  object-fit: cover;
}
.mo-th video {
  display: block;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #0b1626;
  pointer-events: none;
}
.mo-open {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: zoom-in;
  border-radius: 10px;
  max-width: 100%;
}
.mo-th.picture .mo-open {
  width: 100%;
}
.mo-open.is-film {
  cursor: pointer;
}
.mo-open:hover img,
.mo-open:hover video,
.mo-open:focus-visible img,
.mo-open:focus-visible video {
  border-color: var(--accent);
}
.mo-open:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.mo-open-hint {
  position: absolute;
  left: 6px;
  bottom: 6px;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(6, 11, 19, 0.82);
  color: #f6faff;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.5;
  opacity: 0;
  transition: opacity 0.12s;
}
.mo-open.is-film .mo-open-hint,
.mo-open:hover .mo-open-hint,
.mo-open:focus-visible .mo-open-hint {
  opacity: 1;
}
.mo-th.slides .mo-open-hint {
  display: none;
}
.mo-th.picture img {
  width: 100%;
  max-height: 250px;
  object-fit: cover;
}
.mo-stage {
  position: relative;
  max-width: var(--th);
}
.mo-th.slides .mo-open {
  width: 100%;
}
.mo-th.slides img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}
.mo-arrow {
  position: absolute;
  z-index: 1;
  top: 50%;
  width: 36px;
  height: 36px;
  margin-top: -18px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.45);
}
.mo-arrow.is-prev {
  left: 6px;
}
.mo-arrow.is-next {
  right: 6px;
}
.mo-arrow svg {
  display: block;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: #000;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mo-arrow:hover {
  background: var(--accent-strong);
}
.mo-arrow:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.mo-th.none {
  display: grid;
  place-items: center;
  width: 150px;
  min-height: 84px;
  align-self: start;
  border: 1px dashed var(--border);
  border-radius: 10px;
  padding: 8px;
  text-align: center;
  word-break: break-all;
}
.mo-th figcaption {
  margin-top: 5px;
}
.mo-th code {
  font-size: 0.92em;
  word-break: break-all;
}
@media (max-width: 1500px) {
  .mo-post {
    --th: 150px;
  }
  .mo-th.cover img,
  .mo-th.cover video {
    width: 124px;
    height: 220px;
  }
  .mo-th.none {
    width: 124px;
  }
}
@media (max-width: 760px) {
  .mo-post {
    --th: 190px;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      'meta'
      'body'
      'figs'
      'thumb';
  }
  .mo-meta {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .mo-f-menus,
  .mo-f-find {
    width: 100%;
    margin-left: 0;
  }
  .mo-dd {
    position: static;
    flex: 1 1 auto;
  }
  .mo-dd-btn {
    width: 100%;
  }
  .mo-dd-btn b {
    margin-right: auto;
  }
  .mo-dd-panel {
    top: auto;
    left: 0;
    right: 0;
    margin-top: 6px;
    min-width: 0;
  }
  .mo-search {
    flex: 1 1 100%;
  }
  .mo-search input {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    max-width: none;
  }
  .sx-write {
    margin-left: 0;
  }
}

/* ---------- the queue and the archive ---------- */
.soc-hide {
  margin: 0 0 12px;
  font-size: 0.875rem;
}
.soc-hide label {
  display: inline-flex;
  gap: 8px;
  align-items: center;
  cursor: pointer;
}
.soc-posts.is-hiding-scheduled .soc-post[data-state='scheduled'] {
  display: none;
}

/* ---------- stories and carousels ---------- */
.soc-format {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin: 6px 0 0;
}
.soc-slides {
  display: inline-flex;
  gap: 4px;
}
.soc-slides img {
  width: 28px;
  height: 28px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid var(--border-soft);
}
.pf-chip-format {
  background: var(--accent-soft, rgba(23, 201, 111, 0.14));
  color: var(--accent, #17c96f);
}
.pf-slides {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  width: 100%;
}
.pf-media .pf-slide {
  position: relative;
  width: 104px;
  height: 104px;
  padding: 0;
  overflow: hidden;
  border-radius: 8px;
}
.pf-media .pf-slide img {
  width: 100%;
  height: 100%;
  max-height: none;
  object-fit: cover;
  border-radius: 8px;
}
.pf-slide-n {
  position: absolute;
  left: 4px;
  bottom: 4px;
  font-size: 0.6875rem;
  line-height: 1;
  padding: 2px 5px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
}

/* ---------- finding a post or an upload ---------- */
.soc-search {
  margin: 0 0 16px;
}
.soc-search-row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.soc-search-row input {
  flex: 1 1 260px;
  min-width: 0;
}
.soc-search-count {
  margin: 6px 0 0;
}
.soc-uploads {
  margin: 0 0 18px;
}
.soc-uploads h3 {
  margin: 0 0 4px;
  font-size: 0.9375rem;
}
.soc-upload {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  padding: 10px 12px;
  margin: 8px 0 0;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
}
.soc-upload-what {
  flex: 1 1 220px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.soc-upload-count {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  color: var(--text-muted);
}
.soc-upload-act {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.soc-upload-act form {
  margin: 0;
}

/* ---------- linked accounts ---------- */
.soc-links {
  display: grid;
  gap: 8px;
  margin: 0 0 22px;
}
.soc-link {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 13px 16px;
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.soc-link.on {
  border-left-color: var(--accent);
}
.soc-bio-head {
  margin: 0 0 4px;
  font-size: 0.96875rem;
}
.soc-bios {
  display: grid;
  gap: 8px;
  margin: 10px 0 22px;
}
.soc-bio-row {
  display: grid;
  grid-template-columns: 90px minmax(0, 1fr) max-content;
  align-items: center;
  gap: 6px 12px;
  padding: 11px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.soc-bio-row code {
  font-size: 0.875rem;
  word-break: break-all;
}
.soc-bio-row > span {
  grid-column: 1 / -1;
  min-width: 0;
  line-height: 1.45;
}
@media (max-width: 599px) {
  .soc-bio-row {
    grid-template-columns: minmax(0, 1fr) max-content;
  }
  .soc-bio-row b {
    grid-column: 1 / -1;
  }
}
.soc-handles {
  display: grid;
  gap: 8px;
  margin: 10px 0 0;
}
.soc-handle {
  display: grid;
  row-gap: 4px;
}
.soc-handle label {
  margin: 0;
  font-weight: 700;
}
.soc-handle input {
  width: 100%;
  margin: 0;
}
.soc-handles button {
  justify-self: start;
}
.soc-handles-note {
  margin: 8px 0 0;
}
.soc-link > div:first-child {
  flex: 1 1 260px;
  min-width: 0;
}
.soc-link b {
  font-size: 0.96875rem;
}
.soc-link p {
  margin: 3px 0 0;
  line-height: 1.45;
}
.soc-link form {
  margin: 0;
}
.soc-link-acts {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ---------- you are here ----------------------------------------------------
   One rule for every navigation in the app. A link that points at the page you
   are on carries aria-current="page" — set on the server where the page knows
   its own section, and in the browser everywhere else — and this is the only
   place that decides what that looks like. Colour is not doing the work on its
   own: the weight changes and there is a rule under it, so it reads without
   depending on being able to tell green from grey.                            */
.topbar a[aria-current='page'],
.topbar .linklike[aria-current='page'] {
  color: var(--text);
  font-weight: 700;
  position: relative;
}
.topbar a[aria-current='page']::after {
  content: '';
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}
/* the owner's Admin link keeps its own accent when it is the current one */
.topbar a.owner-link[aria-current='page'] {
  color: var(--accent-strong);
}

/* Nod asking whether somebody wants a hand, and showing them how */
.qn-msg-nudge .qn-chip-yes {
  background: var(--accent);
  color: #0b1626;
  border-color: var(--accent);
  font-weight: 700;
}
.qn-demo {
  margin-top: 10px;
  border-radius: 12px;
  overflow: hidden;
  /* the help-centre demo is drawn for a wide page; in the panel it is shrunk */
  zoom: 0.82;
}
.qn-demo .demo {
  margin: 0;
}

/* Nod's walk-through: the tour's spotlight, with a way out on every step */
.walk-bubble {
  border-left: 4px solid var(--accent);
}
.walk-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.75rem;
  color: var(--text-faint);
  margin-bottom: 4px;
}
.walk-nod {
  font-weight: 700;
  color: var(--accent-text);
}
.walk-bubble .tour-row {
  gap: 8px;
  flex-wrap: wrap;
}

/* a card: what Nod would do, and the tap that lets it */
.qn-card {
  max-width: 100%;
  border-left: 4px solid var(--accent);
}
.qn-card ul {
  margin: 8px 0;
  padding-left: 18px;
}
.qn-card li {
  margin: 4px 0;
}
.qn-card-note {
  font-size: 0.78125rem;
  color: var(--text-faint);
  margin: 6px 0;
}
.qn-card-sure {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 2px;
  font-size: 0.8125rem;
  color: var(--warn, #b45309);
}
.qn-card-sure input {
  width: 16px;
  height: 16px;
  margin: 0;
}
.qn-card.is-done {
  border-left-color: var(--ok);
}
.qn-card.is-cancelled {
  opacity: 0.6;
}

/* the advisor: one card per thing I would do next */
.qa-advice {
  display: grid;
  gap: 12px;
  margin-top: 14px;
}
.qa-advice-card {
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--accent);
  border-radius: 10px;
  padding: 12px 14px;
  background: var(--bg-raised);
}
.qa-advice-card.u1 {
  border-left-color: var(--warn);
}
.qa-advice-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.qa-advice-top h2 {
  font-size: 1.0625rem;
  margin: 0;
  flex: 1 1 auto;
}
.qa-advice-n {
  font-weight: 700;
  color: var(--text-faint);
}
.qa-advice-when {
  font-size: 0.75rem;
  color: var(--text-faint);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  padding: 1px 8px;
}
.qa-advice-why {
  margin: 8px 0 4px;
}
.qa-advice-how {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 0.875rem;
}
.qa-advice-acts {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* ---------- long pages split into sections (Settings, Account) ---------- */
.sec-nav {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  justify-content: flex-start;
  overflow-x: auto;
  /* A scroller of our own rather than none at all.
     It was hidden on both engines, which on a phone is fine — you push the
     row with a thumb — but on a desktop with no touch screen it left the
     later sections off the end of the screen with nothing to take hold of
     and nothing to say they were there. Thin, the brand green, and only as
     wide as it needs to be. */
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
  padding: 4px 2px 10px;
  margin: 0 -16px 14px;
  padding-left: 16px;
  padding-right: 16px;
  background: var(--bg);
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.sec-nav::-webkit-scrollbar {
  height: 6px;
}
.sec-nav::-webkit-scrollbar-track {
  background: transparent;
}
.sec-nav::-webkit-scrollbar-thumb {
  background: var(--accent);
  border-radius: 999px;
}
.sec-nav::-webkit-scrollbar-thumb:hover {
  background: var(--accent-strong);
}
section.sec[hidden],
.live-wrap[hidden],
.logo-stage[hidden] {
  display: none;
}
/* centred when there is room; still scrollable when there is not */
@media (min-width: 560px) {
  .sec-nav {
    justify-content: safe center;
  }
}
.sec-chip {
  flex: 0 0 auto;
  white-space: nowrap;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--text);
  padding: 7px 14px;
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  transition:
    background 0.15s,
    border-color 0.15s;
}
.sec-chip:hover {
  border-color: var(--text-muted);
}
.sec-chip.is-on {
  background: var(--navy-900);
  border-color: var(--navy-900);
  color: #fff;
}
:root[data-theme='dark'] .sec-chip.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
section.sec {
  scroll-margin-top: 72px;
}
/* one section at a time: an anchor jump should land at the top, chips and all */
body.has-sections section.sec {
  scroll-margin-top: 320px;
}
/* a block inside a section, named in the address: clear of the bar across the top */
section.sec :target {
  scroll-margin-top: 72px;
}
section.sec > h2:first-child {
  margin-top: 8px;
}
/* without the script every section shows, separated */
body:not(.has-sections) section.sec + section.sec {
  border-top: 1px solid var(--border-soft);
  margin-top: 24px;
  padding-top: 8px;
}
.wrap-settings {
  max-width: 720px;
}
/* The Account page: a phone-width column on a phone, and on a desktop the same
   width as Settings, with the fields held to a readable width and a little
   more air between the groups. It was the phone column on every screen, which
   on a monitor was a strip down the middle with the section chips cut off. */
.wrap-account {
  max-width: 440px;
}
@media (min-width: 1000px) {
  .wrap-account {
    max-width: 880px;
  }
  .wrap-account section.sec > h2 {
    margin-top: 28px;
  }
  .wrap-account section.sec > h2:first-child {
    margin-top: 10px;
  }
  .wrap-account label {
    margin-top: 20px;
  }
  .wrap-account .check-row {
    margin-top: 18px;
  }
  .wrap-account .acct-id,
  .wrap-account input:not([type='checkbox']):not([type='radio']),
  .wrap-account textarea,
  .wrap-account select {
    max-width: 560px;
  }
  .wrap-account .actionbar {
    margin-top: 26px;
  }
}
/* Two fields side by side. The label above each one is whatever length its
   words are, and one that wraps to a second line used to push its field down
   a line below the other. Both columns are the same height — a grid stretches
   them — so letting the label take the slack drops both fields to the same
   line, whatever is written above them. */
.two-up {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  align-items: stretch;
}
.two-up > * {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.two-up > * > label {
  flex: 1 0 auto;
}
.two-up > * > label + * {
  margin-top: 0;
}
@media (max-width: 480px) {
  .two-up {
    grid-template-columns: 1fr;
  }
}

/* the live preview beside the fields */
.live-wrap {
  margin-top: 18px;
}
/* The notice that used to be fixed across the top of the preview itself,
   where it covered the head of the document — the logo and the number, which
   is the part being checked — and wrapped to two lines at that width. Above
   the frame it cannot cover anything. */
.live-note {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 6px;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.live-flag {
  flex: none;
  border-radius: 999px;
  padding: 2px 10px;
  background: var(--warn);
  color: #06231a;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
}
.live-note b {
  color: var(--text);
}
.live-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.live-kinds {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.live-kinds .btn-compact.is-on {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.live-tries {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.8125rem;
}
.live-try {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-weight: 500;
}
/* A tick box carries its own size now. "auto" was here to stop the rule that
   makes every field full width from swallowing the row, and it now collapses
   the box to a sliver instead. */
.live-try input {
  margin: 0;
}
/* An add-on already paid for: ticked, fixed, and not greyed into looking
   broken — the tick is the point, so it keeps its colour and only the
   pointer says it cannot be changed. */
.live-try.is-owned {
  cursor: default;
}
.live-try.is-owned input:disabled {
  opacity: 1;
  cursor: default;
}
#live-frame {
  width: 100%;
  height: 620px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fff;
}
@media (min-width: 1024px) {
  body.has-sections .wrap-settings {
    max-width: 1160px;
  }
  body.has-sections .sec-body {
    display: grid;
    grid-template-columns: minmax(0, 480px) minmax(0, 1fr);
    gap: 32px;
    align-items: start;
  }
  body.has-sections .live-wrap {
    position: sticky;
    top: 62px;
    margin-top: 0;
  }
  body.has-sections #live-frame {
    height: calc(100vh - 150px);
    min-height: 520px;
  }
}
.addon-nudge {
  margin-top: 14px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
}

/* the add-on cards on Account */
/* the three packages on the Account page */
.pkg-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
@media (max-width: 720px) {
  .pkg-grid {
    grid-template-columns: 1fr;
  }
}
.pkg-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  background: var(--bg);
  display: flex;
  flex-direction: column;
}
.pkg-card.is-current {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.pkg-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: baseline;
}
.pkg-head span {
  font-size: 0.8125rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.pkg-card .btn-compact,
.pkg-card .chip {
  align-self: flex-start;
  margin-top: auto;
}
.pkg-pick {
  cursor: pointer;
}
.pkg-pick:has(input:checked) {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.pkg-pick input {
  margin: 0 6px 0 0;
  vertical-align: middle;
}
.pkg-includes {
  margin: 10px 0 0;
  padding-left: 20px;
}
.pkg-includes li {
  margin: 4px 0;
}
.addon-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin-bottom: 14px;
  background: var(--bg);
  display: flex;
  flex-direction: column;
}
/* ---- the Subscription page: pictures and short reasons, columns of a size ----
   Each package and each add-on is a card of the same shape: a drawing, the
   name and price, a one-line summary and four ticked reasons, with the button
   held to the foot so the three cards in a row line up. */
.ticks {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: grid;
  gap: 7px;
  font-size: 0.875rem;
  line-height: 1.4;
}
.ticks li {
  position: relative;
  padding-left: 24px;
}
.ticks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 1px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 18%, transparent)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='m4.5 8.3 2.3 2.2 4.7-5' fill='none' stroke='%2317C96F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 16px no-repeat;
}
.pkg-icon {
  width: 22px;
  height: 22px;
  vertical-align: -5px;
  color: var(--accent);
}
.pkg-choose {
  margin-bottom: 14px;
}
.pkg-choose .pkg-card {
  padding: 16px 18px 18px;
}
.pkg-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.pkg-top .pkg-icon {
  width: 44px;
  height: 44px;
  padding: 10px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  box-sizing: border-box;
}
.pkg-top input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--accent);
}
.pkg-name {
  margin-top: 12px;
  font-size: 1.125rem;
}
.pkg-price {
  color: var(--text-muted);
  font-size: 0.875rem;
}
.pkg-price b {
  color: var(--text);
  font-size: 1.5rem;
  letter-spacing: -0.02em;
}
.pkg-price small {
  display: block;
  font-size: 0.78125rem;
}
.addon-art {
  display: block;
  width: 100%;
  height: 92px;
  margin: 0 0 12px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 8%, var(--bg-raised));
}
.art-paper {
  fill: var(--bg);
  stroke: var(--border);
  stroke-width: 1.5;
}
.art-line {
  fill: var(--border);
}
.art-brand,
.art-after {
  fill: #17c96f;
}
.art-before {
  fill: var(--border);
}
.art-tag {
  fill: var(--border);
  opacity: 0.7;
}
.art-strike,
.art-sig,
.art-share-arrow {
  fill: none;
  stroke: #17c96f;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.art-strike {
  stroke: #e5484d;
}
.art-pen {
  fill: var(--text-muted);
}
.art-heart {
  fill: #e5484d;
}
.art-share {
  fill: color-mix(in srgb, var(--accent) 16%, transparent);
}
.addon-blurb {
  margin: 4px 0 0;
}
.addon-card .addon-actions {
  margin-top: auto;
  padding-top: 16px;
}
.addon-card .addon-actions .btn {
  padding: 0 20px;
  min-height: 48px;
  font-size: 1rem;
}
.addon-order > summary {
  list-style: none;
  cursor: pointer;
  width: auto;
  display: inline-flex;
}
.addon-order > summary::-webkit-details-marker {
  display: none;
}
.addon-order[open] > summary {
  display: none;
}
.bill-trust {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.bill-trust li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.bill-trust svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.addon-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: flex-start;
}
.addon-price {
  text-align: right;
  white-space: nowrap;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  font-size: 0.875rem;
}
.addon-pill {
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 3px 9px;
  background: var(--border-soft);
  color: var(--text);
}
.addon-pill.is-on {
  background: var(--ok-bg);
  color: var(--ok);
}
.addon-pill.is-wait {
  background: var(--warn-bg);
  color: var(--warn);
}
.addon-pill.is-off {
  color: var(--text-muted);
}
.addon-wait {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--warn-bg);
  border-left: 3px solid var(--warn);
}
.addon-actions {
  margin-top: 12px;
}
.addon-actions form {
  margin: 0;
}
.addon-actions .btn,
.addon-actions .btn-quiet {
  width: auto;
}

/* the customisation queue */
/* Where a quote stands, as an edge down the side of its card. Green once it
   is invoiced or signed, amber while the customer is looking, red when they
   have asked for something. A quote that has simply been sent keeps the plain
   card: "sent" is not news, it is the normal state of a quote. */
.quote-card {
  position: relative;
}
.quote-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  background: transparent;
}
.quote-card.q-done::before {
  background: var(--ok);
}
.quote-card.q-waiting::before {
  background: var(--warn);
}
.quote-card.q-needs::before {
  background: var(--danger);
}
.quote-card.gone::before {
  background: transparent;
}

.qcard {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--bg);
}
.qcard.is-late {
  border-color: var(--warn);
}
.qcard-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  align-items: baseline;
}
.qcard-late {
  color: var(--warn);
  font-weight: 700;
}
.qcard-body {
  display: flex;
  gap: 14px;
  margin-top: 10px;
  align-items: flex-start;
}
.qcard-logo {
  width: 96px;
  height: 64px;
  object-fit: contain;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: #fff;
  flex: 0 0 auto;
}
.qcard-nologo {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-raised);
}
.qcard-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 12px;
  margin: 0;
  font-size: 0.875rem;
}
.qcard-facts dt {
  color: var(--text-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  align-self: baseline;
}
.qcard-facts dd {
  margin: 0;
}
.qcard-note {
  white-space: pre-wrap;
  background: var(--bg-raised);
  border-radius: 6px;
  padding: 4px 8px;
}
.sig-upload {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border-soft);
}

/* the desk is behind: said before the message is written, not after */
.busy-note {
  margin: 14px 0;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--warn-bg);
  border-left: 3px solid var(--warn);
}
.busy-note b {
  display: block;
  margin-bottom: 4px;
}
.busy-note p {
  margin: 6px 0 0;
  font-size: 0.90625rem;
}
.busy-pop {
  max-width: 440px;
  width: calc(100% - 32px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg);
  color: var(--text);
  padding: 20px 22px;
  box-shadow: 0 12px 40px rgb(11 22 38 / 0.3);
}
.busy-pop::backdrop {
  background: rgb(11 22 38 / 0.55);
}
.busy-pop h2 {
  margin: 0 0 8px;
  font-size: 1.1875rem;
}
.busy-pop p {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 0.9375rem;
}
.busy-pop form {
  margin: 14px 0 0;
}
.pl-contact-wait {
  margin: 10px 0 0;
  font-size: 0.875rem;
  opacity: 0.75;
}
.pl-contact-busy {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgb(255 201 61 / 0.14);
  border-left: 3px solid #ffc93d;
  font-size: 0.90625rem;
}

/* a post from a plan, still owed its video */
.soc-waiting {
  margin: 6px 0 0;
  font-size: 0.8125rem;
  color: var(--warn);
}
.soc-waiting b {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-weight: 600;
}

/* Nod reading a plan file */
.qn-msg-reading {
  color: var(--text-muted);
  font-style: italic;
}
.qn-msg-reading::after {
  content: '';
  display: inline-block;
  width: 1.2em;
  text-align: left;
  animation: qn-dots 1.2s steps(4, end) infinite;
}
@keyframes qn-dots {
  0% {
    content: '';
  }
  25% {
    content: '.';
  }
  50% {
    content: '..';
  }
  75% {
    content: '...';
  }
}
.qn-plan-choices {
  flex-wrap: wrap;
}
.qn-plan-name {
  display: flex;
  gap: 8px;
  margin: 8px 0 4px;
}
.qn-plan-name input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 36px;
  padding: 6px 10px;
  font-size: 0.875rem;
}
.qn-msg-plan.is-done p:first-child::before {
  content: '✓ ';
  color: var(--ok);
}
.qn-msg-plan.is-cancelled {
  opacity: 0.6;
}
@media (prefers-reduced-motion: reduce) {
  .qn-msg-reading::after {
    content: '…';
    animation: none;
  }
}

/* account support: what is hidden, said plainly on the page */
.redact-note {
  margin: 10px 0 16px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--bg-raised);
  border-left: 3px solid var(--accent);
  font-size: 0.875rem;
  color: var(--text-muted);
}
.sup-facts {
  margin: 14px 0 0;
  max-width: 520px;
}
.idx-search {
  margin-top: 14px;
  max-width: 520px;
}
.idx-search .btn-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.idx-search input[type='search'] {
  flex: 1 1 auto;
  min-width: 0;
}

/* account support: the form, with their document beside it */
.sup-preview iframe {
  width: 100%;
  height: 620px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #eceff3;
}
.sup-preview {
  margin-top: 20px;
}
@media (min-width: 1100px) {
  .sup-body {
    display: grid;
    grid-template-columns: minmax(0, 460px) minmax(0, 1fr);
    gap: 28px;
    align-items: start;
  }
  .sup-preview {
    position: sticky;
    top: 62px;
    margin-top: 0;
  }
  .sup-preview iframe {
    height: calc(100vh - 140px);
    min-height: 520px;
  }
}

/* account support: cancelling, refunding, and the notes nobody else reads */
.sup-cancel {
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.sup-cancel input[type='text'] {
  width: 100%;
}
.sup-closing {
  margin: 14px 0 16px;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--bg-raised);
  border-left: 3px solid var(--warn, #e0a800);
}
.sup-refund {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.sup-refund input[name='amount'] {
  width: 90px;
}
.sup-refund input[name='reason'] {
  flex: 1 1 140px;
  min-width: 120px;
}
.sup-refund-log {
  list-style: none;
  padding: 0;
  margin: 10px 0 0;
}
.sup-refund-log li {
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
}
.sup-props,
.sup-notes {
  list-style: none;
  padding: 0;
  margin: 0;
}
.sup-prop,
.sup-notes li {
  margin: 0 0 12px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
/* waiting on somebody is the one state worth spotting from across the page */
.sup-prop-waiting {
  border-left: 3px solid var(--accent);
}
.sup-prop-failed {
  border-left: 3px solid var(--danger, #d64545);
}
.sup-prop-top {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: space-between;
  align-items: baseline;
}
.sup-prop-lines {
  margin: 6px 0 8px;
  padding-left: 18px;
  font-size: 0.875rem;
}
.sup-prop form {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.sup-notes textarea {
  width: 100%;
}

/* the page a trader lands on from a confirm email */
.confirm-lines {
  margin: 16px 0;
  padding: 14px 18px 14px 34px;
  border-radius: var(--radius);
  background: var(--bg-raised);
  border-left: 3px solid var(--accent);
}
.confirm-lines li {
  margin: 4px 0;
}
.confirm-why {
  margin: 0 0 18px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--bg-raised);
}
/* the two answers are the same weight on purpose: a "yes" that is easier to
   press than a "no" is not really a question */
.confirm-answer {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 20px;
}
.confirm-answer .btn,
.confirm-answer .btn-quiet {
  flex: 1 1 180px;
  text-align: center;
}
.sup-notes .btn-row {
  display: flex;
  flex-direction: row;
  gap: 8px;
  margin-top: 8px;
}
.sup-notes .btn-row button {
  flex: 0 0 auto;
}

/* ---- discounts ---- */
.founding-note {
  margin: 14px 0 18px;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--bg-raised);
  border-left: 3px solid var(--accent);
  font-size: 0.875rem;
}
.disc-new {
  margin-top: 4px;
}
.disc-row {
  display: grid;
  gap: 12px;
  margin-top: 12px;
}
@media (min-width: 720px) {
  .disc-row {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.disc-row input,
.disc-row select {
  width: 100%;
}
.code-list {
  list-style: none;
  padding: 0;
  margin: 12px 0 0;
}
.code-list li {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.code-list code {
  font-size: 1rem;
  letter-spacing: 0.06em;
}
/* The preview runs the full width at the foot of the page. A 600px-wide
   email squeezed into a side column is a scrollbar inside a scrollbar; read
   underneath at full width it is simply the email. */
.disc-preview iframe {
  display: block;
  width: 100%;
  height: 700px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #eceff3;
}
@media (max-width: 700px) {
  .disc-preview iframe {
    height: 560px;
  }
}
/* the two buttons that act on the form above them, outside the collapsibles
   so they cannot be folded away from the thing they act on */
.disc-actions {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 16px 0 0;
}
.disc-actions .btn,
.disc-actions .btn-compact {
  flex: 0 0 auto;
  width: auto;
}

/* the discount code box on the billing page */
.code-box {
  margin: 16px 0 0;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.code-box input[type='text'] {
  flex: 1 1 auto;
  min-width: 0;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* ---- proving the payout account ---- */
.proof {
  margin: 14px 0 0;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  border-left: 3px solid var(--accent);
}
.proof-done {
  border-left-color: var(--accent);
}
.proof-failed {
  border-left-color: var(--danger, #d64545);
}
.proof-title {
  margin: 0 0 8px;
}
.proof-steps {
  margin: 0 0 12px;
  padding-left: 20px;
  font-size: 0.875rem;
  line-height: 1.6;
}
.proof-steps li {
  margin: 0 0 5px;
}
.proof-ref {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--bg);
  border: 1px dashed var(--border);
}
.proof-ref code {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: 0.1em;
}
.proof-wait {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 0.875rem;
}
/* the spinner is not decoration: it is what separates "waiting on your bank"
   from "this page is broken", which look identical without it */
.proof-spin {
  flex: none;
  width: 16px;
  height: 16px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: proof-spin 0.9s linear infinite;
}
@keyframes proof-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .proof-spin {
    animation-duration: 3s;
  }
}
.payout-needs-proof .payout-pill,
.payout-proving .payout-pill {
  background: var(--bg-raised);
}
.bank-check {
  margin: 0 0 16px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.bank-check-top {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: baseline;
}
.bank-check-form input[type='text'] {
  width: 100%;
}
.reveal {
  margin: 14px 0 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.reveal input[name='why'] {
  flex: 1 1 220px;
  min-width: 0;
}

/* ---- Accounting -------------------------------------------------------- */
/* Stat tiles, the VAT gauge and the money tables. Numbers use tabular figures
   so columns of pounds line up on the decimal point rather than drifting. */

.acc-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin: 16px 0;
}
.acc-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.acc-tile-label {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.acc-tile-value {
  font-size: 1.625rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.acc-tile-note {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.acc-note {
  color: var(--text-muted);
  font-size: 0.9375rem;
  max-width: 68ch;
  margin: 8px 0;
}
.acc-next {
  padding: 12px 16px;
  border-left: 4px solid var(--accent);
  background: var(--bg-raised);
  border-radius: var(--radius);
}

.acc-table {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0;
  font-size: 0.9375rem;
}
.acc-table th,
.acc-table td {
  text-align: left;
  padding: 8px 12px 8px 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.acc-table th {
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}
.acc-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.acc-table tr.is-overdue td {
  background: color-mix(in srgb, var(--danger) 8%, transparent);
}
.acc-table tr.is-soon td {
  background: color-mix(in srgb, var(--warn) 8%, transparent);
}
.acc-table .mono {
  font-family: Consolas, Menlo, monospace;
}

/* A table with more columns than a phone is wide scrolls inside itself rather
   than pushing the whole page sideways. */
.acc-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}
.acc-scroll > .acc-table {
  min-width: 34rem;
}

/* The fetch timings in Mail settings: six narrow columns that fit a phone
   when the headings are not shouted and the gaps are smaller, and scroll
   inside themselves rather than push the page sideways on anything smaller. */
.acc-fit {
  max-width: 100%;
  overflow-x: auto;
}
@media (max-width: 560px) {
  .acc-timings th {
    font-size: 0.6875rem;
    letter-spacing: 0;
  }
  .acc-timings th,
  .acc-timings td {
    padding: 7px 6px 7px 0;
    white-space: nowrap;
  }
  .acc-timings td.small {
    font-size: 0.78rem;
  }
}

/* People, dividends and payments.
   The person chips are the top of the Salary and dividends page: five taps
   before anybody has to type anything. */
.acc-people {
  margin: 12px 0 20px;
}
.acc-person-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}
.acc-person {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  text-decoration: none;
  color: inherit;
  min-width: 120px;
}
.acc-person.is-on {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.acc-person-find {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
}
.acc-person-find input {
  max-width: 22ch;
}

.acc-slip {
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  margin: 16px 0 24px;
}

.acc-table tr.is-former td {
  opacity: 0.6;
}

/* A declared dividend's paperwork, shown as the fixed text it is. */
.acc-doc {
  margin: 24px 0;
}
.acc-doc-text {
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  font-family: Consolas, Menlo, monospace;
  font-size: 0.8125rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-x: auto;
}

/* Salary and dividends is four sections in one page, so only the one being
   worked in is expanded. */
.acc-sec {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  margin: 12px 0;
}
.acc-sec > summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  padding: 14px 16px;
  cursor: pointer;
  list-style: none;
  font-size: 1.0625rem;
}
.acc-sec > summary::-webkit-details-marker {
  display: none;
}
.acc-sec > summary::before {
  content: '\203A';
  display: inline-block;
  transition: transform 0.15s ease;
  color: var(--text-muted);
}
.acc-sec[open] > summary::before {
  transform: rotate(90deg);
}
.acc-sec[open] > summary {
  border-bottom: 1px solid var(--border);
}
.acc-sec-body {
  padding: 4px 16px 18px;
}
.acc-sec-body > h2:first-child {
  margin-top: 8px;
}

.acc-hints {
  max-width: 68ch;
  padding-left: 1.2rem;
  color: var(--text-muted);
  font-size: 0.9375rem;
}
.acc-hints li {
  margin: 8px 0;
}

.acc-readiness-none {
  border-left: 4px solid var(--danger);
  padding-left: 12px;
}
.acc-readiness-tight {
  border-left: 4px solid var(--warn);
  padding-left: 12px;
}
.acc-readiness-ready {
  border-left: 4px solid var(--accent);
  padding-left: 12px;
}

.acc-gauge-track {
  height: 10px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
}
.acc-gauge-track > i {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width 0.3s ease;
}
.acc-gauge-track > i.is-over {
  background: var(--danger);
}
@media (prefers-reduced-motion: reduce) {
  .acc-gauge-track > i {
    transition: none;
  }
}

/* The funnel charts. Series colours come through custom properties so one
   piece of markup serves both themes; they were checked for colour-blind
   separation against each surface rather than picked by eye. */
.qc {
  margin: 24px 0;
  max-width: 100%;
  overflow-x: auto;
}
.qc-title {
  font-weight: 600;
  margin-bottom: 8px;
}
.qc svg {
  width: 100%;
  height: auto;
  max-width: 640px;
}
.qc-grid {
  stroke: var(--border);
  stroke-width: 1;
}
.qc-axis {
  fill: var(--text-muted);
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
}
.qc-tip {
  fill: var(--text);
  font-size: 0.75rem;
  font-weight: 600;
}
.qc-dot {
  stroke: var(--bg);
  stroke-width: 2;
}

/* The figure sets its light-mode series colours inline, so it renders correctly
   on its own. Only !important outranks an inline custom property, which is why
   it is used here: without it a dark viewer would get the light palette. Both
   sets were validated against their own surface for colour-blind separation. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .qc {
    --qc-0: #4f90d0 !important;
    --qc-1: #d95f5f !important;
  }
}
:root[data-theme='dark'] .qc {
  --qc-0: #4f90d0 !important;
  --qc-1: #d95f5f !important;
}

/* ---------- the inbox ----------
   Three panes on a desktop, one at a time on a phone. The breakpoint is where
   a reading pane stops being readable rather than a device width. */
/* The mail screen owns the whole viewport: the app's navigation is drawn as
   part of it, and each pane scrolls inside itself so the page never does. */
body.mail-app {
  margin: 0;
  padding: 0;
  overflow: hidden;
}
.mail-shell {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* Room for the scrollbar is kept whether or not one is showing. Without it a
   column that grows past the bottom of its scroller loses the width of the
   bar, rewraps, comes back under the bottom, loses the bar again — and the
   whole thing shudders, most visibly at the foot of a message where the
   signature sits.

   Named one at a time rather than with a star. A gutter is reserved on
   anything that clips, whether or not a scrollbar could ever appear in it, so
   the old rule charged the width of a bar to the shell, then again to the
   panes, then again to the list — three gutters deep on a screen with one
   scrollbar in it. On a phone that is an eighth of the width gone and the
   list sitting off to the left of its own window. These four are the only
   things in here that scroll. */
.ib-rail,
.ib-list,
.ib-read,
.mail-page {
  scrollbar-gutter: stable;
}
/* Whatever the last thing in the shell is — the three panes, or a page that
   scrolls — takes the room that is left; everything above it takes its own.
   A flash message between the ribbon and the panes is then a line, not a
   third of the screen. */
.mail-shell > .ib-panes,
.mail-shell > .mail-page {
  flex: 1 1 auto;
  min-height: 0;
}
.mail-shell > .mail-flash,
.mail-shell > .mail-compose-row {
  flex: 0 0 auto;
}
.mail-top {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-raised);
}
.mail-mark {
  display: flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: inherit;
  flex: 0 0 auto;
}
.mail-links {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  flex: 1 1 auto;
  font-size: 0.9375rem;
}
/* `display: flex` on the class outranks the browser's own [hidden] rule, so
   the fold has to be spelled out or the menu never folds. */
.mail-links[hidden] {
  display: none;
}
/* The dash between Help and Home: the mail tabs on one side of it, the rest
   of QuoteNod on the other. It is inside the folding part, so it is only
   there when the rest is. */
.mail-links-rule {
  color: var(--text-muted);
  opacity: 0.6;
  user-select: none;
}
.mail-links a {
  text-decoration: none;
  color: var(--text-muted);
}
.mail-links a.is-on {
  color: var(--accent-text);
  border-bottom: 2px solid var(--accent);
}
.mail-out {
  margin: 0 0 0 auto;
  flex: 0 0 auto;
}
.mail-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
}
.mail-tools h1 {
  margin: 0;
  font-size: 1.25rem;
}
.mail-tools form {
  margin: 0;
}
.mail-tools-spacer {
  flex: 1 1 auto;
}
/* The toolbar's buttons sit side by side. `.btn-quiet` is a full-width block
   everywhere else in the app, which here would give each one its own row. */
.mail-tools .btn-quiet,
.mail-tools button {
  display: inline-flex;
  align-items: center;
  width: auto;
  margin: 0;
  white-space: nowrap;
}
/* ---------- the animated background ----------
   Streaks of light falling, the way rain runs down a window, in the company
   colours. Two layers moving at different speeds so the pattern never visibly
   repeats, both faint enough to sit behind text, and each pane paints its own
   near-opaque ground over it — so it lives in the gaps between panes and the
   empty reading pane, and is gone the moment anything is on top of it. Pure
   CSS: no canvas, no script, no frames to drop. Off entirely for anybody who
   has asked their system for less motion. */
.mail-shell {
  position: relative;
  isolation: isolate;
  background: linear-gradient(
    160deg,
    color-mix(in srgb, var(--bg) 80%, #000) 0%,
    color-mix(in srgb, var(--bg) 82%, #1d4ed8) 55%,
    color-mix(in srgb, var(--bg) 84%, var(--accent)) 100%
  );
}
.mail-shell::before,
.mail-shell::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: -1;
  pointer-events: none;
  background-repeat: repeat;
  /* The mask is what turns continuous lines into falling streaks: a line is
     visible only inside a soft band, and the band travels down. */
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
}
.mail-shell::before {
  top: -420px;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0 37px,
    rgba(23, 201, 111, 0.55) 37px 39px,
    transparent 39px 71px,
    rgba(96, 165, 250, 0.5) 71px 73px,
    transparent 73px 113px,
    rgba(148, 163, 184, 0.45) 113px 115px,
    transparent 115px 160px
  );
  background-size: 160px 100%;
  -webkit-mask-image: repeating-linear-gradient(
    180deg,
    transparent 0 120px,
    #000 200px 260px,
    transparent 300px 420px
  );
  mask-image: repeating-linear-gradient(
    180deg,
    transparent 0 120px,
    #000 200px 260px,
    transparent 300px 420px
  );
  -webkit-mask-size: 100% 420px;
  mask-size: 100% 420px;
  opacity: 0.32;
  animation: mail-rain-a 9s linear infinite;
}
.mail-shell::after {
  top: -300px;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0 53px,
    rgba(23, 201, 111, 0.4) 53px 54px,
    transparent 54px 97px,
    rgba(96, 165, 250, 0.4) 97px 98px,
    transparent 98px 141px,
    rgba(148, 163, 184, 0.35) 141px 142px,
    transparent 142px 200px
  );
  background-size: 200px 100%;
  -webkit-mask-image: repeating-linear-gradient(
    180deg,
    transparent 0 60px,
    #000 140px 180px,
    transparent 220px 300px
  );
  mask-image: repeating-linear-gradient(
    180deg,
    transparent 0 60px,
    #000 140px 180px,
    transparent 220px 300px
  );
  -webkit-mask-size: 100% 300px;
  mask-size: 100% 300px;
  opacity: 0.22;
  animation: mail-rain-b 14s linear infinite;
}
/* Each layer moves by exactly one period of its own mask, so the end of a
   loop is pixel-identical to its start and the join is never seen. */
@keyframes mail-rain-a {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(420px);
  }
}
@keyframes mail-rain-b {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(300px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .mail-shell::before,
  .mail-shell::after {
    animation: none;
  }
}
/* Every surface with content on it is solid enough to read through, and no
   more: the background is a texture in the gaps, never behind a word. */
.mail-top,
.mail-ribbon,
.ib-rail,
.ib-list,
.ib-read,
.ib-read article,
.mail-page {
  background: color-mix(in srgb, color-mix(in srgb, var(--bg) 88%, #000) 94%, transparent);
}
/* With nothing open the reading pane is still a panel, like the other two,
   with its one line in the middle of it rather than the background showing
   through and the words lost in its top corner. */
.ib-read:not(:has(article)) {
  display: grid;
  place-items: center;
}
.ib-read .ib-empty {
  margin: 0;
  color: var(--text-muted);
}

/* ---------- the tabs and the ribbon ---------- */
.mail-mark {
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: inherit;
  width: auto;
  margin: 0;
}
/* The QuoteNod tick beside the wordmark, as on every other screen. It had no
   size of its own here, so it collapsed to nothing and the header read as
   text alone. */
.mail-mark .mark {
  display: block;
  flex: none;
  width: 24px;
  height: 24px;
  color: var(--text);
}
.mail-mark .mark svg {
  display: block;
  width: 100%;
  height: 100%;
}
.mail-wordmark {
  display: flex;
  flex-direction: column;
  line-height: 1;
  gap: 2px;
  text-align: left;
}
.mail-word-line {
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.mail-word-mail {
  color: var(--accent-text);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* The build number, in the app and nowhere else.
   Quieter than the word beside it on purpose: it is there to be read when
   somebody asks which version you are on, not to be part of the logo. */
.mail-ver {
  color: var(--accent);
  font-weight: 600;
  font-size: 0.6875rem;
  letter-spacing: 0.02em;
  opacity: 0.72;
  font-variant-numeric: tabular-nums;
}
/* Ask Nod, in the ribbon beside Settings. A ribbon button like the others,
   outlined in the accent so it reads as the one thing there that does
   something rather than opening a menu. */
.rb-nod {
  border-color: var(--accent);
  font-weight: 600;
}
.rb-nod .mi {
  color: var(--accent);
}
.rb-nod:hover {
  background: var(--accent-tint);
  border-color: var(--accent);
}

/* The box the Ask Nod button opens. */
.mail-ask-scrim {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgb(0 0 0 / 45%);
}
.mail-ask-scrim[hidden],
.mail-ask-pop[hidden] {
  display: none;
}
/* Nothing behind the sheet scrolls while it is open, or a thumb aiming for
   the text box drags the inbox instead. */
body.ask-open {
  overflow: hidden;
}
.mail-ask-pop {
  position: fixed;
  z-index: 71;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(420px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  padding: 18px 20px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow: 0 18px 50px rgb(0 0 0 / 45%);
  text-align: left;
}
.mail-ask-face {
  display: flex;
  justify-content: center;
  color: var(--text);
}
/* He hovers. A face that holds perfectly still reads as a picture of a face,
   and this one is meant to look like somebody waiting for you to say something. */
.mail-ask-face svg {
  display: block;
  overflow: visible;
  animation: qn-float 4s ease-in-out infinite;
}
.mail-ask-pop label {
  margin-top: 6px;
}
.mail-ask-pop textarea {
  min-height: 78px;
}
.mail-ask-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 14px;
}
.mail-ask-row .btn,
.mail-ask-row .btn-quiet {
  width: auto;
  min-height: 44px;
  margin: 0;
  padding: 8px 20px;
}
@media (prefers-reduced-motion: reduce) {
  .mail-ask-face svg {
    animation: none;
  }
}
/* On a phone the box is a sheet at the bottom rather than a card in the
   middle, and it rides on top of the keyboard instead of behind it.
   --ask-keys is how much of the screen the keyboard has taken, measured by
   the script from the visual viewport; with no script it is zero and the
   sheet simply sits at the bottom, which is where it belongs anyway. */
@media (max-width: 700px) {
  .mail-ask-pop {
    top: auto;
    left: 10px;
    right: 10px;
    bottom: calc(var(--ask-keys, 0px) + 10px);
    width: auto;
    transform: none;
    max-height: calc(var(--ask-room, 100vh) - 20px);
    border-radius: var(--radius-lg);
  }
  .mail-ask-face svg {
    width: 60px;
    height: 60px;
  }
}
/* The compose link's second home, under the strip and only on a phone. */
.mail-compose-row {
  display: none;
}
.mail-ribbon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.rb-form {
  margin: 0;
  display: inline-flex;
}
.rb-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  text-decoration: none;
  font: inherit;
  font-size: 0.9375rem;
  cursor: pointer;
  white-space: nowrap;
  width: auto;
  margin: 0;
}
.rb-btn:hover:not([disabled]) {
  background: var(--bg-raised);
  border-color: var(--border);
}
.rb-btn[disabled] {
  color: var(--text-muted);
  opacity: 0.5;
  cursor: default;
}
.rb-btn.is-primary {
  background: var(--accent);
  color: #06301b;
  font-weight: 600;
}
.rb-btn.is-primary:hover {
  background: var(--accent-strong);
}
.rb-split {
  width: 1px;
  height: 22px;
  background: var(--border);
  margin: 0 4px;
}
.rb-spacer {
  flex: 1 1 auto;
}
.rb-synced {
  white-space: nowrap;
}
/* ---------- icons ----------
   overflow is visible deliberately. An inline SVG clips to its own box by
   default, and on a machine with no graphics driver — where Windows falls
   back to its Basic Render Driver — that clip is computed wrongly once the
   icon is scaled below a whole pixel boundary, and the whole icon is dropped
   rather than trimmed. Measured on such a machine: at 15px an icon drew
   nothing at any stroke width, and the same icon with this one line drew
   normally. Nothing in these paths reaches the edge of the viewBox, so
   turning the clip off changes nothing anywhere else. */
.mi {
  width: 16px;
  height: 16px;
  vertical-align: -3px;
  flex: 0 0 auto;
  overflow: visible;
}
.ib-folder-icon .mi {
  width: 17px;
  height: 17px;
  color: var(--text-muted);
}
.ib-folder.is-on .ib-folder-icon .mi {
  color: var(--accent-text);
}
.ib-marks .mi {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
}
.ib-marks .is-flag .mi {
  color: #e5484d;
}
.ib-hover-btn .mi,
.ib-star .mi {
  width: 15px;
  height: 15px;
}
.ib-star.is-on .mi {
  fill: var(--accent);
}

/* ---------- the three panes ---------- */
.ib-panes {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 0;
  overflow: hidden;
  gap: 8px;
  padding: 8px;
}
.ib-rail {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: 8px;
  overflow-y: auto;
  min-height: 0;
  border-radius: var(--radius);
}
.ib-rail-head {
  flex: 1 0 100%;
  margin: 8px 8px 4px;
  /* Only ever a heading: without this it is a full-width chip. */
  line-height: 1.2;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: none;
}
.ib-rail-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 28px;
  border-radius: 6px;
  transition: background 0.12s;
}
.ib-rail-group.is-over {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  outline: 1px dashed var(--accent);
}
.ib-rail-hint {
  margin: 2px 10px 6px;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.ib-folder-wrap {
  position: relative;
  cursor: grab;
}
.ib-folder-wrap.is-dragging {
  opacity: 0.4;
}
.ib-folder {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
  font-size: 0.9375rem;
}
.ib-folder:hover {
  background: var(--bg-raised);
}
.ib-folder.is-on {
  background: var(--bg-raised);
  box-shadow: inset 3px 0 0 var(--accent);
  font-weight: 600;
}
.ib-folder-icon {
  width: 20px;
  text-align: center;
  font-size: 0.9375rem;
}
.ib-folder-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ib-count {
  font-size: 0.75rem;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--accent);
  color: #06301b;
  font-weight: 700;
}

.ib-list {
  overflow-y: auto;
  min-height: 0;
  border-radius: var(--radius);
}
.ib-list-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px 6px;
  font-size: 1.0625rem;
  position: sticky;
  top: 0;
  background: inherit;
  z-index: 1;
}
.ib-star {
  background: none;
  border: 0;
  color: var(--text-muted);
  font-size: 1.125rem;
  cursor: pointer;
  padding: 0 4px;
  width: auto;
  margin: 0;
  line-height: 1;
}
.ib-star.is-on {
  color: var(--accent-text);
}
.ib-day {
  margin: 6px 0 0;
  padding: 8px 14px 4px;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--text-muted);
}
.ib-row-wrap {
  position: relative;
}
.ib-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 12px 10px 12px;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  position: relative;
}
.ib-row:hover {
  background: var(--bg-raised);
}
.ib-row.is-on {
  background: var(--bg-raised);
  box-shadow: inset 3px 0 0 var(--accent);
}
.ib-row.is-unread .ib-sender,
.ib-row.is-unread .ib-subject {
  font-weight: 700;
  color: var(--text);
}
.ib-row.is-unread .ib-subject {
  color: var(--accent-text);
}
/* Read mail steps back so the unread stands out — the same trick Outlook
   uses, and cheaper on the eye than a coloured bar. */
.ib-row:not(.is-unread) .ib-sender,
.ib-row:not(.is-unread) .ib-subject {
  opacity: 0.68;
}
.ib-row:not(.is-unread) .ib-preview {
  opacity: 0.8;
}
.ib-avatar {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fff;
  background: hsl(var(--hue, 200) 45% 42%);
  margin-top: 2px;
}
.ib-row-main {
  flex: 1 1 auto;
  min-width: 0;
}
.ib-row-top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: baseline;
}
.ib-sender {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
.ib-when {
  flex: 0 0 auto;
  font-size: 0.8125rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* In Sent and Drafts the bold name is who it went to; this is the address it
   went from, which matters when there is more than one to send as. */
.ib-sent-from {
  display: block;
  margin-top: 1px;
  font-size: 0.75rem;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ib-subject {
  display: block;
  margin-top: 1px;
  padding-right: 40px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ib-preview {
  display: block;
  font-size: 0.875rem;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ib-preview:empty {
  display: none;
}
.ib-chips {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  flex-wrap: wrap;
}
.ib-chip {
  display: inline-block;
  max-width: 160px;
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 0.8125rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ib-chip.is-more {
  border: 0;
  color: var(--text-muted);
}
/* Ten seconds, in the corner, while a deleted message is still recoverable. */
.ib-undo {
  position: fixed;
  left: 50%;
  bottom: 20px;
  z-index: 60;
  transform: translate(-50%, 12px);
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 32px);
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: 0 10px 30px rgb(0 0 0 / 35%);
  opacity: 0;
  transition:
    opacity 0.18s ease,
    transform 0.18s ease;
}
.ib-undo.is-in {
  opacity: 1;
  transform: translate(-50%, 0);
}
.ib-undo[hidden] {
  display: none;
}
.ib-undo-text {
  font-size: 0.9375rem;
}
.ib-undo-btn {
  width: auto;
  min-height: 0;
  margin: 0;
  padding: 4px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--accent-text);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.ib-undo-btn:hover {
  background: var(--bg);
}
.ib-undo-left {
  min-width: 1.25em;
  text-align: right;
  font-size: 0.8125rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
@media (prefers-reduced-motion: reduce) {
  .ib-undo {
    transition: none;
  }
}

.ib-marks {
  position: absolute;
  right: 12px;
  bottom: 10px;
  font-size: 0.8125rem;
  display: flex;
  gap: 4px;
}
.ib-marks .is-flag {
  color: #e5484d;
}
/* The bin and the gear appear on hover, where Outlook puts its own. */
.ib-hover {
  position: absolute;
  top: 8px;
  right: 10px;
  display: inline-flex;
  gap: 2px;
  opacity: 0;
  transition: opacity 0.12s;
}
.ib-hover-btn.is-bin:hover {
  color: #e5484d;
}
.ib-row-wrap:hover .ib-hover,
.ib-row-wrap:focus-within .ib-hover {
  opacity: 1;
}
/* The gear takes the time's place, as Outlook's own icons do, rather than
   sitting on top of it. */
.ib-row-wrap:hover .ib-when,
.ib-row-wrap:focus-within .ib-when {
  visibility: hidden;
}
/* On a touch screen there is no hover to reveal anything with, so these were
   drawn permanently — over the time each message arrived. Holding a finger on
   a message opens the same menu instead, which is what a phone means by "more
   about this one", so nothing needs to sit on the row at all. */
@media (hover: none) {
  .ib-hover {
    display: none;
  }
  /* A held message must not also be selected or offered the browser's own
     copy-link menu while ours is opening. */
  .ib-row {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
}
.ib-hover-btn {
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text-muted);
  font-size: 0.9375rem;
  cursor: pointer;
  line-height: 1;
}
.ib-hover-btn:hover {
  color: var(--text);
  border-color: var(--accent);
}

/* ---------- right-click menus ---------- */
.cm {
  position: fixed;
  z-index: 50;
  min-width: 220px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
}
.cm-head {
  margin: 4px 10px 6px;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.cm-form {
  margin: 0;
}
.cm-item {
  display: block;
  width: 100%;
  margin: 0;
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.9375rem;
  text-align: left;
  cursor: pointer;
}
.cm-item:hover,
.cm-item:focus-visible {
  background: var(--bg-raised);
  outline: none;
}
.cm-item.is-off {
  color: var(--text-muted);
  opacity: 0.55;
  cursor: default;
}
.cm-rule {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 4px 0;
}
.cm-link {
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.cm-hint {
  font-size: 0.75rem;
  color: var(--text-muted);
}
.cm-settings {
  min-width: 250px;
}
.rb-btn .mi-chevron {
  width: 14px;
  height: 14px;
}

/* ---------- the reading pane ---------- */
.ib-read {
  overflow-y: auto;
  min-height: 0;
  border-radius: var(--radius);
}
.ib-read article {
  padding: 14px 18px 24px;
  border-radius: var(--radius);
}
/* The last thing in the pane fills it, so a short message is still a panel,
   with room below so the end of a long thread can be scrolled up to the
   middle of the screen rather than stopping at the bottom edge. Only the
   last: a reply box sits above the message it answers, and given the same
   two rules it pushed that message a whole screen and a half down. */
.ib-read > article:last-of-type {
  min-height: 100%;
  padding-bottom: 40vh;
}
.ib-read-subject {
  margin: 4px 0 12px;
  font-size: 1.25rem;
}
.ib-read-top {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
  flex-wrap: wrap;
}
.ib-read-head {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  flex: 1 1 280px;
  min-width: 0;
}
.ib-read-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  flex: 0 1 auto;
}
.ib-read-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* Small, quiet, icon-first: the row Outlook puts at the top right of a
   message. Each is a link or a button, so the row is a set of plain controls
   with a picture beside the word rather than a picture instead of it. */
.ib-act {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-muted);
  text-decoration: none;
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
  width: auto;
  margin: 0;
  white-space: nowrap;
}
.ib-act:hover {
  background: var(--bg-raised);
  color: var(--text);
}
.ib-act .mi {
  width: 17px;
  height: 17px;
}
.ib-act.is-on .mi {
  color: var(--accent-text);
}
.ib-act-nod .mi {
  color: var(--accent-text);
}

.ask-nod {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin: 10px 0 4px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
  opacity: 0;
  transform: translateY(-8px) scale(0.98);
  transition:
    opacity 0.22s ease,
    transform 0.22s ease;
}
.ask-nod.is-in {
  opacity: 1;
  transform: none;
}
.ask-nod[hidden] {
  display: none;
}
.ask-nod-face {
  flex: 0 0 auto;
  transform: scale(0.6);
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.ask-nod.is-in .ask-nod-face {
  transform: scale(1);
}
.ask-nod-face svg {
  width: 60px;
  height: 60px;
}
.ask-nod-face #qnm-eye-l,
.ask-nod-face #qnm-eye-r,
.ask-nod-face #qnm-eye-l-dot,
.ask-nod-face #qnm-eye-r-dot {
  transition: transform 0.12s ease-out;
  transform-box: fill-box;
  transform-origin: center;
}
.ask-nod-body {
  flex: 1 1 auto;
  min-width: 0;
}
.ask-nod-body input {
  margin: 4px 0 8px;
}
.ask-nod-buttons {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.ask-nod-buttons .btn-quiet {
  width: auto;
  min-height: 34px;
  padding: 4px 12px;
  margin: 0;
  font-size: 0.875rem;
}
.ask-nod-note {
  margin: 10px 0 0;
  white-space: pre-wrap;
  font-size: 0.9375rem;
}
.ask-nod-note.is-working,
.ask-nod-note.is-warn {
  color: var(--text-muted);
}
.ask-nod-note.is-error {
  color: #e5484d;
}
.ask-nod.is-thinking .ask-nod-face {
  animation: nod-think 1.1s ease-in-out infinite;
}
@keyframes nod-think {
  0%,
  100% {
    transform: scale(1) translateY(0);
  }
  50% {
    transform: scale(1) translateY(-3px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ask-nod,
  .ask-nod-face {
    transition: none;
  }
  .ask-nod.is-thinking .ask-nod-face {
    animation: none;
  }
}
.ib-read-head .ib-avatar {
  width: 40px;
  height: 40px;
  font-size: 0.9375rem;
}
.ib-read-who {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.ib-read-when {
  flex: 0 0 auto;
  white-space: nowrap;
}
.ib-body {
  width: 100%;
  min-height: 160px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fff;
  margin-top: 12px;
  display: block;
  overflow: hidden;
}
.ib-blocked {
  padding: 8px 12px;
  border-left: 3px solid var(--warn);
  background: var(--bg-raised);
  font-size: 0.875rem;
  color: var(--text-muted);
}
.ib-sensitive {
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  background: var(--bg-raised);
  font-size: 0.875rem;
  color: var(--text-muted);
}
/* Reply and the sensitive toggle sit on one line: a form inside a button row
   is a block by default and would push the buttons apart. */
.ib-actions {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 8px;
}
.ib-read .ib-actions form {
  display: inline-flex;
  flex: 0 0 auto;
  margin: 0;
  width: auto;
}
.ib-read .ib-actions .btn-quiet,
.ib-read .ib-actions form .btn-quiet {
  width: auto;
  min-height: 36px;
  padding: 6px 14px;
  display: inline-flex;
  margin: 0;
}
.ib-attachments {
  padding-left: 1.1rem;
}
.ib-attachments li {
  margin: 6px 0;
}
.ib-empty {
  padding: 24px 16px;
  color: var(--text-muted);
}
.ib-back {
  margin: 0 0 8px;
}
/* The same way out, at the end of the message.
   A long message read to the bottom leaves somebody a full screen away from
   the one at the top, and scrolling back up to leave is the sort of small
   indignity that makes an app feel like a website. */
.ib-back-end {
  margin: 20px 0 4px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

/* Three panes, once there is room for three panes.
   Nine hundred was the old figure and it was wrong: a folder rail and a list
   take five hundred and forty of it before the message gets any, so a window
   a little over nine hundred wide showed a message in a column too narrow to
   read it in. Below this the list and the message take turns at the whole
   width, with a way back between them, which is what a narrow window wants
   and is what the phone has always done. */
@media (min-width: 1100px) {
  .ib-panes {
    grid-template-columns: 220px minmax(320px, 420px) 1fr;
  }
  .ib-rail {
    flex-direction: column;
    flex-wrap: nowrap;
  }
  /* In a column, "100% of the main axis" is the rail's whole height — which
     would push every folder off the bottom of the screen. */
  .ib-rail-head {
    flex: 0 0 auto;
  }
  .ib-back,
  .ib-back-end {
    display: none;
  }
}

/* On a phone the reading pane replaces the list rather than sitting under it. */
@media (max-width: 1099px) {
  .ib-panes.is-reading .ib-list,
  .ib-panes.is-reading .ib-rail {
    display: none;
  }
  /* To, Cc and Bcc stay on the same line as the address they label. The box
     for typing the next one is what wraps underneath, and it is what used to
     drag the label down with it: a label centred on a block two lines tall
     sits beside the gap rather than beside the address. Aligning to the top
     puts it level with the first address, whatever wraps below. */
  /* Written against both classes because the ordinary .cw-row rule, which
     centres everything, is further down the stylesheet than this block. */
  .cw-row.cw-addr {
    align-items: flex-start;
    min-height: 0;
    padding: 6px 0;
  }
  .cw-addr .cw-chips {
    padding: 0;
  }
  .cw-addr .cw-label {
    margin-top: -3px;
  }
  .cw-addr .cw-toggles {
    margin-top: 1px;
  }
  /* The box for the next address is all that wraps underneath, so it is kept
     to the height of a chip rather than leaving a hand's width of nothing. */
  .cw-addr .cw-input {
    padding: 2px 0;
    min-height: 26px;
  }
  .ib-panes:not(.is-reading) .ib-read {
    display: none;
  }
}

/* The attachments list is a document rather than a three-pane view, so it
   scrolls as a page inside the same full-height shell. */
/* A mail page that is a document rather than three panes scrolls like one.
   It used to be a full-height shell with the page scrolling inside it and the
   legal footer stranded below the fold — which left the document taller than
   the window with `overflow: hidden` over the top of it. That is a trap
   rather than a lock: hidden stops a wheel, and stops nothing else. Focusing
   a field below the fold — clicking into the signature editor — scrolls the
   document, and once it has scrolled there is no way to scroll it back. The
   header goes with it, and in the desktop app the header is the title bar, so
   the window could no longer be moved either.

   So these pages are ordinary documents: the whole thing scrolls, the header
   is pinned to the top of it, and the footer is somewhere you can reach. */
body.mail-app:has(.mail-shell-scroll) {
  overflow: auto;
}
.mail-shell-scroll {
  display: flex;
  flex-direction: column;
  height: auto;
  min-height: 100dvh;
  overflow: visible;
}
.mail-shell-scroll .mail-page {
  overflow: visible;
}
.mail-shell-scroll .mail-top {
  position: sticky;
  top: 0;
  /* Above the page under it, below the resize edge the app puts at 9999. */
  z-index: 30;
}
.mail-page {
  overflow-y: auto;
  min-height: 0;
  padding: 12px 16px 32px;
}

.mail-compose {
  max-width: 780px;
}
.mail-compose textarea {
  font-family: inherit;
  line-height: 1.5;
}
.mail-sig {
  display: inline-block;
  margin-top: 4px;
  padding: 8px 12px;
  border-left: 3px solid var(--border);
  white-space: pre-wrap;
}
.mail-rules {
  padding-left: 1.1rem;
  max-width: 68ch;
}
.mail-rules li {
  margin: 10px 0;
}
.mail-rules form {
  display: inline;
  margin: 0 0 0 8px;
}
.mail-rules .btn-quiet {
  display: inline-flex;
  width: auto;
  margin: 0;
  padding: 2px 10px;
}

/* Nod on the compose screen. He sits beside the draft rather than over it:
   a panel that covers what it is writing about is one you close. */
.nod-panel {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  max-width: 780px;
  margin: 20px 0 8px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.nod-face {
  flex: 0 0 auto;
  color: var(--text);
  line-height: 0;
}
.nod-face svg #qnm-eye-l,
.nod-face svg #qnm-eye-r {
  transition: transform 0.12s ease-out;
}
.nod-face svg #qnm-eye-l-dot,
.nod-face svg #qnm-eye-r-dot {
  transition: transform 0.08s ease-out;
}
.nod-body {
  flex: 1 1 auto;
  min-width: 0;
}
.nod-body h2 {
  margin: 0 0 4px;
  font-size: 1.0625rem;
}
.nod-body label {
  margin-top: 10px;
}
.nod-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.nod-buttons .btn-quiet {
  display: inline-flex;
  width: auto;
  margin: 0;
  white-space: nowrap;
}
.nod-note {
  margin: 12px 0 0;
  font-size: 0.9375rem;
  color: var(--text-muted);
  white-space: pre-wrap;
}
.nod-note.is-working {
  color: var(--accent-text);
}
.nod-note.is-error {
  color: var(--danger);
}
.nod-note.is-warn {
  border-left: 3px solid var(--warn);
  padding-left: 10px;
}
.nod-panel.is-thinking .nod-face {
  opacity: 0.85;
}

@media (max-width: 560px) {
  .nod-panel {
    flex-direction: column;
    align-items: center;
    text-align: left;
  }
}

/* The gaps still to fill in. Chips rather than text in the draft: this is a
   guide beside the message, and none of it is in what gets sent. */
.nod-gaps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
}
.nod-gaps-label {
  font-size: 0.875rem;
  color: var(--text-muted);
  margin-right: 2px;
}
.nod-gap {
  font: inherit;
  font-size: 0.8125rem;
  padding: 3px 10px;
  border: 1px dashed var(--accent);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  cursor: pointer;
}
.nod-gap:hover,
.nod-gap:focus-visible {
  background: var(--accent);
  color: #06301b;
}
.nod-gap.is-withheld {
  border-style: solid;
  border-color: var(--warn);
}
.nod-gap.is-withheld:hover,
.nod-gap.is-withheld:focus-visible {
  background: var(--warn);
  color: #1a1200;
}

/* The blanks Nod left, outlined in the draft. A textarea cannot colour its own
   words, so a layer sits under it with the same words, transparent, and a mark
   where each blank is; the writing stays on top and stays editable. The paper
   is always light, so the colours are fixed. */
.cw-body > .nod-marks {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  margin: 0;
  padding: 0;
  border: 0;
  font: 0.9375rem/1.55 var(--font);
  white-space: pre-wrap;
  overflow-wrap: break-word;
  word-wrap: break-word;
  color: transparent;
  pointer-events: none;
  overflow: hidden;
}
.cw-paper .cw-body > textarea.has-marks {
  position: relative;
  z-index: 1;
}
.nod-blank {
  color: transparent;
  background: #fff1b8;
  outline: 1.5px solid #b8860b;
  outline-offset: 1px;
  border-radius: 3px;
}
.cw .cw-subject input#c_subject.has-blank {
  background: rgba(255, 241, 184, 0.12);
  outline: 1.5px solid #b8860b;
  outline-offset: -1.5px;
  border-radius: 3px;
}

/* ---------- the Help tab: Nod given a job ---------- */
.nod-task {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  max-width: 820px;
}
.nod-task .nod-face {
  flex: 0 0 auto;
}
.nod-task-body {
  flex: 1 1 auto;
  min-width: 0;
}
.nod-task-form textarea {
  font-family: inherit;
  line-height: 1.5;
}
.nod-plan {
  margin-top: 18px;
  padding: 14px 18px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.nod-plan h2 {
  margin: 0 0 8px;
  font-size: 1.0625rem;
}
.nod-steps {
  margin: 0 0 8px;
  padding-left: 1.3rem;
}
.nod-steps li {
  margin: 4px 0;
}
.nod-answer {
  white-space: pre-wrap;
}
@media (max-width: 600px) {
  .nod-task {
    flex-direction: column;
  }
}

/* ---------- writing in the reading pane ----------
   A reply opens above the message it answers, the way Outlook does, and a new
   message opens where a message would be read. The conversation sits under
   it, newest first, so the thing being written and the thing being answered
   are on one screen. */
.ib-compose {
  padding: 14px 18px 8px;
  border-radius: var(--radius);
  margin-bottom: 8px;
}
.ib-compose-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}
.ib-compose-head .btn-quiet {
  width: auto;
  min-height: 34px;
  padding: 4px 12px;
  margin: 0;
}
.ib-compose .mail-compose {
  max-width: none;
}
.ib-compose .nod-panel {
  max-width: none;
}
.ib-history {
  opacity: 0.92;
}
.ib-conv {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.ib-conv-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
}
.ib-conv-row:last-child {
  border-bottom: 0;
}
.ib-conv-row:hover {
  background: var(--bg-raised);
}
.ib-conv-row .ib-avatar {
  width: 28px;
  height: 28px;
  font-size: 0.6875rem;
}
.ib-folder-view {
  margin-top: 10px;
  border-top: 1px solid var(--border);
  padding-top: 10px;
  border-radius: 0;
}
.ib-rail-form {
  margin: 0;
}
.ib-folder-add {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  cursor: pointer;
  text-align: left;
  color: var(--text-muted);
}
.ib-folder-add:hover {
  color: var(--text);
}
.mail-flash-link {
  margin-left: 10px;
  font-weight: 700;
}

/* ---------- the compose header, Outlook-shaped ----------
   From as a line of text with a chevron, To / Cc / Bcc as button-shaped
   labels beside a row of chips, the subject a bare line under them, and the
   signature drawn as it will send. Compact on purpose: the header is four
   lines high, not a form. */
.cw {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.cw-from {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px 0 10px;
  border-bottom: 1px solid var(--border);
  font-size: 0.9375rem;
}
.cw-from label {
  margin: 0;
  font-weight: 600;
}
.cw-from-select {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 600;
  padding: 0 2px;
  margin: 0;
  width: auto;
  min-height: 0;
  cursor: pointer;
}
.cw-from .mi-chevron {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
  pointer-events: none;
  margin-left: -2px;
}
/* The opened list takes its colours from the options, not the page, and a
   transparent select gives it none — so on Windows it opens white against
   the navy. The options say what they are. */
.cw-from-select option {
  background: var(--bg-raised);
  color: var(--text);
  font-weight: 500;
}
.cw-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 42px;
  border-bottom: 1px solid var(--border);
}
.cw-row[hidden] {
  display: none;
}
.cw-label {
  flex: 0 0 auto;
  min-width: 50px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  text-align: center;
  font-size: 0.875rem;
  font-weight: 600;
  background: var(--bg-raised);
}
.cw-chips {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-width: 0;
  cursor: text;
  padding: 4px 0;
}
.cw-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 6px 3px 10px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg-raised);
  font-size: 0.875rem;
  max-width: 100%;
}
.cw-chip-x {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1;
  padding: 0 2px;
  margin: 0;
  width: auto;
  min-height: 0;
  cursor: pointer;
}
.cw-chip-x:hover {
  color: var(--text);
}
.cw-input {
  flex: 1 1 120px;
  min-width: 120px;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  padding: 6px 0;
  margin: 0;
  min-height: 0;
  outline: none;
}
.cw-toggles {
  flex: 0 0 auto;
  display: flex;
  gap: 4px;
}
.cw-toggle {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.8125rem;
  padding: 4px 8px;
  margin: 0;
  width: auto;
  min-height: 0;
  cursor: pointer;
  border-radius: 4px;
}
.cw-toggle:hover {
  background: var(--bg-raised);
  color: var(--text);
}
.cw-subject input {
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 1rem;
  padding: 10px 0;
  margin: 0;
  width: 100%;
  min-height: 0;
  outline: none;
}
.cw textarea {
  margin-top: 14px;
  border: 0;
  background: transparent;
  padding: 4px 0;
  font-family: inherit;
  font-size: 0.9375rem;
  line-height: 1.5;
  resize: vertical;
}
.cw textarea:focus {
  outline: none;
  box-shadow: none;
}
.cw-sig {
  margin: 8px 0 4px;
}
.cw-sig[hidden] {
  display: none;
}
.cw-sig-lead {
  display: block;
  margin-bottom: 4px;
}
/* The signature is shown on the paper it will land on. A signature written
   for a white email — dark name, dark title — vanishes against the dark
   compose pane, and recolouring it to suit would show something nobody
   receives. So the preview sits on a white card, colours untouched: what is
   on the card is what the other side gets, and nothing about the card is
   sent. */
.cw-sig-body,
.sig-editor {
  color-scheme: light;
  background: #fff;
  color: #111;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px solid var(--border);
  font-size: 0.9375rem;
  line-height: 1.5;
}
.cw-sig-body {
  display: inline-block;
  max-width: 100%;
  min-width: min(100%, 420px);
}
.cw-sig-body img,
.sig-editor img {
  max-width: 100%;
  height: auto;
}
.cw-sig-body a,
.sig-editor a {
  color: #0b6e3f;
}
/* Send and Discard sit in the header beside Ask Nod, the same height as it. */
.cw-send,
.cw-discard {
  width: auto;
  min-height: 34px;
  padding: 4px 14px;
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.mail-tools .cw-send,
.mail-tools .cw-discard {
  align-self: center;
}

/* The app styles every text box as a box; inside the compose header they are
   bare lines, and the rule has to outrank the type selector to say so. */
.cw input.cw-input,
.cw .cw-subject input[type='text'],
.cw input.cw-input:focus,
.cw .cw-subject input[type='text']:focus {
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  outline: none;
  padding-left: 0;
  padding-right: 0;
}

/* The Nod panel under a draft folds like the one under a message. */
.nod-panel[hidden] {
  display: none;
}
/* The fade is only ever applied once the script is running and has said so,
   because a panel that starts invisible and waits for a script to reveal it
   is a panel that never appears when the script does not run. */
.nod-panel.is-fold {
  opacity: 0;
  transform: translateY(-8px) scale(0.98);
  transition:
    opacity 0.22s ease,
    transform 0.22s ease;
}
.nod-panel.is-fold.is-in {
  opacity: 1;
  transform: none;
}
.ib-compose-tools {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.mail-tools .ib-act {
  width: auto;
}
@media (prefers-reduced-motion: reduce) {
  .nod-panel.is-fold {
    transition: none;
  }
}

/* ---------- notices with an × ----------
   Slighter than the ones on the rest of the app. A mail screen says "Sent"
   several times an hour, and a banner built for a page that shows one once
   sits across the top of the inbox like a wall. Same colours, a third of the
   weight. */
.mail-flash {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 8px 16px 0;
  gap: 10px;
  padding: 6px 10px 6px 12px;
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 500;
  transition: opacity 0.4s ease;
}
.mail-flash.is-going {
  opacity: 0;
}
.mail-flash-text {
  flex: 1 1 auto;
}
.mail-flash-x {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  min-height: 0;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  font-size: 1.0625rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.7;
}
.mail-flash-x:hover {
  opacity: 1;
  background: rgba(0, 0, 0, 0.15);
}
@media (prefers-reduced-motion: reduce) {
  .mail-flash {
    transition: none;
  }
}

/* ---------- locked folders ---------- */
.ib-folder-lock .mi {
  width: 13px;
  height: 13px;
  color: var(--text-muted);
}
.ib-folder-lock.is-open .mi {
  color: var(--accent-text);
}
.lk-inline {
  display: flex;
  gap: 8px;
  align-items: center;
  margin: 0;
  flex-wrap: wrap;
}
.lk-inline input {
  width: auto;
  flex: 1 1 200px;
  margin: 0;
}
.lk-inline .btn-quiet {
  width: auto;
  margin: 0;
  min-height: 38px;
}

/* ---------- the signature editor ---------- */
/* Grows with what is in it, so a pasted signature is seen whole rather than
   through a slot; only sideways overflow scrolls, for a table wider than the
   page. */
.sig-editor {
  min-height: 120px;
  height: auto;
  overflow-x: auto;
  overflow-y: visible;
  margin-bottom: 8px;
}
.sig-editor:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}
.sig-editor[hidden] {
  display: none;
}

/* ---------- the list head's Filter ---------- */
.ib-list-spacer {
  flex: 1 1 auto;
}
.ib-filter {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
  width: auto;
  min-height: 0;
  margin: 0;
}
.ib-filter.is-on {
  border-color: var(--accent);
  color: var(--accent-text);
}
.ib-filter .mi {
  width: 14px;
  height: 14px;
}
.cm-filter .cm-item.is-on {
  color: var(--accent-text);
}
.ib-drawer-head,
.ib-drawer-links,
.ib-drawer-x {
  display: none;
}

/* ---------- the phone: a drawer of folders, and a strip of buttons ----------
   The reference is the Outlook app: the mark top left opens the folders as
   a panel that slides in over the list; the ribbon is a strip that scrolls
   sideways; the list is the screen, and a message takes the screen over. */
@media (max-width: 1099px) {
  .ib-panes {
    grid-template-columns: 1fr;
    padding: 0;
    gap: 0;
  }
  .ib-panes .ib-rail {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: min(84vw, 340px);
    z-index: 70;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    padding: 12px 10px calc(16px + env(safe-area-inset-bottom));
    border-radius: 0 16px 16px 0;
    background: color-mix(in srgb, var(--bg) 96%, #000);
    box-shadow: 0 0 60px rgba(0, 0, 0, 0.5);
    transform: translateX(-105%);
    transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
    overflow-y: auto;
  }
  .ib-panes .ib-rail.is-open {
    transform: none;
  }
  .ib-panes.is-reading .ib-rail {
    display: flex;
  }
  .ib-rail-backdrop {
    position: fixed;
    inset: 0;
    z-index: 65;
    background: rgba(0, 0, 0, 0.55);
  }
  .ib-rail-backdrop[hidden] {
    display: none;
  }
  .ib-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 8px 12px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 6px;
  }
  .ib-drawer-x {
    display: inline-flex;
    width: 34px;
    height: 34px;
    min-height: 0;
    padding: 0;
    margin: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    font-size: 1.5rem;
    line-height: 1;
    align-items: center;
    justify-content: center;
  }
  .ib-drawer-links {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
  }
  .ib-rail-head {
    flex: 0 0 auto;
  }
  .ib-rail-group {
    flex: 0 0 auto;
  }
  body.drawer-open {
    overflow: hidden;
  }
  .mail-links,
  .mail-out {
    display: none;
  }
  .mail-top {
    padding: 8px 12px;
    gap: 10px;
  }
  /* Sideways only, and thick enough to hit.
     overflow-x on its own is not one axis: naming a scroll on either axis
     turns `visible` on the other into `auto`, so the strip could be dragged
     up and down as well — a few pixels of travel with nothing to travel to,
     which showed as the labels sitting off-centre and drifting under a thumb
     meant for the horizontal scroll. Saying hidden out loud is what pins it.

     The height is the other half. A row eight-and-thirty pixels tall is a
     row of things that are almost hit, and on a strip that scrolls sideways
     an almost-hit is a drag that goes somewhere unexpected. */
  .mail-ribbon {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 10px;
    gap: 4px;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
  }
  .mail-ribbon .rb-btn {
    padding: 10px 14px;
    min-height: 44px;
  }
  /* In the strip it is one more thing to scroll past, and the one thing
     somebody opens a mail app to do should not need scrolling to. It moves
     to its own row below, the width of the screen, and the divider that used
     to follow it goes with it. */
  .mail-ribbon .rb-compose,
  .mail-ribbon .rb-split-compose {
    display: none;
  }
  .mail-compose-row {
    display: block;
    padding: 8px 10px;
    border-bottom: 1px solid var(--border);
  }
  .mail-compose-row .mail-compose {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin: 0;
    min-height: 48px;
    font-size: 1.0625rem;
    font-weight: 600;
  }
  /* Nothing to compose about while a message is open.
     The row sits above the panes in the markup, so there is no sibling
     selector that reaches back to it — :has on the shell asks the same
     question from above, and it stays true when the panes are swapped in
     without a page load, which is how a message opens. */
  .mail-shell:has(.ib-panes.is-reading) .mail-compose-row {
    display: none;
  }
  /* Full width is a thumb's width on a phone and a stretched green mile in a
     shortened desktop window. Past the width of a phone these take the size a
     button should be and sit at the start of the line. */
  @media (min-width: 560px) {
    .mail-compose-row .mail-compose {
      width: auto;
      min-width: 190px;
      max-width: 300px;
    }
    .ib-back .btn-quiet,
    .ib-back-end .btn-quiet {
      width: auto;
      min-width: 170px;
      display: inline-flex;
      justify-content: center;
    }
  }
  .mail-ribbon::-webkit-scrollbar {
    display: none;
  }
  .rb-synced {
    display: none;
  }
  .ib-list {
    border-radius: 0;
  }
  .ib-list-head {
    padding: 10px 14px 8px;
    font-size: 1.25rem;
  }
  .ib-read {
    border-radius: 0;
  }
  .ib-read article,
  .ib-read > article:last-of-type {
    padding: 12px 14px 24px;
  }
  .ib-read-top {
    flex-direction: column;
    gap: 10px;
  }
  /* Stacked, the basis that sets the sender block's width in a row becomes its
     height, and 280px of empty space opens under the address. */
  .ib-read-head {
    flex: 0 0 auto;
  }
  .ib-read-right {
    align-items: flex-start;
    flex: 0 0 auto;
  }
  .ib-read-actions {
    justify-content: flex-start;
  }
  .ib-row {
    padding: 12px 14px;
  }
  .ib-avatar {
    width: 40px;
    height: 40px;
    font-size: 0.9375rem;
  }
  .mail-shell::before,
  .mail-shell::after {
    opacity: 0.18;
  }
}

/* ---------- the one-time notification offer, in the phone app ---------- */
.push-offer {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}
.push-offer[hidden] {
  display: none;
}
.push-offer .po-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  border-radius: 50%;
  color: var(--brand);
  background: color-mix(in srgb, var(--brand) 20%, transparent);
}
.push-offer .po-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 220px;
  min-width: 0;
}
.push-offer .po-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.push-offer .btn,
.push-offer .btn-quiet {
  padding: 7px 14px;
  font-size: 0.9rem;
}
@media (max-width: 560px) {
  .push-offer .po-actions {
    flex: 1 1 100%;
  }
  .push-offer .po-actions .btn {
    flex: 1 1 auto;
  }
}

/* ---------- the four controls above the list ----------
   Outlook's row: select, jump to a date, filter, sort. Icon-only and quiet,
   because they sit above the list all day and only two of them are ever
   in force. */
.ib-tools {
  display: flex;
  align-items: center;
  gap: 2px;
  position: relative;
}
.ib-tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.ib-tool:hover {
  background: color-mix(in srgb, var(--text) 10%, transparent);
  color: var(--text);
}
.ib-tool.is-on,
.ib-tool[aria-pressed='true'] {
  color: var(--brand);
  border-color: color-mix(in srgb, var(--brand) 45%, transparent);
  background: color-mix(in srgb, var(--brand) 14%, transparent);
}
.cm-tools {
  min-width: 210px;
}
.cm-tools .cm-head {
  margin: 2px 0 4px;
  padding: 0 10px;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.cm-tools .cm-item {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cm-tick {
  display: inline-flex;
  width: 16px;
  flex: 0 0 16px;
  color: var(--brand);
}
.cm-date {
  gap: 8px;
}
.cm-date input[type='date'] {
  margin: 0;
  padding: 4px 6px;
  min-height: 0;
  width: auto;
  font: inherit;
}
.cm-note {
  margin: 4px 10px 2px;
}
.cm-note[hidden] {
  display: none;
}

/* ---------- selecting several at once ---------- */
.ib-tick {
  display: none;
  align-items: center;
  padding: 0 2px 0 12px;
  cursor: pointer;
}
.ib-list.is-selecting .ib-tick {
  display: flex;
}
.ib-list.is-selecting .ib-row-wrap {
  display: flex;
  align-items: stretch;
}
.ib-list.is-selecting .ib-row {
  flex: 1 1 auto;
  min-width: 0;
}
.ib-tick input {
  width: 17px;
  height: 17px;
  min-height: 0;
  margin: 0;
  accent-color: var(--brand);
}
.ib-select-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin: 0;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
.ib-select-bar[hidden] {
  display: none;
}
.sb-all {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.875rem;
  color: var(--text-muted);
}
.sb-all input {
  width: 17px;
  height: 17px;
  min-height: 0;
  margin: 0;
  accent-color: var(--brand);
}
.sb-spacer {
  flex: 1 1 auto;
}
.sb-btn {
  margin: 0;
  padding: 5px 10px;
  min-height: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.85rem;
  cursor: pointer;
}
.ib-select-bar.has-picked .sb-btn {
  color: var(--text);
}
.sb-btn:hover {
  background: color-mix(in srgb, var(--text) 10%, transparent);
  color: var(--text);
}
.sb-btn.is-danger:hover {
  border-color: color-mix(in srgb, #ef4444 60%, transparent);
  color: #fca5a5;
}

/* ---------- landing on a date, and opening without a flash ---------- */
.ib-row-wrap.is-landed .ib-row {
  box-shadow: inset 3px 0 0 var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  transition: background 0.4s ease;
}
.ib-read.is-waiting {
  opacity: 0.55;
  transition: opacity 0.12s ease 0.09s;
}
.ib-read.is-fresh {
  animation: qn-pane-in 0.2s ease both;
}
@keyframes qn-pane-in {
  from {
    opacity: 0.4;
    transform: translateY(3px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .ib-read.is-fresh {
    animation: none;
  }
  .ib-read.is-waiting {
    transition: none;
  }
}

/* The × belongs to the drawer, so it is only ever drawn while the drawer is
   open over the list — never beside a rail that is simply there. */
.ib-drawer-x {
  display: none;
}
.ib-rail.is-open .ib-drawer-x {
  display: inline-flex;
}

/* ---------- reading down a thread ---------- */
.ib-trail {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ib-trail-item {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
}
.ib-trail-head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  margin: 0;
  padding: 10px 12px;
  min-height: 0;
  border: 0;
  background: transparent;
  color: inherit;
  text-align: left;
  font: inherit;
  cursor: pointer;
}
.ib-trail-head:hover {
  background: color-mix(in srgb, var(--text) 6%, transparent);
}
.ib-trail-chevron {
  flex: 0 0 auto;
  color: var(--text-muted);
  transition: transform 0.18s ease;
}
.ib-trail-head[aria-expanded='true'] .ib-trail-chevron {
  transform: rotate(180deg);
}
.ib-trail-head[aria-expanded='true'] .ib-preview {
  display: none;
}
.ib-trail-body {
  padding: 0 12px 12px;
}
.ib-trail-body[hidden] {
  display: none;
}
.ib-trail-body .ib-body {
  margin-top: 0;
}
.ib-trail-wait {
  margin: 8px 0;
}

/* ---------- Customers ----------
   A customer is a person the trader has met, so the list reads as a row of
   people rather than a table of records: name and reference first, the state
   of the money second, the value last and right-aligned so a column of them
   can be scanned down. */
.cm-search {
  display: flex;
  gap: 8px;
  align-items: center;
  margin: 0 0 16px;
}
.cm-search input {
  flex: 1 1 auto;
  min-width: 0;
}
.cm-search .btn-quiet,
.cm-search .btn-compact {
  width: auto;
  flex: 0 0 auto;
}
/* On a narrow screen the search box has a line to itself, with Search and the
   download beneath it. */
@media (max-width: 640px) {
  .cm-search {
    flex-wrap: wrap;
  }
  .cm-search input {
    flex-basis: 100%;
  }
}
.cm-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cm-row {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  color: var(--text);
  text-decoration: none;
}
.cm-row:hover {
  border-color: var(--brand);
}
/* An erased record is kept so the numbering and the books hold, but it is
   nobody now — it should not read like a customer you could ring up. */
.cm-row.gone {
  opacity: 0.62;
}
.cm-who {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 220px;
  min-width: 0;
}
.cm-who b,
.cm-who span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cm-ref {
  font:
    600 0.75rem ui-monospace,
    SFMono-Regular,
    Menlo,
    monospace;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.cm-ref.big {
  font-size: 0.875rem;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--bg-inset);
}
/* The counts sit between who they are and what they are worth, rather than
   crowded against one end of the row, and the money lines up with them. */
.cm-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
  justify-content: center;
  text-align: center;
  flex: 1 1 auto;
  min-width: 0;
}
.cm-counts {
  display: flex;
  gap: 4px 10px;
  flex-wrap: wrap;
  justify-content: center;
}
/* Each count in the colour of what it is counting, so a customer who is all
   red or all green is one glance rather than four readings. White is the
   total — a count of everything is not good news or bad news, it is a fact. */
.cm-c {
  white-space: nowrap;
}
.cm-c-jobs {
  color: var(--text);
  font-weight: 600;
}
.cm-c-signed {
  color: var(--ok);
}
.cm-c-unsigned {
  color: var(--warn);
}
.cm-c-lost {
  color: var(--danger);
}
.cm-amt {
  /* On the same line as the counts rather than floating in the middle of the
     row: the four numbers and what they are worth are one thought. */
  align-self: flex-start;
  margin-left: auto;
  text-align: right;
  font-size: 1.0625rem;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
.cm-stat {
  align-self: flex-start;
}
@media (max-width: 560px) {
  .cm-stat {
    align-items: flex-start;
    text-align: left;
    flex-basis: 100%;
  }
  .cm-counts {
    justify-content: flex-start;
  }
  .cm-amt {
    margin-left: 0;
  }
}

/* The four figures. Grid rather than flex so they stay in step across rows,
   and two-up on a phone rather than four squeezed ones. */
.cm-figs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 18px 0;
}
.cm-fig {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
}
.cm-fig-l {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-bottom: 2px;
}
.cm-fig b {
  font-size: 1.25rem;
  font-variant-numeric: tabular-nums;
}
.cm-fig.owing b {
  color: var(--warn);
}
.cm-facts {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.875rem;
  color: var(--text-muted);
  margin: 0 0 22px;
}
.cm-late {
  color: var(--warn);
}
.cm-ok {
  color: var(--ok);
}
.cm-jobs {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.cm-job {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  padding: 14px 16px;
}
.cm-job-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.cm-job-head .spacer {
  flex: 1 1 auto;
}
.cm-job-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-top: 6px;
  color: var(--text-muted);
}
.cm-pay {
  width: 100%;
  border-collapse: collapse;
  margin-top: 10px;
  font-size: 0.8125rem;
}
.cm-pay td {
  padding: 5px 0;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
}
.cm-pay td:nth-child(3) {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
/* the amount is right-aligned and its status starts the next cell, so
   without this the two read as one word: "£0.01outstanding" */
.cm-pay td:nth-child(4) {
  padding-left: 8px;
}
.cm-pay tr.cancelled td,
.cm-pay tr.superseded td {
  text-decoration: line-through;
  opacity: 0.6;
}
.cm-gdpr {
  margin-top: 34px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

/* The erasure page. Solid rather than outlined, because it is the one button
   in QuoteNod that destroys something, and it should not look like Cancel. */
.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 20px;
  background: var(--danger);
  color: #fff;
  border: none;
  border-radius: var(--radius);
  font: 700 0.9375rem var(--font);
  cursor: pointer;
  text-decoration: none;
}
.cm-erase-box {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  padding: 4px 18px 18px;
  margin: 0 0 20px;
}
.cm-erase-box h2 {
  font-size: 0.9375rem;
  margin: 18px 0 6px;
}
.cm-erase-box ul {
  margin: 0;
  padding-left: 20px;
  font-size: 0.875rem;
  color: var(--text-muted);
}
.cm-erase-box li {
  margin: 4px 0;
}
.cm-erase-form label {
  display: block;
  margin: 0 0 16px;
}
.cm-erase-form label.check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 0.875rem;
}
.cm-erase-form label.check input {
  flex: 0 0 auto;
  margin-top: 2px;
}
/* Typed as a signature, so it is shown as one rather than as a text field. */
.cm-sign {
  font:
    500 1.25rem 'Segoe Script',
    'Bradley Hand',
    'Brush Script MT',
    cursive;
}
@media (min-width: 700px) {
  .cm-figs {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ---------- Technical info ----------
   Shut by default. What is inside is evidence, not settings: sixty-four
   characters of hexadecimal shown as text so it reads as something recorded
   rather than something to fill in. */
.tech {
  margin: 26px 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
}
.tech > summary {
  cursor: pointer;
  padding: 12px 16px;
  font-weight: 600;
  font-size: 0.875rem;
  list-style: none;
}
.tech > summary::-webkit-details-marker {
  display: none;
}
.tech > summary::before {
  content: '▸';
  display: inline-block;
  margin-right: 8px;
  color: var(--text-muted);
  transition: transform 0.15s;
}
.tech[open] > summary::before {
  transform: rotate(90deg);
}
.tech > p,
.tech-group {
  padding: 0 16px;
}
.tech-group h3 {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 14px 0 6px;
}
.tech-group:last-child {
  padding-bottom: 16px;
}
.tech-row {
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
  padding: 8px 0;
  border-top: 1px solid var(--border);
}
.tech-l {
  flex: 1 1 200px;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.tech-v {
  flex: 2 1 100%;
  font:
    0.75rem ui-monospace,
    SFMono-Regular,
    Menlo,
    monospace;
  word-break: break-all;
  color: var(--text);
  /* Selectable, because copying it by hand has to stay possible, but not a
     field — there is nothing here anybody is meant to edit. */
  user-select: all;
}
.tech-copy {
  width: auto;
  flex: 0 0 auto;
}
/* The customer's name on a quote is now a way into their whole history. */
.q-cust {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px dotted var(--border);
}
.q-cust:hover {
  border-bottom-color: var(--brand);
}

/* A button that exists but is held shut, so the trader can see what is coming
   and what has to happen first — rather than wondering where it went. */
.btn-locked[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}
.btn-locked[disabled]::before {
  content: '🔒';
  margin-right: 8px;
  font-size: 0.8125rem;
}

/* The row of ways to send a link — Share, WhatsApp, SMS, Email, Copy. Wraps
   rather than scrolls, because on a phone the fifth one must not be the one
   nobody finds. */
.share-ways {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.share-ways .btn,
.share-ways .btn-compact,
.share-ways form {
  width: auto;
  flex: 0 0 auto;
}

/* ---------- The customer's code gate ----------
   One field, large, centred, in a monospace so six digits read as six digits
   and a mistyped one is obvious at a glance. */
.pin-wrap {
  padding-top: 8px;
}
.pin-form {
  margin: 20px 0 28px;
}
.pin-form .btn {
  max-width: 320px;
  margin-inline: auto;
}
.pin-form label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  margin: 0 0 8px;
}
/* Six boxes, one digit each.

   A single field asks the customer to reproduce a format — spaces or no
   spaces, a dash or not — and punishes them with "that code is not right"
   when they guess differently from us. One box per digit removes the
   question: there is nowhere to put a space. The boxes are the size of a
   thumb because this is read off one phone and typed on another. */
.pin-boxes {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-bottom: 16px;
}
.pin-boxes .pin-gap {
  width: 10px;
}
.pin-box {
  width: 48px;
  height: 60px;
  text-align: center;
  padding: 0;
  font:
    600 1.625rem ui-monospace,
    SFMono-Regular,
    Menlo,
    monospace;
  caret-color: var(--accent);
}
.pin-box:focus {
  border-color: var(--accent);
}
@media (max-width: 400px) {
  .pin-boxes {
    gap: 6px;
  }
  .pin-boxes .pin-gap {
    width: 4px;
  }
  .pin-box {
    width: 42px;
    height: 54px;
    font-size: 1.375rem;
  }
}
/* Kept for anything still rendering the single field, and for no-JS. */
.pin-input {
  width: 100%;
  max-width: 320px;
  margin-inline: auto;
  display: block;
  text-align: center;
  letter-spacing: 0.35em;
  font:
    600 1.875rem ui-monospace,
    SFMono-Regular,
    Menlo,
    monospace;
  padding: 14px 10px;
  margin-bottom: 14px;
}
.pin-again {
  margin-top: 10px;
  text-align: center;
}
.pin-again button {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--accent-text);
  text-decoration: underline;
  cursor: pointer;
}
.pin-why {
  border-top: 1px solid var(--border);
  padding-top: 16px;
  color: var(--text-muted);
}
.pin-why b {
  color: var(--text);
}

/* "optional" beside a label: quieter than the label, so the field reads as
   one thing and not two. */
.lbl-opt {
  font-weight: 500;
  font-size: 0.75rem;
  color: var(--text-muted);
  text-transform: none;
  letter-spacing: 0;
}

/* A quote that has left the working list: readable, plainly not live. */
.quote-card.gone {
  opacity: 0.55;
}
.quote-card.gone .amt b {
  text-decoration: line-through;
}
/* The countdown box, quieter than a warning — nothing has gone wrong yet. */
.qexp {
  border-left: 4px solid var(--warn);
}

/* ---------- Activity ----------
   One line per thing that happened: what it was, which job, and when. The
   icon carries the kind so the eye can pick "signed" out of a column of
   "opened" without reading a word of it. */
.act-day {
  margin: 0 0 20px;
}
.act-day h2 {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 18px 0 8px;
}
/* A row is a link with a tick beside it, and the tick only appears while
   several are being dealt with — a column of boxes down the side of a list
   nobody is selecting from is a column of boxes in the way. */
.act-item {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 0;
  margin-bottom: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  overflow: hidden;
}
.act-item:hover {
  border-color: var(--brand);
}
/* Where the job stands, as a band down the side. A background wash behind
   the words would fight the text at every theme; an edge does not. */
.act-item::before {
  content: '';
  flex: 0 0 4px;
  background: var(--border);
}
.act-item.t-done::before {
  background: var(--ok);
}
.act-item.t-waiting::before {
  background: var(--warn);
}
.act-item.t-needs::before {
  background: var(--danger);
}
/* Not looked at yet: the whole row sits up, and settles when it is opened. */
.act-item.is-new {
  background: color-mix(in srgb, var(--brand) 7%, var(--bg-card));
  border-color: color-mix(in srgb, var(--brand) 45%, var(--border));
}
.act-item.is-read {
  opacity: 0.82;
}
/* On a computer the boxes are simply there — small, to the left, out of the
   way of the words. On a phone there is no room for a column of them beside
   every row, so they stay hidden until a finger held on one asks for them,
   which is what a thumb tries first anyway. */
.act-tick {
  display: none;
  align-items: center;
  padding: 0 2px 0 12px;
}
@media (hover: hover) and (pointer: fine) {
  .act-tick {
    display: flex;
  }
}
body.act-picking .act-tick {
  display: flex;
}
.act-tick input {
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--brand);
}
.act-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
  flex: 1 1 auto;
  min-width: 0;
  padding: 12px 14px;
  color: var(--text);
  text-decoration: none;
}
.act-icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: var(--bg-inset);
  color: var(--text-muted);
}
.act-glyph {
  width: 19px;
  height: 19px;
}
.act-item.t-done .act-icon {
  color: var(--ok);
}
.act-item.t-waiting .act-icon {
  color: var(--warn);
}
.act-item.t-needs .act-icon {
  color: var(--danger);
}
.act-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 8em;
  min-width: 0;
}
.act-body b {
  font-weight: 600;
}
.act-when {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.act-readby {
  flex: 1 1 100%;
  min-width: 0;
  margin-top: -6px;
  padding-left: 42px;
}
.act-filters {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
  margin: 0 0 12px;
}
.act-kinds {
  margin-top: -4px;
}
.act-kinds .sec-chip {
  font-size: 0.8125rem;
}
.act-filters-gap {
  flex: 1 1 auto;
}
/* Slides in under the filters while something is selected. */
.act-bar {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 10px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  box-shadow: var(--shadow-1);
}
.act-all {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
}
.act-all input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--brand);
}
.act-bar-gap {
  flex: 1 1 auto;
}
.act-allread {
  margin: 12px 0 0;
}
.act-note {
  margin-top: 10px;
}
/* While selecting, a press picks rather than travels — so nothing should
   look like it is about to travel. */
body.act-picking .act-row {
  cursor: default;
}

/* A job in a customer's history that closed without an answer. */
.cm-job.gone {
  opacity: 0.6;
}

/* ---------- Handwriting picker ----------
   The dropdown names the faces; the samples show them. "Parisienne" means
   nothing to a plasterer, so the trader's own name is drawn in each one at the
   size it prints, and picking a sample is picking the thing you can see. */
.hand-pick {
  margin: 18px 0 4px;
}
.hand-samples {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
  margin-top: 10px;
}
.hand-sample {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 78px;
  padding: 10px 8px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  color: var(--text);
  cursor: pointer;
  overflow: hidden;
  width: auto;
}
.hand-sample:hover {
  border-color: var(--brand);
}
.hand-sample.on {
  border-color: var(--brand);
  box-shadow: inset 0 0 0 1px var(--brand);
}
.hs-ink {
  line-height: 1.25;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* The faces sit on wildly different baselines; a little room under the ink
     stops a descender being clipped by the border. */
  padding-bottom: 2px;
}
.hs-name {
  font-size: 0.6875rem;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

/* ---------- Job address ----------
   Broken into boxes because one free-text line got half-filled — "Mum's" —
   and this is what the customer checks the quote is actually for. */
.job-addr {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* Bottom padding matched to the top. At 4px the last row of fields sat
     five pixels off the border and read as falling out of the box. */
  padding: 14px 16px 18px;
  margin: 0 0 20px;
  min-width: 0;
}
.job-addr legend {
  font-size: 0.8125rem;
  font-weight: 700;
  /* The border is drawn through the legend's own line, so the text needs
     something opaque behind it. The notch a browser cuts for a legend is not
     cut when the fieldset carries a border-radius and padding like this. */
  background: var(--bg);
  padding: 0 8px;
  margin-inline-start: -4px;
  color: var(--text);
}
.job-addr > p.small {
  /* Clear of the legend sitting on the border above it. */
  margin-top: 4px;
}
.ja-find {
  display: flex;
  gap: 10px;
  align-items: end;
}
.ja-find > div {
  flex: 1 1 auto;
  min-width: 0;
}
.ja-find > div input {
  text-transform: uppercase;
}
/* Find sits beside the postcode it acts on, at the same height, and looks
   like the button it is rather than a word floating above the field. */
.ja-find .btn-quiet {
  width: auto;
  flex: 0 0 auto;
  margin-bottom: 0;
  min-height: 48px;
  padding: 0 22px;
  font-weight: 700;
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}
.ja-find .btn-quiet:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
.addr-bad {
  color: var(--danger);
}

/* ---------- Contract-terms templates ----------
   The offer to keep a new set of terms sits under the box and out of the way:
   it is a convenience, not a step, and a trader finishing a quote at half five
   should be able to ignore it entirely. */
.terms-pick {
  margin: 0 0 8px;
}
.terms-pick label {
  display: block;
  margin: 0 0 4px;
  color: var(--text-muted);
  font-weight: 500;
}
.terms-save {
  border-left: 3px solid var(--brand);
  padding: 10px 0 2px 12px;
  margin: 10px 0 0;
}
.terms-save label {
  display: block;
  margin: 0 0 6px;
}
.ts-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.ts-row input {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}
.ts-row .btn-compact {
  width: auto;
  flex: 0 0 auto;
}

/* ---------- Compose attachments ----------
   Under the subject, where every other mail client puts them and where the
   sender is already looking. The remove button is always drawn rather than
   appearing on hover: a phone has no hover, and a chip you cannot get rid of
   on a phone is the worst version of this. */
.cw-attach {
  padding: 8px 14px 4px;
  border-bottom: 1px solid var(--border);
}
.cw-clips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.cw-clip-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  padding: 5px 6px 5px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-inset);
  font-size: 0.8125rem;
}
.cc-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 200px;
}
.cc-size {
  color: var(--text-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}
.cc-kill {
  width: 22px;
  height: 22px;
  min-height: 0;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.cc-kill:hover,
.cc-kill:focus-visible {
  background: var(--danger-bg);
  color: var(--danger);
}
.cw-attach-note {
  margin: 6px 0 2px;
}
.cw-clip {
  width: auto;
  min-height: 36px;
  padding: 0 12px;
  flex: 0 0 auto;
}

/* The overlay covers the message and nothing else — between the subject and
   the signature. A drag anywhere over the window still brings it up, because
   a file dragged off a desktop lands wherever the hand lets go of it, but it
   is drawn over the part the file is about rather than over the addresses
   being typed and the signature being checked. */
.cw-body {
  position: relative;
  display: flex;
}
.cw-body > textarea {
  width: 100%;
}
.cw-drop {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
  /* A staggered outline and a wash of the brand green over the compose area,
     so what is under the cursor is landing somewhere obvious. The label is
     grey and barely there on purpose: it says what will happen, it is not the
     thing being looked at — the file in the hand is. */
  border: 2px dashed var(--brand);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  font-weight: 600;
  color: color-mix(in srgb, var(--text-muted) 70%, transparent);
  pointer-events: none;
}

/* The WhatsApp hand-off. Their green, only on this one button, because it is
   the one place a trader is looking for WhatsApp rather than for QuoteNod. */
.wa-send {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border-color: #25d366;
  color: #128c4a;
}
.wa-send:hover {
  background: rgba(37, 211, 102, 0.1);
}
:root[data-theme='dark'] .wa-send {
  color: #4ee08f;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .wa-send {
    color: #4ee08f;
  }
}
.mi-wa {
  flex: 0 0 auto;
}

/* ---------- Correcting a mistyped address ----------
   Shut by default: most quotes never need it, and a form sitting open invites
   somebody to change what they did not mean to. */
.fix-contact {
  margin: 14px 0 0;
  border-top: 1px solid var(--border);
  padding-top: 12px;
}
.fix-contact > summary {
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 600;
  list-style: none;
  color: var(--text-muted);
}
.fix-contact > summary::-webkit-details-marker {
  display: none;
}
.fix-contact > summary::before {
  content: '▸';
  display: inline-block;
  margin-right: 7px;
  transition: transform 0.15s;
}
.fix-contact[open] > summary {
  color: var(--text);
}
.fix-contact[open] > summary::before {
  transform: rotate(90deg);
}
.fix-contact form {
  margin-top: 12px;
}
.fix-contact label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  margin: 0 0 5px;
}
.fix-contact input {
  margin-bottom: 12px;
}
.fix-contact .btn-quiet {
  width: auto;
  min-width: 160px;
}
@media (prefers-reduced-motion: reduce) {
  .fix-contact > summary::before {
    transition: none;
  }
}

/* ---------- Asking for a change ----------
   The customer's side. Framed around putting something right rather than
   turning the job down, because the common case is a wrong house number and
   the customer is the first person able to see it. */
.edit-topics {
  border: none;
  padding: 0;
  margin: 0 0 14px;
}
.edit-topics legend {
  padding: 0;
  font-weight: 600;
  margin-bottom: 8px;
}
.edit-topics .check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 0 0 8px;
  font-size: 0.9375rem;
}
.edit-topics .check input {
  flex: 0 0 auto;
  margin-top: 2px;
}
/* What they sent, read back to them, and how to reach the trader instead. */
.sent-back {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  padding: 4px 18px 16px;
  margin: 0 0 14px;
}
.sent-back h2 {
  font-size: 0.9375rem;
  margin: 16px 0 8px;
}
.sent-back ul {
  margin: 0 0 10px;
  padding-left: 20px;
  font-size: 0.9375rem;
}
.sent-back li {
  margin: 4px 0;
}
.sent-back.reach {
  border-left: 3px solid var(--brand);
}
.reach-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.reach-list li {
  margin: 6px 0;
  font-size: 1rem;
  font-weight: 600;
}

/* The breach note on the correction form. Not a flash — nothing has gone
   wrong yet — but it has to be read before somebody types over an address. */
.fix-warn {
  border-left: 3px solid var(--warn);
  padding: 8px 0 8px 12px;
  margin: 12px 0;
  color: var(--text);
}

/* Two-factor: the enrolment steps, the QR code, the one-time recovery list. */
.tf-steps {
  padding-left: 22px;
  font-size: 1rem;
}
.tf-steps li {
  margin: 0 0 16px;
}
.tf-qr {
  display: block;
  width: max-content;
  background: #fff;
  padding: 12px;
  border-radius: 8px;
  margin: 10px 0;
  line-height: 0;
}
.tf-qr svg {
  width: 200px;
  height: 200px;
  display: block;
}
.tf-secret code {
  font-size: 1.0625rem;
  letter-spacing: 0.08em;
  word-break: break-all;
  user-select: all;
}
.tf-inline label {
  display: block;
  margin-top: 10px;
}
.tf-inline input {
  max-width: 10em;
}
.tf-codes {
  list-style: none;
  padding: 14px 18px;
  margin: 14px 0;
  border: 1px dashed var(--border);
  border-radius: 8px;
  columns: 2;
  column-gap: 24px;
  max-width: 26em;
}
.tf-codes li {
  margin: 4px 0;
  break-inside: avoid;
}
.tf-codes code {
  font-size: 1rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
  user-select: all;
}
@media (max-width: 480px) {
  .tf-codes {
    columns: 1;
  }
}
.warn-text {
  color: var(--warn);
  font-weight: 600;
}
@media print {
  .no-print,
  nav,
  header {
    display: none !important;
  }
  .tf-codes {
    border-color: #000;
  }
}

/* ---------- The contact log ----------
   In the compose window: a label that opens it, one suggestion under the box
   being typed into, and the strip that offers to keep an address nobody has
   saved. On its own page: a list to correct and thin out. */
.cw-label-btn {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--text-muted);
  cursor: pointer;
  text-align: left;
  border-bottom: 1px dashed transparent;
}
.cw-label-btn:hover,
.cw-label-btn:focus-visible {
  color: var(--brand);
  border-bottom-color: var(--brand);
}
/* Under what is being typed, never over it: the whole point of one suggestion
   rather than a list is that it does not cover the thing it is about. */
.cw-hint {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 6;
  margin-top: 2px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  box-shadow: var(--shadow-1);
  color: var(--text);
  font-size: 0.875rem;
  cursor: pointer;
}
.cw-hint:hover {
  border-color: var(--brand);
}
.cw-chips {
  position: relative;
}

/* The log itself, over the message rather than beside it — it is a thing you
   finish with before carrying on. */
.cw-pick {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgb(0 0 0 / 0.45);
}
.cw-pick-box {
  width: min(520px, 100%);
  max-height: min(560px, 84vh);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow: 0 12px 40px rgb(0 0 0 / 0.35);
}
.cw-pick-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.cw-pick-x {
  appearance: none;
  border: 0;
  background: none;
  font-size: 1.375rem;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
}
.cw-pick-search {
  width: 100%;
}
.cw-pick-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}
.cw-pick-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 4px;
  border-bottom: 1px solid var(--border-soft);
}
.cw-pick-who {
  appearance: none;
  border: 0;
  background: none;
  padding: 4px 2px;
  font: inherit;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.cw-pick-who > * {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cw-pick-who:hover b {
  color: var(--brand);
}
/* The tick is to the right of each, so several can be taken at once without
   the list turning into a column of boxes to aim at first. */
.cw-pick-tick {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  accent-color: var(--brand);
}
.cw-pick-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

/* Offered once, and it never takes the cursor: the message is what is being
   written and this is a thing to deal with in passing or ignore. */
.cw-keep {
  margin: 6px 0 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
  background: var(--bg-card);
}
.cw-keep-ask {
  margin: 0 0 8px;
}
.cw-keep-fields {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.cw-keep-name {
  flex: 1 1 140px;
  min-width: 0;
}
.cw-keep-note {
  flex: 2 1 220px;
  min-width: 0;
}
.cw-keep-fields input {
  margin: 0;
}

/* The page */
.ct-search,
.ct-add {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin: 0 0 12px;
}
.ct-search input,
.ct-add input {
  margin: 0;
  flex: 1 1 160px;
  min-width: 0;
}
.ct-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.ct-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-soft);
}
.ct-who {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 240px;
  min-width: 0;
}
.ct-used {
  flex: 0 0 auto;
}
.ct-row form {
  margin: 0;
}

/* Filtering one customer's history. The chips are the ones the long pages
   already use, so a filter reads as a filter wherever it turns up. */
.cm-filters {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 0 0 12px;
}
.cm-filters .sec-chip {
  cursor: pointer;
}
.cm-next {
  color: var(--text);
  font-weight: 600;
}

/* ---------- Attachments, as tiles ----------
   The same tile on both sides of the send: a picture shows itself, anything
   else shows its extension. The name and what can be done with it stay out of
   the way until the pointer is on the tile, then rise from the bottom of it —
   a row of files is something to glance at, and a row of buttons under every
   one of them is not a glance. */
.at-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  margin: 18px 0 8px;
}
.at-head h3 {
  margin: 0;
}
.at-tiles {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 6px;
  padding: 0;
}
.at-tile {
  position: relative;
  width: 156px;
  height: 112px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  overflow: hidden;
}
.at-tile:hover {
  border-color: var(--brand);
}
.at-face {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  text-decoration: none;
  color: var(--text-muted);
}
.at-face img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.at-kind {
  font:
    700 0.9375rem ui-monospace,
    SFMono-Regular,
    Menlo,
    monospace;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}
/* Held below the tile and slid up under the pointer. Transform rather than
   height so it is the compositor doing the work and not the layout. */
.at-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  background: linear-gradient(to top, rgb(0 0 0 / 0.86), rgb(0 0 0 / 0.62));
  color: #fff;
  transform: translateY(100%);
  transition: transform 0.18s ease;
}
.at-tile:hover .at-bar,
.at-tile:focus-within .at-bar {
  transform: translateY(0);
}
.at-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.8125rem;
  font-weight: 600;
}
.at-size {
  flex: 0 0 auto;
  font-size: 0.75rem;
  opacity: 0.8;
}
.at-more {
  flex: 0 0 auto;
  appearance: none;
  border: 0;
  background: none;
  color: #fff;
  font-size: 0.9375rem;
  line-height: 1;
  padding: 2px 4px;
  cursor: pointer;
  border-radius: 5px;
}
.at-more:hover {
  background: rgb(255 255 255 / 0.18);
}
/* The tile clips its contents so the bar can rise from inside it, which also
   clipped the menu to the tile's width and cut its words off. While the menu
   is open the tile lets it out. */
.at-tile:has(.at-menu:not([hidden])) {
  overflow: visible;
  z-index: 5;
}
.at-menu {
  position: absolute;
  left: 6px;
  bottom: 34px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  min-width: 170px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-raised);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.at-menu a {
  padding: 8px 12px;
  font-size: 0.875rem;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
.at-menu a:hover {
  background: var(--bg-inset);
  color: var(--brand);
}
/* A touch screen has no pointer to hover with, so the bar simply stays. */
@media (hover: none) {
  .at-bar {
    transform: translateY(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .at-bar {
    transition: none;
  }
}

/* The paperwork on a job, and the two ways to send a copy of one. */
.cm-jobs-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  /* room under the heading row, so the download button is not sitting on
     the filter chips */
  margin: 0 0 14px;
}
.cm-jobs-head h2 {
  margin-bottom: 0;
}
.cm-copies {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 8px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--border-soft);
}
.cm-copies form {
  margin: 0;
}
/* One row: which document, then where it goes. The select takes the room
   that is going spare, because a document name is the long part and the two
   buttons are not. On a phone the row wraps and the select goes full width,
   which is the only way a name like "Approval record PDF (signed)" is
   readable at 400px. */
.cm-copyform {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  width: 100%;
}
.cm-copyform label {
  margin: 0;
  flex: 0 0 auto;
}
.cm-copyform select {
  flex: 1 1 200px;
  min-width: 0;
  max-width: 320px;
  width: auto;
}
.cm-copyform button {
  flex: 0 0 auto;
}
/* On a phone the row wraps anyway, so the select is given the whole of its
   own line rather than sharing one and truncating. "Completion certificate
   PDF (signed)" is the name of the thing being chosen; half of it is not. */
@media (max-width: 520px) {
  .cm-copyform select {
    flex: 1 1 100%;
    max-width: none;
  }
}

/* ---- Feature votes ----------------------------------------------------
   A chart somebody votes from, not a chart somebody reads. Every row is a
   button the whole width of the page: the target is the row, because the
   thing being decided is worth more than a 14px link, and on a phone a row
   is the only target anybody can hit reliably. The bar sits under the name
   rather than behind it, so the text never has to survive being drawn over
   a colour. */
.vt-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.vt-head h1 {
  margin-bottom: 0;
}
.vt-chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--accent);
  color: var(--accent-strong);
  background: var(--accent-tint);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 0.75rem;
  font-weight: 600;
}
.vt-chip.is-closed {
  border-color: var(--border);
  color: var(--text-muted);
  background: var(--bg-inset);
}
.vt-intro {
  margin: 10px 0 6px;
  font-size: 1rem;
  line-height: 1.55;
  white-space: pre-wrap;
}
.vt-rules,
.vt-count {
  margin: 4px 0 0;
}
.vt-already {
  margin: 10px 0 0;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  background: var(--bg-raised);
  border-radius: 0 8px 8px 0;
}
.vt-chart {
  margin: 18px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.vt-row {
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--bg-raised);
  padding: 10px 12px;
}
.vt-row.is-mine {
  border-color: var(--accent);
}
.vt-open {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  padding: 2px 0;
  cursor: pointer;
}
.vt-open:hover .vt-more,
.vt-open:focus-visible .vt-more {
  color: var(--link);
}
.vt-name {
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.vt-yours {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 999px;
  padding: 2px 8px;
}
.vt-pct {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}
.vt-more {
  font-size: 0.8125rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.vt-track {
  height: 8px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
  margin-top: 8px;
}
.vt-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--border);
  /* A bar that grows when the page opens reads as a count happening. It is
     one transition on one property, and it is dropped entirely for anybody
     who has asked for less movement. */
  transition: width 420ms ease-out;
}
.vt-row.is-leading .vt-fill {
  background: var(--accent);
}
.vt-row.is-mine .vt-fill {
  background: var(--accent-strong);
}
.vt-votes {
  margin: 6px 0 0;
}
@media (prefers-reduced-motion: reduce) {
  .vt-fill {
    transition: none;
  }
}

/* The feature, opened. Same frame as the broadcast library modal, with room
   for a clip at the top — which is most of what somebody is voting on. */
.vt-modal {
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 0;
  max-width: min(560px, 94vw);
  width: 100%;
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.45);
}
.vt-modal::backdrop {
  background: rgb(4 10 20 / 0.62);
}
.vt-modalbar {
  display: flex;
  align-items: center;
  gap: 12px;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-soft);
  margin: 0;
}
.vt-modalbody {
  padding: 14px;
}
.vt-mediawrap {
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-inset);
  margin-bottom: 12px;
}
.vt-media {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
}
.vt-desc {
  margin: 0 0 12px;
  line-height: 1.55;
  white-space: pre-wrap;
}
.vt-optdesc {
  margin: 4px 0 8px;
  white-space: pre-wrap;
}
.vt-confirm {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--bg-raised);
  cursor: pointer;
}
/* No width here. The checkbox is already drawn at 20px by the rule every
   checkbox in the app shares, and `width: auto` on top of it collapsed the box
   to a green sliver that read as a decoration rather than a control. */
.vt-confirm input {
  margin-top: 2px;
}
.vt-cast {
  margin: 0;
}
.vt-submit {
  margin-top: 10px;
}
.vt-submit[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* The owner's side. */
.vt-adminrow .vt-adminhead {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
/* .btn-row stacks, which is right for a form and wrong for a strip of small
   actions on a card — and each of these actions is its own form, because each
   posts somewhere different. */
.vt-actions,
.vt-adminrow .btn-row,
.vt-adminopt .btn-row {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.vt-actions {
  margin: 10px 0 16px;
}
.vt-actions form,
.vt-adminrow .btn-row form,
.vt-adminopt .btn-row form {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.vt-adminopt .btn-row input[type='file'] {
  max-width: 210px;
  font-size: 0.8125rem;
}
.vt-adminopt {
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
}
.vt-adminopthead {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.vt-adminclip {
  max-width: 220px;
  border-radius: 8px;
  overflow: hidden;
  margin: 6px 0;
  background: var(--bg-inset);
}
.vt-post {
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 10px 12px;
  margin-top: 10px;
}
.vt-posthead {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.vt-caption {
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0;
  font: inherit;
  background: var(--bg-raised);
  border-radius: 8px;
  padding: 10px 12px;
}

/* ---- the books, for whoever does them ---------------------------------- */
.ac-intro {
  max-width: 60ch;
}
.ac-dates {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 12px 0 4px;
}
.ac-dates label {
  margin: 0;
}
.ac-dates input[type='date'] {
  width: auto;
  max-width: 180px;
}
.fin-card i.small {
  font-style: normal;
  display: block;
  margin-top: 2px;
}
.ac-gap {
  max-width: 68ch;
  margin: 10px 0 0;
}
/* What an accountant would have rung about, above the buttons rather than
   below them: a warning under a download is a warning read afterwards. */
.ac-problems {
  position: relative;
  border: 1px solid var(--warn);
  background: var(--warn-bg);
  color: var(--warn);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin: 16px 0 0;
  /* Around the words, not across the page. A warning stretched to the full
     width of a wide screen reads as page furniture; one the size of its own
     sentence reads as something that happened. */
  width: fit-content;
  max-width: min(72ch, 100%);
}
.ac-problems:has(.ac-close) {
  padding-right: 44px;
}
.ac-close {
  position: absolute;
  top: 6px;
  right: 8px;
  border: 0;
  background: transparent;
  color: inherit;
  font-size: 1.375rem;
  line-height: 1;
  padding: 2px 6px;
  border-radius: 6px;
  cursor: pointer;
  opacity: 0.7;
}
.ac-close:hover,
.ac-close:focus-visible {
  opacity: 1;
  background: color-mix(in srgb, currentColor 14%, transparent);
  outline: none;
}

.ac-chip {
  display: grid;
  place-items: center;
  width: 96px;
  height: 48px;
  padding: 6px 10px;
  border-radius: 9px;
  background: #fff;
  box-sizing: border-box;
  /* Nothing may spill out of the chip onto the dark page, whatever a future
     logo's aspect ratio turns out to be. */
  overflow: hidden;
}
/*
 * Sized in pixels rather than percentages on purpose.
 *
 * A percentage max-height on an image centred in a grid does not resolve
 * against the padding box the way it reads as though it should — a square
 * mark came out at 74px inside a 44px chip and hung over both edges. Pixels
 * cannot be argued with.
 */
.ac-chip img {
  display: block;
  width: auto;
  height: auto;
  max-width: 76px;
  max-height: 20px;
}
.ac-mark {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  font-weight: 700;
  font-size: 1rem;
  color: #fff;
  background: #64748b;
}
.ac-problemhead {
  margin: 0 0 6px;
}
.ac-problems ul {
  margin: 0;
  padding-left: 20px;
}
.ac-problems li {
  margin: 3px 0;
}
.ac-problems .muted {
  color: inherit;
  opacity: 0.85;
}
.ac-files {
  display: grid;
  gap: 10px;
}
.ac-file {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--bg-raised);
  padding: 12px 14px;
}
.ac-fileword {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  /* Sized to its own words rather than stretched. A card that spans the page
     puts its button an inch from the right edge and a foot from the sentence
     it belongs to, which reads as two unrelated things. */
  flex: 0 1 auto;
}
.ac-file {
  width: fit-content;
  max-width: 100%;
}
.ac-files .ac-file {
  /* The three in the list stay a consistent width as a set, or they step in
     and out with the length of their own blurb. */
  width: 100%;
  max-width: 640px;
}
.ac-basis {
  opacity: 0.85;
}

/* Picking the package the invoice file is written for. */
.ac-formats {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 8px;
  margin: 0 0 12px;
}
/*
 * Switching package swaps this section rather than loading the page.
 *
 * A held-back opacity while the new one is fetched, so a slow connection shows
 * something happening rather than nothing. Kept mild on purpose: this is
 * usually over in under a tenth of a second, and a heavier animation would be a
 * flash of activity announcing work that had already finished.
 */
#ac-swap {
  transition: opacity 120ms ease;
}
#ac-swap.is-swapping {
  opacity: 0.45;
}
@media (prefers-reduced-motion: reduce) {
  #ac-swap {
    transition: none;
  }
}

/*
 * A card is the package; the link inside it picks the layout.
 *
 * The card is the box rather than the anchor because the chosen one grows a
 * second link out to the package's own site, and an anchor inside an anchor is
 * not a thing HTML will parse — the browser silently closes the first one and
 * the card stops being clickable.
 */
.ac-formatcard {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--bg-raised);
  overflow: hidden;
}
.ac-formatcard:hover {
  border-color: var(--text-faint);
}
.ac-formatcard.is-on {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.ac-format {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  text-decoration: none;
  color: inherit;
  flex: 1 1 auto;
}
.ac-format .ac-chip {
  margin: 0 0 4px;
}
/* Out to the package's own site, and only on the one being looked at — six
   outbound links at once is a row of exits, not a choice. */
.ac-site {
  display: block;
  border-top: 1px solid var(--border-soft);
  padding: 8px 12px;
  font-size: 0.75rem;
  color: var(--accent-text);
  text-decoration: none;
}
.ac-site:hover,
.ac-site:focus-visible {
  text-decoration: underline;
  outline: none;
}
/* Read aloud, never shown: the warning that a link leaves the page. */
.ac-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.ac-chosen {
  border-color: var(--accent);
}
.ac-formatwarn {
  margin-top: 8px;
}
.ac-formatwarn ul {
  margin: 0;
  padding-left: 20px;
}
.ac-needs {
  border-left: 3px solid var(--border);
  padding: 2px 0 2px 12px;
  margin: 10px 0 0;
}
.ac-needs p,
.ac-needs ul {
  margin: 0;
}
.ac-needs ul {
  padding-left: 18px;
}
.ac-needs li {
  margin: 3px 0;
  color: var(--text-muted);
}
.ac-settings {
  margin-top: 18px;
}
.ac-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.ac-fields label {
  margin-top: 0;
}
.ac-fields span.small {
  display: block;
  margin-top: 4px;
}
.ac-save {
  margin-top: 14px;
}

/* The FreeAgent connection, under the FreeAgent format. */
.ac-conn {
  margin-top: 12px;
  border-color: var(--accent);
}
.ac-connhead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.ac-connhead form {
  margin: 0;
}
.ac-connwhat {
  margin: 12px 0 0;
  max-width: 64ch;
}
.ac-actions {
  margin-top: 12px;
}
.ac-subhead {
  margin: 16px 0 6px;
  font-size: 0.875rem;
}
.ac-links,
.ac-log {
  margin: 0;
  padding-left: 18px;
}
.ac-links li,
.ac-log li {
  margin: 3px 0;
}
.ac-log li.is-bad {
  color: var(--warn);
}
/* A failure is a way in, not a sentence: the whole line opens the page that
   fixes it, and looks like something worth pressing. */
.ac-log a.ac-fix {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.ac-log a.ac-fix:hover,
.ac-log a.ac-fix:focus-visible {
  text-decoration-thickness: 2px;
  outline: none;
}
.ac-when {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 12px;
  align-items: center;
  margin: 12px 0;
}
.ac-when select,
.ac-when input {
  min-width: 0;
  width: 100%;
}
@media (max-width: 520px) {
  .ac-when {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}
.ac-timing {
  list-style: none;
  padding: 0;
  margin: 12px 0;
}
.ac-timing li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line, rgba(128, 128, 128, 0.25));
}

/* ---- Connections: is the outside world plugged in? -------------------- */
.ig-where {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 12px;
}
.chip.ig-live {
  background: var(--warn-bg);
  color: var(--warn);
  border-color: var(--warn);
}
.ig-lines {
  list-style: none;
  margin: 0;
  padding: 0;
}
.ig-line {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--border-soft);
}
.ig-line:first-child {
  border-top: 0;
}
/* The mark carries the state, so it is a shape as well as a colour — a red
   and a green dot are the same dot to a colour-blind reader. */
.ig-mark {
  flex: 0 0 auto;
  width: 20px;
  text-align: center;
  font-weight: 700;
}
.ig-line.is-ok .ig-mark {
  color: var(--ok);
}
.ig-line.is-bad .ig-mark {
  color: var(--danger);
}
.ig-line.is-unknown .ig-mark {
  color: var(--warn);
}
.ig-line.is-none .ig-mark {
  color: var(--text-faint);
}
.ig-detail {
  font-size: 0.8125rem;
  word-break: break-all;
}
.ig-fix {
  display: block;
  margin-top: 2px;
}
.ig-when {
  white-space: nowrap;
}
.ig-more {
  margin-top: 12px;
}
.ig-url {
  display: block;
  margin-top: 6px;
  font-size: 0.75rem;
  word-break: break-all;
  background: var(--bg-raised);
  border-radius: 8px;
  padding: 8px 10px;
}
.ig-note {
  margin: 12px 0 0;
}
/**
 * A green rule above each section heading.
 *
 * The page is a long stack of cards and every one of them looks like the last,
 * so a reader loses track of which block they are in. The rule is short and in
 * the brand green rather than a full-width divider: it marks a start without
 * cutting the page into slabs.
 */
.ig-subhead {
  margin: 30px 0 8px;
  padding-top: 14px;
  border-top: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
}
.ig-subhead::before {
  content: '';
  display: block;
  width: 44px;
  height: 3px;
  margin-bottom: 10px;
  border-radius: 2px;
  background: var(--accent);
}
.ig-when {
  white-space: nowrap;
}
.ig-hist {
  margin: 0 0 12px;
}
/* One column per day, tallest = busiest. Successes stack under failures so a
   bad day reads red from the top rather than being hidden under a green pile. */
.ig-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 46px;
  margin: 0 0 6px;
}
.ig-bar {
  flex: 1 1 0;
  min-width: 4px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;
}
.ig-bar i {
  display: block;
  border-radius: 2px 2px 0 0;
}
.ig-bar .ig-bad {
  background: var(--danger, #d64545);
}
.ig-bar .ig-ok {
  background: var(--accent);
  opacity: 0.85;
}
.ig-bar .ig-none {
  background: var(--text-faint);
  opacity: 0.18;
  height: 2px;
}
.ig-histtable {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}
.ig-histtable td {
  padding: 5px 8px 5px 0;
  vertical-align: top;
  border-top: 1px solid var(--line, rgba(127, 127, 127, 0.18));
}
.ig-histtable tr:first-child td {
  border-top: 0;
}
.ig-histtable .ig-histwhen {
  white-space: nowrap;
  color: var(--text-faint);
}
.ig-histtable .ig-histmark {
  width: 1.2em;
}
.ig-account {
  margin-bottom: 10px;
}
.ig-broke {
  border-color: var(--danger);
}
.ig-trace {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.75rem;
  margin: 10px 0 0;
  background: var(--bg-raised);
  border-radius: 8px;
  padding: 10px 12px;
  overflow-x: auto;
}

/* Where a payment plan has got to, above the list of payments. */
.pay-plan {
  margin: 0 0 10px;
  font-size: 0.875rem;
}
.pay-plan.is-behind {
  color: var(--warn);
}
.pay-plan.is-behind .muted {
  color: inherit;
  opacity: 0.75;
}
.pay-behind {
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Roadmap
   A horizontal track you drag along, with the write-up of each stop in a list
   underneath it. Three things about the shape are load-bearing rather than
   decorative:

   - The spine is drawn by the stops themselves, each one painting a segment
     that overhangs the gap on both sides by half. A single line behind the row
     would have to know the row's width, which changes with the content, and
     would break the moment a stop was added.
   - Major stops hang below the spine and minor ones sit above it, always the
     same way round. Alternating looks livelier and costs you the ability to
     tell the size of something without reading it.
   - The reveal animates the tile and the node, never the list item, because the
     list item is carrying the spine — fading that in leaves visible gaps in the
     line as you scroll.
--------------------------------------------------------------------------- */

.rm-wrap {
  max-width: 940px;
}
.rm-head h1 {
  margin-bottom: 4px;
}
.rm-tally {
  margin: 10px 0 0;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 0.875rem;
}
.rm-now-pill {
  background: var(--accent-tint);
  color: var(--ok);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 0.78125rem;
  font-weight: 700;
}

/* ---- the strip ---- */

.rm-strip {
  margin: 18px 0 8px;
}
.rm-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  /* No scroll snapping, deliberately. Snapping is for a carousel where every
     position but one is wrong; a timeline has no wrong positions, and a track
     that slides itself somewhere else after you let go of it has overruled
     you. Stopping between two stops to compare them is a thing somebody does
     on purpose. */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  padding: 4px 2px 14px;
  /* The browser's own bar is hidden because the green rail below the track
     says the same thing and says it better. Hiding a scrollbar usually costs
     the only sign that a box scrolls at all — here it does not, because the
     rail, the arrows and the "drag, swipe or use the arrows" line are all
     still there, and the tiles run off the edge of the track besides. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  border-radius: var(--radius-lg);
}
.rm-scroll:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}
.rm-scroll.is-dragging {
  cursor: grabbing;
  user-select: none;
}
.rm-scroll::-webkit-scrollbar {
  display: none;
}
.rm-line {
  list-style: none;
  margin: 0;
  padding: 0 6px;
  display: flex;
  align-items: stretch;
  gap: 28px;
}
.rm-line {
  --rm-big-h: 214px;
  --rm-small-h: 150px;
  --rm-drop: 28px;
  /* Where the spine sits. Measured from the top rather than centred: the
     half above the line only ever holds a small tile, so centring leaves a
     band of empty space the width of the whole track. */
  --rm-mid: calc(var(--rm-small-h) + var(--rm-drop));
}
.rm-stop {
  position: relative;
  flex: none;
  height: calc(var(--rm-mid) + var(--rm-drop) + var(--rm-big-h) + 10px);
}
.rm-big {
  width: 268px;
}
.rm-small {
  width: 200px;
}
.rm-now {
  width: 74px;
}
.rm-more {
  width: 240px;
}
.rm-more::before {
  border-top-style: dotted;
  right: 40%;
}
.rm-more-tile {
  position: absolute;
  left: 0;
  right: 24px;
  top: calc(var(--rm-mid) - 44px);
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 18px;
  border-radius: 14px;
  border: 1.5px dashed var(--accent);
  background: rgb(23 201 111 / 0.06);
  color: var(--text);
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.45s ease,
    transform 0.45s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.rm-more-tile b {
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}
.rm-more-tile span {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.rm-stop.is-in .rm-more-tile {
  opacity: 1;
  transform: none;
}

/* the spine, in segments */
.rm-stop::before {
  content: '';
  position: absolute;
  top: var(--rm-mid);
  left: -16px;
  right: -16px;
  height: 0;
  border-top: 2px dashed var(--border);
  transform: translateY(-1px);
}
.rm-stop.rm-shipped::before,
.rm-stop.rm-now::before {
  border-top: 3px solid var(--accent);
  transform: translateY(-1.5px);
}

/* the dot on the line */
.rm-node {
  position: absolute;
  top: var(--rm-mid);
  left: 50%;
  width: 13px;
  height: 13px;
  margin: -6.5px 0 0 -6.5px;
  border-radius: 50%;
  background: var(--bg);
  border: 3px solid var(--border);
  z-index: 2;
}
.rm-shipped .rm-node {
  border-color: var(--accent);
  background: var(--accent);
}
.rm-building .rm-node {
  border-color: var(--accent);
  background: var(--bg);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* today */
.rm-node-now {
  width: 0;
  height: 104px;
  margin: -52px 0 0 -1px;
  border-radius: 0;
  background: transparent;
  border: 0;
  border-left: 2px dashed var(--text-faint);
}
.rm-now-label {
  position: absolute;
  top: calc(var(--rm-mid) + 60px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.71875rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  white-space: nowrap;
}

/* ---- a tile ---- */

.rm-tile {
  position: absolute;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-decoration: none;
  color: inherit;
  background: var(--bg-raised);
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  padding: 14px;
  box-shadow: var(--shadow-1);
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease,
    border-color 0.18s ease;
}
.rm-big .rm-tile {
  top: calc(var(--rm-mid) + var(--rm-drop));
  height: var(--rm-big-h);
}
.rm-small .rm-tile {
  top: 0;
  height: var(--rm-small-h);
  padding: 12px;
}
.rm-tile::after {
  content: '';
  position: absolute;
  left: 50%;
  width: 0;
  height: var(--rm-drop);
  border-left: 2px dashed var(--border);
}
.rm-big .rm-tile::after {
  top: calc(var(--rm-drop) * -1);
}
.rm-small .rm-tile::after {
  bottom: calc(var(--rm-drop) * -1);
}
.rm-shipped .rm-tile::after {
  border-left: 2px solid var(--accent);
  opacity: 0.55;
}
.rm-tile:hover,
.rm-tile:focus-visible {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 6px 18px rgb(11 22 38 / 0.14);
}
.rm-tile.is-open {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}
.rm-pic {
  display: block;
  color: var(--accent-text);
}
.rm-art {
  display: block;
  width: 48px;
  height: 48px;
}
.rm-small .rm-art {
  width: 34px;
  height: 34px;
}
.rm-art .rm-fill {
  fill: currentColor;
  stroke: none;
}
.rm-art .rm-ink {
  color: var(--accent-text);
}
.rm-later .rm-pic,
.rm-next .rm-pic {
  color: var(--text-faint);
}
.rm-when {
  font-size: 0.71875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.rm-name {
  font-size: 0.96875rem;
  line-height: 1.25;
  flex: none;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.rm-small .rm-name {
  font-size: 0.90625rem;
}
.rm-blurb {
  font-size: 0.78125rem;
  color: var(--text-muted);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: none;
}
/* A small tile carries its picture, its date and its name and stops there.
   The one-liner is in the entry below it, and a small tile with four things
   in it is not a small tile. */
.rm-small .rm-blurb {
  display: none;
}
.rm-badge {
  align-self: flex-start;
  margin-top: auto;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 3px 9px;
  background: var(--bg-inset);
  color: var(--text-muted);
  border: 1px solid var(--border-soft);
}
.rm-shipped .rm-badge {
  background: var(--ok-bg);
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 30%, transparent);
}
.rm-building .rm-badge {
  background: var(--warn-bg);
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
}

/* ---- arriving ---- */

.rm-stop .rm-tile,
.rm-stop .rm-node,
.rm-stop .rm-now-label {
  opacity: 0;
  transition:
    opacity 0.45s ease,
    transform 0.45s cubic-bezier(0.2, 0.7, 0.3, 1);
  transition-delay: calc(min(var(--rm-i, 0), 6) * 40ms);
}
.rm-big .rm-tile {
  transform: translateY(16px) scale(0.97);
}
.rm-small .rm-tile {
  transform: translateY(-16px) scale(0.97);
}
.rm-stop .rm-node {
  transform: scale(0.2);
}
.rm-stop.is-in .rm-tile,
.rm-stop.is-in .rm-node,
.rm-stop.is-in .rm-now-label {
  opacity: 1;
  transform: none;
}

/* ---- rail and arrows ---- */

.rm-rail {
  height: 5px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
}
.rm-rail-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.12s linear;
}
.rm-arrows {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 10px;
}
.rm-arrow {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  background: var(--bg-raised);
  color: var(--text);
  display: grid;
  place-items: center;
  cursor: pointer;
}
.rm-arrow:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}
.rm-arrow svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rm-hint {
  font-size: 0.78125rem;
  color: var(--text-faint);
}

/* ---- the log ---- */

.rm-log {
  margin-top: 26px;
}
.rm-log h2 {
  margin-bottom: 2px;
}
.rm-entry {
  border: 1.5px solid var(--border-soft);
  border-radius: 14px;
  background: var(--bg-raised);
  margin: 12px 0;
  overflow: hidden;
}
.rm-entry[open] {
  border-color: var(--accent);
}
.rm-sum {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  cursor: pointer;
  list-style: none;
}
.rm-sum::-webkit-details-marker {
  display: none;
}
.rm-sum:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: -3px;
}
.rm-sum-pic {
  flex: none;
  color: var(--accent-text);
}
.rm-sum-pic .rm-art {
  width: 40px;
  height: 40px;
}
.rm-next .rm-sum-pic,
.rm-later .rm-sum-pic {
  color: var(--text-faint);
}
.rm-sum-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.rm-sum-top {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.rm-sum-top .rm-badge {
  margin-top: 0;
}
.rm-sum-date {
  font-size: 0.75rem;
  color: var(--text-faint);
  font-weight: 700;
}
.rm-ver {
  font-size: 0.75rem;
  font-weight: 800;
  color: var(--text-muted);
}
.rm-draft {
  background: var(--warn-bg);
  color: var(--warn);
}
.rm-sum-title {
  font-size: 1rem;
}
.rm-sum-blurb {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.rm-chev {
  margin-left: auto;
  flex: none;
  color: var(--text-muted);
  transition: transform 0.2s ease;
}
.rm-chev svg {
  display: block;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rm-entry[open] .rm-chev {
  transform: rotate(180deg);
}
.rm-body {
  padding: 0 14px 14px;
  border-top: 1px solid var(--border-soft);
}
.rm-body > p {
  margin: 12px 0;
  line-height: 1.55;
}
.rm-body .demo {
  margin-top: 14px;
}
.rm-caveat {
  font-size: 0.8125rem;
  color: var(--text-muted);
  background: var(--bg-inset);
  border-left: 3px solid var(--border);
  border-radius: 0 8px 8px 0;
  padding: 10px 12px;
}

/* ---- smaller screens ---- */

@media (max-width: 640px) {
  .rm-line {
    --rm-big-h: 190px;
    --rm-small-h: 126px;
    --rm-drop: 22px;
    gap: 20px;
  }
  .rm-big {
    width: 216px;
  }
  .rm-small {
    width: 168px;
  }
  .rm-now {
    width: 52px;
  }
  .rm-art {
    width: 42px;
    height: 42px;
  }
  .rm-small .rm-art {
    width: 30px;
    height: 30px;
  }
  .rm-hint {
    display: none;
  }
  .rm-sum-pic {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rm-stop .rm-tile,
  .rm-stop .rm-node,
  .rm-stop .rm-now-label {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .rm-tile:hover,
  .rm-tile:focus-visible {
    transform: none;
  }
  .rm-chev {
    transition: none;
  }
}

/* ---- the error page ---- */
.er-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin: 0 0 6px;
}
.er-metric {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.er-metric.er-quiet {
  opacity: 0.75;
}
.er-big {
  font-size: 1.75rem;
  line-height: 1.1;
}
.er-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 90px;
}
.er-bar {
  flex: 1 1 0;
  min-width: 6px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
}
.er-bar i {
  display: block;
  width: 100%;
  border-radius: 3px 3px 0 0;
  background: var(--danger, #c92a2a);
}
.er-bar i.er-none {
  height: 2px;
  background: var(--text-faint);
  opacity: 0.18;
}
.er-barnum {
  font-size: 0.6875rem;
  color: var(--text-faint);
  min-height: 14px;
}
.er-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}
.er-table th {
  text-align: left;
  font-size: 0.75rem;
  color: var(--text-faint);
  padding: 0 10px 6px 0;
  font-weight: 600;
}
.er-table td {
  padding: 7px 10px 7px 0;
  vertical-align: top;
  border-top: 1px solid var(--line, rgba(127, 127, 127, 0.18));
}
.er-ctx {
  font-size: 0.75rem;
  word-break: break-all;
}
.er-when {
  white-space: nowrap;
  color: var(--text-faint);
}
.er-stack pre {
  font-size: 0.6875rem;
  white-space: pre-wrap;
  margin: 4px 0 0;
}
.er-copy {
  width: 100%;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  line-height: 1.5;
}

/* ---- the site-wide legal footer ----
   The footer sits inside the page's own column and runs the whole width of
   it, in the app's own text size. The public site draws the same footer from
   marketing.css, which says the same thing: change one and change the other. The twelve links are a grid, so every row is
   a full one at every width: two across on a phone, each a thumb's height,
   then four, six, and all twelve in one row once there is room for them,
   standing together from the left rather than spread across the width.
   Under them the company paragraph and the copyright line share the width
   side by side on a wide screen, so neither is a line eighteen hundred pixels
   long that nobody finishes, and sit one under the other below that.

   This block was written twice, identically but for the width, and the second
   copy quietly won — so the first was edited for a while with nothing to show
   for it. One copy now. */
.qn-foot {
  margin: 48px 0 0;
  padding: 20px 16px 34px;
  border-top: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
  color: var(--text-faint);
  font-size: 1rem;
  line-height: 1.6;
  container-type: inline-size;
}

.qn-footlinks {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, auto));
  column-gap: 16px;
  font-size: 0.875rem;
  margin-bottom: 12px;
}
.qn-footlinks a {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-faint);
  text-decoration: none;
}
.qn-footlinks a:hover {
  color: var(--accent-text);
  text-decoration: underline;
}
.qn-footco {
  margin: 0 0 8px;
  max-width: none;
  text-wrap: pretty;
}
@media (min-width: 760px) {
  .qn-foot {
    padding-inline: 24px;
  }
  .qn-footlinks {
    grid-template-columns: repeat(4, auto);
    justify-content: start;
    column-gap: 1.25em;
    font-size: 1rem;
  }
  .qn-footlinks a {
    min-height: 36px;
    white-space: nowrap;
  }
}
@media (min-width: 1000px) {
  .qn-foot {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(22em, calc(50% - 24px))), 1fr));
    column-gap: 48px;
  }
  .qn-footlinks {
    grid-column: 1 / -1;
  }
  .qn-footco {
    margin: 0;
  }
}
@media (min-width: 1280px) {
  .qn-footlinks {
    grid-template-columns: repeat(6, auto);
  }
}
@media (min-width: 1760px) {
  .qn-footlinks {
    grid-template-columns: repeat(12, auto);
  }
}
/* The reader's text size has the last word. The widths above count the
   window; these count the footer's own room in the size its words are set
   in, so larger text gets fewer links to a row before any of them is pushed
   off the page, and the two paragraphs go one under the other when half the
   width is too narrow to read. */
@container (max-width: 103em) {
  .qn-footlinks {
    grid-template-columns: repeat(6, auto);
  }
}
@container (max-width: 60.3em) {
  .qn-footlinks {
    grid-template-columns: repeat(4, auto);
  }
}
@container (max-width: 43.6em) {
  .qn-footlinks {
    grid-template-columns: repeat(2, minmax(0, auto));
    justify-content: normal;
    column-gap: 16px;
  }
  .qn-footlinks a {
    white-space: normal;
  }
}
@container (max-width: 16em) {
  .qn-footlinks {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* "A−", the size in use and "A+": the reader's own text size, as the last
   row of the footer at its right-hand end. Hidden until the script in the
   head of the page has run (see text-size.ts): without it they do nothing.
   The public site draws the same three from marketing.css. */
.qn-textsize {
  display: none;
  grid-column: 1 / -1;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}
html[data-textstep] .qn-textsize {
  display: flex;
}
.qn-textsize button {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: transparent;
  color: var(--text-faint);
  font: 600 0.875rem/1 var(--font);
  cursor: pointer;
}
.qn-textsize .qn-ts-now {
  min-width: 3.75em;
}
.qn-textsize button:hover {
  color: var(--accent-text);
  border-color: currentColor;
}
.qn-textsize button[aria-disabled='true'] {
  color: var(--text-faint);
  border-color: var(--border);
  cursor: default;
}
.qn-textsize button[aria-disabled='true']:not(.qn-ts-now) {
  opacity: 0.45;
}
.qn-ts-says {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* The help button floats in the same corner from a tablet up: 58px of it,
   18px from the edge. The three stand to the left of it. */
@media (min-width: 768px) {
  body:has(.qn-fab) .qn-textsize {
    margin-right: 60px;
  }
}
/* An iPhone zooms the whole page when a box with text under 16px is tapped,
   so at a step below the usual size the boxes keep the usual size: the
   step, which the script leaves in --text-step, is divided back out. */
html[data-textsmall] :is(input, select, textarea) {
  font-size: calc(1rem / var(--text-step, 1));
}

/* The menu a selection raises.
   Borrowed from the menus the ribbon already opens — same card, same items —
   because it is the same kind of thing and learning it twice would be one
   time too many. Fixed rather than absolute: it is placed against the window,
   which is where the click was measured. */
.qn-sel-menu {
  position: fixed;
  z-index: 80;
  min-width: 190px;
  padding: 6px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.42);
}
.qn-sel-menu .cm-item {
  display: block;
  width: 100%;
  text-align: left;
  margin: 0;
}

/* ---- the colour key ---- */
.key {
  margin: 0 0 12px;
}
.key > summary {
  cursor: pointer;
}
.key-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.key-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
}

/* ---- extra work on a job ---- */
.mq-family {
  margin: 14px 0;
}
.mq-list {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.mq-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.mq-route {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 0;
  cursor: pointer;
}
.mq-route input {
  margin-top: 3px;
}

/* ---- help centre: shelves, draggable rails, and the guide pop-up ---- */
#help-shelves {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
}
.shelf {
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-raised);
  overflow: hidden;
}
.shelf > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
/* the default triangle sits where the chevron goes, in two different places */
.shelf > summary::-webkit-details-marker {
  display: none;
}
.shelf > summary::marker {
  content: '';
}
.shelf > summary:hover .shelf-title b {
  color: var(--accent-text);
}
.shelf-title {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 2px;
}
.shelf-title b {
  font-size: 1.03125rem;
  transition: color 0.15s ease;
}
.shelf-blurb {
  color: var(--text-muted);
  font-size: 0.8125rem;
}
.shelf-count {
  margin-left: auto;
  color: var(--text-muted);
  font-size: 0.78125rem;
  white-space: nowrap;
}
.shelf-chev {
  display: flex;
  color: var(--text-muted);
  transition: transform 0.18s ease;
}
.shelf[open] > summary {
  border-bottom: 1px solid var(--border);
}
.shelf[open] .shelf-chev {
  transform: rotate(180deg);
}
.shelf-body {
  padding: 12px 16px 14px;
}
.rail {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 10px;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 2px;
}
.rail::-webkit-scrollbar {
  display: none;
}
.rail-card {
  flex: 0 0 calc(50% - 5px);
  align-self: stretch;
  align-items: flex-start;
  flex-direction: column;
  justify-content: space-between;
  gap: 10px;
  margin: 0;
  padding: 14px 16px;
}
.rail-card .who span {
  line-height: 1.45;
}
/* the foot of every card says what pressing it does, and fills the space a
   short summary leaves under a long one */
.rail-card::after {
  content: 'Read the guide \2192';
  display: block;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--accent-strong, var(--accent));
}
/* a guide's title is a sentence, not a customer name — it wraps rather than
   being cut off with an ellipsis the way a row in a list would be */
.rail-card .who {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.rail-card .who b {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.3;
}
@media (max-width: 620px) {
  .rail-card {
    flex-basis: 100%;
  }
}
/* mid-drag the pointer must not land on a card, or letting go opens it */
.rail.is-dragging {
  cursor: grabbing;
  scroll-behavior: auto;
  user-select: none;
}
.rail.is-dragging .rail-card {
  pointer-events: none;
}
.rail-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
.rail-dot {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 7.5px solid transparent;
  border-radius: 50%;
  background: var(--border);
  background-clip: padding-box;
  cursor: pointer;
  transition:
    background 0.15s ease,
    transform 0.15s ease;
}
.rail-dot:hover {
  background: var(--text-muted);
}
.rail-dot.is-on {
  background: var(--accent);
  transform: scale(1.3);
}
.help-pop {
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 0;
  max-width: min(620px, 94vw);
  width: 100%;
  max-height: 86vh;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.45);
}
.help-pop::backdrop {
  background: rgb(4 10 20 / 0.62);
}
.help-pop-body {
  padding: 20px 22px 8px;
  overflow-y: auto;
  max-height: calc(86vh - 86px);
}
.help-pop-body h2 {
  margin: 0 0 10px;
  font-size: 1.3125rem;
}
.help-pop-body .demo {
  max-width: 100%;
}
.help-pop-foot {
  display: flex;
  justify-content: center;
  padding: 12px 22px 16px;
  border-top: 1px solid var(--border);
  background: var(--bg-raised);
}
.help-pop-foot .btn {
  width: auto;
  min-width: 180px;
  min-height: 48px;
  padding: 0 28px;
}

/* ---- announcements: the two faces, the ratio bar, and the comments ---- */
.an-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.an-head h1 {
  margin: 0;
}
.an-head .btn-compact {
  margin-left: auto;
}
.an-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 16px 0 24px;
}
.an-card .who {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.an-card .who b {
  white-space: normal;
}
.an-when {
  margin-top: 2px;
}
.an-body {
  margin: 14px 0 22px;
}

/* the reaction buttons */
.an-react form {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.an-thumb {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1 1 200px;
  min-height: 66px;
  padding: 10px 16px;
  border: 2px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  color: var(--text);
  font: 600 0.9375rem var(--font);
  cursor: pointer;
  transition:
    border-color 0.16s ease,
    transform 0.16s ease,
    background 0.16s ease;
}
.an-thumb:hover {
  transform: translateY(-2px);
}
.an-thumb-up.is-on {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--bg-raised));
}
.an-thumb-down.is-on {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 12%, var(--bg-raised));
}
.an-react-note {
  margin: 10px 0 0;
}
.nod-face {
  flex: 0 0 auto;
}
.nod-head {
  transform-origin: 32px 32px;
}
/* Everything that moves is a transform or an opacity: animating the mouth's
   own path would be the obvious way to turn a smile over, and it is the one
   thing here that does not work in every browser. */
.an-thumb-up:hover .nod-head,
.an-thumb-up.is-on .nod-head {
  animation: nod-wink 1.4s ease-in-out infinite;
}
.an-thumb-up:hover .nod-eye-r,
.an-thumb-up.is-on .nod-eye-r {
  animation: nod-eye-shut 1.4s ease-in-out infinite;
}
.an-thumb-up:hover .nod-wink,
.an-thumb-up.is-on .nod-wink {
  animation: nod-arc 1.4s ease-in-out infinite;
}
.an-thumb-down:hover .nod-head,
.an-thumb-down.is-on .nod-head {
  animation: nod-droop 2s ease-in-out infinite;
}
.an-thumb-down:hover .nod-tear,
.an-thumb-down.is-on .nod-tear {
  animation: nod-tear 2s ease-in-out infinite;
}
@keyframes nod-wink {
  0%,
  55%,
  100% {
    transform: rotate(0deg);
  }
  70% {
    transform: rotate(-7deg) translateY(-2px);
  }
}
@keyframes nod-eye-shut {
  0%,
  55%,
  100% {
    opacity: 0.45;
  }
  62%,
  80% {
    opacity: 0;
  }
}
@keyframes nod-arc {
  0%,
  55%,
  100% {
    opacity: 0;
  }
  62%,
  80% {
    opacity: 1;
  }
}
@keyframes nod-droop {
  0%,
  100% {
    transform: rotate(0deg) translateY(0);
  }
  50% {
    transform: rotate(6deg) translateY(3px);
  }
}
@keyframes nod-tear {
  0%,
  30% {
    opacity: 0;
    transform: translateY(0);
  }
  45% {
    opacity: 1;
    transform: translateY(0);
  }
  85%,
  100% {
    opacity: 0;
    transform: translateY(22px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .an-thumb .nod-head,
  .an-thumb .nod-eye-r,
  .an-thumb .nod-wink,
  .an-thumb .nod-tear {
    animation: none !important;
  }
}

/* the owner's metrics */
.an-metrics {
  margin: 18px 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  overflow: hidden;
}
.an-metrics > summary {
  padding: 12px 16px;
  cursor: pointer;
  font-weight: 700;
}
.an-metrics-body {
  padding: 0 16px 16px;
}
.an-track {
  display: flex;
  height: 14px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--border);
}
.an-track.is-quiet {
  opacity: 0.45;
}
.an-fill-up {
  background: var(--accent);
}
.an-fill-down {
  background: var(--danger);
}
.an-mood {
  margin: 8px 0 12px;
  color: var(--text-muted);
}
.an-figs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin: 0 0 12px;
}
.an-figs div {
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 8px 10px;
}
.an-figs dt {
  font-size: 0.75rem;
  color: var(--text-muted);
}
.an-figs dd {
  margin: 2px 0 0;
  font-size: 1.125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.an-owner {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 22px;
}

/* ---------- owner tools, and what they make ----------
   The row of admin buttons above the vote and the announcements, the drafts
   written about one of them, and the Facebook tally typed in by hand. Held
   together here because they are one feature wherever they are drawn. */
.ct-tools {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 10px 0 16px;
  align-items: center;
}
.ct-tools .btn-compact {
  margin: 0;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
}
.an-social {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  margin: 0 0 18px;
}
.an-social h3 {
  margin: 0 0 8px;
  font-size: 0.9375rem;
}
.an-drafts {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: grid;
  gap: 6px;
}
.an-drafts li {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
}
.vt-fb {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin: 22px 0 0;
}
.vt-fb h2 {
  margin: 0 0 6px;
  font-size: 1rem;
}
.vt-fb-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
.vt-fb-list li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 5px;
}
.vt-fb-list b {
  font-variant-numeric: tabular-nums;
}
.vt-fb-form {
  margin-top: 18px;
}
.vt-fb-rows {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}
.vt-fb-row {
  display: grid;
  grid-template-columns: 1fr 110px;
  gap: 10px;
  align-items: center;
}
@media (max-width: 560px) {
  .vt-fb-row {
    grid-template-columns: 1fr;
  }
}

/* the poll asked alongside */
.an-poll {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  background: var(--bg-raised);
  margin: 0 0 22px;
}
.an-poll h2 {
  margin-top: 0;
}
.an-poll-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 0;
}
.an-poll-row.is-mine .an-poll-name {
  font-weight: 700;
  color: var(--accent-text);
}
.an-poll-row form,
.an-poll-name {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
}
.an-poll-pct {
  flex: 0 0 auto;
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}
.an-poll-track {
  flex: 1 0 100%;
  height: 8px;
  border-radius: 5px;
  background: var(--border);
  overflow: hidden;
}
.an-poll-fill {
  display: block;
  height: 100%;
  background: var(--accent);
}

/* comments */
.an-comments-h {
  display: flex;
  align-items: center;
  gap: 10px;
}
.an-comments {
  list-style: none;
  padding: 0;
  margin: 0 0 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.an-comment {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  background: var(--bg-raised);
}
.an-comment.is-gone {
  opacity: 0.72;
}
.an-by {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 6px;
}
.an-said {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.an-mod {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}
.an-mod form {
  display: flex;
  gap: 6px;
  align-items: center;
}
.an-mod input[type='text'] {
  width: 180px;
}
.an-hours {
  width: 72px;
}
.an-say {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 24px;
}
.an-say button {
  align-self: flex-start;
}
.an-check {
  display: flex;
  align-items: center;
  gap: 6px;
}
.an-later {
  text-align: center;
  margin-top: 8px;
}
.user-name-form {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.user-name-form input {
  max-width: 260px;
}

/* writing one */
.an-compose {
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 0;
  max-width: min(640px, 94vw);
  width: 100%;
  max-height: 88vh;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.45);
}
.an-compose::backdrop {
  background: rgb(4 10 20 / 0.62);
}
.an-compose-body {
  padding: 20px 22px 8px;
  overflow-y: auto;
  max-height: calc(88vh - 132px);
}
.an-compose-body h2 {
  margin-top: 0;
}
.an-compose-body .an-opt {
  margin-bottom: 6px;
}
.an-compose-foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 22px;
  border-top: 1px solid var(--border);
  background: var(--bg-raised);
}
.an-compose-foot .btn {
  width: auto;
  min-height: 46px;
  padding: 0 22px;
}
.an-compose-close {
  padding: 0 22px 14px;
  background: var(--bg-raised);
  text-align: right;
}

/* ---- inside the desktop app: the mail's header IS the title bar ---- */
/*
   None of this does anything in a browser. The class is added by the desktop
   wrapper and exists nowhere else, so the same stylesheet serves both.

   The window has no frame of its own, which is the whole point — no strip of
   grey above the app with a second copy of its name in it. In exchange the
   page owes the window two things it normally gets for free: somewhere to
   drag it by, and somewhere for the minimise, maximise and close buttons to
   sit without landing on top of something.
*/
.qn-desktop {
  /* How wide Windows' own controls are, and how tall the strip is. The
     fallbacks are what they measure at 100% scaling; the real numbers are read
     off the window itself at load and written over these, because at 125% or
     150% the controls are wider and anything hard-coded ends up underneath
     them. */
  --qn-wco-w: 152px;
  --qn-wco-h: 48px;
}
.qn-desktop .mail-top {
  -webkit-app-region: drag;
  padding-right: calc(var(--qn-wco-w) + 16px);
  min-height: 48px;
}
/*
   Everything clickable is handed back. A button inside a drag region is not a
   button — the press starts a window move and the click never arrives — and
   the failure looks like a dead button rather than like a layout problem.
*/
.qn-desktop .mail-top button,
.qn-desktop .mail-top a,
.qn-desktop .mail-top input,
.qn-desktop .mail-top select,
.qn-desktop .mail-top textarea,
.qn-desktop .mail-top form,
.qn-desktop .mail-ask-pop,
.qn-desktop .mail-ask-scrim {
  -webkit-app-region: no-drag;
}
/* Pages with no header of their own — the log-in screen — still have to be
   draggable, or the window is stuck where it opened. */
.qn-desktop #qn-drag {
  position: fixed;
  top: 0;
  left: 0;
  right: var(--qn-wco-w);
  height: var(--qn-wco-h);
  z-index: 40;
  -webkit-app-region: drag;
}
/* The page below the strip has to clear it. Which element that is differs
   from page to page, so the wrapper adds a class rather than the stylesheet
   guessing at a sibling. */
.qn-chrome-strip .wrap,
.qn-chrome-strip .wrap-narrow {
  padding-top: 56px;
}

/* The top edge, kept resizable inside the desktop app. Above everything, so
   it wins over the header's drag region beneath it. */
.qn-desktop #qn-resize-top {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  z-index: 9999;
  -webkit-app-region: no-drag;
}

/* ---- the scrollbar, everywhere ----
   The browser's default is a pale grey bar with arrow buttons on the ends,
   which on a navy page reads as a piece of somebody else's software sitting
   inside ours. This is the same green thumb and slim track already used on
   Nod's panels and the dashboard filter row, promoted to the default so the
   whole app agrees with itself.

   The thumb is drawn inside a transparent border, so the gutter can be wide
   enough to grab with a mouse while the bar you see stays slim. */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}
::-webkit-scrollbar {
  /* Eight rather than ten, with two of those spent on the transparent border
     below — so the bar you see is four pixels and the gutter you can grab is
     still eight. A scrollbar is a readout, not a control you aim at: what it
     is mostly doing is telling you how much of the list you are looking at,
     and it does that better thin. */
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--accent);
  background-clip: content-box;
  border: 2px solid transparent;
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--accent-strong);
  background-clip: content-box;
}
::-webkit-scrollbar-corner {
  background: transparent;
}
/* the little arrow buttons at each end are not part of the design */
::-webkit-scrollbar-button {
  display: none;
}

/* Full screen: no title bar, so nothing to leave room for and nothing to drag
   the window by. The header goes back to an ordinary header. */
.qn-desktop.qn-fullscreen .mail-top {
  padding-right: 16px;
}
.qn-desktop.qn-fullscreen {
  --qn-wco-w: 0px;
}
.qn-desktop.qn-fullscreen #qn-drag,
.qn-desktop.qn-fullscreen #qn-resize-top {
  display: none;
}
.qn-desktop.qn-fullscreen.qn-chrome-strip .wrap,
.qn-desktop.qn-fullscreen.qn-chrome-strip .wrap-narrow {
  padding-top: 0;
}

/* The window buttons, each in its own broken green bracket.
   Windows paints minimise, maximise and close itself, on a strip whose colour
   the wrapper sets to match this header — so they sit on the same background
   as everything else rather than in a slab of their own. It will not tell us
   where each button is, but it does tell us how wide the three of them are
   together, and it draws them at equal widths — so three equal cells across
   that measured width land on them.

   Sides and bottom, no top: the strip runs to the very top of the window and a
   line there would be half off the screen. */
.qn-desktop .mail-top {
  position: relative;
}
#qn-wco {
  position: fixed;
  top: 0;
  right: 0;
  width: var(--qn-wco-w);
  height: var(--qn-wco-h);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  z-index: 41;
  pointer-events: none;
}
#qn-wco span {
  border-left: 1px dashed var(--accent);
  border-bottom: 1px dashed var(--accent);
  opacity: 0.55;
}
#qn-wco span:last-child {
  border-right: 1px dashed var(--accent);
}
/* Nothing is drawn there in full screen, so nothing is marked off. */
.qn-desktop.qn-fullscreen #qn-wco {
  display: none;
}

/* ---- KPIs ----
   Stat tiles rather than charts: each of these is one current number and a
   change, and a one-bar bar chart would be decoration. The verdict is drawn
   three ways at once — colour, arrow, word — because colour alone says
   nothing to a reader who cannot separate the green from the amber, and
   nothing at all in print. */
.kpi-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 2px;
}
.kpi-head h1 {
  margin: 0;
}
.kpi-hero {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  padding: 20px 22px 18px;
  margin: 16px 0 22px;
}
/* Proportional figures, not tabular: at this size tabular-nums leaves a
   number like 121 looking gappy. The columns in the compare table are the
   place for tabular. */
.kpi-hero-num {
  margin: 2px 0 6px;
  font-size: clamp(2.5rem, 11vw, 3.5rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--text);
}
.kpi-group {
  margin: 0 0 26px;
}
.kpi-group h2 {
  margin-bottom: 2px;
}
.kpi-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin-top: 12px;
}
.kpi-tile {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  padding: 14px 16px 12px;
}
.kpi-label {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-muted);
}
.kpi-value {
  margin: 4px 0 6px;
  font-size: 1.6875rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
}
.kpi-help {
  margin: 8px 0 0;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--text-faint);
}
/* The change. The arrow and the word are the channels that survive greyscale,
   so they are never dropped on small screens. */
.kpi-delta {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 5px;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-muted);
}
.kpi-delta.is-better {
  color: var(--ok);
}
.kpi-delta.is-worse {
  color: var(--warn);
}
.kpi-pct {
  font-weight: 500;
  opacity: 0.85;
}
.kpi-word {
  font-weight: 700;
}
.kpi-periods {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 10px 0 16px;
}
.kpi-pop {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  color: var(--text);
  padding: 0;
  width: min(680px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
}
.kpi-pop::backdrop {
  background: rgb(11 22 38 / 0.55);
}
.kpi-pop-body {
  padding: 20px 22px 18px;
  overflow: auto;
}
.kpi-pop-close {
  margin-top: 14px;
}
.kpi-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.kpi-table th,
.kpi-table td {
  text-align: left;
  padding: 8px 6px;
  border-top: 1px solid var(--border);
  vertical-align: baseline;
}
.kpi-table thead th {
  border-top: 0;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
/* Columns of numbers do line up, so here tabular is right. */
.kpi-table td {
  font-variant-numeric: tabular-nums;
}
.kpi-cell.is-better {
  color: var(--ok);
}
.kpi-cell.is-worse {
  color: var(--warn);
}
@media (max-width: 560px) {
  .kpi-table th,
  .kpi-table td {
    padding: 8px 4px;
  }
  .kpi-table thead th:nth-child(3),
  .kpi-table tbody td:nth-child(3) {
    display: none;
  }
}

/* ---- the KPI calendar ----
   Every cell is a link, so the picker works with no script and a period can
   be bookmarked. In week mode the row is the target rather than the day: a
   week is what is being chosen, and lighting one day would promise something
   narrower than what you get. */
.kpi-cal {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  padding: 10px 12px 12px;
  margin: 0 0 14px;
}
.kpi-cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 0.9375rem;
}
.kpi-cal-nav {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
  font-size: 1.1875rem;
  line-height: 1;
}
.kpi-cal-nav:hover {
  border-color: var(--text-muted);
}
.kpi-cal-nav.is-off {
  opacity: 0.35;
  pointer-events: none;
}
.kpi-cal-grid {
  display: grid;
  gap: 6px;
}
.kpi-cal-grid.is-month {
  grid-template-columns: repeat(4, 1fr);
}
.kpi-cal-grid.is-year {
  grid-template-columns: repeat(4, 1fr);
}
.kpi-pick {
  display: grid;
  place-items: center;
  min-height: 40px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 600;
}
.kpi-pick:hover {
  border-color: var(--accent);
}
.kpi-pick.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.kpi-pick.is-off {
  opacity: 0.3;
  background: none;
  border-style: dashed;
}
.kpi-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--text-faint);
  text-align: center;
  margin-bottom: 4px;
}
/* The row is the link. The anchor is stretched across it rather than wrapped
   around the days, so the whole week is one hit target without nesting seven
   spans inside an <a> that a screen reader would then read out as a date. */
.kpi-week {
  position: relative;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  border-radius: 8px;
  border: 1px solid transparent;
}
.kpi-week:hover {
  border-color: var(--accent);
}
.kpi-week.is-on {
  background: var(--accent);
  border-color: var(--accent);
}
.kpi-week.is-on .kpi-day {
  color: var(--on-accent);
}
.kpi-week.is-off {
  opacity: 0.3;
}
.kpi-week-hit {
  position: absolute;
  inset: 0;
  border-radius: 8px;
}
.kpi-week-hit:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.kpi-day {
  display: grid;
  place-items: center;
  min-height: 36px;
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.kpi-day.is-dim {
  color: var(--text-faint);
}
/* A day inside the chosen week that has not happened. The week is still the
   one picked, but nothing is counted there, so it should not look as though
   it were. */
.kpi-day.is-ahead {
  opacity: 0.45;
}
.kpi-day.is-today {
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.kpi-chosen {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 14px;
  font-size: 0.9375rem;
}
.kpi-today {
  font-size: 0.875rem;
  font-weight: 600;
}

/* ======================================================================
   The 2026 look.

   A layer over everything above it, not a rewrite of it. Every rule in this
   block comes after the one it changes, so it wins by order rather than by
   piling on selectors, and every page keeps the markup and the behaviour it
   had: what changes is the shape of things, the type they are set in, and
   how they move. Nothing here is a view transition — see the loader block
   above for why that snapshots the whole document and is not coming back.
   Motion is opacity and transform only, on small elements, and switched off
   for anyone who has asked their device for less of it.

   The brand is untouched: the navy, the green, the mark, the wordmark, the
   dark-first theme. What is new is the typeface (Onest, served from here,
   34KB once and then cached for a year), the surfaces (hairlines and soft
   shadows in place of hard borders), the rail (icons, a green spine on the
   page you are on), a tab bar along the foot of a phone, and the way a
   button answers a press.
   ====================================================================== */

/* ---- 1. type ---- */

@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/onest-latin.woff2') format('woff2');
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---- 2. tokens ----
   The old names are re-issued rather than replaced, so every rule above that
   asked for --radius or --shadow-1 takes the new shape without being edited.
   The dark values are stated twice for the same reason the originals are:
   once for a device set to dark, once for an account that chose it. */
:root {
  --radius: 12px;
  --radius-lg: 18px;
  --surface: #ffffff;
  --surface-2: #f4f6f9;
  --hairline: rgb(18 35 60 / 0.11);
  --hairline-soft: rgb(18 35 60 / 0.07);
  --ring: rgb(23 201 111 / 0.24);
  --glow: rgb(23 201 111 / 0.38);
  --btn-face: linear-gradient(180deg, #22d47b 0%, #14c068 100%);
  --btn-sheen: inset 0 1px 0 rgb(255 255 255 / 0.28);
  --shadow-1: 0 1px 2px rgb(18 35 60 / 0.06), 0 1px 1px rgb(18 35 60 / 0.03);
  --shadow-2: 0 6px 16px -6px rgb(18 35 60 / 0.14), 0 2px 4px rgb(18 35 60 / 0.04);
  --shadow-3: 0 28px 56px -16px rgb(18 35 60 / 0.28);
  --rail-bg: #fafbfc;
  --tab-bg: rgb(255 255 255 / 0.86);
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-spring: cubic-bezier(0.34, 1.35, 0.64, 1);
  --dur-1: 120ms;
  --dur-2: 220ms;
  --dur-3: 300ms;
  --nav-h: 62px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --border: #263c5b;
    --border-soft: #1a2d47;
    --surface: #10203a;
    --surface-2: #142744;
    --hairline: rgb(255 255 255 / 0.09);
    --hairline-soft: rgb(255 255 255 / 0.055);
    --ring: rgb(43 224 128 / 0.28);
    --glow: rgb(23 201 111 / 0.42);
    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.35);
    --shadow-2: 0 8px 20px -8px rgb(0 0 0 / 0.5), 0 2px 4px rgb(0 0 0 / 0.25);
    --shadow-3: 0 32px 64px -16px rgb(0 0 0 / 0.65);
    --rail-bg: #0d1a2e;
    --tab-bg: rgb(11 22 38 / 0.84);
  }
}
:root[data-theme='dark'] {
  --border: #263c5b;
  --border-soft: #1a2d47;
  --surface: #10203a;
  --surface-2: #142744;
  --hairline: rgb(255 255 255 / 0.09);
  --hairline-soft: rgb(255 255 255 / 0.055);
  --ring: rgb(43 224 128 / 0.28);
  --glow: rgb(23 201 111 / 0.42);
  --shadow-1: 0 1px 2px rgb(0 0 0 / 0.35);
  --shadow-2: 0 8px 20px -8px rgb(0 0 0 / 0.5), 0 2px 4px rgb(0 0 0 / 0.25);
  --shadow-3: 0 32px 64px -16px rgb(0 0 0 / 0.65);
  --rail-bg: #0d1a2e;
  --tab-bg: rgb(11 22 38 / 0.84);
}

/* ---- 3. the page itself ---- */

body {
  font-size: 1rem;
  line-height: 1.5;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
/* A little light behind the navy: two soft washes, one green and one cool,
   fixed to the window so they paint once and never again while the page
   scrolls. Behind everything, in front of nothing. Fainter on white paper,
   where it is a tint rather than a glow. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(900px 520px at -8% -12%, rgb(23 201 111 / 0.075), transparent 62%),
    radial-gradient(760px 460px at 108% -6%, rgb(116 182 255 / 0.05), transparent 60%);
  opacity: 0.55;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) body::before {
    opacity: 1;
  }
}
:root[data-theme='dark'] body::before {
  opacity: 1;
}
h1 {
  font-size: 1.75rem;
  font-weight: 750;
  letter-spacing: -0.028em;
  line-height: 1.15;
  margin: 4px 0 18px;
  text-wrap: balance;
}
h2 {
  font-size: 1.1875rem;
  font-weight: 700;
  letter-spacing: -0.018em;
  line-height: 1.25;
  margin: 26px 0 8px;
}
h3 {
  letter-spacing: -0.012em;
}
@media (min-width: 1000px) {
  h1 {
    font-size: 2rem;
  }
}
b,
strong {
  font-weight: 650;
}
/* Money and counts line up in a column; prose does not. */
.quote-card .amt b,
.cm-amt,
.fin-card b,
.fin-row,
.kpi-table td,
.kpi-value,
.pay-amount,
.cm-pay td,
.mono {
  font-variant-numeric: tabular-nums;
}
::selection {
  background: rgb(23 201 111 / 0.28);
}
/* Scrollbars in the app's colours, thin, and out of the way. */
* {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--text-faint) 45%, transparent) transparent;
}
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-faint) 45%, transparent);
  border: 3px solid transparent;
  background-clip: padding-box;
  border-radius: 999px;
}
::-webkit-scrollbar-track {
  background: transparent;
}

/* ---- 4. the rail, on a wide screen ---- */

@media (min-width: 1000px) {
  .shell {
    grid-template-columns: 252px minmax(0, 1fr);
  }
  .siderail {
    gap: 1px;
    padding: 18px 14px 16px;
    background: var(--rail-bg);
    border-right: 1px solid var(--hairline-soft);
  }
  .sr-brand {
    padding: 2px 10px 18px;
    gap: 9px;
  }
  .sr-brand .mark {
    width: 30px;
    height: 30px;
  }
  .sr-word {
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: -0.035em;
  }
  .sr-new {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    margin: 0 0 14px;
    padding: 0 14px;
    border-radius: 12px;
    background: var(--btn-face);
    box-shadow:
      var(--btn-sheen),
      0 10px 22px -12px var(--glow);
    font-size: 0.90625rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    transition:
      transform var(--dur-1) var(--ease),
      box-shadow var(--dur-2) var(--ease);
  }
  .sr-new:hover {
    filter: none;
    transform: translateY(-1px);
    box-shadow:
      var(--btn-sheen),
      0 14px 28px -12px var(--glow);
  }
  .sr-new:active {
    transform: translateY(0) scale(0.98);
    box-shadow:
      var(--btn-sheen),
      0 4px 10px -6px var(--glow);
  }
  .sr-new svg {
    width: 18px;
    height: 18px;
  }
  .sr-group {
    gap: 1px;
    padding: 8px 0;
    border-top: 1px solid var(--hairline-soft);
  }
  /* Scoped under .siderail so these beat the global "a.sr-link { color:
     inherit }": every item — link or fold heading — is the same muted grey,
     white under the mouse, green on the page you are on. */
  .siderail .sr-link {
    position: relative;
    gap: 12px;
    padding: 9px 12px;
    border-radius: 10px;
    font-size: 0.90625rem;
    font-weight: 550;
    letter-spacing: -0.008em;
    color: var(--text-muted);
    transition:
      background-color var(--dur-1) var(--ease),
      color var(--dur-1) var(--ease);
  }
  .siderail .sr-link svg {
    width: 20px;
    height: 20px;
    flex: none;
    opacity: 0.72;
    transition: opacity var(--dur-1) var(--ease);
  }
  .siderail .sr-link:hover {
    background: color-mix(in srgb, var(--text) 6%, transparent);
    color: var(--text);
  }
  .siderail .sr-link:hover svg {
    opacity: 1;
  }
  /* The page you are on: tinted green, in green, with a spine of it down the
     rail's own edge. The spine is the one mark in the app that is only ever
     in one place. A fold heading whose page is inside it is green too, so a
     closed fold still says where you are. */
  .siderail .sr-link[aria-current='page'],
  .siderail .sr-fold-head[data-current='inside'] {
    background: var(--accent-tint);
    color: var(--link);
    font-weight: 650;
  }
  .siderail .sr-fold[open] > .sr-fold-head[data-current='inside'] {
    background: transparent;
    font-weight: 550;
  }
  .siderail .sr-link[aria-current='page'] svg {
    opacity: 1;
  }
  .siderail .sr-link[aria-current='page']::before {
    content: '';
    position: absolute;
    left: -14px;
    top: 50%;
    width: 3px;
    height: 22px;
    border-radius: 0 3px 3px 0;
    background: var(--accent);
    transform: translateY(-50%);
    animation: qn-spine var(--dur-3) var(--ease-spring) both;
  }
  .sr-link .nav-badge {
    margin-left: auto;
  }
  .sr-grouphead {
    margin: 4px 0 4px;
    font-size: 0.65625rem;
    letter-spacing: 0.09em;
  }
  .sr-out .linklike {
    border-radius: 10px;
    padding: 8px 12px;
    font-weight: 550;
  }
  .sr-out .linklike:hover {
    background: color-mix(in srgb, var(--text) 6%, transparent);
    color: var(--text);
  }
  .wrap {
    padding: 30px 36px 120px;
  }
}
@keyframes qn-spine {
  from {
    transform: translateY(-50%) scaleY(0.2);
  }
  to {
    transform: translateY(-50%) scaleY(1);
  }
}

/* ---- 5. the bar across the top, below a wide screen ---- */

.topbar {
  padding: 10px 16px;
  border-bottom: 1px solid var(--hairline-soft);
  /* Solid, and deliberately not blurred like the tab bar below: a backdrop
     filter makes the bar the containing block for anything fixed inside it,
     and the phone's drawer and its scrim are fixed inside it. */
  background: var(--bg);
}
.topbar .word {
  font-weight: 800;
  letter-spacing: -0.035em;
}
.linklike {
  font-family: var(--font);
  font-weight: 600;
  border-radius: 8px;
  text-decoration: none;
  transition:
    background-color var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease);
}
.topbar .linklike:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 6%, transparent);
}
.topbar .linklike[aria-current='page'] {
  color: var(--link);
  background: var(--accent-tint);
}
@media (max-width: 767px) {
  .tb-links {
    padding: 72px 12px calc(20px + env(safe-area-inset-bottom));
    background: var(--surface);
    border-right: 1px solid var(--hairline);
    box-shadow: var(--shadow-3);
    transition: transform var(--dur-3) var(--ease);
  }
  .tb-group {
    border-top: 1px solid var(--hairline-soft);
  }
  .tb-group .linklike {
    border-radius: 10px;
    font-size: 1rem;
    font-weight: 550;
  }
  .tb-group .linklike[aria-current='page'] {
    color: var(--link);
    background: var(--accent-tint);
    font-weight: 650;
  }
  /* The tint is the marker in the drawer; the rule under the word is for the
     bar, where there is no room for a tint. */
  .topbar .tb-group a[aria-current='page']::after {
    display: none;
  }
  .tb-scrim {
    background: rgb(4 10 20 / 0.5);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
  }
}
/* Anyone who has asked for less see-through gets solid bars. */
@media (prefers-reduced-transparency: reduce) {
  .qn-tabs {
    background: var(--bg);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* ---- 6. the tab bar along the foot of a phone ----
   Five places a thumb can reach without moving: the four a trader opens
   most, and the door to everything else, which is the same drawer the logo
   opens. Hidden with the rail and the top bar's own logic — it exists only
   below 768px, where the links are otherwise behind a door. */
.qn-tabs {
  display: none;
}
@media (max-width: 767px) {
  .qn-tabs {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    /* Under the top bar's own layer (10), because the drawer and its scrim
       live inside that bar: a higher number here would put these five over
       the scrim and across the foot of the open drawer. */
    z-index: 9;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
    padding: 6px 8px env(safe-area-inset-bottom, 0px);
    background: var(--tab-bg);
    -webkit-backdrop-filter: blur(18px) saturate(1.5);
    backdrop-filter: blur(18px) saturate(1.5);
    border-top: 1px solid var(--hairline-soft);
  }
  .qt-item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    padding: 4px 2px;
    border: 0;
    border-radius: 12px;
    background: none;
    color: var(--text-muted);
    /* The five labels share the width of the phone, so their size follows the
       reader's only as far as the longest of them still fits its fifth. */
    font: 600 min(0.6875rem, 3.6vw)/1.1 var(--font);
    letter-spacing: 0;
    text-decoration: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color var(--dur-1) var(--ease);
  }
  .qt-item svg {
    width: 23px;
    height: 23px;
    transition: transform var(--dur-2) var(--ease-spring);
  }
  .qt-item:active svg {
    transform: scale(0.88);
  }
  .qt-item[aria-current='page'] {
    color: var(--link);
  }
  .qt-item[aria-current='page']::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 18px;
    height: 3px;
    border-radius: 0 0 3px 3px;
    background: var(--accent);
    transform: translateX(-50%);
    animation: qn-tab-in var(--dur-3) var(--ease-spring) both;
  }
  .qt-item .nav-badge {
    position: absolute;
    top: 2px;
    left: calc(50% + 4px);
  }
  /* Everything at the foot of a page moves up by the height of the bar. */
  body:has(.qn-tabs) {
    padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  }
  body:has(.qn-tabs) .actionbar {
    bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  }
  body:has(.qn-tabs) .qn-help {
    bottom: calc(var(--nav-h) + 24px + env(safe-area-inset-bottom, 0px));
  }
}
@media (max-width: 520px) {
  body:has(.qn-tabs) .qn-help {
    bottom: 0;
  }
}
@keyframes qn-tab-in {
  from {
    transform: translateX(-50%) scaleX(0.2);
  }
  to {
    transform: translateX(-50%) scaleX(1);
  }
}

/* ---- 7. buttons ----
   One family. The green ones carry a little light along the top edge and a
   green shadow underneath, and dip when pressed — the nod. The quiet ones
   are a hairline that fills on hover. */
.btn,
.btn-big {
  min-height: 54px;
  border-radius: 14px;
  font-weight: 650;
  font-size: 1.03125rem;
  letter-spacing: -0.012em;
  background: var(--btn-face);
  box-shadow:
    var(--btn-sheen),
    0 10px 24px -12px var(--glow);
  transition:
    transform var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    filter var(--dur-1) var(--ease);
}
.btn-big {
  min-height: 58px;
  font-size: 1.09375rem;
}
.btn:hover,
.btn-big:hover {
  filter: brightness(1.04);
  box-shadow:
    var(--btn-sheen),
    0 14px 30px -12px var(--glow);
}
.btn:active,
.btn-big:active {
  background: var(--btn-face);
  filter: brightness(0.96);
  transform: translateY(1px) scale(0.99);
  box-shadow:
    var(--btn-sheen),
    0 3px 8px -4px var(--glow);
}
.btn[disabled],
.btn-big:disabled,
.bc-send .btn-big:disabled {
  background: var(--bg-inset);
  box-shadow: none;
  transform: none;
  filter: none;
}
.btn-quiet {
  min-height: 48px;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--surface);
  font-weight: 600;
  font-size: 0.96875rem;
  letter-spacing: -0.01em;
  box-shadow: var(--shadow-1);
  transition:
    background-color var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease),
    transform var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}
.btn-quiet:hover {
  background: var(--surface-2);
  border-color: color-mix(in srgb, var(--text) 22%, transparent);
  box-shadow: var(--shadow-2);
}
.btn-quiet:active {
  transform: translateY(1px) scale(0.99);
  box-shadow: none;
}
.btn-danger-quiet {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}
.btn-danger-quiet:hover {
  background: var(--danger-bg);
  border-color: var(--danger);
}
.btn-compact {
  min-height: 40px;
  padding: 0 15px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--surface);
  font-weight: 600;
  font-size: 0.875rem;
  letter-spacing: -0.006em;
  box-shadow: var(--shadow-1);
  transition:
    background-color var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease),
    transform var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    color var(--dur-1) var(--ease);
}
.btn-compact:hover {
  border-color: color-mix(in srgb, var(--text) 22%, transparent);
  background: var(--surface-2);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.btn-compact:active {
  transform: translateY(0) scale(0.98);
  box-shadow: none;
}
.btn-compact.primary {
  background: var(--btn-face);
  border-color: transparent;
  box-shadow:
    var(--btn-sheen),
    0 8px 18px -10px var(--glow);
}
.btn-compact.primary:hover {
  filter: brightness(1.04);
  border-color: transparent;
  box-shadow:
    var(--btn-sheen),
    0 12px 22px -10px var(--glow);
}
.btn-compact.primary.pay-locked,
.btn-compact.primary.pay-locked:hover {
  box-shadow: none;
  filter: none;
  transform: none;
}
.btn-row {
  gap: 10px;
}
.actionbar {
  background: linear-gradient(transparent, var(--bg) 34%);
}

/* ---- 8. fields ---- */

input[type='text'],
input[type='email'],
input[type='password'],
input[type='tel'],
input[type='number'],
input[type='search'],
input[type='url'],
input[type='date'],
input[type='datetime-local'],
input[type='time'],
input[type='month'],
textarea,
select {
  font-size: 1.03125rem;
  font-weight: 450;
  letter-spacing: -0.006em;
  background-color: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 12px 14px;
  min-height: 48px;
  box-shadow: var(--shadow-1);
  transition:
    border-color var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    background-color var(--dur-1) var(--ease);
}
input[type='text']:hover,
input[type='email']:hover,
input[type='password']:hover,
input[type='tel']:hover,
input[type='number']:hover,
input[type='search']:hover,
input[type='url']:hover,
input[type='date']:hover,
textarea:hover,
select:hover {
  border-color: color-mix(in srgb, var(--text) 24%, transparent);
}
input:focus,
textarea:focus,
select:focus {
  border-color: var(--accent);
  box-shadow:
    0 0 0 4px var(--ring),
    var(--shadow-1);
}
input[aria-invalid='true'],
input[aria-invalid='true']:focus {
  border-color: var(--danger);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--danger) 22%, transparent);
}
::placeholder {
  color: var(--text-faint);
  opacity: 1;
}
label {
  font-size: 0.84375rem;
  font-weight: 600;
  letter-spacing: -0.004em;
  color: var(--text-muted);
  margin: 18px 0 6px;
}
input[type='checkbox'],
input[type='radio'] {
  border-radius: 7px;
  border-color: color-mix(in srgb, var(--text) 30%, transparent);
  background: var(--surface);
  box-shadow: none;
}
input[type='radio'] {
  border-radius: 50%;
}
input[type='checkbox']:focus,
input[type='radio']:focus {
  box-shadow: 0 0 0 4px var(--ring);
}
input[type='file'] {
  border: 1px dashed color-mix(in srgb, var(--text) 26%, transparent);
  border-radius: 12px;
  background: var(--surface-2);
  box-shadow: none;
}
input[type='file']::file-selector-button,
input[type='file']::-webkit-file-upload-button {
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--surface);
  font-family: var(--font);
}

/* ---- 9. surfaces: cards, rows, tiles ---- */

.quote-card {
  gap: 14px;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  padding: 15px 18px 15px 22px;
  margin-bottom: 10px;
  background: var(--surface);
  box-shadow: var(--shadow-1);
  transition:
    transform var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}
.quote-card:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--hairline));
  box-shadow: var(--shadow-2);
}
.quote-card::before {
  width: 4px;
  border-radius: 16px 0 0 16px;
}
.quote-card .who b {
  font-weight: 650;
  letter-spacing: -0.012em;
}
.quote-card .who span {
  font-size: 0.8125rem;
  color: var(--text-faint);
}
.quote-card .amt b {
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.help-card {
  border-color: var(--hairline);
  background: var(--surface);
  box-shadow: var(--shadow-1);
}
.help-card:hover {
  box-shadow: var(--shadow-2);
}
.fin-card,
.kpi-tile,
.kpi-hero,
.act-item,
.fin-table,
.pay-row,
.pay-bank,
.cm-fig,
.cm-row,
.cm-job,
.install-card,
.q-cust,
.faq-item,
.tour-bubble {
  border-color: var(--hairline);
  background: var(--surface);
  box-shadow: var(--shadow-1);
}
.cm-fig,
.cm-row,
.cm-job {
  border-radius: 16px;
}
.cm-row {
  transition:
    border-color var(--dur-1) var(--ease),
    background-color var(--dur-1) var(--ease),
    transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}
.cm-row:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.cm-fig b {
  font-weight: 700;
  letter-spacing: -0.025em;
}
.sec-chip {
  border-color: var(--hairline);
  background: var(--surface);
  font-weight: 600;
  transition:
    background-color var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease);
}
.tour-bubble {
  border-radius: 18px;
  box-shadow: var(--shadow-3);
}
.fin-card {
  border-width: 1px;
  border-radius: 16px;
  padding: 16px;
}
.fin-card span {
  font-size: 0.78125rem;
  letter-spacing: 0.01em;
}
.fin-card b {
  font-weight: 700;
  letter-spacing: -0.025em;
}
.fin-card.profit {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--hairline));
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--accent) 9%, var(--surface)),
    var(--surface)
  );
}
.fin-card.loss {
  border-color: color-mix(in srgb, var(--danger) 50%, var(--hairline));
}
.fin-table {
  border-width: 1px;
  border-radius: 16px;
}
.fin-row {
  border-bottom-color: var(--hairline-soft);
  transition: background-color var(--dur-1) var(--ease);
}
.fin-row.fin-head {
  background: var(--surface-2);
}
a.fin-row:hover {
  background: var(--surface-2);
}
.kpi-hero {
  position: relative;
  overflow: hidden;
  border-radius: 20px;
  padding: 22px 24px 20px;
  background:
    radial-gradient(
      520px 220px at 0% 0%,
      color-mix(in srgb, var(--accent) 14%, transparent),
      transparent 70%
    ),
    var(--surface);
}
.kpi-hero-num {
  font-weight: 750;
  letter-spacing: -0.04em;
}
.kpi-tile {
  border-radius: 16px;
  padding: 15px 17px 13px;
  transition:
    transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease);
}
.kpi-tile:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
  border-color: color-mix(in srgb, var(--text) 18%, var(--hairline));
}
.kpi-value {
  font-weight: 700;
  letter-spacing: -0.03em;
}
.kpi-label {
  font-size: 0.84375rem;
}
.act-item {
  border-radius: 14px;
  margin-bottom: 8px;
  transition:
    border-color var(--dur-1) var(--ease),
    background-color var(--dur-1) var(--ease);
}
.pay-row {
  border-radius: 16px;
}
/* Pills: the filters along the top of a list and the small labels on a row. */
.filters a {
  font-weight: 600;
  font-size: 0.84375rem;
  padding: 8px 14px;
  border: 1px solid transparent;
  background: var(--surface-2);
  color: var(--text-muted);
  transition:
    background-color var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease);
}
.filters a:hover {
  color: var(--text);
  border-color: var(--hairline);
}
.filters a.active,
.filters a.active-filter {
  background: var(--text);
  color: var(--bg);
  border-color: transparent;
}
.chip {
  font-weight: 650;
  font-size: 0.75rem;
  letter-spacing: -0.002em;
  padding: 3px 10px;
  border: 1px solid transparent;
}
.chip.ok {
  border-color: color-mix(in srgb, var(--ok) 28%, transparent);
}
.chip.warn {
  border-color: color-mix(in srgb, var(--warn) 32%, transparent);
}
.chip.danger {
  border-color: color-mix(in srgb, var(--danger) 30%, transparent);
}
.trial-chip {
  border: 1px solid color-mix(in srgb, var(--warn) 32%, transparent);
}
.sec-nav {
  gap: 6px;
  padding-bottom: 12px;
}
/* Messages the page has for you: a coloured bar down the left edge, so the
   colour says what kind it is before the words do. */
.flash-error,
.flash-warn,
.flash-ok {
  position: relative;
  padding: 13px 16px 13px 20px;
  border-radius: 14px;
  border: 1px solid transparent;
  font-weight: 600;
  overflow: hidden;
}
.flash-error::before,
.flash-warn::before,
.flash-ok::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: currentColor;
  opacity: 0.9;
}
.flash-error {
  border-color: color-mix(in srgb, var(--danger) 26%, transparent);
}
.flash-warn {
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
}
.flash-ok {
  border-color: color-mix(in srgb, var(--ok) 26%, transparent);
}
.field-err {
  font-weight: 600;
}
/* Tables that are plain <table>s. */
table {
  border-spacing: 0;
}
th {
  font-weight: 650;
  letter-spacing: 0.01em;
}
.kpi-table th,
.kpi-table td {
  border-top-color: var(--hairline-soft);
  padding: 9px 8px;
}
.kpi-table thead th {
  font-size: 0.75rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ---- 10. dialogs ----
   A pop-up arrives rather than appears: a short rise and a fade, from the
   moment it opens, and its backdrop blurs what it sits over. @starting-style
   is what lets a dialog animate in from display:none; a browser without it
   simply shows the dialog, which is what it did before. */
dialog {
  border: 1px solid var(--hairline);
  border-radius: 20px;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-3);
}
/* No blur on the backdrop. Blurring the whole page underneath a dialog is
   re-rendered every frame of the opening animation, and on a page full of
   tiles and tables it is the difference between a smooth open and a stutter. */
dialog::backdrop {
  background: rgb(4 10 20 / 0.58);
}
dialog[open] {
  opacity: 1;
  transform: none;
  will-change: transform, opacity;
  transition:
    opacity var(--dur-2) var(--ease),
    transform var(--dur-3) var(--ease-spring),
    overlay var(--dur-2) allow-discrete,
    display var(--dur-2) allow-discrete;
}
/* A large dialog — a table and a calendar — fades in without the spring: a
   transform on something that big repaints all of it on every frame. */
dialog.kpi-pop[open] {
  transition:
    opacity var(--dur-2) var(--ease),
    overlay var(--dur-2) allow-discrete,
    display var(--dur-2) allow-discrete;
}
dialog[open]::backdrop {
  opacity: 1;
  transition: opacity var(--dur-2) var(--ease);
}
@starting-style {
  dialog[open] {
    opacity: 0;
    transform: translateY(14px) scale(0.98);
  }
  dialog.kpi-pop[open] {
    transform: none;
  }
  dialog[open]::backdrop {
    opacity: 0;
  }
}
.kpi-pop {
  border-radius: 20px;
}
.kpi-pop-body {
  padding: 22px 24px 20px;
}

/* ---- 11. arriving on a page ----
   The first few things on a page fade up in turn, 260ms each and 30ms
   apart. Small elements, opacity and a translate, and only the first eight
   children of the column: no page-wide layer, no snapshot, nothing that
   grows with the length of the page. Fixed-position things are left out —
   a transform on an ancestor would pin them to the wrong box for a third of
   a second. */
.wrap > :nth-child(-n + 8):not(.upd-overlay, .tour-overlay, dialog, [hidden]) {
  /* backwards, not both: once it has landed the element is left exactly as
     it was, with no transform on it to pin a fixed child to the wrong box. */
  animation: qn-rise var(--dur-3) var(--ease) backwards;
}
.wrap > :nth-child(2) {
  animation-delay: 30ms;
}
.wrap > :nth-child(3) {
  animation-delay: 60ms;
}
.wrap > :nth-child(4) {
  animation-delay: 90ms;
}
.wrap > :nth-child(5) {
  animation-delay: 120ms;
}
.wrap > :nth-child(6) {
  animation-delay: 150ms;
}
.wrap > :nth-child(7) {
  animation-delay: 180ms;
}
.wrap > :nth-child(8) {
  animation-delay: 210ms;
}
@keyframes qn-rise {
  from {
    opacity: 0;
    translate: 0 8px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* ---- 12. the chat button and the footer ---- */

.qn-fab {
  background: var(--btn-face);
  box-shadow:
    var(--btn-sheen),
    0 12px 28px -10px var(--glow),
    0 6px 20px rgb(0 0 0 / 0.22);
  transition:
    transform var(--dur-2) var(--ease-spring),
    box-shadow var(--dur-2) var(--ease);
}
.qn-fab:hover {
  filter: none;
  transform: translateY(-2px) scale(1.04);
}
.qn-fab:active {
  background: var(--btn-face);
  transform: scale(0.96);
}
.qn-help {
  border-color: var(--hairline);
  border-radius: 20px;
  box-shadow: var(--shadow-3);
}
.qn-footlinks a {
  transition: color var(--dur-1) var(--ease);
}
.qn-footlinks a:hover {
  text-decoration: none;
}

/* ---- 14. the dashboard ----
   Tiles that are doors, lists that are doors, and a bill that is a door.
   The rows borrow the quote card's shape so the eye already knows what a
   tap will do. */
.ag-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 4px;
}
.ag-head h1 {
  margin: 4px 0 2px;
}
.ag-sub {
  margin: 0 0 8px;
  font-size: 0.9375rem;
}
.ag-head .btn-compact {
  flex: none;
  margin-top: 6px;
}
.ag-periods {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin: 8px 0 18px;
}
.ag-back {
  margin-left: 6px;
}
/* Two tiles abreast on a phone and four from a tablet up, for as long as
   each is at least 8.5em wide in the reader's own text size; fewer than that
   and they take fewer to a row, so a figure is never broken in two. */
.ag-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, max(8.5em, calc(50% - 5px))), 1fr));
  gap: 10px;
  margin: 0 0 26px;
}
@media (min-width: 700px) {
  .ag-tiles {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, max(8.5em, calc(25% - 7.5px))), 1fr));
  }
}
.ag-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 14px 16px 12px;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  box-shadow: var(--shadow-1);
  transition:
    transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease);
}
.ag-tile:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
  border-color: color-mix(in srgb, var(--text) 18%, var(--hairline));
}
.ag-tile-l {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-muted);
}
.ag-tile-v {
  font-size: clamp(1.375rem, 6vw, 1.75rem);
  font-weight: 750;
  letter-spacing: -0.03em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.ag-tile-n {
  font-size: 0.78125rem;
  color: var(--text-faint);
}
.ag-tile.is-in .ag-tile-v {
  color: var(--ok);
}
.ag-tile.is-late .ag-tile-v {
  color: var(--danger);
}
.ag-tile.is-late {
  border-color: color-mix(in srgb, var(--danger) 40%, var(--hairline));
}
.ag-tile.is-due .ag-tile-v {
  color: var(--warn);
}
.ag-tile.is-news {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--hairline));
}
.ag-sec {
  margin: 0 0 28px;
}
.ag-sec h2 {
  margin: 0 0 10px;
}
.ag-h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 18px 0 8px;
  font-size: 0.90625rem;
  font-weight: 650;
  color: var(--text-muted);
}
.ag-count {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  min-height: 22px;
  padding: 0 7px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 700;
}
.ag-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ag-row,
.ag-bill {
  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 13px 16px 13px 20px;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition:
    transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease);
}
.ag-row:hover,
.ag-bill:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--hairline));
}
.ag-row::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: transparent;
}
.ag-row[data-tone='overdue']::before {
  background: var(--danger);
}
.ag-row[data-tone='today']::before,
.ag-row[data-tone='soon']::before {
  background: var(--warn);
}
.ag-row[data-tone='paid']::before {
  background: var(--ok);
}
.ag-row-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 8em;
}
.ag-row-main b {
  font-weight: 650;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ag-row-main span {
  font-size: 0.84375rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ag-row-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex: none;
  margin-left: auto;
  text-align: right;
}
.ag-row-side b {
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.ag-empty {
  margin: 0;
  padding: 18px 16px;
  border: 1px dashed var(--hairline);
  border-radius: 14px;
  color: var(--text-muted);
  font-size: 0.9375rem;
}
.ag-bill.is-attention {
  border-color: color-mix(in srgb, var(--danger) 45%, var(--hairline));
}
.ag-bill .ag-row-main span {
  white-space: normal;
}
.ag-bill-go {
  flex: none;
  font-weight: 650;
  color: var(--link);
}
/* A calendar whose days are the links, for choosing one day. */
.kpi-week.is-days {
  border-color: transparent;
}
.kpi-week.is-days:hover {
  border-color: transparent;
}
a.kpi-day {
  border-radius: 8px;
  text-decoration: none;
  transition:
    background-color var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease);
}
a.kpi-day:hover {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}
a.kpi-day.is-on {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 750;
}
/* The block for a job's address stands off the field above it, so its title
   on the border does not read as a label for that field. */
.job-addr {
  margin-top: 26px;
}
.job-addr legend {
  font-family: var(--font);
  background: var(--bg);
}

/* ---- 13. less motion, on request ----
   Every entrance and every hover lift above is dropped here; colour changes
   stay, since a colour change is not motion. */
@media (prefers-reduced-motion: reduce) {
  .wrap > :nth-child(-n + 8),
  .sr-link[aria-current='page']::before,
  .qt-item[aria-current='page']::before {
    animation: none;
  }
  dialog[open],
  dialog[open]::backdrop {
    transition: none;
  }
  .btn:active,
  .btn-big:active,
  .btn-quiet:active,
  .btn-compact:active,
  .btn-compact:hover,
  .sr-new:hover,
  .sr-new:active,
  .quote-card:hover,
  .kpi-tile:hover,
  .cm-row:hover,
  .ag-tile:hover,
  .ag-row:hover,
  .ag-bill:hover,
  .qn-fab:hover,
  .qn-fab:active,
  .qt-item:active svg {
    transform: none;
  }
}

/* ---- Dashboard: nearing the £150 fee limit ----
   Highlighted, not tucked under the bill: what it protects is one-tap
   payment for the trader's customers. Amber within £25 of the limit, red at
   it. The button sits beside the words on a wide screen and under them on a
   phone, full width, where a thumb finds it. */
.ag-cap {
  display: flex;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 18px;
  padding: 14px 16px;
  border-radius: var(--radius-lg);
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  background: var(--warn-bg);
  color: var(--warn);
  animation: ag-cap-in 0.35s ease backwards;
}
.ag-cap-at {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  background: var(--danger-bg);
  color: var(--danger);
}
.ag-cap-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.ag-cap-text b {
  font-size: 1rem;
}
.ag-cap-text span {
  font-size: 0.875rem;
  opacity: 0.92;
}
.ag-cap-go {
  margin: 0;
  flex: none;
}
@keyframes ag-cap-in {
  from {
    opacity: 0;
    translate: 0 6px;
  }
}
@media (max-width: 640px) {
  .ag-cap {
    flex-direction: column;
    align-items: stretch;
  }
  .ag-cap-go .btn {
    width: 100%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .ag-cap {
    animation: none;
  }
}
/* The £100 heads-up: the same box, quieter — plain surface, amber edge. */
.ag-cap-watch {
  background: transparent;
  color: inherit;
  border-color: color-mix(in srgb, var(--warn) 35%, transparent);
}

/* ---- the plan optimiser and its costs table ----
   The trader's side of a payment plan: what it comes to, date by date, and
   what each date is worth in fees. Never rendered on anything a customer can
   open. Scrolls sideways on a phone rather than shrinking the figures. */
.plan-opt {
  margin: 10px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.plan-opt > summary {
  cursor: pointer;
}
.plan-costs {
  margin: 10px 0 0;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--line);
  overflow-x: auto;
}
.plan-fee {
  width: 100%;
  border-collapse: collapse;
  margin: 8px 0 0;
  font-size: 0.875rem;
}
.plan-fee th,
.plan-fee td {
  text-align: right;
  padding: 5px 6px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.plan-fee th:first-child,
.plan-fee td:first-child,
.plan-fee th:nth-child(2),
.plan-fee td:nth-child(2) {
  text-align: left;
}
.plan-fee tfoot th {
  border-bottom: 0;
  border-top: 2px solid var(--line);
}

/* ---- the drawer's head: the mark, and the light switch ----
   Hidden everywhere but inside the drawer itself. Above the drawer's width the
   rail carries the brand and Settings carries the theme, and a second copy of
   either is clutter. */
.tb-head {
  display: none;
}
@media (max-width: 767px) {
  .tb-links {
    /* The head takes the room the padding used to hold open. */
    padding-top: calc(8px + env(safe-area-inset-top));
  }
  .tb-head {
    position: sticky;
    top: calc(-1 * env(safe-area-inset-top));
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0 -12px;
    padding: 14px 14px 12px;
    background: color-mix(in srgb, var(--bg) 96%, #000);
    border-bottom: 1px solid transparent;
    /* Both move with the scroll — see nav-drawer.js, which sets --qn-head on
       the panel as the list goes under it. The head keeps its place; what it
       loses is height and weight, which is what makes the list feel like it is
       passing behind something rather than starting below it. */
    padding-block: calc(14px - 6px * var(--qn-head, 0)) calc(12px - 5px * var(--qn-head, 0));
    border-bottom-color: color-mix(
      in srgb,
      var(--border-soft) calc(100% * var(--qn-head, 0)),
      transparent
    );
    transition:
      padding 0.18s var(--ease, ease),
      border-color 0.18s ease;
  }
  .tb-head-brand {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
    font-weight: 700;
    letter-spacing: -0.01em;
    /* Shrinks a little as the list climbs past it, from its left edge so the
       mark stays put rather than drifting inward. */
    transform-origin: left center;
    scale: calc(1 - 0.1 * var(--qn-head, 0));
    transition: scale 0.18s ease;
  }
  .tb-head-brand .mark {
    display: block;
    width: 26px;
    height: 26px;
    color: var(--text);
  }
  .tb-head-brand .mark svg {
    display: block;
    width: 100%;
    height: 100%;
  }
  .tb-head-brand .word {
    font-size: 1.0625rem;
  }
  .tb-theme {
    margin: 0;
    flex: none;
  }
  .tb-theme button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    padding: 6px 11px 6px 9px;
    cursor: pointer;
    transition:
      background 0.16s ease,
      color 0.16s ease,
      scale 0.12s ease;
  }
  .tb-theme button:active {
    scale: 0.96;
  }
  .tb-theme svg {
    width: 16px;
    height: 16px;
    flex: none;
  }
}

/* ---------- the mail on a phone ----------
   The phone layout from the app design: the mark and the folder name at the
   top (a press opens the folders), filters as chips, each message a card,
   a round button to write, and Mail / Sent / Settings along the bottom.
   None of it is drawn on a wider screen, where the ribbon and the rail do
   these jobs. */
.mail-top-folder,
.ib-chipbar,
.ib-fab,
.ib-tabs {
  display: none;
}
@media (max-width: 760px) {
  .mail-top .mail-wordmark,
  .mail-compose-row,
  .ib-list-head > b,
  .ib-list-head > .rb-form,
  .ib-row .ib-avatar {
    display: none;
  }
  .mail-top-folder {
    display: block;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
  }
  .mail-mark {
    gap: 10px;
  }
  .mail-shell:not(:has(.ib-panes.is-reading)) .mail-ribbon {
    display: none;
  }
  .ib-chipbar {
    display: flex;
    gap: 7px;
    padding: 10px 12px 6px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .ib-chipbar::-webkit-scrollbar {
    display: none;
  }
  .ib-fchip {
    flex: none;
    font-size: 0.8rem;
    padding: 6px 12px;
    border-radius: 99px;
    border: 1px solid #23395a;
    color: #b6c8de;
    text-decoration: none;
    white-space: nowrap;
  }
  .ib-fchip.is-on {
    background: var(--accent);
    border-color: var(--accent);
    color: #05240f;
    font-weight: 700;
  }
  .ib-list {
    padding-bottom: calc(150px + env(safe-area-inset-bottom));
  }
  .ib-row-wrap {
    margin: 0 12px 9px;
  }
  .ib-row {
    border: 1px solid #15283f;
    background: #0c1729;
    border-radius: 13px;
    padding: 11px 12px;
  }
  .ib-row.is-unread .ib-sender::before {
    content: '';
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 6px;
    border-radius: 99px;
    background: var(--accent);
    vertical-align: 1px;
  }
  .ib-fab {
    display: grid;
    place-items: center;
    position: fixed;
    right: 14px;
    bottom: calc(76px + env(safe-area-inset-bottom));
    z-index: 40;
    width: 54px;
    height: 54px;
    border-radius: 17px;
    background: var(--accent);
    color: #05240f;
    box-shadow: 0 10px 24px rgba(23, 201, 111, 0.35);
  }
  .ib-fab .mi {
    width: 24px;
    height: 24px;
    stroke-width: 2.4;
  }
  .ib-tabs {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    padding: 7px 0 calc(10px + env(safe-area-inset-bottom));
    border-top: 1px solid #152841;
    background: color-mix(in srgb, var(--bg) 94%, #000);
  }
  .ib-tab {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    font-size: 0.72rem;
    color: #7f93ad;
    text-decoration: none;
  }
  .ib-tab .mi {
    width: 19px;
    height: 19px;
  }
  .ib-tab.is-on {
    color: var(--accent-text);
  }
  .mail-shell:has(.ib-panes.is-reading) .ib-fab,
  .mail-shell:has(.ib-panes.is-reading) .ib-tabs {
    display: none;
  }
}

/* ---------- forwarding a message's files ---------- */
.cw-carry {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(3, 8, 16, 0.6);
}
.cw-carry[hidden] {
  display: none;
}
.cw-carry-card {
  width: min(460px, 100%);
  max-height: 80vh;
  overflow-y: auto;
  padding: 18px 18px 16px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-raised);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.cw-carry-card h3 {
  margin: 0 0 4px;
  font-size: 1.05rem;
}
.cw-carry-list {
  list-style: none;
  margin: 14px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cw-carry-list label {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
}
.cw-carry-list label:has(input:checked) {
  border-color: var(--accent);
}
.cw-carry-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cw-carry-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.cw-carry-note {
  margin: 6px 0;
  color: var(--text-muted);
}
.cw-carry-open {
  border: 0;
  background: none;
  padding: 0;
  color: var(--brand);
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}

/* ---------- looking at an attachment without downloading it ---------- */
.at-view {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(3, 8, 16, 0.72);
}
.at-view-card {
  display: flex;
  flex-direction: column;
  width: min(1100px, 100%);
  height: min(88vh, 100%);
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--bg-raised);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
.at-view-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 10px 16px;
  border-bottom: 1px solid var(--border);
}
.at-view-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
.at-view-head .btn-quiet {
  flex: none;
  width: auto;
}
.at-view-x {
  flex: none;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--text);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.at-view-x:hover {
  background: var(--bg-inset);
}
.at-view-body {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  place-items: center;
  overflow: auto;
  background: #0a1320;
}
.at-view-body img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.at-view-body iframe {
  width: 100%;
  height: 100%;
  border: 0;
  background: #fff;
}
.at-view-body pre {
  align-self: start;
  justify-self: stretch;
  margin: 0;
  padding: 16px;
  white-space: pre-wrap;
  word-break: break-word;
  font:
    0.8125rem/1.5 Consolas,
    Menlo,
    monospace;
  color: var(--text);
}

/* ---------- the trader's own accounting package ---------- */
.ac-default {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 99px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-text);
  font-size: 0.75rem;
  font-weight: 700;
  vertical-align: 2px;
}
.ac-default-form {
  margin: 6px 0 0;
}
.ac-others {
  margin-top: 12px;
}
.ac-others > summary {
  display: inline-flex;
  cursor: pointer;
  list-style: none;
}
.ac-others > summary::-webkit-details-marker {
  display: none;
}
.ac-others[open] > summary {
  margin-bottom: 12px;
}

/* ---------- writing a message on the page it will arrive on ----------
   One white sheet, like an opened email: the writing with no box round it,
   the signature straight under it, then the earlier correspondence below two
   ruled lines, in the order the reader gets them. */
.cw-paper {
  color-scheme: light;
  background: #fff;
  color: #111;
  border-radius: 12px;
  padding: 16px 18px 20px;
  margin-top: 10px;
}
.cw-paper .cw-body > textarea {
  display: block;
  width: 100%;
  min-height: 7.5em;
  padding: 0;
  border: 0;
  outline: none;
  box-shadow: none;
  background: transparent;
  color: #111;
  font: 0.9375rem/1.55 var(--font);
  resize: none;
  overflow: hidden;
}
.cw-paper .cw-body > textarea::placeholder {
  color: #8a8f98;
}
.cw-paper .cw-sig {
  margin: 10px 0 0;
}
.cw-paper .cw-sig-body {
  display: block;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}
.cw-rule {
  border: 0;
  border-top: 1px solid #d5d8dd;
  margin: 18px 0 0;
}
.cw-rule + .cw-rule {
  margin: 3px 0 14px;
}
.cw-quoted {
  white-space: pre-wrap;
  word-break: break-word;
  color: #555b66;
  font: 0.875rem/1.5 var(--font);
}

/* ---- The clock on a vote ----------------------------------------------
   Solid pills in fixed colours rather than theme tokens, so green, yellow and
   red read as green, yellow and red on a light screen and a dark one alike. */
.vt-timer {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  margin: 10px 0 4px;
  padding: 6px 14px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
  background: #1f9d55;
  color: #fff;
  transition:
    background-color 0.4s ease,
    color 0.4s ease;
}
.vt-timer-label {
  font-size: 0.75rem;
  font-weight: 600;
  opacity: 0.9;
}
.vt-timer-label:empty {
  display: none;
}
.vt-timer-clock {
  font-size: 1.125rem;
  letter-spacing: 0.02em;
}
.vt-timer.is-yellow {
  background: #f5c400;
  color: #2b2100;
}
.vt-timer.is-red {
  background: #d62828;
  color: #fff;
}
.vt-timer.is-finished {
  background: #1f9d55;
  color: #fff;
}
.vt-adminhead .vt-timer {
  margin: 0;
  padding: 2px 10px;
}
.vt-adminhead .vt-timer-clock {
  font-size: 0.8125rem;
}

/* A finished vote: greyed, still readable, results shown. */
.vt-page.is-finished .vt-chart,
.an-poll.is-finished .an-poll-row {
  filter: grayscale(1);
  opacity: 0.72;
}
.vt-page.is-finished .vt-open {
  cursor: default;
}

.vt-comment {
  margin: 18px 0 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 0 12px 12px 0;
  background: var(--bg-raised);
}
.vt-comment-who {
  margin: 0 0 4px;
  color: var(--text-muted);
  font-weight: 600;
}
.vt-comment-text {
  margin: 0;
  white-space: pre-wrap;
}
.vt-comment-form {
  margin: 14px 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.vt-comment-form .btn-compact {
  align-self: flex-start;
}

.vt-closes {
  margin: 10px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
}
.vt-closes legend {
  font-weight: 600;
  padding: 0 4px;
}
.vt-closes-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.vt-closes-row label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 140px;
  min-width: 0;
}
/* the label is a column, so a flex-basis on the input would set its
   height, not its width — the label does the sharing, the input just fills it */
.vt-closes-row input,
.vt-closes-row select {
  flex: none;
  width: 100%;
  min-width: 0;
}

/* ---- Open votes on the dashboard ---------------------------------------
   Every option written out with its description, so a trader can decide
   without leaving the page. */
.hv-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-raised);
  padding: 14px 16px;
  margin: 0 0 12px;
}
.hv-card.is-voted {
  border-left: 3px solid var(--ok);
}
.hv-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.hv-head .vt-timer {
  margin: 0;
  padding: 3px 12px;
}
.hv-head .vt-timer-clock {
  font-size: 0.875rem;
}
.hv-title {
  font-size: 1rem;
}
.hv-intro {
  margin: 8px 0 4px;
  white-space: pre-wrap;
}
.hv-voted {
  margin: 6px 0 2px;
}
.hv-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
}
.hv-option {
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.hv-desc {
  margin: 0;
  white-space: pre-wrap;
  color: var(--text-muted);
}
.hv-option .vt-submit {
  align-self: flex-start;
}
.hv.is-finished .hv-options,
.hv-card.is-finished .hv-options {
  filter: grayscale(1);
  opacity: 0.72;
}

/* Attachments sit at the top of a message, above the body, in the reading
   pane and in each card of the trail — not after a long email you have to
   scroll past to find them. */
.ib-files {
  margin: 4px 0 14px;
}
.ib-files .at-head {
  margin-top: 0;
}
.ib-trail-body .ib-files {
  margin: 10px 12px 12px;
}

/* ---- Taking payment online: Stripe or GoCardless -------------------------
   Two cards side by side on a wide screen, stacked on a phone. */
.pay-choose {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  margin: 0 0 18px;
  background: var(--bg-raised);
}
.pay-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.pay-option {
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.pay-option-name {
  font-size: 1rem;
}
.pay-option-facts {
  margin: 4px 0 10px;
  padding-left: 18px;
}
.pay-option .btn {
  margin-top: auto;
  align-self: flex-start;
}
.pay-connected .btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.pay-alt {
  margin: 18px auto 0;
  text-align: left;
}
.pay-alt summary {
  cursor: pointer;
  text-align: center;
}

/* ---- Stripe: the Pay by Bank step, and the facts a trader must not miss ---- */
.pay-fact-key {
  color: var(--text);
}
.pbb-step {
  border: 1px solid var(--warn);
  background: var(--warn-bg);
  border-radius: 10px;
  padding: 12px;
  margin: 8px 0 10px;
}
.pbb-step .demo {
  margin: 8px 0;
}
.pbb-list {
  margin: 8px 0 10px;
  padding-left: 20px;
}
.pbb-on {
  color: var(--ok);
}

/* ---- online payments: providers as sections split by thin green lines ---- */
.pay-intro {
  margin: 0 0 14px;
}
.pay-both {
  margin: 0 0 22px;
}
.pay-provs {
  margin: 0 0 18px;
  border-bottom: 1px solid var(--accent);
}
.pay-prov {
  border-top: 1px solid var(--accent);
  padding: 0;
}
.pay-prov-head {
  list-style: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px 28px 16px 0;
  position: relative;
}
.pay-prov-head::-webkit-details-marker {
  display: none;
}
.pay-prov-head::after {
  content: '';
  position: absolute;
  right: 6px;
  top: 22px;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}
.pay-prov[open] > .pay-prov-head::after {
  transform: rotate(-135deg);
  top: 26px;
}
.pay-prov-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  font-size: 1rem;
}
.pay-prov-body {
  padding: 2px 0 22px;
}
.pay-prov-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}
.pay-fee-note {
  margin: 0;
}

/* ---- finance: the expenses and QuoteNod fees pop-up ---- */
.fin-cards {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.fin-card-btn {
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.fin-card-btn small {
  display: block;
  margin-top: 4px;
  color: var(--accent-text);
  font-weight: 600;
}
.fx-body {
  padding: 4px 18px 18px;
  max-height: 72vh;
  overflow-y: auto;
}
.fx-body h3 {
  margin: 18px 0 8px;
}
.fx-row {
  border-top: 1px solid var(--border-soft);
  padding: 12px 0;
}
.fx-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: inherit;
  text-decoration: none;
}
.fx-top {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.fx-amt.fx-off {
  text-decoration: line-through;
  color: var(--text-muted);
}
.fx-job,
.fx-when,
.fx-why {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.fx-open {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--accent-text);
  margin-top: 2px;
}
.fx-open.fx-none {
  color: var(--text-muted);
  font-weight: 400;
}
.fx-job-link {
  display: inline-block;
  margin-top: 6px;
  font-size: 0.8125rem;
}
.fx-amt.fx-wait {
  color: var(--text-muted);
}
.fin-card-note,
.fin-fee-part {
  display: block;
  margin-top: 4px;
  font-size: 0.75rem;
  color: var(--text-muted);
  font-weight: 500;
}

/* ---- data transfer: the card, its countdown, and the steps to ask ---- */
.tr-card {
  border: 1px solid var(--accent);
  border-radius: 14px;
  padding: 16px;
  margin: 0 0 18px;
  background: var(--bg-raised);
}
.tr-card.tr-cancelled,
.tr-card.tr-declined,
.tr-card.tr-expired,
.tr-card.tr-failed {
  border-color: var(--border);
}
.tr-kicker {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
}
.tr-title {
  margin: 4px 0 6px;
}
.tr-status {
  margin: 0 0 10px;
  font-weight: 600;
}
.tr-clock {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 10px;
  padding: 10px 12px;
  margin: 0 0 10px;
  border-radius: 10px;
  background: var(--accent-tint);
}
.tr-clock-time {
  font-size: 1.375rem;
  font-variant-numeric: tabular-nums;
}
.tr-clock.is-done {
  opacity: 0.6;
}
.tr-actions {
  margin: 12px 0 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-start;
}
.tr-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 16px 0;
}
.tr-details {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 14px;
  margin: 0 0 12px;
}
.tr-details dt {
  color: var(--text-muted);
}
.tr-details dd {
  margin: 0;
}
.tr-agree {
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
@media (max-width: 640px) {
  .tr-details {
    grid-template-columns: 1fr;
  }
}

/* ---- admin: the data breach register ---- */
.br-new {
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 12px 14px;
  margin: 14px 0 18px;
}
.br-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 10px 0 18px;
}
.br-form h2 {
  margin: 18px 0 2px;
}
.br-hint {
  margin: 0;
}
.br-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.br-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  color: inherit;
  text-decoration: none;
}
.br-row.br-status-closed {
  opacity: 0.7;
}
.br-clock {
  display: inline-block;
  align-self: flex-start;
  margin: 6px 0;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 700;
  border: 1px solid var(--border);
}
.br-clock.br-ok {
  border-color: var(--accent);
  color: var(--accent-text);
}
.br-clock.br-soon {
  border-color: var(--warn);
  color: var(--warn);
}
.br-clock.br-urgent,
.br-clock.br-overdue {
  border-color: var(--danger);
  color: var(--danger);
}
.br-missing {
  border: 1px solid var(--warn);
  background: var(--warn-bg);
  border-radius: 10px;
  padding: 10px 12px;
  margin: 10px 0;
}
.br-log {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-left: 18px;
}
.br-log li span {
  display: block;
}

/* maintenance switch (admin) */
.mt-state {
  font-size: 1rem;
  margin: 12px 0;
}
.mt-form {
  max-width: 560px;
  margin: 18px 0 26px;
}
.mt-form h2 {
  margin: 0 0 10px;
  font-size: 1.125rem;
}
.mt-form label {
  display: block;
  font-weight: 600;
  margin: 12px 0 4px;
}
.mt-form textarea,
.mt-form input {
  width: 100%;
  box-sizing: border-box;
}
.mt-disk {
  border-collapse: collapse;
  margin: 8px 0 12px;
  max-width: 760px;
}
.mt-disk td {
  padding: 6px 14px 6px 0;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: top;
}
.mt-disk td.num {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}

/* ---- Nod's welcome tour ------------------------------------------------ */
.nt {
  position: fixed;
  inset: 0;
  z-index: 120;
  pointer-events: none;
  --hx: 50vw;
  --hy: 50vh;
  --hw: 0px;
  --hh: 0px;
}
.nt-dim {
  position: absolute;
  inset: 0;
  background: rgb(4 10 20 / 0.66);
  pointer-events: auto;
  transition: clip-path 0.55s cubic-bezier(0.22, 0.8, 0.3, 1);
  clip-path: polygon(
    0 0,
    100% 0,
    100% 100%,
    0 100%,
    0 0,
    var(--hx) var(--hy),
    var(--hx) calc(var(--hy) + var(--hh)),
    calc(var(--hx) + var(--hw)) calc(var(--hy) + var(--hh)),
    calc(var(--hx) + var(--hw)) var(--hy),
    var(--hx) var(--hy)
  );
}
/* the highlight: a rounded ring that breathes slowly around the target */
.nt-ring {
  position: absolute;
  border-radius: 14px;
  box-shadow:
    0 0 0 2px var(--accent),
    0 0 0 6px rgb(23 201 111 / 0.28),
    0 0 28px 6px rgb(23 201 111 / 0.35);
  transition:
    left 0.55s cubic-bezier(0.22, 0.8, 0.3, 1),
    top 0.55s cubic-bezier(0.22, 0.8, 0.3, 1),
    width 0.55s cubic-bezier(0.22, 0.8, 0.3, 1),
    height 0.55s cubic-bezier(0.22, 0.8, 0.3, 1);
  animation: ntPulse 2.6s ease-in-out infinite;
  opacity: 0;
}
.nt.is-target .nt-ring {
  opacity: 1;
}
@keyframes ntPulse {
  0%,
  100% {
    box-shadow:
      0 0 0 2px var(--accent),
      0 0 0 6px rgb(23 201 111 / 0.22),
      0 0 22px 4px rgb(23 201 111 / 0.28);
  }
  50% {
    box-shadow:
      0 0 0 2px var(--accent),
      0 0 0 10px rgb(23 201 111 / 0.12),
      0 0 40px 10px rgb(23 201 111 / 0.45);
  }
}
/* the thing under the spotlight can still be used */
.nt-on .nt-dim {
  pointer-events: auto;
}
/* Nod himself: floats, and glides to wherever he is sent */
.nt-nod {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--size, 96px);
  height: var(--size, 96px);
  color: var(--text);
  filter: drop-shadow(0 10px 22px rgb(0 0 0 / 0.4));
  transition: transform 0.9s cubic-bezier(0.22, 0.8, 0.3, 1);
  will-change: transform;
}
.nt-nod svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  animation: qn-float 4s ease-in-out infinite;
}
.nt-nod #qnt-eye-l {
  transform: translate(7px, 0);
}
.nt-nod #qnt-eye-l-dot,
.nt-nod #qnt-eye-r-dot {
  transition: transform 0.09s ease-in;
}
.nt-nod.is-pleased svg {
  animation: qn-nod 0.7s ease-in-out 2;
}
/* his words */
.nt-bubble {
  position: absolute;
  pointer-events: auto;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px 12px;
  box-shadow:
    0 18px 48px rgb(0 0 0 / 0.38),
    0 0 0 1px rgb(23 201 111 / 0.15);
  transition:
    left 0.7s cubic-bezier(0.22, 0.8, 0.3, 1),
    top 0.7s cubic-bezier(0.22, 0.8, 0.3, 1),
    max-width 0.3s ease;
  animation: ntIn 0.35s ease both;
}
@keyframes ntIn {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.nt-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.nt-who {
  font-weight: 800;
  color: var(--accent-text);
  letter-spacing: -0.01em;
}
.nt-count {
  color: var(--text-faint);
  font-size: 0.75rem;
  font-weight: 600;
}
.nt-sound {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--text-faint);
  cursor: pointer;
  padding: 4px;
  border-radius: 8px;
  display: inline-flex;
}
.nt-sound.is-off .nt-wave {
  display: none;
}
.nt-sound:hover {
  color: var(--text);
  background: var(--bg-raised);
}
.nt-title {
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
}
.nt-body {
  min-height: 48px;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text-muted);
}
.nt-body p {
  margin: 0 0 8px;
}
.nt-row {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  flex-wrap: wrap;
  margin-top: 8px;
}
.nt-btn {
  border: none;
  border-radius: var(--radius);
  font: 600 0.875rem var(--font);
  padding: 9px 16px;
  min-height: 40px;
  cursor: pointer;
  background: var(--bg-raised);
  color: var(--text);
  transition:
    transform 0.15s ease,
    opacity 0.2s ease;
}
.nt-btn.primary {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 6px 18px rgb(23 201 111 / 0.35);
}
.nt-btn.quiet {
  background: none;
  color: var(--text-faint);
}
.nt-btn:disabled {
  opacity: 0.45;
  cursor: default;
}
.nt-btn:not(:disabled):hover {
  transform: translateY(-1px);
}
.nt-btn:focus-visible {
  outline: 3px solid var(--text);
  outline-offset: 2px;
}
.nt-live {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
/* pop-up windows */
.nt-pop {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 16px;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.25s ease,
    visibility 0s linear 0.25s;
}
.nt-pop.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.25s ease;
}
.nt-card {
  width: min(520px, 100%);
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 20px 20px 18px;
  box-shadow:
    0 24px 64px rgb(0 0 0 / 0.45),
    0 0 0 1px rgb(23 201 111 / 0.18);
  transform: translateY(14px) scale(0.98);
  transition: transform 0.3s cubic-bezier(0.22, 0.8, 0.3, 1);
}
.nt-pop.is-open .nt-card {
  transform: none;
}
.nt-card-h {
  margin: 0 0 12px;
  font-size: 1.1875rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.nt-card-demo {
  margin: 0 0 12px;
}
.nt-card-cap {
  margin: 0 0 14px;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text-muted);
}
.nt-card .nt-btn {
  width: 100%;
}
/* the page fades as Nod leads the way out, and back in as he arrives */
body.nt-leave {
  transition: opacity 0.26s ease;
  opacity: 0;
}
body.nt-arrive {
  animation: ntArrive 0.5s ease both;
}
@keyframes ntArrive {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
/* the practice job is marked so nobody mistakes it for a saved one */
form.nt-practice {
  position: relative;
}
form.nt-practice::before {
  content: 'Practice — not saved';
  position: sticky;
  top: 8px;
  z-index: 5;
  display: inline-block;
  margin: 0 0 10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font: 700 0.75rem var(--font);
  letter-spacing: 0.02em;
}
/* the phone: the bubble is a sheet at the foot of the screen */
.nt[data-device='phone'] .nt-bubble {
  left: 8px !important;
  right: 8px !important;
  bottom: calc(8px + env(safe-area-inset-bottom, 0px)) !important;
  top: auto !important;
  max-width: none !important;
  max-height: 62vh;
  overflow: auto;
  border-radius: 18px;
}
.nt[data-device='phone'] .nt-row {
  position: sticky;
  bottom: -12px;
  margin: 8px -16px -12px;
  padding: 10px 16px 12px;
  background: var(--bg);
  border-top: 1px solid var(--border);
}
.nt[data-device='phone'] .nt-card {
  max-height: 88vh;
  overflow: auto;
}
.nt[data-device='phone'] .nt-body {
  font-size: 0.90625rem;
}
@media (prefers-reduced-motion: reduce) {
  .nt-nod,
  .nt-bubble,
  .nt-dim,
  .nt-ring {
    transition: none;
  }
  .nt-ring {
    animation: none;
  }
  .nt-nod svg {
    animation: none;
  }
}

/* ---- the roadmap: a road down the page ---------------------------------- */
.rd-wrap {
  max-width: 960px;
}
.rd-head {
  margin-bottom: 8px;
}
.rd-idea-row {
  margin: 10px 0 0;
}
.rd {
  position: relative;
  padding: 24px 0 40px;
  --rd-road: 150px;
}
.rd-road {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.rd-road path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* the road is stroked lanes on one path: a soft shadow under it, a dark kerb,
   the tarmac, a lighter edge catching the light, the dashed centre line, and
   the stretch behind Nod lit in green */
.rd-road-shadow {
  stroke: rgb(0 0 0 / 0.35);
  stroke-width: 34;
  transform: translate(3px, 9px);
  filter: blur(6px);
}
.rd-road-kerb {
  stroke: var(--rd-kerb, #0d1728);
  stroke-width: 30;
  transform: translate(0, 6px);
}
.rd-road-base {
  stroke: var(--rd-tarmac, #1b2a44);
  stroke-width: 28;
}
.rd-road-edge {
  stroke: var(--rd-edge, rgb(255 255 255 / 0.12));
  stroke-width: 30;
  opacity: 0.9;
  transform: translate(-1px, -1px);
}
.rd-road-mid {
  stroke: var(--rd-line, rgb(255 255 255 / 0.55));
  stroke-width: 2.5;
  stroke-dasharray: 10 14;
}
.rd-road-done {
  stroke: var(--accent);
  stroke-width: 5;
  filter: drop-shadow(0 0 8px rgb(23 201 111 / 0.6));
}
/* a ring spreading across the road when a stop is opened */
.rd-ripple {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  opacity: 0;
  pointer-events: none;
}
.rd-ripple.is-going {
  animation: rdRipple 0.9s ease-out forwards;
}
@keyframes rdRipple {
  0% {
    r: 6;
    opacity: 0.9;
    stroke-width: 4;
  }
  100% {
    r: 70;
    opacity: 0;
    stroke-width: 1;
  }
}
.rd-nod.is-nod svg {
  animation: qn-nod 0.7s ease-in-out 2;
}
/* light theme: the tarmac stays dark, so it reads as a road against a pale page */
.rd {
  --rd-tarmac: #2b3a52;
  --rd-tarmac-dark: #1f2c40;
  --rd-kerb: #1a2536;
  --rd-edge: rgb(255 255 255 / 0.18);
  --rd-line: rgb(255 255 255 / 0.7);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .rd {
    --rd-tarmac: #1b2a44;
    --rd-tarmac-dark: #122038;
    --rd-kerb: #0d1728;
    --rd-edge: rgb(255 255 255 / 0.1);
    --rd-line: rgb(255 255 255 / 0.55);
  }
}
:root[data-theme='dark'] .rd {
  --rd-tarmac: #1b2a44;
  --rd-tarmac-dark: #122038;
  --rd-kerb: #0d1728;
  --rd-edge: rgb(255 255 255 / 0.1);
  --rd-line: rgb(255 255 255 / 0.55);
}
.rd-nod {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;
  width: 64px;
  height: 64px;
  color: var(--text);
  pointer-events: none;
  will-change: transform;
  filter: drop-shadow(0 8px 16px rgb(0 0 0 / 0.35));
}
.rd-nod svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  animation: qn-float 4s ease-in-out infinite;
}
.rd-nod #qnr-eye-l {
  transform: translate(7px, 0);
}
html:not(.rd-js) .rd-road,
html:not(.rd-js) .rd-nod {
  display: none;
}
.rd-list {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 34px;
}
.rd-item {
  position: relative;
  display: grid;
  grid-template-columns: 1fr var(--rd-road) 1fr;
  align-items: start;
  min-height: 72px;
}
/* everything in a stop sits on one row: without this the grid put a card on
   the left into a second row under the dot, fifty pixels lower than the dot
   the road passed through */
.rd-item > * {
  grid-row: 1;
}
.rd-item.is-right .rd-card {
  grid-column: 3;
}
.rd-item.is-left .rd-card {
  grid-column: 1;
}
/* the dot sits level with the card's title, not its middle: a card that opens
   grows downwards and the dot — and the road through it — stays put */
.rd-dot {
  grid-column: 2;
  justify-self: center;
  align-self: start;
  margin-top: 42px;
  z-index: 1;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--bg);
  border: 3px solid var(--border);
  box-shadow: 0 0 0 4px var(--bg);
  transition:
    border-color 0.3s ease,
    box-shadow 0.3s ease;
}
.rd-shipped .rd-dot {
  border-color: var(--accent);
}
/* the dot sits on the card's side of the lane, so the road weaves to meet it */
.rd-item.is-right .rd-dot {
  justify-self: end;
  margin-right: 22px;
}
.rd-item.is-left .rd-dot {
  justify-self: start;
  margin-left: 22px;
}
.rd-item.is-open .rd-dot {
  box-shadow:
    0 0 0 4px var(--bg),
    0 0 18px 4px rgb(23 201 111 / 0.45);
}
.rd-today {
  min-height: 40px;
  align-items: center;
}
.rd-today .rd-dot {
  align-self: center;
  margin-top: 0;
}
.rd-dot-now {
  width: 14px;
  height: 14px;
  background: var(--accent);
  border-color: var(--accent);
}
.rd-today-label {
  grid-column: 3;
  font-size: 0.71875rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-strong, var(--accent));
}
/* arriving: from the side the card sits on */
html.rd-js .rd-item .rd-card,
html.rd-js .rd-item .rd-dot {
  opacity: 0;
  transition:
    opacity 0.55s ease,
    transform 0.55s cubic-bezier(0.2, 0.7, 0.3, 1);
  transition-delay: calc(min(var(--rd-i, 0), 9) * 60ms);
}
html.rd-js .rd-item.is-right .rd-card {
  transform: perspective(900px) rotateY(-14deg) translateX(36px);
}
html.rd-js .rd-item.is-left .rd-card {
  transform: perspective(900px) rotateY(14deg) translateX(-36px);
}
html.rd-js .rd-item .rd-dot {
  transform: scale(0.4);
}
html.rd-js .rd-item.is-in .rd-card {
  opacity: 1;
  transform: perspective(900px) rotateY(0) translateX(0);
}
html.rd-js .rd-item.is-in .rd-dot {
  opacity: 1;
  transform: none;
}
.rd-card {
  transform-style: preserve-3d;
  contain: layout paint;
  will-change: transform;
}
body.has-roadmap {
  overflow-anchor: none;
}
html.rd-js .rd-held {
  display: none;
}
/* the card */
.rd-card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.rd-item.is-open .rd-card {
  border-color: rgb(23 201 111 / 0.55);
  box-shadow:
    var(--shadow-2),
    0 0 0 1px rgb(23 201 111 / 0.2);
}
.rd-sum {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: 14px 14px 14px 16px;
  background: none;
  border: none;
  color: inherit;
  text-align: left;
  font: inherit;
  cursor: pointer;
}
.rd-sum:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
  border-radius: 16px;
}
.rd-pic {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--bg);
  color: var(--text-muted);
}
.rd-pic .rm-art {
  width: 34px;
  height: 34px;
}
.rd-shipped .rd-pic {
  color: var(--accent-strong, var(--accent));
}
.rd-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.rd-top {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.rd-date {
  font-size: 0.75rem;
  color: var(--text-faint);
}
.rd-title {
  font-size: 1rem;
  letter-spacing: -0.01em;
  line-height: 1.3;
}
.rd-blurb {
  font-size: 0.84375rem;
  color: var(--text-muted);
  line-height: 1.45;
}
.rd-chev {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--text-faint);
  transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.3, 1);
  margin-top: 10px;
}
.rd-chev svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rd-item.is-open .rd-chev {
  transform: rotate(180deg);
  color: var(--accent-text);
}
/* the panel grows in place: nothing below is covered, the road just gets longer */
.rd-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.5s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.rd-panel-in {
  min-height: 0;
  overflow: hidden;
  padding: 0 16px;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.rd-item.is-open .rd-panel {
  grid-template-rows: 1fr;
}
.rd-item.is-open .rd-panel-in {
  opacity: 1;
  padding: 0 16px 16px;
  transition: opacity 0.4s ease 0.15s;
}
html:not(.rd-js) .rd-panel {
  grid-template-rows: 1fr;
}
html:not(.rd-js) .rd-panel-in {
  opacity: 1;
  padding: 0 16px 16px;
}
.rd-demo {
  margin: 4px 0 12px;
}
.rd-demo .demo {
  max-width: 100%;
  contain: layout paint;
}
.rd-panel-in p {
  margin: 8px 0;
  font-size: 0.90625rem;
  line-height: 1.55;
}
.rd-more,
.rd-back {
  text-align: center;
  font-size: 0.8125rem;
  color: var(--text-faint);
  min-height: 24px;
}
.rd-more {
  padding: 84px 0 0;
}
.rd-back {
  padding: 0 0 22px;
}
.rd-jump {
  border: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--text);
  font: 600 0.8125rem var(--font);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
}
.rd-jump:hover {
  border-color: var(--accent);
}
.rd-more-end {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  color: var(--text-muted);
}
.rd-end-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px rgb(23 201 111 / 0.2);
}
.rd-where {
  text-align: center;
  font-size: 0.75rem;
  color: var(--text-faint);
  margin: 10px 0 0;
}
/* the ten on their way out */
html.rd-js .rd-item.is-out .rd-card,
html.rd-js .rd-item.is-out .rd-dot {
  opacity: 0 !important;
  transition-delay: 0s !important;
  transition-duration: 0.28s !important;
}
/* the idea window */
.rd-idea {
  width: min(520px, calc(100vw - 32px));
  padding: 0;
}
.rd-idea-form {
  padding: 22px 22px 18px;
}
.rd-idea-form h2 {
  margin: 0 0 6px;
  font-size: 1.3125rem;
}
.rd-idea-form label {
  display: block;
  font-weight: 600;
  margin: 12px 0 4px;
}
.rd-idea-form input,
.rd-idea-form textarea {
  width: 100%;
  box-sizing: border-box;
}
.rd-idea-form .btn-row {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-top: 16px;
}
/* the switch between a road with depth and a flat line */
.rd-idea-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.rd-view {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
  margin-left: auto;
}
.rd-view-btn {
  border: none;
  background: none;
  color: var(--text-muted);
  font: 700 0.8125rem var(--font);
  padding: 7px 14px;
  min-height: 34px;
  cursor: pointer;
}
.rd-view-btn.is-on {
  background: var(--accent);
  color: var(--on-accent);
}
.rd-view-btn:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}
/* depth, in 3D: the cards rest turned a few degrees toward the road, lift on
   hover, and cast a deeper shadow; the road has a kerb and a shadow under it */
.rd[data-view='3d'] .rd-item.is-in.is-right .rd-card {
  transform: perspective(900px) rotateY(-4deg) translateX(0);
}
.rd[data-view='3d'] .rd-item.is-in.is-left .rd-card {
  transform: perspective(900px) rotateY(4deg) translateX(0);
}
.rd[data-view='3d'] .rd-item.is-in.is-open .rd-card,
.rd[data-view='3d'] .rd-item.is-in .rd-card:hover {
  transform: perspective(900px) rotateY(0) translateX(0) translateZ(14px);
}
.rd[data-view='3d'] .rd-card {
  box-shadow:
    var(--shadow-2),
    0 18px 30px -18px rgb(0 0 0 / 0.55);
}
/* flat, in 2D: a thin line, flat dots, cards square to the page */
.rd[data-view='2d'] .rd-road-shadow,
.rd[data-view='2d'] .rd-road-kerb,
.rd[data-view='2d'] .rd-road-edge,
.rd[data-view='2d'] .rd-road-mid {
  display: none;
}
.rd[data-view='2d'] .rd-road-base {
  stroke: var(--border);
  stroke-width: 4;
}
.rd[data-view='2d'] .rd-road-done {
  stroke-width: 4;
  filter: none;
}
.rd[data-view='2d'] .rd-nod {
  filter: none;
}
.rd[data-view='2d'] .rd-nod svg {
  animation: none;
}
html.rd-js .rd[data-view='2d'] .rd-item .rd-card {
  transform: translateY(10px);
}
html.rd-js .rd[data-view='2d'] .rd-item.is-in .rd-card {
  transform: none;
}
.rd[data-view='2d'] .rd-card {
  box-shadow: none;
}
.rd[data-view='2d'] .rd-dot {
  box-shadow: none;
  border-width: 2px;
}

/* the phone: the road down the left, every card on the right */
@media (max-width: 720px) {
  .rd {
    --rd-road: 64px;
  }
  /* a blurred stroke the height of the page is the one thing here a phone's
     chip feels; a plain translucent one reads the same at this width */
  .rd-road-shadow {
    stroke-width: 24;
    transform: translate(2px, 7px);
    filter: none;
    opacity: 0.6;
  }
  .rd-road-kerb {
    stroke-width: 22;
    transform: translate(0, 5px);
  }
  .rd-road-base {
    stroke-width: 20;
  }
  .rd-road-edge {
    stroke-width: 22;
  }
  .rd-item {
    grid-template-columns: var(--rd-road) 1fr;
  }
  .rd-item.is-right .rd-card,
  .rd-item.is-left .rd-card {
    grid-column: 2;
  }
  .rd-dot {
    grid-column: 1;
  }
  .rd-item.is-left .rd-dot {
    justify-self: start;
    margin-left: 8px;
  }
  .rd-item.is-right .rd-dot {
    justify-self: end;
    margin-right: 8px;
  }
  .rd-today-label {
    grid-column: 2;
  }
  html.rd-js .rd-item.is-left:not(.is-in) .rd-card,
  html.rd-js .rd-item.is-right:not(.is-in) .rd-card {
    transform: perspective(700px) rotateY(-12deg) translateX(30px);
  }
  .rd-nod {
    width: 48px;
    height: 48px;
    margin-left: -8px;
  }
  .rd-list {
    gap: 26px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .rd-nod svg {
    animation: none;
  }
  html.rd-js .rd-item .rd-card,
  html.rd-js .rd-item .rd-dot,
  .rd-panel,
  .rd-panel-in,
  .rd-chev {
    transition: none;
  }
}

/* ---------- strikes, bans and appeals ---------------------------------------
   The trader's block on the Account page, and the owner's Reports & strikes
   page. Both are lists of things said in writing, so the words get the room
   and the controls sit under them.                                            */
.cd-strikes {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cd-strike {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-raised);
}
.cd-strike.is-revoked {
  opacity: 0.65;
}
.cd-strike.is-revoked .cd-reason {
  text-decoration: line-through;
}
.cd-strike-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.cd-reason {
  margin: 8px 0;
  white-space: pre-wrap;
}
.cd-ban {
  margin-bottom: 12px;
}
.cd-appeal {
  margin-top: 6px;
}
.cd-appeal > summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--accent-strong, var(--accent));
}
.cd-appeal-form {
  margin-top: 10px;
}
.cd-appeal-form textarea,
.cd-appeal-form input[type='file'] {
  width: 100%;
}
.cd-evidence,
.cd-credits,
.cd-decided,
.cd-banned {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cd-report {
  margin: 0 0 14px;
}
.cd-report-head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.cd-body {
  white-space: pre-wrap;
  margin: 10px 0;
  padding: 10px 12px;
  border-left: 3px solid var(--border);
}
.cd-decide {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 10px;
}
.cd-decide textarea {
  width: 100%;
}
.cd-inline {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin: 8px 0;
}
.cd-inline input {
  flex: 1 1 200px;
}
@media (max-width: 640px) {
  .cd-decide {
    grid-template-columns: 1fr;
  }
}

/* ---- Customisation: the style presets ---- */
.style-rows {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  margin: 8px 0 4px;
  min-width: 0;
}
.style-row {
  min-width: 0;
}
.style-row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.style-row-head h3 {
  margin: 0;
  font-size: 0.9375rem;
}
.style-row-head h3 .small {
  display: block;
  font-weight: 400;
}
.scroll-arrows {
  display: flex;
  flex: none;
  gap: 6px;
}
.scroll-arrow {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--text);
  font-size: 1.375rem;
  line-height: 1;
  cursor: pointer;
}
.scroll-arrow:hover:not(:disabled) {
  border-color: var(--accent);
}
.scroll-arrow:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.scroll-arrow:disabled {
  opacity: 0.35;
  cursor: default;
}
.style-strip {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 3px;
  padding: 3px 3px 10px;
  scrollbar-width: thin;
  cursor: grab;
}
.style-strip:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.style-strip.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}
.style-strip > .style-card {
  flex: 0 0 168px;
  scroll-snap-align: start;
}
.style-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  border: 1.5px solid var(--border-soft);
  border-radius: 10px;
  padding: 10px;
  cursor: pointer;
  margin: 0;
  font-weight: 400;
  position: relative;
}
.style-card input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.style-card.is-on {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.style-card:has(input:checked) {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.style-card:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.style-card b {
  font-size: 0.875rem;
}
.style-card .small {
  line-height: 1.3;
}
.style-card.is-warn {
  border-style: dashed;
}
.style-warn {
  color: var(--danger);
}
.style-swatch {
  display: block;
  height: 64px;
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  background: #fff;
  position: relative;
  overflow: hidden;
}
.style-swatch i {
  position: absolute;
  left: 10%;
  right: 10%;
  height: 4px;
  border-radius: 2px;
  background: #cfd6de;
}
.style-swatch i:nth-child(1) {
  top: 30%;
}
.style-swatch i:nth-child(2) {
  top: 48%;
  right: 30%;
}
.style-swatch i:nth-child(3) {
  top: 66%;
  right: 45%;
}
.style-swatch::before {
  content: '';
  position: absolute;
  left: 10%;
  right: 10%;
  top: 14%;
  height: 3px;
  background: var(--accent);
}
.style-swatch.style-banner::before,
.style-swatch.style-tab::before,
.style-swatch.style-night::before {
  left: 0;
  right: 0;
  top: 0;
  height: 22%;
}
.style-swatch.style-night::before {
  background: var(--navy-800);
}
.style-swatch.style-tab::before {
  left: 60%;
  right: 8%;
  height: 26%;
  border-radius: 0 0 4px 4px;
}
.style-swatch.style-duo::before {
  left: 0;
  right: 0;
  top: 0;
  height: 22%;
  background: linear-gradient(90deg, var(--navy-800) 0 56%, var(--accent) 56%);
}
.style-swatch.style-sidebar::before {
  left: 0;
  top: 0;
  bottom: 0;
  right: 72%;
  height: auto;
  opacity: 0.25;
}
.style-swatch.style-stripe::before,
.style-swatch.style-compact::before {
  left: 0;
  right: 0;
  top: 0;
  height: 6%;
}
.style-swatch.style-angular::before {
  left: 55%;
  right: 0;
  top: 0;
  height: 14%;
  clip-path: polygon(20% 0, 100% 0, 100% 100%, 0 100%);
}
.style-swatch.style-corner::before {
  left: 0;
  right: 55%;
  top: 0;
  height: 40%;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}
.style-swatch.style-ribbon::before {
  left: 62%;
  right: -20%;
  top: 8%;
  height: 10%;
  transform: rotate(35deg);
}
.style-swatch.style-vertical::before {
  left: 4%;
  right: auto;
  width: 4px;
  top: 20%;
  height: 60%;
}
.style-swatch.style-frame::before,
.style-swatch.style-outline::before {
  left: 6%;
  right: 6%;
  top: 8%;
  bottom: 8%;
  height: auto;
  background: none;
  border: 1px solid var(--accent);
}
.style-swatch.style-ink::before,
.style-swatch.style-ink i {
  background: #000;
}
.style-swatch.style-mono i,
.style-swatch.style-receipt i {
  background: repeating-linear-gradient(90deg, #cfd6de 0 4px, transparent 4px 7px);
}
.style-swatch.style-letterhead::before,
.style-swatch.style-classic::before {
  left: 35%;
  right: 35%;
}
.style-swatch.style-block::before,
.style-swatch.style-tally::before {
  top: 78%;
  height: 12%;
}
.style-swatch.style-panel::before {
  left: 55%;
  top: 30%;
  height: 30%;
  opacity: 0.85;
}
.style-swatch.style-soft::before {
  left: 6%;
  right: 6%;
  top: 6%;
  height: 24%;
  opacity: 0.2;
  border-radius: 4px;
}
.style-swatch.style-twotone::before {
  left: 0;
  right: 0;
  top: 0;
  height: 40%;
  opacity: 0.15;
}
.style-swatch.style-boldrule::before,
.style-swatch.style-trade::before {
  height: 8px;
}
.style-swatch.style-underline::before {
  left: 10%;
  right: 55%;
  top: 22%;
  height: 5px;
}
.style-swatch.style-tag::before {
  left: 60%;
  right: 10%;
  top: 8%;
  height: 12px;
  border-radius: 999px;
}
.style-swatch.style-bracket::before {
  left: 10%;
  right: 55%;
  top: 8%;
  height: 14px;
  background: none;
  border-left: 3px solid var(--accent);
  border-right: 3px solid var(--accent);
}
.style-swatch.style-dblrule::before,
.style-swatch.style-ruled::before {
  height: 4px;
  background: none;
  border-top: 1px solid var(--text);
  border-bottom: 1px solid var(--text);
}
.ink {
  display: inline-block;
  font-size: 0.65625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-muted);
  width: max-content;
}
.ink-low {
  border-color: var(--accent);
  color: var(--accent-text);
}
.ink-high {
  border-color: var(--warn, #b45309);
  color: var(--warn, #b45309);
}

/* ---- Customisation: emails and service reminders ---- */
.email-tpl {
  border-top: 1px solid var(--border-soft);
  padding-top: 12px;
  margin-top: 14px;
}
.email-tpl h3 {
  margin: 0 0 2px;
}
.svc-row {
  display: grid;
  grid-template-columns: 1.4fr 80px 80px;
  gap: 8px;
  align-items: start;
  border-top: 1px solid var(--border-soft);
  padding-top: 12px;
  margin-top: 12px;
}
.svc-row textarea {
  grid-column: 1 / -1;
}
.svc-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: 8px;
}
.svc-new {
  border-top: 2px solid var(--border);
}

/* ---- Customisation: the preview turns over when the document changes ---- */
.live-flip {
  perspective: 2000px;
}
.live-flip.is-turning #live-frame {
  animation: live-turn 0.6s ease;
}
@keyframes live-turn {
  0% {
    transform: rotateY(0);
  }
  50% {
    transform: rotateY(90deg);
  }
  100% {
    transform: rotateY(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .live-flip.is-turning #live-frame {
    animation: none;
  }
}

/* ---------- On site: photos, the clock, hazards, sketch, certificates ---------- */
.wrap-site {
  max-width: 760px;
}
.site-card {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin: 12px 0 16px;
}
.site-card.has-warn {
  border-color: var(--warn);
}
.site-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.site-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}
.site-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--bg);
  border: 1px solid var(--border-soft);
  text-decoration: none;
  color: var(--text);
  min-width: 0;
}
.site-stat b {
  font-size: 1.125rem;
  line-height: 1.1;
}
.site-stat span {
  font-size: 0.75rem;
  color: var(--text-muted);
}
.site-stat.is-warn {
  background: var(--warn-bg);
  border-color: var(--warn);
}
.site-stat.is-warn b {
  color: var(--warn);
}
@media (max-width: 560px) {
  .site-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.site-h3 {
  font-size: 0.9375rem;
  margin: 18px 0 8px;
}
.site-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
}
.site-row form {
  margin: 0;
}
/* upload */
.site-upload {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 8px;
}
.site-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 22px 16px;
  border: 2px dashed var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  cursor: pointer;
  text-align: center;
}
.site-drop:focus-within {
  border-color: var(--accent);
}
.site-drop input[type='file'] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}
.site-drop-big {
  font-size: 1.0625rem;
  font-weight: 700;
}
.site-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
}
.site-grid-small {
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  margin: 8px 0;
}
.site-thumb {
  position: relative;
  margin: 0;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.site-thumb a {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--bg-inset);
}
.site-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.site-doc {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}
.site-thumb figcaption {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px 8px;
  font-size: 0.75rem;
  overflow: hidden;
}
.site-thumb figcaption span:first-child {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.site-thumb form {
  position: absolute;
  top: 4px;
  right: 4px;
  margin: 0;
}
.site-thumb .expense-del {
  background: rgba(255, 255, 255, 0.9);
  /* always dark on the white disc, whatever the theme */
  color: #12233c;
  border-radius: 999px;
  line-height: 1;
  width: 26px;
  height: 26px;
  padding: 0;
}
/* clock */
.site-clock {
  text-align: center;
  padding: 22px 16px;
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  margin-bottom: 12px;
}
.site-clock.is-running {
  border-color: var(--accent);
  background: var(--accent-tint);
}
.site-clock-big {
  font-size: 2.75rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.site-clock form {
  margin: 14px auto 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 360px;
}
.site-start {
  font-size: 1.0625rem;
  padding: 14px 18px;
}
.btn-compact.danger {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
}
.site-manual {
  margin: 0 0 12px;
}
.site-manual summary {
  cursor: pointer;
  color: var(--text-muted);
  font-size: 0.875rem;
}
.site-manual .expense-form {
  margin-top: 8px;
}
.site-entries li > b {
  white-space: nowrap;
}
/* hazards */
.site-hazard-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  margin-bottom: 8px;
}
.site-sev {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}
.site-sev-opt {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  font-size: 0.8125rem;
  cursor: pointer;
  background: var(--bg);
}
.site-sev-opt:has(input:checked) {
  border-width: 2px;
}
.site-sev-opt.sev-low:has(input:checked) {
  border-color: var(--ok);
  background: var(--ok-bg);
}
.site-sev-opt.sev-medium:has(input:checked) {
  border-color: var(--warn);
  background: var(--warn-bg);
}
.site-sev-opt.sev-high:has(input:checked) {
  border-color: var(--danger);
  background: var(--danger-bg);
}
.site-file-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.chip.sev-low {
  background: var(--ok-bg);
  color: var(--ok);
}
.chip.sev-medium {
  background: var(--warn-bg);
  color: var(--warn);
}
.chip.sev-high {
  background: var(--danger-bg);
  color: var(--danger);
}
.chip.chip-ok {
  background: var(--ok-bg);
  color: var(--ok);
}
.chip.chip-warn {
  background: var(--warn-bg);
  color: var(--warn);
}
.site-hazard {
  position: relative;
  padding: 12px 40px 12px 14px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-soft);
  border-left-width: 5px;
  margin-bottom: 10px;
  background: var(--bg-raised);
}
.site-hazard.is-high {
  border-left-color: var(--danger);
}
.site-hazard.is-medium {
  border-left-color: var(--warn);
}
.site-hazard.is-low {
  border-left-color: var(--ok);
}
.site-hazard.is-resolved {
  border-left-color: var(--border);
  opacity: 0.85;
}
.site-hazard-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.site-hazard-desc {
  margin: 6px 0 0;
  white-space: pre-wrap;
}
.site-resolved {
  margin: 8px 0 0;
  font-size: 0.875rem;
}
.site-resolve {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  flex-wrap: wrap;
}
.site-resolve input {
  flex: 1;
  min-width: 180px;
}
.site-del {
  position: absolute;
  top: 8px;
  right: 6px;
  margin: 0;
}
.hazards-card {
  background: var(--warn-bg);
  border: 1px solid var(--warn);
  border-radius: var(--radius-lg);
  padding: 12px 16px;
  margin: 0 0 14px;
}
.hazards-card ul {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
}
.hazards-card li {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 3px 0;
  flex-wrap: wrap;
}
/* sketch */
.sketch-pad {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 10px;
}
.sketch-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}
.sketch-colours,
.sketch-widths {
  display: flex;
  gap: 6px;
}
.sketch-colour {
  width: 28px;
  height: 28px;
  border-radius: 999px;
  border: 2px solid transparent;
  cursor: pointer;
}
.sketch-colour.is-on {
  border-color: var(--text);
  box-shadow: 0 0 0 2px var(--bg);
}
.sketch-width {
  width: 34px;
  height: 28px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
}
.sketch-width.is-on,
.sketch-tools .btn-compact.is-on {
  border-color: var(--accent);
  background: var(--accent-tint);
}
.sketch-canvas {
  width: 100%;
  aspect-ratio: 3 / 2;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  touch-action: none;
  cursor: crosshair;
  display: block;
}
.sketch-save {
  display: flex;
  gap: 8px;
  margin-top: 8px;
  flex-wrap: wrap;
}
.sketch-save input[type='text'] {
  flex: 1;
  min-width: 13em;
}
/* certificates */
.cert-new {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.cert-new select {
  flex: 1;
  min-width: 200px;
}
.cert-row {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  margin-bottom: 10px;
  background: var(--bg-raised);
}
.cert-row.is-issued {
  border-left: 5px solid var(--accent);
}
.cert-row-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.cert-share {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border-soft);
}
.cert-send {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.cert-send input {
  flex: 1;
  min-width: 200px;
}
.cert-form .cert-h2 {
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 20px 0 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border-soft);
}
.cert-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 14px;
}
.cert-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  grid-column: span 2;
}
.cert-field.half {
  grid-column: span 1;
}
.cert-field > span {
  font-size: 0.8125rem;
  font-weight: 600;
}
.cert-field .req {
  color: var(--danger);
}
.cert-field input[type='checkbox'] {
  width: 22px;
  height: 22px;
}
@media (max-width: 480px) {
  .cert-field.half {
    grid-column: span 2;
  }
}
.cert-more {
  margin: 10px 0;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  padding: 8px 12px;
}
.cert-more summary {
  cursor: pointer;
  font-weight: 600;
}
.cert-more .cert-grid {
  margin-top: 8px;
}
.cert-footer {
  margin-top: 18px;
  border-top: 1px solid var(--border-soft);
  padding-top: 8px;
}
.cert-actions {
  margin-top: 14px;
  justify-content: flex-end;
}
/* receipts on expenses */
.expense-receipt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  font-size: 0.8125rem;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.expense-receipt input[type='file'] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.expense-receipt span {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- Customer portal, messages, enquiries ---------- */
.portal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0 14px;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 16px;
}
.portal-head form {
  margin: 0;
}
.portal-kicker {
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.portal-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 12px 0;
}
.portal-form .btn,
.portal-form .btn-compact {
  align-self: flex-start;
  margin-top: 6px;
}
.portal-newcode {
  margin-top: 14px;
}
.portal-newcode summary {
  cursor: pointer;
  color: var(--text-muted);
}
.portal-foot {
  margin-top: 30px;
  border-top: 1px solid var(--border-soft);
  padding-top: 10px;
}
.portal-job {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 14px 16px;
  margin-bottom: 12px;
}
.portal-job-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 8px;
}
.portal-docs {
  list-style: none;
  padding: 0;
  margin: 6px 0;
}
.portal-docs li {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border-soft);
}
/* messages */
.presence {
  display: flex;
  align-items: center;
  gap: 6px;
}
.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--border);
  vertical-align: middle;
}
.dot-online {
  background: var(--accent);
}
.dot-away {
  background: var(--warn);
}
.dot-offline {
  background: var(--text-faint);
}
.msg-thread {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  min-height: 120px;
  margin-bottom: 10px;
}
.msg {
  max-width: 82%;
  align-self: flex-start;
}
.msg.is-mine {
  align-self: flex-end;
  text-align: right;
}
.msg-body {
  display: inline-block;
  text-align: left;
  padding: 9px 12px;
  border-radius: 14px 14px 14px 4px;
  background: var(--bg);
  border: 1px solid var(--border-soft);
}
.msg.is-mine .msg-body {
  background: var(--accent-tint);
  border-color: transparent;
  border-radius: 14px 14px 4px 14px;
  color: var(--text);
}
.msg-text {
  white-space: pre-wrap;
  word-break: break-word;
}
.msg-att {
  display: block;
  margin-top: 6px;
}
.msg-att img {
  max-width: 240px;
  max-height: 240px;
  border-radius: 8px;
  display: block;
}
.msg-meta {
  margin-top: 2px;
}
.msg-keep {
  align-self: flex-start;
  margin: -4px 0 4px;
}
.msg-compose {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.msg-compose-row {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  align-items: center;
}
.msg-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.msg-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  text-decoration: none;
  color: var(--text);
}
.msg-row.is-unread {
  border-left: 5px solid var(--accent);
}
.msg-row.is-blocked {
  opacity: 0.7;
}
.msg-row-main {
  min-width: 0;
}
.msg-row-preview {
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.msg-row-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex: 0 0 auto;
}
.msg-badge {
  background: var(--accent);
  color: var(--on-accent);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 1px 8px;
}
.msg-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 18px;
  align-items: start;
}
@media (max-width: 860px) {
  .msg-layout {
    grid-template-columns: 1fr;
  }
}
.msg-job {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 14px;
  position: sticky;
  top: 12px;
}
.msg-job-head {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  align-items: flex-start;
}
.msg-drawer {
  margin-top: 10px;
  border-top: 1px solid var(--border-soft);
  padding-top: 8px;
}
.msg-drawer summary {
  cursor: pointer;
  font-weight: 600;
}
.msg-lines {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
  margin-top: 6px;
}
.msg-lines td {
  padding: 4px 0;
  border-bottom: 1px solid var(--border-soft);
}
.msg-lines td:last-child {
  text-align: right;
  white-space: nowrap;
}
.msg-total td {
  font-weight: 700;
  border-bottom: 0;
}
.msg-block {
  margin-top: 12px;
}
.cm-portal {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  margin: 12px 0;
}
.cm-portal form {
  margin: 0;
}
/* enquiries */
.enq-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}
.enq-top > h1 {
  flex: 1 1 auto;
  min-width: 0;
}
.enq-top select {
  max-width: 100%;
  min-width: 0;
}
/* on a phone the status picker takes its own line, full width, so its words are never cut under the arrow */
@media (max-width: 640px) {
  .enq-top .site-row {
    flex: 1 1 100%;
    margin: 0 0 16px;
  }
  .enq-top .site-row select {
    width: 100%;
  }
  .enq-top > .btn {
    flex: 1 1 100%;
    margin: 0 0 12px;
  }
}
.enq-form {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.enq-card {
  border: 1px solid var(--border-soft);
  border-left: 5px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 12px 14px;
  margin-bottom: 10px;
}
.enq-card.is-soon {
  border-left-color: var(--warn);
}
.enq-card.is-closed {
  border-left-color: var(--border);
  opacity: 0.8;
}
.enq-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.enq-wants {
  margin: 6px 0;
}
.enq-detail {
  margin-top: 14px;
}
.chase-card {
  background: var(--bg-raised);
  border: 1px solid var(--accent);
  border-radius: var(--radius-lg);
  padding: 12px 16px;
  margin: 0 0 14px;
}
.chase-card ul {
  list-style: none;
  padding: 0;
  margin: 6px 0 10px;
}
.chase-card li {
  padding: 3px 0;
}

/* ---------- Team and diary ---------- */
.avatar {
  border-radius: 999px;
  object-fit: cover;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
}
.avatar-initials {
  color: #fff;
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
}
.sr-who {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 10px;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.team-add {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  margin-bottom: 14px;
}
.team-add .btn-compact {
  align-self: flex-start;
  margin-top: 8px;
}
.team-row {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  margin-bottom: 10px;
}
.team-main {
  flex: 1;
  min-width: 0;
}
.team-edit,
.team-photo {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 8px;
}
.team-edit input[type='text'] {
  flex: 1;
  min-width: 140px;
}
.team-edit input[type='color'] {
  width: 40px;
  height: 36px;
  padding: 2px;
}
.team-side {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-end;
}
.team-side form {
  margin: 0;
}
.team-row {
  flex-wrap: wrap;
}
.team-row.is-paused {
  opacity: 0.75;
  border-style: dashed;
}
/* the sign-in tools sit on their own line under the person */
.team-tools {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 8px;
  border-top: 1px dashed var(--border-soft);
}
.team-tools form {
  margin: 0;
}
.team-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 600;
  background: var(--bg-inset);
  color: var(--text-muted);
  vertical-align: middle;
}
.team-tag-warn {
  background: var(--warn-bg);
  color: var(--warn);
}
.feed-url {
  display: block;
  word-break: break-all;
  padding: 8px 10px;
  border-radius: var(--radius);
  background: var(--bg-inset);
  font-size: 0.75rem;
}
/* diary */
.diary-nav {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.diary-nav h1 {
  margin: 0;
  flex: 1;
  text-align: center;
  font-size: 1.375rem;
}
/* the diary sits in the middle of the screen rather than hugging the top */
.wrap.diary {
  min-height: calc(100vh - 220px);
  min-height: calc(100dvh - 220px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-bottom: 40px;
}
/* press the month to pick another month and year */
.dy-month-pick {
  flex: 1;
  position: relative;
  text-align: center;
}
.dy-month-pick summary {
  list-style: none;
  cursor: pointer;
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--radius);
}
.dy-month-pick summary::-webkit-details-marker {
  display: none;
}
.dy-month-pick summary:hover {
  background: var(--bg-inset);
}
.dy-month-pick summary h1 {
  display: inline;
}
.dy-month-pick summary h1::after {
  content: ' ▾';
  font-size: 0.875rem;
  color: var(--text-muted);
}
.dy-month-form {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 100%;
  z-index: 5;
  margin-top: 6px;
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg);
  box-shadow: 0 12px 32px rgb(0 0 0 / 0.2);
  white-space: nowrap;
}
.dy-month-form input {
  width: auto;
}
.cal-head {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  font-size: 0.75rem;
  color: var(--text-muted);
  text-align: center;
  margin-bottom: 4px;
}
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
}
.cal-cell {
  min-height: 84px;
  padding: 6px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-raised);
  text-decoration: none;
  color: var(--text);
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
}
.cal-cell.is-pad {
  border-color: transparent;
  background: transparent;
}
.cal-cell.is-today {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.cal-cell.has-work {
  background: var(--bg);
}
.cal-num {
  font-weight: 700;
  font-size: 0.8125rem;
}
.cal-sum {
  display: flex;
  flex-direction: column;
  font-size: 0.71875rem;
  line-height: 1.3;
}
@media (max-width: 640px) {
  .cal-cell {
    min-height: 58px;
    padding: 4px;
  }
  .cal-sum span:not(:first-child),
  .cal-sum .muted {
    display: none;
  }
}
.lane-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 999px;
  vertical-align: middle;
}
.dy-grid {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 6px;
  position: relative;
}
.dy-times {
  flex: 0 0 48px;
  font-size: 0.6875rem;
  color: var(--text-muted);
}
.dy-hour {
  border-top: 1px solid var(--border-soft);
  position: relative;
}
.dy-hour span {
  position: absolute;
  top: -8px;
  left: 0;
  background: var(--bg-raised);
  padding-right: 4px;
}
.dy-lane {
  flex: 1 1 200px;
  min-width: 180px;
  position: relative;
}
.dy-lane-head {
  height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  border-bottom: 3px solid var(--border);
  margin-bottom: 0;
  white-space: nowrap;
  overflow: hidden;
}
.dy-times .dy-lane-head {
  border-bottom-color: transparent;
}
.dy-lane-body {
  position: relative;
  background-image: repeating-linear-gradient(
    to bottom,
    var(--border-soft) 0,
    var(--border-soft) 1px,
    transparent 1px,
    transparent 72px
  );
}
.dy-lane.is-me .dy-lane-body {
  background-color: var(--accent-tint);
}
.dy-travel {
  position: absolute;
  left: 4px;
  right: 4px;
  background: repeating-linear-gradient(135deg, var(--bg-inset) 0 6px, var(--border-soft) 6px 12px);
  border-radius: 6px;
  font-size: 0.6875rem;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.dy-item {
  position: absolute;
  left: 4px;
  right: 4px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-left: 5px solid var(--accent);
  border-radius: 8px;
  padding: 4px 8px;
  font-size: 0.78125rem;
  overflow: hidden;
  z-index: 1;
}
.dy-item[open] {
  overflow: visible;
  z-index: 3;
  height: auto !important;
  min-height: 40px;
  box-shadow: 0 8px 24px rgb(11 22 38 / 0.18);
}
.dy-item.block {
  background: var(--bg-inset);
  border-left-style: dashed;
}
.dy-item.is-done {
  opacity: 0.7;
}
.dy-item summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}
.dy-item summary::-webkit-details-marker {
  display: none;
}
.dy-title {
  font-weight: 600;
}
.dy-menu {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border-soft);
}
.dy-menu form {
  margin: 0;
}
.dy-move {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.dy-move input,
.dy-move select {
  font-size: 0.75rem;
  padding: 4px 6px;
  min-height: 0;
}
.dy-move input[type='number'] {
  width: 70px;
}
.dy-nav-gap {
  flex: 1;
}
/* Book a job and Add a block: pop-ups opened from the buttons in the header */
.dy-dialog {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 0;
  width: min(560px, calc(100vw - 32px));
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 18px 48px rgb(0 0 0 / 0.28);
}
.dy-dialog::backdrop {
  background: rgb(11 22 38 / 0.55);
}
.dy-dialog-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}
.dy-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 18px 18px;
  background: var(--bg);
}
.dy-form .site-h3 {
  margin: 0 0 4px;
}
.dy-form-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.dy-form-row input[type='number'] {
  width: 84px;
}
.diary-line {
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.diary-line-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.diary-line-row + .diary-line-row {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border-soft);
}

/* ---------- Getting paid, three ways; mark as paid ---------- */
.pay-way {
  font-size: 0.9375rem;
  margin: 18px 0 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border-soft);
}
.pay-way-box {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 12px 14px;
}
.mark-paid {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
}
.mark-paid select {
  min-height: 0;
  padding: 6px 8px;
  font-size: 0.8125rem;
  max-width: 220px;
}

/* ---------- Scan to pay, at the door ---------- */
.qr-door {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px 16px;
  text-align: center;
  background: #fff;
  color: #12233c;
}
.qr-door-biz {
  font-weight: 700;
  font-size: 1.125rem;
  margin: 0;
}
.qr-door-code svg {
  width: min(78vw, 360px);
  height: auto;
  display: block;
}
.qr-door-amount {
  font-size: 2.5rem;
  font-weight: 800;
  margin: 6px 0 0;
}
.qr-door-what {
  margin: 0;
  color: #4d5e72;
}
.qr-door-hint {
  margin: 8px 0 0;
  font-size: 0.9375rem;
}
.qr-door-back {
  margin-top: 18px;
}

/* ---------- Stock ---------- */
.stock-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.stock-table th {
  text-align: left;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 4px 6px;
  border-bottom: 1px solid var(--border);
}
.stock-table td {
  padding: 6px;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
}
.stock-table .num {
  text-align: right;
  white-space: nowrap;
}
.stock-table tr.is-low td {
  background: var(--warn-bg);
}
.stock-count {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  margin: 0;
}
.stock-count input {
  width: 72px;
  min-height: 0;
  padding: 4px 6px;
}
@media (max-width: 480px) {
  .stock-count {
    display: inline-grid;
    grid-template-columns: auto auto;
    justify-items: end;
  }
  .stock-count .chip {
    grid-column: 1 / -1;
  }
}
.stock-find {
  display: flex;
  gap: 6px;
  align-items: center;
  margin: 0 0 10px;
}
.stock-find input[type='search'] {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 560px;
}
.stock-showing {
  margin: -4px 0 8px;
}
@media (max-width: 480px) {
  .stock-find {
    flex-wrap: wrap;
  }
  .stock-find input[type='search'] {
    flex-basis: 100%;
  }
}
@media (min-width: 700px) {
  .stock-list {
    table-layout: fixed;
  }
  .stock-list .st-cost {
    width: 110px;
  }
  .stock-list .st-price {
    width: 170px;
  }
  .stock-list .st-count {
    width: 230px;
  }
}
@media (min-width: 481px) {
  .stock-list .stock-count .chip {
    order: -1;
  }
}
@media (max-width: 699px) {
  .stock-list,
  .stock-list tbody {
    display: block;
  }
  .stock-list thead {
    display: none;
  }
  .stock-list tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 10px;
    align-items: center;
    padding: 8px 6px;
    border-bottom: 1px solid var(--border-soft);
  }
  .stock-list tbody td,
  .stock-list tbody td.num {
    display: block;
    padding: 0;
    border: 0;
    text-align: left;
    white-space: normal;
  }
  .stock-list .st-name {
    grid-column: 1 / -1;
    padding-bottom: 4px;
    overflow-wrap: anywhere;
  }
  .stock-list .st-cost {
    grid-column: 1;
    grid-row: 2;
  }
  .stock-list .st-price {
    grid-column: 1;
    grid-row: 3;
  }
  .stock-list tbody td.st-count {
    grid-column: 2;
    grid-row: 2 / span 2;
    text-align: right;
  }
  .stock-list td[data-label]::before {
    content: attr(data-label) ' ';
    font-size: 0.75rem;
    color: var(--text-muted);
  }
  .stock-list tr.is-low {
    background: var(--warn-bg);
  }
  .stock-list tr.is-low td {
    background: none;
  }
  .stock-list tbody tr:has(+ .stock-taken-row) {
    border-bottom: 0;
  }
  .stock-list tbody tr.stock-taken-row {
    display: block;
    padding-top: 0;
  }
  .stock-taken li {
    overflow-wrap: anywhere;
  }
}
.stock-reminders {
  margin-top: 26px;
}
.stock-levels {
  margin: 10px 0;
  max-width: 640px;
}
.stock-levels td:first-child {
  overflow-wrap: anywhere;
}
.stock-levels td:first-child span {
  display: block;
}
.stock-levels input {
  width: 84px;
  min-height: 0;
  padding: 4px 6px;
}
.stock-table tr:has(+ .stock-taken-row) td {
  border-bottom: 0;
}
.stock-taken-row td {
  padding-top: 2px;
}
.stock-taken summary {
  cursor: pointer;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.stock-taken summary b {
  color: var(--text);
  font-weight: 600;
}
.stock-taken ul,
.stock-taken-list {
  list-style: none;
  margin: 6px 0 4px;
  padding: 0 0 0 16px;
  font-size: 0.8125rem;
}
.stock-taken-list {
  padding-left: 0;
}
.stock-taken li,
.stock-taken-list li {
  padding: 3px 0;
}
.three-up {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
@media (max-width: 480px) {
  .three-up {
    grid-template-columns: 1fr;
  }
}
.margin-panel {
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
}
.margin-panel summary {
  cursor: pointer;
}
.sug-cat {
  display: inline-block;
  margin-left: 6px;
  font-size: 0.6875rem;
  color: var(--text-muted);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  padding: 0 6px;
}
.sug-stock {
  display: inline-block;
  margin-left: 6px;
  font-size: 0.6875rem;
  color: var(--ok);
}
.sug-stock.is-out {
  color: var(--danger);
}
@media (max-width: 480px) {
  .sug-desc {
    white-space: normal;
  }
}
.item-short {
  grid-column: 1 / -1;
  margin-top: -4px;
  font-size: 0.8125rem;
  color: var(--warn);
}

.cm-cis {
  margin: 12px 0;
  padding: 10px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.cm-cis summary {
  cursor: pointer;
}
.item-kind {
  font-size: 0.65625rem;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text-muted);
  cursor: pointer;
  margin-left: 4px;
}
.item-kind.is-labour {
  background: var(--accent-tint);
  border-color: var(--accent);
  color: var(--text);
}

.api-pre {
  background: var(--bg-inset);
  border-radius: var(--radius);
  padding: 10px 12px;
  font-size: 0.75rem;
  overflow-x: auto;
  white-space: pre;
  margin: 0 0 10px;
}

/* ---------- Tasks ---------- */
.task-new {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  margin: 0 0 12px;
}
.task-new-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.task-new-row > select,
.task-new-row > input,
.task-new-row .task-field {
  flex: 1 1 160px;
  min-width: 0;
}
/* a small title over each field, so the row reads without guessing */
.task-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 0;
  font-weight: 400;
}
.task-field > span {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
}
/* inside the titled field the box is a row of the column, never a flex share of its height */
.task-field select,
.task-field input {
  width: 100%;
  flex: 0 0 auto;
}
.task-new-row .task-add {
  align-self: flex-end;
  margin-bottom: 2px;
}
.proj-deadline {
  margin: -2px 0 10px;
  padding: 8px 12px;
  border-radius: var(--radius);
  background: var(--accent-tint);
  display: inline-block;
}
.proj-deadline.is-today {
  background: var(--warn-bg);
}
.proj-deadline.is-over {
  background: var(--danger-bg);
}
.task-start {
  margin: 6px 0 12px;
}
.task-start.is-asked {
  padding: 12px 14px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--accent-tint);
}
.task-started {
  margin: 4px 0 10px;
  color: var(--text-muted);
}
.task-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0;
}
.task-chips .chip.is-on {
  background: var(--accent-tint);
  color: var(--text);
}
.task-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.task-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 4px;
  border-bottom: 1px solid var(--border-soft);
}
.task-row.is-done .task-title {
  text-decoration: line-through;
  color: var(--text-muted);
}
.task-main {
  flex: 1;
  min-width: 0;
}
.task-title {
  font-weight: 600;
}
.task-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-top: 3px;
}
.task-who {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.task-tick {
  margin: 0;
}
.task-check {
  width: 24px;
  height: 24px;
  border-radius: 999px;
  border: 2px solid var(--border);
  background: var(--bg);
  color: var(--bg);
  cursor: pointer;
  padding: 0;
  line-height: 1;
}
.task-check.on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.task-timer {
  margin: 0;
}
.task-timer .is-running {
  border-color: var(--accent);
  background: var(--accent-tint);
}
.chip.pri-low {
  background: var(--bg-inset);
}
.chip.pri-medium {
  background: var(--accent-tint);
  color: var(--text);
}
.chip.pri-high {
  background: var(--warn-bg);
  color: var(--warn);
}
.chip.pri-critical {
  background: var(--danger-bg);
  color: var(--danger);
}
.task-row.due-overdue .task-due,
.task-card .due-overdue {
  color: var(--danger);
  font-weight: 600;
}
.task-row.due-soon .task-due,
.task-card .due-soon {
  color: var(--warn);
  font-weight: 600;
}
.task-push {
  margin-top: 16px;
}

/* ---------- HR, time off and pay ---------- */
.chip.chip-danger {
  background: var(--danger-bg);
  color: var(--danger);
}
.hr-now {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 14px;
}
.hr-now-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--border-soft);
  border-left-width: 5px;
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  text-decoration: none;
  color: var(--text);
}
.hr-now-card.pres-on-job {
  border-left-color: var(--accent);
}
.hr-now-card.pres-travelling {
  border-left-color: var(--warn);
}
.hr-now-card.pres-leave {
  border-left-color: var(--danger);
}
.hr-now-card.pres-free {
  border-left-color: var(--accent);
}
.hr-now-card.pres-off {
  border-left-color: var(--border);
  opacity: 0.8;
}
.pres-on-job .pres-chip,
.pres-free .pres-chip {
  background: var(--accent-tint);
  color: var(--text);
}
.pres-travelling .pres-chip {
  background: var(--warn-bg);
  color: var(--warn);
}
.pres-leave .pres-chip {
  background: var(--danger-bg);
  color: var(--danger);
}
.hr-decide {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.hr-decide input {
  flex: 1 1 140px;
  min-width: 0;
}
.hr-days {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 2px 0 8px;
}
.hr-day {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  font-size: 0.8125rem;
  cursor: pointer;
}
.hr-day:has(input:checked) {
  background: var(--accent-tint);
  border-color: var(--accent);
}
.pay-card {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  padding: 12px 14px;
  margin: 0 0 12px;
}
.pay-card.is-paid {
  border-color: var(--accent);
}
.pay-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}
.pay-gross {
  font-size: 1.25rem;
}
.pay-lines {
  margin: 8px 0;
}
.cal-off {
  color: var(--danger);
  font-weight: 600;
}

/* ---------- Nod: photo cards and charts ---------- */
.qn-card-file {
  display: block;
  margin: 6px 0;
  font-size: 0.8125rem;
}
.qn-chart {
  padding: 8px;
}
.qn-chart svg {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
}

/* ---------- Projects ---------- */
.proj-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}
.proj-card {
  display: block;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  text-decoration: none;
  color: var(--text);
}
.proj-card:hover {
  border-color: var(--accent);
}
.proj-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.proj-bar {
  height: 8px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
  margin: 8px 0 4px;
}
.proj-bar span {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
}
.chip.proj-live {
  background: var(--accent-tint);
  color: var(--text);
}
.chip.proj-snagging {
  background: var(--warn-bg);
  color: var(--warn);
}
.chip.proj-complete {
  background: var(--ok-bg);
  color: var(--ok);
}
.proj-snag {
  color: var(--warn);
  font-weight: 600;
}
.proj-over {
  color: var(--danger);
}
.proj-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: 20px;
}
@media (max-width: 900px) {
  .proj-cols {
    grid-template-columns: 1fr;
  }
}
.proj-board {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  margin-top: 10px;
}
@media (max-width: 1100px) {
  .proj-board {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 640px) {
  .proj-board {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.proj-col {
  background: var(--bg-inset);
  border-radius: var(--radius-lg);
  padding: 8px;
  min-height: 80px;
}
.proj-col h3 {
  font-size: 0.8125rem;
  margin: 0 0 6px;
}
.proj-col-snag h3 {
  color: var(--warn);
}
.proj-task {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--border);
  border-radius: 10px;
  padding: 8px;
  margin-bottom: 6px;
}
.proj-task.pri-high {
  border-left-color: var(--warn);
}
.proj-task.pri-critical {
  border-left-color: var(--danger);
}
.proj-task.pri-medium {
  border-left-color: var(--accent);
}
.proj-task-title {
  font-weight: 600;
  font-size: 0.8125rem;
}
.proj-task-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 3px 0;
}
.proj-task-move select {
  width: 100%;
  font-size: 0.75rem;
  padding: 3px 6px;
}
.proj-task-move {
  margin: 0;
}
.proj-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
  margin: 10px 0;
}
.proj-gallery figure {
  margin: 0;
}
.proj-gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 10px;
  display: block;
}
.proj-doc {
  display: block;
  padding: 20px 10px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  text-align: center;
  font-size: 0.8125rem;
}
.proj-history {
  list-style: none;
  padding: 0;
  margin: 0;
}
.proj-history li {
  padding: 5px 0;
  border-bottom: 1px solid var(--border-soft);
}
.proj-history li .small {
  margin-right: 8px;
}

/* ---------- Social and the portfolio ---------- */
.soc-status {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.soc-post {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 14px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  margin: 0 0 12px;
}
.soc-post.is-posted {
  border-color: var(--accent);
}
@media (max-width: 640px) {
  .soc-post {
    grid-template-columns: 1fr;
  }
}
.soc-photos {
  display: grid;
  gap: 8px;
}
.soc-thumb {
  margin: 0;
}
.soc-thumb img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 8px;
  display: block;
}
.soc-thumb figcaption {
  font-size: 0.6875rem;
  color: var(--text-muted);
  margin-top: 2px;
}
.soc-thumb.is-empty figcaption {
  padding: 24px 8px;
  border: 1px dashed var(--border);
  border-radius: 8px;
  text-align: center;
}
.soc-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.soc-head input {
  flex: 1 1 200px;
  font-weight: 600;
}
.soc-actions {
  margin-top: 8px;
}
.soc-review {
  font-style: italic;
  margin: 4px 0;
}
.soc-stars {
  color: var(--warn);
  letter-spacing: 0.06em;
}
.rev-stars {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  gap: 4px;
  margin: 4px 0 10px;
}
.rev-stars input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.rev-stars label {
  font-size: 2.125rem;
  color: var(--border);
  cursor: pointer;
}
.rev-stars input:checked ~ label,
.rev-stars label:hover,
.rev-stars label:hover ~ label {
  color: var(--warn);
}
.port-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 20px;
}
@media (max-width: 1000px) {
  .port-cols {
    grid-template-columns: 1fr;
  }
}
.port-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.port-frame {
  display: block;
  position: relative;
  width: 100%;
  aspect-ratio: 794 / 1123;
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--border-soft);
}
.port-mini {
  position: absolute;
  top: 0;
  left: 0;
  width: 794px;
  height: 1123px;
  transform-origin: 0 0;
  transform: scale(0.19);
}
.port-frame .sheet {
  font-family: Arial, sans-serif;
}
.port-preview {
  position: sticky;
  top: 12px;
  align-self: start;
}
#port-frame {
  display: block;
  width: 100%;
  aspect-ratio: 794 / 1123;
  border: 0;
  border-radius: var(--radius);
  background: #fff;
}

/* ---------- Diary: rows layout, and dragging ---------- */
.dy-hours {
  display: contents;
}
.dy-grid.dy-rows {
  --dy-span: 1200px;
  display: block;
  overflow-x: auto;
}
.dy-rows .dy-times {
  display: flex;
  flex: none;
  min-width: calc(140px + var(--dy-span));
}
.dy-rows .dy-times .dy-lane-head {
  flex: 0 0 140px;
  height: 28px;
}
.dy-rows .dy-hours {
  display: flex;
  height: 28px;
  width: var(--dy-span);
  border-bottom: 1px solid var(--border-soft);
}
.dy-rows .dy-hour {
  border-top: 0;
  border-left: 1px solid var(--border-soft);
  flex: none;
}
.dy-rows .dy-hour span {
  top: 6px;
  left: 4px;
  padding-right: 0;
}
.dy-rows .dy-lane {
  display: flex;
  min-width: calc(140px + var(--dy-span));
  border-bottom: 1px solid var(--border-soft);
}
.dy-rows .dy-lane-head {
  flex: 0 0 140px;
  height: 84px;
  border-bottom: 0;
  border-right: 3px solid var(--border);
  padding-right: 6px;
}
.dy-rows .dy-lane-body {
  position: relative;
  width: var(--dy-span);
  height: 84px;
  background-image: repeating-linear-gradient(
    to right,
    var(--border-soft) 0,
    var(--border-soft) 1px,
    transparent 1px,
    transparent 72px
  );
}
.dy-rows .dy-item {
  top: 6px;
  bottom: 6px;
  left: auto;
  right: auto;
  border-left-width: 5px;
}
.dy-rows .dy-item[open] {
  height: auto !important;
  bottom: auto;
  min-width: 260px;
}
.dy-rows .dy-travel {
  top: 10px;
  bottom: 10px;
  left: auto;
  right: auto;
}
.dy-grip {
  display: inline-block;
  cursor: grab;
  color: var(--text-muted);
  font-size: 0.75rem;
  letter-spacing: -2px;
  margin-right: 4px;
  touch-action: none;
  user-select: none;
}
.dy-item.is-dragging {
  opacity: 0.85;
  z-index: 5;
  box-shadow: 0 8px 24px rgb(11 22 38 / 0.25);
  pointer-events: none;
}
.dy-lane.is-target .dy-lane-body {
  outline: 2px dashed var(--accent);
  outline-offset: -2px;
}
.dy-days {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin: 0 0 8px;
}
.dy-days[hidden] {
  display: none;
}
.dy-day-drop {
  padding: 6px 10px;
  border: 1px dashed var(--border);
  border-radius: 999px;
  font-size: 0.78125rem;
}
.dy-day-drop.is-today {
  border-style: solid;
}
.dy-day-drop.is-target {
  background: var(--accent-tint);
  border-color: var(--accent);
}
.dy-flip {
  margin-left: auto;
}
/* connections: the plug-and-play page */
.cx-section {
  margin-top: 28px;
}
.cx-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  background: var(--bg);
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cx-card > b {
  font-size: 0.9375rem;
}
.cx-zap .btn-row {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 2px;
}
.cx-zap .btn-row form {
  margin: 0;
}
.cx-zap-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: baseline;
}
.cx-form .task-field {
  margin-top: 10px;
}
.cx-kinds {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}
.cx-kind {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 8px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
}
.cx-kind small {
  grid-column: 2;
  line-height: 1.35;
}
.cx-kind:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-tint);
}
.cx-events {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 12px 10px;
  margin: 12px 0 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
}
.cx-events legend {
  font-size: 0.8125rem;
  color: var(--text-muted);
  padding: 0 4px;
}
.cx-event {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  font-size: 0.875rem;
}
.cx-secret {
  width: 100%;
  text-align: left;
  border: 1px dashed var(--border);
  color: inherit;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  align-items: baseline;
}
.cx-secret.is-shown {
  border-style: solid;
  user-select: all;
}
.cx-secret-hint {
  font-family: inherit;
  font-size: 0.75rem;
  color: var(--accent);
  font-weight: 600;
}
.cx-connect .btn-row {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 10px;
}
.cx-app .cx-zap-head {
  justify-content: flex-start;
}
.cx-app .cx-zap-head .muted {
  margin-left: auto;
}
.cx-on {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-tint);
  border-radius: 999px;
  padding: 2px 8px;
}
.cx-paste {
  margin-top: 14px;
}
.cx-paste > summary {
  cursor: pointer;
  font-size: 0.875rem;
  color: var(--text-muted);
}
.cx-allow {
  max-width: 560px;
}
.cx-allow-list {
  margin: 0 0 12px;
  padding-left: 20px;
  line-height: 1.5;
}
.cx-allow .btn-row {
  flex-direction: row;
  gap: 10px;
  margin-top: 14px;
}
.cx-allow .btn-row form {
  margin: 0;
}
/* the email editor: green inserts instead of curly brackets, and the live preview beside it */
.email-edit {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}
.email-live {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.email-preview {
  width: 100%;
  height: 420px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: #fff;
}
.email-layouts {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 12px 10px;
  margin: 12px 0 0;
}
.email-layouts legend {
  font-size: 0.8125rem;
  color: var(--text-muted);
  padding: 0 4px;
}
.ins-wrap {
  position: relative;
  margin-bottom: 8px;
}
.ins-editor {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-inset);
  color: var(--text);
  font: inherit;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  outline: none;
}
.ins-wrap.is-single .ins-editor {
  min-height: 2.6em;
}
.ins-editor:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.ins {
  display: inline-block;
  padding: 0 7px;
  margin: 0 1px;
  border-radius: 6px;
  font-weight: 600;
  color: var(--link);
  background:
    linear-gradient(225deg, transparent 35%, rgb(255 255 255 / 0.55) 50%, transparent 65%) no-repeat,
    var(--accent-tint);
  background-size: 300% 300%;
  background-position: 100% 0;
  cursor: default;
  user-select: none;
  line-height: 1.35;
}
/* the sway: a light band sweeps from the top right to the bottom left, so the eye can follow where it went */
@keyframes ins-sway {
  0% {
    background-position: 100% 0;
  }
  100% {
    background-position: 0 100%;
  }
}
.ins.is-new {
  animation: ins-sway 0.9s ease-in-out 3;
}
/* a value the veil put back into Nod's answer: the same green word, the same sway, no bracket */
.qn-msg .ins-fill {
  padding: 0 5px;
  margin: 0;
  user-select: text;
  cursor: text;
}
.ins:hover,
.ins-opt.is-active .ins,
.ins-opt:hover .ins {
  animation: ins-sway 0.9s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ins.is-new,
  .ins:hover,
  .ins-opt.is-active .ins,
  .ins-opt:hover .ins {
    animation: none;
  }
}
.ins-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
  margin-top: 6px;
}
.ins-tools .small {
  flex: 1 1 220px;
  min-width: 0;
}
.ins-pop {
  position: absolute;
  z-index: 30;
  min-width: 220px;
  max-width: 280px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg);
  box-shadow: 0 12px 32px rgb(0 0 0 / 0.22);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ins-pop-hint {
  margin: 2px 6px 4px;
  font-size: 0.75rem;
  color: var(--text-muted);
}
.ins-opt {
  display: flex;
  align-items: center;
  text-align: left;
  padding: 5px 6px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.ins-opt.is-active,
.ins-opt:hover {
  background: var(--bg-inset);
}
/* a team member's quote waiting for confirmation */
.chip-wait {
  background: var(--warn-bg);
  color: var(--warn);
}
.approval-wait .approval-btns {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.approval-wait .approval-btns form {
  margin: 0;
}
.waiting-card {
  border-left: 4px solid var(--warn);
}

/* ---- replying to contact-form messages in the page ---- */
.sr-replied {
  margin-left: 6px;
  font-size: 0.75rem;
}
.sr-box {
  margin-top: 12px;
  padding: 14px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--surface-2, transparent);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sr-row {
  display: grid;
  grid-template-columns: 72px 1fr;
  align-items: center;
  gap: 8px;
}
.sr-row label {
  font-weight: 600;
  font-size: 0.875rem;
}
.sr-row input,
.sr-row select,
.sr-box textarea {
  width: 100%;
  min-width: 0;
}
.sr-row input[readonly] {
  opacity: 0.8;
}
.sr-sig {
  border-left: 2px solid var(--border-soft);
  padding: 2px 0 2px 10px;
  font-size: 0.875rem;
  overflow-wrap: anywhere;
}
.sr-sig:empty {
  display: none;
}
.sr-sig img {
  max-width: 100%;
  height: auto;
}
.sr-files-pick {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.sr-files-pick input[type='file'] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}
.sr-files-pick input[type='file']:focus-visible + span,
.sr-files-pick label:focus-within {
  outline: 2px solid var(--accent);
}
.sr-too-big {
  color: var(--danger, #c92a2a);
}
.sr-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.sr-actions .btn {
  width: auto;
  min-height: 44px;
  padding: 0 28px;
}
.sr-trail {
  margin-top: 10px;
  border-top: 1px solid var(--border-soft);
  padding-top: 8px;
}
.sr-trail > summary {
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 600;
  min-height: 32px;
  display: flex;
  align-items: center;
}
.sr-trail > summary::-webkit-details-marker {
  display: none;
}
.sr-trail > summary::before {
  content: '▸';
  width: 1.1em;
  color: var(--accent);
}
.sr-trail[open] > summary::before {
  content: '▾';
}
.sr-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sr-item {
  border-left: 3px solid var(--border);
  padding: 4px 0 4px 10px;
}
.sr-item.sr-us {
  border-left-color: var(--accent);
}
.sr-item-head {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 0.875rem;
}
.sr-item-body {
  white-space: pre-wrap;
  margin: 4px 0;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
@media (max-width: 520px) {
  .sr-row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

/* ---- reviews on the Social page: taken down for a reason, answered in public ---- */
.rev-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-start;
}
.rev-hide {
  display: flex;
  gap: 6px;
  align-items: center;
}
.rev-hide select {
  width: auto;
  max-width: 260px;
}
.rev-answer > summary {
  list-style: none;
  cursor: pointer;
}
.rev-answer > summary::-webkit-details-marker {
  display: none;
}
.rev-answer form {
  display: grid;
  gap: 6px;
  margin-top: 6px;
  min-width: 260px;
}
.rev-reply {
  display: block;
  margin-top: 4px;
  color: var(--text-muted);
}
@media (max-width: 640px) {
  .rev-list li {
    flex-direction: column;
    align-items: stretch;
  }
  .rev-list li > span:first-child {
    flex: none;
  }
  .rev-hide {
    flex: 1 1 100%;
    min-width: 0;
    flex-wrap: wrap;
  }
  .rev-hide select {
    flex: 1 1 160px;
    min-width: 0;
    max-width: 100%;
  }
}
.soc-photos-ok {
  margin: 0 0 8px;
}

/* ---- admin: takedowns ---- */
.td-form {
  padding: 18px 20px;
  margin: 16px 0 24px;
}
.td-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px 16px;
}
.td-grid label {
  display: grid;
  gap: 4px;
}
.td-what {
  border: 0;
  padding: 0;
  margin: 14px 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
}
.td-late {
  color: var(--danger, #c92a2a);
  font-weight: 700;
}

/* ---- admin: playbook and emails ---- */
.ops-doc {
  max-width: 820px;
}
.ops-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 8px 0 20px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.ops-toc a {
  font-size: 0.9rem;
}
.ops-notes {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}
.ops-mail {
  padding: 12px 16px;
  margin: 8px 0;
}
.ops-mail summary {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: baseline;
  cursor: pointer;
}
.ops-pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: inherit;
  font-size: 0.92rem;
  line-height: 1.5;
  margin: 8px 0 0;
  padding: 12px 14px;
  background: var(--bg-inset);
  border-radius: var(--radius);
}
.ops-preview {
  padding: 16px 20px;
  margin: 16px 0 24px;
  border-left: 3px solid var(--accent);
}

/* ---- social: top-ups ---- */
.soc-topup {
  padding: 12px 16px;
  margin: 12px 0;
}
.soc-topup summary {
  cursor: pointer;
}
.soc-topup.is-low {
  border-left: 3px solid var(--warn);
}
.soc-topup p {
  margin: 0 0 8px;
}
.soc-topup-pay {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 8px 0;
}

/* ---- admin: launch check ---- */
.lc-page {
  max-width: 900px;
}
.lc-verdict {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: baseline;
  padding: 12px 16px;
  border-radius: var(--radius);
  border-left: 4px solid var(--ok);
  background: var(--bg-raised);
}
.lc-verdict.is-fail {
  border-left-color: var(--danger);
}
.lc-list {
  list-style: none;
  padding: 0;
  margin: 0 0 20px;
  display: grid;
  gap: 8px;
}
.lc-row {
  padding: 10px 14px;
  border: 1px solid var(--border-soft);
  border-left-width: 4px;
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.lc-row.is-pass {
  border-left-color: var(--ok);
}
.lc-row.is-warn {
  border-left-color: var(--warn);
}
.lc-row.is-fail {
  border-left-color: var(--danger);
}
.lc-row p {
  margin: 4px 0 0;
}
.lc-head {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  align-items: center;
  justify-content: space-between;
}
.lc-found {
  white-space: pre-line;
}
.lc-actions li {
  margin: 0 0 10px;
}

/* ---- admin: launch posts offer ---- */
.soc-launch {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  margin: 0 0 16px;
  border-left: 3px solid var(--accent);
}
.soc-launch p {
  margin: 0;
  flex: 1 1 320px;
}

/* ---- admin: the plan and the best times ---- */
.soc-sum {
  margin: 0 0 14px;
  color: var(--text-muted);
  max-width: 78ch;
}
.soc-cadence {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
  margin: 0 0 14px;
}
.soc-cad {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--bg-raised);
}
.soc-approve {
  padding: 14px 16px;
  margin: 0 0 18px;
  border-left: 3px solid var(--accent);
}
.soc-approve p {
  margin: 0 0 10px;
}
.soc-approve p:last-child {
  margin-bottom: 0;
}
.soc-plat {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 22px 0 8px;
  font-size: 1.0625rem;
}
.soc-plan {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.soc-line {
  display: grid;
  grid-template-columns: 170px minmax(0, 1fr) 150px 150px;
  gap: 14px;
  align-items: start;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--bg-raised);
}
.soc-line-when {
  display: flex;
  flex-direction: column;
  font-size: 0.875rem;
  color: var(--text-muted);
}
.soc-line-when b {
  color: var(--text);
}
.soc-line-time {
  font-weight: 700;
  color: var(--accent-text);
}
.soc-line-what {
  min-width: 0;
}
.soc-line-what > b {
  display: block;
  margin-bottom: 2px;
}
.soc-line-what details {
  margin: 0;
}
.soc-line-what summary {
  cursor: pointer;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.soc-line-what .soc-caption {
  margin: 8px 0;
  max-height: none;
}
.soc-line-media {
  font-size: 0.8125rem;
}
.soc-media-film {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent-text);
  font-weight: 600;
  font-size: 0.75rem;
  line-height: 1.3;
}
.soc-media-pic {
  display: block;
  width: 36px;
  height: 45px;
  border-radius: 4px;
  object-fit: cover;
  border: 1px solid var(--border);
}
.soc-line-status {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
}
.soc-state.is-scheduled {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent-text);
}
.soc-state.is-waiting-for-film {
  background: color-mix(in srgb, var(--warn, #f5c945) 18%, transparent);
}
.soc-state.is-posted {
  background: var(--accent);
  color: var(--on-accent, #06231a);
}
.soc-poll-opts {
  margin: 4px 0 0;
  padding-left: 20px;
  font-size: 0.875rem;
}
.soc-times {
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  overflow: hidden;
}
.soc-times-head,
.soc-times-row {
  display: grid;
  grid-template-columns: 130px repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding: 9px 12px;
  align-items: baseline;
}
.soc-times.has-tiktok .soc-times-head,
.soc-times.has-tiktok .soc-times-row {
  grid-template-columns: 130px repeat(3, minmax(0, 1fr));
}
.soc-times-head {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  background: var(--bg-raised);
}
.soc-times-row + .soc-times-row {
  border-top: 1px solid var(--border-soft);
}
.soc-times-row span > span {
  display: block;
}
@media (max-width: 760px) {
  .soc-line {
    grid-template-columns: 1fr 1fr;
  }
  .soc-line-what {
    grid-column: 1 / -1;
  }
  .soc-times-head,
  .soc-times-row {
    grid-template-columns: 90px repeat(2, minmax(0, 1fr));
    font-size: 0.8125rem;
  }
  .soc-times.has-tiktok .soc-times-head,
  .soc-times.has-tiktok .soc-times-row {
    grid-template-columns: 90px repeat(3, minmax(0, 1fr));
  }
}

/* ---- the plan review pop-up ---- */
.pf-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgb(4 10 20 / 0.72);
  display: grid;
  place-items: center;
  padding: 16px;
}
.pf-modal {
  width: min(1240px, 100%);
  max-height: 94vh;
  overflow: auto;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 30px 80px rgb(0 0 0 / 0.5);
  display: flex;
  flex-direction: column;
}
.pf-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 14px;
  align-items: center;
  padding: 14px 18px;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-soft);
}
.pf-title {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.pf-title b {
  font-size: 1.125rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pf-filters {
  display: flex;
  gap: 4px;
  justify-content: center;
  flex-wrap: wrap;
}
.pf-filters a {
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-muted);
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid transparent;
}
.pf-filters a span {
  opacity: 0.7;
  font-weight: 500;
}
.pf-filters a.is-on {
  color: var(--text);
  border-color: var(--border);
  background: var(--bg-raised);
}
.pf-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
}
.pf-close {
  font-size: 1.625rem;
  line-height: 1;
  text-decoration: none;
  color: var(--text-muted);
  padding: 2px 8px;
}
.pf-schedule {
  background: #f5c945;
  color: #1a1400;
  border: none;
  border-radius: 10px;
  font: 700 0.9375rem var(--font, inherit);
  padding: 10px 18px;
  cursor: pointer;
  box-shadow: 0 6px 20px rgb(245 201 69 / 0.3);
}
.pf-schedule:hover {
  background: #ffd75a;
}
.pf-done {
  background: var(--accent);
  color: #06231a;
}
.pf-pages {
  display: flex;
  gap: 6px;
  justify-content: center;
  align-items: center;
  padding: 10px 18px;
  font-size: 0.875rem;
}
.pf-pages a,
.pf-pages span {
  padding: 4px 10px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--text-muted);
}
.pf-pages a:hover {
  background: var(--bg-raised);
}
.pf-pages .is-on {
  background: var(--accent);
  color: #06231a;
  font-weight: 700;
}
.pf-redo-note,
.pf-problems {
  margin: 12px 18px 0;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 0.875rem;
}
.pf-redo-note {
  border: 1px solid #f5c945;
  background: color-mix(in srgb, #f5c945 12%, transparent);
}
.pf-problems {
  border: 1px solid var(--danger);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
}
.pf-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 6px 18px;
}
.pf-post {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 18px;
  padding: 16px;
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--border);
  border-radius: 12px;
  background: var(--bg-raised);
}
.pf-post.is-saved {
  border-left-color: var(--accent);
}
.pf-post.is-redo {
  border-left-color: #f5c945;
}
.pf-post.is-edited {
  border-left-color: #7c9cff;
}
.pf-body {
  min-width: 0;
}
.pf-when {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  font-size: 0.875rem;
  margin-bottom: 6px;
}
.pf-post h3 {
  margin: 0 0 8px;
  font-size: 1.0625rem;
}
.pf-post .soc-caption {
  white-space: pre-wrap;
  max-height: 260px;
  overflow: auto;
}
.pf-tags {
  margin: 8px 0 0;
  color: var(--accent-text);
  font-size: 0.875rem;
}
.pf-chip-saved {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent-text);
}
.pf-chip-redo {
  background: color-mix(in srgb, #f5c945 22%, transparent);
  color: #f5c945;
}
.pf-chip-edited {
  background: color-mix(in srgb, #7c9cff 22%, transparent);
  color: #9db4ff;
}
.pf-suggest {
  margin: 12px 0 0;
  padding: 10px 14px;
  border: 1px dashed #f5c945;
  border-radius: 10px;
  font-size: 0.875rem;
}
.pf-suggest ol {
  margin: 6px 0;
  padding-left: 20px;
}
.pf-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}
.pf-media {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.pf-media img,
.pf-media video {
  width: 100%;
  max-height: 420px;
  object-fit: contain;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #0b1626;
}
.pf-nofile {
  width: 100%;
  min-height: 140px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 16px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  color: var(--text-muted);
}
.pf-review {
  margin: 0;
  padding: 14px 16px;
  border-left: 3px solid var(--accent);
  background: var(--bg);
  border-radius: 0 10px 10px 0;
  font-size: 1rem;
  line-height: 1.5;
}
.pf-review footer {
  margin-top: 8px;
  font-size: 0.875rem;
  color: var(--text-muted);
}
.pf-foot {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 12px;
  padding: 10px 18px 16px;
}
/* Save all / Redo all: every post on every page, one press */
.pf-alls {
  display: flex;
  align-items: center;
  gap: 8px;
}
.pf-alls form {
  margin: 0;
}
.soc-line-review {
  grid-template-columns: minmax(0, 1fr) 220px;
}
.soc-planfile {
  margin-top: 10px;
}
.dropzone-small {
  min-height: 84px;
  padding: 14px;
  flex-direction: column;
  gap: 4px;
}
.soc-lessons {
  margin: 4px 0 0;
  padding-left: 20px;
  font-size: 0.875rem;
  line-height: 1.6;
}
.soc-lessons-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
}
.soc-lessons-grid h3 {
  margin: 0 0 4px;
  font-size: 1rem;
}
.soc-note-form {
  margin-top: 8px;
}
.soc-extract {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  align-items: flex-end;
  padding: 12px 14px;
  margin: 0 0 16px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--bg-raised);
}
.soc-extract > div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.soc-extract input {
  width: 170px;
}
.soc-extract > span {
  flex: 1 1 320px;
}
/* ---- the viewer: a picture or film, larger, over the review ---- */
.pf-open {
  display: block;
  position: relative;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: zoom-in;
  text-align: left;
}
.pf-open img,
.pf-open video {
  width: 100%;
  max-height: 420px;
  object-fit: contain;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #0b1626;
  display: block;
}
.pf-err {
  flex-basis: 100%;
  margin: 6px 0 0;
  font-size: 0.84375rem;
  color: var(--danger);
}
.pf-film {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 150px;
  padding: 18px 12px 34px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: #0b1626;
  color: var(--accent-text);
  text-align: center;
}
.pf-film code {
  font-size: 0.78125rem;
  color: var(--text-muted);
  word-break: break-all;
}
/* the film's cover in its tile: what the platforms will show before play */
.pf-film.has-cover {
  padding: 10px 10px 34px;
}
.pf-cover {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 420px;
  border-radius: 8px;
  object-fit: contain;
}
.pv-cover {
  white-space: nowrap;
}
.pv-cover-note {
  margin: 0;
  padding: 0 14px 10px;
  font-size: 0.8125rem;
  color: var(--accent-text);
}
.pv-cover-note.is-bad {
  color: var(--danger);
}
.pf-open-hint {
  position: absolute;
  right: 10px;
  bottom: 10px;
  padding: 5px 10px;
  border-radius: 999px;
  background: rgb(4 10 20 / 0.72);
  color: #edf2f7;
  font-size: 0.75rem;
  font-weight: 700;
}
.pv-overlay {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgb(4 10 20 / 0.8);
}
.pv-window {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(1100px, 94vw);
  max-height: 94vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 30px 90px rgb(0 0 0 / 0.6);
  overflow: hidden;
}
.pv-window.is-moved {
  transform: none;
}
.pv-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-soft);
  cursor: move;
  user-select: none;
  touch-action: none;
}
.pv-head b {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pv-close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 1.625rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 6px;
}
.pv-stage {
  flex: 1;
  min-height: min(360px, 50vh);
  display: grid;
  place-items: center;
  background: #0b1626;
}
.pv-stage img,
.pv-stage video {
  max-width: 100%;
  max-height: calc(94vh - 130px);
  object-fit: contain;
  display: block;
}
.pv-stage video {
  cursor: pointer;
}
.pv-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-top: 1px solid var(--border-soft);
}
.pv-controls button {
  background: none;
  border: 1.5px solid var(--border);
  color: var(--text);
  border-radius: 999px;
  min-width: 44px;
  min-height: 40px;
  padding: 0 12px;
  font: 700 0.875rem var(--font, inherit);
  cursor: pointer;
}
.pv-controls #pv-play {
  min-width: 52px;
  font-size: 1rem;
}
.pv-bar {
  flex: 1;
  height: 10px;
  border-radius: 999px;
  background: var(--border);
  cursor: pointer;
  touch-action: none;
  position: relative;
}
.pv-bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
}
.pv-time {
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.pv-vol {
  display: flex;
  align-items: center;
}
.pv-controls .pv-mute {
  display: grid;
  place-items: center;
  padding: 0;
}
.pv-mute svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pv-mute .pv-mute-body {
  fill: currentColor;
}
.pv-mute .pv-mute-off,
.pv-mute.is-muted .pv-mute-on {
  display: none;
}
.pv-mute.is-muted .pv-mute-off {
  display: inline;
}
.pv-mute.is-muted {
  color: var(--text-muted);
}
.pv-level {
  width: 0;
  min-width: 0;
  height: 20px;
  margin: 0;
  padding: 0;
  opacity: 0;
  accent-color: var(--accent);
  cursor: pointer;
  transition:
    width 0.15s ease,
    margin 0.15s ease,
    opacity 0.15s ease;
}
.pv-vol:hover .pv-level,
.pv-vol.is-held .pv-level {
  width: 96px;
  margin-left: 8px;
  opacity: 1;
}
.pv-vol:has(:focus-visible) .pv-level {
  width: 96px;
  margin-left: 8px;
  opacity: 1;
}
@media (hover: none) {
  .pv-level {
    width: 96px;
    margin-left: 8px;
    opacity: 1;
  }
}
.pv-vol.no-level .pv-level {
  display: none;
}
.soc-alert {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  margin: 0 0 12px;
  border: 1px solid var(--danger);
  border-left-width: 4px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}
.soc-alert.is-missing {
  border-color: #f5c945;
  background: color-mix(in srgb, #f5c945 10%, transparent);
}
.soc-alert > b {
  font-size: 0.9375rem;
}
.soc-alloc {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.soc-alloc code {
  flex: 1 1 260px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.soc-alloc select {
  flex: 1 1 260px;
  min-width: 0;
}
.soc-shelf {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 12px;
}
.soc-shelf-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 6px 10px;
  border-radius: 8px;
  border-left: 3px solid var(--border);
  background: var(--bg-raised);
  font-size: 0.875rem;
}
.soc-shelf-row.is-kept {
  border-left-color: var(--accent);
}
.soc-shelf-row.is-missing {
  border-left-color: #f5c945;
}
.soc-shelf-row code {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.soc-shelf-name {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.soc-shelf-name code {
  display: block;
}
.soc-shelf-acts {
  flex-wrap: wrap;
  justify-content: flex-end;
}
/* the cover, small, 9:16 — the shape the platforms show it in */
.soc-cover {
  display: block;
  width: 54px;
  height: 96px;
  border-radius: 6px;
  overflow: hidden;
  background: #0b1626;
  border: 1px solid var(--border);
}
.soc-cover.is-none {
  background: repeating-linear-gradient(45deg, #0b1626 0 6px, #15243a 6px 12px);
}
.soc-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.soc-cover-pick {
  cursor: pointer;
}
.soc-cover-pick.is-busy {
  opacity: 0.5;
  pointer-events: none;
}
@media (max-width: 640px) {
  .soc-shelf-row {
    grid-template-columns: auto minmax(0, 1fr);
  }
  .soc-shelf-acts {
    grid-column: 1 / -1;
    justify-content: flex-start;
  }
}
.soc-films {
  margin: 10px 0 0;
  padding-left: 18px;
  font-size: 0.875rem;
}
.soc-films .is-ok {
  color: var(--accent-text);
}
.soc-films .is-bad {
  color: var(--danger);
}
.soc-films .soc-retry {
  margin-left: 6px;
  vertical-align: middle;
}
@media (max-width: 860px) {
  .pf-head {
    grid-template-columns: 1fr;
  }
  .pf-actions {
    justify-content: space-between;
  }
  .pf-post {
    grid-template-columns: 1fr;
  }
  .soc-line-review {
    grid-template-columns: 1fr;
  }
}

/* ---- admin: money checks ---- */
.mc-warn {
  padding: 10px 14px;
  border-left: 4px solid var(--danger);
  background: var(--bg-raised);
  border-radius: var(--radius);
}
.mc-flag {
  padding: 14px 16px;
  margin: 10px 0;
  border-left: 3px solid var(--warn);
}
.mc-flag p {
  margin: 4px 0;
}
.mc-head {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: baseline;
  justify-content: space-between;
}
.mc-note {
  display: grid;
  gap: 4px;
  margin: 10px 0;
}

/* ---- legal details: the Account section, the set-up step ---- */
.lg-kinds {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 16px 14px;
  margin: 8px 0 4px;
  min-width: 0;
}
.lg-kinds legend {
  font-size: 0.875rem;
  font-weight: 700;
  padding: 0 6px;
}
.lg-kind {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 8px;
  margin: 2px 0;
  border-radius: var(--radius);
  cursor: pointer;
  font-weight: 400;
  font-size: 0.9375rem;
}
.lg-kind:has(input:checked) {
  background: var(--accent-tint);
}
.lg-kind input {
  width: 22px;
  height: 22px;
  margin-top: 2px;
  flex: none;
}
/* On a wide screen the Account page holds its fields to a readable width;
   every box in this section keeps to the same one, so their edges agree. */
@media (min-width: 1000px) {
  .wrap-account #legal > p,
  .wrap-account #legal .lg-form,
  .wrap-account #legal .lg-cert {
    max-width: 560px;
  }
}
.lg-h {
  font-size: 1rem;
  margin: 26px 0 6px;
}
.lg-problem {
  color: var(--danger);
  margin: 4px 0 0;
}
.lg-gaps {
  margin: 0 0 10px;
}
.lg-vat {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: baseline;
  margin: 20px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  font-size: 0.875rem;
}
.lg-vat > p {
  flex: 1 0 100%;
}
.lg-body,
.lg-cert {
  margin: 10px 0 0;
  padding: 10px 12px 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.lg-body .two-up label {
  margin-top: 8px;
}
.lg-body-name {
  display: block;
  font-size: 0.9375rem;
}
.lg-suggest-intro {
  margin: 16px 0 0;
}
.lg-ticks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin-top: 10px;
}
.lg-tick {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 400;
  font-size: 0.875rem;
}
.lg-tick input {
  width: 20px;
  height: 20px;
  flex: none;
}
.lg-add {
  margin: 14px 0 0;
}
.lg-add > summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.875rem;
}
.lg-cert-file {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
  margin-top: 8px;
}
.lg-cert-file label {
  margin: 0;
  flex: 1 0 100%;
}
.lg-cert-file input[type='file'] {
  flex: 1 1 200px;
  min-width: 0;
  max-width: 100%;
  font-size: 0.8125rem;
}
.lg-cert-file a {
  overflow-wrap: anywhere;
}

/* ---- a customer that is a business: the tick and the fields it opens ---- */
.biz-tick {
  margin: 16px 0 4px;
}
.biz-fields > label:first-child {
  margin-top: 10px;
}
.cm-business-form {
  max-width: 560px;
}
/* On a wide screen a single field is held to a readable width and a pair
   side by side is not; here the pair sits under single fields of the same
   block, so the block keeps to that width and every edge in it agrees. */
@media (min-width: 1000px) {
  .shell-main .wrap .biz-fields {
    max-width: 560px;
  }
}

/* ---- a trader's legal details at the foot of a page their customer opens ---- */
.trader-legal {
  margin-top: 28px;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--text-muted);
}
.trader-legal b {
  display: block;
  margin-bottom: 2px;
  color: var(--text);
}
.trader-legal span {
  display: block;
  overflow-wrap: anywhere;
}
.trader-legal + footer.legal {
  margin-top: 14px;
}

/* A row in a list holds a name on the left and a figure on the right, and a
   name too long for its half is cut short with dots. When the row is narrow
   for the size its words are set in (larger text on a phone), the name takes
   the whole row and wraps, and the figure goes underneath, so nothing is cut.
   The cards on Help and Announcements borrow the quote card's look but are
   laid out their own way, and are left as they were. */
.quote-card:not(.rail-card, .an-card),
.ag-row,
.ag-bill,
.cm-row,
.act-row {
  container-type: inline-size;
}
.quote-card:not(.rail-card, .an-card) {
  flex-wrap: wrap;
}
.quote-card:not(.rail-card, .an-card) .who {
  flex: 1 1 7em;
}
@container (max-width: 17.5em) {
  .quote-card:not(.rail-card, .an-card) .who,
  .ag-row-main {
    flex-basis: 100%;
  }
  .quote-card:not(.rail-card, .an-card) .amt {
    flex: 0 1 auto;
    min-width: 0;
  }
  .act-body {
    flex-basis: calc(100% - 42px);
  }
  .act-when {
    flex: 1 1 100%;
    flex-direction: row;
    justify-content: flex-start;
    gap: 0 8px;
    padding-left: 42px;
    text-align: left;
    order: 1;
  }
  .quote-card:not(.rail-card, .an-card) .who b,
  .ag-row-main b,
  .ag-row-main span,
  .cm-who b,
  .cm-who span {
    white-space: normal;
    overflow: visible;
    overflow-wrap: anywhere;
  }
}

/* A button is as tall as it is drawn until its words need more: then it
   grows, with room above and below them, and words on two lines are centred. */
.btn,
.btn-big,
.btn-quiet {
  padding-block: 0.3em;
  text-align: center;
}
.btn-compact {
  padding-block: 0.25em;
  text-align: center;
}

/* ---- the "on my way" prompt ----
   A small pop-up over whatever page a person opens on leaving a finished
   job. Two buttons: Send takes the room, Not now sits beside it at its own
   width; on a phone they stack, each the full width. */
.omw-pop {
  width: min(440px, calc(100vw - 32px));
}
.omw-pop-actions {
  display: flex;
  align-items: stretch;
  gap: 10px;
  margin-top: 16px;
}
.omw-pop-actions form {
  margin: 0;
}
.omw-pop-actions form:first-child {
  flex: 1 1 auto;
}
.omw-pop-actions .btn,
.omw-pop-actions .btn-compact {
  box-sizing: border-box;
  min-height: 54px;
  height: 100%;
}
@media (max-width: 599px) {
  .omw-pop-actions {
    flex-direction: column;
  }
  .omw-pop-actions .btn-compact {
    width: 100%;
  }
}

/* ---- who the contract is between ----
   The parties and the price, read before signing. Two columns on a desktop,
   one under the other on a phone; the price full width beneath. */
.contract-parties {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  margin-top: 16px;
}
.contract-parties h4 {
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 4px;
}
.contract-parties p {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.45;
}
.contract-parties .cp-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px 24px;
  margin-bottom: 12px;
}
@media (min-width: 600px) {
  .contract-parties .cp-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* The preview with the post beside it: the picture or film on the left, its
   words and buttons, and a note to yourself, on the right; one above the
   other on a narrow screen. Green arrows either side of the picture step to
   the next post and the one before. */
.pv-window.has-side {
  width: min(1400px, 96vw);
}
.pv-main {
  display: flex;
  flex: 1;
  min-height: 0;
}
.pv-left {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.pv-stage {
  position: relative;
}
.pv-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 0;
  background: var(--accent);
  color: #06231a;
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.45);
}
.pv-arrow[hidden] {
  display: none;
}
.pv-arrow.is-prev {
  left: 12px;
}
.pv-arrow.is-next {
  right: 12px;
}
.pv-arrow svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pv-arrow:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}
.pv-side {
  width: 360px;
  flex: none;
  border-left: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--bg);
}
.pv-side[hidden] {
  display: none;
}
.pv-tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
}
.pv-tabs button {
  flex: 1;
  padding: 10px;
  background: none;
  border: 0;
  border-bottom: 3px solid transparent;
  color: var(--text-muted);
  font-weight: 700;
  cursor: pointer;
}
.pv-tabs button[aria-selected='true'] {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.pv-pane {
  padding: 14px 16px;
  overflow: auto;
  flex: 1;
}
.pv-title {
  margin: 0 0 4px;
  font-size: 1.05rem;
}
.pv-when {
  margin: 0 0 10px;
}
.pv-caption {
  margin: 0 0 10px;
  white-space: pre-wrap;
  font: inherit;
  font-size: 0.875rem;
}
.pv-tags {
  margin: 0 0 14px;
  color: var(--accent-strong);
  font-size: 0.875rem;
}
.pv-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.pv-pane label {
  display: block;
  margin-bottom: 6px;
  font-size: 0.875rem;
}
.pv-pane textarea {
  width: 100%;
  box-sizing: border-box;
}
.pv-note-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  flex-wrap: wrap;
}
@media (max-width: 760px) {
  .pv-overlay {
    z-index: 130;
  }
  .pv-window,
  .pv-window.has-side,
  .pv-window.is-moved {
    left: 0 !important;
    top: 0 !important;
    transform: none;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    max-height: none;
    border: 0;
    border-radius: 0;
  }
  .pv-head {
    cursor: default;
    touch-action: auto;
    padding: calc(10px + env(safe-area-inset-top, 0px)) 8px 10px 14px;
  }
  .pv-hint {
    display: none;
  }
  .pv-close {
    min-width: 44px;
    min-height: 44px;
    font-size: 2rem;
  }
  .pv-main {
    flex-direction: column;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  .pv-left {
    flex: none;
  }
  .pv-stage {
    flex: none;
    min-height: 0;
  }
  .pv-stage img,
  .pv-stage video {
    max-height: 56vh;
    max-height: 56dvh;
  }
  .pv-controls {
    flex-wrap: wrap;
  }
  .pv-side {
    width: auto;
    flex: none;
    border-left: 0;
    border-top: 1px solid var(--border);
  }
  .pv-pane {
    overflow: visible;
    flex: none;
    padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  }
  .pv-acts .btn-compact,
  .pv-note-row .btn-compact {
    min-height: 44px;
  }
}
.mo-note {
  margin-top: 8px;
  padding: 8px 10px;
  border-left: 3px solid var(--accent);
  background: var(--bg-inset, rgb(255 255 255 / 0.04));
  border-radius: 6px;
}
.mo-note-when {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted);
}
.mo-note-body {
  margin: 2px 0 0;
  white-space: pre-wrap;
  font-size: 0.875rem;
}

/* a long month or plan stays light: rows off the screen are not drawn, and are drawn again just before they scroll in */
.mo-post,
.pf-post {
  content-visibility: auto;
  contain-intrinsic-size: auto 340px;
  overflow-clip-margin: 8px;
}
@media (max-width: 760px) {
  .pf-overlay {
    z-index: 130;
    padding: 0;
  }
  .pf-modal {
    width: 100%;
    height: 100vh;
    height: 100dvh;
    max-height: none;
    border: 0;
    border-radius: 0;
    overscroll-behavior: contain;
  }
  .pf-head {
    padding-top: calc(14px + env(safe-area-inset-top, 0px));
  }
  .pf-foot {
    padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
  .pf-close {
    min-width: 44px;
    min-height: 44px;
    display: inline-grid;
    place-items: center;
  }
}

/* ---------- the whole page, on a tablet and up ----------
   Jay, 14 October: pages sat in a column down the middle of a wide screen
   with blank space either side. On a tablet and anything wider, a working
   page now takes the full width beside the rail (or under the top bar) and
   starts at its left edge. Sign-in boxes and the long documents to read keep
   their column; fields keep a size a field should be (see .shell-main .wrap
   input above), so a form reads down the left and the space beside it is
   there for what the page puts there, such as the catalogue on a quote. */
@media (min-width: 768px) {
  .shell-main
    main.page-main
    > .wrap:not(.wrap-narrow):not(.wrap-read):not(.narrow):not(.pin-wrap):not(.wrap-fit):not(
      .wrap-account
    ):not(.wrap-settings) {
    max-width: none;
    margin-left: 0;
    margin-right: 0;
    padding-left: clamp(20px, 2.6vw, 48px);
    padding-right: clamp(20px, 2.6vw, 48px);
  }
  /* A page with only a little on it (one part, one quote, a message, a short
     form) sits in a column in the middle, as before: stretched across a wide
     screen it reads as a strip down the left with nothing beside it. */
  .shell-main main.page-main > .wrap.wrap-fit {
    max-width: 1120px;
    margin-left: auto;
    margin-right: auto;
    padding-left: clamp(20px, 2.6vw, 48px);
    padding-right: clamp(20px, 2.6vw, 48px);
  }
}
/* The diary's month fills the screen it is on: six weeks of days share the
   height under the heading, and the day's figures read at a size a desk
   screen can carry. */
@media (min-width: 768px) {
  .diary .cal-head {
    font-size: 0.875rem;
  }
  .diary .cal-grid {
    gap: 6px;
  }
  .diary .cal-cell {
    min-height: max(96px, calc((100vh - 250px) / 6));
    min-height: max(96px, calc((100dvh - 250px) / 6));
    padding: 10px 12px;
  }
  .diary .cal-num {
    font-size: 1rem;
  }
  .diary .cal-sum {
    font-size: 0.875rem;
    gap: 2px;
  }
}
/* Quotes: one New quote and one New enquiry, at the top on every screen. The
   bar at the foot is only a phone's stand-in, shown once the top pair has
   scrolled away (nav-drawer.js sets .is-shown), never alongside it. */
.q-new {
  display: flex;
  gap: 8px;
  flex: 0 0 auto;
}
.q-new .btn {
  width: auto;
  min-width: 0;
  white-space: nowrap;
  padding-inline: 18px;
  margin: 0;
}
.actionbar.q-foot {
  display: none;
}
@media (max-width: 999px) {
  .actionbar.q-foot.is-shown {
    display: flex;
  }
}
@media (max-width: 599px) {
  .q-head {
    flex-wrap: wrap;
  }
  .q-search {
    flex: 1 1 100%;
  }
  .q-new {
    flex: 1 1 100%;
  }
  .q-new .btn:first-child {
    flex: 1;
  }
}

/* ---------- the Catalogue ----------
   A merchant's whole trade list, kept quick: rows off the screen are not laid
   out (content-visibility), the rest of a list is fetched as it is scrolled
   towards, and the layout spreads to the full width on a desk and folds to a
   single column on a phone. */
.cat-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px 24px;
  margin-bottom: 14px;
}
.cat-head h1 {
  margin-bottom: 4px;
}
.cat-sub {
  margin: 0;
  max-width: 70ch;
}
.cat-head-name {
  display: flex;
  align-items: center;
  gap: 14px;
}
.cat-head-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}
.cat-crumb {
  margin: 0 0 8px;
  font-size: 0.875rem;
  color: var(--text-muted);
}
.cat-h2 {
  margin-top: 8px;
}
.cat-badge {
  --hue: 150;
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: #fff;
  background: linear-gradient(135deg, hsl(var(--hue) 55% 42%), hsl(calc(var(--hue) + 30) 60% 30%));
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.12);
}
.cat-badge-own {
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  color: var(--on-accent);
  font-size: 1.25rem;
}
.cat-search {
  margin: 0 0 14px;
}
.cat-search input[type='search'] {
  width: 100%;
}
.shell-main .wrap .cat-search input[type='search'] {
  max-width: 720px;
}
.cat-suppliers {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 12px;
}
.cat-supplier {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
  transition:
    border-color 0.15s,
    transform 0.15s;
}
.cat-supplier:hover,
.cat-supplier:focus-visible {
  border-color: var(--accent);
  transform: translateY(-1px);
}
.cat-s-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.cat-go {
  font-size: 1.5rem;
  color: var(--text-faint);
}
.cat-low {
  color: var(--warn);
  font-weight: 600;
}
.cat-update {
  position: relative;
}
.cat-update > summary {
  list-style: none;
  cursor: pointer;
}
.cat-update > summary::-webkit-details-marker {
  display: none;
}
.cat-update-body {
  margin-top: 10px;
  padding: 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-sizing: border-box;
  width: 100%;
  max-width: 760px;
}
.cat-update[open] {
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.cat-head-acts:has(.cat-update[open]) {
  flex: 1 1 100%;
}
.cat-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 22px 14px;
  border: 2px dashed var(--border);
  border-radius: var(--radius-lg);
  text-align: center;
  cursor: pointer;
  position: relative;
}
.cat-drop input[type='file'] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.cat-drop.is-over,
.cat-drop.has-file {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.cat-markup-form {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
}
.cat-mk-row {
  display: flex;
  align-items: center;
  gap: 6px;
}
.shell-main .wrap .cat-mk-row input,
.cat-mk-row input {
  width: 90px;
  max-width: 90px;
}
.cat-body {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}
@media (min-width: 900px) {
  .cat-body {
    grid-template-columns: 260px minmax(0, 1fr);
    align-items: start;
  }
  .cat-cats {
    position: sticky;
    top: 16px;
    max-height: calc(100vh - 32px);
    overflow: auto;
  }
}
.cat-cats {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
@media (max-width: 899px) {
  /* on a phone the categories are a strip to swipe along, not a column to scroll past */
  .cat-cats {
    flex-direction: row;
    overflow-x: auto;
    padding: 6px;
    scrollbar-width: none;
  }
  .cat-cats > a,
  .cat-cat summary a {
    white-space: nowrap;
  }
  .cat-cat .cat-subcat {
    display: none;
  }
}
.cat-cats a {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  color: var(--text);
  text-decoration: none;
  font-size: 0.9375rem;
}
.cat-cats a span {
  color: var(--text-faint);
  font-size: 0.8125rem;
}
.cat-cats a:hover {
  background: var(--bg-inset);
}
.cat-cats a.is-on {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-text);
  font-weight: 700;
}
.cat-cat > summary {
  list-style: none;
}
.cat-cat > summary::-webkit-details-marker {
  display: none;
}
.cat-subcat {
  margin-left: 14px;
  font-size: 0.875rem !important;
}
.cat-count {
  margin: -6px 0 8px;
}
.cat-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cat-row {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
  content-visibility: auto;
  contain-intrinsic-size: auto 78px;
}
.cat-row:hover,
.cat-row:focus-visible {
  border-color: var(--accent);
}
.cat-pic {
  width: 56px;
  height: 56px;
  border-radius: 10px;
  object-fit: contain;
  background: #fff;
}
.cat-pic-none {
  display: grid;
  place-items: center;
  background: var(--bg-inset);
  color: var(--text-faint);
  font-weight: 800;
  font-size: 1.25rem;
}
.cat-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.cat-desc {
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.cat-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.cat-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text);
}
.cat-stock {
  color: var(--ok);
  font-weight: 600;
}
.cat-stock.is-low {
  color: var(--warn);
}
.cat-prices {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  white-space: nowrap;
}
.cat-sell {
  font-weight: 800;
  font-size: 1.0625rem;
}
.cat-trade {
  font-size: 0.75rem;
  color: var(--text-faint);
}
@media (max-width: 520px) {
  .cat-row {
    grid-template-columns: 44px minmax(0, 1fr);
    gap: 10px;
    padding: 10px;
  }
  .cat-pic {
    width: 44px;
    height: 44px;
  }
  .cat-prices {
    grid-column: 2;
    flex-direction: row;
    align-items: baseline;
    gap: 8px;
  }
}
.cat-sentinel {
  height: 1px;
}
.cat-part {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
  margin: 8px 0 20px;
}
@media (min-width: 700px) {
  .cat-part {
    grid-template-columns: 220px minmax(0, 1fr);
  }
}
.cat-part-pic .cat-pic {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  max-width: 220px;
  font-size: 3rem;
  border-radius: var(--radius-lg);
}
.cat-figures {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
  margin: 14px 0 0;
}
.cat-figures > div {
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.cat-figures dt {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.cat-figures dd {
  margin: 2px 0 0;
  font-weight: 800;
  font-size: 1.25rem;
}
.cat-figures dd small {
  font-weight: 500;
  font-size: 0.75rem;
  color: var(--text-faint);
}
.cat-part-form {
  max-width: 820px;
}
.cat-sample {
  overflow-x: auto;
  margin: 12px 0 18px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.cat-sample table {
  font-size: 0.8125rem;
  white-space: nowrap;
}
.cat-map-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
  gap: 6px 16px;
  margin-bottom: 14px;
}
.cat-remove {
  margin-top: 28px;
}

/* ---------- the catalogue beside a quote (desk only) ---------- */
.q-cat {
  display: none;
}
@media (min-width: 1200px) {
  .q-edit.has-cat {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(380px, 30vw);
    gap: 28px;
    align-items: start;
  }
  .q-edit.has-cat .q-edit-main {
    min-width: 0;
  }
  .q-cat {
    position: sticky;
    top: 16px;
    display: flex;
    flex-direction: column;
    height: calc(100vh - 32px);
    height: calc(100dvh - 32px);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-lg);
    background: var(--bg-raised);
    overflow: hidden;
  }
}
.q-cat-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 14px 16px 6px;
  font-size: 1.0625rem;
}
.q-cat-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 6px 16px 10px;
}
.shell-main .wrap .q-cat-controls select,
.shell-main .wrap .q-cat-controls input {
  max-width: none;
  width: 100%;
}
.q-cat-chips {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: 2px;
}
.q-chip {
  flex: none;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  border-radius: 999px;
  padding: 4px 12px;
  font: 600 0.8125rem var(--font);
  cursor: pointer;
}
.q-chip.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.q-cat-markup {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 16px 10px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--bg-inset);
}
.q-cat-markup .check-row {
  margin: 0;
}
.q-cat-mk-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.q-cat-mk-row label {
  font-weight: 700;
  margin: 0;
}
.q-cat-mk-row input[type='range'] {
  flex: 1;
  accent-color: var(--accent);
}
.q-cat-mk-num {
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 700;
}
.shell-main .wrap .q-cat-mk-num input,
.q-cat-mk-num input {
  width: 76px;
  max-width: 76px;
  padding: 6px 8px;
}
.q-cat.mk-own .q-cat-mk-row {
  opacity: 0.7;
}
.q-cat-list {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 4px 10px 10px;
  border-top: 1px solid var(--border-soft);
}
.q-cat-row {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto 28px;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin-top: 6px;
  padding: 8px 10px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  text-align: left;
  font: inherit;
  cursor: pointer;
  content-visibility: auto;
  contain-intrinsic-size: auto 60px;
  transition:
    border-color 0.15s,
    background-color 0.3s;
}
.q-cat-row:hover,
.q-cat-row:focus-visible {
  border-color: var(--accent);
}
.q-cat-row.is-added {
  background: color-mix(in srgb, var(--accent) 22%, var(--bg));
}
.q-cat-pic {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  object-fit: contain;
  background: #fff;
}
.q-cat-pic.is-none {
  display: grid;
  place-items: center;
  background: var(--bg-inset);
  color: var(--text-faint);
  font-weight: 800;
}
.q-cat-txt {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.q-cat-txt b {
  font-size: 0.875rem;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.q-cat-txt small,
.q-cat-price small {
  font-size: 0.75rem;
  color: var(--text-muted);
}
.q-cat-price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  white-space: nowrap;
}
.q-cat-price small {
  color: var(--ok);
}
.q-cat-add {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 800;
}
.q-cat-empty {
  padding: 14px 6px;
}
.q-cat-sentinel {
  height: 1px;
}
.q-cat-foot {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0 10px;
  padding: 12px 16px;
  border-top: 1px solid var(--border-soft);
  background: var(--bg);
}
.q-cat-foot b {
  font-size: 1.125rem;
  color: var(--ok);
}
.q-cat-foot small {
  grid-column: 1 / -1;
}
.q-profit span:last-child {
  color: var(--ok);
  font-weight: 700;
}
.item-row.just-added {
  animation: qn-added 0.9s ease-out;
}
@keyframes qn-added {
  from {
    background: color-mix(in srgb, var(--accent) 30%, transparent);
  }
  to {
    background: transparent;
  }
}
.sug-merchant {
  color: var(--accent-text);
}
/* The Stock page opens on the figures: products, what is counted, what is running low and the catalogue. */
.stock-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin: 4px 0 16px;
}
.stock-summary a {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
}
.stock-summary a:hover {
  border-color: var(--accent);
}
.stock-summary b {
  font-size: 1.5rem;
  font-weight: 800;
}
.stock-summary span {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.stock-summary a.is-warn b {
  color: var(--warn);
}
/* The film's bar in the preview: a finger-wide grip around a thin bar, and a knob to show where it is held. */
.pv-bar::before {
  content: '';
  position: absolute;
  inset: -16px -6px;
}
.pv-bar i {
  position: relative;
  will-change: width;
}
.pv-bar i::after {
  content: '';
  position: absolute;
  right: -8px;
  top: 50%;
  width: 16px;
  height: 16px;
  margin-top: -8px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.4);
  transform: scale(0.75);
  transition: transform 0.12s;
}
.pv-bar:hover i::after,
.pv-bar.is-held i::after {
  transform: scale(1);
}
@media (max-width: 760px) {
  .pv-bar {
    height: 8px;
  }
  .pv-bar i::after {
    transform: scale(1);
  }
}

/* ---- between pages, signed in: the frame stays, the page moves ----
   Jay, 14 October: on a phone, going from page to page felt jumpy. The whole
   screen faded out and in, the top bar and the tab bar with it, so every tap
   blinked the parts that never change. Now the rail, the bars and the tabs
   stay put and only the page itself goes: it dims as the next one is fetched
   and the new one rises into place. Opacity and a small transform only, on
   the compositor, so a long page costs no more than a short one. */
html body > .shell,
html body > .qn-tabs,
html body > nav {
  animation: none;
}
html.is-leaving body > .shell,
html.is-leaving body > .qn-tabs,
html.is-leaving body > nav {
  opacity: 1;
  transition: none;
}
.shell .page-main > * {
  animation: qnContentIn 0.22s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
html.is-leaving .shell .page-main > * {
  opacity: 0.3;
  transform: translateY(-3px);
  transition:
    opacity 0.12s ease-in,
    transform 0.12s ease-in;
}
@keyframes qnContentIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
/* No grey flash on a tap, and a pressed link answers at once. */
html {
  -webkit-tap-highlight-color: transparent;
}
@media (prefers-reduced-motion: reduce) {
  .shell .page-main > * {
    animation: none;
  }
  html.is-leaving .shell .page-main > * {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
@media (max-width: 599px) {
  .stock-summary {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
    margin: 0 0 10px;
  }
  .stock-summary a {
    padding: 8px 8px;
    border-radius: var(--radius);
  }
  .stock-summary b {
    font-size: 1.125rem;
  }
  .stock-summary span {
    font-size: 0.6875rem;
    line-height: 1.2;
  }
}

/* ---------- the Stock summary ---------- */
.sk-figs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
  gap: 10px;
  margin: 0 0 18px;
}
.sk-fig {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
}
.sk-fig:hover,
.sk-fig:focus-visible {
  border-color: var(--accent);
}
.sk-fig b {
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.15;
}
.sk-fig-label {
  font-weight: 700;
  font-size: 0.875rem;
}
.sk-fig-note {
  font-size: 0.75rem;
  color: var(--text-muted);
}
.sk-fig.is-good {
  border-left-color: var(--accent);
}
.sk-fig.is-warn {
  border-left-color: var(--warn);
}
.sk-fig.is-warn b {
  color: var(--warn);
}
.sk-fig.is-bad {
  border-left-color: var(--danger);
}
.sk-fig.is-bad b,
.sk-bad {
  color: var(--danger);
}
.sk-empty {
  margin: 0 0 18px;
  padding: 16px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
}
.sk-empty p {
  margin: 6px 0 0;
}
.sk-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  align-items: start;
}
@media (min-width: 900px) {
  .sk-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .sk-wide {
    grid-column: 1 / -1;
  }
}
@media (min-width: 1500px) {
  .sk-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.sk-card {
  min-width: 0;
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.sk-card h2 {
  margin: 0 0 10px;
  font-size: 1rem;
}
.sk-card > p:last-child {
  margin-bottom: 0;
}
.sk-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.sk-list li {
  padding: 8px 0;
  border-top: 1px solid var(--border-soft);
}
.sk-list li:first-child {
  border-top: 0;
  padding-top: 0;
}
.sk-line {
  display: block;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.sk-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.sk-table th {
  text-align: left;
  font-size: 0.75rem;
  color: var(--text-muted);
  font-weight: 600;
  padding: 0 8px 6px 0;
}
.sk-table td {
  padding: 8px 8px 8px 0;
  border-top: 1px solid var(--border-soft);
  vertical-align: middle;
}
.sk-table .num {
  text-align: right;
  white-space: nowrap;
}
.sk-table .chip {
  margin-left: 6px;
}
.sk-topup {
  display: flex;
  gap: 6px;
  align-items: center;
  margin: 0;
}
.shell-main .wrap .sk-topup input,
.sk-topup input {
  width: 80px;
  max-width: 80px;
  padding: 6px 8px;
}
@media (max-width: 640px) {
  .sk-table thead {
    display: none;
  }
  .sk-table tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2px 10px;
    padding: 8px 0;
    border-top: 1px solid var(--border-soft);
  }
  .sk-table td {
    border: 0;
    padding: 2px 0;
    text-align: left;
  }
  .sk-table td:first-child,
  .sk-table td:last-child {
    grid-column: 1 / -1;
  }
  .sk-table td.num::before {
    content: attr(data-label) ': ';
    color: var(--text-muted);
    font-size: 0.75rem;
  }
}
.cat-sample-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 18px;
  margin: 18px 0 0;
  padding: 14px 16px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
}
.cat-sample-box p {
  margin: 4px 0 0;
}
@media (max-width: 640px) {
  .sk-figs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  .sk-fig {
    padding: 10px 12px;
  }
  .sk-fig b {
    font-size: 1.25rem;
  }
  .sk-table td.num {
    text-align: left;
  }
}
.sk-table th:last-child {
  padding-left: 12px;
}
/* The Catalogue's front page: each merchant card narrows the parts below to
   that merchant (pressed again, every merchant); its arrow opens the
   merchant's own page. */
div.cat-supplier {
  padding: 0;
  gap: 0;
}
.cat-s-pick {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 1;
  min-width: 0;
  padding: 16px 8px 16px 16px;
  color: inherit;
  text-decoration: none;
}
.cat-s-open {
  display: grid;
  place-items: center;
  align-self: stretch;
  width: 44px;
  font-size: 1.5rem;
  color: var(--text-faint);
  text-decoration: none;
  border-left: 1px solid var(--border-soft);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}
.cat-s-open:hover,
.cat-s-open:focus-visible {
  color: var(--accent);
  background: var(--bg-inset);
}
.cat-supplier.is-on {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--bg-raised));
}
.cat-all {
  margin-top: 24px;
}
.cat-all-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
}
.cat-all-head .cat-count {
  margin: 0;
}
.cat-all-sort {
  font-size: 0.875rem;
  font-weight: 500;
  margin-left: 6px;
}
.cat-filters {
  margin: 10px 0;
}
.cat-filters input[type='search'] {
  width: 100%;
}
.shell-main .wrap .cat-filters input[type='search'] {
  max-width: 720px;
}
.cat-chips {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin-bottom: 10px;
  scrollbar-width: thin;
}
.cat-chips a {
  flex: none;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
  font-size: 0.8125rem;
  font-weight: 600;
}
.cat-chips a.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.cat-chips a.cat-chip-clear {
  border-style: dashed;
  color: var(--text-muted);
}
.cat-used {
  color: var(--accent-text);
  font-weight: 600;
}

/* ---- the Catalogue as a parts database (14 October) ----
   Figures across the top, a filter bar, chips, and the parts as a table on
   a desk or cards on a phone: the same rows, laid out by the width the list
   has (a container query), so the merchant page with its categories down the
   side and the list with the part's panel open beside it both fit. */
.cat-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.cat-alert {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 6px 16px 6px 6px;
  border: 1px solid color-mix(in srgb, var(--warn) 55%, transparent);
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn);
  font-weight: 700;
  text-decoration: none;
}
.cat-alert b {
  display: inline-grid;
  place-items: center;
  min-width: 28px;
  height: 28px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--warn);
  color: var(--bg);
}
.cat-alert:hover {
  border-color: var(--warn);
}
.cat-figs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
  margin: 4px 0 18px;
}
.cat-fig {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
}
.cat-fig b {
  font-size: 1.6rem;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.cat-fig span {
  color: var(--text-muted);
  font-size: 0.875rem;
}
.cat-fig.is-good {
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, var(--bg-raised));
}
.cat-fig.is-good b {
  color: var(--accent-text);
}
.cat-fig.is-warn {
  border-left-color: var(--warn);
}
.cat-fig.is-bad {
  border-left-color: var(--danger);
}
a.cat-fig:hover {
  border-color: var(--accent);
}
.cat-page .cat-suppliers {
  margin-bottom: 14px;
}

/* the filter bar */
.cat-bar-f {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: stretch;
  margin: 6px 0 10px;
}
.cat-q {
  position: relative;
  flex: 1 1 280px;
  display: flex;
}
.cat-q input {
  width: 100%;
  max-width: none;
  min-height: 44px;
  padding-right: 40px;
}
.cat-kbd {
  position: absolute;
  right: 10px;
  top: 50%;
  translate: 0 -50%;
  padding: 1px 7px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-faint);
  font: 600 0.75rem var(--font);
  pointer-events: none;
}
.cat-selects {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.cat-sel {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 44px;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}
.cat-sel span {
  padding-left: 12px;
  color: var(--text-muted);
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
}
.cat-sel select {
  width: auto;
  min-height: 42px;
  max-width: 230px;
  border: 0;
  background-color: transparent;
  font-weight: 700;
  padding-left: 6px;
}
.cat-sel.is-set {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, var(--bg));
}
.cat-sel.is-set select {
  color: var(--accent-text);
}
.cat-more-f {
  display: none;
}
.cat-chips a i {
  font-style: normal;
  font-weight: 500;
  opacity: 0.75;
  margin-left: 2px;
}
.cat-chips a.cat-chip-warn {
  border-color: color-mix(in srgb, var(--warn) 60%, transparent);
  color: var(--warn);
}
.cat-chips a.cat-chip-warn.is-on {
  background: var(--warn);
  border-color: var(--warn);
  color: var(--bg);
}
.cat-all .cat-count {
  margin: 0 0 8px;
}

/* the list and the panel beside it */
.cat-work {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
.cat-work-list {
  container: catlist / inline-size;
  min-width: 0;
}
.cat-table {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  overflow: clip;
}
.cat-thead,
.cat-r {
  display: grid;
  grid-template-columns:
    48px minmax(200px, 1fr) 104px 84px 70px 92px 88px minmax(170px, 210px)
    44px 84px;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
}
.cat-thead {
  position: sticky;
  top: var(--nav-h, 0px);
  z-index: 2;
  padding-top: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border-soft);
  background: var(--bg-inset);
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.cat-table .cat-list {
  gap: 0;
}
.cat-r {
  min-height: 64px;
  border-bottom: 1px solid var(--border-soft);
  border-left: 3px solid transparent;
  content-visibility: auto;
  contain-intrinsic-size: auto 66px;
  cursor: pointer;
}
.cat-r:last-child {
  border-bottom: 0;
}
.cat-r:hover {
  background: color-mix(in srgb, var(--accent) 5%, var(--bg-raised));
}
.cat-r.is-open {
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--bg-raised));
}
.cat-r .cat-pic {
  width: 44px;
  height: 44px;
  border-radius: 10px;
}
.cat-r-part {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 6px;
  min-width: 0;
}
.cat-r-name {
  color: var(--text);
  font-weight: 650;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.cat-r-name:hover {
  color: var(--accent-text);
  text-decoration: underline;
}
.cat-unit {
  padding: 0 7px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 0.75rem;
  white-space: nowrap;
}
.cat-r-sub {
  flex-basis: 100%;
  font-size: 0.8125rem;
}
.cat-r-sub:empty {
  display: none;
}
.cat-r-code {
  color: var(--text-muted);
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
}
.cat-thead .cat-r-code {
  font-family: var(--font);
  font-size: 0.75rem;
}
.cat-r-trade,
.cat-r-sell,
.cat-r-profit,
.cat-r-used {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cat-r-trade {
  color: var(--text-muted);
}
.cat-r-trade i {
  display: none;
  font-style: normal;
}
.cat-r-mk {
  text-align: center;
}
.cat-mk {
  display: inline-block;
  min-width: 52px;
  padding: 2px 8px;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  font-variant-numeric: tabular-nums;
}
.cat-mk.is-own {
  border-color: var(--focus);
  color: var(--focus);
  font-weight: 700;
}
.cat-r-sell {
  font-weight: 750;
}
.cat-r-profit {
  color: var(--ok);
  font-weight: 650;
}
.cat-r-stock {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 0.875rem;
}
.cat-r-qty {
  min-width: 2ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.cat-bar {
  flex: 1 1 40px;
  max-width: 64px;
  height: 6px;
  border-radius: 999px;
  background: var(--bg-inset);
  overflow: hidden;
}
.cat-bar i {
  display: block;
  height: 100%;
  min-width: 3px;
  border-radius: inherit;
  background: var(--accent);
}
.is-low .cat-bar i {
  background: var(--warn);
}
.is-out .cat-bar i {
  background: var(--danger);
}
.cat-pill {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.cat-pill.is-in {
  background: var(--ok-bg);
  color: var(--ok);
}
.cat-pill.is-low {
  background: var(--warn-bg);
  color: var(--warn);
}
.cat-pill.is-out {
  background: var(--danger-bg);
  color: var(--danger);
}
.cat-r-min {
  white-space: nowrap;
}
.cat-r-used {
  color: var(--text-muted);
}
.cat-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 36px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font: 700 0.875rem var(--font);
  cursor: pointer;
  white-space: nowrap;
}
.cat-add:hover {
  background: var(--accent-strong);
}
.cat-add.is-added {
  background: var(--accent-tint);
  color: var(--accent-text);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.cat-nothing {
  padding: 18px 0;
}

/* narrower lists: the code, trade and used columns give way */
@container catlist (max-width: 1240px) {
  .cat-thead,
  .cat-r {
    grid-template-columns: 44px minmax(180px, 1fr) 84px 70px 92px 88px minmax(150px, 190px) 84px;
  }
  .cat-r-code,
  .cat-r-used {
    display: none;
  }
}
@container catlist (max-width: 1000px) {
  .cat-thead,
  .cat-r {
    grid-template-columns: 44px minmax(160px, 1fr) 64px 88px 84px minmax(140px, 180px) 50px;
  }
  .cat-r-trade {
    display: none;
  }
  .cat-add {
    width: 40px;
    padding: 0;
  }
  .cat-add-word {
    display: none;
  }
}
/* a phone, or a narrow list: each part a card */
@container catlist (max-width: 680px) {
  .cat-table {
    border: 0;
    background: none;
    overflow: visible;
  }
  .cat-thead {
    display: none;
  }
  .cat-table .cat-list {
    gap: 10px;
  }
  .cat-r {
    grid-template-columns: 64px auto auto minmax(0, 1fr) auto;
    grid-template-areas:
      'pic part part part add'
      'pic stock stock stock add'
      'pic sell trade profit add';
    gap: 2px 6px;
    padding: 12px 12px 12px 14px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-lg);
    background: var(--bg-raised);
    contain-intrinsic-size: auto 112px;
  }
  .cat-r:last-child {
    border-bottom: 1px solid var(--border-soft);
  }
  .cat-r.is-open {
    border-color: var(--accent);
  }
  .cat-r .cat-pic {
    grid-area: pic;
    width: 64px;
    height: 64px;
    margin-right: 8px;
    border-radius: 14px;
  }
  .cat-r-part {
    grid-area: part;
  }
  .cat-r > * {
    min-width: 0;
  }
  .cat-r-name {
    font-size: 1rem;
  }
  .cat-r-sub {
    flex-basis: auto;
    font-size: 0.8125rem;
  }
  .cat-unit {
    display: none;
  }
  .cat-r-stock {
    grid-area: stock;
    font-size: 0.8125rem;
  }
  .cat-r-stock .cat-bar {
    display: none;
  }
  .cat-r-mk,
  .cat-r-code,
  .cat-r-used {
    display: none;
  }
  /* price, trade and profit along the foot */
  .cat-r-sell {
    grid-area: sell;
    font-size: 1.15rem;
    text-align: left;
  }
  .cat-r-trade,
  .cat-r-profit {
    display: block;
    font-size: 0.875rem;
    text-align: left;
  }
  .cat-r-trade {
    grid-area: trade;
    padding-left: 6px;
  }
  .cat-r-profit {
    grid-area: profit;
    padding-left: 6px;
  }
  .cat-r-trade i {
    display: inline;
  }
  .cat-add,
  .cat-r-none {
    grid-area: add;
    margin-left: 8px;
  }
  .cat-add {
    width: 52px;
    height: 52px;
    padding: 0;
    font-size: 1.5rem;
  }
  .cat-add-word {
    display: none;
  }
}

/* the part's panel: a column beside the list on a wide screen */
.cat-panel[hidden],
.cat-scrim[hidden] {
  display: none;
}
.cat-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  outline: none;
}
.cat-panel.is-saving {
  box-shadow: inset 0 3px 0 var(--accent);
}
.cat-panel-x {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: var(--bg-inset);
  color: var(--text);
  cursor: pointer;
}
.cat-grip {
  display: none;
}
.cat-panel-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.cat-panel-body > .cat-pic {
  width: 72px;
  height: 72px;
  border-radius: 14px;
}
.cat-p-name {
  margin: 0;
  padding-right: 40px;
  font-size: 1.25rem;
}
.cat-p-meta {
  margin: -6px 0 0;
}
.cat-p-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg);
}
.cat-p-card h3 {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.cat-p-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-variant-numeric: tabular-nums;
}
.cat-p-profit b {
  color: var(--ok);
}
.cat-p-note {
  margin: -4px 0 0;
}
.cat-panel .link-btn {
  padding: 0;
  border: 0;
  background: none;
  color: var(--link);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.cat-slider {
  width: 100%;
  accent-color: var(--accent);
}
.cat-mk-box {
  width: 3.6em;
  min-height: 34px;
  margin: 0 4px 0 8px;
  padding: 4px 6px;
  text-align: center;
  -moz-appearance: textfield;
}
.cat-mk-box::-webkit-inner-spin-button,
.cat-mk-box::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.cat-mk-box.is-own {
  border-color: var(--focus);
}
.cat-step {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.cat-step-l {
  display: flex;
  flex-direction: column;
}
.cat-step-l small {
  font-size: 0.75rem;
}
.cat-step-c {
  display: flex;
  align-items: center;
  gap: 6px;
}
.cat-step-c button {
  width: 44px;
  height: 44px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-raised);
  color: var(--text);
  font-size: 1.25rem;
  cursor: pointer;
}
.cat-step-c input {
  width: 4.2em;
  min-height: 44px;
  text-align: center;
  font-size: 1.15rem;
  font-weight: 750;
  -moz-appearance: textfield;
}
.cat-step-c input::-webkit-inner-spin-button {
  -webkit-appearance: none;
}
.cat-deliv {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.cat-deliv-f {
  display: flex;
  gap: 6px;
}
.cat-deliv-f[hidden] {
  display: none;
}
.cat-deliv-f input {
  width: 7em;
}
.cat-switch {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  cursor: pointer;
}
.cat-switch > span {
  display: flex;
  flex-direction: column;
  font-weight: 600;
}
.cat-switch small {
  font-weight: 400;
}
.cat-switch input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.cat-switch i {
  flex: none;
  position: relative;
  width: 48px;
  height: 28px;
  border-radius: 999px;
  background: var(--border);
  transition: background 0.15s;
}
.cat-switch i::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  transition: translate 0.15s;
}
.cat-switch input:checked + i {
  background: var(--accent);
}
.cat-switch input:checked + i::after {
  translate: 20px 0;
}
.cat-switch input:focus-visible + i {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.cat-stop {
  align-self: flex-start;
}
.cat-p-err {
  margin: 0;
  color: var(--danger);
  font-weight: 600;
}
.cat-p-err[hidden] {
  display: none;
}
.cat-moves {
  margin: 0;
  padding: 0;
  list-style: none;
}
.cat-moves li {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  border-top: 1px solid var(--border-soft);
  font-size: 0.875rem;
}
.cat-moves li:first-child {
  border-top: 0;
}
.cat-short {
  color: var(--warn);
}
.cat-p-acts {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.cat-p-add {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  width: 100%;
  justify-content: center;
}
.cat-mk-l {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.cat-panel .cat-p-line .cat-mk-box {
  width: 3.6em;
  min-width: 0;
  flex: none;
}
.cat-panel .cat-step-c input {
  width: 4.2em;
  flex: none;
}
.cat-p-wait {
  padding: 24px 0;
}
@media (min-width: 1280px) {
  .cat-work.has-panel {
    grid-template-columns: minmax(0, 1fr) 380px;
  }
  .cat-work.has-panel .cat-panel {
    position: sticky;
    top: calc(var(--nav-h, 0px) + 12px);
    max-height: calc(100vh - var(--nav-h, 0px) - 24px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}
/* narrower than that: a drawer from the right, over a scrim */
@media (max-width: 1279px) {
  .cat-panel {
    position: fixed;
    z-index: 30;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(420px, 92vw);
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: -12px 0 40px rgb(0 0 0 / 0.35);
    translate: 100% 0;
    transition: translate 0.22s ease-out;
  }
  .cat-panel.is-in {
    translate: 0 0;
  }
  .cat-scrim {
    position: fixed;
    inset: 0;
    z-index: 29;
    background: rgb(4 10 20 / 0.45);
  }
}
/* a phone: a sheet up from the foot */
@media (max-width: 767px) {
  .cat-panel {
    top: auto;
    left: 0;
    width: auto;
    max-height: 86vh;
    max-height: 86dvh;
    padding: 10px 16px calc(18px + env(safe-area-inset-bottom, 0px));
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -12px 40px rgb(0 0 0 / 0.35);
    translate: 0 100%;
  }
  .cat-panel.is-in {
    translate: 0 0;
  }
  .cat-grip {
    display: block;
    align-self: center;
    width: 44px;
    height: 5px;
    border-radius: 999px;
    background: var(--border);
  }
  .cat-panel-x {
    top: 14px;
  }
  html.cat-sheet-open {
    overflow: hidden;
  }
  .cat-figs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  .cat-fig {
    padding: 10px 12px;
  }
  .cat-fig b {
    font-size: 1.25rem;
  }
  .cat-fig span {
    font-size: 0.8125rem;
  }
  .cat-fig:first-child {
    display: none;
  }
  /* the selects fold behind Filters */
  .cat-more-f {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg);
    color: var(--accent-text);
    font: 700 0.9375rem var(--font);
  }
  .cat-bar-f.filters-set .cat-more-f {
    border-color: var(--accent);
  }
  .cat-selects {
    display: none;
    flex-basis: 100%;
  }
  .cat-bar-f.filters-open .cat-selects {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  .cat-sel select {
    max-width: none;
    width: 100%;
  }
  .cat-kbd {
    display: none;
  }
  .cat-q {
    flex: 1 1 0;
  }
  .cat-head-acts {
    width: 100%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .cat-panel {
    transition: none;
  }
}

/* the parts picked with + Add, along the foot */
.cat-basket[hidden] {
  display: none;
}
.cat-basket {
  position: fixed;
  z-index: 8;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  translate: -50% 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 10px;
  width: max-content;
  max-width: calc(100vw - 32px);
  padding: 10px 12px 10px 18px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--bg-raised);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.3);
}
.cat-basket-n {
  font-weight: 750;
}
.cat-basket select {
  min-height: 36px;
}
body.cat-has-basket .cat-page {
  padding-bottom: 96px;
}
@media (max-width: 767px) {
  .cat-basket {
    bottom: calc(var(--nav-h) + 10px + env(safe-area-inset-bottom, 0px));
    border-radius: 18px;
    padding: 10px 12px;
  }
}

/* Account and Settings are forms: a column in the middle of a wide screen,
   at their own widths, not a strip down the left with the rest empty. */
@media (min-width: 768px) {
  .shell-main main.page-main > .wrap.wrap-account,
  .shell-main main.page-main > .wrap.wrap-settings {
    margin-left: auto;
    margin-right: auto;
  }
}
/* A button on a phone is the width of the screen, for a thumb. On a tablet or
   a PC that made Save profile, Connect and the like a bar from one side of
   the page to the other; there they are no wider than a button needs to be. */
@media (min-width: 768px) {
  .shell-main main .btn,
  .shell-main main .btn-big,
  .shell-main main .btn-quiet {
    max-width: 420px;
  }
}

/* Customisation: a section with no document preview beside it (Emails,
   Reminders, Service reminders) takes the whole width instead of the left
   column with an empty right. Each email's wording and its preview sit side
   by side. */
@media (min-width: 1024px) {
  body.has-sections .sec-body.no-live {
    grid-template-columns: minmax(0, 1fr);
  }
  .sec-body.no-live section.sec > p {
    max-width: 78ch;
  }
  .sec-body.no-live .email-edit {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 24px;
  }
  .sec-body.no-live .email-preview {
    height: 520px;
  }
}

/* The things still to set up, over the quotes list: side by side across a
   wide screen, each as wide as its share, rather than a short stack down the
   left with the rest of the row empty. */
.q-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}
.q-cards:not(:has(> :not([hidden]))) {
  display: none;
}
.q-cards > * {
  width: auto;
  margin: 0;
}
.q-cards > .paycard {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.q-cards > .paycard p {
  flex: 1 1 auto;
}

/* ---- Customers as a working table (14 October) ----
   The catalogue's figures, filter bar and chips, and every customer on one
   row: how to reach them, where the job is, the work they have given you and
   what they owe, with call, WhatsApp, directions and a new quote on the row.
   Cards on a phone, by the width the list has. */
.cat-alert.is-bad {
  border-color: color-mix(in srgb, var(--danger) 55%, transparent);
  background: var(--danger-bg);
  color: var(--danger);
}
.cat-alert.is-bad b {
  background: var(--danger);
}
.cu-pill-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text);
  font-weight: 650;
  text-decoration: none;
}
.cu-pill-link:hover {
  border-color: var(--accent);
}
.cu-page .cat-head-acts {
  align-items: center;
}
.cu-page .filters-dl-form {
  margin: 0;
}
.cat-chips a.cu-chip-bad {
  border-color: color-mix(in srgb, var(--danger) 60%, transparent);
  color: var(--danger);
}
.cat-chips a.cu-chip-bad.is-on {
  background: var(--danger);
  border-color: var(--danger);
  color: var(--bg);
}
.cu-table {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  overflow: clip;
}
.cu-thead,
.cu-r {
  display: grid;
  grid-template-columns:
    44px minmax(210px, 1.3fr) minmax(170px, 1fr) minmax(150px, 1fr) 176px 108px
    120px 178px;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
}
.cu-thead {
  position: sticky;
  top: var(--nav-h, 0px);
  z-index: 2;
  border-bottom: 1px solid var(--border-soft);
  background: var(--bg-inset);
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.cu-list {
  display: flex;
  flex-direction: column;
}
.cu-r {
  min-height: 70px;
  border-bottom: 1px solid var(--border-soft);
  border-left: 3px solid transparent;
  content-visibility: auto;
  contain-intrinsic-size: auto 72px;
  cursor: pointer;
}
.cu-r[hidden] {
  display: none;
}
.cu-r:last-child {
  border-bottom: 0;
}
.cu-r:hover {
  background: color-mix(in srgb, var(--accent) 5%, var(--bg-raised));
}
.cu-r.is-open {
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--bg-raised));
}
.cu-r.needs {
  border-left-color: var(--danger);
}
.cu-r.is-gone {
  opacity: 0.7;
}
.cu-r > * {
  min-width: 0;
}
.cu-av {
  --hue: 150;
  display: inline-grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: hsl(var(--hue) 45% 30%);
  color: #fff;
  font-weight: 800;
  font-size: 0.9375rem;
}
.cu-av.is-biz {
  border-radius: 12px;
  background: hsl(var(--hue) 35% 28%);
}
.cu-av.is-gone {
  background: var(--bg-inset);
  color: var(--text-faint);
}
.cu-who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 3px 6px;
}
.cu-name {
  color: var(--text);
  font-weight: 700;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.cu-name:hover {
  color: var(--accent-text);
  text-decoration: underline;
}
.cu-ref,
.cu-tag,
.cu-pc {
  padding: 0 7px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}
.cu-ref {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}
.cu-tag {
  border-color: color-mix(in srgb, var(--focus) 55%, transparent);
  color: var(--focus);
}
.cu-sub {
  flex-basis: 100%;
  font-size: 0.8125rem;
}
.cu-contact,
.cu-site {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 0.875rem;
}
.cu-contact a {
  color: var(--text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cu-contact a:hover {
  color: var(--accent-text);
  text-decoration: underline;
}
.cu-mail {
  color: var(--text-muted) !important;
}
.cu-addr {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cu-pc {
  align-self: flex-start;
}
.cu-jobs {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.cu-counts {
  display: flex;
  flex-wrap: wrap;
  gap: 0 8px;
}
.cu-won,
.cu-bal {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.cu-won {
  font-weight: 650;
}
.cu-won i {
  display: none;
  font-style: normal;
  color: var(--text-muted);
  font-weight: 400;
}
.cu-bal {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}
.cu-pill {
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--bg-inset);
  color: var(--text-muted);
}
.cu-pill.is-ok {
  background: var(--ok-bg);
  color: var(--ok);
}
.cu-pill.is-warn {
  background: var(--warn-bg);
  color: var(--warn);
}
.cu-pill.is-bad {
  background: var(--danger-bg);
  color: var(--danger);
}
.cu-pill.is-info {
  background: color-mix(in srgb, var(--focus) 18%, transparent);
  color: var(--focus);
}
.cu-pill.is-none {
  background: none;
}
.cu-acts {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 6px;
}
.cu-act {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text);
}
.cu-act:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}
.cu-quote {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 36px;
  padding: 0 12px 0 8px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  font-size: 0.875rem;
  text-decoration: none;
  white-space: nowrap;
}
.cu-quote:hover {
  background: var(--accent-strong);
}
.cu-none {
  padding: 16px;
}
@container catlist (max-width: 1240px) {
  .cu-thead,
  .cu-r {
    grid-template-columns: 44px minmax(190px, 1.3fr) minmax(160px, 1fr) 140px 104px 120px 130px;
  }
  .cu-site {
    display: none;
  }
  .cu-act:nth-child(2) {
    display: none;
  }
  .cu-quote-w {
    display: none;
  }
  .cu-quote {
    padding: 0;
    width: 36px;
    justify-content: center;
  }
}
@container catlist (max-width: 900px) {
  .cu-thead,
  .cu-r {
    grid-template-columns: 44px minmax(170px, 1fr) 130px 120px 92px;
  }
  .cu-contact,
  .cu-won {
    display: none;
  }
  .cu-act:not(:last-of-type) {
    display: none;
  }
}
/* a phone, or a narrow list: each customer a card */
@container catlist (max-width: 620px) {
  .cu-table {
    border: 0;
    background: none;
    overflow: visible;
  }
  .cu-thead {
    display: none;
  }
  .cu-list {
    gap: 10px;
  }
  .cu-r {
    grid-template-columns: 44px minmax(0, 1fr) auto;
    grid-template-areas:
      'av who bal'
      'av contact contact'
      'av jobs jobs'
      'av acts acts';
    gap: 4px 10px;
    padding: 12px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-lg);
    background: var(--bg-raised);
    contain-intrinsic-size: auto 150px;
  }
  .cu-r:last-child {
    border-bottom: 1px solid var(--border-soft);
  }
  .cu-r.needs {
    border-left: 3px solid var(--danger);
  }
  .cu-av {
    grid-area: av;
    align-self: start;
  }
  .cu-who {
    grid-area: who;
  }
  .cu-contact {
    display: flex;
    grid-area: contact;
  }
  .cu-site {
    display: none;
  }
  .cu-jobs {
    grid-area: jobs;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 2px 10px;
    font-size: 0.8125rem;
  }
  .cu-won {
    display: none;
  }
  .cu-bal {
    grid-area: bal;
    align-self: start;
  }
  .cu-acts {
    grid-area: acts;
    justify-content: flex-start;
    margin-top: 6px;
  }
  .cu-act,
  .cu-act:nth-child(2),
  .cu-act:not(:last-of-type) {
    display: inline-grid;
    width: 44px;
    height: 44px;
  }
  .cu-quote {
    width: auto;
    min-height: 44px;
    padding: 0 16px 0 12px;
    margin-left: auto;
  }
  .cu-quote-w {
    display: inline;
  }
}

/* the customer's panel */
.cu-big-acts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(76px, 1fr));
  gap: 8px;
}
.cu-big-act {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font-size: 0.8125rem;
  font-weight: 650;
  text-decoration: none;
}
.cu-big-act:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}
.cu-break {
  overflow-wrap: anywhere;
  text-align: right;
}
.cu-p-addr {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.cu-p-figs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.cu-p-figs > div {
  display: flex;
  flex-direction: column;
  padding: 8px 10px;
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.cu-p-figs b {
  font-size: 1.1rem;
  font-variant-numeric: tabular-nums;
}
.cu-p-figs span {
  color: var(--text-muted);
  font-size: 0.8125rem;
}
.cu-p-figs .is-warn b {
  color: var(--warn);
}
.cu-p-figs .is-bad b {
  color: var(--danger);
}
.cu-p-counts {
  margin: 0;
}
.cu-p-jobs {
  margin: 0;
  padding: 0;
  list-style: none;
}
.cu-p-jobs li {
  border-top: 1px solid var(--border-soft);
}
.cu-p-jobs li:first-child {
  border-top: 0;
}
.cu-p-jobs a {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  color: var(--text);
  text-decoration: none;
}
.cu-p-jobs a > span:first-child {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.cu-p-jr {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  white-space: nowrap;
}
.cu-page .filters-dl {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 16px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text);
  font: 600 0.875rem var(--font);
  cursor: pointer;
  white-space: nowrap;
}
.cu-page .filters-dl svg {
  color: var(--accent);
}
.cu-page .filters-dl:hover {
  background: var(--accent-tint);
}
.cu-page-acts {
  display: inline-flex;
  margin-left: 4px;
}
@media (max-width: 767px) {
  .cat-q input {
    padding-right: 12px;
  }
  /* the customers' fuller hint needs the line to itself; Filters goes under it */
  .cm-search.cat-bar-f .cat-q {
    flex: 1 1 100%;
  }
}
/* On a PC there is no bar across the top (the rail is down the side), so the
   table heads and the part's panel stick to the very top of the window. */
@media (min-width: 1000px) {
  .cat-thead,
  .cu-thead {
    top: 0;
  }
}
@media (min-width: 1280px) {
  .cat-work.has-panel .cat-panel {
    top: 12px;
    max-height: calc(100vh - 24px);
  }
}

/* ---- the help centre and the FAQs (15 October) ----
   On a PC the guides (or the questions) down the side and the one being read
   beside them; on a phone a list, each guide its own page and each answer
   opening under its question. One search, which sticks to the top of a phone. */
.hc {
  max-width: 1240px;
  min-width: 0;
  margin-inline: auto;
}
.hc-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.hc-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 8px 0 18px;
}
.hc-head h1 {
  margin: 0 0 2px;
}
.hc-head p {
  margin: 0;
}
.hc-mark {
  flex: none;
  display: inline-block;
  width: 48px;
  height: 48px;
  color: var(--text);
}
.hc-search {
  position: relative;
  display: flex;
  align-items: center;
  margin: 0 0 12px;
}
.hc-search svg {
  position: absolute;
  left: 14px;
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  pointer-events: none;
}
.hc-search input {
  width: 100%;
  max-width: none;
  min-height: 46px;
  padding-left: 42px;
  padding-right: 40px;
  border-radius: 999px;
}
.hc-search kbd {
  position: absolute;
  right: 14px;
  padding: 1px 7px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-faint);
  font: 600 0.75rem var(--font);
  pointer-events: none;
}
.hc-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
.hc-shelf {
  margin-bottom: 14px;
}
.hc-shelf[hidden],
.hc-shelf li[hidden] {
  display: none;
}
.hc-shelf-h {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hc-shelf-h .muted {
  font-weight: 600;
  margin-left: 4px;
}
.hc-shelf-blurb {
  margin: 2px 0 6px;
  font-size: 0.8125rem;
}
.hc-shelf ul {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hc-link {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 9px 12px;
  border: 1px solid transparent;
  border-left: 3px solid transparent;
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
}
.hc-link b {
  font-weight: 650;
}
.hc-link span {
  color: var(--text-muted);
  font-size: 0.8125rem;
}
.hc-link:hover {
  background: var(--bg-raised);
  border-color: var(--border-soft);
}
.hc-link.is-on {
  background: color-mix(in srgb, var(--accent) 10%, var(--bg-raised));
  border-color: var(--border-soft);
  border-left-color: var(--accent);
}
.hc-link.is-on b {
  color: var(--accent-text);
}
.hc-none {
  padding: 8px 12px;
}
.hc-faq-door {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
  padding: 12px 14px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-tint);
  color: var(--text);
  text-decoration: none;
}
.hc-faq-door span {
  font-size: 0.8125rem;
}
.hc-read {
  min-width: 0;
}
.hc-back {
  display: none;
}
.hc-crumb {
  margin: 0 0 4px;
  color: var(--accent-text);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.hc-title {
  margin: 0 0 10px;
  font-size: clamp(1.4rem, 2.4vw, 1.9rem);
}
.hc-guide,
.hc-welcome {
  padding: 22px 24px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  margin-bottom: 14px;
}
.hc-guide .help-steps {
  max-width: 68ch;
}
.hc-pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border-soft);
}
.hc-pager a {
  display: flex;
  flex-direction: column;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  color: var(--text);
  font-weight: 650;
  text-decoration: none;
}
.hc-pager a small {
  color: var(--text-muted);
  font-weight: 500;
}
.hc-pager a.is-next {
  grid-column: 2;
  text-align: right;
}
.hc-pager a:hover {
  border-color: var(--accent);
}
.hc-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.hc-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  text-decoration: none;
}
.hc-card i {
  margin-top: auto;
  padding-top: 8px;
  font-style: normal;
  font-weight: 700;
  color: var(--accent-text);
  font-size: 0.875rem;
}
.hc-card:hover {
  border-color: var(--accent);
}
/* the FAQs */
.hc-faq-bar {
  margin-bottom: 14px;
}
.hc-chips button {
  flex: none;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: none;
  color: var(--text);
  font: 600 0.8125rem var(--font);
  cursor: pointer;
}
.hc-chips button i {
  font-style: normal;
  font-weight: 500;
  opacity: 0.75;
}
.hc-chips button.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.hc-qs {
  display: none;
}
.hc-topic[hidden],
.hc-faq[hidden] {
  display: none;
}
.hc-topic-h {
  margin: 18px 0 8px;
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hc-topic:first-child .hc-topic-h {
  margin-top: 0;
}
.hc-answer {
  padding-top: 4px;
}
.hc-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 8px;
}
.hc-tag {
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 650;
}
.hc-copy {
  margin-top: 10px;
}
@media (max-width: 999px) {
  /* a guide is its own page on a phone: the list makes way for it */
  .hc.has-guide .hc-side {
    display: none;
  }
  .hc.has-guide .hc-back {
    display: inline-flex;
    margin-bottom: 10px;
    font-weight: 650;
  }
  .hc-search {
    position: sticky;
    top: 0;
    z-index: 3;
    padding: 8px 0;
    background: var(--bg);
  }
  .hc-guide,
  .hc-welcome {
    padding: 18px 16px;
  }
}
@media (min-width: 1000px) {
  .hc-body {
    grid-template-columns: 340px minmax(0, 1fr);
    gap: 32px;
  }
  .hc-side {
    position: sticky;
    top: 16px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 4px;
  }
  .hc-qs {
    display: block;
  }
  /* one answer at a time, beside the questions */
  .hc-faqs.is-split .hc-faq:not(.is-shown),
  .hc-faqs.is-split .hc-topic-h {
    display: none;
  }
  .hc-faqs.is-split .hc-faq.is-shown {
    padding: 22px 24px;
    border-radius: var(--radius-lg);
  }
  .hc-faqs.is-split .hc-faq.is-shown > summary {
    pointer-events: none;
    font-size: 1.35rem;
    list-style: none;
  }
  .hc-faqs.is-split .hc-faq.is-shown > summary::-webkit-details-marker {
    display: none;
  }
  .hc-faqs.is-split .hc-answer {
    font-size: 1.0625rem;
  }
}
.hc > *,
.hc-faq-bar,
.hc-side {
  min-width: 0;
}
.hc-faqs.is-split .hc-answer p,
.hc-faqs.is-split .hc-answer li {
  color: var(--text);
}
/* the chip row scrolls sideways on a phone instead of widening the page */
.hc-chips {
  contain: inline-size;
}
.wrap.hc {
  width: 100%;
  box-sizing: border-box;
}
@media (max-width: 999px) {
  /* on the FAQs the search and the topic chips stick together */
  .hc-faq-bar {
    position: sticky;
    top: 0;
    z-index: 3;
    padding-top: 8px;
    background: var(--bg);
  }
  .hc-faq-bar .hc-search {
    position: relative;
    padding: 0;
  }
}

/* ---------- the Buy list and Suppliers, under Stock ---------- */
.bl-subnav {
  margin: 0 0 16px;
}
.bl-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 16px;
  color: var(--text-muted);
}
.chip.bl-non,
.chip.bl-unordered {
  background: var(--bg-inset);
  color: var(--text);
  border: 1px solid var(--border);
}
.bl-day-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}
.bl-day-head h2 {
  margin: 0;
  font-size: 1.25rem;
}
.bl-make {
  margin-left: auto;
}
.bl-make > summary {
  list-style: none;
}
.bl-make > summary::-webkit-details-marker {
  display: none;
}
.bl-make[open] {
  flex-basis: 100%;
  margin-left: 0;
}
.bl-make-form {
  display: grid;
  gap: 6px;
  margin: 10px 0 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg);
  max-width: 560px;
}
.bl-make-form label {
  margin: 4px 0 0;
}
.bl-make-form .check-row {
  margin: 4px 0;
  font-weight: 400;
}
.bl-delivery {
  margin: 6px 0 0;
  padding: 6px 10px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.bl-sum-main {
  flex-basis: 100%;
}
.bl-sum-left {
  color: var(--warn);
  font-weight: 700;
}
.bl-sum-done {
  color: var(--ok);
  font-weight: 700;
}
.bl-sup-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}
.bl-sup-head h3 {
  margin: 0;
  font-size: 1rem;
}
.bl-page {
  --bl-edge: #17c96f;
  --bl-glow: rgba(23, 201, 111, 0.16);
  --bl-blue: #1f63c2;
  --bl-blue-bg: #e4eefc;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .bl-page {
    --bl-glow: rgba(23, 201, 111, 0.28);
    --bl-blue: #7fb6ff;
    --bl-blue-bg: #142a4a;
  }
}
:root[data-theme='dark'] .bl-page {
  --bl-glow: rgba(23, 201, 111, 0.28);
  --bl-blue: #7fb6ff;
  --bl-blue-bg: #142a4a;
}
.bl-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.bl-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 0 0 14px;
}
.bl-kpi {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-width: 0;
  padding: 14px 16px;
  border: 1.5px solid var(--bl-edge);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow:
    0 0 0 1px var(--bl-glow),
    0 0 18px var(--bl-glow);
  color: var(--text);
  text-decoration: none;
  text-align: center;
  overflow-wrap: anywhere;
}
a.bl-kpi:hover {
  border-color: var(--accent-strong);
}
.bl-kpi-n {
  font-size: 1.75rem;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.bl-kpi-words {
  font-size: 1.0625rem;
}
.bl-kpi.is-warn .bl-kpi-n {
  color: var(--warn);
}
.bl-kpi-label {
  font-weight: 600;
}
.bl-kpi-note {
  font-size: 0.75rem;
  color: var(--text-muted);
}
.bl-kpi-fin {
  align-items: flex-start;
  text-align: left;
  font-size: 0.8125rem;
}
.bl-kpi-h {
  font-weight: 800;
  font-size: 0.9375rem;
}
.bl-profit {
  color: var(--ok);
}
.bl-show {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 12px;
}
.bl-show-h {
  font-weight: 700;
  margin-right: 2px;
}
.bl-show-opt {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 14px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font-weight: 600;
  font-size: 0.875rem;
  text-decoration: none;
}
.bl-show-opt.is-on {
  border-color: var(--bl-edge);
  background: var(--bl-edge);
  color: #062a17;
}
.bl-live:empty {
  display: none;
}
.bl-live {
  margin: 0 0 12px;
  padding: 8px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--bl-edge);
  background: var(--ok-bg);
  font-size: 0.875rem;
}
.bl-live.is-bad {
  border-color: var(--danger);
  background: var(--danger-bg);
}
.bl-day {
  margin: 0 0 26px;
  padding: 0 0 0 14px;
  border-left: 4px solid var(--accent);
  scroll-margin-top: 80px;
  min-width: 0;
}
.bl-is-sample .bl-day {
  border-left-style: dashed;
}
.bl-sum {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 10px 0 12px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  font-size: 0.875rem;
}
.bl-sup {
  margin: 14px 0 0;
  padding: 12px 14px 8px;
  border: 1.5px solid var(--bl-edge);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  box-shadow:
    0 0 0 1px var(--bl-glow),
    0 0 18px var(--bl-glow);
  min-width: 0;
}
.bl-sup[data-status='ordered'] {
  border-color: var(--border);
  box-shadow: none;
}
.bl-sup-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.bl-sup-acts:empty {
  display: none;
}
.btn-compact.bl-go {
  background: var(--bl-edge);
  border-color: var(--bl-edge);
  color: #062a17;
  min-height: 44px;
}
.btn-compact.bl-go:hover {
  background: var(--accent-strong);
}
.bl-table {
  width: 100%;
  margin: 8px 0 0;
  border-collapse: collapse;
  table-layout: auto;
  font-size: 0.875rem;
}
.bl-table th {
  padding: 6px 8px;
  border-bottom: 1.5px solid var(--border);
  text-align: left;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  white-space: nowrap;
}
.bl-table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
}
.bl-table .bl-c-qty,
.bl-table .bl-c-unit,
.bl-table .bl-c-line {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bl-table th.bl-c-acts,
.bl-table td.bl-c-acts {
  width: 1%;
  text-align: right;
  white-space: nowrap;
}
.bl-c-pn {
  color: var(--text-muted);
  overflow-wrap: break-word;
  max-width: 9rem;
}
.bl-c-desc {
  min-width: 0;
  overflow-wrap: anywhere;
}
.bl-item-name {
  display: block;
  overflow-wrap: anywhere;
}
.bl-sub {
  display: block;
  font-size: 0.75rem;
  color: var(--text-muted);
}
.bl-sub-pn,
.bl-sub-unit,
.bl-sub-calc {
  display: none;
}
.bl-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.bl-acts {
  display: inline-flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  align-items: center;
  gap: 2px;
}
.bl-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.bl-ico:hover,
.bl-ico:focus-visible {
  border-color: var(--bl-edge);
  color: var(--accent-text);
}
.bl-ico[aria-expanded='true'] {
  color: var(--accent-text);
  border-color: var(--bl-edge);
}
.bl-jobs-row > td {
  padding: 4px 8px 10px;
  background: var(--bg);
}
.bl-jobs {
  margin: 0;
  font-size: 0.8125rem;
}
.bl-job {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 6px;
  padding: 3px 0 3px 10px;
  border-left: 2px solid var(--bl-edge);
}
.bl-total td {
  padding: 8px;
  border-bottom: 0;
  text-align: right;
  font-size: 0.8125rem;
}
.chip.bl-pill {
  border: 1px solid transparent;
  white-space: nowrap;
}
.chip.bl-p-order {
  background: var(--warn-bg);
  color: var(--warn);
  border-color: var(--warn);
}
.chip.bl-p-replenish {
  background: var(--ok-bg);
  color: var(--ok);
  border-color: var(--ok);
}
.chip.bl-p-nonstock {
  background: var(--bg-inset);
  color: var(--text-muted);
  border-color: var(--border);
}
.chip.bl-p-hand {
  background: var(--bl-blue-bg);
  color: var(--bl-blue);
  border-color: var(--bl-blue);
}
.chip.bl-p-notpart {
  background: transparent;
  color: var(--text-muted);
  border: 1px dashed var(--border);
  text-decoration: line-through;
}
.chip.bl-p-ordered,
.bl-jobs .chip.chip-ok {
  background: transparent;
  color: var(--accent-text);
  border: 1px solid var(--bl-edge);
}
.bl-item.is-off td:not(.bl-c-acts):not(.bl-c-status),
.bl-job.is-off {
  color: var(--text-muted);
  text-decoration: line-through;
  opacity: 0.7;
}
.bl-job.is-off .bl-inline,
.bl-job.is-off .chip.bl-p-notpart {
  opacity: 1;
}
.bl-state {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 6px 0;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.bl-inline {
  display: inline;
  margin: 0;
}
.bl-jobs,
.bl-suppliers,
.bl-pop-list,
.bl-covers {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bl-item-name {
  overflow-wrap: anywhere;
}
.bl-job {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 6px;
  padding: 3px 0 3px 10px;
  border-left: 2px solid var(--border);
}
.bl-acks {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
}
.bl-ack {
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.bl-flagged {
  margin: 0 0 10px;
  padding: 10px 12px;
  border: 1px solid var(--danger);
  border-radius: var(--radius);
  background: var(--danger-bg);
  font-size: 0.875rem;
}
.bl-flagged ul {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}
.bl-flagged li {
  padding: 3px 0;
  overflow-wrap: anywhere;
}
.bl-order-state {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 0 0 14px;
}
.bl-copy {
  max-width: 760px;
}
.bl-copy-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.bl-copy-row input {
  flex: 1 1 220px;
  min-width: 0;
}
.bl-copy textarea {
  width: 100%;
  box-sizing: border-box;
  font:
    0.875rem/1.5 ui-monospace,
    SFMono-Regular,
    Menlo,
    Consolas,
    monospace;
  white-space: pre-wrap;
}
.bl-covers li {
  padding: 4px 0;
  border-top: 1px solid var(--border-soft);
  font-size: 0.875rem;
  overflow-wrap: anywhere;
}
.bl-suppliers {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 12px;
  margin: 0 0 18px;
}
.bl-supplier {
  min-width: 0;
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.bl-supplier .btn-compact {
  margin-left: auto;
  min-height: 34px;
}
.bl-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 10px;
  margin: 10px 0 0;
  font-size: 0.875rem;
}
.bl-facts dt {
  color: var(--text-muted);
}
.bl-facts dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
.bl-address {
  white-space: pre-line;
}
.bl-merchants {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.bl-pop-list li {
  padding: 6px 0;
  border-top: 1px solid var(--border-soft);
}
.stock-window .check-row {
  margin: 6px 0 0;
}
.bl-added {
  overflow-wrap: anywhere;
}
.bl-edit-item {
  display: inline-block;
}
.bl-edit-item > summary {
  list-style: none;
  cursor: pointer;
}
.bl-edit-item > summary::-webkit-details-marker {
  display: none;
}
.bl-edit-item[open] {
  display: block;
  flex-basis: 100%;
}
.bl-make-form .two-up {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 6px 12px;
}
.bl-make-form input,
.bl-make-form select {
  min-width: 0;
  max-width: 100%;
}
.bl-notparts {
  margin: 10px 0 0;
  padding: 6px 10px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.bl-notparts > summary {
  cursor: pointer;
  font-weight: 600;
}
.bl-notparts ul {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}
.bl-notparts li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 8px;
  padding: 4px 0;
  border-top: 1px solid var(--border-soft);
  overflow-wrap: anywhere;
}
.bl-sample {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 2px dashed var(--accent);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  min-width: 0;
}
.bl-sample > div {
  flex: 1 1 320px;
  min-width: 0;
}
.bl-sample-h {
  font-size: 1.0625rem;
}
.bl-sample p {
  margin: 4px 0 0;
  font-size: 0.875rem;
  color: var(--text-muted);
}
.bl-is-sample button[disabled],
.bl-page button[data-sample-action] {
  cursor: not-allowed;
  opacity: 0.6;
}
@media (max-width: 1100px) {
  .bl-table .bl-c-unit {
    display: none;
  }
  .bl-sub-unit {
    display: block;
  }
  .bl-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 760px) {
  .bl-day {
    padding-left: 10px;
  }
  .bl-sup {
    padding: 10px 10px 6px;
  }
  .bl-sup-head h3 {
    flex: 1 1 100%;
  }
  .bl-sup-acts {
    margin-left: 0;
  }
  .bl-kpi {
    padding: 10px;
  }
  .bl-kpi-n {
    font-size: 1.375rem;
  }
  .bl-table,
  .bl-table tbody,
  .bl-table tfoot,
  .bl-table tr,
  .bl-table td {
    display: block;
  }
  .bl-table thead {
    display: none;
  }
  .bl-table tr.bl-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border-soft);
  }
  .bl-table tr.bl-item td {
    padding: 0;
    border: 0;
    text-align: left;
  }
  .bl-table tr.bl-item .bl-c-pn,
  .bl-table tr.bl-item .bl-c-qty,
  .bl-table tr.bl-item .bl-c-unit,
  .bl-table tr.bl-item .bl-c-line {
    display: none;
  }
  .bl-sub-unit {
    display: none;
  }
  .bl-sub-pn,
  .bl-sub-calc {
    display: block;
  }
  .bl-sub-calc {
    font-size: 0.875rem;
    color: var(--text);
  }
  .bl-acts {
    justify-content: flex-start;
  }
  .bl-jobs-row[hidden] {
    display: none;
  }
  .bl-total td {
    text-align: left;
  }
}
@media (max-width: 640px) {
  .bl-make {
    margin-left: 0;
    flex-basis: 100%;
  }
  .bl-make > summary {
    width: 100%;
  }
  .bl-facts {
    grid-template-columns: 1fr;
  }
}

/* ---- Email previews: the whole email by default, drag the corner to change it ---- */
.email-frame {
  position: relative;
  width: 100%;
  height: 420px;
  min-height: 140px;
  resize: vertical;
  overflow: hidden;
  padding-bottom: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: #fff;
}
.email-frame > iframe.email-preview,
.sec-body.no-live .email-frame > iframe.email-preview {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 0;
}

/* ---- Customisation › Emails: the look, the signature, the add-on ticks ---- */
.email-look {
  border-top: 1px solid var(--border-soft);
  padding-top: 12px;
  margin-top: 14px;
}
.email-look h3 {
  margin: 0 0 2px;
}
.el-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
  margin: 4px 0 2px;
}
.el-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  border: 1.5px solid var(--border-soft);
  border-radius: 10px;
  padding: 8px;
  margin: 0;
  font-weight: 400;
  cursor: pointer;
  position: relative;
  min-width: 0;
}
.el-card input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.el-card:has(input:checked) {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.el-card:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.el-card b {
  font-size: 0.875rem;
}
.el-card .small {
  line-height: 1.3;
}
.el-swatch {
  display: block;
  height: 56px;
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  background: #fff;
  position: relative;
  overflow: hidden;
}
.el-swatch i {
  position: absolute;
  left: 12%;
  right: 12%;
  height: 4px;
  border-radius: 2px;
  background: #cfd6de;
}
.el-swatch i:nth-child(1) {
  top: 44%;
}
.el-swatch i:nth-child(2) {
  top: 60%;
  right: 34%;
}
.el-swatch i:nth-child(3) {
  top: 76%;
  right: 50%;
}
.el-swatch::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 26%;
  height: 3px;
  background: var(--accent);
}
.el-swatch.el-banner::before {
  top: 0;
  height: 30%;
}
.el-swatch.el-letterhead::before {
  left: 40%;
  right: 40%;
  top: 30%;
}
.el-swatch.el-editorial::before {
  height: 1px;
  background: #9aa7b4;
}
.el-swatch.el-ink {
  border-color: #000;
}
.el-swatch.el-ink::before {
  height: 1px;
  background: #000;
}
.el-swatch.el-ink i {
  background: #6b6b6b;
}
.el-swatch.el-match::before {
  background: linear-gradient(90deg, var(--accent) 0 50%, #9aa7b4 50%);
}
.el-tries {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 8px;
}
.el-tries .live-try {
  align-items: flex-start;
  font-weight: 400;
}
.el-tries .live-try input {
  margin-top: 3px;
}
.el-built {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
@media (min-width: 1024px) {
  .el-built {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* ---- Visit reminders: tomorrow's visits on Home, and the line in the diary ---- */
.vr-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.vr-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.vr-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 12px;
  padding: 8px 0;
  border-top: 1px solid var(--border-soft);
}
.vr-main {
  min-width: 0;
  overflow-wrap: anywhere;
}
.vr-addr {
  display: block;
}
.vr-form {
  margin: 0;
}
.vr-sent,
.vr-why {
  overflow-wrap: anywhere;
}
.vr-why {
  color: var(--warn, #b45309);
}

/* ---- The order page: send it from QuoteNod, and the email it sends ---- */
.bl-send {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  margin: 0 0 14px;
  max-width: 760px;
  overflow-wrap: anywhere;
}
.bl-send h2 {
  margin: 0 0 4px;
}
.bl-preview {
  max-width: 760px;
  margin: 0 0 14px;
}
.bl-yourself {
  max-width: 760px;
  margin: 0 0 14px;
}
.bl-yourself > summary {
  cursor: pointer;
  font-weight: 600;
  margin: 0 0 8px;
}

/* ---- Messages with a supplier about an order: their page, the order page and the buy list ---- */
.sup-page h1 {
  margin: 0 0 4px;
}
.sup-table-wrap {
  max-width: 100%;
  overflow-x: auto;
  margin: 0 0 14px;
}
.sup-items {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}
.sup-items th,
.sup-items td {
  padding: 8px 6px;
  border-bottom: 1px solid var(--border-soft);
  text-align: left;
  vertical-align: top;
  overflow-wrap: anywhere;
}
.sup-items th {
  font-size: 0.8125rem;
  color: var(--text-muted);
  font-weight: 600;
}
.sup-items td:nth-child(2) {
  overflow-wrap: normal;
  white-space: nowrap;
}
.sup-items .num {
  text-align: right;
  white-space: nowrap;
}
.sup-facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 6px 14px;
  margin: 0 0 16px;
  font-size: 0.9375rem;
}
.sup-facts dt {
  color: var(--text-muted);
  font-weight: 600;
}
.sup-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}
.sup-words {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font: inherit;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 10px 12px;
}
.sup-from {
  margin: 0 0 16px;
  overflow-wrap: anywhere;
}
.sup-from p {
  margin: 4px 0 0;
}
.sup-thread .msg-compose label {
  font-size: 0.8125rem;
  font-weight: 600;
}
.bl-talk {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  margin: 0 0 14px;
  max-width: 760px;
  overflow-wrap: anywhere;
}
.bl-talk h2 {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 4px;
}
.bl-day-talk {
  margin: 0 0 10px;
}
.bl-talk-fold {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 8px 12px;
  margin: 0 0 8px;
  overflow-wrap: anywhere;
}
.bl-talk-fold > summary {
  cursor: pointer;
  font-weight: 600;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}
.bl-talk-fold > summary a {
  font-weight: 400;
  font-size: 0.875rem;
}
@media (max-width: 480px) {
  .sup-facts {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }
  .sup-facts dd {
    margin: 0 0 8px;
  }
}
