/* ==========================================================================
   Finance — shared across finance pages
   Classes used by two or more of Übersicht / Transaktionen / Wunschliste /
   Einstellungen. Loaded before every finance page stylesheet, so a page file
   can still override any of these. Generic, non-finance components
   (tile-picker, the colored .fin-tag badge) live in components.css instead.
   ========================================================================== */

/* Sizes shared by the finance pages (see the token note in css/base.css). */
:root {
  --fin-list-avatar: 36px;         /* admin-row / Transaktionen-row icon box */
  --fin-list-avatar-mobile: 30px;  /* … on phones */
  --fin-dropzone-h: 140px;         /* image upload area (Wunschliste / Empfänger / Artikel) */
}

/* ---------- Field-row bottom alignment ---------- */
/* Two fields side by side whose actual controls should line up at the same
   height regardless of label differences (Verwaltung's Zielbetrag/Zieldatum,
   Startkapital/Notgroschen-Anteil). */
.fin-field-row-stretch {
  align-items: stretch;
}

.fin-field-row-stretch .field {
  justify-content: flex-end;
}

/* ---------- Trailing-unit inputs (Zielbetrag, Startkapital, Anteil, Budget) ---------- */
/* Input + always-visible "€" suffix sharing one underline, so the currency
   doesn't disappear with the placeholder once a value is typed. */
.fin-suffix-input-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  border-bottom: var(--bw-strong) solid var(--line-strong);
  padding: var(--space-8) var(--space-2);
}

.fin-suffix-input-row:hover,
.fin-suffix-input-row:focus-within {
  border-bottom-color: var(--brass);
}

.fin-suffix-input-row input {
  flex: 1;
  min-width: 0;
  border: none;
  padding: 0;
  background: none;
  font-size: var(--fs-xl);
  color: var(--ink);
}

.fin-suffix {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: var(--fs-s);
}

/* ---------- Bucket groups (Übersicht bucket table, Einstellungen > Budgets) ---------- */
.fin-bucket-group {
  margin-bottom: var(--space-20);
}

.fin-bucket-group:last-child {
  margin-bottom: 0;
}

.fin-bucket-group-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-10);
  flex-wrap: wrap;
  font-size: var(--fs-l);
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brass);
  padding: var(--space-16) var(--space-4) var(--space-8);
  border-bottom: var(--bw-accent) solid var(--brass);
  margin-bottom: var(--space-10);
}

.fin-bucket-group-title svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

/* ---------- Admin list rows (accounts / payees / buckets / articles / categories) ---------- */
.fin-list-row {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-10) var(--space-4);
  border-bottom: var(--bw) solid var(--line);
}

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

.fin-list-row-icon {
  width: var(--fin-list-avatar);
  height: var(--fin-list-avatar);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--tag-color, var(--muted)) 16%, var(--panel-alt));
  color: var(--tag-color, var(--ink-dim));
  flex: 0 0 auto;
}

.fin-list-row-icon svg,
.fin-list-row-icon .masked-icon {
  width: var(--icon-lg);
  height: var(--icon-lg);
}

/* A full-colour uploaded icon (e.g. an article SVG) fills the avatar box —
   contained, so a non-square image isn't cropped, and never overflowing (a
   viewBox-only SVG has no intrinsic size). */
.fin-list-row-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.fin-payee-logo {
  background: var(--panel-alt);
  overflow: hidden;
}

.fin-payee-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.fin-list-row-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

/* Name + inline tag (e.g. a bucket's Typ bubble) on one compact line. */
.fin-list-row-title {
  display: flex;
  gap: var(--space-8);
  min-width: 0;
}

.fin-list-row-title b {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.fin-list-row-sub {
  font-size: var(--fs-s);
  color: var(--ink-dim);
}

.fin-list-row-actions {
  display: flex;
  gap: var(--space-4);
  flex: 0 0 auto;
}

.fin-row-btn {
  width: var(--hit);
  height: var(--hit);
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: var(--bw) solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink-dim);
  cursor: pointer;
}

.fin-row-btn svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

/* Hover/danger states shared app-wide — see components.css "SHARED HOVER STATES". */

