/* ==========================================================================
   Einstellungen (#page-settings)
   Two-level tab nav (Profil / Finanzen / Katalog) + one full-width `.card` per
   sub-tab with a shared bottom-right FAB and an `.overlay > .modal` for
   add/edit. The Finanzen sub-tabs (Buckets / Sparziele / Budget-Kategorien /
   Konten / Empfänger / Wunschliste / Vorlagen) manage finance records, so the
   list/row/tag look here is deliberately the shared finance-management one —
   hence the `.fin-*` class prefix is kept rather than renamed to `.settings-*`.

   Shared bits live elsewhere and are only used here:
   - `.fin-list-row*`, `.fin-row-btn*`, `.fin-empty`, `.fin-list-summary`,
     `.fin-bucket-group*`, `.fin-wishlist-dropzone*`, `.fin-field-row-stretch`,
     `.fin-suffix*` → finance-shared.css
   - `.fin-product-*` / `.fin-flag` (the article-product card, also used by the
     quick-create modal js/components/article-form-modal.js) → finance-shared.css
   - `.fin-tag*`, `.fin-tx-search`, `.fin-tx-filter-btn*`, `.fin-trigger-icon`,
     `.fin-field-trigger-btn`, `.drag-handle`, `.tile-picker*` → components.css /
     finance-transactions.css
   ========================================================================== */

/* ---------- Group bar (level 1) + sub-tab pills (level 2) ---------- */
.fin-admin-tabs {
  display: flex;
  gap: var(--space-8);
  margin-bottom: var(--space-16);
  border-bottom: var(--bw) solid var(--line);
}

/* Second-level nav: the active group's sub-tabs, as pills (distinct from the
   underline group bar above). Hidden when a group has only one tab (Profil) —
   the group bar then keeps its own `.fin-admin-tabs` bottom gap so the panel
   below doesn't butt right up against the tab row. The negative top margin
   just tightens the gap to the group bar when the sub-tabs ARE shown. */
.fin-admin-subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  margin: calc(-1 * var(--space-6)) 0 var(--space-16);
}

.fin-admin-subtabs .fin-tab-btn {
  padding: var(--space-6) var(--space-12);
  border: var(--bw) solid var(--line-strong);
  border-radius: var(--radius-pill);
  font-size: var(--fs-m);
}

.fin-admin-subtabs .fin-tab-btn.active {
  background: var(--brass);
  border-color: var(--brass);
  color: var(--on-accent);
}

/* Einstellungen has several tabs per level — narrow viewports need this to
   become a horizontally scrollable strip instead of silently overflowing past
   the edge with the trailing tabs unreachable. */
@media (max-width: 900px) {
  .fin-admin-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
  }
  .fin-admin-subtabs {
    flex-wrap: nowrap;
    overflow-x: auto;
  }
}

/* Wrapper around the two nav bars — layout-transparent (`display: contents`)
   so the group bar + sub-tab row flow as if they were direct children of the
   panel. Kept as an element only so JS can hide *both* bars at once
   (updateSettingsNavVisibility() toggles `.is-hidden`, which wins over
   `display: contents`). */
.fin-admin-nav-sticky {
  display: contents;
}

.fin-tab-btn {
  flex-shrink: 0;
  white-space: nowrap;
  padding: var(--space-10) var(--space-16);
  background: none;
  border: none;
  border-bottom: var(--bw-accent) solid transparent;
  color: var(--ink-dim);
  font-weight: 600;
  cursor: pointer;
}

.fin-tab-btn.active {
  color: var(--brass);
  border-bottom-color: var(--brass);
}

.fin-tab-panel {
  display: none;
}

.fin-tab-panel.active {
  display: block;
}

/* applyRoleRestrictions() (js/app/auth.js) toggles .hidden on any element
   with data-min-role — Einstellungen applies it per-tab (button + panel)
   rather than on the whole page, since Profil must stay reachable for
   every role. .fin-tab-panel is already display:none by default (only
   .active shows it) so this mostly matters for the button, which isn't. */
.fin-tab-btn.hidden,
.fin-tab-panel.hidden {
  display: none;
}

