/* ── Dashboard shell ── */
.dash-shell {
  display: grid;
  grid-template-columns: 220px 1fr;
  grid-template-rows: 52px 1fr;
  min-height: 100vh;
}

/* ── Top bar (paper-tone, editorial) ── */
.dash-topbar {
  grid-column: 1 / -1;
  background: var(--paper-lo);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  z-index: 100;
}

.dash-brand {
  font-family: var(--serif);
  font-size: 1.2rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -.01em;
}
.dash-brand span { font-weight: 700; color: var(--ink); }

.dash-topbar-right {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: .82rem;
  color: var(--ink-2);
}

.dash-topbar-right a,
.dash-topbar-right button {
  background: none;
  border: none;
  color: var(--ink-2);
  cursor: pointer;
  font-family: var(--sans);
  font-size: .82rem;
  text-decoration: none;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  transition: color .15s, background .15s;
  /* Never wrap topbar labels ("Log ud" / "+ Ny faktura" broke onto two lines at 390px). */
  white-space: nowrap;
}
.dash-topbar-right a:hover,
.dash-topbar-right button:hover { color: var(--ink); background: var(--paper-hi); }

/* Theme toggle (sun/moon) */
.theme-toggle {
  width: 32px;
  height: 32px;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  padding: 0 !important;
  border: 1px solid var(--rule) !important;
  border-radius: var(--radius) !important;
  color: var(--ink-2) !important;
}
.theme-toggle:hover { color: var(--ink) !important; background: var(--paper-hi) !important; }
.theme-toggle svg { width: 16px; height: 16px; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* EN/DA account-language switch (mounted by js/app-lang-toggle.js). Same
   pattern as the marketing/auth toggle (.lang-toggle in marketing-header.css
   and auth.css): small caps codes, the active one bold. The generic
   .dash-topbar-right button rule above is overridden for size + padding. */
.dash-topbar-right .app-lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .05em;
  color: var(--ink-2);
  flex-shrink: 0;
}
.dash-topbar-right .app-lang-toggle button {
  padding: 4px 6px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: inherit;
  text-transform: uppercase;
  color: inherit;
}
.dash-topbar-right .app-lang-toggle button[aria-pressed="true"] { color: var(--ink); font-weight: 700; }
.dash-topbar-right .app-lang-toggle button:disabled { cursor: progress; opacity: .6; }

/* ── Sidebar (paper-tone) ── */
.dash-sidebar {
  background: var(--paper-lo);
  padding: 24px 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-right: 1px solid var(--rule);
  /* APP-3: two-line gloss entries make the nav taller than a short viewport.
     Scroll the sidebar itself rather than the page. */
  overflow-y: auto;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: var(--ink-2);
  text-decoration: none;
  font-size: .88rem;
  font-weight: 500;
  transition: background .12s, color .12s, border-color .12s;
  border-left: 2px solid transparent;
}

.nav-link:hover { background: var(--paper-hi); color: var(--ink); }
.nav-link.active {
  background: var(--paper-hi);
  color: var(--ink);
  font-weight: 600;
  border-left-color: var(--gold);
}

.nav-icon { width: 18px; text-align: center; flex-shrink: 0; }
.nav-feather { display: block; height: 18px; width: auto; margin: 0 auto; }

/* APP-3 — brand name over its plain function word. `.nav-text` is the stacking
   column so `.nav-link`'s flex row keeps working for single-line entries too
   (Dashboard, Clients, Trash, Settings render exactly as before). */
