:root {
  --bg: #f5f5f3;
  --surface: #ffffff;
  --text: #1a1a1a;
  --muted: #6b6b6b;
  --border: #e0e0dc;
  --accent: #2f6f4f;
  --accent-hover: #245a3f;
  --danger: #b3402a;
  --warn-bg: #fff4e5;
  --warn-border: #e8b565;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
}

/* Baseline for every link in the app: match the theme's text color instead
   of the browser default blue/purple (which also differs for :visited —
   an already-clicked link would otherwise silently change color on its
   own). Kept as the low-specificity default on purpose: anything that
   wants a different look (nav links, buttons, etc.) already overrides
   this with its own class further down and keeps working unchanged. */
a, a:link, a:visited {
  color: var(--text);
}

.topnav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem 1rem;
  padding: 0.75rem 1.25rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.topnav .brand {
  font-weight: 700;
  font-size: 1.1rem;
  text-decoration: none;
  color: var(--text);
}

.topnav .nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
}

.topnav .nav-links a {
  text-decoration: none;
  color: var(--muted);
  font-weight: 500;
}

.topnav .nav-links a:hover {
  color: var(--text);
}

.nav-user {
  color: var(--text);
  font-weight: 600;
}

.nav-logout-form {
  display: contents;
}

.nav-logout {
  background: none;
  border: none;
  padding: 0;
  color: var(--muted);
  font-weight: 500;
  font-size: inherit;
  font-family: inherit;
  cursor: pointer;
  text-decoration: underline;
}

.nav-logout:hover {
  color: var(--text);
}

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-size: 1.2rem;
  line-height: 1;
  padding: 0.35rem 0.6rem;
  cursor: pointer;
}

@media (max-width: 700px) {
  .nav-toggle {
    display: block;
  }

  .topnav .nav-links {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    gap: 0;
  }

  .topnav .nav-links.open {
    display: flex;
  }

  .topnav .nav-links a {
    padding: 0.6rem 0.25rem;
    border-top: 1px solid var(--border);
  }
}

main {
  max-width: 900px;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 3rem;
}

h1 {
  margin-top: 0;
}

.scan-hero {
  text-align: center;
  padding: 3rem 1rem;
}

.scan-hero p {
  color: var(--muted);
  margin-bottom: 2rem;
}

.scan-form {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  width: 100%;
  max-width: 420px;
  min-height: 220px;
  border: 2px dashed var(--border);
  border-radius: 16px;
  padding: 2.5rem 1.5rem;
  margin-bottom: 1.5rem;
  background: var(--surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
  box-sizing: border-box;
}

.dropzone:hover {
  border-color: var(--accent);
}

.dropzone:active {
  transform: scale(0.99);
}

.dropzone.dropzone--dragover {
  border-color: var(--accent);
  border-style: solid;
  background: var(--bg);
}

.dropzone.dropzone--has-file {
  border-style: solid;
  border-color: var(--accent);
}

.dropzone-icon {
  font-size: 3rem;
  line-height: 1;
  margin-bottom: 0.5rem;
}

.dropzone.dropzone--has-file .dropzone-icon {
  display: none;
}

.dropzone-preview {
  display: none;
  max-width: 100%;
  max-height: 200px;
  border-radius: 10px;
  margin-bottom: 0.75rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.dropzone.dropzone--has-file .dropzone-preview {
  display: block;
}

.dropzone-text {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.dropzone-text strong {
  font-size: 1.05rem;
  word-break: break-word;
}

.dropzone-text span {
  color: var(--muted);
  font-size: 0.85rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.training-only-note {
  display: inline-block;
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: 6px;
  padding: 0.4rem 0.75rem;
  font-size: 0.85rem;
  color: var(--text);
}

.training-only-toggle {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  max-width: 420px;
  margin: 0 auto 1.25rem;
  padding: 0.75rem 0.9rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  text-align: left;
  font-size: 0.85rem;
  font-weight: normal;
  color: var(--muted);
  cursor: pointer;
}

.training-only-toggle input {
  margin-top: 0.15rem;
  flex-shrink: 0;
}

.file-list {
  max-width: 420px;
  margin: 0 auto 1.25rem;
  padding: 0;
  list-style: none;
  text-align: left;
  font-size: 0.85rem;
  color: var(--muted);
}

.file-list:empty {
  display: none;
}

.file-list li {
  padding: 0.25rem 0.5rem;
  border-bottom: 1px solid var(--border);
}

.file-list li:last-child {
  border-bottom: none;
}

.scan-queue-notice {
  max-width: 420px;
  margin-left: auto;
  margin-right: auto;
  text-align: left;
}

#scan-submit {
  width: 100%;
  max-width: 420px;
}

#scan-submit:disabled {
  background: var(--border);
  color: var(--muted);
  cursor: not-allowed;
}

button, .button {
  display: inline-block;
  background: var(--accent);
  color: white;
  border: none;
  padding: 0.85rem 1.75rem;
  font-size: 1.05rem;
  font-weight: 600;
  border-radius: 8px;
  cursor: pointer;
  text-decoration: none;
}

button:hover, .button:hover {
  background: var(--accent-hover);
}

button.danger {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--danger);
}

button.danger:hover {
  background: var(--danger);
  color: white;
}

button.small, .button.small {
  padding: 0.35rem 0.75rem;
  font-size: 0.85rem;
}

.row-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  white-space: nowrap;
}

