:root {
  --bg: #0f0f10;
  --surface: #1a1a1c;
  --surface-2: #232326;
  --border: #2c2c30;
  --fg: #f5f5f5;
  --fg-soft: #d4d4d8;
  --muted: #8a8a90;
  --accent: #e2c054;
  --accent-2: #b8932a;
  --accent-title-mid: #f5e2a4;
  --error: #e07a5f;
  --ok: #7dc8a4;
  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 1px 0 rgba(255,255,255,0.03) inset, 0 8px 24px rgba(0,0,0,0.25);
  --header-bg: rgba(15,15,16,0.85);
  --hover-bg: #2a2a2d;
  --row-hover: rgba(255,255,255,0.02);
  --row-hover-strong: rgba(255,255,255,0.03);
  --bg-glow-1: rgba(226,192,84,0.06);
  --bg-glow-2: rgba(184,147,42,0.05);
  --history-border-top: rgba(0,0,0,0.4);
  /* Active-button gradient — dark mode uses the already-bright accent. */
  --btn-active-top: var(--accent);
  --btn-active-bottom: var(--accent-2);
}
[data-theme="light"] {
  --bg: #f7f6f2;
  --surface: #ffffff;
  --surface-2: #f0eee7;
  --border: #e3e0d6;
  --fg: #1a1a1c;
  --fg-soft: #3a3a3e;
  --muted: #6b6b70;
  /* Title gradient + dealer links use the Brass palette. */
  --accent: #b58915;
  --accent-2: #8a6510;
  --accent-title-mid: #e0a833;
  --bg-glow-1: rgba(181,137,21,0.06);
  --bg-glow-2: rgba(138,101,16,0.04);
  --error: #b04428;
  --ok: #3a8a5c;
  --shadow: 0 1px 2px rgba(0,0,0,0.04), 0 6px 18px rgba(0,0,0,0.06);
  --header-bg: rgba(247,246,242,0.85);
  --hover-bg: #ebe8de;
  --row-hover: rgba(0,0,0,0.025);
  --row-hover-strong: rgba(0,0,0,0.04);
  --history-border-top: rgba(0,0,0,0.08);
  /* Active-button highlight uses the brighter Honey gradient so it pops
     against white without going as dark as the Brass title tones. */
  --btn-active-top: #e8b94a;
  --btn-active-bottom: #c8941f;
}
* { box-sizing: border-box; }
html, body { height: 100%; }
html { overflow-x: hidden; }
body {
  margin: 0; padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", Roboto, sans-serif;
  font-size: 16px; line-height: 1.45;
  color: var(--fg);
  background:
    radial-gradient(1100px 600px at 80% -10%, var(--bg-glow-1), transparent 60%),
    radial-gradient(900px 500px at -10% 0%, var(--bg-glow-2), transparent 60%),
    var(--bg);
  background-attachment: fixed;
  padding-bottom: env(safe-area-inset-bottom);
  padding-top: env(safe-area-inset-top);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background-color 200ms ease, color 200ms ease;
}

header {
  display: flex; align-items: center;
  gap: 0.5rem;
  /* 1rem horizontal padding matches the cards' margin so the menu
     button lines up exactly with the card edge at every viewport size. */
  padding: 1rem;
  border-bottom: 1px solid var(--border);
  background: var(--header-bg);
  backdrop-filter: saturate(140%) blur(8px);
  -webkit-backdrop-filter: saturate(140%) blur(8px);
  position: sticky; top: 0; z-index: 10;
}
header h1 {
  margin: 0;
  font-size: 1.3rem; font-weight: 700; letter-spacing: -0.01em;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-title-mid) 50%, var(--accent-2) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* Hamburger menu — slide-in drawer from the left, with a backdrop overlay. */
.menu-wrapper { flex: 0 0 auto; }
.menu-dropdown {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: min(260px, 80vw);
  background: var(--surface);
  border-right: 1px solid var(--border);
  box-shadow: 4px 0 20px rgba(0, 0, 0, 0.35);
  padding: 1.25rem 0.85rem;
  z-index: 200;
  display: flex; flex-direction: column;
  gap: 0.35rem;
  transform: translateX(-100%);
  transition: transform 0.22s ease;
  pointer-events: none;
}
.menu-dropdown.is-open {
  transform: translateX(0);
  pointer-events: auto;
}
.menu-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 150;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease;
}
.menu-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}
.menu-item {
  display: block; width: 100%;
  background: transparent; border: none;
  padding: 0.65rem 0.85rem;
  color: var(--fg-soft);
  font: inherit; font-size: 0.95rem;
  text-align: left; cursor: pointer;
  border-radius: 8px;
  transition: background 100ms ease, color 100ms ease;
}
.menu-item:hover { background: var(--hover-bg); color: var(--fg); }
.menu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.menu-item[hidden], .menu-account-info[hidden], .menu-divider[hidden] { display: none; }

