/* ==========================================================================
   Diverd Invoice - minimalist design system
   Palette is derived from the diverd.dev brand mark (#004ca2).
   ========================================================================== */

:root {
  --brand: #004ca2;
  --brand-dark: #003b7e;
  --brand-light: #e8f0f9;
  --brand-tint: #f4f8fc;

  --ink: #16202c;
  --ink-muted: #5b6b7c;
  --ink-faint: #8a99a8;

  --surface: #ffffff;
  --canvas: #f6f8fa;
  --line: #e2e8ef;
  --line-strong: #cbd6e0;

  --ok: #1a7f52;
  --ok-bg: #e6f4ed;
  --warn: #a76a00;
  --warn-bg: #fdf3e2;
  --danger: #b3261e;
  --danger-bg: #fdecea;
  --info-bg: #eaf1fa;

  --radius: 8px;
  --radius-sm: 5px;
  --shadow: 0 1px 2px rgba(22, 32, 44, 0.06), 0 4px 12px rgba(22, 32, 44, 0.04);
  --shadow-lg: 0 2px 6px rgba(22, 32, 44, 0.08), 0 12px 32px rgba(22, 32, 44, 0.08);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --gap: 20px;
  --sidebar-width: 232px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0 0 0.5em; line-height: 1.25; font-weight: 650; letter-spacing: -0.011em; }
h1 { font-size: 1.75rem; }
h2 { font-size: 1.3rem; }
h3 { font-size: 1.05rem; }
h4 { font-size: 0.95rem; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

hr { border: none; border-top: 1px solid var(--line); margin: var(--gap) 0; }

code, kbd { font-family: var(--mono); font-size: 0.88em; }

/* --- Layout ---------------------------------------------------------------- */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-width);
  flex: 0 0 var(--sidebar-width);
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

.sidebar-brand {
  padding: 20px 20px 16px;
  border-bottom: 1px solid var(--line);
}

/* Stacked lockup, centred in the column: wordmark on top, product name
   beneath. The mark is 5:1, so anything that constrains its height crops or
   distorts it — it gets its width and keeps its own ratio. */
.sidebar-brand a { display: block; color: var(--ink); text-align: center; }
.sidebar-brand a:hover { text-decoration: none; }

.sidebar-brand .wordmark {
  display: block;
  width: 100%;
  max-width: 148px;
  height: auto;
  margin: 0 auto;
}

.sidebar-brand .product {
  display: block;
  margin-top: 6px;
  font-size: 0.78rem;
  font-weight: 650;
  /* Trailing letter-space is trimmed so the text optically centres rather than
     sitting a couple of pixels left. */
  letter-spacing: 0.16em;
  text-indent: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.sidebar-nav { padding: 12px 10px; flex: 1; overflow-y: auto; }

.nav-section {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-faint);
  padding: 14px 10px 6px;
  font-weight: 600;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  font-size: 0.92rem;
  font-weight: 500;
  margin-bottom: 1px;
}

.nav-link:hover { background: var(--brand-tint); color: var(--brand); text-decoration: none; }
.nav-link.is-active { background: var(--brand-light); color: var(--brand); font-weight: 600; }
.nav-link .icon { flex: 0 0 16px; opacity: 0.9; }

.sidebar-foot { border-top: 1px solid var(--line); padding: 12px; }

.plan-chip {
  display: block;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  background: var(--brand-tint);
  font-size: 0.8rem;
  color: var(--ink-muted);
  margin-bottom: 8px;
}
.plan-chip:hover { text-decoration: none; background: var(--brand-light); }
.plan-chip strong { display: block; color: var(--brand); font-size: 0.88rem; }

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

.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 0 26px;
  height: 58px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  position: sticky;
  top: 0;
  z-index: 20;
}

.topbar-title { font-weight: 640; font-size: 1.02rem; letter-spacing: -0.01em; }
.topbar-actions { display: flex; align-items: center; gap: 10px; }

.content { padding: 26px; flex: 1; }
.content-narrow { max-width: 780px; }
.content-wide { max-width: 1200px; }

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: var(--gap);
  flex-wrap: wrap;
}

.page-head h1 { margin-bottom: 2px; }
.page-head .sub { color: var(--ink-muted); font-size: 0.92rem; }
/* The header action row. Nine buttons on an issued invoice, and the labels are
   longer in Bosnian, so it is tightened here rather than at .btn - the same
   buttons elsewhere have room to breathe.

   `flex-wrap` stays as a safety net: an overflowing nowrap row would clip or
   push the page sideways, which is worse than a second line. At 1440px it fits
   on one line in both languages with all nine buttons - measured, not asserted;
   the test suite cannot see layout. Re-measure if a tenth action is added. */
.page-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  /* Grow to fill the line. Without this the row sizes to its content, so
     `flex-end` has no free space to push anything into once it has wrapped onto
     a line of its own - which is exactly when the alignment matters. */
  flex: 1 1 auto;
  justify-content: flex-end;
}

/* The document-language picker is not an action - it changes what the PDF is
   rendered in. Held hard left so the slack in the row sits between it and the
   first button, rather than trailing off the right-hand edge past the last one. */
