/* ============================================================================
 * SurgeNode v2 :: sn-clientarea.css
 *
 * Everything a customer sees after they have paid: the dashboard, the services
 * and invoices lists, product details, the account pages, and the invoice
 * document itself.
 *
 * Written as styling rather than as forked markup. With `config: parent: nexus`
 * every template in this area already resolves, and the pages are built from
 * objects that hooks can extend ($panels on the dashboard) or from DataTables
 * whose JavaScript addresses columns by index (the services and invoices
 * lists). Forking those templates would freeze a menu graph and a column order
 * that are not ours to freeze, for no visual gain. One template is overridden,
 * viewinvoice.tpl, and only because it is a standalone HTML document that has
 * to opt into the theme's stylesheets explicitly.
 *
 * Load order: sn-tokens.css, then sn-nexus-bridge.css, then this file, then
 * custom.css. Tokens are frozen; nothing here redeclares one at :root.
 *
 * The `body` ancestor prefix appears throughout for the reason sn-tokens.css
 * documents: it lifts a bare class from (0,1,0) to (0,1,1) and beats nexus's
 * light theme.min.css without reaching for !important. Where !important does
 * appear it is beating a Bootstrap utility that is itself !important, and it
 * says so at the point of use.
 * ==========================================================================*/


/* ---------------------------------------------------------------------------
 * 1. Page furniture.
 * ------------------------------------------------------------------------ */

body #main-body > .container,
body #main-body > .container-fluid { padding-bottom: 8px; }

/* WHMCS emits the page heading as an h1 followed by the breadcrumb. */
body #main-body h1.h1,
body #main-body > .container > h1:first-child { margin: 0 0 18px; }

body .card + .card,
body .client-home-cards .card { margin-bottom: 18px; }


/* ---------------------------------------------------------------------------
 * 2. Dashboard tiles.
 *
 * nexus renders four counters in a `.row.no-gutters` strip: a light grey slab
 * per tile, a 55px watermark icon, a 40px number, an uppercase caption and a
 * 2px `.highlight` bar whose colour comes from a `.bg-color-*` class.
 *
 * Kept as four tiles, rebuilt as four separate flat cards. The strip is split
 * into cards by padding the grid columns rather than by touching the markup,
 * so the WHMCS column classes and the conditional second tile (domains, or
 * affiliates, or quotes, depending on what the install sells) are untouched.
 * ------------------------------------------------------------------------ */

body .tiles { margin: 0 -5px 24px; }
body .tiles [class*="col-"] { padding: 5px; }

body .tiles .tile {
  position: relative;
  display: block;
  overflow: hidden;
  height: 100%;
  padding: 16px 18px;
  background: var(--ink-850);
  border: 1px solid var(--line);
  border-right: 1px solid var(--line);   /* nexus sets only border-right */
  border-radius: var(--r-md);
  color: var(--ink-200);
  text-decoration: none;
  transition: border-color .15s ease, background-color .15s ease;
}

body .tiles .tile:hover {
  background: var(--ink-800);
  border-color: var(--line-strong);
  cursor: pointer;
}

/* The watermark. nexus parks it top right at 55px in #ccc, which on a dark
   ground would be a bright blob, so it drops back to a hairline tint and the
   accent only arrives on hover. */
body .tiles .tile i {
  position: absolute;
  top: 50%;
  right: 16px;
  transform: translateY(-50%);
  font-size: 40px;
  line-height: 1;
  color: var(--ink-100);
  opacity: .06;
  transition: opacity .15s ease, color .15s ease;
}

body .tiles .tile:hover i { color: var(--cobalt); opacity: .18; }

body .tiles .tile .stat {
  margin-top: 0;
  font-family: var(--stat);
  font-size: 34px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--ink-100);
  font-variant-numeric: tabular-nums;
}

body .tiles .tile .title {
  margin-top: 2px;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-400);
}

/* The accent bar. nexus colours it through .bg-color-<name>; those names are
   repainted in section 3 so this only has to set the shape. */
body .tiles .tile .highlight {
  margin-top: 12px;
  width: 26px;
  height: 2px;
  border-radius: var(--r-pill);
  transition: width .2s var(--sn-ease);
}

body .tiles .tile:hover .highlight { width: 44px; }


