/* ============================================================
   bibloc admin · design system
   Primary olive/sage #8fb450 with harmonized supporting tones
   ============================================================ */

:root{
  /* olive ramp */
  --olive-50:#f4f8ea;
  --olive-100:#e8f0d6;
  --olive-200:#d5e3b8;
  --olive-300:#bcd393;
  --olive-400:#a3c26e;
  --olive-500:#8fb450;
  --olive-600:#7fa03f;
  --olive-700:#6a8a33;
  --olive-800:#57702a;
  --olive-900:#465a22;

  /* neutrals */
  --bg:#f5f7ef;
  --surface:#ffffff;
  --surface-2:#fbfcf7;
  --border:#e3e7d9;
  --border-strong:#cfd6c0;
  --text:#262e1a;
  --text-2:#5c6550;
  --text-3:#8a917c;

  /* supporting hues */
  --amber-100:#f9efd8;
  --amber-500:#d9a13e;
  --amber-700:#9a6d1d;
  --rust-100:#f7e3da;
  --rust-500:#c4674a;
  --rust-700:#a8502f;
  --blue-100:#e0ebf1;
  --blue-500:#628fa5;
  --blue-700:#476f83;
  --ink:#1f2416;

  --shadow-sm:0 1px 2px rgba(38,46,26,.06);
  --shadow-md:0 4px 12px -2px rgba(38,46,26,.08),0 2px 4px rgba(38,46,26,.04);
  --shadow-lg:0 24px 48px -12px rgba(38,46,26,.25);

  --radius-sm:8px;
  --radius:10px;
  --radius-lg:14px;
  --radius-xl:18px;

  /* component tokens (theme-aware) */
  --toolbar-bg:rgba(245,247,239,.86);
  --avatar-bg:#e8f0d6;
  --avatar-fg:#55742a;
  --draft-bg:#eef0e8;
  --toast-border:rgba(38,46,26,.1);
  --btn-grad:linear-gradient(180deg,var(--olive-600),var(--olive-700));
  --btn-grad-hover:linear-gradient(180deg,var(--olive-700),var(--olive-800));
  --brand-grad:linear-gradient(135deg,var(--olive-400),var(--olive-700));
}
html{color-scheme:light}

/* ---------- reset & base ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  font-family:'Inter',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  font-size:14px;line-height:1.5;color:var(--text);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
  transition:background-color .2s ease,color .2s ease;
}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:none}
a{color:inherit;text-decoration:none}
ul{list-style:none}
[hidden]{display:none!important}
svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
::selection{background:var(--olive-200)}
:focus-visible{outline:2px solid var(--olive-600);outline-offset:2px;border-radius:4px}
/* left/top anchor the box so it can never stretch the page's scrollable area
   (absolute boxes escape overflow clipping of non-positioned ancestors) */
.visually-hidden{position:absolute;left:0;top:0;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:99px;border:3px solid var(--surface)}
::-webkit-scrollbar-thumb:hover{background:var(--olive-300)}

/* ---------- app layout ---------- */
.app{display:grid;grid-template-columns:248px 1fr;min-height:100dvh}

/* ---------- sidebar ---------- */
.sidebar{
  position:sticky;top:0;height:100dvh;display:flex;flex-direction:column;
  background:var(--surface-2);border-right:1px solid var(--border);
  padding:20px 14px 16px;gap:22px;
  /* sticky creates a stacking context (z:auto traps the dropdown's z-index:
     the main column's positioned tables would paint over the open menu).
     Raising the sidebar keeps sidebar dropdowns above view content, yet
     below overlays (60/65), the mobile drawer (70) and toasts (80). */
  z-index:45;
}
/* sidebar top row — brand plus the search/notifications icons that replace the toolbar on non-dashboard views */
.sidebar-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.sidebar-quick-actions{position:relative;display:flex;align-items:center;gap:4px;flex-shrink:0}
.brand{display:flex;align-items:center;gap:10px;padding:2px 8px}
/* brand lockup — see templates/_brand.html.twig. Only one variant is ever visible:
   the light logo on light surfaces, its white-wordmark twin once data-theme="dark",
   and the icon-only mark inside the collapsed rail (whose rule outranks these).
   :where() keeps the theme switch at zero specificity so the rail never has to
   out-specify or !important-over it. */