/* ---------- Profil panel (avatar / name / role + theme + accent) ---------- */
:root {
  --fin-profile-avatar: 150px;         /* the square (1:1) profile-picture dropzone */
  --fin-profile-avatar-mobile: 96px;   /* … shrunk on phones so name stays alongside it */
  --fin-settings-card-w: 440px;        /* the Profil card — narrower than the list cards, form-width */
  --fin-theme-toggle-w: 52px;          /* light/dark switch track */
  --fin-theme-toggle-h: 28px;
  --fin-theme-toggle-inset: 3px;       /* knob gap from the track edge */
  --fin-theme-toggle-knob: 20px;       /* → track-w minus 2×inset gives the "on" offset below */
  --fin-list-title-mobile-max: 150px;  /* row-title name cap on phones (single line, ellipsis) */
}

.fin-settings-display-card {
  max-width: var(--fin-settings-card-w);
}

/* Card heading row: the "Profil" title with the Kontotyp badge pinned to the
   far right of the same line. */
.fin-settings-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  margin-bottom: var(--space-10);
}

.fin-settings-card-head h3 {
  margin-bottom: 0;
}

/* Square profile picture on the left, Nutzername + Speichern stacked on the
   right; one block with no inner divider (unlike the theme/accent rows below). */
.fin-profile-form {
  display: flex;
  align-items: flex-start;
  gap: var(--space-16);
  border-bottom: var(--bw) solid var(--line);
}

.fin-profile-avatar-field {
  flex: 0 0 auto;
}

/* 1:1 dropzone — overrides the shared band's fixed height. */
.fin-profile-avatar-field .fin-wishlist-dropzone {
  width: var(--fin-profile-avatar);
  height: var(--fin-profile-avatar);
}

.fin-profile-form-fields {
  flex: 1;
  min-width: 0;
  min-height: var(--fin-profile-avatar);
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}

/* Speichern is pushed to the bottom-right, its baseline level with the
   bottom edge of the square profile picture. */
.fin-profile-form-fields .modal-actions {
  justify-content: flex-end;
  margin-top: auto;
}

@media (max-width: 720px) {
  /* Keep picture-left / name-right, just on a smaller square. */
  .fin-profile-form {
    gap: var(--space-12);
  }

  .fin-profile-avatar-field .fin-wishlist-dropzone {
    width: var(--fin-profile-avatar-mobile);
    height: var(--fin-profile-avatar-mobile);
  }

  /* Too narrow for the "Profilbild hochladen" caption — leave just the icon. */
  .fin-profile-avatar-field .fin-wishlist-dropzone-hint {
    display: none;
  }

  .fin-profile-form-fields {
    min-height: var(--fin-profile-avatar-mobile);
  }

  /* On phones the avatar is short, so "Speichern" ends up crammed against the
     card's border-bottom divider — give it some breathing room below. */
  .fin-profile-form-fields .modal-actions {
    margin-bottom: var(--space-12);
  }
}

/* Kontotyp tag — the translucent-accent look (soft accent fill + accent text),
   same for Administrator and Normal; only the label differs. */
.fin-role-badge {
  flex: 0 0 auto;
  padding: var(--space-4) var(--space-10);
  border-radius: var(--radius-pill);
  font-size: var(--fs-s);
  font-weight: 700;
  background: var(--brass-soft);
  color: var(--brass);
  border: var(--bw) solid var(--brass);
}

.fin-settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
  padding: var(--space-16) 0;
  border-bottom: var(--bw) solid var(--line);
}

.fin-settings-row:last-child {
  border-bottom: none;
}

.fin-settings-row-column {
  flex-direction: column;
  align-items: stretch;
}