/* ---------------------------------------------------------------------------
 * 3. nexus colour-name classes.
 *
 * bg-color-* and card-accent-* are nexus's palette-by-name helpers: 19 and 21
 * names respectively, a whole flat-UI palette. The dashboard tiles use four of
 * them, and a home panel takes whichever name a module or a hook asks for.
 * This install is live proof the long tail is real: the dashboard renders a
 * card-accent-asbestos panel that no template in this theme mentions.
 *
 * NOT repainted name by name, deliberately. All 40 of those rules are already
 * written as var(--info), var(--success), var(--yellow-300), var(--pink-400),
 * var(--notice) and so on, which are exactly the names sn-nexus-bridge.css
 * repairs. Fixing the bridge colours all 40 at once, on brand, and keeps them
 * consistent with every other component that reads the same variables.
 *
 * It is also why these were worth checking rather than assuming. Without the
 * bridge they do not fall back to a nexus colour, they fall back to nothing,
 * and `border-top: 3px solid <invalid>` draws no rule at all: all 21 panel
 * accents were silently missing their top border.
 *
 * So only the shape is set here. The attribute selector covers every name,
 * including the ones this theme has never heard of.
 * ------------------------------------------------------------------------ */

body [class*="card-accent-"] {
  border-top-width: 2px;   /* nexus draws 3px */
  border-top-style: solid;
  overflow: hidden;        /* clip the rule to the card radius */
}

/* nexus's includes/panel.tpl builds its heading as
   `card-title py-1 px-2 text-white font-weight-bold bg-<type>`, so the heading
   is a solid contextual fill with hard coded white text. Solid fills are not
   this design's language and white on amber is illegible, so the fills become
   tinted bars with a matching hairline and the text takes the accent colour.
   .text-white has to be beaten: Bootstrap sets it !important. */
body .card > .card-title[class*="bg-"] {
  margin: 0;
  padding: 10px 14px !important;
  border-bottom: 1px solid var(--line);
  border-radius: calc(var(--r-md) - 1px) calc(var(--r-md) - 1px) 0 0;
  font-family: var(--display);
  font-size: 13.5px;
  letter-spacing: -0.01em;
}

body .card > .card-title.bg-info,
body .card > .card-title.bg-primary { background: var(--cobalt-dim) !important; color: var(--cobalt) !important; }
body .card > .card-title.bg-success { background: var(--mint-dim)   !important; color: var(--mint)   !important; }
body .card > .card-title.bg-warning { background: var(--amber-dim)  !important; color: var(--amber)  !important; }
body .card > .card-title.bg-danger  { background: rgba(255,77,109,.14) !important; color: var(--danger) !important; }

/* Same problem on the "apply credit" heading in the invoice document. */
body .card-header.bg-success { background: var(--mint-dim) !important; border-bottom-color: var(--line); }
body .card-header.bg-success .card-subtitle,
body .card-header.bg-success.text-white { color: var(--mint) !important; }


/* ---------------------------------------------------------------------------
 * 4. Status pills.
 *
 * Shared surface: the services list, the invoices list, the addons table on
 * product details and the services item partial all render status through
 * `.label`.
 *
 * nexus fills the pill solid and sets `color: #fff`. Two problems. White on
 * amber fails contrast, and half the fills come from variables that this theme
 * shadows, which is the defect sn-nexus-bridge.css exists to fix. Rebuilt as a
 * tinted pill with a hairline and coloured text, which is legible on every
 * status and does not depend on the fill surviving.
 *
 * One local variable, --st, carries the status colour so each state below is a
 * single declaration.
 * ------------------------------------------------------------------------ */

/* Geometry and type follow the site's .pill-status, which is the same object:
   a small tinted state badge. It resolves to border-radius var(--r-chip) (6px),
   font-size 12px, letter-spacing 0.01em, padding 3px 8px at globals.css's final
   generation. It is NOT a 999px capsule: --r-pill has exactly one consumer on
   the whole site, the nav CTA at nav.tsx:689, and the only other 999px shapes
   are circular avatars. Capsule status chips are not part of this design. */