.page-actions #doc-language { margin-right: auto; }

.page-actions .btn {
  padding: 7px 11px;
  gap: 6px;
}

/* An icon must never be the thing that gets squeezed - at one point the row
   fitted with a single pixel to spare and the Duplicate glyph was clipped. */
.page-actions .btn .icon { flex: none; }

/* --- Cards ----------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.card + .card { margin-top: var(--gap); }

/* ...but not between grid siblings. The rule is for cards stacked down a column;
   inside a grid it landed on the second card in the row, whose stretched box then
   sat 20px lower than the first and 20px shorter. That is what pulled the
   "Due in the next 14 days" card out of line with "Recent invoices", and the
   charts below them out of line with each other. */
.grid > .card + .card { margin-top: 0; }
/* min-height so a head with an action button and a head with only a title come
   out the same height - 30px of padding, a 1px border and a 32px btn-sm. Two
   cards side by side otherwise start their tables at different heights. */
.card-head {
  min-height: 63px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.card-head h2, .card-head h3 { margin: 0; font-size: 0.98rem; }
.card-body { padding: 18px; }
.card-body.tight { padding: 0; }
.card-foot {
  padding: 13px 18px;
  border-top: 1px solid var(--line);
  background: var(--brand-tint);
  border-radius: 0 0 var(--radius) var(--radius);
}

.grid { display: grid; gap: var(--gap); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* --- Stats ----------------------------------------------------------------- */

.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  box-shadow: var(--shadow);
}

.stat-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  font-weight: 600;
  margin-bottom: 6px;
}
.stat-value { font-size: 1.5rem; font-weight: 680; letter-spacing: -0.02em; }
.stat-value.is-danger { color: var(--danger); }
.stat-value.is-ok { color: var(--ok); }
.stat-note { font-size: 0.82rem; color: var(--ink-muted); margin-top: 3px; }

.meter { height: 5px; background: var(--line); border-radius: 3px; margin-top: 9px; overflow: hidden; }
.meter span { display: block; height: 100%; background: var(--brand); border-radius: 3px; }
.meter.is-full span { background: var(--danger); }

/* --- Tables ---------------------------------------------------------------- */

.table-wrap { overflow-x: auto; }

table.data { width: 100%; border-collapse: collapse; font-size: 0.9rem; }

table.data th {
  text-align: left;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-faint);
  font-weight: 650;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--brand-tint);
}

table.data td { padding: 11px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.data tbody tr:last-child td { border-bottom: none; }
table.data tbody tr:hover { background: var(--brand-tint); }
table.data .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
table.data .shrink { width: 1%; white-space: nowrap; }

.empty { padding: 44px 20px; text-align: center; color: var(--ink-muted); }
.empty .empty-icon { width: 34px; height: 34px; opacity: 0.3; margin-bottom: 10px; }
.empty h3 { color: var(--ink); }

/* --- Icons ----------------------------------------------------------------- */

/* Bootstrap Icons, inlined as an SVG sprite. Sized in em so an icon always
   matches the type around it, and coloured by currentColor. */
.icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  flex: none;
  vertical-align: -0.125em;
}

.btn .icon { font-size: 1.05em; }
.icon-lg { width: 1.35em; height: 1.35em; }

/* --- Buttons --------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 8px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 0.89rem;
  font-weight: 550;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s ease, border-color 0.12s ease;
}

.btn:hover { background: var(--brand-tint); border-color: var(--line-strong); text-decoration: none; }
.btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

.btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }

.btn-danger { color: var(--danger); border-color: #e8c4c1; }
.btn-danger:hover { background: var(--danger-bg); }

.btn-ghost { border-color: transparent; background: transparent; }
.btn-ghost:hover { background: var(--brand-tint); }

.btn-sm { padding: 5px 10px; font-size: 0.82rem; }
.btn-lg { padding: 11px 22px; font-size: 0.98rem; }
.btn-block { width: 100%; }

.btn-group { display: inline-flex; gap: 6px; flex-wrap: wrap; }

/* Square icon-only button, for inline table row actions. */
.btn-icon {
  padding: 6px;
  width: 30px;
  height: 30px;
  color: var(--ink-muted);
  border-color: transparent;
  background: transparent;
}

.btn-icon:hover { background: var(--brand-light); color: var(--brand); border-color: transparent; }
.btn-icon .icon { font-size: 1rem; }

/* Destructive row action: neutral until hovered, so it does not shout from
   every row, but unmistakable once the pointer is on it. */
.btn-icon-danger:hover { background: var(--danger-bg); color: var(--danger); }

.row-actions { display: inline-flex; gap: 2px; align-items: center; }

/* --- Forms ----------------------------------------------------------------- */

.field { margin-bottom: 15px; }
.field:last-child { margin-bottom: 0; }

.field label,
.form-label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-muted);
  margin-bottom: 5px;
}

.field .req { color: var(--danger); }