.fin-list-summary {
  margin-top: var(--space-10);
  padding-top: var(--space-10);
  font-size: var(--fs-m);
  color: var(--ink-dim);
}

.fin-empty {
  padding: var(--space-24);
  text-align: center;
  color: var(--ink-dim);
  /* Span every column when it stands in for a grid of cards/tiles (recipe grid,
     wishlist grid); inert in the flex/block lists that also use it. */
  grid-column: 1 / -1;
}

/* ---------- Image dropzone (Wunschliste, Einstellungen Empfänger + Artikel, Rezept) ---------- */
/* Large click-to-browse upload area, always the form's topmost field. One
   shared class so all the forms look identical. `.field .fin-wishlist-dropzone`
   re-asserts `display:flex` because `.field label { display:block }` in
   components.css (a `<label>` carries this class) is more specific. */
.fin-wishlist-dropzone,
.field .fin-wishlist-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  height: var(--fin-dropzone-h);
  border: var(--bw-strong) dashed var(--line-strong);
  border-radius: var(--radius);
  background: var(--panel-alt);
  color: var(--muted);
  cursor: pointer;
  overflow: hidden;
  text-align: center;
}

.fin-wishlist-dropzone:hover {
  border-color: var(--brass);
  color: var(--brass);
}

/* The preview span is the label's only direct child — display:contents lifts
   its contents (upload icon + hint, or an <img> once a file is chosen) up to
   be direct flex items of the label itself. */
#finWishlistImagePreview,
#finPayeeLogoPreview,
#articleAdminIconPreview,
#articleFormIconPreview,
#artCatIconPreview,
#brandLogoPreview,
#profileAvatarPreview,
#rfImagePreview {
  display: contents;
}

.fin-wishlist-dropzone svg {
  width: var(--icon-xl);
  height: var(--icon-xl);
}

.fin-wishlist-dropzone-hint {
  font-size: var(--fs-m);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.fin-wishlist-dropzone img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

/* Icon/logo dropzones (article + subcategory + brand) hold a small glyph on a
   transparent background, not a scenic photo — fit the whole thing instead of
   cropping it to fill the box like the Wunschliste/Empfänger/Rezept photos do. */
#articleAdminIconPreview img,
#articleFormIconPreview img,
#artCatIconPreview img,
#brandLogoPreview img {
  object-fit: contain;
  padding: var(--space-8);
}

/* The profile avatar preview shows the whole picture, never a zoomed-in crop —
   contain, not the `cover` the scenic photo dropzones use. */
#profileAvatarPreview img {
  object-fit: contain;
}

/* The <input type="file"> that sits behind a .fin-wishlist-dropzone <label> —
   kept in the DOM (so the `for=` opens the picker + it stays focusable) but
   visually gone. `pointer-events:none` stops the 1×1 box from swallowing clicks
   meant for elements near it. Shared by the recipe form + the article-form
   modal (class name is historical: `rf-` = the recipe form it started in). */
.field input.rf-image-file-input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* ---------- Progress / affordability bar (Übersicht Sparziel-Zeile, Wunschliste card) ---------- */
.fin-btbl-goal-bar-wrap {
  grid-area: bar;
  height: var(--space-6);
  border-radius: var(--radius-pill);
  background: var(--line-strong);
  overflow: hidden;
}

.fin-btbl-goal-bar {
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--tag-color, var(--brass));
}

/* ---------- Phone (<=720px) tweaks for the shared bits above ---------- */
@media (max-width: 720px) {
  /* Zielbetrag/Zieldatum etc. get too cramped side by side — stack them. */
  .fin-field-row-stretch {
    flex-direction: column;
  }

  .fin-list-row {
    /* icon at the top of the (multi-line on phones) row content, not centred
       against it */
    align-items: flex-start;
    gap: var(--space-8);
    padding: var(--space-8) var(--space-4);
  }

  .fin-list-row-icon {
    width: var(--fin-list-avatar-mobile);
    height: var(--fin-list-avatar-mobile);
  }

  .fin-list-row-icon svg,
  .fin-list-row-icon .masked-icon {
    width: var(--icon-md);
    height: var(--icon-md);
  }

  /* Bucket rows are the only .fin-list-row with a second inline element (the
     Bucket/Sparziel type tag) fighting the name for space — stack them. */
  .fin-list-row-title {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
  }
}