.nav-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.nav-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-gloss {
  font-size: .72rem;
  font-weight: 400;
  color: var(--muted);
  letter-spacing: .01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nav-link:hover .nav-gloss,
.nav-link.active .nav-gloss { color: var(--ink-2); }

.nav-link--child {
  padding-left: 28px;
  font-size: .84rem;
  margin-left: 8px;
  border-left: 1px solid var(--slate-200);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.nav-link--child .nav-feather { height: 15px; }
.nav-link--child .nav-gloss { font-size: .69rem; }
.nav-link--child.active { border-left-color: var(--gold); }

/* ── Tier pill: "Pro" / "Studio" next to a module name or a section header ──
   One shared badge (js/tier-pill.js). Tokens only, so it follows light, dark
   and the pennapay app palette. Pro is outlined, Studio is filled, so the two
   read apart at a glance. */
.tier-pill {
  display: inline-block;
  flex-shrink: 0;
  margin-left: 6px;
  padding: 1px 7px;
  border: 1px solid var(--gold-text);
  border-radius: 999px;
  background: var(--accent-light);
  color: var(--gold-text);
  font-size: .66rem;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: .03em;
  text-transform: none;
  vertical-align: middle;
  white-space: nowrap;
  cursor: help;
}
.tier-pill--studio {
  border-color: var(--gold);
  background: var(--gold);
  color: var(--on-gold);
}
/* Sidebar: the name keeps its ellipsis, the pill never shrinks. */
.nav-title { display: flex; align-items: center; min-width: 0; }
.nav-title .nav-name { min-width: 0; }
.nav-title .tier-pill { margin-left: 6px; }
.nav-link--child .tier-pill { font-size: .62rem; }
/* Page title with its pill beside the h1 (the h1 is rewritten by i18n, so the pill is a sibling). */
.dash-title-main { display: flex; align-items: center; gap: 4px; min-width: 0; }
.dash-title-main .tier-pill { font-size: .7rem; }

/* ── Main content area ── */
.dash-main {
  background: var(--paper);
  /* Extra bottom padding so the last row of content clears the floating
     Feedback pill (fixed bottom-right) instead of sitting under it.
     --pf-launcher-clearance (feedback-widget.css) follows the launcher when a
     page lifts it (composer, action bar); 96px is the floor. */
  padding: 32px 32px max(96px, calc(var(--pf-launcher-clearance, 0px) + 22px));
  overflow-y: auto;
}

.dash-page-title {
  font-family: var(--serif);
  font-size: 1.9rem;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  letter-spacing: -.02em;
}

/* ── Stat cards ── */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 28px;
}

.stat-card {
  background: var(--paper-hi);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 24px;
  transition: transform .18s, border-color .18s;
  position: relative;
  overflow: hidden;
}
.stat-card:hover {
  transform: translateY(-1px);
  border-color: var(--muted);
}
/* Subtle top-border accent per card color */
.stat-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--rule);
}
.stat-card:has(.success)::before  { background: var(--success); }
.stat-card:has(.accent)::before   { background: var(--gold); }
.stat-card:has(.danger)::before   { background: var(--danger); }

.stat-label {
  font-family: var(--mono);
  font-size: .65rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted);
  margin-bottom: 12px;
}

.stat-value {
  font-family: var(--serif);
  font-size: 2.1rem;
  font-weight: 500;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -.02em;
}

.stat-value.accent  { color: var(--gold); }
.stat-value.success { color: var(--success); }
.stat-value.warning { color: var(--warning); }
.stat-value.danger  { color: var(--danger); }

/* ── Invoice / data table ── */
.data-table-wrap {
  background: var(--paper-hi);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  /* Scroll horizontally instead of clipping — on mobile the TOTAL column was
     cut off past the right edge with no way to reach it. -webkit-overflow-
     scrolling gives momentum scroll on touch. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}

.data-table-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--paper-hi);
}

.data-table-title {
  font-family: var(--serif);
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -.01em;
}

table.data-table {
  width: 100%;
  border-collapse: collapse;
}

table.data-table th {
  padding: 12px 20px;
  font-family: var(--mono);
  font-size: .65rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--muted);
  text-align: left;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
  background: var(--paper-lo);
}

table.data-table td {
  padding: 12px 20px;
  font-size: .88rem;
  color: var(--ink-2);
  border-bottom: 1px solid var(--rule);
  vertical-align: middle;
}

table.data-table tbody tr:last-child td { border-bottom: none; }
table.data-table tbody tr:hover td { background: var(--paper-lo); }

table.data-table td.mono {
  font-family: var(--mono);
  font-size: .82rem;
  color: var(--ink);
  /* Invoice / credit-note numbers must not wrap ("INV-" / "2026-006" on two
     lines) — keep them on one line; the column has room to spare. */
  white-space: nowrap;
}