input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="date"], input[type="url"], input[type="tel"], input[type="search"],
select, textarea {
  width: 100%;
  padding: 8px 11px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.92rem;
  color: var(--ink);
  background: var(--surface);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(0, 76, 162, 0.12);
}

input[type="color"] { padding: 2px; height: 38px; cursor: pointer; }

/* At identical padding and font a select computes 38px against an input's 41px,
   so any row mixing the two - the KIF filter, the invoice filters, the form
   grids - stepped out of line by 3px. Matched to the input rather than the
   other way round, because inputs are the majority everywhere. */
select { height: 41px; }
textarea { resize: vertical; min-height: 72px; }

.field-help { font-size: 0.79rem; color: var(--ink-faint); margin-top: 4px; }
.field-error { font-size: 0.81rem; color: var(--danger); margin-top: 4px; }
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: var(--danger); }

.field-row { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.field-row-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.checkbox { display: flex; align-items: center; gap: 8px; }
.checkbox input { width: auto; }
.checkbox label { margin: 0; font-weight: 500; color: var(--ink); }

fieldset { border: none; padding: 0; margin: 0 0 22px; }
legend {
  padding: 0;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  font-weight: 650;
  margin-bottom: 10px;
}

/* --- Badges ---------------------------------------------------------------- */

.badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 20px;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  background: var(--line);
  color: var(--ink-muted);
  white-space: nowrap;
}