.fin-settings-row-label {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.fin-settings-row-label b {
  font-size: var(--fs-l);
}

.fin-settings-row-label span {
  font-size: var(--fs-m);
  color: var(--muted);
}

/* Light/Dark toggle switch — a track + sliding knob, not a plain button.
   Reads the existing global data-theme attribute directly (set by
   js/services/theme.js) rather than needing its own state class, so no JS
   changes were needed to make this a "real" toggle. */
.fin-theme-toggle {
  flex: 0 0 auto;
  position: relative;
  width: var(--fin-theme-toggle-w);
  height: var(--fin-theme-toggle-h);
  padding: 0;
  border-radius: var(--radius-pill);
  background: var(--panel-alt);
  border: var(--bw) solid var(--line-strong);
  cursor: pointer;
}

.fin-theme-toggle-knob {
  position: absolute;
  top: var(--fin-theme-toggle-inset);
  left: var(--fin-theme-toggle-inset);
  width: var(--fin-theme-toggle-knob);
  height: var(--fin-theme-toggle-knob);
  border-radius: 50%;
  background: var(--brass);
  color: var(--on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: left var(--t-med) ease;
}

.fin-theme-toggle-knob svg {
  width: var(--icon-xs);
  height: var(--icon-xs);
}

:root[data-theme="dark"] .fin-theme-toggle {
  background: var(--brass-soft);
  border-color: var(--brass);
}

:root[data-theme="dark"] .fin-theme-toggle-knob {
  /* slid to the far end: track width minus the knob and both edge gaps */
  left: calc(var(--fin-theme-toggle-w) - var(--fin-theme-toggle-knob) - 2 * var(--fin-theme-toggle-inset));
}

/* ---------- List cards: full-width `.card` + FAB + `.overlay > .modal` ----------
   Every sub-tab (Finanzen + Katalog) renders one full-width `.card`; the shared
   bottom-right FAB (mountFab, pageId "settings") opens the active sub-tab's
   add/edit modal. Articles / Marken / NFC-Tags / Empfänger also carry a
   search + filter row inside `.fin-admin-card-head`. */

/* Layout-transparent wrapper — the `<h3>` and (optional) `.fin-admin-list-tools`
   flow as plain `.card` children with their own margins. It exists only to
   group them in the markup. */
.fin-admin-card-head {
  display: contents;
}

/* Search box (reuses .fin-tx-search's underline look) + filter toggle(s). */
.fin-admin-list-tools {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-bottom: var(--space-12);
}

/* "Ohne Bild" toggle uses the app-wide filter-button recipe
   (`.btn-ghost.btn-pill.fin-tx-filter-btn`, same as the Transaktionen filters);
   its pressed state is the shared `.fin-tx-filter-btn.active` in components.css. */

/* Drag grip in an admin list row — sits left of the icon, vertically centred
   and compact rather than stretched to the row height. Extends .drag-handle. */
.fin-admin-drag {
  flex: 0 0 auto;
  align-self: center;
  width: var(--icon-xl);
  padding: var(--space-8) 0;
  border-radius: var(--radius);
}

.fin-list-row.is-dragging {
  opacity: var(--dragging-opacity);
}

/* ---------- Katalog > Artikel: Typ/Kategorie filter pills ----------
   Popover-select triggers sitting in `.fin-admin-list-tools` next to the search
   field. Styled like `.btn-ghost` (bordered mono pill); `.has-value` picks up
   the accent so an active filter reads at a glance. Both are a fixed width so
   they line up regardless of the chosen label. */
:root {
  --fin-admin-filter-w: 200px;   /* Typ / Kategorie filter pill — fixed so the two align */
}

.fin-admin-filter {
  flex: 0 0 auto;
  width: var(--fin-admin-filter-w);
  max-width: 100%;
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-12);
  background: none;
  border: var(--bw) solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink-dim);
  font-size: var(--fs-s);
  font-family: var(--font-mono);
  text-align: left;
  cursor: pointer;
}

/* Label sits next to the leading icon and ellipsizes rather than widening the pill. */
.fin-admin-filter .fin-admin-filter-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.fin-admin-filter .fin-trigger-icon {
  margin-right: 0;
  flex: 0 0 auto;
}

.fin-admin-filter.has-value {
  border-color: var(--brass);
  color: var(--brass);
}

.fin-admin-filter:hover:not(:disabled) {
  border-color: var(--brass);
}

/* Kategorie-Filter only makes sense once a Typ is chosen — each Typ has its
   own distinct category set, so filtering by Kategorie alone across all
   types would mix unrelated labels. Disabled (not just visually muted)
   until a Typ is selected. */
.fin-admin-filter:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Article-category sections on Katalog > Artikel-Kategorien: the group heading
   is just the Typ icon + label, so pull them together on the left (the shared
   rule spreads a trailing total to the right, which these lack). */
#artCatList .fin-bucket-group-title {
  justify-content: flex-start;
}