/* ── Status badge (small caps with hairline ring) ── */
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: .65rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .12em;
  border: 1px solid transparent;
}

.badge-draft          { background: var(--paper-lo); color: var(--muted); border-color: var(--rule); }
.badge-sent           { background: var(--info-bg); color: var(--info); border-color: var(--info-br); }
.badge-paid           { background: var(--success-bg); color: var(--success); border-color: var(--success-br); }
.badge-overdue        { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-br); }
.badge-partially_paid { background: var(--warning-bg); color: var(--warning); border-color: var(--warning-br); }
.badge-cancelled      { background: var(--paper-lo); color: var(--muted); border-color: var(--rule); text-decoration: line-through; }
.badge-quote          { background: var(--warning-bg); color: var(--warning); border-color: var(--warning-br); }

/* ── Table row actions ── */
.row-actions {
  display: flex;
  gap: 8px;
  opacity: 0;
  transition: opacity .15s;
}

table.data-table tbody tr:hover .row-actions { opacity: 1; }

/* Touch devices have no hover — always show row actions */
@media (hover: none) {
  .row-actions { opacity: 1; }
}

.row-actions a,
.row-actions button {
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  padding: 6px 12px;
  min-height: 28px;
  font-family: var(--sans);
  font-size: .75rem;
  color: var(--ink-2);
  cursor: pointer;
  text-decoration: none;
  transition: background .1s, color .1s, border-color .1s;
}
.row-actions a:hover,
.row-actions button:hover { background: var(--paper); color: var(--ink); border-color: var(--ink-2); }
.row-actions button.danger:hover { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-br); }

/* ── Files table (files.html) ──
   The name column keeps room for a real file name at every width. Without a
   floor, the auto table layout gave a long name (a single unbroken string) a
   sliver a few characters wide, one or two characters per line, next to the
   nowrap link / size / date columns. */
table.files-table td.files-name {
  min-width: 16rem;
  font-weight: 600;
  color: var(--slate-800);
  overflow-wrap: anywhere;
}
/* The five hover buttons wrap onto a second line instead of claiming ~350px,
   which is what left the name column nothing at laptop widths. */
table.files-table td.files-actions { min-width: 15rem; }
table.files-table .files-actions .row-actions { flex-wrap: wrap; row-gap: 6px; }
table.files-table td.files-size { color: var(--slate-400); white-space: nowrap; }
table.files-table td.files-date { white-space: nowrap; }

/* Phones: a file is a stacked card instead of a six-column row (the sideways
   scroll left the name a few characters wide). Row 1: full name + the "⋯"
   menu; then project, link state, and size / date. The header row stays for
   screen readers but is not drawn. Rows that are not files (group headings,
   empty and error states) stay plain blocks. */
@media (max-width: 600px) {
  table.data-table.files-table { min-width: 0; }
  /* Nothing scrolls sideways here, so no "more to the right" fade. */
  .data-table-wrap.files-wrap { box-shadow: none; }
  .files-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .files-table,
  .files-table tbody,
  .files-table tbody tr,
  .files-table tbody td { display: block; }
  .files-table tbody tr.files-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 10px;
    row-gap: 8px;
    padding: 14px 14px 12px;
    border-bottom: 1px solid var(--rule);
  }
  .files-table tbody tr.files-row:last-child { border-bottom: none; }
  .files-table tbody tr.files-row:hover { background: var(--paper-lo); }
  table.data-table.files-table tbody tr.files-row td {
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
  }
  .files-table .files-name { grid-column: 1; grid-row: 1; }
  .files-table .files-project,
  .files-table .files-link { grid-column: 1 / -1; }
  .files-table .files-project select { max-width: 100%; }
  .files-table .files-size { grid-column: 1; }
  .files-table .files-date { grid-column: 2; text-align: right; }
  .files-table .files-empty { display: none; }
  /* The "⋯" cell is pinned to the scroller's edge on other tables; here the row
     does not scroll, so it is an ordinary grid cell (two ids of specificity to
     beat the shared .ofm-cell rules). */
  table.data-table.files-table tbody tr.files-row td.files-actions.files-actions {
    grid-column: 2;
    grid-row: 1;
    align-self: start;
    position: static;
    box-shadow: none;
    padding: 0;
  }
}