.badge-draft { background: #eceff3; color: #5b6b7c; }
.badge-sent { background: var(--info-bg); color: var(--brand); }
.badge-partial { background: var(--warn-bg); color: var(--warn); }
.badge-paid { background: var(--ok-bg); color: var(--ok); }
.badge-overdue { background: var(--danger-bg); color: var(--danger); }
.badge-cancelled { background: #eceff3; color: var(--ink-faint); text-decoration: line-through; }
.badge-brand { background: var(--brand-light); color: var(--brand); }

/* --- Messages -------------------------------------------------------------- */

.messages { margin-bottom: var(--gap); display: grid; gap: 8px; }

.alert {
  padding: 11px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 0.9rem;
}

/* The leading icon ran straight into the text ("⚠Columns follow..."). Spaced
   inline rather than with flex on the alert: several alerts are a sentence with
   a link inside it, and flex would break that link onto a column of its own. */
.alert > svg:first-child { margin-right: 7px; }

.alert-success { background: var(--ok-bg); border-color: #bfe0cf; color: #145c3c; }
.alert-error, .alert-danger { background: var(--danger-bg); border-color: #f0c8c4; color: #8c1e17; }
.alert-warning { background: var(--warn-bg); border-color: #ecd6ac; color: #7d4f00; }
.alert-info { background: var(--info-bg); border-color: #c6d9ef; color: var(--brand-dark); }

/* --- Pagination ------------------------------------------------------------ */

.pager { display: flex; gap: 6px; align-items: center; justify-content: center; padding: 16px; }
.pager a, .pager span {
  padding: 6px 11px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  font-size: 0.86rem;
  color: var(--ink-muted);
  background: var(--surface);
}
.pager a:hover { background: var(--brand-tint); text-decoration: none; }
.pager .is-current { background: var(--brand); border-color: var(--brand); color: #fff; }
.pager .is-disabled { opacity: 0.45; }

/* --- Filters --------------------------------------------------------------- */

.filters { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.filters .field { margin: 0; min-width: 150px; flex: 1 1 150px; }
.filters .field-actions { display: flex; gap: 8px; }

/* --- Utilities ------------------------------------------------------------- */

.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); }
.small { font-size: 0.85rem; }
.tiny { font-size: 0.78rem; }
.strong { font-weight: 650; }
.mono { font-family: var(--mono); }
.nowrap { white-space: nowrap; }
.right { text-align: right; }
.center { text-align: center; }
.num { font-variant-numeric: tabular-nums; }

.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: 8px; }
.mb-2 { margin-bottom: 16px; }
.mb-3 { margin-bottom: 24px; }

.flex { display: flex; }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.flex-gap { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.stack { display: grid; gap: 14px; }

.divider { border-top: 1px solid var(--line); margin: 18px 0; }

/* --- Responsive ------------------------------------------------------------ */

@media (max-width: 900px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
  .shell { flex-direction: column; }
  .sidebar {
    width: 100%;
    flex: none;
    height: auto;
    position: static;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  .sidebar-nav { display: flex; flex-wrap: wrap; gap: 4px; padding: 10px; }
  .nav-section { display: none; }
  .nav-link { margin: 0; }
  .sidebar-foot { display: none; }
  /* minmax(0, 1fr), not 1fr. A bare `1fr` is `minmax(auto, 1fr)`, and that auto
     minimum is the track's min-content width - so a card holding a table with
     fixed column widths could not shrink, `overflow-x: auto` on .table-wrap never
     engaged, and the whole page scrolled sideways instead of the table. At 380px
     the dashboard overflowed by 223px. */
  .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); }
  .field-row, .field-row-3 { grid-template-columns: minmax(0, 1fr); }
  .content { padding: 16px; }
  .topbar { padding: 0 16px; }
}

/* Locked invoices show a lock in place of the edit/delete actions. */
.btn-icon.is-locked-hint { color: var(--ink-faint); cursor: default; }
.btn-icon.is-locked-hint:hover { background: transparent; color: var(--ink-faint); }

/* --- Modal ----------------------------------------------------------------- */

/* Native <dialog>: the browser supplies focus trapping, Esc and the backdrop. */
.modal {
  border: none;
  border-radius: var(--radius);
  padding: 0;
  max-width: 440px;
  width: calc(100% - 32px);
  box-shadow: var(--shadow-lg);
  color: var(--ink);
  background: var(--surface);
}

.modal::backdrop { background: rgba(22, 32, 44, 0.45); }

.modal-card { padding: 0; }

.modal-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 18px 20px 0;
}

.modal-head h3 { margin: 0; font-size: 1.05rem; }

.modal-icon {
  width: 34px;
  height: 34px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--brand-light);
  color: var(--brand);
}

.modal.is-danger .modal-icon { background: var(--danger-bg); color: var(--danger); }

.modal-body {
  padding: 12px 20px 20px;
  color: var(--ink-muted);
  font-size: 0.93rem;
  line-height: 1.5;
}

.modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 14px 20px;
  border-top: 1px solid var(--line);
  background: var(--brand-tint);
  border-radius: 0 0 var(--radius) var(--radius);
}

@media (max-width: 480px) {
  .modal-foot { flex-direction: column-reverse; }
  .modal-foot .btn { width: 100%; }
}

/* --- Toasts ---------------------------------------------------------------- */

.toasts {
  position: fixed;
  top: 72px;
  right: 20px;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 9px;
  width: 360px;
  max-width: calc(100vw - 32px);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 13px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  font-size: 0.9rem;
  pointer-events: auto;
  animation: toast-in 0.18s ease-out;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

.toast.is-leaving { opacity: 0; transform: translateY(-6px); transition: opacity 0.18s, transform 0.18s; }

.toast-icon { flex: none; display: flex; align-items: center; }
.toast-text { flex: 1; min-width: 0; }

.toast-close {
  flex: none;
  border: none;
  background: transparent;
  color: var(--ink-faint);
  cursor: pointer;
  padding: 2px;
  line-height: 1;
  border-radius: var(--radius-sm);
}
.toast-close:hover { color: var(--ink); background: var(--canvas); }

.toast-success { border-left: 3px solid var(--ok); }
.toast-success .toast-icon { color: var(--ok); }
.toast-error, .toast-danger { border-left: 3px solid var(--danger); }
.toast-error .toast-icon, .toast-danger .toast-icon { color: var(--danger); }
.toast-warning { border-left: 3px solid var(--warn); }
.toast-warning .toast-icon { color: var(--warn); }
.toast-info, .toast-debug { border-left: 3px solid var(--brand); }
.toast-info .toast-icon, .toast-debug .toast-icon { color: var(--brand); }

@media (max-width: 720px) {
  .toasts { top: 12px; right: 12px; left: 12px; width: auto; }
}

/* Marks a document that is not an ordinary invoice, and one that has been
   credited. Both change what the figures mean, so they sit beside the number
   rather than being left to the reader to work out from the totals. */
.badge-type {
  background: var(--brand-tint);
  color: var(--brand-dark);
  border: 1px solid #c6d9ef;
}

.badge-credited {
  background: #fdf1e7;
  color: #8a4b12;
  border: 1px solid #f2d4b8;
}

/* Searchable select (see country-select.js). Styled to be indistinguishable
   from an ordinary field, because as far as the user is concerned it is one. */
.combo { position: relative; }

.combo-input { width: 100%; }

.combo-list {
  position: absolute;
  z-index: 40;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}

.combo-item {
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  cursor: pointer;
}

.combo-item:hover,
.combo-item.is-active { background: var(--brand-tint); }

.combo-item.is-selected { font-weight: 620; }

.combo-list::-webkit-scrollbar { width: 10px; }
.combo-list::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: 6px;
  border: 3px solid var(--surface);
}

/* A feature the current plan does not include. Still clickable — the click is
   what takes the user to the plan page — but visibly not yet theirs. */
.is-locked { opacity: 0.62; }
.is-locked:hover { opacity: 0.85; }
.is-locked .icon:last-child { opacity: 0.75; }

.nav-lock {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
}

.nav-lock .icon { width: 13px; height: 13px; }

/* A group of form fields the plan does not include. The inputs are genuinely
   disabled by the form; this only makes that legible. */
.is-locked-fields .field label,
.is-locked-fields .field-help { opacity: 0.6; }

.is-locked-fields input:disabled,
.is-locked-fields select:disabled {
  background: var(--canvas);
  color: var(--ink-faint);
  cursor: not-allowed;
}

.lock-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 10px;
  padding: 2px 9px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-faint);
}

.lock-badge:hover { color: var(--brand); border-color: var(--brand); text-decoration: none; }
.lock-badge .icon { width: 12px; height: 12px; }