.brand-logo{display:block;flex-shrink:0}
.brand-logo-dark,.brand-logo-rail{display:none}
:where(html[data-theme="dark"]) .brand-logo-light{display:none}
:where(html[data-theme="dark"]) .brand-logo-dark{display:block}
.brand-badge{
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  background:var(--olive-100);color:var(--olive-800);
  padding:3px 7px;border-radius:999px;
}
/* company switcher — sits between the logo and the nav */
.co-switch{display:flex;align-items:center;gap:8px;padding:0 8px;margin:-13px 0 -6px}
.co-chip{
  width:28px;height:28px;border-radius:9px;display:grid;place-items:center;flex-shrink:0;
  font-size:10.5px;font-weight:800;letter-spacing:.02em;user-select:none;
}
.co-field{position:relative;flex:1;min-width:0}
.co-select{
  display:block;width:100%;appearance:none;-webkit-appearance:none;-moz-appearance:none;
  font-size:12.5px;font-weight:600;color:var(--text);
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:7px 26px 7px 9px;cursor:pointer;
  text-overflow:ellipsis;white-space:nowrap;overflow:hidden;
  transition:border-color .15s,background .15s;
}
.co-select:hover{border-color:var(--olive-300)}
.co-chev{
  position:absolute;right:7px;top:50%;transform:translateY(-50%);
  width:14px;height:14px;color:var(--text-3);pointer-events:none;
}
.nav{display:flex;flex-direction:column;gap:3px;flex:1}
.nav-label{
  font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.09em;
  color:var(--text-3);padding:0 10px;margin:10px 0 5px;
}
.nav-label:first-child{margin-top:0}
.nav-item{
  display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--radius);
  color:var(--text-2);font-weight:500;font-size:13.5px;position:relative;
  transition:background .15s,color .15s;
}
.nav-item svg{color:var(--text-3);transition:color .15s}
.nav-item:hover{background:var(--olive-50);color:var(--text)}
.nav-item:hover svg{color:var(--olive-700)}
.nav-item.active{background:var(--olive-100);color:var(--olive-900);font-weight:600}
.nav-item.active svg{color:var(--olive-700)}
.nav-item.active::before{
  content:"";position:absolute;left:-14px;top:8px;bottom:8px;width:3px;
  border-radius:0 3px 3px 0;background:var(--olive-500);
}
.nav-badge{
  margin-left:auto;font-size:11px;font-weight:700;
  background:var(--olive-500);color:#fff;padding:1px 7px;border-radius:999px;
}
/* hide the sidebar badge entirely when its count is zero */
.nav-badge[data-count="0"], .nav-badge[data-count=""]{display:none}
/* sidebar user block — bottom of the sidebar, menu opens upward */
.sidebar-user{
  margin-top:auto;position:relative;
  display:flex;flex-direction:column;gap:10px;
  padding-top:14px;border-top:1px solid var(--border);
}
.sidebar-version{
  text-align:center;
  font-size:10.5px;color:var(--text-3);
}
.sidebar-user .user-btn{width:100%;padding:6px 8px}
.ub-meta{display:flex;flex-direction:column;min-width:0;flex:1;line-height:1.25;text-align:left}
.ub-name{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ub-mail{font-size:11px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* close button — only shown when the sidebar floats as a mobile drawer */
.sidebar-close{
  display:none;position:absolute;top:18px;right:12px;z-index:2;
  width:32px;height:32px;border-radius:var(--radius-sm);
  align-items:center;justify-content:center;
  border:1px solid var(--border);background:var(--surface);
  color:var(--text-2);cursor:pointer;flex-shrink:0;
  transition:background .15s,color .15s,border-color .15s;
}
.sidebar-close svg{width:16px;height:16px}
.sidebar-close:hover{background:var(--olive-100);color:var(--olive-800);border-color:var(--olive-300)}
.sidebar-close:focus-visible{outline:2px solid var(--olive-500);outline-offset:2px}

/* ---------- avatars ---------- */
.avatar{
  width:32px;height:32px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:700;letter-spacing:.02em;flex-shrink:0;user-select:none;
}
.avatar-lg{width:52px;height:52px;font-size:16px;border-radius:16px}

/* ---------- main ---------- */
.main{padding:26px 30px 40px;min-width:0}
.main > .toolbar { margin-top:-15px; padding-top:0; }
.topbar{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:22px}
.topbar-heading h1{font-size:22px;font-weight:800;letter-spacing:-.02em}
.topbar-heading p{font-size:13px;color:var(--text-3);margin-top:2px}
.topbar-actions{display:flex;gap:10px}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:8px;
  font-size:13.5px;font-weight:600;padding:9px 14px;border-radius:var(--radius);
  border:1px solid transparent;transition:background .15s,border-color .15s,box-shadow .15s,transform .05s;
  white-space:nowrap;
}
.btn:active{transform:translateY(1px)}
.btn-primary{
  background:var(--btn-grad);
  color:#fff;box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 1px 2px rgba(87,112,42,.35);
}
.btn-primary:hover{background:var(--btn-grad-hover)}
.btn-ghost{background:var(--surface);border-color:var(--border);color:var(--text-2)}
.btn-ghost:hover{border-color:var(--olive-300);background:var(--olive-50);color:var(--olive-900)}
.btn-block{width:100%;justify-content:center}
.icon-btn{
  width:30px;height:30px;border-radius:var(--radius-sm);display:inline-flex;align-items:center;justify-content:center;
  color:var(--text-3);transition:background .15s,color .15s;flex-shrink:0;
}
.icon-btn:hover{background:var(--olive-100);color:var(--olive-800)}
.link-btn{align-self:flex-start;font-size:12.5px;font-weight:600;color:var(--olive-700);padding:2px 0}
.link-btn:hover{color:var(--olive-900);text-decoration:underline}

/* ---------- KPI cards ---------- */
.period-bar{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:14px}
.period-nav{display:flex;align-items:center;gap:8px}
.period-label{font-size:13px;font-weight:700;color:var(--text);min-width:96px;text-align:center}
.kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;margin-bottom:18px}
.kpi{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:16px;display:flex;flex-direction:column;gap:9px;box-shadow:var(--shadow-sm);min-width:0;
}
.kpi-top{display:flex;align-items:center;gap:9px}
.kpi-chip{width:34px;height:34px;border-radius:var(--radius);display:grid;place-items:center}
.kpi-chip svg{width:16px;height:16px}
.chip-olive{background:var(--olive-100);color:var(--olive-800)}
.chip-amber{background:var(--amber-100);color:var(--amber-700)}
.chip-rust{background:var(--rust-100);color:var(--rust-700)}
.kpi-label{font-size:12.5px;font-weight:600;color:var(--text-2)}
.kpi-value{font-size:23px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.kpi-warn{color:var(--rust-700)}
.kpi-foot{display:flex;align-items:center;gap:8px;margin-top:2px;flex-wrap:wrap}
.kpi-caption{font-size:11px;color:var(--text-3)}
.delta{font-size:11px;font-weight:700;padding:2px 7px;border-radius:999px;white-space:nowrap}
.delta.up{background:var(--olive-100);color:var(--olive-800)}
.delta.warn{background:var(--amber-100);color:var(--amber-700)}
.delta.danger{background:var(--rust-100);color:var(--rust-700)}
.spark{width:82px;height:28px;margin-left:auto}
.spark polyline{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.spark polygon{fill:currentColor;opacity:.12}
.spark-olive{color:var(--olive-400)}
.spark-amber{color:var(--amber-500)}
.spark-rust{color:var(--rust-500)}

/* ---------- panel & toolbar ---------- */
.panel{
  background:var(--surface);border:1px solid var(--border);border-radius:16px;
  box-shadow:var(--shadow-sm);overflow:hidden;
}
.panel.dup-group, .panel.merge-options {
    margin-bottom: 15px;
}

.merge-options .scope-group {
    padding: 10px 16px;
}
.merge-options .export-note {
    margin: 5px 16px;
}

.merge-options th {
    padding-left: 16px;
}

.panel-toolbar{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding:13px 16px;border-bottom:1px solid var(--border);
}
.tabs{
  display:flex;gap:2px;background:var(--bg);padding:3px;border-radius:var(--radius);
  overflow-x:auto;max-width:100%;scrollbar-width:none;
}
.tabs::-webkit-scrollbar{display:none}
.tab{
  border-radius:7px;padding:6px 12px;font-size:13px;font-weight:600;color:var(--text-2);
  white-space:nowrap;transition:background .15s,color .15s;
}
.tab:hover{color:var(--text)}
.tab.active{background:var(--surface);color:var(--text);box-shadow:var(--shadow-sm)}
.tab .count{margin-left:5px;font-size:11px;font-weight:600;color:var(--text-3);font-variant-numeric:tabular-nums}
.tab.active .count{color:var(--olive-700)}
.toolbar-right{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ---------- inputs ---------- */
.input{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  padding:9px 12px;font-size:13.5px;color:var(--text);width:100%;
  transition:border-color .15s,box-shadow .15s;
}
.input::placeholder{color:var(--text-3)}
.input:focus{outline:none;border-color:var(--olive-500);box-shadow:0 0 0 3px var(--olive-100)}
.input.invalid{border-color:var(--rust-500);box-shadow:0 0 0 3px var(--rust-100)}
.input-sm{padding:8px 11px;font-size:13px}
textarea.input{resize:vertical;min-height:74px;line-height:1.55}
/* Send-invoice modal: From/To share one row; Subject and Message each
   take their own full-width line, with a roomy message textarea. */
#sendInvoiceForm .grid-pair{display:grid;grid-template-columns:1.15fr 1fr;gap:12px}
#sendInvoiceForm textarea.input{min-height:180px}
/* Record-payment modal: two-column rows for amount/date and method/account. */
#recordPaymentForm .grid-pair{display:grid;grid-template-columns:1.15fr 1fr;gap:12px}
/* select inputs: drop the native chevron (appearance:none) and draw our own
   so the control reads as a dropdown at a glance. The SVG data-URI is a
   chevron-down colored to match --text-3; the right padding reserves room
   and keeps long option text from running under the icon. Background-image
   never intercepts clicks, so the click target stays the whole control. */
select.input{
  appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a917c' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 11px center;
  background-size:15px 15px;
  padding-right:34px;
}
/* the compact variant resets padding via its shorthand; keep room for the
   chevron there too, and nudge the icon inward to match the smaller control */
select.input-sm{
  background-position:right 10px center;
  padding-right:30px;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
input[type="number"]{-moz-appearance:textfield;appearance:textfield}

.search-wrap{position:relative;flex:1;min-width:200px;max-width:280px}
.search-wrap svg{position:absolute;left:10px;top:50%;transform:translateY(-50%);width:15px;height:15px;color:var(--text-3);pointer-events:none}
.search-wrap .input{padding-left:32px}
.select-inline{width:auto;min-width:128px;cursor:pointer}

/* ---------- table ---------- */
/* position:relative keeps absolutely-positioned descendants (e.g. .visually-hidden)
   inside this scroll container's clip — without it they escape and stretch the page */
.table-wrap{position:relative;overflow-x:auto}
.table{width:100%;border-collapse:collapse;min-width:720px}
.table thead th{
  text-align:left;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;
  color:var(--text-3);padding:11px 16px;border-bottom:1px solid var(--border);
  background:var(--surface-2);white-space:nowrap;
}
.table thead th.sortable{cursor:pointer;user-select:none;transition:color .15s}
.table thead th.sortable:hover{color:var(--olive-800)}
.table thead th[data-dir="asc"]::after{content:"↑";margin-left:5px;color:var(--olive-700)}
.table thead th[data-dir="desc"]::after{content:"↓";margin-left:5px;color:var(--olive-700)}
.table tbody td{padding:12px 16px;border-top:1px solid var(--border);vertical-align:middle}
.table tbody tr{transition:background .12s}
.table tbody tr:hover{background:var(--olive-50)}
.table tbody tr[data-invoice-row],.table tbody tr[data-expense-row]{cursor:pointer}
.table tbody tr:first-child td{border-top:none}
.td-id{font-weight:600;font-size:13px;font-variant-numeric:tabular-nums;white-space:nowrap}
.td-date{font-size:13px;color:var(--text-2);white-space:nowrap;font-variant-numeric:tabular-nums}
.td-amount,.th-amount{text-align:right}
.td-amount{font-weight:700;font-size:13.5px;font-variant-numeric:tabular-nums;white-space:nowrap}
.td-act,.th-act{text-align:right;width:76px}
/* keep the cell a table-cell so .table tbody td vertical-align:middle applies —
   display:flex here breaks the table model and pins the icons to the top of a
   tall row (long client/contact names wrapping at narrower widths) */
.td-act{white-space:nowrap}
.td-act .icon-btn{vertical-align:middle}
.td-act .icon-btn + .icon-btn{margin-left:4px}
/* Delete actions sit inside an inline <form>; make the form inline so the
   trash icon stays side-by-side with the edit icon instead of stacking. */
.td-act .inline-form{display:inline}
.td-act .inline-form .icon-btn{margin-left:4px}
.client-link{display:block;text-align:left;border:none;background:none;border-radius:var(--radius);padding:0;cursor:pointer;font:inherit;color:inherit;transition:background .12s}
.client-link:hover{color:var(--olive-800);text-decoration:underline}
.client-meta{display:flex;flex-direction:column;line-height:1.3;min-width:0}
.c-name{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}
.c-sub{font-size:12px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}

/* status pills */
.pill{
  display:inline-flex;align-items:center;gap:6px;
  font-size:12px;font-weight:600;padding:4px 10px;border-radius:999px;white-space:nowrap;
}
.pill .dot{width:6px;height:6px;border-radius:50%;display:inline-block}
.pill-paid{background:var(--olive-100);color:var(--olive-800)}
.pill-paid .dot{background:var(--olive-500)}
.pill-pending{background:var(--amber-100);color:var(--amber-700)}
.pill-pending .dot{background:var(--amber-500)}
.pill-overdue{background:var(--rust-100);color:var(--rust-700)}
.pill-overdue .dot{background:var(--rust-500)}
.pill-draft{background:var(--draft-bg);color:var(--text-2)}
.pill-draft .dot{background:#9aa394}

/* ---------- panel footer / pager ---------- */
.panel-footer{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:12px 16px;border-top:1px solid var(--border);background:var(--surface-2);
}
.panel-footer p{font-size:12.5px;color:var(--text-3);font-variant-numeric:tabular-nums}
.pager{display:flex;align-items:center;gap:6px}
.page-btn{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:30px;height:30px;padding:0 8px;border-radius:var(--radius-sm);
  border:1px solid var(--border);background:var(--surface);
  font-size:13px;font-weight:600;color:var(--text-2);
  transition:border-color .15s,color .15s,background .15s;
}
.page-btn:hover:not(:disabled):not([aria-disabled="true"]){border-color:var(--olive-400);color:var(--olive-800)}
.page-btn.active{background:var(--olive-100);border-color:var(--olive-300);color:var(--olive-900)}
.page-btn:disabled{opacity:.45;cursor:default}
.page-btn[aria-disabled="true"]{opacity:.45;cursor:default}
.page-indicator{font-size:12.5px;color:var(--text-3);font-variant-numeric:tabular-nums;padding:0 4px}
.page-ellipsis{align-self:center;font-size:12px;color:var(--text-3);padding:0 2px}

/* empty state */
.empty-state{padding:52px 20px;text-align:center}
.empty-state .empty-icon{
  width:52px;height:52px;border-radius:16px;background:var(--olive-50);color:var(--olive-400);
  display:grid;place-items:center;margin:0 auto 14px;
}
.empty-state .empty-icon svg{width:24px;height:24px}
.empty-state h4{font-size:14.5px;font-weight:700}
.empty-state p{font-size:13px;color:var(--text-3);margin:4px 0 14px}
@keyframes rowFlash{0%{background:var(--olive-100)}100%{background:transparent}}
tr.flash{animation:rowFlash 1.6s ease}

/* ---------- overlays ---------- */
.overlay{
  position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;
  background:rgba(31,37,20,.46);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  opacity:0;pointer-events:none;transition:opacity .18s ease;
}
.overlay.open{opacity:1;pointer-events:auto}
/* The flex display beats the UA [hidden]{display:none}, so restore it explicitly. */
#exportEmailOverlay[hidden]{display:none}
body.no-scroll{overflow:hidden}

/* mobile nav backdrop */
.app-overlay{
  position:fixed;inset:0;z-index:65;background:rgba(31,37,20,.46);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  opacity:0;pointer-events:none;transition:opacity .2s ease;
}
.app-overlay.open{opacity:1;pointer-events:auto}

/* company switch loading */
.switch-loading{
  display:flex;flex-direction:column;align-items:center;gap:14px;padding:22px 32px;
  background:var(--surface);border-radius:var(--radius-xl);box-shadow:var(--shadow-lg);
  color:var(--text);font-size:13.5px;font-weight:600;
}
.spinner{
  width:26px;height:26px;border-radius:50%;
  border:3px solid var(--border-strong);border-top-color:var(--olive-600);
  animation:spin .7s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- modal ---------- */
.modal{
  width:min(680px,calc(100vw - 24px));max-height:calc(100dvh - 24px);
  display:flex;flex-direction:column;background:var(--surface);
  border-radius:var(--radius-xl);box-shadow:var(--shadow-lg);
  transform:translateY(12px) scale(.98);transition:transform .22s cubic-bezier(.2,.8,.3,1);
  margin:12px;
}
.overlay.open .modal{transform:none}
.modal-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
  padding:18px 22px;border-bottom:1px solid var(--border);
}
.mh-title h2{font-size:17px;font-weight:800;letter-spacing:-.01em}
.mh-title p{font-size:12.5px;color:var(--text-3);margin-top:2px}
.modal-body{padding:18px 22px;overflow-y:auto;display:flex;flex-direction:column;gap:16px}
.modal-foot{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:13px 22px;border-top:1px solid var(--border);background:var(--surface-2);
  border-radius:0 0 var(--radius-xl) var(--radius-xl);
}
.mf-total{font-size:13px;color:var(--text-2)}
.mf-total strong{font-size:15px;font-weight:800;color:var(--text);margin-left:6px;font-variant-numeric:tabular-nums}
.mf-actions{display:flex;gap:10px;margin-left:auto}

/* a real <form> wrapping .modal-body/.modal-foot must not break .modal's
   flex column, or .modal-body's overflow-y:auto stops constraining height
   and the footer gets pushed past the viewport */
.modal > form{display:contents}

/* ============================================================
   CSV/XLSX IMPORT MODAL (#impModalOverlay)
   Ported from theme/styles.css's CSV IMPORT MODAL block. The theme's
   `.imp-types` type grid and per-row `.imp-row-err/-warn`/`.imp-status`
   rules are intentionally not ported: this app only imports contacts, and
   the preview here is pure presentation with no client-side validation —
   see assets/clients.js. `.imp-consent*` and `.imp-error` are new, not in
   the theme.
   ============================================================ */
.imp-drop{
  border:1.5px dashed var(--border-strong);border-radius:12px;background:var(--surface-2);
  padding:24px 18px;text-align:center;cursor:pointer;outline:none;
  display:flex;flex-direction:column;align-items:center;gap:5px;
  transition:border-color .15s,background .15s;
}
.imp-drop:hover,.imp-drop:focus-visible,.imp-drop.drag{
  border-color:var(--olive-500);background:var(--olive-50);
}
.imp-drop > svg{width:26px;height:26px;color:var(--olive-700)}
.imp-drop-main{font-size:13.5px;font-weight:600;color:var(--text)}
.imp-or{color:var(--olive-700)}
.imp-hint{font-size:11.5px;line-height:1.5;color:var(--text-3);max-width:440px}
.imp-tpl{font-size:12.5px;color:var(--text-2);display:flex;align-items:baseline;gap:4px;margin-top:8px}

/* #impPreview has no wrapping element of its own in the markup — it needs
   the same flex/gap rhythm as .modal-body, or its children touch. */
#impPreview{display:flex;flex-direction:column;gap:16px}

.imp-summary{display:flex;gap:8px;flex-wrap:wrap}
.imp-chip{
  display:inline-flex;align-items:center;gap:6px;
  font-size:12px;font-weight:700;padding:4px 11px;border-radius:999px;
  border:1px solid var(--border);background:var(--surface-2);color:var(--text-2);
}
.imp-chip .ic{width:6px;height:6px;border-radius:50%;background:var(--text-3);flex-shrink:0}
.imp-chip-ok{border-color:rgba(143,180,80,.5);background:var(--olive-50);color:var(--olive-800)}
.imp-chip-ok .ic{background:var(--olive-500)}

.imp-table-wrap{
  border:1px solid var(--border);border-radius:10px;
  overflow:auto;max-height:268px;background:var(--surface);
}
.imp-table-wrap .table{min-width:0}
.imp-table-wrap thead th{
  position:sticky;top:0;z-index:1;background:var(--surface-2);
  font-size:10.5px;padding:8px 12px;white-space:nowrap;
}
.imp-table-wrap td{font-size:12px;padding:7px 12px;white-space:nowrap;max-width:240px;overflow:hidden;text-overflow:ellipsis}
.imp-note{font-size:12px;color:var(--text-3);line-height:1.5}

.imp-consent-warning{font-size:12.5px;color:var(--amber-700);line-height:1.5}
.imp-consent{display:flex;align-items:flex-start;gap:8px;font-size:12.5px;color:var(--text-2);cursor:pointer}
.imp-consent input{margin-top:2px}
.imp-error{font-size:12.5px;color:var(--rust-700);line-height:1.5}

@media (max-width:640px){
  .imp-drop{padding:18px 12px}
}

.field{display:flex;flex-direction:column;gap:6px;min-width:0}
.field > label{font-size:12px;font-weight:600;color:var(--text-2);letter-spacing:.01em}
/* client-side show/hide (assets/clients.js toggles the `hidden` attribute
   on `.field` rows, e.g. vat_number / employer_contact by contact type) —
   `.field{display:flex}` above would otherwise beat the UA `[hidden]` rule */
.field[hidden]{display:none}

/* Company/Person segmented switch (ContactType::type, expanded ChoiceType).
   Two radio+label pairs rendered by choice_widget_expanded; the
   `type-switch` class is added in templates/form/modal_theme.html.twig's
   form_row block. Both options stay visible at all times — no native
   <select>, so both labels read at a glance. */
.type-switch{
  display:inline-flex;gap:0;padding:2px;width:fit-content;
  border:1px solid var(--border-strong);border-radius:11px;background:var(--surface-2);
}
.type-switch input[type="radio"]{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}
.type-switch label{
  padding:7px 16px;border-radius:9px;font-size:13px;font-weight:600;color:var(--text-2);
  cursor:pointer;user-select:none;transition:background .15s,color .15s;
}
.type-switch label:hover{color:var(--text)}
.type-switch input[type="radio"]:checked + label{background:var(--btn-grad);color:#fff}
.type-switch input[type="radio"]:focus-visible + label{outline:2px solid var(--olive-600);outline-offset:2px}

.form-fieldset{border:0;margin:0;padding:0;min-width:0;display:flex;flex-direction:column;gap:12px}
.form-fieldset + .form-fieldset{padding-top:16px;border-top:1px solid var(--border)}
.form-fieldset legend{padding:0;margin:0 0 2px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)}

/* Searchable combobox (assets/js/combobox.js): a
   progressive enhancement over the `employer_contact` <select> (and the
   client drawer's `#dAddEmploymentSelect`). The <select> itself gets
   `.visually-hidden` (clip-rect technique above, reused as-is — not
   display:none/[hidden], it must stay in the accessibility/submission
   tree as a real, valid form field) and this wrapper positions the
   visible text input + listbox in its place. */
.combobox{position:relative;min-width:0}
/* The enhanced <select> keeps its server-rendered `.input` class (width:100%
   etc., declared further below) alongside `.visually-hidden` (declared much
   earlier, near the top of this file). Both are single-class selectors, so
   at equal specificity source order decides — `.input` would win and the
   "hidden" select would render at full size. Re-assert the clip-rect here,
   at higher specificity, scoped to exactly this case. */
.combobox select.visually-hidden{
  position:absolute;left:0;top:0;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.combobox-input{cursor:text}
.combobox-input:disabled{background:var(--surface-2);color:var(--text-3);cursor:not-allowed}
#txForm input:disabled,
#txForm select:disabled{opacity:.5;cursor:not-allowed;background:var(--surface-2)}
.combobox-listbox{
  position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:20;
  margin:0;padding:4px;list-style:none;max-height:220px;overflow-y:auto;
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius);
  box-shadow:var(--shadow-lg);
}
.combobox-option{padding:8px 10px;border-radius:8px;font-size:13.5px;color:var(--text);cursor:pointer;user-select:none}
.combobox-option:hover{background:var(--olive-50)}
.combobox-option.is-active{background:var(--olive-100);color:var(--olive-900)}
.combobox-option[aria-selected="true"]{font-weight:600}
.combobox-empty{padding:8px 10px;font-size:13px;color:var(--text-3);cursor:default}
/* The drawer's inline add-form lays its select out as a flex item
   (`.pe-add-employment select{flex:1}` below) — once enhanced, the
   visible flex item is this wrapper, not the now-hidden select. */
.pe-add-employment .combobox{flex:1;min-width:140px}
.grid-3{display:grid;grid-template-columns:1.15fr 1fr 1fr;gap:12px}
.grid-2{display:grid;grid-template-columns:1.15fr 1fr;gap:12px}
.new-client-grid{
  display:grid;grid-template-columns:1fr 1fr;gap:12px;
  background:var(--bg);border:1px dashed var(--border-strong);border-radius:12px;padding:14px;
}

/* line items */
.li-remove{width:26px;height:26px;border-radius:7px;color:var(--text-3)}
.li-remove:hover{background:var(--rust-100);color:var(--rust-700)}
.btn-add-line{
  width:100%;padding:8px;border:1px dashed var(--border-strong);border-radius:9px;
  font-size:13px;font-weight:600;color:var(--olive-800);transition:background .15s,border-color .15s;
}
.btn-add-line:hover{background:var(--olive-50);border-color:var(--olive-400)}
/* Row under the lines table: "+ Add line" on the left half, the discount
   affordance (and its expanded panel) on the right half. */
.lines-actions{display:flex;gap:16px;margin-top:7px;align-items:flex-start}
.lines-actions .btn-add-line{margin-top:0;flex:1;min-width:0}
.lines-discount{flex:1;min-width:0;display:flex;flex-direction:column;gap:7px;align-items:flex-start}
.lines-discount .discount-affordance{align-self:flex-end}
/* expanded discount panel: keep its contents right-aligned, under the
   affordance, so the whole discount build-up hugs the right edge */
.lines-discount .discount-panel{text-align:right;align-self:stretch}
.lines-discount .discount-panel .t-row{justify-content:flex-end;gap:12px}
.lines-discount .discount-panel .t-global-discount-fields{align-items:flex-end}

/* ---------- document lines table editor (legacy bibloc design) ---------- */
/* Shared by the invoice and expense editors: both render the same table and
   carry the .invoice-lines class (see assets/js/line-editor.js). */
/* `overflow` stays visible: the .tax-pill-menu dropdown is absolutely
   positioned below the il-taxes cell (top: calc(100% + 2px)) and would be
   clipped by an overflow:hidden table — the "+ tax" button appeared to do
   nothing. The rounded corners are preserved by explicit radii on the
   corner cells instead of relying on table-level clipping. */
.invoice-lines{width:100%;min-width:0;border-collapse:separate;border-spacing:0;background:var(--surface);border:1px solid var(--border);border-radius:12px;overflow:visible}
.invoice-lines thead th{
  padding:9px 10px;font-size:10.5px;background:var(--surface-2);border-bottom:1px solid var(--border);
}
.invoice-lines thead th:first-child{border-top-left-radius:11px}
.invoice-lines thead th:last-child{border-top-right-radius:11px}
.invoice-lines tbody tr:first-child td:first-child{border-top-left-radius:11px}
.invoice-lines tbody tr:first-child td:last-child{border-top-right-radius:11px}
.invoice-lines tbody tr:last-child td:first-child{border-bottom-left-radius:11px}
.invoice-lines tbody tr:last-child td:last-child{border-bottom-right-radius:11px}
/* light vertical separators, matching the legacy bordered-table look */
.invoice-lines tbody td{padding:6px 8px;border-top:1px solid var(--border);vertical-align:top}
.invoice-lines tbody tr:hover{background:transparent}
.invoice-lines tbody td:not(:first-child){border-left:1px solid var(--border)}
.invoice-lines tbody tr:first-child td{border-top:none}
.invoice-lines td.il-desc{padding:6px 10px}
.invoice-lines .il-col-handle, .invoice-lines td.il-handle{width:36px;min-width:36px}
.invoice-lines .il-col-qty, .invoice-lines td.il-qty{width:72px;min-width:72px}
.invoice-lines .il-col-price, .invoice-lines td.il-price{width:110px;min-width:110px}
.invoice-lines .il-col-discount, .invoice-lines td.il-discount{width:88px;min-width:88px}
.invoice-lines .il-col-taxes, .invoice-lines td.il-taxes{width:190px;min-width:190px}
.invoice-lines .il-col-act, .invoice-lines td.il-act{width:40px;min-width:40px}
/* "Discount per product" toggle off: hide the column without touching the
   DOM (rows keep the cell, so nothing needs re-rendering when toggled back
   on — see the `data-line-discount-toggle` handler in assets/invoices.js) */
.invoice-lines.no-line-discount .il-col-discount,
.invoice-lines.no-line-discount td.il-discount{display:none}
/* Row kinds. The cells stay in the DOM so the table grid never shifts and so
   every field keeps submitting (a display:none control still posts); only
   their contents are hidden. line-editor.js drops the hidden controls from
   the tab order — see dropInvisibleTabStops(). */
.invoice-line--title td.il-qty > *,
.invoice-line--title td.il-price > *,
.invoice-line--title td.il-discount > *,
.invoice-line--title td.il-taxes > *,
.invoice-line--supplied td.il-discount > *,
.invoice-line--supplied td.il-taxes > *{display:none}
/* A title is a heading between the lines, not a priced row. */
.invoice-line--title td.il-desc input.input{font-weight:700;color:var(--text-1)}
/* The row renders all three badges; only the one matching the row kind shows,
   so a JS-added row needs no translated string handed to it. */
.il-kind{
  display:none;font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-3);padding:2px 0 0 8px;
}
.invoice-line--title .il-kind-title,
.invoice-line--supplied .il-kind-supplied{display:block}

/* "Add line" split button: primary action + a caret opening the other kinds */
.add-line-split{position:relative;display:flex;flex:1;min-width:0}
.add-line-split .btn-add-line{flex:1;min-width:0;border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}
.btn-add-line-more{
  width:34px;padding:8px 0;border:1px dashed var(--border-strong);border-left:none;
  border-top-right-radius:9px;border-bottom-right-radius:9px;color:var(--olive-800);
  display:flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s;
}
.btn-add-line-more:hover{background:var(--olive-50);border-color:var(--olive-400)}
.btn-add-line-more svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.add-line-menu{
  position:absolute;z-index:30;top:calc(100% + 4px);right:0;min-width:190px;
  background:var(--surface);border:1px solid var(--border);border-radius:10px;
  box-shadow:0 8px 24px rgba(0,0,0,.12);padding:4px;display:flex;flex-direction:column;
}
.add-line-menu[hidden]{display:none}
.add-line-menu button{
  text-align:left;padding:8px 10px;border-radius:7px;font-size:12.5px;font-weight:600;color:var(--text-1);
}
.add-line-menu button:hover,.add-line-menu button:focus-visible{background:var(--olive-50)}
/* cells hold borderless inputs: the row grid + cell borders carry the
   structure, the underlying .input chrome is neutralized inside the table */
.invoice-lines .field{min-width:0}
.invoice-lines input.input, .invoice-lines textarea.input{
  border:none;background:transparent;border-radius:0;box-shadow:none;
  padding:7px 8px;font-size:12.5px;
}
.invoice-lines input.input:focus{border:none;box-shadow:none;background:var(--olive-50)}
.invoice-lines input.input.invalid{border:none;box-shadow:none;background:var(--rust-100)}
.invoice-lines .combobox{min-width:0}
/* stray field-errors inside a table cell read as small inline notes */
.invoice-lines .field-errors{font-size:11px;letter-spacing:0;text-transform:none;font-weight:400;color:var(--rust-700)}
/* drag handle */
.invoice-lines td.il-handle{text-align:center;cursor:grab;user-select:none;padding-top:12px}
.invoice-lines td.il-handle .il-grip{display:inline-block;color:var(--text-3);line-height:0}
.invoice-lines td.il-handle .il-grip svg{width:12px;height:12px}
.invoice-lines td.il-handle:hover .il-grip, .invoice-lines td.il-handle:hover{color:var(--olive-800)}
.invoice-lines tr.dragging td{background:var(--olive-100)}
.invoice-lines tr.dragging{outline:2px solid var(--olive-400);opacity:.9}
.invoice-lines tr.dragging td.il-handle{cursor:grabbing}
/* tax pills */
td.il-taxes{position:relative}
.tax-pills{display:flex;flex-wrap:wrap;align-items:center;gap:4px;min-height:24px}
.tax-pill{
  display:inline-flex;align-items:center;gap:2px;
  font-size:11px;font-weight:600;padding:3px 4px 3px 8px;border-radius:999px;
  background:var(--olive-100);color:var(--olive-800);white-space:nowrap;
}
.tax-pill-remove{
  border:none;background:none;color:inherit;cursor:pointer;
  padding:0 3px;font-size:12px;line-height:1;
}
.tax-pill-remove:hover{color:var(--rust-700)}
.tax-pill-add{
  width:24px;height:24px;padding:0;margin:3px 0 0;
  border:1px dashed var(--border-strong);border-radius:999px;background:none;
  color:var(--olive-800);font-size:14px;line-height:1;cursor:pointer;
}
.tax-pill-add:hover{background:var(--olive-50);border-color:var(--olive-400)}
.tax-pill-add[hidden]{display:none}
.tax-pill-menu{
  position:absolute;top:calc(100% + 2px);left:8px;z-index:30;min-width:260px;max-width:320px;
  padding:4px;background:var(--surface);border:1px solid var(--border-strong);
  border-radius:var(--radius);box-shadow:var(--shadow-lg);
}
.tax-pill-menu-empty{display:block;padding:8px 8px;font-size:12px;color:var(--text-3);cursor:default}
/* the most-used taxes, surfaced as one-click chips above the search box;
   `.has-more` only gets the divider, since without a search box below it
   there is nothing to divide from */
.tax-pill-menu-quick{display:flex;flex-wrap:wrap;gap:4px;padding:4px}
.tax-pill-menu-quick.has-more{padding-bottom:7px;margin-bottom:3px;border-bottom:1px solid var(--border)}
.tax-pill-quick{
  display:inline-flex;align-items:center;cursor:pointer;
  font-size:11px;font-weight:600;padding:4px 9px;border-radius:999px;
  border:1px solid transparent;background:var(--olive-100);color:var(--olive-800);white-space:nowrap;
  transition:background .15s,border-color .15s;
}
.tax-pill-quick:hover{background:var(--olive-50);border-color:var(--olive-400)}
.tax-pill-quick:focus-visible{outline:none;border-color:var(--olive-500);box-shadow:0 0 0 3px var(--olive-100)}


/* expense/contact attachment field + current-file list (theme/styles.css) */
.att-field-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.att-field-head label{margin:0}
.att-list{display:flex;flex-direction:column;gap:8px}
.att-row{display:flex;align-items:center;gap:10px;padding:9px 11px;border:1px solid var(--border);border-radius:10px;background:var(--surface-2)}
.att-ico{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;flex-shrink:0}
.att-ico svg{width:15px;height:15px}
.att-ico.t-pdf{background:var(--rust-100);color:var(--rust-700)}
.att-ico.t-img{background:var(--blue-100);color:var(--blue-700)}
.att-ico.t-file{background:var(--olive-100);color:var(--olive-800)}
.att-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:1px}
.att-name{font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.att-meta{font-size:11px;color:var(--text-3)}
.att-act{display:flex;gap:2px;flex-shrink:0}
.att-act .icon-btn{width:26px;height:26px}
.expense-attachment-field{margin-top:2px}
.expense-attachment-drop{padding:18px 16px}
.expense-attachment-drop.has-file{border-color:var(--olive-500);background:var(--olive-50)}
.expense-attachment-drop.has-file > svg{color:var(--olive-600)}
.expense-attachment-drop.has-file .imp-drop-main{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.expense-attachment-field > .att-list{margin-top:2px}

/* totals */
.bottom-grid{display:grid;grid-template-columns:1fr 236px;gap:16px;align-items:end}
.totals{
  background:var(--bg);border:1px solid var(--border);border-radius:12px;
  padding:12px 14px;display:flex;flex-direction:column;gap:7px;
}
.t-row{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;color:var(--text-2)}
.t-row strong{font-weight:600;font-variant-numeric:tabular-nums;color:var(--text)}
.t-total{border-top:1px solid var(--border-strong);padding-top:9px;margin-top:3px;font-weight:700;color:var(--text)}
.t-total strong{font-size:16px;font-weight:800;color:var(--olive-900)}
/* "+ Add discount" affordance: same progressive-disclosure idea as
   `.btn-add-line`, but deliberately lighter — a plain text link, not a
   full-width dashed block — since it only ever needs to feel like a small
   discreet entry point, not a peer of the line-items table. */
.discount-affordance{
  padding:0;border:0;background:none;font-size:13px;font-weight:600;color:var(--olive-800);
  text-decoration:underline;text-decoration-color:transparent;transition:text-decoration-color .15s,color .15s;
}
.discount-affordance:hover{color:var(--olive-900);text-decoration-color:currentColor}
.discount-panel{display:flex;flex-direction:column;gap:7px}
/* discount toggle rows ("Discount per product" / "Global discount") */
.t-row-ctl{gap:8px}
.t-check{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--text-2);cursor:pointer}
.t-check input[type="checkbox"]{margin:0}
.t-global-discount-fields{display:flex;flex-direction:column;gap:7px;padding:2px 0 3px;border-bottom:1px dashed var(--border)}
.t-global-discount-fields .t-row-ctl{gap:6px}
.t-discount-value{flex:1;min-width:0}
.t-discount-unit{width:64px;flex-shrink:0}
/* the edit screen's own totals block (show_totals_preview=false) only
   carries the discount controls — its read-only figures live in the
   pe-side stat cards instead, so it drops the padded card chrome */
.totals-inline{background:none;border:none;padding:0;margin-bottom:14px}

/* ---------- drawer ---------- */
.overlay-right{justify-content:flex-end;align-items:stretch}
.drawer{
  width:min(440px,100%);height:100%;background:var(--surface);
  display:flex;flex-direction:column;box-shadow:-24px 0 48px -12px rgba(38,46,26,.2);
  transform:translateX(100%);transition:transform .26s cubic-bezier(.2,.8,.3,1);
}
.overlay.open .drawer{transform:none}
.drawer-head{
  display:flex;align-items:center;gap:13px;padding:18px 20px;border-bottom:1px solid var(--border);
}
.dh-meta{min-width:0;flex:1}
.dh-meta h3{font-size:15.5px;font-weight:700;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dh-meta p{font-size:12.5px;color:var(--text-3);margin-top:1px}
.drawer-body{flex:1;overflow-y:auto;padding:18px 20px;display:flex;flex-direction:column;gap:20px}
.contact-list{display:flex;flex-direction:column;gap:2px}
.contact-row{
  display:flex;align-items:center;gap:11px;padding:8px 10px;border-radius:10px;transition:background .12s;
}
.contact-row:hover{background:var(--bg)}
.contact-icon{
  width:30px;height:30px;border-radius:9px;background:var(--olive-50);color:var(--olive-800);
  display:grid;place-items:center;flex-shrink:0;
}
.contact-icon svg{width:14px;height:14px}
.contact-meta{display:flex;flex-direction:column;line-height:1.3;min-width:0}
.contact-meta strong{font-size:13px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.contact-meta strong a{color:var(--olive-700);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
.contact-meta strong a:hover{text-decoration:underline;color:var(--olive-800)}
.contact-meta span{font-size:11.5px;color:var(--text-3)}
.section-title{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--text-3);margin-bottom:9px}
.stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.stat-card{background:var(--bg);border:1px solid var(--border);border-radius:12px;padding:11px 12px;display:flex;flex-direction:column;gap:3px;min-width:0}
.stat-label{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text-3);overflow-wrap:anywhere}
.stat-value{font-size:14px;font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Labels wrap (see .stat-label), so a two-line label in one card would push its
   value a line lower than its neighbours. The grid stretches every card to the
   tallest, so pinning the value to the bottom keeps the numbers on one line. */
.stat-card .stat-value{margin-top:auto}
.stat-value.warn{color:var(--rust-700)}
.drawer-invoices{display:flex;flex-direction:column;gap:8px}
.drawer-inv{
  display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;text-align:left;
  border:1px solid var(--border);border-radius:12px;background:var(--surface);
  color:inherit;text-decoration:none;transition:border-color .15s,background .15s;
}
.drawer-inv:hover{border-color:var(--olive-300);background:var(--olive-50)}
.di-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.di-meta{display:flex;flex-direction:column;line-height:1.3;min-width:0;flex:1}
.di-meta strong{font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums}
.di-meta span{font-size:11.5px;color:var(--text-3)}
.di-amount{font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums}
.drawer-empty{font-size:13px;color:var(--text-3);padding:6px 2px}
.drawer-foot{
  display:flex;gap:10px;padding:14px 20px;border-top:1px solid var(--border);background:var(--surface-2);
}
.drawer-foot .btn{flex:1;justify-content:center}

/* ---------- docs drawer (reusable reference drawer) ---------- */
/* Stacks above the base overlays (60/65) and the mobile drawer (70),
   below toasts (80): the drawer can be opened on top of the wide
   template-code modal. */
.overlay.docs-drawer-overlay{z-index:72}
.docs-drawer{width:min(480px,100%)}
.docs-head h3{display:flex;align-items:center;gap:8px}
.docs-head h3 svg{width:16px;height:16px;color:var(--olive-700);flex-shrink:0}
.docs-body{font-size:12.5px;color:var(--text-2);display:block}
.docs-body .section-title{margin-bottom:8px}
.vars-tbl{width:100%;border-collapse:collapse}
.vars-tbl td,.vars-tbl th{
  text-align:left;padding:5px 8px;border-bottom:1px solid var(--border);vertical-align:top;
}
.vars-tbl th{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-3)}
.vars-tbl tr:last-child td{border-bottom:none}
.vars-tbl td:first-child{white-space:nowrap;width:1%}
.vars-tbl code,.docs-body code{
  font-family:ui-monospace,'Sarasa Mono SC',SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11.5px;color:var(--olive-700);background:var(--olive-50);
  border:1px solid var(--olive-300);border-radius:5px;padding:1px 5px;white-space:nowrap;
}
.docs-body .vars-note{
  font-size:12px;color:var(--text-3);background:var(--bg);border:1px solid var(--border);
  border-radius:12px;padding:9px 12px;
}
.docs-body .vars-note + .vars-note{margin-top:-14px}
.docs-body .vars-sample{
  font-family:ui-monospace,'Sarasa Mono SC',SFMono-Regular,Menlo,Consolas,monospace;
  font-size:11.5px;line-height:1.6;white-space:pre;overflow-x:auto;
  background:var(--surface-2);border:1px solid var(--border);border-radius:12px;padding:12px;
}
.tc-docs-btn{margin-left:auto;display:inline-flex;align-items:center;gap:4px}
.tc-docs-btn svg{width:11px;height:11px}

/* ---------- toasts ---------- */
.toast-stack{position:fixed;right:20px;bottom:20px;display:flex;flex-direction:column;gap:10px;z-index:80}
.toast{
  display:flex;align-items:flex-start;gap:10px;max-width:360px;
  background:var(--ink);color:#eef3e2;padding:12px 14px;border-radius:12px;
  border:1px solid var(--toast-border);
  box-shadow:0 12px 24px -8px rgba(0,0,0,.35);font-size:13.5px;line-height:1.45;
  animation:toastIn .28s cubic-bezier(.2,.8,.3,1);
}
.toast.out{animation:toastOut .25s ease forwards}
.toast-icon{width:22px;height:22px;border-radius:7px;display:grid;place-items:center;flex-shrink:0;margin-top:1px}
.toast-icon svg{width:13px;height:13px;stroke-width:2.25}
.toast-success .toast-icon{background:rgba(143,180,80,.28);color:#c6de96}
.toast-error .toast-icon{background:rgba(196,103,74,.32);color:#eba287}
.toast-info .toast-icon{background:rgba(98,143,165,.32);color:#a9cbdb}
@keyframes toastIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(8px)}}

/* ---------- global toolbar ---------- */
.toolbar{
  position:sticky;top:0;z-index:40;
  align-items:center;gap:14px;
  margin:0 -30px 20px;padding:11px 30px;
  background:var(--toolbar-bg);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--border);
  display: none;
}
.main.section-dashboard > .toolbar{display:flex}
.g-search{position:relative;flex:0 1 400px;min-width:170px}
.g-search .gs-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--text-3);pointer-events:none}
.g-search .input{padding:9px 64px 9px 38px;border-radius:12px}
.g-search input::-webkit-search-cancel-button{-webkit-appearance:none}
.g-search kbd{
  position:absolute;right:10px;top:50%;transform:translateY(-50%);
  font-family:inherit;font-size:10.5px;font-weight:600;color:var(--text-3);
  background:var(--bg);border:1px solid var(--border);border-radius:6px;
  padding:2px 6px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;
}
.g-search kbd:hover{background:var(--olive-100);color:var(--olive-800);border-color:var(--olive-300)}

.toolbar-actions{display:flex;align-items:center;gap:6px;margin-left:auto}
.tool-btn{
  position:relative;width:36px;height:36px;border-radius:11px;
  display:grid;place-items:center;color:var(--text-2);
  border:1px solid transparent;transition:background .15s,border-color .15s,color .15s;
}
.tool-btn:hover,.tool-btn[aria-expanded="true"]{background:var(--surface);border-color:var(--border);color:var(--text)}
.tool-btn svg{width:17px;height:17px}
.badge-count{
  position:absolute;top:3px;right:3px;min-width:15px;height:15px;padding:0 4px;
  border-radius:999px;background:var(--rust-500);color:#fff;
  font-size:9.5px;font-weight:700;line-height:1;display:grid;place-items:center;
  box-shadow:0 0 0 2px var(--bg);
}
.tool-divider{width:1px;height:22px;background:var(--border);margin:0 6px}
.burger-btn{display:none}
.mobile-burger{margin:0 0 14px} /* rendered outside the toolbar on non-dashboard views; .burger-btn already keeps it desktop-hidden */

.user-btn{
  display:flex;align-items:center;gap:9px;padding:4px 8px 4px 5px;border-radius:12px;
  border:1px solid transparent;transition:background .15s,border-color .15s;
}
.user-btn:hover,.user-btn[aria-expanded="true"]{background:var(--surface);border-color:var(--border)}
.user-btn .avatar{width:30px;height:30px;font-size:10.5px;background:var(--avatar-bg);color:var(--avatar-fg)}
.ub-name{font-size:13px;font-weight:600;white-space:nowrap}
.user-btn .chev{width:14px;height:14px;color:var(--text-3);transition:transform .18s}
.menu-wrap.open .chev{transform:rotate(180deg)}

/* dropdown menus */
.menu{
  position:absolute;top:calc(100% + 10px);right:0;min-width:300px;
  background:var(--surface);border:1px solid var(--border);border-radius:14px;
  box-shadow:var(--shadow-lg);z-index:50;
  opacity:0;transform:translateY(-6px) scale(.98);transform-origin:top right;
  pointer-events:none;transition:opacity .16s ease,transform .16s ease;
}
.menu.open{opacity:1;transform:none;pointer-events:auto}
.menu-head{display:flex;align-items:center;gap:11px;padding:14px 16px;border-bottom:1px solid var(--border)}
.menu-head .avatar{width:38px;height:38px;background:var(--avatar-bg);color:var(--avatar-fg)}
.menu-head-meta{min-width:0}
.menu-title{font-size:14px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.menu-sub{font-size:12px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.menu-list{padding:6px;display:flex;flex-direction:column}
.menu-item{
  display:flex;align-items:center;gap:10px;width:100%;text-align:left;
  padding:9px 10px;border-radius:9px;font-size:13px;font-weight:500;color:var(--text-2);
  transition:background .12s,color .12s;
}
.menu-item:hover{background:var(--olive-50);color:var(--text)}
.menu-item svg{width:15px;height:15px;color:var(--text-3)}
.menu-item.danger{color:var(--rust-700)}
.menu-item.danger svg{color:var(--rust-700)}
.menu-item.danger:hover{background:var(--rust-100)}
.menu-sep{height:1px;background:var(--border);margin:5px 8px}

/* .menu (position:absolute) anchors to its own .menu-wrap — without this
   it falls back to the nearest positioned ancestor (or the document),
   which misplaces every dropdown built on this pair, export's included. */
.menu-wrap{position:relative}

/* export popover (clients topbar) — ported from theme/index.html's
   #cliExportMenu; format is a segmented control, scope a radio list. */
.export-menu{padding:14px 14px 16px}
.export-menu .btn-label{display:inline} /* the ≤760px .btn-label rule must not strip the popover's CTA */
.export-title{font-size:14px;font-weight:700}
.export-sub{margin-top:2px;font-size:12px;color:var(--text-3)}
.export-label{margin:14px 0 6px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--text-3)}
.seg-group{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;background:var(--surface-2);border:1px solid var(--border);border-radius:11px}
.seg-opt{
  padding:7px 10px;border:0;border-radius:8px;background:transparent;
  font:inherit;font-size:12.5px;font-weight:600;color:var(--text-2);cursor:pointer;
  transition:background .12s,color .12s,box-shadow .12s;
}
.seg-opt:hover{color:var(--text)}
.seg-opt.is-on{background:var(--surface);color:var(--olive-700);box-shadow:var(--shadow-sm)}
/* 3-option variant of the segmented control (settings › numbering series);
   the base .seg-group above is a 2-column grid for the export menu */
.seg-group-3{grid-template-columns:repeat(3,1fr)}
.scope-group{display:flex;flex-direction:column;gap:6px}
.scope-opt{
  position:relative;display:flex;align-items:center;gap:10px;
  padding:9px 11px;border:1px solid var(--border);border-radius:11px;cursor:pointer;
  transition:border-color .12s,background .12s;
}
.scope-opt:hover{border-color:var(--border-strong)}
.scope-opt input{position:absolute;opacity:0;pointer-events:none}
.scope-dot{width:15px;height:15px;border-radius:50%;border:1.5px solid var(--border-strong);flex-shrink:0;transition:border .12s}
.scope-opt input:checked ~ .scope-dot{border:5px solid var(--olive-500)}
.scope-opt:has(input:checked){border-color:var(--olive-400);background:var(--olive-50)}
.scope-txt{display:flex;align-items:center;justify-content:space-between;gap:8px;flex:1;font-size:13px;font-weight:600;color:var(--text-2)}
.scope-opt input:checked ~ .scope-txt{color:var(--text)}
.scope-txt em{font-style:normal;font-size:11px;font-weight:700;color:var(--text-3);background:var(--draft-bg);border-radius:999px;padding:2px 8px}
.export-note{margin-top:12px;padding:8px 10px;border:1px solid var(--border);border-radius:11px;background:var(--surface-2);font-size:11.5px;color:var(--text-3)}
#btnCliExpGo,#expExpGo,#invExpGo{width:100%;justify-content:center;margin-top:14px}
/* ≤760px the topbar buttons collapse to icons, so a 300px right-anchored
   popover would clip past the left viewport edge — go full-width sheet
   under the sticky toolbar, same pattern as the mobile user menu. */
@media (max-width:760px){
  .export-menu{position:fixed;top:66px;left:12px;right:12px;min-width:0;width:auto}
}

/* global search results */
/* min-width:0 so the closed dropdown can never outgrow the search box and
   stretch the page (the generic .menu min-width would otherwise win) */
.menu.gs-menu{left:0;right:auto;width:min(430px,100%);min-width:0;max-height:400px;overflow-y:auto}
.gs-group{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--text-3);padding:10px 14px 4px}
.gs-item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:8px 14px;transition:background .12s}
.gs-item:hover{background:var(--olive-50)}
.gs-item.active{background:var(--olive-100)}
.gs-icon-chip{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;flex-shrink:0}
.gs-icon-chip svg{width:14px;height:14px}
.gi-client{background:var(--blue-100);color:var(--blue-700)}
.gi-invoice{background:var(--olive-100);color:var(--olive-800)}
.gs-txt{display:flex;flex-direction:column;min-width:0;line-height:1.3;flex:1}
.gs-main{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gs-sub{font-size:11.5px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gs-empty{padding:18px 14px;text-align:center;font-size:13px;color:var(--text-3)}

/* command palette (⌘K / Ctrl K) — global quick actions + record search */
.cmdk-overlay{align-items:flex-start;padding:11vh 16px 16px}
.cmdk{
  width:min(580px,100%);display:flex;flex-direction:column;background:var(--surface);
  border-radius:16px;box-shadow:var(--shadow-lg);overflow:hidden;
  transform:translateY(10px) scale(.98);transition:transform .2s cubic-bezier(.2,.8,.3,1);
}
.cmdk-overlay.open .cmdk{transform:none}
.cmdk-head{display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid var(--border)}
.cmdk-head>svg{width:16px;height:16px;color:var(--text-3);flex-shrink:0}
.cmdk-input{flex:1;min-width:0;border:none;outline:none;background:transparent;font:inherit;font-size:14.5px;color:var(--text)}
.cmdk-input::placeholder{color:var(--text-3)}
kbd.cmdk-esc,.cmdk-foot kbd{
  font-family:inherit;font-size:10px;font-weight:700;color:var(--text-3);
  background:var(--surface-2);border:1px solid var(--border);border-radius:5px;
  padding:2px 6px;line-height:1.4;
}
.cmdk-list{max-height:46vh;overflow-y:auto;padding:6px}
.cmdk-group{font-size:10.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--text-3);padding:10px 10px 4px;margin:0}
.cmdk-item{
  display:flex;align-items:center;gap:11px;width:100%;text-align:left;
  padding:9px 10px;border:none;background:transparent;border-radius:9px;cursor:pointer;font:inherit;color:var(--text);
}
.cmdk-item:hover{background:var(--surface-2)}
.cmdk-item.active{background:var(--olive-100)}
.cmdk-ico{width:30px;height:30px;border-radius:8px;display:grid;place-items:center;flex-shrink:0;background:var(--surface-2);color:var(--text-2)}
.cmdk-item.active .cmdk-ico{background:rgba(143,180,80,.18);color:var(--olive-800)}
.cmdk-ico svg{width:14px;height:14px}
.cmdk-txt{min-width:0;flex:1;display:flex;flex-direction:column;gap:1px}
.cmdk-main{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-sub{font-size:11.5px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-hint{font-size:10.5px;color:var(--text-3);flex-shrink:0;white-space:nowrap}
.cmdk-empty{padding:24px;text-align:center;font-size:12.5px;color:var(--text-3);margin:0}
.cmdk-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:24px;font-size:12.5px;color:var(--text-3)}
.cmdk-spinner{width:14px;height:14px;border-radius:50%;border:2px solid var(--border-strong);border-top-color:var(--olive-600);animation:cmdk-spin .7s linear infinite}
@keyframes cmdk-spin{to{transform:rotate(360deg)}}
.cmdk-foot{display:flex;gap:16px;padding:9px 16px;border-top:1px solid var(--border);font-size:11px;color:var(--text-3)}
.cmdk-foot span{display:inline-flex;align-items:center;gap:4px}
@media (max-width:640px){
  .cmdk-overlay{padding-top:7vh}
  .cmdk-list{max-height:54vh}
}

/* notifications */
.notif-menu{min-width:340px}
/* menus opened inside the narrow sidebar open rightward — the shared
   .menu right:0 anchor would throw them off-screen to the left */
.sidebar-quick-actions .menu{left:0;right:auto;transform-origin:top left}
.notif-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:13px 16px;border-bottom:1px solid var(--border)}
.notif-head h4{font-size:13.5px;font-weight:700}
.mark-read{font-size:12px;font-weight:600;color:var(--olive-700)}
.mark-read:hover{color:var(--olive-900);text-decoration:underline}
.notif-list{max-height:340px;overflow-y:auto;padding:6px;display:flex;flex-direction:column;gap:2px}
.notif-item{
  display:flex;align-items:flex-start;gap:11px;width:100%;text-align:left;
  padding:10px;border-radius:10px;position:relative;transition:background .12s;
}
.notif-item:hover{background:var(--bg)}
.notif-item.unread{background:var(--olive-50)}
.notif-item.unread:hover{background:var(--olive-100)}
.n-icon{width:32px;height:32px;border-radius:10px;display:grid;place-items:center;flex-shrink:0}
.n-icon svg{width:15px;height:15px}
.n-paid{background:var(--olive-100);color:var(--olive-800)}
.n-overdue{background:var(--rust-100);color:var(--rust-700)}
.n-draft{background:var(--draft-bg);color:var(--text-2)}
.n-client{background:var(--blue-100);color:var(--blue-700)}
.n-main{display:flex;flex-direction:column;min-width:0;flex:1}
.n-title{font-size:13px;font-weight:600;color:var(--text)}
.n-sub{font-size:12px;color:var(--text-3);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.n-time{font-size:10.5px;color:var(--text-3);margin-top:3px}
.n-dot{width:7px;height:7px;border-radius:50%;background:var(--olive-500);flex-shrink:0;margin-top:6px}
.notif-item.read .n-dot{display:none}
.n-message{background:var(--olive-100);color:var(--olive-800)}
.n-support{background:var(--blue-100);color:var(--blue-700)}
.n-system{background:var(--draft-bg);color:var(--text-2)}
.notif-empty{padding:24px 12px;text-align:center;font-size:12.5px;color:var(--text-3)}
.notif-foot{padding:10px;border-top:1px solid var(--border)}
.notif-foot .btn{width:100%;justify-content:center;font-size:12.5px;padding:8px}

/* ---------- notifications page (View all) ---------- */
.notif-page-list{display:flex;flex-direction:column}
.notif-page-item{display:flex;flex-direction:column;gap:2px;padding:14px 16px;border-bottom:1px solid var(--border)}
.notif-page-item:last-child{border-bottom:0}
.notif-page-item.unread{background:var(--olive-50)}
.notif-page-link{display:flex;flex-direction:column;gap:2px;color:inherit;text-decoration:none}
.notif-page-link:hover .n-title{text-decoration:underline}
.notif-page-item .n-sub{white-space:normal}

/* ---------- dark theme ---------- */
html[data-theme="dark"]{
  color-scheme:dark;
  --bg:#12150d;
  --surface:#1a1f13;
  --surface-2:#202615;
  --border:#2c3420;
  --border-strong:#3d4929;
  --text:#edf2e1;
  --text-2:#b5bea4;
  --text-3:#7f8a6f;
  --ink:#0b0e07;
  --olive-50:#1d2415;
  --olive-100:#27331b;
  --olive-200:#334122;
  --olive-300:#465731;
  --olive-700:#9fc75f;
  --olive-800:#bdd689;
  --olive-900:#d8e8b0;
  --amber-100:rgba(217,161,62,.16);
  --amber-700:#e4b65f;
  --rust-100:rgba(196,103,74,.17);
  --rust-700:#eb9f81;
  --blue-100:rgba(98,143,165,.18);
  --blue-700:#a5c6d6;
  --toolbar-bg:rgba(15,18,10,.85);
  --avatar-bg:rgba(143,180,80,.22);
  --avatar-fg:#c9e09a;
  --draft-bg:#262d1b;
  --toast-border:rgba(255,255,255,.09);
  --btn-grad:linear-gradient(180deg,#8fb450,#759639);
  --btn-grad-hover:linear-gradient(180deg,#85a944,#6a8a33);
  --brand-grad:linear-gradient(135deg,#8fb450,#5f7d2c);
  --shadow-sm:0 1px 2px rgba(0,0,0,.3);
  --shadow-md:0 4px 12px -2px rgba(0,0,0,.35);
  --shadow-lg:0 24px 48px -12px rgba(0,0,0,.55);
}

/* ---------- admin palette (darker) ---------- */
/* ROLE_ADMIN users get a deeper, lower-contrast palette in both themes:
   bounded overrides layered on top of the base and dark ramps. */
html[data-admin="1"]{
  --bg:#dfe5d2;
  --surface:#eef1e6;
  --surface-2:#e4e9d9;
  --border:#ccd3bc;
  --border-strong:#b0b99c;
  --text-2:#4c5440;
  --text-3:#6f7660;
}
html[data-admin="1"][data-theme="dark"]{
  --bg:#0a0c07;
  --surface:#10130a;
  --surface-2:#161b0e;
  --border:#20261a;
  --border-strong:#2d3820;
  --text:#dfe6cf;
  --text-2:#99a387;
  --text-3:#6a745c;
  --toolbar-bg:rgba(8,10,5,.88);
  --shadow-sm:0 1px 2px rgba(0,0,0,.5);
  --shadow-md:0 4px 12px -2px rgba(0,0,0,.5);
}

/* ---------- sticky notices ---------- */
/* Server-rendered, dismissible banner (e.g. new-user invite link) that must
   stay on the page until dismissed — unlike .toast, nothing auto-hides it. */
.notice{
  display:flex;align-items:flex-start;gap:12px;
  margin:-6px 0 16px;padding:14px 16px;
  background:var(--surface);border:1px solid var(--border-strong);
  border-radius:12px;box-shadow:var(--shadow-md);
}
.notice-icon{background:rgba(143,180,80,.28);color:#c6de96}
.notice-body{flex:1;min-width:0}
.notice-body p{margin:0 0 6px;font-size:13.5px;font-weight:600;color:var(--text)}
.notice-link{
  display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:12.5px;color:var(--text-2);background:var(--surface-2);
  border:1px solid var(--border);border-radius:8px;padding:7px 10px;
}
.notice-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}
.notice.out{animation:toastOut .25s ease forwards}
.btn-xs{padding:6px 10px;font-size:12px}

/* ---------- motion preferences ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* ---------- responsive ---------- */
@media (min-width:761px) and (max-width:1080px){
  .app{grid-template-columns:70px 1fr}
  .sidebar{padding:20px 10px 16px}
  .brand{justify-content:center;padding:0}
  .brand-badge,.nav-text,.nav-badge{display:none}
  .sidebar .brand-logo-light,.sidebar .brand-logo-dark{display:none} /* the 104px lockup overflows the 70px rail */
  .sidebar .brand-logo-rail{display:block}
  .co-switch{display:none} /* 70px rail cannot fit the select — it stays available on desktop & the mobile drawer */
  .sidebar-quick-actions{display:none} /* same reasoning — search/notif icons only fit the full-width sidebar */
  .nav-item{justify-content:center;padding:10px}
  .nav-item.active::before{left:-10px}
  /* collapse section labels into divider lines so they never overflow the rail */
  .nav-label{
    height:2px;padding:0;margin:12px 5px 6px;
    background:var(--border);border-radius:2px;
    font-size:0;line-height:0;color:transparent;letter-spacing:0;
    text-indent:100%;white-space:nowrap;overflow:hidden;
  }
  .nav-label:first-child{margin-top:0}
  .nav-item+.nav-label{margin-top:14px}
  .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:920px){
  .th-due,.td-due{display:none}
  .spark{display:none}
}
@media (max-width:760px){
  .main{padding:20px 16px 32px}
  .main > .toolbar {margin-top: 0;display:flex}
  .topbar { margin-top: 10px; }
  .th-issued,.td-issued{display:none}
  .btn-label{display:none}
  .modal-foot .btn-label{display:inline} /* modal CTAs never go icon-only — they are the primary action */
  .btn{padding:9px 11px}
  /* 4 KPI cards in a row cannot fit between 521-760px — switch to 2×2 */
  .kpis{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
}
@media (max-width:640px){
  .grid-3{grid-template-columns:1fr 1fr}
  .grid-3 .field:first-child{grid-column:1 / -1}
  /* One column on phones: the invoice header's empty left cells would
     otherwise squeeze each date into half the width beside dead space. */
  .grid-2{grid-template-columns:1fr}
  .field-spacer{display:none}
   .bottom-grid{grid-template-columns:1fr}
   .lines-actions{flex-direction:column}
   .lines-discount .discount-affordance{align-self:flex-start}
  .modal-head,.modal-body,.modal-foot{padding-left:16px;padding-right:16px}
  .drawer-head,.drawer-body,.drawer-foot{padding-left:16px;padding-right:16px}
  .search-wrap{max-width:none}
}
@media (max-width:520px){
  .kpis{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .kpi-value{font-size:19px}
  .btn-pdf{display:none}
  .stats-grid{grid-template-columns:1fr 1fr}
  .stat-card:last-child{grid-column:1 / -1}
  .table{min-width:560px}
}

/* ---------- toolbar responsive ---------- */
@media (max-width:1080px){
  .sidebar-version{display:none}
}
@media (max-width:760px){
  .toolbar{margin:0 -16px;padding:11px 16px;display:flex}
  .g-search kbd{display:none}
  .notif-menu{min-width:300px}
}
@media (max-width:520px){
  .toolbar{gap:10px;display:flex}
  .toolbar-actions{gap:4px}
  .g-search{min-width:120px}
  .menu{max-width:calc(100vw - 24px)}
  .notif-menu{min-width:280px}
}

/* ---------- mobile navigation ---------- */
@media (max-width:760px){
  .app{grid-template-columns:1fr}
  .burger-btn{display:grid}
  .sidebar{
    position:fixed;left:0;top:0;bottom:0;height:100dvh;width:min(280px,84vw);
    z-index:70;transform:translateX(-105%);
    visibility:hidden;
    transition:transform .26s cubic-bezier(.2,.8,.3,1),visibility 0s linear .26s;
  }
  .sidebar.open{
    transform:none;box-shadow:var(--shadow-lg);visibility:visible;
    transition:transform .26s cubic-bezier(.2,.8,.3,1),visibility 0s;
  }
  .sidebar-close{display:flex}
}

/* ============================================================
   VIEWS · router sections + dashboard/projects/reports/settings
   ============================================================ */

/* shared panel head/body (used by dashboard & reports panels) */
.panel-head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:15px 18px;border-bottom:1px solid var(--border);
}
.ph-title h3{font-size:14.5px;font-weight:700;letter-spacing:-.01em}
.ph-title p{font-size:12px;color:var(--text-3);margin-top:1px}
.ph-side{font-size:12px;color:var(--text-3);font-variant-numeric:tabular-nums}
.panel-body{padding:16px 18px}
/* The create modal's body is a flex column with a 16px gap, so its blocks —
   header rows, the lines table, totals — breathe. The edit screens render the
   very same form partial into a .panel-body, which carries padding only, so
   those blocks ended up flush against each other. Scope the modal's rhythm to
   the two editor forms rather than to every panel in the app. */
[data-invoice-editor] .panel-body,
[data-expense-editor] .panel-body{display:flex;flex-direction:column;gap:16px}
.panel-head .link-btn{align-self:center}

.icon-chip{width:32px;height:32px;border-radius:10px;display:grid;place-items:center;flex-shrink:0}
.icon-chip svg{width:15px;height:15px}
.t-olive{background:var(--olive-100);color:var(--olive-800)}
.t-amber{background:var(--amber-100);color:var(--amber-700)}
.t-rust{background:var(--rust-100);color:var(--rust-700)}
.t-blue{background:var(--blue-100);color:var(--blue-700)}
.t-neutral{background:var(--draft-bg);color:var(--text-2)}

.chip-blue{background:var(--blue-100);color:var(--blue-700)}
.delta.neutral{background:var(--draft-bg);color:var(--text-2)}

.legend{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.legend span{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-2)}
.lg-dot{width:9px;height:9px;border-radius:3px;display:inline-block}

/* ---------- dashboard ---------- */
.dash-grid{display:grid;grid-template-columns:1.55fr 1fr;gap:16px}
.dash-grid .panel{min-width:0}

.barchart{display:flex;align-items:stretch;gap:12px;height:216px}
.bc-col{flex:1;display:flex;flex-direction:column;gap:8px;min-width:0;position:relative}
.bc-tip{
  position:absolute;left:50%;top:0;transform:translate(-50%,4px);
  display:flex;flex-direction:column;gap:4px;white-space:nowrap;z-index:20;
  padding:8px 10px;border-radius:10px;border:1px solid var(--border);
  background:var(--surface);box-shadow:0 8px 24px rgba(0,0,0,.14);
  font-size:11.5px;color:var(--text-2);
  opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease,transform .15s ease;
}
.bc-col:hover .bc-tip,.bc-col:focus-within .bc-tip{opacity:1;visibility:visible;transform:translate(-50%,0)}
.bc-col:first-child .bc-tip{left:0;transform:translate(0,4px)}
.bc-col:first-child:hover .bc-tip,.bc-col:first-child:focus-within .bc-tip{transform:translate(0,0)}
.bc-col:last-child .bc-tip{left:auto;right:0;transform:translate(0,4px)}
.bc-col:last-child:hover .bc-tip,.bc-col:last-child:focus-within .bc-tip{transform:translate(0,0)}
.bc-tip-title{font-weight:700;color:var(--text)}
.bc-tip-row{display:flex;align-items:center;gap:6px}
.bc-tip-row b{margin-left:auto;padding-left:10px;color:var(--text)}
.bc-bars{
  flex:1;display:flex;align-items:flex-end;justify-content:center;gap:6px;
  border-bottom:1px solid var(--border);
}
.bc-bar{width:17px;max-width:36px;border-radius:6px 6px 2px 2px;min-height:2px;transition:height .35s ease}
.b-inc{background:var(--olive-500)}
.b-exp{background:var(--rust-500)}
.bc-month{font-size:11.5px;font-weight:600;color:var(--text-3);text-align:center}

.tc-list,.act-list,.due-list{display:flex;flex-direction:column;padding:6px 10px}
.tc-row,.act-row,.due-row{
  display:flex;align-items:center;gap:11px;width:100%;text-align:left;
  padding:9px 8px;border-radius:10px;transition:background .12s;
}
.tc-row:hover,.act-row:hover,.due-row:hover{background:var(--olive-50)}
.tc-row .avatar{width:30px;height:30px;font-size:10.5px;background:var(--avatar-bg);color:var(--avatar-fg)}
.tc-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}
.tc-name{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tc-bar{height:6px;border-radius:999px;background:var(--draft-bg);overflow:hidden}
.tc-bar i{display:block;height:100%;border-radius:999px;background:var(--olive-500)}
.tc-side{display:flex;flex-direction:column;align-items:flex-end;gap:2px}
.tc-side strong{font-size:12.5px;font-variant-numeric:tabular-nums;white-space:nowrap}
.tc-side span{font-size:11px;color:var(--text-3)}

.act-main{
  flex:1;min-width:0;font-size:12.5px;color:var(--text-2);line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.act-main strong{color:var(--text);font-weight:600;font-variant-numeric:tabular-nums}
.act-main span{display:block;font-size:11.5px;color:var(--text-3)}
.act-amt{font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}

.due-row .due-when{
  font-size:11px;font-weight:700;padding:3px 8px;border-radius:999px;
  background:var(--olive-100);color:var(--olive-800);white-space:nowrap;
  min-width:64px;text-align:center;flex-shrink:0;
}
.due-row .due-when.late{background:var(--rust-100);color:var(--rust-700)}
.due-main{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.3}
.due-main strong{font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums}
.due-main span{font-size:11.5px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.list-empty{font-size:13px;color:var(--text-3);padding:8px}

/* ---------- projects ---------- */
.proj-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.proj-card{
  border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface);
  padding:16px;display:flex;flex-direction:column;gap:13px;min-width:0;
  transition:border-color .15s,box-shadow .15s;
}
.proj-card:hover{border-color:var(--olive-300);box-shadow:var(--shadow-sm)}
.pc-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.pc-top h3{font-size:14px;font-weight:700;line-height:1.35;letter-spacing:-.01em}
.pc-client{
  display:inline-flex;align-items:center;gap:9px;font-size:12.5px;font-weight:600;color:var(--text-2);
  align-self:flex-start;padding:2px 6px;margin:-2px -6px;border-radius:999px;
  transition:background .12s,color .12s;
}
.pc-client:hover{background:var(--olive-50);color:var(--olive-900)}
.pc-client .avatar{width:24px;height:24px;font-size:9px}
.pc-progress{display:flex;align-items:center;gap:10px}
.p-bar{flex:1;height:7px;border-radius:999px;background:var(--draft-bg);overflow:hidden}
.p-bar i{display:block;height:100%;border-radius:999px;background:var(--olive-500)}
.p-pct{font-size:11.5px;font-weight:700;color:var(--text-2);min-width:34px;text-align:right;font-variant-numeric:tabular-nums}
.p-meta{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.p-meta > div{display:flex;flex-direction:column;gap:2px;min-width:0}
.p-meta span{font-size:10.5px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text-3)}
.p-meta strong{font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.p-meta strong.p-warn{color:var(--rust-700)}
.pc-foot{display:flex;align-items:center;justify-content:space-between;margin-top:auto;padding-top:11px;border-top:1px solid var(--border)}
.p-team{display:flex}
.p-team .avatar{width:26px;height:26px;font-size:9px;background:var(--draft-bg);color:var(--text-2);border:2px solid var(--surface)}
.p-team .avatar + .avatar{margin-left:-8px}

.pill-active{background:var(--olive-100);color:var(--olive-800)}
.pill-active .dot{background:var(--olive-500)}
.pill-planning{background:var(--blue-100);color:var(--blue-700)}
.pill-planning .dot{background:var(--blue-500)}
.pill-paused{background:var(--amber-100);color:var(--amber-700)}
.pill-paused .dot{background:var(--amber-500)}
.pill-done{background:var(--draft-bg);color:var(--text-2)}
.pill-done .dot{background:#9aa394}

/* ---------- reports ---------- */
.rep-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:16px}
.rep-card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:16px;display:flex;flex-direction:column;gap:11px;box-shadow:var(--shadow-sm);
}
.rep-card h3{font-size:13.5px;font-weight:700}
.rep-card p{font-size:12px;color:var(--text-3);margin-top:3px;line-height:1.5}
.rc-main{flex:1}
.btn-sm{padding:7px 10px;font-size:12.5px}
.rep-card .btn-sm{justify-content:center}

.rep-grid{display:grid;grid-template-columns:1.5fr 1fr;gap:16px}
.rep-grid .panel{min-width:0}
#view-report-taxes .panel,#view-report-sales .panel{margin-bottom:18px}
.table-vat{min-width:480px}
.table-vat .th-num{text-align:right}
.th-mix{width:130px}
.td-mix{vertical-align:middle}
.vat-stack{display:flex;height:8px;border-radius:999px;overflow:hidden;background:var(--draft-bg)}
.vat-stack i{display:block;height:100%}
.vat-stack.is-empty i{background:var(--border)}
.vat-panel-empty{font-size:12px;color:var(--text-3);margin-top:2px}

/* ---------- sales report evolution chart ---------- */
/* Resets the global icon-svg rule (svg{fill:none;stroke:currentColor;...},
   meant for 24x24 outline icons) which otherwise draws a bold stroke around
   every bar/dot/glyph in this chart. Stroke is re-declared below only on
   the elements that actually need one (grid, line, hatch). */
.evo-chart{width:100%;height:auto;overflow:visible;fill:currentColor;stroke:none}
.evo-chart *{stroke:none}
.evo-grid{stroke:var(--border);stroke-width:1}
.evo-axis-label{font-size:10px;fill:var(--text-3)}
.evo-axis-title{font-size:10px;fill:var(--text-3);text-transform:uppercase;letter-spacing:.04em}
.evo-month-label{font-size:11px;fill:var(--text-2)}
.evo-bar-gross{fill:var(--olive-500)}
.evo-bar-tax{fill:url(#evoTaxHatch)}
.evo-hatch-bg{fill:var(--blue-100)}
.evo-hatch-line{stroke:var(--blue-500);stroke-width:2}
.evo-line{fill:none;stroke:var(--rust-500);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.evo-dot{fill:var(--rust-500)}
.lg-swatch{width:14px;height:10px;border-radius:2px;display:inline-block;background:var(--blue-100);border:1px solid var(--blue-500);position:relative;overflow:hidden}
.lg-swatch.lg-hatch{background-image:repeating-linear-gradient(45deg,var(--blue-500) 0,var(--blue-500) 1px,transparent 1px,transparent 4px)}

.age-row{display:grid;grid-template-columns:112px 1fr auto auto;gap:12px;align-items:center;padding:11px 2px}
.age-row + .age-row{border-top:1px solid var(--border)}
.age-label{font-size:12px;font-weight:600;color:var(--text-2)}
.age-bar{height:8px;border-radius:999px;background:var(--draft-bg);overflow:hidden}
.age-bar i{display:block;height:100%;border-radius:999px}
.age-bar i.ab-ok{background:var(--olive-500)}
.age-bar i.ab-soon{background:var(--amber-500)}
.age-bar i.ab-mid{background:var(--rust-500)}
.age-bar i.ab-late{background:var(--rust-700)}
.age-amt{font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums;min-width:92px;text-align:right}
.age-count{font-size:11px;color:var(--text-3);min-width:52px;text-align:right}

/* ---------- settings ---------- */
.set-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}

/* my-profile: identity card full width, password/preferences side by side,
   one shared save bar — avoids uneven columns leaving holes */
.profile-grid{margin-top:16px;display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:stretch}
.profile-grid .set-card{display:flex;flex-direction:column}
.profile-grid .set-body{flex:1}
.profile-savebar{margin-top:16px;border-radius:var(--radius-lg);border:1px solid var(--border)}
.savebar-hint{font-size:12px;color:var(--text-3)}
@media (max-width:900px){
  .profile-grid{grid-template-columns:1fr}
  .savebar-hint{display:none}
}
.set-card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-sm);overflow:hidden;
}
.set-head{padding:15px 18px;border-bottom:1px solid var(--border)}
.set-head h3{font-size:14.5px;font-weight:700}
.set-head p{font-size:12px;color:var(--text-3);margin-top:2px}
.set-body{padding:16px 18px;display:flex;flex-direction:column;gap:14px}
.set-foot{
  padding:13px 18px;border-top:1px solid var(--border);background:var(--surface-2);
  display:flex;align-items:center;justify-content:flex-end;gap:10px;
}
.set-note{font-size:11.5px;color:var(--text-3)}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.set-row{display:flex;align-items:center;justify-content:space-between;gap:14px}
.set-row-main{display:flex;flex-direction:column;gap:1px;min-width:0}
.set-row-main strong{font-size:13px;font-weight:600}
.set-row-main span{font-size:11.5px;color:var(--text-3)}

/* settings › plan pricing cards */
.set-card-pricing{grid-column:1/-1}
.pricing-banner{
  display:flex;align-items:center;gap:12px;
  padding:12px 16px;border-radius:var(--radius-lg);
  background:linear-gradient(120deg,var(--olive-100),var(--olive-50) 60%,var(--amber-100));
  border:1px solid var(--olive-200);
}
.pricing-banner-icon{
  width:34px;height:34px;flex-shrink:0;display:grid;place-items:center;
  border-radius:999px;background:var(--olive-600);color:#fff;box-shadow:var(--shadow-sm);
}
.pricing-banner-icon svg{width:18px;height:18px}
.pricing-banner-text{display:flex;flex-direction:column;gap:1px;min-width:0}
.pricing-banner-text strong{font-size:13.5px;color:var(--olive-900)}
.pricing-banner-text span{font-size:11.5px;color:var(--olive-700)}

.pricing-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;align-items:stretch}
.pricing-card{
  position:relative;display:flex;flex-direction:column;gap:10px;
  padding:18px 16px 16px;border-radius:var(--radius-lg);
  background:var(--surface);border:1px solid var(--border);
  box-shadow:var(--shadow-sm);transition:border-color .15s,box-shadow .15s,transform .15s;
}
.pricing-card:hover{border-color:var(--olive-300);box-shadow:var(--shadow-md);transform:translateY(-2px)}
.pricing-card.is-popular{
  border:2px solid var(--olive-500);
  background:linear-gradient(180deg,var(--olive-50),var(--surface) 120px);
  box-shadow:var(--shadow-md);
}
.pricing-flag{
  position:absolute;top:-11px;left:50%;transform:translateX(-50%);
  background:var(--olive-600);color:#fff;font-size:10.5px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;
  padding:3px 12px;border-radius:999px;white-space:nowrap;box-shadow:var(--shadow-sm);
}
.pricing-card h4{font-size:14px;font-weight:700;color:var(--ink)}
.pricing-price{display:flex;align-items:baseline;gap:5px}
.pricing-now{
  font-size:27px;font-weight:800;letter-spacing:-.02em;color:var(--olive-800);
  font-variant-numeric:tabular-nums;
}
.pricing-per{font-size:11.5px;color:var(--text-3);font-weight:600}
.pricing-note{font-size:11.5px;color:var(--text-3);line-height:1.45;margin:0}
.pricing-was{
  text-decoration:line-through;font-weight:600;color:var(--rust-500);
  font-variant-numeric:tabular-nums;margin-right:4px;
}
.pricing-feats{list-style:none;margin:2px 0 auto;padding:0;display:flex;flex-direction:column;gap:6px}
.pricing-feats li{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text-2)}
.pricing-feats svg{width:14px;height:14px;flex-shrink:0;color:var(--olive-600)}
.pricing-card form{margin-top:10px}
.pricing-disclaimer{font-size:11px;color:var(--text-3);margin:0}
@media(max-width:1024px){
  .pricing-grid{grid-template-columns:1fr}
}

/* toggle switch */
.switch{position:relative;display:inline-block;width:42px;height:24px;flex-shrink:0}
.switch input{position:absolute;inset:0;width:100%;height:100%;opacity:0;margin:0;cursor:pointer}
.switch .track{
  position:absolute;inset:0;border-radius:999px;pointer-events:none;
  background:var(--draft-bg);border:1px solid var(--border-strong);
  transition:background .18s,border-color .18s;
}
.switch .track::before{
  content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;
  background:#fff;box-shadow:var(--shadow-sm);transition:transform .18s ease;
}
.switch input:checked + .track{background:var(--olive-500);border-color:var(--olive-600)}
.switch input:checked + .track::before{transform:translateX(18px)}
.switch input:focus-visible + .track{outline:2px solid var(--olive-500);outline-offset:2px}

/* ============================================================
   SETTINGS · tabs + companies / users / invoices / taxes / connections
   Ported from theme/styles.css (lines 1643-1813, minus the .pv-doc /
   .pv-iframe block — this app's invoice preview uses .doc-sheet, not
   .pv-doc, so those rules would be dead here).
   ============================================================ */
.set-tabs{
  display:flex;gap:2px;margin-bottom:18px;overflow-x:auto;-webkit-overflow-scrolling:touch;
  border-bottom:1px solid var(--border);scrollbar-width:none;
}
.set-tabs::-webkit-scrollbar{display:none}
.set-tab{
  position:relative;display:inline-flex;align-items:center;gap:7px;
  padding:10px 13px;font-size:13px;font-weight:600;color:var(--text-3);
  border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap;flex-shrink:0;
  transition:color .15s,border-color .15s;background:transparent;border-left:0;border-right:0;border-top:0;
}
.set-tab svg{width:15px;height:15px}
.set-tab:hover{color:var(--text-2)}
.set-tab.is-on{color:var(--olive-700);border-bottom-color:var(--olive-500)}
.set-span2{grid-column:1/-1}
/* settings › titled section header sitting above each .set-grid (invoices tab) */
.set-section{margin:24px 0 12px}
.set-section:first-child{margin-top:0}
.set-section h2{font-size:15.5px;font-weight:700}
.set-section p{margin-top:3px;font-size:12.5px;color:var(--text-3)}
/* settings › two-sided card head: title + description left, controls right */
.set-head-row{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.set-head-row .shr-text{min-width:0}
.set-head-row .shr-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
/* settings › numbering-series card: its tables sit flush against the card
   edges (no body padding / gap), one visible pane at a time */
.set-body-flush{padding:0;gap:0}

/* inline pill tags (role / status / tax groups) */
.tag{
  display:inline-flex;align-items:center;gap:5px;padding:2.5px 9px;border-radius:999px;
  font-size:11px;font-weight:700;letter-spacing:.01em;vertical-align:1px;
}
.tag-neutral{background:var(--surface-2);color:var(--text-2);border:1px solid var(--border)}
.tag-outline-olive{border:1px solid var(--olive-300);color:var(--olive-700)}

/* settings tables (companies / users / taxes) */
.table-set td{vertical-align:middle}
.table-set .c-name{font-size:13px;font-weight:600;color:var(--text);display:block}
.table-set .c-sub{font-size:11.5px;color:var(--text-3);display:block;margin-top:1px}
.set-star{color:var(--text-3);background:none;border:0;cursor:pointer;padding:0;display:inline-flex}
.set-star svg{fill:none}
.set-star.is-active{color:var(--olive-500)}
.set-star.is-active svg{fill:currentColor}
.set-star.is-active:disabled{opacity:1}
tr.is-default-co .c-name{color:var(--text)}
.co-cell{display:flex;align-items:center;gap:10px;min-width:0}
.icon-btn:disabled,.icon-btn.is-disabled{opacity:.32;cursor:not-allowed}
.icon-btn:disabled:hover,.icon-btn.is-disabled:hover{background:transparent;color:var(--text-3)}
.icon-btn.arm{background:var(--rust-100);color:var(--rust-700)}
.icon-btn.arm:hover{background:var(--rust-100);color:var(--rust-700)}
.icon-btn.arm svg{fill:none}

/* invoice template picker */
.tpl-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.tpl-card{
  background:var(--surface);border:1.5px solid var(--border);border-radius:var(--radius);
  padding:9px;display:flex;flex-direction:column;gap:8px;cursor:pointer;text-align:left;
  transition:border-color .15s,box-shadow .15s,transform .05s;
}
.tpl-card:hover{border-color:var(--olive-300)}
.tpl-card:active{transform:translateY(1px)}
.tpl-card.is-on{border-color:var(--olive-500);box-shadow:0 0 0 3px var(--olive-100)}
.tpl-card:focus-visible{outline:2px solid var(--olive-600);outline-offset:2px}
.tpl-thumb{
  border:1px solid var(--border);border-radius:6px;overflow:hidden;background:#ffffff;
  aspect-ratio:4/5;display:block;
}
.tpl-thumb svg{width:100%;height:100%;display:block}
.tpl-meta{display:flex;align-items:center;justify-content:space-between;gap:8px}
.tpl-name{font-size:12.5px;font-weight:600;color:var(--text)}
.tpl-desc{font-size:10.5px;color:var(--text-3);display:block;margin-top:1px;font-weight:500}
.tpl-dot{width:16px;height:16px;border-radius:50%;display:grid;place-items:center;flex-shrink:0;background:var(--surface-2);color:transparent}
.tpl-card.is-on .tpl-dot{background:var(--olive-500);color:#fff}
.tpl-dot svg{width:9px;height:9px;stroke-width:3}

/* template card foot · Edit HTML + custom badge */
.tpl-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:12px}
.tpl-mod{
  display:inline-flex;align-items:center;font-size:9.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--olive-700);background:var(--olive-50);border:1px solid var(--olive-300);
  border-radius:99px;padding:2px 7px;margin-left:6px;vertical-align:1px;
}
.tpl-custom-note{color:var(--olive-700);font-weight:700}

/* ---------- template HTML code editor (wide modal) ---------- */
.modal-wide{width:min(1120px,calc(100vw - 24px))}
.tc-body{gap:12px}
.tc-toolbar{display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap}
.tc-tpl-field{width:200px;flex-shrink:0}
.tc-tpl-field label{display:none}
.tc-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;flex:1;min-width:0}
.tc-chips-label{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-3);margin-right:2px}
.tc-chip{
  font-family:ui-monospace,'Sarasa Mono SC',SFMono-Regular,Menlo,Consolas,monospace;
  font-size:10.5px;font-weight:600;color:var(--text-2);background:var(--surface-2);
  border:1px solid var(--border);border-radius:6px;padding:3px 7px;cursor:pointer;
  transition:border-color .15s,color .15s,background .15s;
}
.tc-chip:hover{border-color:var(--olive-300);color:var(--olive-700);background:var(--olive-50)}
.tc-chip-key{color:var(--olive-700);border-color:var(--olive-300);font-weight:700}
/* The DEFINITE height lives on the grid row, and it has to: .tc-editor
   carries `flex:1` (= flex-basis:0%) inside the column-flex .tc-pane, so a
   `height` there is overridden and the editor resolves against its content
   instead. Without a definite row the textarea grew to the full height of
   the template (12000px+ for a real one) and scrolled nothing — .modal-body
   scrolled instead — which made `tcCode.scrollTop` a silent no-op in
   revealSearchHit() and left Ctrl/Cmd+F unable to jump to a match far down.
   Every child in the chain below needs min-height:0 to be allowed to shrink
   into it. */
.tc-panes{display:grid;grid-template-columns:1.08fr .92fr;grid-auto-rows:clamp(340px,52vh,560px);gap:12px;align-items:stretch}
.tc-pane{display:flex;flex-direction:column;min-width:0;min-height:0;border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface)}
.tc-pane-head{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:8px 12px;border-bottom:1px solid var(--border);background:var(--surface-2);
  font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--text-3);
}
.tc-pane-hint{text-transform:none;letter-spacing:0;font-weight:500;font-size:11px}
.tc-editor{position:relative;display:flex;flex:1;min-height:0;background:var(--surface-2);overflow:hidden}
.tc-editor-body{position:relative;display:flex;flex:1;min-width:0}
.tc-editor .tc-gutter,.tc-editor .tc-search-marks,.tc-editor .tc-code{
  font-family:ui-monospace,'Sarasa Mono SC',SFMono-Regular,Menlo,Consolas,monospace;
  font-size:12.5px;line-height:1.65;tab-size:2;font-variant-ligatures:none;
}
.tc-gutter{
  flex:none;min-width:42px;padding:14px 10px 14px 14px;text-align:right;overflow:hidden;white-space:pre;
  color:var(--text-3);background:color-mix(in srgb,var(--surface-2) 82%,var(--border));border-right:1px solid var(--border);user-select:none;
  font-variant-numeric:tabular-nums;
}
.tc-editor .tc-search-marks,.tc-editor .tc-code{
  margin:0;padding:14px 16px;border:0;white-space:pre;overflow-wrap:normal;
  letter-spacing:normal;word-spacing:normal;
}
.tc-search-marks{
  position:absolute;inset:0;overflow:hidden;pointer-events:none;color:var(--text);background:none;
}
.tc-search-marks{color:transparent}
.tc-search-marks mark{color:transparent;background:color-mix(in srgb,var(--amber-500) 34%,transparent);border-radius:2px}
.tc-search-marks mark.is-active{background:color-mix(in srgb,var(--olive-500) 42%,transparent);box-shadow:0 0 0 1px var(--olive-300)}
.tc-code{
  /* min-height:0 is what lets the textarea shrink to .tc-editor's definite
     height and scroll its own content — a min-height here would re-inflate
     it and break Ctrl/Cmd+F scrolling again (see .tc-editor above). */
  position:relative;display:block;flex:1;min-width:0;width:100%;min-height:0;resize:none;outline:none;
  background:none;color:var(--text);caret-color:var(--olive-600);overflow:auto;
}
.tc-code::selection{background:color-mix(in srgb,var(--olive-300) 38%,transparent)}
.tc-code:focus{box-shadow:inset 0 0 0 2px var(--olive-300)}
.tc-find{
  position:absolute;z-index:3;top:9px;right:12px;display:flex;align-items:center;gap:4px;
  padding:5px 6px 5px 9px;border:1px solid var(--border);border-radius:8px;
  background:var(--surface);box-shadow:var(--shadow-md);
}
.tc-find[hidden]{display:none}
.tc-find-icon{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:2;color:var(--text-3)}
.tc-find-input{width:180px;border:0;background:none;outline:none;color:var(--text);font-size:12px;padding:3px 2px}
.tc-find-count{flex:none;min-width:48px;text-align:right;color:var(--text-3);font-size:11px;font-variant-numeric:tabular-nums}
.tc-find-count.is-empty{color:var(--rust-700)}
.tc-find-separator{width:1px;height:18px;background:var(--border);margin:0 2px}
.tc-find-button{
  min-width:26px;height:26px;padding:0 5px;border:1px solid transparent;border-radius:6px;
  display:inline-flex;align-items:center;justify-content:center;background:none;color:var(--text-2);
  font-size:11px;font-weight:700;cursor:pointer;
}
.tc-find-button:hover{background:var(--surface-2);color:var(--text)}
.tc-find-button[aria-pressed="true"]{background:var(--olive-100);border-color:var(--olive-300);color:var(--olive-700)}
.tc-find-button svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.tc-prev-wrap{flex:1;min-height:0;background:var(--surface-2);display:block;overflow:auto}
#tcPrev{width:100%;min-height:0;height:100%;border:0;display:block;background:#ffffff}
.btn-armed{border-color:var(--rust-500)!important;color:var(--rust-700)!important;background:var(--rust-100)!important}

/* invoice logo uploader */
.logo-row{display:flex;gap:14px;align-items:center}
.inv-logo-tile{
  width:220px;height:104px;max-width:45%;flex-shrink:0;border-radius:var(--radius);
  border:1.5px solid var(--border-strong);display:grid;place-items:center;overflow:hidden;
  color:var(--text-3);background:var(--surface);cursor:pointer;transition:border-color .15s,background .15s,box-shadow .15s;
}
.inv-logo-tile:hover,.inv-logo-tile:focus-visible,.inv-logo-tile.drag{border-color:var(--olive-500);background:var(--olive-50);box-shadow:0 0 0 3px var(--olive-100);outline:0}
.inv-logo-tile svg{width:22px;height:22px}
.inv-logo-tile img{width:100%;height:100%;object-fit:contain;background:#ffffff;padding:8px}
.inv-logo-tile.is-empty{border-style:dashed}
.logo-meta{display:flex;flex-direction:column;gap:8px;min-width:0}
.logo-actions{display:flex;gap:8px;flex-wrap:wrap}

/* invoice texts */
/* single column: the texts card sits in a 1-column grid cell next to the
   logo card, so the three textareas stack instead of squeezing 3-across */
.texts-grid{display:grid;grid-template-columns:1fr;gap:14px}

/* subscription */
.set-foot-actions{display:flex;gap:10px;justify-content:flex-end}

/* connections */
.conn-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;padding:16px}
.conn-card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:15px;display:flex;flex-direction:column;gap:11px;box-shadow:var(--shadow-sm);min-width:0;
}
.conn-card.is-on{border-color:var(--olive-300)}
.conn-top{display:flex;align-items:center;gap:11px}
.conn-ic{
  width:42px;height:42px;border-radius:12px;flex-shrink:0;display:grid;place-items:center;
  font-size:15px;font-weight:800;letter-spacing:.02em;user-select:none;
}
.conn-name{font-size:13.5px;font-weight:700;display:flex;align-items:center;gap:8px;min-width:0}
.conn-name .tag{flex-shrink:0}
.conn-desc{font-size:12.5px;color:var(--text-2);line-height:1.5;flex:1}
.conn-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;border-top:1px solid var(--border);padding-top:11px}
.conn-status{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:600;color:var(--text-3);min-width:0}
.conn-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.conn-dot.on{background:var(--olive-500);box-shadow:0 0 0 3px var(--olive-100)}
.conn-dot.off{background:var(--border-strong)}
.conn-meta{font-size:11.5px;color:var(--text-2);background:var(--surface-2);border:1px dashed var(--border);border-radius:8px;padding:8px 11px}
.conn-foot-actions{display:flex;gap:8px;flex-shrink:0}

/* store list inside the connection modal (ported from the theme) */
.conn-store-list{display:flex;flex-direction:column;gap:8px}
.conn-store{
  display:flex;align-items:center;gap:12px;padding:10px 12px;
  border:1px solid var(--border);border-radius:10px;background:var(--surface-2);
}
.conn-store-main{flex:1;min-width:0}
.conn-store-main strong{display:block;font-size:13px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.conn-store-main span{display:block;font-size:11px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.conn-store-tags{display:flex;gap:6px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}
.conn-store-actions{display:flex;gap:6px;flex-shrink:0;align-items:center}
.mini-chip{font-size:10px;font-weight:600;background:var(--draft-bg);color:var(--text-2);border-radius:999px;padding:2px 8px;white-space:nowrap}
.mini-chip.tint{background:var(--olive-100);color:var(--olive-800)}
.conn-back{display:inline-flex;align-items:center;gap:5px;align-self:flex-start}
.conn-back svg{width:13px;height:13px}

/* "Connect another store" inline form */
.conn-add-store{margin-top:12px;display:flex;flex-direction:column;gap:6px}
.conn-add-store label{font-size:12.5px;font-weight:600}
.conn-add-store-row{display:flex;gap:8px}
.conn-add-store-row .input{flex:1;min-width:0}

/* inline checkbox row inside modal forms (new-user invite email switch);
   reuses .check-row behaviour styling, scoped to not clash with .field */
.field-check{margin-top:-4px}
.field-check label{font-size:13px;font-weight:600;color:var(--text);cursor:pointer}
.field-check ul.field-errors{margin-top:6px}

/* behaviour checkboxes (connection settings, ported from the theme) */
.cs-divider{height:1px;background:var(--border);margin:14px 0 10px}
.check-row{display:flex;align-items:flex-start;gap:11px}
.check-row input[type="checkbox"]{
  width:16px;height:16px;margin-top:2px;flex-shrink:0;cursor:pointer;
  accent-color:var(--olive-600);
}
.check-main{display:flex;flex-direction:column;gap:2px;min-width:0}
.check-main label{font-size:13px;font-weight:600;color:var(--text);cursor:pointer}
.check-main > span{font-size:11.5px;color:var(--text-3)}
.cs-state-line{margin-top:6px}
.cs-state-line .select-inline{min-width:110px}

@media (max-width:1020px){
  .conn-grid{grid-template-columns:1fr}
  .tc-panes{grid-template-columns:1fr;grid-auto-rows:clamp(250px,46vh,460px)}
}
@media (max-width:760px){
  .tpl-grid{grid-template-columns:1fr 1fr}
  .conn-foot{flex-direction:column;align-items:stretch}
  .conn-foot .btn{justify-content:center}
  .tc-tpl-field{width:100%}
  .tc-panes{grid-auto-rows:clamp(210px,42vh,380px)}
  .tc-find{left:8px;right:8px}
  .tc-find-input{width:auto;min-width:0;flex:1}
  .modal-wide .modal-foot{flex-wrap:wrap;gap:10px}
  .modal-wide .mf-actions{width:100%;margin-left:0}
  .modal-wide .mf-actions .btn{flex:1;justify-content:center}
}

/* ---------- responsive for new views ---------- */
@media (min-width:761px) and (max-width:1080px){
  .rep-cards{grid-template-columns:1fr 1fr}
}
@media (max-width:920px){
  .dash-grid,.rep-grid,.set-grid{grid-template-columns:1fr}
  .proj-grid{grid-template-columns:1fr}
  .rep-cards{grid-template-columns:1fr 1fr}
}
@media (max-width:640px){
  .rep-cards{grid-template-columns:1fr}
  .form-grid{grid-template-columns:1fr}
  .barchart{gap:6px}
  .bc-bar{width:12px}
  .age-row{grid-template-columns:96px 1fr auto;gap:8px}
  .age-count{display:none}
}

/* ============================================================
   SIDEBAR USER MENU · opens upward from the sidebar bottom
   ============================================================ */
.sidebar-user .menu.menu-up{
  top:auto;bottom:calc(100% + 12px);left:0;right:auto;
  transform-origin:bottom left;min-width:280px;
}
/* icon rail → avatar only, menu flies out to the right */
@media (min-width:761px) and (max-width:1080px){
  .sidebar-user{padding-top:12px;gap:0}
  .sidebar-user .user-btn{width:auto;padding:5px;border-radius:12px}
  .ub-meta,.sidebar-user .chev{display:none}
  .su-wrap{position:static;display:flex;justify-content:center}
  .sidebar-user .menu.menu-up{left:calc(100% + 14px);bottom:-2px;min-width:262px}
}
/* mobile drawer → bottom-sheet style menu anchored to the viewport */
@media (max-width:760px){
  .su-wrap{position:static}
  .sidebar-user .menu.menu-up{position:fixed;left:12px;right:12px;bottom:12px;min-width:0;width:auto}
}

/* ============================================================
   PROJECT ↔ INVOICE LINKING
   ============================================================ */
.th-proj{width:150px}
.td-proj{white-space:nowrap}
.td-proj .p-none{color:var(--text-3);font-size:12px}
.pill.proj-link{cursor:pointer;border:none;transition:box-shadow .15s,transform .05s}
.pill.proj-link:hover{box-shadow:var(--shadow-sm)}
.pill.proj-link:active{transform:translateY(1px)}
@media (max-width:920px){
  .th-proj,.td-proj{display:none}
}

.pc-inv{display:flex;flex-direction:column;gap:8px}
.pc-inv-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.pc-inv-top .link-btn{flex-shrink:0}
.pc-inv-title{
  font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.pc-inv-title strong{color:var(--text);font-size:12px;font-variant-numeric:tabular-nums}
.pc-inv-title em{font-style:normal;text-transform:none;letter-spacing:0;color:var(--amber-700);font-weight:600}
.pc-inv-chips{display:flex;flex-wrap:wrap;gap:6px}
.pc-inv-chip{
  display:inline-flex;align-items:center;gap:6px;
  font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:999px;
  border:1px solid var(--border);background:var(--surface-2);color:var(--text-2);
  transition:border-color .15s,background .15s,color .15s;
}
.pc-inv-chip:hover{border-color:var(--olive-300);background:var(--olive-50);color:var(--olive-900)}
.pc-inv-chip .dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.pc-inv-chip span{font-weight:600;color:var(--text-3);font-variant-numeric:tabular-nums}
.pc-inv-empty{font-size:12px;color:var(--text-3)}
.proj-card.flash-card{animation:cardFlash 1.6s ease}
@keyframes cardFlash{0%{background:var(--olive-100);border-color:var(--olive-300)}100%{background:var(--surface)}}

.label-opt{color:var(--text-3);font-weight:500;font-size:11px;letter-spacing:0}

/* ============================================================
   CLIENTS VIEW
   ============================================================ */
.panel-title{font-size:13.5px;font-weight:700}
.table-clients{min-width:660px}
.c-plain{color:var(--text-2);font-weight:500}
.o-warn{color:var(--amber-700)}
.td-num{font-variant-numeric:tabular-nums}

/* ============================================================
   PRODUCTS VIEW
   ============================================================ */
.prod-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.prod-card{
  border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface);
  padding:16px;display:flex;flex-direction:column;gap:11px;min-width:0;
  transition:border-color .15s,box-shadow .15s;
}
.prod-card:hover{border-color:var(--olive-300);box-shadow:var(--shadow-sm)}
.prod-top{display:flex;align-items:center;gap:11px}
.prod-name{min-width:0;flex:1}
.prod-name h3{font-size:14px;font-weight:700;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.prod-name span{font-size:11.5px;color:var(--text-3)}
.prod-desc{font-size:12.5px;color:var(--text-2);line-height:1.5;flex:1}
.prod-chips{display:flex;flex-wrap:wrap;gap:6px}
.pchip{
  display:inline-flex;align-items:center;gap:5px;
  font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:999px;
  background:var(--draft-bg);color:var(--text-2);white-space:nowrap;
}
.pchip-price{background:var(--olive-100);color:var(--olive-800)}
.pchip-muted{background:transparent;border:1px solid var(--border)}
.prod-usage{display:flex;align-items:center;gap:10px;padding-top:11px;border-top:1px solid var(--border)}
.prod-usage .p-bar{height:6px}
.prod-usage strong{font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.kpi-topname{font-size:16.5px;line-height:1.3}

/* product editor */
.pe-back{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;color:var(--olive-700);padding:4px 10px 4px 7px;margin-bottom:10px;border-radius:999px;background:var(--olive-50);border:1px solid var(--olive-100)}
.pe-back:hover{background:var(--olive-100);border-color:var(--olive-300)}
.pe-back svg{width:14px;height:14px}
.pe-grid{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:18px;align-items:start}
.pe-main,.pe-side{display:flex;flex-direction:column;gap:18px;min-width:0}
.pe-form,.pe-sum{display:flex;flex-direction:column;gap:14px}
.pe-client-meta{display:flex;flex-direction:column;min-width:0}
.pe-client-meta strong{font-size:13px;font-weight:700;overflow:hidden;text-overflow:ellipsis}
.pe-client-meta span{font-size:11.5px;color:var(--text-3)}
.pe-clientbox{display:flex;flex-direction:column;gap:7px;padding-top:13px;border-top:1px solid var(--border)}
/* summary panel (invoice / expense edit screens): the Total card stands out
   from the sibling stats and trailing notes stay muted */
.stat-card-total .stat-value{font-size:19px;color:var(--olive-900)}
.pe-sum-hint{margin:0;font-size:12px;line-height:1.45;color:var(--text-3)}
.ex-payrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pe-inv-list{display:flex;flex-direction:column;gap:8px}
.pe-inv-row{display:flex;align-items:center;gap:12px;width:100%;min-width:0;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface-2);transition:border-color .15s,background .15s}
.pe-inv-row:hover{border-color:var(--olive-300);background:var(--olive-50)}
.pe-inv-id{font-size:12.5px;font-weight:700;white-space:nowrap}.pe-inv-date{font-size:12px;color:var(--text-3);white-space:nowrap}.pe-inv-amt{margin-left:auto;font-size:12.5px;font-weight:700;white-space:nowrap}.pe-inv-go{width:15px;height:15px;color:var(--text-3)}.pe-inv-empty{font-size:12.5px;color:var(--text-3)}
.pe-inv-remove{margin-left:auto}
#dAddEmploymentToggle{margin-top:10px}
.pe-add-employment{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding-top:10px;margin-top:2px;border-top:1px solid var(--border)}
.pe-add-employment select{flex:1;min-width:140px}
.pe-add-actions{display:flex;gap:8px;width:100%}
.prd-profile .icon-chip{width:44px;height:44px;border-radius:12px}.prd-rev{font-size:15px;font-weight:800}.prod-top .icon-btn{width:28px;height:28px}
.product-usage-panel{margin-top:18px}

/* product main image — catalog card thumb + editor/modal picker + lightbox */
.prd-img-row{display:flex;align-items:center;gap:12px}
.prd-img-tile{
  width:72px;height:72px;border-radius:12px;overflow:hidden;flex-shrink:0;
  display:grid;place-items:center;color:var(--text-3);
  border:1px dashed var(--border);background:var(--surface-2);
}
.prd-img-tile svg{width:24px;height:24px}
.prd-img-tile:not(.is-empty){border-style:solid;border-color:var(--border)}
.prd-img-tile img{width:100%;height:100%;object-fit:cover;display:block}
.prd-img-meta{display:flex;flex-direction:column;gap:6px;min-width:0}
.prd-img-actions{display:flex;align-items:center;gap:8px}
.prd-img-hint{font-size:11.5px;color:var(--text-3)}
.icon-chip.has-img{padding:0;overflow:hidden}
.icon-chip.has-img img{width:100%;height:100%;object-fit:cover;display:block}
/* product thumbnail in the >3 paginated list table (matches .vendor-cell avatar slot) */
.prod-thumb{width:28px;height:28px;border-radius:50%;overflow:hidden;flex-shrink:0;border:1px solid var(--border);background:var(--surface-2)}
.prod-thumb img{width:100%;height:100%;object-fit:cover;display:block}
/* the editor tile invites a click only when it actually holds an image */
#prdImgTile.prd-img-tile:not(.is-empty){cursor:zoom-in}

/* create-modal image drop zone — same pattern as theme .imp-drop */
.pd-drop{
  border:1.5px dashed var(--border-strong);border-radius:12px;background:var(--surface-2);
  padding:20px 16px;text-align:center;cursor:pointer;outline:none;
  display:flex;flex-direction:column;align-items:center;gap:6px;
  transition:border-color .15s,background .15s;
}
.pd-drop:hover,.pd-drop:focus-visible,.pd-drop.drag{
  border-color:var(--olive-500);background:var(--olive-50);
}
.pd-drop-main{font-size:13.5px;font-weight:600;color:var(--text);margin:0}
.pd-drop-or{color:var(--olive-700)}
.pd-drop-hint{font-size:11.5px;line-height:1.5;color:var(--text-3);max-width:440px}
.pd-drop-icon{width:26px;height:26px;color:var(--olive-700);flex-shrink:0}
.pd-drop .prd-img-tile{width:72px;height:72px}
.pd-drop .prd-img-actions{margin-top:4px}
.pd-drop.has-preview .pd-drop-main,
.pd-drop.has-preview .pd-drop-hint{display:none}

/* Always hide product image file inputs (native [hidden] + id fallback).
   Compiled CSS can lag; the HTML hidden attribute alone is the theme's approach. */
#pdImgInput,
#prdImgInput,
#prdImgRemoveInput,
#ceAttInput,
input[type="file"][hidden]{
  display:none!important;
  position:absolute!important;
  width:1px!important;height:1px!important;
  opacity:0!important;pointer-events:none!important;
  clip:rect(0 0 0 0)!important;border:0!important;padding:0!important;margin:-1px!important;
  overflow:hidden!important;
}
.hidden{display:none!important}

/* image lightbox (product editor tile) — topmost layer above all overlays */
.lb-overlay{z-index:75}
.lb-figure{position:relative;margin:0;display:flex;flex-direction:column;align-items:center;gap:10px;max-width:min(92vw,1100px)}
.lb-img{max-width:92vw;max-height:80vh;object-fit:contain;border-radius:14px;box-shadow:0 24px 64px rgba(0,0,0,.5);background:#fff}
.lb-close{position:absolute;top:-13px;right:-13px;width:34px;height:34px;border-radius:50%;background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-md)}
.lb-close svg{width:16px;height:16px}
.lb-caption{font-size:12px;font-weight:600;color:rgba(255,255,255,.94);text-shadow:0 1px 6px rgba(0,0,0,.65);max-width:92vw;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.pe-danger .panel-body{display:flex;flex-direction:column;gap:8px}.pe-danger h3{font-size:13.5px;color:var(--rust-700)}.pe-danger p{font-size:12px;color:var(--text-3)}
.pe-delete{align-self:flex-start;margin-top:2px;border-color:var(--border);background:var(--surface);color:var(--rust-700)}.pe-delete:hover{border-color:var(--rust-500);background:var(--rust-100)}.pe-delete.arm{background:var(--rust-500);border-color:var(--rust-500);color:#fff}
.field-errors{margin-top:5px;color:var(--rust-700);font-size:11.5px}.input.invalid,[aria-invalid="true"]{border-color:var(--rust-500)}

/* client edit screen — side profile + contact rows */
.ce-profile{display:flex;align-items:center;gap:12px;padding-bottom:13px;border-bottom:1px solid var(--border)}
.ce-profile .pe-client-meta{gap:2px}
.ce-profile .pe-client-meta strong{font-size:14.5px}
.ce-profile .pe-client-meta span{font-size:12px}
.ce-contact{display:flex;flex-direction:column;gap:8px;list-style:none;margin:0;padding:0}
.ce-crow{display:flex;align-items:flex-start;gap:9px;font-size:12.5px;color:var(--text-2);line-height:1.45;min-width:0}
.ce-crow svg{width:14px;height:14px;color:var(--text-3);flex-shrink:0;margin-top:2px}
.ce-crow span{overflow-wrap:anywhere}

/* client editor tabs — reuses .tabs/.tab tokens; panes stack like .pe-main */
.ce-tabs{flex-shrink:0}
.ce-pane{display:flex;flex-direction:column;gap:18px;min-width:0}
.ce-pane[hidden]{display:none}

/* client edit screen — bank account cards (SEPA mandates) */
.ba-list{display:flex;flex-direction:column;gap:10px}
.ba-card{border:1px solid var(--border);border-radius:12px;background:var(--surface-2);padding:10px 12px 12px;position:relative}
.ba-card.is-def{border-color:var(--olive-400);box-shadow:inset 3px 0 0 var(--olive-400)}
.ba-head{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:9px}
.ba-def{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;color:var(--text-3);cursor:pointer;user-select:none}
.ba-card.is-def .ba-def{color:var(--olive-700)}
.ba-def input{position:absolute;opacity:0;width:1px;height:1px;margin:0}
.ba-radio{width:16px;height:16px;border:2px solid var(--border-strong);border-radius:50%;position:relative;flex-shrink:0;transition:border-color .15s}
.ba-def:hover .ba-radio{border-color:var(--olive-400)}
.ba-def input:checked + .ba-radio{border-color:var(--olive-600)}
.ba-def input:checked + .ba-radio::after{content:'';position:absolute;inset:2px;border-radius:50%;background:var(--olive-600)}
.ba-def input:focus-visible + .ba-radio{outline:2px solid var(--olive-400);outline-offset:2px}
.ba-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.ba-span2{grid-column:1/-1}
.ba-mono{font-family:ui-monospace,'Sarasa Mono SC',SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;letter-spacing:.02em}
.ba-empty{border:1.5px dashed var(--border);border-radius:12px;padding:16px 14px;font-size:12.5px;color:var(--text-3);text-align:center;line-height:1.5}
.ba-head .icon-btn{width:28px;height:28px;flex-shrink:0}

/* client notes (client editor) — same card language as bank accounts */
.cn-list{display:flex;flex-direction:column;gap:10px}
.cn-card{border:1px solid var(--border);border-radius:12px;background:var(--surface-2);padding:10px 12px 12px}
.cn-head{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:9px}
.cn-who{display:flex;align-items:center;gap:8px;min-width:0}
.cn-ava{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;font-size:9px;font-weight:800;letter-spacing:.02em;flex-shrink:0;background:var(--avatar-bg);color:var(--avatar-fg)}
.cn-author{font-size:12px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cn-date{font-size:11px;color:var(--text-3);white-space:nowrap}
.cn-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.cn-span2{grid-column:1/-1}
.cn-card textarea.input{min-height:64px}

@media (max-width:920px){
  .prod-grid,.pe-grid{grid-template-columns:1fr}
}

/* ============================================================
   EXPENSES VIEW
   ============================================================ */
.table-exp{min-width:800px}
.vendor-cell{display:flex;align-items:center;gap:11px;min-width:0}
.vendor-cell .avatar{width:28px;height:28px;font-size:10px;transition:transform .15s}
.vendor-name{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}
tr:hover .vendor-cell .avatar{transform:scale(1.06)}

.cat-chip{
  display:inline-flex;align-items:center;gap:6px;
  font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:999px;white-space:nowrap;
}
.cat-chip svg{width:12px;height:12px;stroke-width:2}

.td-xdue.x-late{color:var(--rust-700);font-weight:600}

/* expense modal · VAT selector lives inside the totals box */
.t-row-ctl{display:flex;align-items:center;justify-content:space-between;gap:10px}
.t-row-ctl select{
  width:auto;min-width:92px;padding:5px 9px;font-size:12.5px;
  background:var(--surface);border:1px solid var(--border);border-radius:8px;color:var(--text);
}
.t-row-ctl select:focus{outline:none;border-color:var(--olive-500);box-shadow:0 0 0 3px var(--olive-100)}

@media (max-width:920px){
  .th-xdue,.td-xdue{display:none}
}
@media (max-width:640px){
  .t-row-ctl select{min-width:80px}
}
.att-list{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.att-row{display:flex;align-items:center;gap:10px;padding:9px 11px;border:1px solid var(--border);border-radius:10px;background:var(--surface-2)}
.att-ico{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;flex-shrink:0}
.att-ico svg{width:15px;height:15px}
.att-ico.t-pdf{background:var(--rust-100);color:var(--rust-700)}
.att-ico.t-img{background:var(--blue-100);color:var(--blue-700)}
.att-ico.t-file{background:var(--olive-100);color:var(--olive-800)}
.att-main{display:flex;min-width:0;flex:1;flex-direction:column;gap:1px}
.att-name{overflow:hidden;font-weight:600;font-size:12.5px;text-overflow:ellipsis;white-space:nowrap}
.att-meta{color:var(--text-3);font-size:11px}
.att-act{display:flex;align-items:center;gap:2px}
.att-act .icon-btn{width:26px;height:26px}
.att-act form{margin:0}
.att-empty{
  width:100%;display:flex;flex-direction:column;align-items:center;gap:3px;padding:20px 16px;
  border:1.5px dashed var(--border);border-radius:12px;background:transparent;
  color:var(--text-3);font-size:11.5px;line-height:1.45;text-align:center;
}
.att-empty strong{font-size:12.5px;font-weight:600;color:var(--text-2)}
.att-empty svg{width:18px;height:18px;margin-bottom:3px;opacity:.7}
button.att-empty{cursor:pointer;transition:border-color .15s ease,color .15s ease}
button.att-empty:hover{border-color:var(--olive-500);color:var(--olive-700)}
.attachment-upload{margin-top:10px;position:relative}
.attachment-upload .pd-drop{width:100%}
.field-hint{font-size:11.5px;color:var(--text-3);margin:0}

/* ===== Invoice document preview (templates/invoices/_document.html.twig) =====
   Browser-rendered counterpart of assets/styles/invoice-pdf.css — same
   markup, richer styling since app.css (unlike Dompdf) supports modern CSS. */
.doc-preview-panel{
    padding:28px;
    background:#fff;
}

/* ===== Invoice preview two-column layout (templates/invoices/preview.html.twig) =====
   Document on the left, compact payments aside on the right. The JS scaler
   (assets/invoices.js) scales the A4 iframe to the wrapper's actual width,
   so narrowing the document column below the sheet's natural width is safe. */
.invoice-preview-grid{
  display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:20px;align-items:start;
}
.invoice-preview-side{position:sticky;top:16px}
.doc-preview-panel .doc-frame-wrap{max-width:100%}

/* ===== Expense receipt preview (templates/expenses/show.html.twig) =====
   A plain rasterized PNG, not a scaled HTML document like the invoice
   preview above: the rasterizer already caps width at 1600px (see
   ExpenseReceiptRasterizer), so max-width:100% is all it needs to fit. */
.expense-receipt-panel{display:flex;justify-content:center;padding:20px;background:var(--surface-2)}
.expense-receipt-preview{display:block;max-width:100%;height:auto;border-radius:8px;border:1px solid var(--border);background:#fff}

.pay-summary{list-style:none;margin:0 0 14px;padding:0}
.pay-summary li{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:3px 0;font-size:13px}
.pay-summary .pay-label{color:var(--text-3)}
.pay-summary .pay-value{font-variant-numeric:tabular-nums;white-space:nowrap}
.pay-summary li.grand{border-top:1px solid var(--border-strong);margin-top:5px;padding-top:7px}
.pay-summary li.grand .pay-label{color:var(--text);font-weight:600}
.pay-summary li.grand .pay-value{font-weight:700}

.pay-history{list-style:none;margin:0;padding:0}
.pay-history li{
  position:relative;padding:9px 28px 9px 0;
  border-top:1px solid var(--border);
}
.pay-history li:first-child{border-top:0}
/* Zebra stripes: every second payment gets the subtle surface tint (the same
   tone table headers use), so the rows read as separate entries at a glance.
   The variable redefines itself in the dark/contrast themes. */
.pay-history li:nth-child(even){background:var(--surface-2)}
.pay-history .pay-delete{position:absolute;top:5px;right:0;margin:0}
.pay-history .pay-delete .btn{padding:4px;color:var(--text-3)}
.pay-history .pay-delete .btn .btn-label{display:none}
.pay-history .pay-date{margin:0;font-weight:600;font-size:12.5px}
.pay-history .pay-detail{margin:1px 0 0;color:var(--text-2);font-size:12px}
.pay-history .pay-notes{margin:3px 0 0;color:var(--text-3);font-size:11.5px}
.pay-history .pay-amount{
  display:block;margin-top:4px;text-align:right;
  font-size:13px;font-variant-numeric:tabular-nums;white-space:nowrap;
}
.payments-side-panel .panel-body{padding:14px 16px}

@media (max-width:1100px){
  .invoice-preview-grid{grid-template-columns:1fr}
  .invoice-preview-side{position:static}
}

/* ===== Invoice detail screen (templates/invoices/show.html.twig) =====
   Same two-column shape as the preview grid but the left column is the
   browser's own PDF viewer (print route, inline disposition) instead of
   the scaled srcdoc iframe, and the right sidebar switches between
   General | Messages | History tabs.
   ============================================================ */
.inv-detail-topbar .topbar-heading{gap:12px}
.inv-detail-topbar .topbar-heading h1{font-size:16px}
.inv-nav-btn{padding:9px 10px}
.inv-nav-btn.is-disabled{opacity:.4;cursor:default}

.invoice-detail-grid{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:20px;align-items:stretch}
.detail-viewer-panel{padding:28px;display:flex;min-height:720px;background-color:#fff;}
.detail-viewer-panel .doc-frame-wrap{max-width:100%}
.invoice-detail-side{position:sticky;top:16px;align-self:start;min-width:0;display:flex;flex-direction:column;gap:12px}
.detail-tabs{align-self:stretch;background:var(--border)}
.detail-tabs .tab{font-size:12.5px;padding:7px 11px}

.doc-menu{min-width:185px;padding:6px;display:flex;flex-direction:column}
/* Split button (invoice preview downloads): main action + caret sharing one pill. */
.btn-split{display:inline-flex}
.btn-split > .btn:first-child{border-top-right-radius:0;border-bottom-right-radius:0}
.btn-split > [data-menu-toggle]{border-top-left-radius:0;border-bottom-left-radius:0;border-left:1px solid rgba(255,255,255,.35);padding-left:8px;padding-right:8px}
.menu-item-form{margin:0}
.icon-only{padding:9px 10px}

.msg-thread{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:12px}
.msg-item{display:flex;flex-direction:column;align-items:flex-start;max-width:88%}
.msg-item .avatar{width:28px;height:28px;font-size:10.5px;background:var(--avatar-bg);color:var(--avatar-fg);flex-shrink:0;margin-bottom:-16px;z-index:1}
.msg-bubble{
  padding:9px 12px;border-radius:12px;background:var(--surface-2);
  border:1px solid var(--border);font-size:12.5px;line-height:1.5;word-break:break-word;
  display:flex;flex-direction:column;gap:4px;
}
.msg-item:not(.is-internal) .msg-meta{align-self:flex-start}
.msg-meta{margin:4px 0 0;font-size:10.5px;color:var(--text-3)}
.msg-tag{
  align-self:flex-start;font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  padding:1px 8px;border-radius:999px;background:var(--amber-100);color:var(--amber-700);
}
.msg-item.is-internal{align-items:flex-end;align-self:flex-end}
.msg-item.is-internal .msg-bubble{background:var(--amber-100);border-color:rgba(0,0,0,.06)}
.msg-item.is-internal .msg-meta{align-self:flex-end}

.msg-composer{display:flex;flex-direction:column;gap:8px;margin-top:14px;padding-top:12px;border-top:1px solid var(--border)}
.msg-input{resize:vertical;min-height:64px}
.msg-composer-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.msg-composer-foot .btn{margin-left:auto}
.msg-internal-toggle{align-items:center;font-size:12px;font-weight:600;color:var(--text-2)}
.msg-internal-toggle .check-main label{font-size:12px;font-weight:600;color:var(--text-2);cursor:pointer}
.msg-email-hint{font-size:11px;color:var(--text-3)}

/* Sheet watermark for cancelled documents — the class is referenced (not
   required) by InvoiceDocumentRenderer::injectVoidWatermark()'s inline styles. */
.doc-void-watermark{margin:0;padding:0}

/* Red destructive action (void confirm). Mirrors .btn's chrome with rust colors. */
.btn-danger{
  background:var(--rust-500);border-color:var(--rust-500);color:#fff;
}
.btn-danger:hover{background:var(--rust-700);border-color:var(--rust-700)}

/* Void invoice confirm modal — centered card, circular trash icon */
.modal-void{max-width:400px;text-align:center}
.void-modal-body{display:flex;flex-direction:column;align-items:center;gap:7px;padding:30px 28px 26px}
.void-icon{
  width:56px;height:56px;border-radius:999px;display:grid;place-items:center;
  background:var(--rust-100);color:var(--rust-700);margin-bottom:4px;
}
.void-icon svg{width:24px;height:24px;stroke-width:1.6}
.void-number{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-3);margin:0}
.modal-void h2{font-size:19px;font-weight:700;margin:0}
.void-copy{font-size:13px;color:var(--text-2);line-height:1.55;margin:0 0 8px}
.void-actions{display:flex;gap:10px;justify-content:center}
.void-actions .btn{min-width:120px;justify-content:center}
.void-actions form{margin:0;display:contents}

@media (max-width:1100px){
  .invoice-detail-grid{grid-template-columns:1fr}
  .invoice-detail-side{position:static}
  .detail-viewer-panel{min-height:560px}
}

/* ----- History tab: persisted action log (invoices/_activity.html.twig) ----- */
.inv-activity{list-style:none;margin:0;padding:0}
.inv-activity-item{display:flex;align-items:flex-start;gap:12px;padding:2px 0;margin:0}
.inv-activity-item + .inv-activity-item{margin-top:22px}
.inv-activity-icon{
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
  width:24px;height:24px;margin-top:1px;border-radius:7px;
  color:var(--text-3);
}
.inv-activity-icon svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.inv-activity-item.tone-green .inv-activity-icon{color:var(--olive-600)}
.inv-activity-item.tone-blue .inv-activity-icon{color:var(--blue-500)}
.inv-activity-item.tone-red .inv-activity-icon{color:var(--rust-500)}
.inv-activity-copy{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.inv-activity-title{font-size:15px;font-weight:700;color:var(--text);line-height:1.25}
.inv-activity-actor{font-size:13px;color:var(--text-3)}
.inv-activity-detail{font-size:13px;color:var(--text-2);font-variant-numeric:tabular-nums}
.inv-activity-when{display:flex;flex-direction:column;align-items:flex-end;gap:1px;flex-shrink:0}
.inv-activity-date{font-size:13px;color:var(--text-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.inv-activity-time{font-size:12px;color:var(--text-3);font-variant-numeric:tabular-nums}
.inv-activity .empty-note{margin:6px 0 0}



/* Scaled document frame · preview.html.twig
   A tenant invoice template is a standalone A4 document whose sheet is a
   hard `210mm` (~794px) wide, so it cannot reflow into a narrower panel.
   The iframe is therefore rendered at the full A4 canvas width and scaled
   down with a transform (see assets/invoices.js), which keeps the whole
   invoice visible instead of producing a horizontal scrollbar. The wrapper
   carries the visible sheet chrome and the post-scale height, set by the
   same script. */
.doc-frame-wrap{
  --doc-w:860;--doc-h:1220;
  width:100%;max-width:calc(var(--doc-w) * 1px);margin:0 auto;overflow:hidden;
  /*border:1px solid #cdd4d9;border-radius:10px;
  box-shadow:2px 2px 0 rgba(6,41,66,.1);*/
}
.doc-frame{
  display:block;border:0;transform-origin:0 0;
  width:calc(var(--doc-w) * 1px);height:calc(var(--doc-h) * 1px);
}
.doc-sheet{font-size:13px;color:var(--text)}
.doc-header,.doc-billto,.doc-lines,.doc-totals,.doc-meta-table{width:100%;border-collapse:collapse}
.doc-header td{vertical-align:top;padding:0}
.doc-from{width:60%}
.doc-meta{width:40%;text-align:right}
.doc-title{font-size:20px;font-weight:700;margin:0 0 10px}
.doc-company-name{font-weight:700;margin:0 0 2px}
.doc-meta-table td{padding:2px 0;text-align:right}
.doc-meta-table td:first-child{padding-right:14px;color:var(--text-3)}
.doc-section-label{font-weight:700;text-transform:uppercase;font-size:10.5px;color:var(--text-3);letter-spacing:.03em;margin:0 0 6px}
.doc-billto{margin-top:22px}
.doc-lines{margin-top:22px}
.doc-lines th,.doc-lines td{border-bottom:1px solid var(--border);padding:8px 6px;text-align:left}
.doc-lines th{background:var(--surface-2);font-size:10.5px;text-transform:uppercase}
.doc-col-qty,.doc-col-price,.doc-col-amount{text-align:right;white-space:nowrap}
.doc-totals{margin-top:10px;width:320px;float:right}
.doc-totals td{padding:4px 6px}
.doc-totals-label{text-align:left;color:var(--text-3)}
.doc-totals-value{text-align:right}
.doc-totals-grand td{border-top:1px solid var(--text);font-weight:700}
.doc-section{clear:both;margin-top:22px}
.doc-pre{white-space:pre-wrap;margin:0}

/* ===== Admin panel (templates/admin/index.html.twig) ===== */
.admin-tag{
  background:var(--ink);color:#fff;border:1px solid var(--ink);
  letter-spacing:.05em;text-transform:uppercase;font-size:10.5px;
}
.count-chip{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:30px;height:30px;padding:0 10px;border-radius:999px;
  background:var(--olive-100);color:var(--olive-800);
  font-size:13px;font-weight:800;font-variant-numeric:tabular-nums;
}
.table-admin{min-width:640px}
.status-detail{font-size:11px;color:var(--text-3);margin-left:8px;white-space:nowrap}
.dot{width:7px;height:7px;border-radius:999px;display:inline-block;flex-shrink:0}
.dot-on{background:var(--olive-500)}
.dot-off{background:var(--border-strong)}

/* ---------- Settings › API tokens ---------- */
/* Status pills for the token table. `.badge-count` already exists for the
   sidebar counters; these are the flat text variants. */
.badge{
  display:inline-block;padding:2px 9px;border-radius:999px;
  font-size:11.5px;font-weight:600;letter-spacing:.01em;
}
.badge-ok{background:rgba(143,180,80,.18);color:var(--olive-700)}
.badge-muted{background:var(--surface-2);color:var(--text-3);border:1px solid var(--border)}
/* Duplicates table: flags the newest record of a group (highest auto-increment id). */
.badge-newest{background:var(--blue-100);color:var(--blue-700)}
/* Duplicates: keep the "Most recent" badge visible even when the company name is very long.
   The name itself truncates with ellipsis; the badge is a non-shrinking flex sibling. */
.c-name-wrap{
  display:inline-flex;align-items:center;gap:6px;
  min-width:0;max-width:220px;vertical-align:middle;
}
.c-name-wrap .c-name--truncate{
  flex:1 1 auto;min-width:0;max-width:none;
}
.c-name-wrap .badge-newest{flex-shrink:0;white-space:nowrap}
/* A revoked token keeps its row — it is audit evidence — but must read as
   inert at a glance, not as something still granting access. */
tr.is-muted{opacity:.55}
tr.is-muted .c-name{text-decoration:line-through}

/* ===== Support ticketing ===== */
.support-view{max-width:1500px}
.support-form-panel{max-width:780px}
.support-field-wide{grid-column:1/-1}
.support-form-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:4px}
.support-back{display:inline-flex;margin:0 0 14px;color:var(--text-2);font-size:13px;font-weight:600;text-decoration:none}
.support-layout{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:18px;align-items:start}
.support-side{display:flex;flex-direction:column;gap:14px;position:sticky;top:18px}
.support-thread{display:flex;flex-direction:column;gap:14px}
.support-message{display:flex;align-items:flex-start;gap:10px}
.support-message .avatar{width:32px;height:32px;font-size:11px;flex:0 0 auto}
.support-bubble{min-width:0;flex:1;padding:12px 14px;border:1px solid var(--border);border-radius:12px;background:var(--surface-2)}
.support-message.is-staff .support-bubble{background:var(--olive-100);border-color:rgba(143,180,80,.35)}
.support-bubble header{display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:12.5px}
.support-bubble header time{margin-left:auto;color:var(--text-3);font-size:11.5px;white-space:nowrap}
.support-bubble p{margin:0;white-space:pre-wrap;line-height:1.55;font-size:13.5px;overflow-wrap:anywhere}
.support-event{display:flex;justify-content:center;color:var(--text-3);font-size:11.5px}
.support-event span{padding:5px 10px;border:1px solid var(--border);border-radius:999px;background:var(--surface)}
.support-files{display:flex;flex-wrap:wrap;gap:7px;margin-top:10px}
.support-file{display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:6px 9px;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text);text-decoration:none;font-size:12px}
.support-file svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.8;flex:0 0 auto}
.support-file span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.support-file small{color:var(--text-3);white-space:nowrap}
.support-file-item{display:flex;align-items:flex-start;gap:4px;max-width:100%}
.support-file-item form{margin:0}
.support-image{display:flex;flex-direction:column;gap:5px;width:112px;padding:5px;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text);text-decoration:none;font-size:11.5px;cursor:zoom-in}
.support-image img{display:block;width:100%;height:74px;object-fit:cover;border-radius:5px;background:var(--surface-2)}
.support-image span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.support-file-delete{display:grid;place-items:center;width:28px;height:28px;padding:0;border:0;border-radius:7px;background:transparent;color:var(--text-3);cursor:pointer}
.support-file-delete:hover,.support-file-delete:focus-visible{background:var(--rust-100);color:var(--rust-700)}
.support-file-delete svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.8}
.support-reply{display:flex;flex-direction:column;gap:10px;margin-top:18px;padding-top:16px;border-top:1px solid var(--border)}
.support-details{display:flex;flex-direction:column;gap:11px}
.support-details>div{display:flex;justify-content:space-between;gap:12px;font-size:12.5px}.support-details span{color:var(--text-3)}.support-details strong{text-align:right}
.support-close{width:100%;justify-content:center;color:var(--rust-700)}
.support-manage{display:flex;flex-direction:column;gap:11px}.support-manage .btn{justify-content:center}
.support-attachment-drop .pd-drop-main{max-width:100%;overflow-wrap:anywhere}
.support-attachment-drop.has-files{border-style:solid;border-color:var(--olive-500);background:var(--olive-50)}
.support-badge{display:inline-flex;align-items:center;padding:3px 9px;border-radius:999px;font-size:11.5px;font-weight:700;white-space:nowrap;background:var(--surface-2);color:var(--text-2)}
.status-open,.status-in_progress{background:var(--blue-100);color:var(--blue-700)}
.status-waiting,.priority-high{background:var(--amber-100);color:var(--amber-700)}
.status-resolved,.priority-low{background:var(--olive-100);color:var(--olive-700)}
.status-closed{background:var(--surface-2);color:var(--text-3)}
.priority-urgent{background:var(--rust-100);color:var(--rust-700)}
.support-stats{display:grid;grid-template-columns:repeat(5,minmax(100px,1fr));gap:10px;margin-bottom:14px}
.support-stats a{display:flex;flex-direction:column;padding:13px 15px;border:1px solid var(--border);border-radius:10px;background:var(--surface);color:var(--text);text-decoration:none}.support-stats strong{font-size:20px}.support-stats span{font-size:11.5px;color:var(--text-3)}
.support-filters{display:flex;gap:9px;flex-wrap:wrap}.support-filters .search-wrap{flex:1;min-width:210px}.support-filters select.input{width:auto;min-width:140px}
.support-table{min-width:850px}.support-table .client-meta{display:flex;flex-direction:column}.support-table .client-meta small{color:var(--text-3)}
@media(max-width:900px){.support-layout{grid-template-columns:1fr}.support-side{position:static}.support-stats{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.support-form .support-field-wide{grid-column:auto}.support-bubble header{align-items:flex-start;flex-wrap:wrap}.support-bubble header time{width:100%;margin-left:0}.support-filters select.input{width:100%}}

/* ── Contacts listing filter IC — chips + dropdown (Tiendy listing pattern) ──
   Classes re-created here against bibloc's own CSS variables; do not collide
   with the admin theme's .fpop/.fchip selectors. */
.fchip{display:inline-flex;align-items:center;gap:2px;flex:none;max-width:100%}
.fchip__body{display:inline-flex;align-items:center;gap:6px;min-width:0;font-size:12.5px;font-weight:600;white-space:nowrap}
.fchip__key{padding:4px 8px;border-radius:8px;background:var(--surface-2);color:var(--text-2)}
.fchip__val{padding:4px 9px;border-radius:8px;min-width:0;background:var(--olive-100);color:var(--olive-700);overflow:hidden;text-overflow:ellipsis}
.fchip__body:hover .fchip__key{color:var(--text)}
.fchip__x{display:inline-flex;align-items:center;justify-content:center;flex:none;width:20px;height:20px;border-radius:6px;color:var(--text-3)}
.fchip__x:hover{background:var(--rust-100);color:var(--rust-500)}

/* Popover anchored under the filter button */
.fpop{position:relative;flex:none;z-index:20}
.fpop__btn{display:inline-flex;align-items:center;gap:6px;padding:7px 10px;border-radius:var(--radius-sm);cursor:pointer;list-style:none;border:1px solid var(--border);background:var(--surface);font-size:12.5px;font-weight:600;color:var(--text-2);user-select:none}
.fpop__btn::-webkit-details-marker{display:none}
.fpop__btn:hover,[open]>.fpop__btn{background:var(--surface-2);color:var(--text)}
.fpop__btn--icon{padding:7px}
.fpop__btn--icon span{display:none}
.fpop__menu{position:absolute;right:0;top:calc(100% + 8px);z-index:80;min-width:260px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-md);padding:10px;animation:cfpop .16s ease}
.fpop__group h4{font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--text-3);padding:0 0 8px}
.fpop__fields{display:grid;gap:8px}
.fpop__fields select,.fpop__fields input{width:100%}
.fpop__foot{display:flex;justify-content:space-between;gap:8px;border-top:1px solid var(--border);margin-top:10px;padding:10px 0 0}
@keyframes cfpop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