body .label,
body .label.status {
  --st: var(--ink-400);
  display: inline-block;
  max-width: 100%;
  margin-bottom: 0;
  padding: 3px 8px;
  border: 1px solid color-mix(in srgb, var(--st) 42%, transparent);
  border-radius: var(--r-chip);
  background: color-mix(in srgb, var(--st) 16%, transparent);
  color: var(--st);
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.01em;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
}

/* Live and healthy. */
body .label.status-active,
body .label.status-completed,
body .label.status-open,
body .label.status-paid,
body .label.status-answered,
body .label.label-success   { --st: var(--mint); }

/* Waiting on someone. */
body .label.status-pending,
body .label.status-pending-transfer,
body .label.status-suspended,
body .label.status-customer-reply,
body .label.status-payment-pending,
body .label.status-refunded,
body .label.status-collections,
body .label.status-onhold,
body .label.label-warning   { --st: var(--amber); }

/* Needs money or attention. */
body .label.status-unpaid,
body .label.status-overdue,
body .label.status-fraud,
body .label.status-terminated,
body .label.label-danger    { --st: var(--danger); }

/* Informational. */
body .label.status-inprogress,
body .label.label-info      { --st: var(--cobalt); }

/* Retired. */
body .label.status-cancelled,
body .label.status-closed,
body .label.status-expired,
body .label.status-draft,
body .label.label-default   { --st: var(--ink-400); }

/* nexus renders a shimmering placeholder while the services partial loads. */
body .label.label-placeholder {
  background: var(--ink-800);
  border-color: var(--line-soft);
  color: transparent;
  min-width: 62px;
}


/* ---------------------------------------------------------------------------
 * 5. DataTables list chrome.
 *
 * Shared surface: the services list and the invoices list, and any other page
 * that includes includes/tablelist.tpl.
 *
 * The DataTables `dom` string is `<"listtable"fit>pl`, so the filter box, the
 * info line, the table, the pager and the length menu are all siblings in that
 * order. Styling only; the column indices the page JavaScript sorts and
 * filters on are untouched.
 * ------------------------------------------------------------------------ */

body .table-container { position: relative; }

body .dataTables_wrapper table.table-list {
  margin: 0 0 14px !important;      /* nexus sets margin with !important */
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  border-collapse: separate;
  border-spacing: 0;
  overflow: hidden;
  background: var(--ink-850);
}

body .dataTables_wrapper table.table-list thead th {
  background: var(--ink-800);
  border-bottom: 1px solid var(--line);   /* nexus: 4px solid rgba(29,57,101,.2) */
  color: var(--ink-400);
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 11px 14px;
  white-space: nowrap;
}

body .dataTables_wrapper table.table-list tbody td {
  border-top: 1px solid var(--line-soft);
  color: var(--ink-200);
  font-size: 13.5px;
  padding: 12px 14px;
  vertical-align: middle;
}

body .dataTables_wrapper table.table-list tbody tr:first-child td { border-top: 0; }

/* Every row in these two lists carries an onclick that navigates. Make that
   discoverable rather than a surprise. */
body .dataTables_wrapper table.table-list tbody tr[onclick] { cursor: pointer; }
body .dataTables_wrapper table.table-list tbody tr[onclick]:hover td {
  background: var(--ink-800);
  color: var(--ink-100);
}

body .dataTables_wrapper table.table-list tbody tr td strong { color: var(--ink-100); font-weight: 600; }

/* Sort affordances. */
body table.table-list thead th.sorting,
body table.table-list thead th.sorting_asc,
body table.table-list thead th.sorting_desc { cursor: pointer; }
body table.table-list thead th.sorting_asc,
body table.table-list thead th.sorting_desc { color: var(--ink-100); }

/* Filter box, pager, length menu, info line. */
body .dataTables_filter { float: right; margin-bottom: 12px; }
body .dataTables_filter input {
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  color: var(--ink-100);
  font-size: 13.5px;
  padding: 7px 11px;
  min-width: 210px;
}
body .dataTables_filter input:focus { border-color: var(--cobalt); box-shadow: var(--shadow-accent); outline: none; }
body .dataTables_filter input::placeholder { color: var(--ink-400); }

body .dataTables_info { color: var(--ink-400); font-size: 12.5px; padding-top: 8px; }