/* --- Cookie disclosure -------------------------------------------------- */
/* A bar, not a modal. Nothing non-essential is set before a choice is made, so
   there is nothing to block the page for — and a full-screen wall over strictly
   necessary cookies is the pattern regulators object to. */
.cookie-notice {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  background: var(--surface);
  border-top: 1px solid var(--line-strong);
  box-shadow: 0 -6px 28px rgba(16, 24, 34, 0.09);
}

.cookie-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 14px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
}

.cookie-text strong { display: block; font-size: 0.92rem; margin-bottom: 2px; }
.cookie-text p { margin: 0; font-size: 0.84rem; color: var(--ink-muted); max-width: 68ch; }

.cookie-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.cookie-actions form { display: flex; gap: 8px; }

/* --- Privacy hover card ------------------------------------------------- */
.privacy-hover { position: relative; }

.privacy-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font: inherit;
  font-size: 0.84rem;
  color: var(--ink-muted);
  cursor: pointer;
}

.privacy-trigger:hover { color: var(--brand); border-color: var(--brand); }
.privacy-trigger .icon { width: 13px; height: 13px; }

.privacy-card {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0;
  width: min(420px, calc(100vw - 40px));
  max-height: min(60vh, 520px);
  overflow-y: auto;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}

/* Hover for a mouse, focus-within for a keyboard or a tap. Hover alone would
   leave the card unreachable for both. */
.privacy-hover:hover .privacy-card,
.privacy-hover:focus-within .privacy-card {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.privacy-card h3 { font-size: 0.95rem; margin: 0 0 12px; }
.privacy-card dl { margin: 0; }
.privacy-card dt {
  font-size: 0.78rem;
  font-weight: 680;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  margin-top: 12px;
}
.privacy-card dt:first-of-type { margin-top: 0; }
.privacy-card dd { margin: 3px 0 0; font-size: 0.85rem; line-height: 1.5; }

.privacy-foot {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 0.78rem;
  color: var(--ink-faint);
}

@media (max-width: 760px) {
  .cookie-inner { flex-direction: column; align-items: flex-start; gap: 12px; }
  .cookie-actions { width: 100%; flex-wrap: wrap; }
  .privacy-card { left: auto; right: 0; }
}

/* The labels under an invoice number - its type, and whether it is void.
   Their own row rather than trailing the number: one badge fitted beside it,
   two widened the column enough to put a horizontal scrollbar under the table.
   They wrap between badges but never inside one. */
.number-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  margin-top: 4px;
}

.number-badges .badge { flex: none; }

/* A POST action sitting among the icon links in a table row. A bare <form> is
   a block element and would push the icons after it onto a new line. */
.row-action-form { display: inline-flex; margin: 0; }

/* A document declared void: kept on the record, out of every figure. Struck
   through rather than merely greyed, because "this does not count" has to be
   unmistakable next to figures that do. */
.badge-void {
  background: #f1f1f3;
  color: #6b6b75;
  border: 1px solid #d9d9df;
  text-decoration: line-through;
}

/* A two-letter type code beside an invoice number. Monospaced digits and
   tighter padding than a word badge, so it reads as a marker rather than a
   label and never widens the column. */
.badge-code {
  padding: 2px 6px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: help;
}

.number-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

/* Status badge and its qualifier on one line. `nowrap` on the wrapper rather
   than the parts, so the pair is one unbreakable unit and the column sizes to
   it instead of stacking them. */
.status-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.status-cell .badge { flex: none; }

/* Client name in a table: one line, elided rather than wrapped. A wrapped name
   costs a line on every row, and because column widths shift with the language
   it wrapped in one and not the other - the same table two heights. */
.col-client {
  width: 160px;
  max-width: 160px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Pinned columns in the invoice list.
 *
 * `table.data th` sets nowrap, which turns a width into a *minimum* - a long
 * header simply forces the column wider. "DATUM IZDAVANJA" is half again the
 * width of "ISSUE DATE", and the difference came out of the client column,
 * wrapping the name and making the same table taller in one language than the
 * other. Letting these headers wrap costs height once, in the header row. */
/* `table.data th` is specificity 0-1-2 and sets nowrap, so a bare class here
   loses to it. Qualified selectors, or the width stays a minimum. */
table.data th.col-date {
  width: 104px;
  white-space: normal;
}

table.data th.col-status {
  width: 158px;
  white-space: normal;
}

table.data th.col-client {
  width: 160px;
  white-space: normal;
}

/* A stat note carrying something that needs attention rather than describing the
   figure above it. */
.stat-note.is-warning { color: var(--danger); font-weight: 600; }

/* Inline danger colour for a figure that points the wrong way — a refund owed
   sitting beside an amount receivable. */
.is-danger { color: var(--danger); }

/* More money arrived than was asked for. Warning rather than error colouring:
   nothing is broken, but somebody has to send some back. */
.badge-overpaid {
  background: #fdf1e7;
  color: #8a4b12;
  border: 1px solid #f2d4b8;
}

/* Money that still has to go back to the client. Deliberately not the same
   colour as a credit badge: one describes a charge that was cancelled, the other
   an action still outstanding. */
.badge-refund {
  background: var(--danger-bg);
  color: var(--danger);
  border: 1px solid #f3c9c6;
}

/* Dashboard stat row. auto-fit rather than a fixed count, because the refund
   tile only appears when money is owed back — four and five tiles both have to
   lay out without a second grid class or a media query per case. */
/* 1fr, so the four tiles fill the row and their right edge lands on the page
   margin like every card below them. Capping the track width kept a wrapped row
   tidy, but there is nothing left to wrap: the tile count is fixed at four and the
   wide documents block sits outside this grid. */
.grid-stats { grid-template-columns: repeat(auto-fit, minmax(205px, 1fr)); }

/* Stacked by default, side by side once there is room. Deliberately not auto-fit:
   the divider between compartments has to be a left border in one arrangement and
   a top border in the other, and CSS cannot ask a grid how many columns it ended
   up with. Fixing the fold at one breakpoint means the rule is always the right
   rule - auto-fit gave two columns at 600px with the divider suppressed, which is
   the ambiguity this is here to remove. */
.stat-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}