/* ---------- Katalog > Artikel: collapsible row ---------- */
/* The row is a plain `.fin-list-row` whose icon+main sit inside a full-width
   button (`.fin-article-row-head`, taking the place of a bare div so the
   whole row toggles the detail panel below it) instead of directly inside
   `.fin-list-row` — edit/delete stay outside the button so they keep working
   as independent controls. `.fin-article-row-chevron` joins the shared
   collapsible-header chevron family (components.css) for the rotate-on-
   `.is-collapsed` behaviour; everything else here is local. */
.fin-article-row {
  border-bottom: var(--bw) solid var(--line);
}

.fin-article-row:last-child {
  border-bottom: none;
}

.fin-article-row > .fin-list-row {
  border-bottom: none;
}

.fin-article-row-head {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.fin-article-row.is-collapsed .fin-article-row-detail {
  display: none;
}

/* Einheit line + product list, indented to roughly align under the title
   (past the row icon + chevron). */
.fin-article-row-detail {
  padding: 0 var(--space-4) var(--space-12) calc(var(--fin-list-avatar) + var(--space-24));
}

.fin-article-detail-units {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-12);
  font-size: var(--fs-s);
  color: var(--ink-dim);
  margin-bottom: var(--space-8);
}

.fin-article-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}

.fin-article-chip svg {
  width: var(--icon-xs);
  height: var(--icon-xs);
  flex: 0 0 auto;
  color: var(--brass);
}

.fin-article-detail-products {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.fin-article-detail-product {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-6) var(--space-8);
  background: var(--panel-alt);
  border-radius: var(--radius);
}

/* Marke (bold, normal size) — reads as the more prominent identifier than
   the product name next to it, same reasoning as a shop receipt/label. */
.fin-article-detail-product-brand {
  font-weight: 600;
}

.fin-article-detail-product-name {
  font-size: var(--fs-s);
  color: var(--ink-dim);
  flex: 1 1 auto;
  min-width: var(--space-48);
}

.fin-article-detail-product-ean {
  font-size: var(--fs-s);
  color: var(--muted);
}

.fin-article-detail-product-default {
  font-size: var(--fs-2xs);
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brass);
  border: var(--bw) solid var(--brass);
  border-radius: var(--radius-pill);
  padding: 0 var(--space-6);
}

/* Typ-Tag + Kategorie + Mindestbestand on one sub-line. */
.fin-article-tagline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

/* Vegan/vegetarisch + Siegel icon badges on a product's detail row. */
.fin-article-badge {
  display: inline-flex;
  align-items: center;
  color: var(--green);
}

.fin-article-badge svg,
.fin-article-badge img {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

.fin-article-badge img {
  object-fit: contain;
}

/* NFC-tag list: one uniform line "Artikel (± Menge Einheit)" — composed text,
   no bold segment, no metadata styling, so it reads as a single run. */
.fin-nfc-line {
  font-weight: 600;
  color: var(--ink);
}

/* ⚠ flagged-brand names on a Marken/Konzerne list row. */
.fin-list-warn {
  color: var(--coral);
}

/* Small muted explainer line under a form field / above the actions
   (e.g. the NFC-tag modal's "beim Antippen wird verrechnet" note). */
.fin-form-hint {
  margin: calc(-1 * var(--space-4)) 0 var(--space-8);
  font-size: var(--fs-s);
  color: var(--muted);
}

/* ---------- Phone (<=720px) ---------- */
@media (max-width: 720px) {
  /* Row title: keep it one line, cap the name so a long article/payee name
     can't shove the row-actions off the edge. (Overrides the shared rule that
     stacks title children — the settings lists read better single-line here.) */
  #page-settings .fin-list-row-title {
    flex-direction: row;
    align-items: center;
    max-width: 100%;
  }

  #page-settings .fin-list-row-title b,
  #page-settings .fin-nfc-line {
    max-width: var(--fin-list-title-mobile-max);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Wunschliste-Kategorie: the funding tag is too wide to sit beside the name —
     drop it under the title (back to the shared column behaviour, which the
     rule above turned off for the other settings lists). */
  #finWishlistCategoryList .fin-list-row-title {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
  }

  /* Article Einheit line inside an expanded row: one chip per line rather
     than a wrapping row. */
  .fin-article-detail-units {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
  }

  /* Vorlagen type picker: icon only (label on the tooltip / aria-label). */
  #finTxTemplateTypePicker .segmented-item span {
    display: none;
  }
}