.error {
  color: var(--danger);
  font-weight: 600;
}

.progress-steps {
  list-style: none;
  padding: 0;
  max-width: 380px;
  margin: 2rem auto 0;
  text-align: left;
}

.progress-steps li {
  padding: 0.6rem 0.75rem 0.6rem 2.25rem;
  border-radius: 6px;
  color: var(--muted);
  position: relative;
}

.progress-steps li::before {
  content: "○";
  position: absolute;
  left: 0.6rem;
}

.progress-steps li.active {
  color: var(--text);
  font-weight: 600;
  background: var(--surface);
}

.progress-steps li.active::before {
  content: "◐";
  color: var(--accent);
}

.progress-steps li.done {
  color: var(--accent);
}

.progress-steps li.done::before {
  content: "✓";
  color: var(--accent);
}

.queue-list {
  list-style: none;
  padding: 0;
  max-width: 480px;
  margin: 2rem auto 0;
  text-align: left;
}

.queue-item {
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 0.5rem;
  background: var(--surface);
}

.queue-item-status {
  color: var(--muted);
}

.queue-item--done .queue-item-status {
  color: var(--accent);
  font-weight: 600;
}

.queue-item--error .queue-item-status {
  color: var(--danger);
  font-weight: 600;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0 2rem;
  background: var(--surface);
}

th, td {
  text-align: left;
  padding: 0.6rem 0.75rem;
  border-bottom: 1px solid var(--border);
}

th {
  color: var(--muted);
  font-weight: 600;
  font-size: 0.9rem;
}

.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.5rem;
}

a.stat-card,
a.stat-card:link,
a.stat-card:visited {
  display: block;
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.15s ease, transform 0.1s ease;
}

a.stat-card:hover {
  border-color: var(--accent);
}

a.stat-card:active {
  transform: scale(0.99);
}

.stat-value {
  display: block;
  color: var(--text);
  font-size: 1.6rem;
  font-weight: 700;
}

.stat-label {
  color: var(--muted);
  font-size: 0.9rem;
}

.bar-chart {
  margin-bottom: 2rem;
}

.bar-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.6rem;
}

.bar-label {
  width: 160px;
  flex-shrink: 0;
  overflow-wrap: break-word;
}

.bar-track {
  flex: 1;
  background: var(--border);
  border-radius: 4px;
  height: 18px;
  overflow: hidden;
}

.bar-fill {
  background: var(--accent);
  height: 100%;
}

.bar-value {
  width: 210px;
  flex-shrink: 0;
  font-size: 0.9rem;
  color: var(--muted);
}

.saved-tag {
  display: block;
  color: var(--accent);
  font-size: 0.8rem;
}

.bar-chart-more {
  margin: -0.5rem 0 1.5rem;
}