body .dataTables_length,
body .dataTables_length label { color: var(--ink-400); font-size: 12.5px; }
body .dataTables_length select {
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  color: var(--ink-100);
  padding: 4px 8px;
  margin: 0 6px;
}
body .dataTables_length select option { background: var(--ink-800); color: var(--ink-100); }

body .dataTables_paginate { padding-top: 6px; }
body .dataTables_paginate .paginate_button {
  display: inline-block;
  padding: 6px 11px;
  margin-left: 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  background: var(--ink-850);
  color: var(--ink-200) !important;   /* DataTables sets colour !important */
  font-size: 13px;
  cursor: pointer;
}
body .dataTables_paginate .paginate_button:hover {
  background: var(--ink-800);
  border-color: var(--line-strong);
  color: var(--ink-100) !important;
}
body .dataTables_paginate .paginate_button.current,
body .dataTables_paginate .paginate_button.current:hover {
  background: var(--cobalt);
  border-color: var(--cobalt);
  color: var(--ink-on-accent) !important;
}
body .dataTables_paginate .paginate_button.disabled,
body .dataTables_paginate .paginate_button.disabled:hover {
  background: transparent;
  border-color: var(--line-soft);
  color: var(--ink-500) !important;
  cursor: default;
}

/* The "no records" row, and the spinner shown before DataTables initialises. */
body .dataTables_empty { color: var(--ink-400); padding: 26px 14px !important; text-align: center; }
body #tableLoading p { color: var(--ink-400); font-size: 13.5px; padding: 20px 0; }

/* View filter buttons, the sidebar radio list that drives column filtering. */
body .view-filter-btns .list-group-item.active { color: var(--ink-100); }
body .view-filter-btns i.far { color: var(--cobalt); }


/* ---------------------------------------------------------------------------
 * 6. Active services partial.
 *
 * includes/active-products-services-item.tpl, the row the dashboard panel and
 * the services sidebar render for each service.
 * ------------------------------------------------------------------------ */

body .div-service-item {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  padding: 2px 0;
}

body .div-service-name { min-width: 0; flex: 1 1 auto; color: var(--ink-100); font-weight: 600; }
body .div-service-name .text-domain { display: block; color: var(--ink-400); font-size: 12.5px; font-weight: 400; }
body .div-service-status { flex: 0 0 auto; }
body .div-service-buttons { flex: 0 0 auto; }

body .btn-group-primary .btn,
body .btn-group-secondary .btn { font-size: 12.5px; }

/* Bootstrap 4 drops .caret; nexus still emits it. Give it a shape so the
   dropdown toggle does not render a stray empty span. */
body .caret {
  display: inline-block;
  width: 0; height: 0;
  margin-left: 4px;
  vertical-align: middle;
  border-top: 4px dashed;
  border-right: 4px solid transparent;
  border-left: 4px solid transparent;
}


/* ---------------------------------------------------------------------------
 * 7. Product details.
 *
 * clientareaproductdetails.tpl. The page is a tab strip over a panel, with a
 * left rail carrying the product icon, the status block and the action
 * buttons.
 * ------------------------------------------------------------------------ */

body .product-details .product-icon i { color: var(--cobalt); }
body .product-details .product-icon .fa-stack .fa-circle { color: var(--ink-800); }

/* nexus fills the status block solid and prints uppercase white on top of it.
   Same treatment as the status pills: tinted block, coloured text. The colours
   are hard coded hex upstream rather than variables, so each one is restated. */
body .product-status {
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--ink-800);
}

body .product-status .product-status-text {
  padding: 9px 8px;
  color: var(--ink-100);
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
}

body .product-status-active     { background: var(--mint-dim);   border-color: color-mix(in srgb, var(--mint) 42%, transparent); }
body .product-status-active .product-status-text     { color: var(--mint); }
body .product-status-pending    { background: var(--amber-dim);  border-color: color-mix(in srgb, var(--amber) 42%, transparent); }
body .product-status-pending .product-status-text    { color: var(--amber); }
body .product-status-suspended  { background: var(--amber-dim);  border-color: color-mix(in srgb, var(--amber) 42%, transparent); }
body .product-status-suspended .product-status-text  { color: var(--amber); }
body .product-status-cancelled,
body .product-status-terminated { background: var(--ink-800);    border-color: var(--line); }
body .product-status-cancelled .product-status-text,
body .product-status-terminated .product-status-text { color: var(--ink-400); }
body .product-status-fraud      { background: rgba(255,77,109,.14); border-color: color-mix(in srgb, var(--danger) 42%, transparent); }
body .product-status-fraud .product-status-text      { color: var(--danger); }