/* A rule between compartments, not just space. Three groups of pills across one
   card read as a single strip of nine: the gap between neighbouring columns was no
   larger than the gap between pills within one, so nothing said where a group
   ended. */
.stat-split > div + div {
  border-top: 1px solid var(--line);
  margin-top: 14px;
  padding-top: 14px;
}

@media (min-width: 860px) {
  .stat-split { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stat-split > div { padding-right: 26px; }
  .stat-split > div + div {
    border-top: 0;
    margin-top: 0;
    padding-top: 0;
    border-left: 1px solid var(--line);
    padding-left: 26px;
  }
}

/* The limit is context for the number, not a second number. */
.stat-split .of-limit { font-size: 0.6em; font-weight: 500; color: var(--ink-faint); }
.stat-split .meter { margin-top: 7px; }

/* The per-type tally. The count sits *inside* the badge rather than after it: as
   a bare number alongside a pill it read as a separate figure and left the eye to
   pair the two up. One object, two compartments - code tinted, count on the
   surface. */
/* Sized to their content and held close under their own number. Stretched to fill
   the column they were the width of the compartment, which put the last pill of
   one group hard against the first pill of the next - and a pill mostly empty down
   the middle reads as a progress bar rather than a label. Proximity is what says
   which tally belongs to which heading. */
.tally { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }

.tally-badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.5;
  cursor: help;
}

/* Two compartments in one pill: the code tinted, the count on the surface. The
   count keeps a floor width so 1 and 12 do not change the pill's shape, and the
   three pills in a row stay the same size as each other. */
.tally-badge .code,
.tally-badge .count { padding: 1px 7px; text-align: center; }
.tally-badge .count { min-width: 26px; }

.tally-badge .code { background: var(--brand-light); color: var(--brand); }
.tally-badge .count {
  background: var(--surface);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* Zeros stay, because the row is read as a comparison across the three types and
   dropping the empty ones makes the same account look structurally different from
   one month to the next. They recede rather than disappear. */
.tally-badge.is-zero { opacity: 0.5; }

}

/* --- Document numbers ------------------------------------------------------ */
/* A document number is an identifier, not prose. Set in the system monospace
   with tabular figures so INV-2026-08-0001 and CRN-2026-08-0001 occupy the same
   width and a column of them lines up digit under digit — the proportional face
   made the prefixes different widths and the numbers ragged.
   System stack only: a webfont would need a network request, which the artifact
   CSP forbids and which would flash unstyled text anyway. */
.doc-number {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono",
               "Roboto Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.94em;
  letter-spacing: -0.01em;
}

/* In a heading the mono face reads large; pull it back to match the sans. */
h1 .doc-number, .doc-number-lg { font-size: 0.88em; letter-spacing: -0.02em; }

/* ---------------------------------------------------------------------------
   Charts

   The categorical hues are fixed in this order and never cycled: slot 1 is
   always the first series, so narrowing the dashboard to one client cannot
   repaint the series that remain. They were checked, not chosen by eye - the
   worst confusable adjacent pair is teal/orange at dE 11.3 under simulated
   protanopia, above the 8 threshold, with a normal-vision floor of dE 27.5.

   Slot 3 is a teal rather than the green it started as. The green cleared the
   colour-vision check but sat at 2.74:1 against the card, and a 2px line at
   that contrast is much harder to follow than a filled bar was; darkening the
   green on its own dropped it to dE 6.4 against the orange. Moving the hue
   toward teal clears both - all three are now above 3:1.
--------------------------------------------------------------------------- */
.chart {
  --viz-cat-1: #2a78d6;
  --viz-cat-2: #eb6834;
  --viz-cat-3: #12958c;
  --viz-ink: var(--muted);
  --viz-grid: #eceef2;
  --viz-surface: #ffffff;
  position: relative;
}

.chart-plot { position: relative; min-height: 220px; }
.chart-plot svg { display: block; overflow: visible; }
.viz-hit { cursor: default; }