/* ── Invoice tables on a phone: one card per invoice ─────────────────────────
   Recent invoices (dashboard) and the Invoices list are wide tables; at 375px the
   dates were squeezed ("17 Oc 20") and Status and Total sat behind a sideways
   scroll, so the amounts could not be seen. Up to 600px each row becomes a small
   card (same approach as the Files table above): invoice number and total on the
   first line, client and status on the second, then the dates, the "⋯" menu at the
   right. Rows are told apart by column position, see the two table classes:
     .invoice-cards--recent  number, client, date, status, total, actions
     .invoice-cards--list    number, client, issued, due, status, total, actions */
@media (max-width: 600px) {
  table.data-table.invoice-cards { min-width: 0; }
  .data-table-wrap:has(> table.invoice-cards) { box-shadow: none; }
  .invoice-cards thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .invoice-cards,
  .invoice-cards tbody,
  .invoice-cards tfoot,
  .invoice-cards tbody td,
  .invoice-cards tfoot td { display: block; }
  table.data-table.invoice-cards tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    column-gap: 10px;
    row-gap: 4px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--rule);
  }
  table.data-table.invoice-cards tbody tr:last-child { border-bottom: none; }
  table.data-table.invoice-cards tbody tr td {
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
  }
  /* "Loading…", empty and error rows are one cell across the whole card. */
  table.data-table.invoice-cards tbody tr td[colspan] { grid-column: 1 / -1; padding: 24px 8px; }
  /* A labelled date ("Due date 24 Oct 2026"): the label comes from data-label. */
  .invoice-cards td[data-label] { font-size: .8rem; color: var(--ink-2); }
  .invoice-cards td[data-label]::before { content: attr(data-label) ": "; color: var(--muted); }
  .invoice-cards tbody td:nth-child(1) { white-space: nowrap; }

  /* Dashboard: number, total | client, status | date */
  .invoice-cards--recent tbody td:nth-child(1) { grid-area: 1 / 1; }
  .invoice-cards--recent tbody td:nth-child(5) { grid-area: 1 / 2; text-align: right; white-space: nowrap; }
  .invoice-cards--recent tbody td:nth-child(6) { grid-area: 1 / 3 / 3 / 4; }
  .invoice-cards--recent tbody td:nth-child(2) { grid-area: 2 / 1; }
  .invoice-cards--recent tbody td:nth-child(4) { grid-area: 2 / 2; text-align: right; }
  .invoice-cards--recent tbody td:nth-child(3) { grid-area: 3 / 1 / 4 / -1; font-size: .8rem; color: var(--ink-2); }

  /* Invoices: number, total | client, status | issued | due */
  .invoice-cards--list tbody td:nth-child(1) { grid-area: 1 / 1; }
  .invoice-cards--list tbody td:nth-child(6) { grid-area: 1 / 2; text-align: right; white-space: nowrap; }
  .invoice-cards--list tbody td:nth-child(7) { grid-area: 1 / 3 / 3 / 4; }
  .invoice-cards--list tbody td:nth-child(2) { grid-area: 2 / 1; }
  .invoice-cards--list tbody td:nth-child(5) { grid-area: 2 / 2; text-align: right; }
  .invoice-cards--list tbody td:nth-child(3) { grid-area: 3 / 1 / 4 / -1; }
  .invoice-cards--list tbody td:nth-child(4) { grid-area: 4 / 1 / 5 / -1; }

  /* The "⋯" cell is pinned to the scroller's edge on wide tables; a card does not
     scroll, so it is an ordinary grid cell (extra ids of specificity beat .ofm-cell). */
  table.data-table.invoice-cards tbody tr td.ofm-cell.ofm-cell {
    display: block;
    position: static;
    box-shadow: none;
    padding: 0;
    align-self: start;
  }

  /* The list footer: "N invoices" on the left, the total on the right. */
  .invoice-cards tfoot tr { display: flex; justify-content: space-between; gap: 12px; padding: 10px 14px; }
  table.data-table.invoice-cards tfoot td { padding: 0; border: 0; }
  table.data-table.invoice-cards tfoot td:empty { display: none; }
}