.bar-chart-more > summary {
  cursor: pointer;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.9rem;
  padding: 0.3rem 0;
  list-style: none;
}

.bar-chart-more > summary::-webkit-details-marker {
  display: none;
}

.bar-chart-more > summary::before {
  content: "▸ ";
}

.bar-chart-more[open] > summary::before {
  content: "▾ ";
}

.bar-chart-more .bar-chart {
  margin-top: 0.75rem;
}

.search-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: flex-end;
  margin-bottom: 1.5rem;
}

.search-form label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-weight: 600;
  font-size: 0.9rem;
}

.search-form input[type="text"],
.search-form input[type="number"],
.search-form input[type="date"] {
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 1rem;
  font-weight: normal;
  min-width: 240px;
  box-sizing: border-box;
}

.review-list {
  list-style: none;
  padding: 0;
}

.review-list li {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 0.75rem;
}

.review-list a {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.35rem 1rem;
  padding: 1rem 1.25rem;
  text-decoration: none;
  color: var(--text);
}

.review-list .flags {
  color: var(--danger);
  font-size: 0.9rem;
  font-weight: 600;
}

.flags-box {
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: 8px;
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
}

.flags-box ul {
  margin: 0.5rem 0 0;
  padding-left: 1.25rem;
}

.settings-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1.25rem 1.5rem;
  margin: 1.5rem 0;
}

.settings-box p {
  margin-top: 0;
}

.settings-box .status {
  font-weight: 600;
}

.receipt-image {
  max-width: 100%;
  max-height: 400px;
  border-radius: 8px;
  border: 1px solid var(--border);
  margin-bottom: 1.5rem;
  display: block;
}

.review-form label {
  display: block;
  margin-bottom: 0.75rem;
  font-weight: 600;
}

.review-form input[type="text"],
.review-form input[type="date"],
.review-form input[type="number"] {
  display: block;
  width: 100%;
  max-width: 320px;
  padding: 0.5rem;
  margin-top: 0.25rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 1rem;
  font-weight: normal;
}

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

.item-table {
  min-width: 1020px;
}

/* Without this, the browser's table layout squeezes the product-name
   column down to fit whatever's left after the other 7 (mostly short,
   numeric) columns claim space -- clipping real product names like
   "COCA COLA 33CL 12-P" to a few characters, on ANY screen width (this
   isn't viewport-driven: `main` caps content at 900px, so a wide desktop
   window hits the exact same squeeze as a narrow one). Reserving width
   here instead makes the table wider than 900px when needed, which
   .table-scroll (the wrapping div) already handles via horizontal
   scroll -- expected/designed-for on this table already, and clearly
   better than silently clipped text. 260px (not the original 180px)
   because even that wasn't enough for longer real names (e.g. "Juice
   Äpple Ananas Koncentrat") -- the input itself still clipped the text
   at its own right edge rather than the browser squeezing the column. */
.item-table td:first-child {
  min-width: 260px;
}

.item-table input {
  width: 100%;
  padding: 0.4rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  /* >=16px stops iOS Safari auto-zooming the page on focus. */
  font-size: 1rem;
}

.item-table .line-total {
  color: var(--muted);
  white-space: nowrap;
}

.field-hint {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.2rem;
}

.category-input {
  margin-top: 0.35rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.unit-select {
  white-space: nowrap;
}

.unit-toggle {
  display: inline-flex;
  flex-wrap: nowrap;
  width: fit-content;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.unit-option {
  position: relative;
  display: block;
  margin: 0;
  padding: 0.35rem 0.6rem;
  font-weight: 600;
  font-size: 0.8rem;
  line-height: 1;
  color: var(--muted);
  background: var(--surface);
  border-right: 1px solid var(--border);
  cursor: pointer;
  user-select: none;
  transition: background 0.1s ease, color 0.1s ease;
}

.unit-option:last-child {
  border-right: none;
}

.unit-option:hover {
  background: var(--bg);
}

.unit-option input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}

.unit-option:has(input:checked) {
  background: var(--accent);
  color: white;
}

.unit-option:has(input:checked):hover {
  background: var(--accent-hover);
}

.unit-suffix {
  display: inline-block;
  margin-left: 0.3rem;
  color: var(--muted);
  font-size: 0.8rem;
  white-space: nowrap;
}

.field-disabled {
  opacity: 0.5;
  background: var(--bg);
  cursor: not-allowed;
}

.sum-check {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.85rem 1.1rem;
  margin: 1rem 0;
}

.sum-match {
  font-weight: 700;
}

.sum-match.ok {
  color: var(--accent);
}

.sum-match.mismatch {
  color: var(--danger);
}

.price-chart {
  display: block;
  width: 100%;
  max-width: 700px;
  height: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem;
}

.price-chart-label {
  fill: var(--muted);
  font-size: 10px;
}

.price-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--text);
}