.chart-legend {
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  margin: 0 0 10px; padding: 0; list-style: none;
  font-size: 0.78rem; color: var(--muted);
}
.chart-legend li { display: flex; align-items: center; gap: 6px; }

/* Identity is the swatch beside the text, never the text itself. */
.viz-swatch {
  width: 10px; height: 10px; border-radius: 3px;
  flex: 0 0 auto; display: inline-block;
}
.viz-swatch-1 { background: var(--viz-cat-1); }
.viz-swatch-2 { background: var(--viz-cat-2); }
.viz-swatch-3 { background: var(--viz-cat-3); }

/* :not([hidden]) rather than a bare .chart-tip: a display declaration outranks
   the `hidden` attribute's own display:none, which left the tooltip parked over
   the legend on load. */
.chart-tip:not([hidden]) {
  display: grid;
}

.chart-tip {
  position: absolute; top: 6px; z-index: 3;
  grid-template-columns: auto auto auto; gap: 2px 8px;
  align-items: center; pointer-events: none;
  padding: 8px 10px; border-radius: 8px;
  background: #ffffff; border: 1px solid var(--border);
  box-shadow: 0 6px 18px rgba(24, 24, 32, 0.12);
  font-size: 0.76rem; color: var(--text); white-space: nowrap;
}
.chart-tip strong { grid-column: 1 / -1; font-size: 0.72rem; color: var(--muted); }
.chart-tip b { justify-self: end; font-variant-numeric: tabular-nums; }

.chart-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 8px;
}
.chart-table { margin-top: 10px; }
.chart-table table { font-size: 0.76rem; }

/* The client filter sits in one row above everything it scopes, so its reach
   is unambiguous - a filter beside a single tile reads as filtering that tile. */
.dash-filter { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Sized to its content, not to the card: a select stretched across the full
   width reads as the page's subject rather than as a control over it, and it
   pushed the scope note onto a line of its own. */
.dash-filter select { width: auto; min-width: 220px; max-width: 320px; }
.dash-filter .scope-note { font-size: 0.78rem; color: var(--muted); }

/* ---------------------------------------------------------------------------
   Date picker

   Attached to the day-first text date fields by core/js/datepicker.js. One panel
   is moved between fields, positioned in page coordinates, so it is a child of
   <body> rather than of the form - inside a form group it would have been clipped
   by the card's overflow.
--------------------------------------------------------------------------- */
.datepicker {
  position: absolute;
  z-index: 60;
  width: 252px;
  padding: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  font-size: 0.85rem;
}

.datepicker-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px; margin-bottom: 8px;
}
.datepicker-month { font-weight: 640; text-transform: capitalize; }

.datepicker-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  background: none; border: 1px solid var(--line); border-radius: var(--radius-sm);
  color: var(--ink-muted); cursor: pointer;
}
.datepicker-nav:hover { background: var(--brand-tint); color: var(--brand); }

.datepicker-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  text-align: center;
}

.datepicker-weekday {
  font-size: 0.66rem; font-weight: 650; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--ink-faint); padding-bottom: 4px;
}

.datepicker-day {
  padding: 5px 0;
  background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
  color: var(--ink); font: inherit; font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.datepicker-day:hover { background: var(--brand-tint); }
.datepicker-day.is-empty { cursor: default; }

/* Today is outlined, the selected day is filled: they can be the same date and
   still have to be told apart. */
.datepicker-day.is-today { border-color: var(--line-strong); font-weight: 650; }
.datepicker-day.is-selected {
  background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 650;
}

.datepicker-foot {
  display: flex; justify-content: space-between; gap: 6px;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line);
}

/* The calendar affordance. The native input drew one and a text input does not,
   so without it the field gave no sign it had a picker at all.

   A background image rather than markup: every date field stays a bare <input>,
   so no template that renders a form has to know about this. The glyph is not a
   separate control - the whole field opens the calendar on focus - so it is not
   in the tab order and needs no label. */
input[data-datepicker] {
  font-variant-numeric: tabular-nums;
  padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%20fill='%238a99a8'%3E%3Cpath%20d='M11%206.5a.5.5%200%200%201%20.5-.5h1a.5.5%200%200%201%20.5.5v1a.5.5%200%200%201-.5.5h-1a.5.5%200%200%201-.5-.5z'/%3E%3Cpath%20d='M3.5%200a.5.5%200%200%201%20.5.5V1h8V.5a.5.5%200%200%201%201%200V1h1a2%202%200%200%201%202%202v11a2%202%200%200%201-2%202H2a2%202%200%200%201-2-2V3a2%202%200%200%201%202-2h1V.5a.5.5%200%200%201%20.5-.5M1%204v10a1%201%200%200%200%201%201h12a1%201%200%200%200%201-1V4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 15px 15px;
  cursor: pointer;
}

/* Bright while the calendar is open, so the field and the panel read as one. */
input[data-datepicker]:focus { cursor: text; }

/* A tile carrying more than one currency: the figures are peers, so same size,
   just tighter than the single-figure case was. */
.stat-value + .stat-value { margin-top: 1px; }