/* ── Empty state ── */
.empty-state {
  text-align: center;
  padding: 48px 20px;
  color: var(--ink-2);
  /* Sans, not mono — a mono empty/error line reads as debug output. */
  font-family: var(--sans);
  font-size: .95rem;
  letter-spacing: normal;
}
.empty-state p { margin-top: 8px; font-family: var(--sans); font-size: .9rem; letter-spacing: normal; color: var(--muted); }

/* ── Filter bar ── */
.filter-bar {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.filter-bar select,
.filter-bar input {
  width: auto;
  font-size: .82rem;
  padding: 6px 10px;
}

/* ── Dashboard "Recent invoices + sidebar widgets" grid ── */
.dash-bottom-grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 16px;
  align-items: start;
}

/* ── Modular dashboard (V2) — customizable widget grid ── */
.dash-widgets {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  align-items: start;
  margin-bottom: 20px;
}
.dash-widget { min-width: 0; }
.dash-widget--full { grid-column: 1 / -1; }
.dash-widget--half { grid-column: span 1; }
.dash-widget--off  { display: none !important; }

/* Customize trigger + drawer buttons: shared .btn .btn-ghost .btn-sm (main.css). */

/* ── Customize drawer ── */
.cz-overlay {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--ink) 38%, transparent);
  z-index: 400;
}
.cz-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(380px, 92vw);
  background: var(--paper-hi);
  border-left: 1px solid var(--rule);
  box-shadow: -8px 0 28px color-mix(in srgb, var(--ink) 16%, transparent);
  z-index: 401;
  display: flex;
  flex-direction: column;
  padding: 20px 20px 16px;
  transform: translateX(100%);
  transition: transform .22s ease;
  overflow-y: auto;
}
.cz-drawer.cz-open { transform: translateX(0); }
/* Parked off-screen, its 28px shadow still bled onto the right edge of every
   dashboard screen as a grey strip. Only cast it while the drawer is open. */
.cz-drawer:not(.cz-open) { box-shadow: none; }

.cz-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.cz-head h2 {
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -.01em;
}
.cz-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1.05rem;
  line-height: 1;
  color: var(--muted);
  padding: 6px;
  border-radius: var(--radius-sm);
}
.cz-close:hover { color: var(--ink); background: var(--paper-lo); }
.cz-close:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.cz-sub {
  font-size: .82rem;
  color: var(--ink-2);
  margin: 6px 0 16px;
  line-height: 1.45;
}

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

.cz-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}
.cz-row.cz-dragging { opacity: .55; border-style: dashed; }
.cz-row--locked { opacity: .72; }

.cz-grip {
  cursor: grab;
  color: var(--muted);
  font-size: 1rem;
  line-height: 1;
  user-select: none;
  flex-shrink: 0;
}
.cz-row--locked .cz-grip { cursor: not-allowed; }

.cz-row-main { flex: 1; min-width: 0; }
.cz-row-title {
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 6px;
}
.cz-row-blurb {
  font-size: .74rem;
  color: var(--muted);
  margin-top: 2px;
  line-height: 1.35;
}
.cz-lock {
  font-family: var(--mono);
  font-size: .58rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--gold);
  border: 1px solid var(--gold);
  border-radius: 999px;
  padding: 1px 6px;
}

.cz-width { display: inline-flex; flex-shrink: 0; }
.cz-width-btn {
  background: var(--paper-hi);
  border: 1px solid var(--rule);
  color: var(--ink-2);
  cursor: pointer;
  width: 28px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .85rem;
  padding: 0;
}
.cz-width-btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.cz-width-btn:last-child  { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; border-left: none; }
.cz-width-btn.active { background: var(--gold); border-color: var(--gold); color: var(--paper); }
.cz-width-btn:disabled { cursor: not-allowed; opacity: .5; }
.cz-width-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