.price-chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.price-chart-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

.actions {
  margin: 1.5rem 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
}

/* Generic sidebar-menu layout — used by any section with a few distinct
   sub-pages (Budget, Statistik, Träningsdata): a persistent side menu on
   wide screens, collapsing to a wrapped horizontal tab row on narrow ones
   (see the topnav's own wrap/hamburger behavior for the same idea). */
.side-layout {
  display: flex;
  align-items: flex-start;
  gap: 2rem;
}

.side-menu {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 160px;
  flex-shrink: 0;
  position: sticky;
  top: 1rem;
}

.side-menu a {
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  text-decoration: none;
  color: var(--muted);
  font-weight: 600;
}

.side-menu a:hover {
  background: var(--surface);
  color: var(--text);
}

.side-menu a.active {
  background: var(--accent);
  color: white;
}

.side-content {
  flex: 1;
  min-width: 0;
}

@media (max-width: 700px) {
  .side-layout {
    flex-direction: column;
  }

  .side-menu {
    flex-direction: row;
    flex-wrap: wrap;
    width: 100%;
    position: static;
  }
}

.cancel-link {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
}

.cancel-link:hover {
  background: var(--border);
  color: var(--text);
}

.reject-form {
  margin-top: 1rem;
}

.changelog-entry {
  padding-bottom: 1.5rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--border);
}

.changelog-entry:last-child {
  border-bottom: none;
}

.changelog-entry h2 {
  margin-bottom: 0.15rem;
}

.changelog-date {
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 0;
  margin-bottom: 0.75rem;
}

.changelog-entry ul {
  margin: 0;
  padding-left: 1.25rem;
}

.changelog-entry li {
  margin-bottom: 0.4rem;
}

/* Below this, item-table's 7 columns (min-width: 640px) get too narrow to
   read even inside .table-scroll's horizontal scroll — turn each row into
   its own stacked card instead, one field per line, label from
   data-label (set per <td> in review_edit.html). Inputs keep their same
   name attributes either way, so submission/parsing is unaffected. */
@media (max-width: 700px) {
  .item-table {
    min-width: 0;
    width: 100%;
  }

  .item-table thead {
    display: none;
  }

  .item-table tr {
    display: block;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.6rem 0.85rem;
    margin-bottom: 0.75rem;
    background: var(--surface);
  }

  .item-table td {
    display: block;
    border-bottom: none;
    padding: 0.35rem 0;
  }

  .item-table td::before {
    content: attr(data-label);
    display: block;
    color: var(--muted);
    font-size: 0.75rem;
    font-weight: 600;
    margin-bottom: 0.2rem;
  }
}

/* Below this, the bar-chart's fixed-width label/value columns (140px +
   210px) leave the track itself no room — stack each row instead. */
@media (max-width: 600px) {
  main {
    padding: 1.25rem 1rem 3rem;
  }

  .bar-row {
    flex-direction: column;
    align-items: stretch;
    gap: 0.3rem;
  }

  .bar-label,
  .bar-value {
    width: auto;
  }

  .bar-value {
    text-align: right;
  }

  .stat-value {
    font-size: 1.35rem;
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #16181a;
    --surface: #1f2224;
    --text: #eee;
    --muted: #9a9a9a;
    --border: #33373a;
    --warn-bg: #3a2f14;
    --warn-border: #8a6a1f;
  }
}