/* Tabs. The panel below the strip carries Bootstrap's .bg-white utility AND
   nexus sets background-color:#fff on .product-details-tab-container, so this
   is one of the places !important is unavoidable: .bg-white is
   `background-color:#fff!important` and cannot be outranked by specificity.
   Overriding the template instead would mean forking 30 KB of module, addon
   and metric logic to delete one class, which is the worse trade. */
body .tab-content.product-details-tab-container,
body .product-details-tab-container.bg-white {
  background: var(--ink-850) !important;
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 var(--r-md) var(--r-md);
  padding: 22px;
}

body .nav-tabs.responsive-tabs-sm { border-bottom: 1px solid var(--line); margin-bottom: 0; }
body .responsive-tabs-sm-connector { border-color: var(--line); }

body .bottom-border { border-bottom: 1px solid var(--line-soft); padding-bottom: 12px; margin-bottom: 12px; }

/* Usage meters. nexus paints each segment white with a #ddd divider, which is
   a white bar on a dark card. Inverted to a filled track. */
body .dial-usage { color: var(--ink-100); }
body .channel {
  float: left;
  width: 6px;
  height: 5px;
  background: var(--ink-700);
  border-right: 1px solid var(--ink-850);
  border-left: 1px solid var(--ink-850);
}
body .channel.active,
body .channel.used { background: var(--cobalt); }

/* Metric bars WHMCS renders for disk and bandwidth. */
body .product-details .progress { background: var(--ink-700); height: 8px; }
body .product-details .progress-bar { background: var(--cobalt); }


/* ---------------------------------------------------------------------------
 * 8. Account pages.
 *
 * clientareadetails.tpl, account-paymentmethods*.tpl, account-contacts-*.tpl,
 * account-user-*.tpl, clientareaaddfunds.tpl, clientareacancelrequest.tpl.
 *
 * These are Bootstrap forms and tables, which sn-tokens.css already repaints,
 * so this section is only the parts nexus styles itself.
 * ------------------------------------------------------------------------ */

/* Legacy helper classes nexus still emits. */
body .textright { text-align: right; }
body .fullwidth { width: 100%; }
body .form-stacked .form-group { margin-bottom: 16px; }

body .form-group > label { display: block; margin-bottom: 5px; }
body .card-body > .row > [class*="col-"] > .form-group:last-child { margin-bottom: 0; }

/* The toggle used for marketing opt in on clientareadetails. */
body .toggle-switch-success.form-check-input:checked { background-color: var(--mint); border-color: var(--mint); }
body .no-icheck { accent-color: var(--cobalt); }
body .form-check-input { accent-color: var(--cobalt); }

/* Payment methods: a table of stored cards and bank accounts, each row with a
   set-default / edit / delete button group, plus confirm modals. The striping
   itself is already handled by sn-tokens.css and is not repeated here. */