/* Toggle switch */
.cz-switch { position: relative; display: inline-block; width: 38px; height: 22px; flex-shrink: 0; }
.cz-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.cz-slider {
  position: absolute;
  inset: 0;
  cursor: pointer;
  background: var(--muted);
  border-radius: 999px;
  transition: background .15s;
}
.cz-slider::before {
  content: '';
  position: absolute;
  height: 16px;
  width: 16px;
  left: 3px;
  top: 3px;
  background: var(--paper-hi);
  border-radius: 50%;
  transition: transform .15s;
}
.cz-switch input:checked + .cz-slider { background: var(--success); }
.cz-switch input:checked + .cz-slider::before { transform: translateX(16px); }
.cz-switch input:disabled + .cz-slider { cursor: not-allowed; opacity: .5; }
.cz-switch input:focus-visible + .cz-slider { outline: 2px solid var(--gold); outline-offset: 2px; }

.cz-actions {
  display: flex;
  gap: 10px;
  justify-content: space-between;
  padding-top: 16px;
  margin-top: 12px;
  border-top: 1px solid var(--rule);
}
.cz-actions .btn { font-size: .85rem; }
/* The feedback launcher (z-index 1200, bottom-right) sits above the drawer (401) and
   covers its Save button. Step it aside while the drawer is open. */
body:has(.cz-drawer.cz-open) .pf-launcher { display: none; }

/* ── Mobile bottom nav (paper-tone) ── */
.dash-mobile-nav {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--paper-lo);
  border-top: 1px solid var(--rule);
  z-index: 200;
  padding: 0;
  transform: translateZ(0);
  will-change: transform;
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.dash-mobile-nav-inner {
  display: flex;
  align-items: stretch;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.dash-mobile-nav-inner::-webkit-scrollbar { display: none; }
.dash-mobile-nav a {
  flex: 0 0 auto;
  min-width: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 8px;
  color: var(--ink-2);
  text-decoration: none;
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .04em;
  transition: color .15s, background .15s;
  white-space: nowrap;
}
.dash-mobile-nav a .nav-icon { font-size: 1.1rem; }
.dash-mobile-nav a .nav-feather { height: 20px; }
.dash-mobile-nav a.active { color: var(--gold); font-weight: 600; }
.dash-mobile-nav a:hover { color: var(--ink); }

/* ── Mobile ── */
@media (max-width: 768px) {
  /* Kill any horizontal overflow at the document level so the page
     doesn't jerk sideways while scrolling fast on mobile. */
  html, body { overflow-x: hidden; max-width: 100vw; }

  /* minmax(0, 1fr), not 1fr: a bare 1fr track has an automatic minimum equal to
     its widest child, and the topbar (brand + workspace switcher + theme toggle
     + "New invoice" + "Log out", all nowrap) is wider than a 375px phone. The
     column then grew to ~424px and overflow-x:hidden below cut the page off at
     the right: "Log ud", "+ Ny faktura" and the right edge of every card. */
  .dash-shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 52px 1fr;
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0));
    max-width: 100vw;
    overflow-x: hidden;
  }
  .dash-sidebar { display: none; }
  .dash-mobile-nav { display: block; }
  .stat-grid { grid-template-columns: 1fr 1fr; }
  /* Bottom: clear the launcher, which sits above the 58px mobile nav that
     .dash-shell already pads for. */
  .dash-main { padding: 16px 16px max(16px, calc(var(--pf-launcher-clearance, 0px) - 58px + 12px)); }

  /* Let tables scroll horizontally on small screens; right-edge fade = a clearer
     "there's more →" affordance than the old faint inset line (the TOTAL column
     sat off-screen with no hint it was reachable). */
  .data-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    box-shadow: inset -14px 0 12px -12px var(--ink-2);
  }
  table.data-table { min-width: 560px; }

  /* Row actions always visible on mobile (no hover) */
  .row-actions { opacity: 1; }

  /* PennaSchedule section nav: scroll affordance at 390px */
  .pb-section-nav {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    box-shadow: inset -2px 0 0 var(--rule);
  }
  .pb-section-nav::-webkit-scrollbar { display: none; }

  /* Page title stacks on very small screens */
  .dash-page-title { flex-wrap: wrap; font-size: 1.1rem; }

  /* Stack the Recent-invoices / sidebar widgets grid into one column */
  .dash-bottom-grid {
    grid-template-columns: 1fr;
  }
  .dash-bottom-grid > div:last-child {
    min-width: 0 !important;
    max-width: none !important;
  }

  /* Modular dashboard (V2) — every widget spans full width on mobile */
  .dash-widgets { grid-template-columns: 1fr; gap: 16px; }
  .dash-widget--half, .dash-widget--full { grid-column: 1 / -1; }
}