/* The money chart's currency picker, in its card head beside the title. */
.chart-scope { display: flex; align-items: center; gap: 6px; }
.chart-scope select { width: auto; padding: 4px 8px; font-size: 0.82rem; }

/* --- Language select ------------------------------------------------------- */
/* Replaces the native control so a flag can be an image; see
   core/js/language-select.js for why an emoji cannot do this job. */
.langsel { position: relative; display: inline-block; }
.langsel-native { display: none; }

.langsel-button {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 9px;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: 0.82rem; line-height: 1.4;
  cursor: pointer;
}
.langsel-button:hover { border-color: var(--brand); }
.langsel-caret { width: 10px; height: 6px; margin-left: 2px; opacity: 0.55; }

.langsel-list {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 40;
  min-width: 100%; margin: 0; padding: 4px; list-style: none;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
}

.langsel-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 9px; border-radius: var(--radius-sm);
  font-size: 0.85rem; white-space: nowrap; cursor: pointer;
}
.langsel-item:hover { background: var(--brand-tint); }

/* Inside a form field it is one control among others, so it fills the cell and
   matches their height and type - the native <select> it replaces took width:100%
   from the shared input rule, and the button, sizing to its text, came out at 108px
   in a 254px cell. Elsewhere - the topbar, the invoice summary - it stays compact. */
.field .langsel { display: block; width: 100%; }

.field .langsel-button {
  width: 100%;
  justify-content: flex-start;
  padding: 8px 11px;
  font-size: 0.92rem;
  /* Same 41px the inputs and selects settle at, so the control it stands in for
     is not visibly shorter than the one beside it. */
  height: 41px;
}

.field .langsel-caret { margin-left: auto; }
.field .langsel-list { width: 100%; }
.langsel-item.is-selected { background: var(--brand-light); color: var(--brand); font-weight: 600; }

/* 20x14 is the flag sprite's own ratio; a border keeps a white flag off a white
   background. */
.lang-flag {
  width: 20px; height: 14px; flex: 0 0 20px;
  border-radius: 2px; box-shadow: 0 0 0 1px rgba(22, 32, 44, 0.12);
}

/* The fallback for a language with no flag drawn yet. */
.lang-code {
  flex: 0 0 auto; padding: 1px 5px; border-radius: 3px;
  background: var(--brand-light); color: var(--brand);
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.04em;
}

/* The language control in the invoice summary: it sits in a label/value row, so
   it has to look like the value it replaced rather than like a form. */
.row-form { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.row-form .langsel-button { padding: 3px 7px; font-size: 0.78rem; }
.row-form .lang-flag { width: 17px; height: 12px; flex-basis: 17px; }

/* The language question inside the confirm dialog.

   It is a sibling of .modal-body rather than inside it, so it carries the same
   horizontal padding itself - without that the options ran edge to edge and sat
   against the card's border. */
.modal-choice { padding: 4px 20px 20px; }

/* These triggers ask a question and pass no message, and an empty body still
   contributed its own 32px, opening a gap under the title. */
.modal-body:empty { padding: 0; }

.choice-hint {
  font-size: 0.86rem; color: var(--ink-muted); line-height: 1.5;
  margin: 0 0 14px;
}

.choice-list { display: flex; flex-direction: column; gap: 8px; }

.choice {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: 0.95rem; cursor: pointer;
}
.choice:hover { background: var(--brand-tint); }
.choice:has(input:checked) { border-color: var(--brand); background: var(--brand-light); font-weight: 600; }
.choice input { margin: 0; accent-color: var(--brand); }

/* Marks a feature that exists for one country's rules - the KIF is Bosnian tax
   law, not a general invoicing feature, and nothing else on the page says so. */
.country-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px 3px 6px; border-radius: 999px;
  border: 1px solid var(--line-strong); background: var(--surface);
  font-size: 0.68rem; font-weight: 650; letter-spacing: 0.02em;
  color: var(--ink-muted); text-transform: none; vertical-align: middle;
  cursor: help;
}
h1 .country-badge { margin-left: 10px; position: relative; top: -2px; }
.btn .lang-flag { width: 16px; height: 11px; flex-basis: 16px; }

/* --- Recording a payment --------------------------------------------------- */
/* Six fields and a button. As a `.filters` flex row each field sized itself and
   the row wrapped wherever it ran out of width, so the two conversion fields
   landed on different lines from each other and out of their source order, with
   the help text under one of them dragging that column further out of line.

   A grid instead: three even columns, two full rows, and the button on its own
   row. The fields no longer decide the layout, so a longer label in Bosnian or
   German moves nothing. */
.payment-form {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px 14px;
  /* Fields align at their tops, so the inputs across a row line up even when
     one cell carries help text underneath. */
  align-items: start;
}

.payment-form .field { margin: 0; min-width: 0; }

/* Its own row, right-aligned under the fields. The alternative - sitting in the
   last cell of row two - puts it beside a field carrying help text, where it
   lines up with neither the input above it nor the text beside it. */
.payment-form .field-actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

@media (max-width: 900px) {
  .payment-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .payment-form { grid-template-columns: 1fr; }
}