body .btn-set-default,
body .btn-delete { min-width: 34px; }
body .btn-delete:hover { background: var(--danger); border-color: var(--danger); color: #1d0703; }
body .btn.disabled,
body .btn:disabled { opacity: var(--disabled-opacity); }

/* The card art / brand icon column. */
body .payment-method-icon,
body td > i.fab,
body td > i.fas.fa-credit-card { color: var(--ink-300); font-size: 18px; }

/* Add funds: the amount field is the only thing on the page, so give it room. */
body #frmAddFunds .form-control { font-size: 16px; }

/* Cancellation request: a destructive form. The warning stays loud. */
body .alert-warning + .card { border-color: color-mix(in srgb, var(--amber) 30%, var(--line)); }


/* ---------------------------------------------------------------------------
 * 9. The invoice document.
 *
 * DELIBERATE VISUAL BREAK, and the only one in this theme.
 *
 * viewinvoice.php is a standalone HTML document, not a client area page: it
 * has its own <head>, it does not include header.tpl or footer.tpl, and it
 * loads invoice.min.css instead of the client area chrome. It is also the page
 * customers print and the page they forward to whoever pays their bills.
 *
 * A dark invoice is unusable on paper. It burns ink, and most browsers drop
 * background colours when printing, which turns light-on-dark text into
 * near-white text on white. So the page chrome is dark and the invoice
 * document itself stays light.
 *
 * HOW THE LIGHT ISLAND WORKS
 *
 * Not by re-styling components. `.invoice-container` reassigns the ink ramp
 * and the hairline tokens to light values, and every rule downstream of them
 * relights itself: sn-tokens.css paints `body .card`, `body .table`,
 * `body .form-control` and the rest through var(--ink-*), so they follow. This
 * is the same mechanism the .theme-<game> scopes in sn-tokens.css use, applied
 * to the whole ramp instead of one accent.
 *
 * THE ONE TRAP, worth stating because it is silent and it bites hard:
 * a custom property is computed where it is DECLARED. Inside this block
 * `--ink-100: var(--ink-900)` would not give dark text, it would resolve
 * against the remapped --ink-900 on the same element and come back white.
 * So every value below references the --color-slate-* scale, which this block
 * does NOT remap, and never the --ink-* names it is redefining.
 *
 * The nexus bridge variables are redeclared here for the same reason: they
 * were computed at :root against the dark ramp and inherit that value, so they
 * do not re-resolve on their own. invoice.min.css makes 30 references to them.
 * ------------------------------------------------------------------------ */

body .invoice-container {

  /* Surfaces, lightest first. */
  --ink-900: var(--color-slate-50);    /* #ffffff  the paper */
  --ink-850: var(--color-slate-50);    /* #ffffff  cards on the paper */
  --ink-800: var(--color-slate-100);   /* #f5f5f5  table heads, totals */
  --ink-750: var(--color-slate-100);
  --ink-700: var(--color-slate-200);
  --ink-600: var(--color-slate-300);

  /* Text, lightest to darkest. --ink-400 is the muted step; on white it is
     deliberately taken darker than a literal inversion would put it, because
     the palette's mid grey (#8f8f8f) is 3.4:1 on white and this is a document
     someone has to read a total off. Flagged in the handover as the one gap:
     there is no mid grey that passes AA on white. */
  --ink-500: var(--color-slate-400);
  --ink-400: var(--color-slate-600);   /* #2a2a2a */
  --ink-300: var(--color-slate-700);
  --ink-200: var(--color-slate-800);   /* #111111  body copy */
  --ink-100: var(--color-slate-950);   /* #050505  headings */

  /* Hairlines. The dark theme's lines are white at 14 / 8 / 22 percent, so the
     light ones are the same percentages of the near black, derived rather than
     invented. */
  --line:        color-mix(in srgb, var(--color-slate-950) 14%, transparent);
  --line-soft:   color-mix(in srgb, var(--color-slate-950)  8%, transparent);
  --line-strong: color-mix(in srgb, var(--color-slate-950) 22%, transparent);

  /* nexus bridge names, relit. */
  --bg:            var(--color-slate-50);
  --bg-muted:      var(--color-slate-50);
  --bg-lifted:     var(--color-slate-100);
  --bg-accented:   var(--color-slate-200);
  --bg-inverted:   var(--color-slate-950);
  --text:          var(--color-slate-950);
  --text-accented: var(--color-slate-800);
  --text-lifted:   var(--color-slate-700);
  --text-muted:    var(--color-slate-600);
  --text-inverted: var(--color-slate-50);
  --grayscale:          var(--color-slate-950);
  --grayscale-lifted:   var(--color-slate-800);
  --grayscale-accented: var(--color-slate-700);
  --border:          color-mix(in srgb, var(--color-slate-950) 14%, transparent);
  --border-muted:    color-mix(in srgb, var(--color-slate-950)  8%, transparent);
  --border-lifted:   color-mix(in srgb, var(--color-slate-950) 22%, transparent);
  --border-accented: color-mix(in srgb, var(--color-slate-950) 22%, transparent);

  /* The sheet itself. */
  position: relative;
  z-index: 1;
  max-width: 900px;
  margin: 0 auto;
  padding: 56px 56px 44px;
  background: var(--color-slate-50);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  color: var(--color-slate-800);
  font-family: var(--sans);
}

body .invoice-container h2,
body .invoice-container h3 { font-family: var(--display); color: var(--color-slate-950); }
body .invoice-container h3 { font-size: 18px; }
body .invoice-container p,
body .invoice-container address,
body .invoice-container td,
body .invoice-container th { color: var(--color-slate-800); }
body .invoice-container strong { color: var(--color-slate-950); }
body .invoice-container hr { border-top: 1px solid var(--line); }
body .invoice-container a { color: var(--cobalt-lo); }
body .invoice-container .small-text { color: var(--color-slate-600); font-size: 12.5px; }
body .invoice-container address { font-style: normal; line-height: 1.65; }

/* Amounts read as figures, not prose. */
body .invoice-container .table td:last-child,
body .invoice-container td.total-row { font-variant-numeric: tabular-nums; }
body .invoice-container td.total-row { background: var(--color-slate-100); border-top: 1px solid var(--line); }

/* The status word, the loudest thing on the sheet. */
body .invoice-container .invoice-status {
  margin: 16px 0 0;
  font-family: var(--display);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
body .invoice-container .invoice-status .paid      { color: var(--mint); }
body .invoice-container .invoice-status .unpaid    { color: var(--danger); }
body .invoice-container .invoice-status .draft,
body .invoice-container .invoice-status .cancelled { color: var(--color-slate-600); }
body .invoice-container .invoice-status .refunded,
body .invoice-container .invoice-status .collections { color: var(--amber); }

body .invoice-container .card {
  background: var(--color-slate-50);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
body .invoice-container .card-header { background: var(--color-slate-100); border-bottom: 1px solid var(--line); }
body .invoice-container .table th,
body .invoice-container .table thead td { color: var(--color-slate-600); }

/* The dark chrome the sheet sits on. The invoice document has no #main-body,
   so the page level rules in sn-tokens.css do not reach it and the shell is
   set up here. */
body.sn-invoice-page {
  background: var(--ink-900);
  padding: 0 16px 40px;
}

body.sn-invoice-page > p { position: relative; z-index: 1; }
body.sn-invoice-page > p a { color: var(--ink-300); font-size: 13px; }
body.sn-invoice-page > p a:hover { color: var(--cobalt); }

/* Slim brand bar above the sheet, so a forwarded invoice still says who sent
   it before the paper starts. */
.sn-invoice-topbar {
  position: relative;
  z-index: 1;
  max-width: 900px;
  margin: 0 auto;
  padding: 22px 4px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.sn-invoice-topbar .sn-brand-name { font-family: var(--brand); font-weight: 800; font-size: 17px; color: var(--ink-100); }
.sn-invoice-topbar .sn-brand-name span { color: var(--cobalt); }
.sn-invoice-topbar .sn-invoice-ref { font-family: var(--mono); font-size: 12px; color: var(--ink-400); }

@media (max-width: 700px) {
  body .invoice-container { padding: 28px 20px 24px; border-radius: var(--r-md); }
  .sn-invoice-topbar { padding: 16px 4px 12px; }
}


/* ---------------------------------------------------------------------------
 * 10. Print.
 *
 * The reason the invoice is light in the first place, so it is worth getting
 * right rather than leaving to the browser. Everything that is chrome goes
 * away and the sheet becomes the page.
 * ------------------------------------------------------------------------ */

@media print {
  html, body,
  body.sn-invoice-page {
    background: #ffffff !important;
    color: #000000 !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  .sn-page-grid,
  .sn-invoice-topbar,
  body.sn-invoice-page > p,
  .payment-btn-container,
  .d-print-none { display: none !important; }

  body .invoice-container {
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: #ffffff !important;
  }

  /* Keep the ledger and line item tables from splitting mid row. */
  body .invoice-container table { page-break-inside: auto; }
  body .invoice-container tr { page-break-inside: avoid; page-break-after: auto; }

  body .invoice-container .card { border: 1px solid #cccccc !important; }
  body .invoice-container td.total-row { background: #f5f5f5 !important; }

  /* Print the link target for anything that survives onto paper. */
  body .invoice-container a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 10px;
    color: #555555;
  }
}