@media (max-width: 500px) {
  /* Tighten the topbar so its (now non-wrapping) labels still fit at 390px. */
  .dash-topbar { padding: 0 10px; gap: 6px; }
  .dash-brand { font-size: 1rem; flex-shrink: 0; }
  .dash-topbar-right { gap: 2px; font-size: .78rem; min-width: 0; }
  .dash-topbar-right a,
  .dash-topbar-right button { padding: 4px 4px; font-size: .78rem; }
  .dash-topbar-right .app-lang-toggle button { padding: 4px 3px; font-size: .7rem; }
  /* Buttons and links never shrink (a clipped "Log ud" reads "Lo"); the
     workspace name is the ONE flexible label. It takes whatever room is left
     and ends in an ellipsis; the full name stays on the control's title
     (org-switcher.js). Before this the name was capped at 60px while the
     buttons were still pushed past 375px, and overflow-x:hidden on .dash-shell
     cut "Log out" off. */
  .dash-topbar-right > * { flex-shrink: 0; }
  .dash-topbar-right > .pp-orgsw { flex: 0 1 auto; min-width: 32px; }
  .dash-topbar .pp-orgsw-toggle { min-width: 32px; max-width: 100%; gap: 4px; padding: 5px 6px !important; }
  .dash-topbar .pp-orgsw-name { min-width: 0; max-width: none; }
  .theme-toggle { width: 28px; height: 28px; }

  /* Stack the workflow chain vertically — arrows look messy when wrapped,
     so hide them and let each step sit on its own row. */
  .wf-row { align-items: flex-start; gap: 8px; }
  .wf-client {
    min-width: 0;
    max-width: 100%;
    margin-right: 0;
    flex: 0 0 auto;
  }
  .wf-chain {
    flex-direction: column;
    align-items: stretch;
    flex: 1 1 100%;
    gap: 6px;
  }
  .wf-chain .wf-arrow { display: none; }
  .wf-step { justify-content: flex-start; }
}

@media (max-width: 360px) {
  /* A 320px phone has no room for the theme button as well: it follows the
     system light/dark setting there, and the workspace switcher keeps its
     caret (name on the title) instead of being squeezed to nothing. */
  .dash-topbar-right .theme-toggle { display: none !important; }
  .dash-topbar { padding: 0 8px; gap: 4px; }
  .dash-brand { font-size: .92rem; }
}

/* ── Focus indicators (WCAG 2.4.7) ── */
.dash-topbar-right a:focus-visible,
.dash-topbar-right button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.theme-toggle:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.nav-link:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.row-actions a:focus-visible,
.row-actions button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* ── org-switcher ─────────────────────────────────────────────────────────────
 * Styles for the multi-organization workspace switcher injected by
 * frontend/js/org-switcher.js into .dash-topbar-right. These live here (a
 * <link>ed static stylesheet, CSP-allowed as 'self') rather than in a
 * JS-injected <style> — under strict CSP a runtime-injected <style> carries no
 * nonce and is rejected by the browser, so the switcher (dropdown + modal)
 * rendered unstyled. Do not move these back into JS. */