/* Title is a click-link to the Prices view. */
#header-title-link { cursor: pointer; }
#menu-btn { font-size: 1.25rem; }
.icon-btn {
  background: transparent; border: 1px solid transparent;
  color: var(--fg-soft); width: 46px; height: 46px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; font-size: 1.45rem; cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.icon-btn:hover { background: var(--surface-2); color: var(--fg); border-color: var(--border); }
.icon-btn:active { transform: scale(0.96); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

main { max-width: 720px; margin: 0 auto; }

/* Header layout — title on the left, tabs immediately after the title,
   settings on the far right. Tabs read as navigation, not primary CTAs. */
.header-title {
  display: flex; align-items: center; gap: 2rem;
  min-width: 0;  /* let the h1 truncate if narrow */
  flex: 1;
}
.tab-strip {
  display: flex; gap: 1.1rem;
  transform: translateY(2px);
}
/* The `hidden` HTML attribute sets `display: none` at attribute specificity,
   which the `.tab-strip { display: flex }` rule above out-ranks. Restore
   the override so showReportsView() can actually hide the tab strip. */
.tab-strip[hidden] { display: none; }
.tab-strip button {
  background: none; border: none;
  padding: 0.15rem 0; margin: 0;
  font: inherit; font-size: 0.78rem; font-weight: 600;
  color: var(--muted); cursor: pointer;
  border-bottom: 2px solid transparent;
  text-transform: uppercase; letter-spacing: 0.08em;
  transition: color 120ms ease, border-color 120ms ease;
}
.tab-strip button:hover { color: var(--fg-soft); }
.tab-strip button.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
@media (max-width: 480px) {
  /* Tighten title on narrow phones so the tabs still fit on one line.
     1rem horizontal padding matches the card margin so the hamburger's
     left edge lines up exactly with the cards. Title and tabs spread
     to opposite ends so tabs hug the right edge. */
  header { padding: 0.7rem 1rem; gap: 0.35rem; }
  header h1 { font-size: 1.05rem; }
  .header-title { gap: 0.5rem; justify-content: space-between; }
  .tab-strip { gap: 0.75rem; }
  .tab-strip button { font-size: 0.7rem; }
  .icon-btn { width: 38px; height: 38px; font-size: 1.1rem; }
  #menu-btn { font-size: 1.1rem; }
}
.card {
  margin: 1rem; padding: 1.1rem 1.1rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  position: relative;
}
.card h2 {
  margin: 0 0 0.65rem 0;
  font-size: 0.72rem; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em;
}
.card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 0.75rem;
}
.card-head h2 { margin: 0 0 0.65rem 0; }

.buttons { display: flex; gap: 0.5rem; }
.buttons button {
  flex: 1; padding: 0.7rem 0.75rem;
  background: var(--surface-2); color: var(--fg-soft);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 0.95rem; font-weight: 500; cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.buttons button:hover { background: var(--hover-bg); color: var(--fg); }
.buttons button:active { transform: scale(0.98); }
.buttons button.active {
  background: linear-gradient(180deg, var(--btn-active-top) 0%, var(--btn-active-bottom) 100%);
  color: #1a1300; border-color: var(--btn-active-bottom);
  box-shadow: 0 1px 0 rgba(255,255,255,0.18) inset, 0 6px 16px rgba(184,147,42,0.18);
}

.results-head {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 0.5rem;
  min-height: 32px;
  margin-bottom: 0.15rem;
}
.results-head .icon-btn { width: 34px; height: 34px; font-size: 1.15rem; }
#status, #coins-status {
  color: var(--muted);
  font-size: 0.7rem;
  text-align: right;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.muted-tiny { font-size: 0.7rem; }
#refresh {
  flex: 0 0 auto;
}
#refresh[hidden] { display: none; }

/* Table is pulled out into the card's horizontal padding so row hover and
   expanded-row highlights extend to the card's outer edges. The first/last
   cell pad back inward by the same amount so text stays at the same
   on-screen position. */
table {
  width: calc(100% + 2.2rem);
  margin-left: -1.1rem;
  margin-right: -1.1rem;
  border-collapse: separate; border-spacing: 0;
  margin-top: 0;
  font-variant-numeric: tabular-nums;
}
#results.card { padding-top: 0.55rem; }
th, td { padding: 0.55rem 0.3rem; text-align: left; border-bottom: 1px solid var(--border); font-size: 0.88rem; }
th:first-child, td:first-child { padding-left: 1.1rem; }
th:last-child, td:last-child { padding-right: 1.1rem; text-align: right; }
th { color: var(--muted); font-weight: 500; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; }
/* Shared sortable-column treatment. All tables with class="sortable" on
   their <th> get the same ▲/▼ indicator pattern. The active column gets a
   filled triangle in --accent; inactive columns show no indicator. JS
   toggles `sort-active` + `sort-asc` / `sort-desc` on the <th>. */
th.sortable { cursor: pointer; user-select: none; transition: color 120ms ease; }
th.sortable:hover { color: var(--fg-soft); }
th.sortable.sort-active { color: var(--accent); }
th.sortable .sort-indicator::after {
  content: ""; margin-left: 0.3em; opacity: 0.5; font-size: 0.85em;
}
th.sortable.sort-active .sort-indicator::after { opacity: 1; }
th.sortable.sort-asc  .sort-indicator::after { content: " ▲"; }
th.sortable.sort-desc .sort-indicator::after { content: " ▼"; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr { transition: background 120ms ease; }
tbody tr:hover { background: var(--row-hover); }
tr.error td { color: var(--error); }
tr.unavailable td { color: var(--muted); }
tr.out_of_stock td { color: var(--muted); }
.brand-cell { color: var(--fg-soft); }
.loading-msg {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.5rem;
  color: var(--muted);
  padding: 1.4rem 0 1rem;
  font-size: 0.95rem;
}
.loading-msg[hidden] { display: none; }
.spinner {
  display: inline-flex; gap: 0.4rem;
}
.spinner span {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-2) 100%);
  box-shadow: 0 0 10px rgba(226,192,84,0.45);
  animation: spinner-bounce 1.1s ease-in-out infinite both;
}
.spinner span:nth-child(2) { animation-delay: 0.16s; }
.spinner span:nth-child(3) { animation-delay: 0.32s; }
@keyframes spinner-bounce {
  0%, 80%, 100% { transform: scale(0.5); opacity: 0.35; }
  40%           { transform: scale(1.0); opacity: 1; }
}
.loading-text { font-size: 0.85rem; letter-spacing: 0.02em; }
.dealer-link {
  color: var(--accent);
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px dotted rgba(226,192,84,0.35);
  transition: color 120ms ease, border-color 120ms ease;
}
.dealer-link:hover { color: #f5e2a4; border-bottom-color: var(--accent); }
.visit-arrow {
  display: inline-block;
  margin-left: 0.25rem;
  font-size: 0.9em;
  opacity: 0.8;
  vertical-align: middle;
  position: relative;
  top: -0.05em;
}

dialog {
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: var(--shadow);
  width: min(90vw, 360px);
  max-width: 360px;
  position: relative;
}
dialog form { position: relative; }
.dialog-close {
  position: absolute;
  top: -0.5rem; right: -0.5rem;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none;
  color: var(--muted, var(--fg-soft));
  font-size: 1.4rem; line-height: 1;
  cursor: pointer; padding: 0; margin: 0;
  border-radius: 999px;
  transition: color 120ms ease, background 120ms ease;
}
.dialog-close:hover { color: var(--accent); background: var(--surface-2); }
.dialog-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 480px) {
  dialog { padding: 1.1rem 1rem; width: min(82vw, 300px); }
  dialog h2 { font-size: 0.95rem; }
  dialog input { padding: 0.5rem 0.6rem; font-size: 0.95rem; }
  dialog menu button { padding: 0.5rem 0.85rem; }
}
dialog::backdrop { background: rgba(0,0,0,0.65); backdrop-filter: blur(2px); }
dialog h2 { margin: 0 0 0.75rem 0; font-size: 1rem; }
dialog label { display: block; margin: 0.75rem 0; font-size: 0.85rem; color: var(--fg-soft); }
dialog input {
  width: 100%; padding: 0.6rem 0.7rem; margin-top: 0.35rem;
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font: inherit;
}
dialog input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(226,192,84,0.18); }
.settings-field {
  margin: 0.75rem 0 0; padding: 0.65rem 0.8rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg);
}
.settings-field:first-of-type { margin-top: 0; }
.settings-field legend {
  padding: 0 0.35rem; font-size: 0.78rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.settings-field input[type="password"],
.settings-field input[type="text"] {
  /* No top margin — legend already provides the label/input gap. */
  margin-top: 0.1rem;
}
.theme-option {
  display: inline-flex; align-items: center; gap: 0.4rem;
  margin: 0.35rem 1rem 0.1rem 0;
  font-size: 0.9rem; color: var(--fg-soft); cursor: pointer;
}
.theme-option input[type="radio"] {
  accent-color: var(--accent);
  margin: 0; width: auto;
}
dialog menu {
  display: flex; gap: 0.5rem; justify-content: flex-end;
  margin: 1rem 0 0; padding: 0;
}
dialog menu button {
  padding: 0.55rem 0.95rem;
  background: var(--surface-2); color: var(--fg-soft);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font: inherit; cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
dialog menu button:hover { background: var(--hover-bg); color: var(--fg); }
dialog menu button:disabled {
  opacity: 0.55;
  cursor: wait;
  filter: none;
}
dialog menu button[value="save"] {
  background: linear-gradient(180deg, var(--btn-active-top) 0%, var(--btn-active-bottom) 100%);
  color: #1a1300; border-color: var(--btn-active-bottom); font-weight: 600;
}
dialog menu button[value="save"]:hover { filter: brightness(1.05); }
dialog menu button[value="save"]:disabled:hover { filter: none; }

.spot-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 0.35rem 0;
  font-size: 0.95rem;
}
.spot-row + .spot-row { border-top: 1px solid var(--border); }
.spot-row span:first-child { color: var(--muted); font-size: 0.85rem; }
.spot-value {
  font-variant-numeric: tabular-nums;
}
@keyframes spotFlash {
  0%   { color: inherit; text-shadow: none; }
  10%  { color: var(--accent); text-shadow: 0 0 16px rgba(226,192,84,0.65); }
  70%  { color: var(--accent); text-shadow: 0 0 12px rgba(226,192,84,0.4); }
  100% { color: inherit; text-shadow: none; }
}
.spot-value.flash {
  animation: spotFlash 2.8s ease;
}

.muted-tiny { color: var(--muted); margin-top: 0.6rem; }

/* Inline history panel ———————————————————————————————————————————————— */
tr.row-clickable { cursor: pointer; }
tr.row-clickable:hover { background: var(--row-hover-strong); }
tr.row-expanded { background: rgba(226,192,84,0.05); }
tr.row-expanded td { border-bottom-color: transparent; }

tr.history-row > td {
  padding: 0;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.history-panel {
  /* Recessed look: sits on a darker background than the card around it,
     so it reads as a secondary detail panel. Horizontal padding kept
     small so charts fill nearly the full card width. */
  background: var(--bg);
  border-top: 1px solid var(--history-border-top);
  box-shadow: 0 1px 0 rgba(255,255,255,0.02) inset;
  padding: 0.85rem 0.6rem 0.95rem;
}
.history-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; margin-bottom: 0.6rem;
  flex-wrap: wrap;
}
.history-panel-head h3 {
  margin: 0; font-size: 0.85rem; font-weight: 600; color: var(--fg);
  letter-spacing: 0;
}
.range-toggle {
  display: flex; gap: 0.3rem;
}
.range-toggle button {
  padding: 0.3rem 0.65rem;
  background: var(--surface-2); color: var(--fg-soft);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 0.78rem; font-weight: 500; cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.range-toggle button:hover { background: var(--hover-bg); color: var(--fg); }
.range-toggle button.active {
  background: linear-gradient(180deg, var(--btn-active-top) 0%, var(--btn-active-bottom) 100%);
  color: #1a1300; border-color: var(--btn-active-bottom);
}

.charts-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-top: 0.5rem;
}
/* min-width: 0 is critical: grid items default to min-width: auto, which
   makes them refuse to shrink below their content's intrinsic size. The
   Chart.js canvas inflates to its declared dimensions, which pushes each
   cell past its 1fr track and breaks the grid into a single column. */
.chart-block { min-width: 0; }
.chart-block h4 {
  margin: 0 0 0.3rem; font-size: 0.65rem; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em;
}
.chart-container { position: relative; height: 240px; width: 100%; min-width: 0; }

.history-status:not([hidden]) {
  grid-column: 1 / -1;
  display: flex; justify-content: center; padding: 1rem 0;
  color: var(--muted); font-size: 0.85rem;
}

.buy-context {
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
  text-align: left;
}
.buy-context:empty { display: none; }
.buy-context h4 {
  margin: 0 0 0.6rem;
  font-size: 0.95rem;
  display: flex; align-items: center; gap: 0.6rem;
}
.bc-stats {
  display: flex; gap: 1.5rem; flex-wrap: wrap;
  margin-bottom: 0.55rem;
}
.bc-stat { display: flex; flex-direction: column; gap: 0.1rem; }
.bc-label {
  font-size: 0.7rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.bc-value { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.bc-ago { font-size: 0.75rem; color: var(--muted); font-weight: normal; }
.bc-verdict { margin: 0; font-size: 0.9rem; color: var(--muted); }
.bc-verdict strong { color: var(--fg); }
.bc-muted { color: var(--muted); font-size: 0.85rem; }
.bc-new-low {
  display: inline-block;
  padding: 0.1rem 0.55rem;
  background: linear-gradient(135deg, #e2c054, #e8b94a);
  color: #1a1a1a;
  border-radius: 12px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Phone — stack the two charts vertically. 600px breakpoint catches all
   phones in portrait and most in landscape. Each chart can stay shorter on
   mobile since vertical space is at a premium and the whole panel scrolls. */
@media (max-width: 600px) {
  .charts-grid { grid-template-columns: 1fr; gap: 0.6rem; }
  .chart-container { height: 180px; }
  .history-panel-head h3 { font-size: 0.8rem; }
  /* Coins table: 5 columns is too wide on phones — every cell wraps to
     two lines. Hide the "g (fine)" column; the size is already implied
     by the size_label in the Coin column. */
  #coin-listings th:nth-child(3),
  #coin-listings td:nth-child(3) { display: none; }
}

.archive-list { display: flex; flex-direction: column; gap: 0.35rem; }
.archive-item {
  display: flex; justify-content: space-between; align-items: center;
  padding: 0.55rem 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.archive-item:hover { border-color: var(--accent); }
.archive-label { font-size: 0.95rem; }
.archive-download { margin: 0; }
#reports-gen-status { margin-top: 0.4rem; }

.archive-filters {
  display: flex; gap: 0.75rem; flex-wrap: wrap;
  margin: 0.5rem 0 1rem;
}
/* Plain divs instead of <label> on purpose — a wrapping <label> would
   forward any click inside (including on dropdown options) to its
   contained button, re-opening the dropdown right after we close it. */
.archive-filter {
  display: flex; flex-direction: column; gap: 0.2rem;
}
.archive-filter-label {
  font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--muted, #8a8a8a);
}

/* Custom dropdown — replaces native <select> so the popup matches the rest
   of the UI (rounded, honey-accent hover) instead of OS-blue rectangles. */
.dd { position: relative; display: inline-block; min-width: 7rem; }
.dd-trigger {
  appearance: none; -webkit-appearance: none;
  background: var(--surface-2, var(--surface));
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 0.35rem 1.7rem 0.35rem 0.65rem;
  font-size: 0.85rem; font-weight: 500;
  cursor: pointer;
  width: 100%;
  text-align: left;
  position: relative;
  transition: border-color 120ms ease, background 120ms ease;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 14px) center, calc(100% - 10px) center;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
}
.dd-trigger:hover, .dd.is-open .dd-trigger { border-color: var(--accent); }
.dd-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.dd-list {
  position: absolute;
  top: calc(100% + 4px); left: 0;
  min-width: 100%;
  background: var(--surface-2, var(--surface));
  border: 1px solid var(--border);
  border-radius: 7px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  list-style: none; padding: 0.25rem; margin: 0;
  z-index: 50;
  max-height: 14rem; overflow-y: auto;
}
.dd-list[hidden] { display: none; }
.dd-list li {
  padding: 0.35rem 0.65rem;
  border-radius: 5px;
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--fg);
  transition: background 80ms ease;
}
/* Subtle yellow tint on hover and current selection — much lighter than the
   solid bar-size button gradient so the dropdown feels softer, and shifted
   toward true yellow (rather than honey/beige) for more visual punch. */
.dd-list li:hover { background: rgba(255, 224, 32, 0.20); }
.dd-list li.selected { background: rgba(255, 224, 32, 0.32); }
.dd-list li.selected:hover { background: rgba(255, 224, 32, 0.40); }

/* When an archive section is a <details>, the <summary> must sit on one
   line. The <h2> inside gets normalized so the disclosure triangle stays
   aligned with the heading text. */
#reports-weekly > summary,
#reports-monthly > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 0.55rem;
}
#reports-weekly > summary::-webkit-details-marker,
#reports-monthly > summary::-webkit-details-marker { display: none; }
#reports-weekly > summary > h2,
#reports-monthly > summary > h2 {
  display: inline; font-size: 1.1rem; margin: 0; line-height: 1;
}
#reports-weekly > summary::before,
#reports-monthly > summary::before {
  content: "\25B6"; display: inline-block;
  font-size: 0.7em; color: var(--muted);
  transition: transform 0.15s;
  /* Optical centering: the unicode triangle's bounding box puts the glyph
     near the baseline. Nudge it up so it lines up with h2 text middle. */
  position: relative; top: -1px;
}
#reports-weekly[open] > summary::before,
#reports-monthly[open] > summary::before { transform: rotate(90deg); }

/* Auth + portfolio —————————————————————————————————————————————————————— */

.menu-divider {
  border: none;
  border-top: 1px solid var(--border);
  margin: 0.4rem 0;
}
.menu-account-info {
  padding: 0.4rem 0.75rem;
  font-size: 0.78rem;
  color: var(--muted);
  word-break: break-all;
}

/* Canonical action-button style — see CLAUDE.md "Buttons" convention.
   All standalone action buttons (outside .buttons containers and outside
   dialog <menu> blocks, which have their own neutral styling) should use
   this class. Don't introduce primary/secondary gold variants. */
.site-btn {
  padding: 0.5rem 0.9rem;
  background: var(--surface-2);
  color: var(--fg-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit; font-size: 0.9rem; font-weight: 500;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.site-btn:hover { background: var(--hover-bg); color: var(--fg); }
.site-btn:disabled { opacity: 0.55; cursor: wait; }

/* Affirmative variant — gold gradient. Use for Save/Add/Submit standalone
   buttons. Dialog menu buttons get this automatically via value="save". */
.site-btn-primary {
  padding: 0.45rem 0.85rem;
  background: linear-gradient(180deg, var(--btn-active-top) 0%, var(--btn-active-bottom) 100%);
  color: #1a1300;
  border: 1px solid var(--btn-active-bottom);
  border-radius: var(--radius-sm);
  font: inherit; font-size: 0.85rem; font-weight: 600;
  cursor: pointer;
  transition: filter 120ms ease;
}
.site-btn-primary:hover { filter: brightness(1.05); }
.site-btn-primary:disabled { opacity: 0.55; cursor: wait; }
@media (max-width: 600px) {
  .site-btn-primary { padding: 0.35rem 0.7rem; font-size: 0.78rem; }
}

.dialog-helper {
  margin: 0 0 0.7rem;
  color: var(--muted);
  font-size: 0.88rem;
}
.dialog-error {
  margin: 0.5rem 0;
  padding: 0.5rem 0.7rem;
  background: rgba(220, 70, 70, 0.12);
  border: 1px solid rgba(220, 70, 70, 0.35);
  color: var(--error, #e85a5a);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
}

/* Portfolio view */
#portfolio-view .results-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 0.6rem;
}
.portfolio-summary-grid {
  display: flex; gap: 1.5rem; flex-wrap: wrap;
  margin-bottom: 0.65rem;
}
.ps-stat { display: flex; flex-direction: column; gap: 0.1rem; }
.ps-label {
  font-size: 0.65rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.ps-value { font-size: 0.95rem; font-variant-numeric: tabular-nums; }
.pnl-pos { color: var(--success, #5ec27a); }
.pnl-neg { color: var(--error, #e85a5a); }

.metal-chip {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 10px;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: capitalize;
  letter-spacing: 0.02em;
}

/* Per-metal breakdown — two equal panels under the totals row. */
.metal-breakdown {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.85rem;
  margin-top: 0.85rem;
}
.metal-panel {
  padding: 0.75rem 0.9rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.metal-panel-head {
  margin-bottom: 0.55rem;
  display: flex; align-items: center; gap: 0.5rem;
}
.metal-panel-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.45rem 0.85rem;
}
.metal-panel.is-empty .metal-panel-stats { opacity: 0.55; }
.metal-panel-empty {
  font-size: 0.78rem; color: var(--muted); font-style: italic;
}
/* Silly UI gimmick: gold + silver tiles get a metallic border tint so each
   summary tile reads as its own colour at a glance. Slightly thicker border
   replaces the default 1px so the colour actually registers. */
.metal-panel.is-gold {
  border: 1.5px solid rgba(226, 192, 84, 0.55);
  box-shadow: 0 0 0 1px rgba(226, 192, 84, 0.08) inset;
}
.metal-panel.is-silver {
  border: 1.5px solid rgba(200, 200, 208, 0.55);
  box-shadow: 0 0 0 1px rgba(200, 200, 208, 0.08) inset;
}
[data-theme="light"] .metal-panel.is-gold {
  border-color: rgba(184, 147, 42, 0.55);
}
[data-theme="light"] .metal-panel.is-silver {
  border-color: rgba(140, 140, 148, 0.55);
}
/* Non-empty panels act as filter toggles — click to filter the table to that
   metal. Empty panels stay non-interactive (no purchases of that metal yet). */
.metal-panel[data-metal]:not(.is-empty) {
  cursor: pointer;
  transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
}
.metal-panel[data-metal]:not(.is-empty):hover {
  transform: translateY(-1px);
}
.metal-panel.is-active.is-gold {
  border-color: rgba(226, 192, 84, 0.95);
  box-shadow: 0 0 0 1px rgba(226, 192, 84, 0.25) inset, 0 0 14px rgba(226, 192, 84, 0.22);
}
.metal-panel.is-active.is-silver {
  border-color: rgba(220, 220, 228, 0.95);
  box-shadow: 0 0 0 1px rgba(220, 220, 228, 0.25) inset, 0 0 14px rgba(220, 220, 228, 0.22);
}
.metal-panel[data-metal]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (max-width: 600px) {
  .metal-breakdown { grid-template-columns: 1fr; gap: 0.55rem; }
}
.metal-gold { background: rgba(226, 192, 84, 0.18); color: #e2c054; border: 1px solid rgba(226, 192, 84, 0.3); }
.metal-silver { background: rgba(192, 192, 192, 0.18); color: #c9c9c9; border: 1px solid rgba(192, 192, 192, 0.3); }
[data-theme="light"] .metal-gold { color: #8a6512; background: rgba(184,147,42,0.14); border-color: rgba(184,147,42,0.32); }
[data-theme="light"] .metal-silver { color: #4d4d52; background: rgba(120,120,128,0.14); border-color: rgba(120,120,128,0.3); }

/* Native date-picker calendar icon is barely visible in dark theme.
   Invert it so it reads against the dark surface; in light theme leave it
   alone. */
input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(0.85);
  opacity: 0.7;
  cursor: pointer;
}
[data-theme="light"] input[type="date"]::-webkit-calendar-picker-indicator {
  filter: none;
  opacity: 0.85;
}

/* iOS Safari quirk: <input type="date"> has an intrinsic min-width based on
   the longest possible rendered value text plus default UA padding, which
   ignores the parent container width and overflows to the right on real
   iPhones (Chrome devtools mobile emulator doesn't reproduce). Stripping
   -webkit-appearance lets our box-sizing/width rules win, and a min-width
   of 0 allows the input to shrink inside the dialog's fieldset. */
#purchase-dialog input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  display: block;
}


.empty-state {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--muted);
}
.empty-state a { color: var(--accent); text-decoration: none; }
.empty-state a:hover { text-decoration: underline; }

/* Filter indicator chip — appears above the portfolio table when a metal
   filter is active. Compact + low-key so it doesn't compete with the table. */
.portfolio-filter-bar {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.3rem 0 0.5rem;
  font-size: 0.82rem;
  color: var(--muted);
}
.filter-chip-label strong { color: var(--fg-soft); text-transform: capitalize; }
.filter-chip-clear {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg-soft);
  font: inherit;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease;
}
.filter-chip-clear:hover { border-color: var(--accent); color: var(--accent); }
.filter-chip-clear:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

#portfolio-table thead th:last-child,
#portfolio-table tr.portfolio-row td:last-child { text-align: right; width: 1%; }
.row-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  justify-content: flex-end;
}
.row-edit {
  font-size: 0.9rem;
  color: var(--muted);
  background: transparent; border: none;
  padding: 0.2rem 0.35rem;
  cursor: pointer;
}
.row-edit:hover { color: var(--accent); }
.row-delete {
  font-size: 0.85rem;
  color: var(--muted);
  background: none;
  border: none;
  cursor: pointer;
}
.row-delete:hover { color: var(--error, #e85a5a); }

#purchase-form textarea {
  width: 100%;
  background: var(--surface-2);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.55rem;
  font-family: inherit;
  font-size: 0.88rem;
  resize: vertical;
}

/* Wider purchase dialog with a 2-column form grid — keeps the modal
   short enough to avoid a scroll bar on typical viewports. */
#purchase-dialog {
  max-width: min(640px, 96vw);
  width: 600px;
}
.purchase-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.55rem 0.85rem;
  margin-top: 0.5rem;
}
.purchase-grid .settings-field { margin: 0; }
.purchase-grid-wide { grid-column: 1 / -1; }
@media (max-width: 520px) {
  /* Cap the modals so they don't fill the whole phone viewport — leaves
     visible margin around the dialog and makes it feel like a popup, not
     a full-screen page. Applies to all our dialogs for visual consistency. */
  #purchase-dialog,
  #settings-dialog,
  #login-dialog,
  #confirm-dialog {
    width: auto;
    max-width: min(380px, 92vw);
    padding: 1rem 0.85rem;
  }
  .purchase-grid { grid-template-columns: 1fr; gap: 0.4rem; }
  #purchase-dialog .settings-field { padding: 0.4rem 0.6rem 0.5rem; }
  #purchase-dialog input,
  #purchase-dialog textarea { padding: 0.45rem 0.55rem; font-size: 0.9rem; }
}

/* Date column stays on one line — DD-MM-YYYY otherwise wraps on phone. */
#portfolio-table th:first-child,
#portfolio-table td:first-child { white-space: nowrap; }
/* Weight column — numbers like "253.12 g" mustn't break across lines. */
#portfolio-table tr.portfolio-row td:nth-child(3) { white-space: nowrap; }
/* Push the delete column flush right — drop the global 1.1rem right padding. */
#portfolio-table tr.portfolio-row td:last-child,
#portfolio-table thead th:last-child { padding-right: 0.3rem; }

/* Portfolio row — compact 4-col layout with click-to-expand detail panel. */
.portfolio-row { cursor: pointer; }
.portfolio-row:hover { background: var(--hover-bg); }
.portfolio-row.is-expanded { background: var(--hover-bg); }
.portfolio-detail-row > td {
  background: var(--bg);
  padding: 0.55rem 0.6rem 0.85rem;
  border-top: 1px solid var(--history-border-top);
}
.purchase-detail {
  padding: 0.2rem 0.4rem;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.85rem;
  text-align: left;
}
#portfolio-table tr.portfolio-detail-row > td { padding-right: 0.6rem; }
.pd-section {
  padding: 0.55rem 0.7rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.pd-section-head {
  margin: 0 0 0.5rem;
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.pd-section-grid {
  /* Grid with auto-fit so cells spread evenly across the section width
     on desktop (3 cells = thirds; 4 cells = quarters). `minmax(0, 1fr)`
     lets cells shrink below their content size — combined with the
     `min-width: 0` + `overflow-wrap: anywhere` below, long values like
     "+2.580 dkk (+161.26%)" wrap onto two lines on narrow viewports
     instead of overflowing the section bounds. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: 0.4rem 1.5rem;
}
.pd-section-grid .pd-cell { min-width: 0; }
/* "About" group spans the full detail panel width; the three numeric
   groups (Spec / At purchase / Now) sit below it in the 3-column grid. */
.pd-section-about { grid-column: 1 / -1; }
/* About has its own fixed 2-column layout so Notes can be a proper
   full-width row instead of a cramped third column on mobile. */
.pd-section-about .pd-section-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.pd-cell-wide { grid-column: 1 / -1; }
.pd-value-multiline {
  white-space: pre-wrap;
  word-break: break-word;
}
.pd-cell { display: flex; flex-direction: column; gap: 0.05rem; min-width: 0; }
.pd-label {
  font-size: 0.62rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.pd-value {
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

@media (max-width: 720px) {
  .purchase-detail { grid-template-columns: 1fr; gap: 0.55rem; }
}