/* ---------- Article-product card ----------
   One card per product variant of an article. Used by the Einstellungen article
   editor (renderArticleAdminProductList) AND the quick "create article" modal
   (js/components/article-form-modal.js, reachable from pantry + shopping), so
   it lives here rather than in a page file. */
:root {
  --fin-product-qty-w: 84px;   /* the Anzahl field, sharing a line with EAN + Einheit */
}

.fin-product-editor {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}

.fin-product-editor:empty {
  display: none;
}

.fin-product-editor + .btn-text-action {
  margin-top: var(--space-8);
}

/* One card: wrapping labelled field lines + an optional warning line. */
.fin-product-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding: var(--space-10) var(--space-12);
  border: var(--bw) solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-alt);
}

.fin-product-card-line {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-8) var(--space-12);
}

/* Each control sits in a labelled column (`.fin-product-field-wrap`, a <label>
   with the control then its caption *below* — the app's `.field` convention).
   The column is the flex item; `.is-narrow` = the Anzahl / Einheit fields. Rows
   top-align so the checkboxes / remove button line up with the inputs rather
   than the captions. */
.fin-product-card-line .fin-product-field-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  flex: 1 1 var(--space-48);
  min-width: 0;
}

.fin-product-card-line .fin-product-field-wrap.is-narrow {
  flex: 0 1 var(--fin-product-qty-w);
}

.fin-product-field-wrap .fin-product-field,
.fin-product-field-wrap .fin-product-trigger {
  width: 100%;
}

/* Remove-× sits next to the (labelled) name field — align it to the input row. */
.fin-product-card-line > .icon-btn-bare {
  margin-top: var(--space-4);
}

.fin-product-field-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.fin-product-check,
.fin-product-default {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  flex: 0 0 auto;
  /* nudge down so the checkbox lines up with the trigger's text, not its top
     edge (the row top-aligns for the labelled field columns). */
  margin-top: var(--space-6);
  font-size: var(--fs-s);
  color: var(--muted);
  white-space: nowrap;
}

.fin-product-default {
  margin-left: auto;
}

/* Country flag icon of the chosen brand — read-only, sits after the Marke
   trigger. Icon sizing comes from the shared `.fin-flag svg` rule. */
.fin-product-flag {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
}

.fin-product-warning {
  display: flex;
  align-items: flex-start;
  gap: var(--space-6);
  font-size: var(--fs-s);
  color: var(--coral);
}

.fin-product-warning svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
  flex: 0 0 auto;
  margin-top: var(--space-2);
}

/* Siegel — picked-chip + "+ Siegel" picker on a product card, same pattern as
   the recipe form's Tags picker (.rf-tags in css/pages/recipes.css) but kept
   local since finance-shared.css is the file this page (and article-form-modal's
   product card) actually loads. */
.fin-product-seals-field .fin-seal-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
}

.fin-product-seals-field .fin-seal-chips:not(:empty) {
  margin-bottom: var(--space-6);
}

.fin-seal-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-4) var(--space-2) var(--space-8);
  border-radius: var(--radius-pill);
  background: var(--panel);
  border: var(--bw) solid var(--line-strong);
  font-size: var(--fs-s);
}

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

/* An uploaded seal logo (instead of the generic fallback glyph) — same slot, contained not cropped. */
.fin-seal-chip > img {
  width: var(--icon-sm);
  height: var(--icon-sm);
  object-fit: contain;
  flex: 0 0 auto;
}

.fin-seal-chip-x {
  width: var(--hit);
  height: var(--hit);
}

.fin-seal-chip-x svg {
  width: var(--icon-xs);
  height: var(--icon-xs);
  color: var(--muted);
}

/* Country flag icon — brand list rows + the brand popover trigger + product
   rows. Its `<svg>` is a full flag (js/icons.js flagEU/CH/GB/NO/US/CA). */
.fin-flag {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}

.fin-flag svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
}