.pp-orgsw { position: relative; display: inline-flex; align-items: center; }
.pp-orgsw-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 200px; padding: 5px 9px !important;
  border: 1px solid var(--rule) !important; border-radius: 8px !important;
  background: var(--paper-hi) !important; color: var(--ink) !important;
  font-family: var(--sans); font-size: .82rem; line-height: 1; cursor: pointer;
}
.pp-orgsw-toggle:hover { background: var(--paper-lo) !important; }
.pp-orgsw-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 150px; }
.pp-orgsw-caret { flex-shrink: 0; opacity: .6; }
.pp-orgsw-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  min-width: 240px; max-width: 300px; padding: 6px;
  background: var(--paper-hi, #fff); color: var(--ink); /* lint-allow-color */
  border: 1px solid var(--rule); border-radius: 10px;
  box-shadow: var(--shadow-lg);
}
.pp-orgsw-menu[hidden] { display: none; }
.pp-orgsw-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--ink-2, #64748b); padding: 4px 8px 6px; } /* lint-allow-color */
.pp-orgsw-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 8px; border: none; border-radius: 7px; background: none;
  color: var(--ink) !important; font-family: var(--sans); font-size: .85rem;
  text-align: left; cursor: pointer;
}
.pp-orgsw-item:hover { background: var(--paper-lo) !important; }
.pp-orgsw-item .pp-orgsw-itemname { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-orgsw-item .pp-orgsw-tier { font-size: .68rem; color: var(--ink-2, #64748b); text-transform: capitalize; } /* lint-allow-color */
.pp-orgsw-check { width: 16px; flex-shrink: 0; color: var(--accent, #2563eb); } /* lint-allow-color */
.pp-orgsw-sep { height: 1px; background: var(--rule); margin: 6px 4px; }
.pp-orgsw-action { color: var(--accent, #2563eb) !important; font-weight: 500; } /* lint-allow-color */

.pp-orgsw-modal[hidden] { display: none; }
.pp-orgsw-modal {
  position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
  background: rgba(15,23,42,.45); padding: 16px; /* lint-allow-color */
}
.pp-orgsw-dialog {
  width: 100%; max-width: 400px; background: var(--paper-hi, #fff); color: var(--ink); /* lint-allow-color */
  border-radius: 14px; padding: 22px; box-shadow: var(--shadow-lg);
}
.pp-orgsw-dialog h2 { font-size: 1.05rem; font-weight: 700; margin: 0 0 4px; color: var(--ink); }
.pp-orgsw-dialog p { font-size: .85rem; color: var(--ink-2, #64748b); margin: 0 0 14px; } /* lint-allow-color */
.pp-orgsw-dialog input {
  width: 100%; padding: 10px 12px; font-size: .9rem; font-family: var(--sans);
  border: 1px solid var(--rule); border-radius: 9px; background: var(--paper-lo, #fff); color: var(--ink); /* lint-allow-color */
  box-sizing: border-box;
}
.pp-orgsw-dialog-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.pp-orgsw-error { color: var(--danger, #dc2626); font-size: .8rem; margin-top: 8px; min-height: 1em; } /* lint-allow-color */

/* Consumer withdrawal period banner (SR-08, js/dashboard-withdrawal.js).
   No dismiss control: see the module header. Tokens only (penna-tokens.css). */
.dash-withdrawal {
  display: flex; align-items: center; gap: 12px 16px; flex-wrap: wrap;
  background: var(--info-bg); border: 1px solid var(--info-br);
  border-radius: var(--radius-lg); padding: 14px 18px; margin-bottom: 20px;
  color: var(--ink);
}
.dash-withdrawal[hidden] { display: none; }
.dash-withdrawal__text { flex: 1 1 260px; min-width: 0; }
.dash-withdrawal__title { display: block; font-size: .95rem; font-weight: 700; color: var(--ink); }
.dash-withdrawal__line { margin: 2px 0 0; font-size: .875rem; color: var(--ink-2); }
.dash-withdrawal__link { white-space: nowrap; }

/* invoices.html — Invoices / Trash switch and the Trash notice (app IA PR 5, B7).
   The pressed button reads as the current view; setView() sets aria-pressed. */
.invoice-view-switch { display: inline-flex; gap: 4px; }
.invoice-view-switch .btn { font-weight: 400; color: var(--muted); }
.invoice-view-switch .btn[aria-pressed="true"] { font-weight: 700; color: var(--ink); }
.invoice-trash-notice { margin: -4px 0 12px; font-size: .82rem; color: var(--muted); }
