/* ============================================================================
   HINOVEST — Tables, toolbar, filters, forms, modal, states
   ============================================================================ */

/* ============================================================================
   TRADE TOOLBAR
   ============================================================================ */
.toolbar {
    display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
    padding: var(--space-3);
    background: var(--color-surface-1);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-bottom: 0;
}
.toolbar__search {
    display: flex; align-items: center; gap: var(--space-2);
    height: 34px; padding: 0 var(--space-3); min-width: 220px;
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
    background: var(--color-surface-inset);
    color: var(--color-text-tertiary);
}
.toolbar__search input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--color-text-primary); font-size: var(--text-sm); outline: none; }
.toolbar__spacer { flex: 1; }

/* Controls that belong to one another, tighter to each other than to the next
   group. The toolbar's own gap separates the groups; this one separates the
   members inside a group. */
.toolbar__cluster { display: flex; align-items: center; gap: var(--space-1); }
/* Everything that acts on the table, as one block. Left to the toolbar's own
   wrap, the nine controls broke wherever they happened to run out of room and
   left two segments on one line and three buttons on the next. */
.toolbar__trail {
    display: flex; align-items: center; justify-content: flex-end;
    gap: var(--space-2); flex-wrap: wrap;
}
/* What a group of chips is filtering on. */
.toolbar__label {
    align-self: center;
    margin-inline-end: 2px;
    color: var(--color-text-tertiary);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    white-space: nowrap;
}
/* Positioning context for a popover that hangs off a toolbar button. */
.toolbar__anchor { position: relative; display: flex; }

/* One height for the whole bar. A 34px chip beside a 32px segment beside a
   30px small button is why a row of nine controls read as clutter — the eye
   has no baseline to run along. */
.toolbar > .chip,
.toolbar > .btn,
.toolbar__cluster > .btn,
.toolbar__anchor > .btn,
.toolbar .trade-filter-group > .chip { height: 34px; }
.toolbar .segment { height: 34px; padding: 3px; }
.toolbar .segment button { height: 100%; }
.toolbar__count { font-size: var(--text-xs); color: var(--color-text-tertiary); white-space: nowrap; }
.toolbar__count b { color: var(--color-text-primary); font-family: var(--font-mono); }

/* filter chips */
.chip {
    display: inline-flex; align-items: center; gap: 6px;
    height: 34px; padding: 0 var(--space-3);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
    background: var(--color-surface-1); color: var(--color-text-secondary);
    font-size: var(--text-xs); font-weight: var(--weight-medium); cursor: pointer;
    transition: background 110ms ease, color 110ms ease, border-color 110ms ease;
}
.chip:hover { background: var(--color-surface-2); color: var(--color-text-primary); }
.chip.is-on { background: var(--color-accent-muted); color: var(--color-accent-glow); border-color: var(--color-accent-border); }
.chip .ico { font-size: 13px; opacity: 0.8; }
.chip__x { margin-inline-start: 2px; opacity: 0.7; }

/* ============================================================================
   DATA TABLE
   ============================================================================ */
.table-wrap {
    border: 1px solid var(--color-border-subtle);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    overflow: auto;
    max-height: 62vh;
    background: var(--color-surface-inset);
}
table.dt { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--table-fs); }
table.dt thead th {
    position: sticky; top: 0; z-index: 3;
    height: 38px; padding: 0 var(--space-3);
    background: var(--color-surface-2);
    border-bottom: 1px solid var(--color-border-mid);
    color: var(--color-text-secondary);
    font-size: var(--text-xs); font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-wide); text-align: start; white-space: nowrap;
}
table.dt thead th.sortable { cursor: pointer; }
table.dt thead th.sortable:hover { color: var(--color-text-primary); }
table.dt thead th .sort-ind { opacity: 0; margin-inline-start: 4px; font-size: 10px; }
/* The indicator is an icon now, and 10px of it is unreadable. */
table.dt thead th .sort-ind .aico { width: 13px; height: 13px; vertical-align: -3px; }
table.dt thead th.is-sorted { color: var(--color-text-primary); }
table.dt thead th.is-sorted .sort-ind { opacity: 1; color: var(--color-accent-primary); }
/* The mono face belongs to the numbers, not to the word above them. A numeric
   column's header is prose — "حد ضرر", "برد / باخت" — and JetBrains Mono has no
   Persian glyphs, so every header over a number column was being assembled
   glyph by glyph out of whatever face the system offered instead. */
/* Resetting text-align alone left that in place: .num in components.css is what
   sets the face, and this rule never took it back off. */
table.dt thead th.num { text-align: end; font-family: inherit; letter-spacing: var(--tracking-wide); }
table.dt td.num { text-align: end; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

table.dt tbody td {
    height: var(--row-h);
    padding: var(--cell-py) var(--space-3);
    border-bottom: 1px solid var(--color-border-subtle);
    color: var(--color-text-primary);
    white-space: nowrap;
    vertical-align: middle;
}
table.dt tbody tr { transition: background 80ms ease; }
table.dt tbody tr:hover td { background: var(--color-surface-2); }
table.dt tbody tr.is-selected td { background: var(--color-accent-muted); }

/* sticky first + last columns. Only the checkbox + row-number columns freeze on
   horizontal scroll (see .trade-sel-* / .trade-rownum-* below). */
table.dt .sticky-start { position: sticky; inset-inline-start: 0; z-index: 2; background: var(--color-surface-inset); }
table.dt thead .sticky-start { z-index: 4; background: var(--color-surface-2); }
table.dt tbody tr:hover .sticky-start { background: var(--color-surface-2); }
table.dt .sticky-end { position: sticky; inset-inline-end: 0; z-index: 2; background: var(--color-surface-inset); border-inline-start: 1px solid var(--color-border-subtle); }
table.dt thead .sticky-end { z-index: 4; background: var(--color-surface-2); }
table.dt tbody tr:hover .sticky-end { background: var(--color-surface-2); }

.cell-pair { display: flex; align-items: center; gap: var(--space-2); }
.cell-pair .sym { font-weight: var(--weight-semibold); font-family: var(--font-mono); }
.cell-sub { color: var(--color-text-tertiary); font-size: var(--text-2xs); }
.row-actions { display: flex; gap: 4px; opacity: 0; transition: opacity 100ms ease; justify-content: flex-end; }
table.dt tbody tr:hover .row-actions,
.row-actions:focus-within { opacity: 1; }
.row-act { width: 26px; height: 26px; border: 0; border-radius: var(--radius-xs); background: transparent; color: var(--color-text-tertiary); cursor: pointer; display: grid; place-items: center; font-size: 14px; }
.row-act:hover { background: var(--color-surface-3); color: var(--color-text-primary); }
.row-act.danger:hover { color: var(--color-loss); }

/* row multi-select (Excel-style) — only the checkbox + row-number columns freeze. */
table.dt th.trade-sel-th, table.dt td.trade-sel-td { width: 38px; text-align: center; padding-inline: var(--space-2); }
table.dt .trade-sel-th, table.dt .trade-sel-td { position: sticky; inset-inline-start: 0; z-index: 3; background: var(--color-surface-inset); }
table.dt thead .trade-sel-th { z-index: 5; background: var(--color-surface-2); }
table.dt tbody tr:hover .trade-sel-td { background: var(--color-surface-2); }
/* Row-number column, frozen right after the checkbox (offset by its 38px width). */
table.dt th.trade-rownum-th, table.dt td.trade-rownum-td {
  position: sticky; inset-inline-start: 38px; z-index: 3;
  width: 46px; text-align: center;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--color-text-tertiary); background: var(--color-surface-inset);
  border-inline-end: 1px solid var(--color-border-subtle);
}
table.dt thead .trade-rownum-th { z-index: 5; background: var(--color-surface-2); color: var(--color-text-secondary); }
table.dt tbody tr:hover .trade-rownum-td { background: var(--color-surface-2); }
table.dt input.trade-sel, table.dt input.trade-sel-all { cursor: pointer; width: 15px; height: 15px; accent-color: var(--color-accent-primary); }
table.dt tbody tr.is-row-selected td { background: var(--color-accent-muted); }
table.dt tbody tr.is-row-selected:hover td { background: color-mix(in srgb, var(--color-accent-primary) 16%, transparent); }
/* Frozen columns must stay OPAQUE when a row is selected, otherwise the scrolled
   cells underneath show through the translucent accent tint (a "glassy" look). */
table.dt tbody tr.is-row-selected .trade-sel-td,
table.dt tbody tr.is-row-selected .trade-rownum-td,
table.dt tbody tr.is-row-selected .sticky-end {
  background: color-mix(in srgb, var(--color-accent-primary) 12%, var(--color-surface-inset));
}
table.dt tbody tr.is-row-selected:hover .trade-sel-td,
table.dt tbody tr.is-row-selected:hover .trade-rownum-td,
table.dt tbody tr.is-row-selected:hover .sticky-end {
  background: color-mix(in srgb, var(--color-accent-primary) 18%, var(--color-surface-inset));
}

.trade-thumb {
  width: 44px; height: 30px; flex-shrink: 0; object-fit: cover;
  border-radius: var(--radius-xs); border: 1px solid var(--color-border-mid);
  cursor: zoom-in; transition: border-color 120ms ease;
}
.trade-thumb:hover { border-color: var(--color-accent-primary); }

/* Full-screen screenshot preview */
.trade-lightbox {
  position: fixed; inset: 0; z-index: 2200;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-6);
  background: color-mix(in srgb, var(--color-void) 82%, transparent);
  backdrop-filter: blur(3px);
}
.trade-lightbox img {
  max-width: 92vw; max-height: 88vh; object-fit: contain;
  border-radius: var(--radius); border: 1px solid var(--color-border-mid);
  box-shadow: var(--shadow-float);
}
.trade-lightbox__close {
  position: absolute; top: 18px; inset-inline-end: 22px;
  width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--color-border-mid); background: var(--color-surface-2);
  color: var(--color-text-primary); font-size: 22px; line-height: 1;
}
.trade-lightbox__close:hover { background: var(--color-surface-3); }

/* ---- Strategy tag chips (trade modal Attachments section) ---------------- */
.strategy-tags { display: flex; flex-direction: column; gap: var(--space-2); }
.strategy-tags__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.strategy-tags__chips:empty { display: none; }
.strategy-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding-block: 4px; padding-inline: 10px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--color-accent-primary) 16%, var(--color-surface-2));
  border: 1px solid color-mix(in srgb, var(--color-accent-primary) 36%, transparent);
  color: var(--color-text-primary); font-size: var(--text-xs); font-weight: 600;
}
.strategy-chip__x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%; border: 0; cursor: pointer; padding: 0;
  background: color-mix(in srgb, var(--color-text-primary) 12%, transparent);
  color: var(--color-text-primary); font-size: 13px; line-height: 1;
}
.strategy-chip__x:hover { background: var(--color-loss); color: #fff; }
.strategy-tags__entry { position: relative; }

/* Strategy chips inside the trades table cell */
/* Strategy chips: lay out in a fixed 3-per-row grid that wraps to new rows. */
.trade-strats { display: grid; grid-template-columns: repeat(3, auto); gap: 4px; justify-content: start; width: max-content; }
.trade-strat-chip {
  padding: 2px 8px; border-radius: 999px; font-size: var(--text-2xs); font-weight: 600;
  background: color-mix(in srgb, var(--color-accent-primary) 14%, var(--color-surface-2));
  border: 1px solid color-mix(in srgb, var(--color-accent-primary) 30%, transparent);
  color: var(--color-text-secondary); white-space: nowrap;
}

/* ---- Attachments: table "eye" button + popover -------------------------- */
.attach-eye {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 26px; border-radius: var(--radius-xs); cursor: pointer;
  border: 1px solid var(--color-border-mid); background: var(--color-surface-2);
  color: var(--color-text-secondary); transition: border-color 120ms ease, color 120ms ease;
}
.attach-eye:hover { border-color: var(--color-accent-primary); color: var(--color-accent-primary); }

.attach-pop-overlay {
  position: fixed; inset: 0; z-index: 2150;
  display: flex; align-items: center; justify-content: center; padding: var(--space-6);
  background: color-mix(in srgb, var(--color-void) 72%, transparent); backdrop-filter: blur(2px);
}
.attach-pop {
  width: min(560px, 94vw); max-height: 86vh; display: flex; flex-direction: column;
  border-radius: var(--radius); border: 1px solid var(--color-border-mid);
  background: var(--color-surface-1); box-shadow: var(--shadow-float); overflow: hidden;
}
.attach-pop__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--color-border-subtle);
}
.attach-pop__head-actions { display: flex; align-items: center; gap: var(--space-2); }
.attach-pop__close {
  width: 30px; height: 30px; border-radius: var(--radius-xs); cursor: pointer; font-size: 20px; line-height: 1;
  border: 1px solid var(--color-border-mid); background: var(--color-surface-2); color: var(--color-text-primary);
}
.attach-pop__close:hover { background: var(--color-surface-3); }
.attach-pop__body { padding: var(--space-4); overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-3); }
.attach-pop__shots { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.attach-pop__img {
  width: 100%; max-width: 240px; height: auto; max-height: 180px; object-fit: cover;
  border-radius: var(--radius-sm); border: 1px solid var(--color-border-mid); cursor: zoom-in;
}
.attach-pop__note {
  white-space: pre-wrap; font-size: var(--text-sm); color: var(--color-text-secondary);
  background: var(--color-surface-inset); border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-sm); padding: var(--space-3);
}
.attach-pop__stale { padding: var(--space-3); border-radius: var(--radius-sm);
  border: 1px solid var(--color-warning, var(--color-border));
  background: var(--color-surface-2); font-size: var(--text-xs); line-height: 1.6; }
.attach-eye.is-stale { position: relative; color: var(--color-warning, inherit); }
.attach-tile { position: relative; display: flex; align-items: center; justify-content: center;
  min-width: 96px; min-height: 72px; border: 1px dashed var(--color-border-mid);
  border-radius: var(--radius-sm); background: var(--color-surface-2); overflow: hidden; }
.attach-tile.is-filled { border-style: solid; }
.attach-tile__empty { display: flex; flex-direction: column; align-items: center; gap: 4px;
  color: var(--color-text-secondary); font-size: var(--text-xs); padding: var(--space-2); }
.attach-tile__pick { position: absolute; inset-block-start: 4px; inset-inline-end: 4px;
  display: flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  border: 0; border-radius: var(--radius-sm); background: var(--color-surface-3);
  color: var(--color-text-primary); cursor: pointer; }
.attach-tile__pick:hover { background: var(--color-surface-1); }

/* Current-attachment image preview (trade modal) */
.attachment-preview { display: inline-flex; flex-direction: column; gap: 6px; max-width: 260px; text-decoration: none; }
.attachment-preview img {
  width: 100%; max-height: 180px; object-fit: cover;
  border-radius: var(--radius-sm); border: 1px solid var(--color-border-mid); transition: border-color 120ms ease;
}
.attachment-preview:hover img { border-color: var(--color-accent-primary); }
.attachment-preview__hint { font-size: var(--text-2xs); color: var(--color-text-tertiary); display: inline-flex; align-items: center; gap: 4px; }
.dropzone__thumb { max-height: 64px; max-width: 100%; border-radius: var(--radius-sm); object-fit: cover; }

/* ---- Activity log change chips ------------------------------------------ */
.audit-changes { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.audit-change {
  padding: 2px 8px; border-radius: 999px; font-size: var(--text-2xs); font-family: var(--font-mono);
  background: var(--color-surface-inset); border: 1px solid var(--color-border-subtle);
  color: var(--color-text-tertiary);
}
.audit-change b { color: var(--color-text-secondary); margin-inline-end: 4px; font-family: var(--font-sans, inherit); }

/* ---- Calendar view (trades) --------------------------------------------- *
 * Month grid that replaces the table body; sits under the same toolbar, so it
 * carries the toolbar's bottom radii. */
.trade-calendar {
  padding: var(--space-3);
  border: 1px solid var(--color-border-subtle);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  background: var(--color-surface-inset);
}
.trade-calendar__head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
.trade-calendar__title {
  flex: 1; font-size: var(--text-sm); font-weight: 600; color: var(--color-text-primary);
}
.cal-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--radius-xs); cursor: pointer;
  border: 1px solid var(--color-border-mid); background: var(--color-surface-2);
  color: var(--color-text-secondary);
}
.cal-nav:hover { background: var(--color-surface-3); color: var(--color-text-primary); }
.trade-calendar__dow, .trade-calendar__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--space-2); }
.trade-calendar__dow { margin-bottom: 6px; }
/* Week/month grouping: fewer, wider cells (the day grid keeps its 7 columns). */
.trade-calendar__grid.is-gran-week { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.trade-calendar__grid.is-gran-month { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.trade-calendar__dow span {
  text-align: center; font-size: var(--text-2xs); text-transform: uppercase;
  letter-spacing: var(--tracking-wide); color: var(--color-text-tertiary);
}
.cal-day {
  position: relative; display: flex; flex-direction: column; gap: 2px;
  min-height: 82px; padding: 6px; cursor: pointer;
  border: 1px solid var(--color-border-subtle); border-radius: var(--radius-sm);
  background: var(--color-surface-1);
  transition: border-color 110ms ease, background 110ms ease;
}
.cal-day:hover { border-color: var(--color-accent-primary); }
.cal-day:focus-visible { outline: 2px solid var(--color-accent-primary); outline-offset: 1px; }
.cal-day.is-blank { background: transparent; border-color: transparent; cursor: default; min-height: 0; }
.cal-day.is-today { border-color: var(--color-accent-primary); }
.cal-day.is-selected { background: var(--color-accent-muted); border-color: var(--color-accent-border); }
.cal-day__n { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-text-secondary); }
.cal-day.is-today .cal-day__n { color: var(--color-accent-glow); font-weight: 700; }
.cal-day__pnl { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600; }
.cal-day__wl { font-size: var(--text-2xs); color: var(--color-text-tertiary); }
.cal-day__add {
  position: absolute; inset-inline-end: 4px; top: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border-radius: var(--radius-xs); cursor: pointer;
  font-size: 11px; opacity: 0.35;
  border: 1px solid var(--color-border-mid); background: var(--color-surface-2);
  color: var(--color-text-secondary); transition: opacity 110ms ease, color 110ms ease;
}
.cal-day:hover .cal-day__add, .cal-day__add:hover, .cal-day__add:focus-visible { opacity: 1; color: var(--color-accent-primary); }
.cal-day.is-blank .cal-day__add { display: none; }

/* ---- Self review (trades) ----------------------------------------------- *
 * Activity/emotion bar lists. No chart library on this page — the bars are
 * plain divs sized by percentage. */
.trade-review {
  padding: var(--space-4);
  border: 1px solid var(--color-border-subtle);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  background: var(--color-surface-inset);
}
/* Standalone Self review page — no toolbar above it, so round every corner. */
.trade-review--page { border-radius: var(--radius-lg); }
.review-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--space-4); }
.review-card {
  padding: var(--space-4); border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-subtle); background: var(--color-surface-1);
}
.review-card__title { margin: 0 0 var(--space-3); font-size: var(--text-sm); font-weight: 600; color: var(--color-text-primary); }
.review-bars { display: flex; flex-direction: column; gap: 8px; }
.review-bar { display: grid; grid-template-columns: 92px 1fr auto; align-items: center; gap: var(--space-3); }
.review-bar__label { font-size: var(--text-xs); color: var(--color-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.review-bar__track { height: 10px; border-radius: 999px; background: var(--color-surface-3); overflow: hidden; }
.review-bar__fill { display: block; height: 100%; border-radius: 999px; }
.review-bar__fill.is-fill-pos { background: var(--color-profit); }
.review-bar__fill.is-fill-neg { background: var(--color-loss); }
.review-bar__meta { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--color-text-tertiary); white-space: nowrap; }
.review-foot { margin: var(--space-4) 0 0; font-size: var(--text-xs); }

/* ---- Self review: psychology scorecard ---------------------------------- */
.review-banner {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin: 0 0 var(--space-4); padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-accent-border); border-radius: var(--radius-sm);
  background: var(--color-accent-muted); color: var(--color-text-secondary); font-size: var(--text-xs);
}
.review-banner > i { color: var(--color-accent-glow); font-size: 15px; }
/* Direct child only — a descendant match also stretched the first chip. */
.review-banner > span:first-of-type { flex: 1; min-width: 200px; }
.review-banner__chips { display: inline-flex; gap: 4px; }
.review-stack { display: flex; flex-direction: column; gap: var(--space-4); }

/* Trader profile + radar */
.review-profile__head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.review-profile__lv {
  display: inline-flex; align-items: center; justify-content: center; min-width: 46px; height: 26px; padding: 0 8px;
  border-radius: 999px; font-size: var(--text-2xs); font-weight: 700; letter-spacing: var(--tracking-wide);
  background: var(--color-accent-primary); color: var(--color-void);
}
.review-profile__sub { margin: 2px 0 0; font-size: var(--text-2xs); }
.review-profile__overall { margin-inline-start: auto; text-align: center; line-height: 1.1; }
.review-profile__overall b { display: block; font-family: var(--font-mono); font-size: 18px; color: var(--color-accent-glow); }
.review-profile__overall small { font-size: var(--text-2xs); color: var(--color-text-tertiary); }
.radar { width: 100%; max-width: 320px; height: auto; margin: 0 auto; display: block; overflow: visible; }
.radar__ring, .radar__shape { fill: none; }
.radar__ring { stroke: var(--color-border-subtle); stroke-width: 1; }
.radar__spoke { stroke: var(--color-border-subtle); stroke-width: 1; }
.radar__shape { fill: var(--color-accent-muted); stroke: var(--color-accent-primary); stroke-width: 2; }
.radar__dot { fill: var(--color-accent-glow); }
.radar__label { fill: var(--color-text-secondary); font-size: 10px; font-weight: 600; }
.radar__value { fill: var(--color-accent-glow); font-family: var(--font-mono); font-size: 10px; }
.review-profile__legend {
  list-style: none; margin: var(--space-3) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 6px var(--space-3);
}
.review-profile__legend li { display: flex; align-items: baseline; gap: 6px; font-size: var(--text-2xs); color: var(--color-text-secondary); }
.review-profile__legend b { font-family: var(--font-mono); color: var(--color-text-primary); }
.review-profile__legend small { flex: 1; text-align: end; }
.review-xp { margin-top: var(--space-4); }
.review-xp__track { height: 6px; border-radius: 999px; background: var(--color-surface-3); overflow: hidden; }
.review-xp__track span { display: block; height: 100%; border-radius: 999px; background: var(--color-accent-primary); }
.review-xp__label { display: block; margin-top: 6px; font-size: var(--text-2xs); color: var(--color-text-tertiary); font-family: var(--font-mono); }

/* Month mistake pattern card */
.review-clean {
  display: flex; align-items: center; gap: var(--space-4);
  border-color: color-mix(in srgb, var(--color-profit) 40%, transparent);
  background: color-mix(in srgb, var(--color-profit) 10%, var(--color-surface-1));
}
.review-clean--warn {
  border-color: color-mix(in srgb, var(--color-loss) 40%, transparent);
  background: color-mix(in srgb, var(--color-loss) 10%, var(--color-surface-1));
}
.review-clean__icon { font-size: 34px; color: var(--color-profit); }
.review-clean--warn .review-clean__icon { color: var(--color-loss); }
.review-clean__eyebrow { display: block; font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--color-text-tertiary); }
.review-clean__title { display: block; margin: 2px 0 4px; font-size: var(--text-lg, 17px); color: var(--color-text-primary); }
.review-clean p { margin: 0; font-size: var(--text-xs); }

/* Mistake heatmap */
.review-heat {
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-subtle); background: var(--color-surface-1);
}
.review-heat > summary {
  display: flex; align-items: center; gap: var(--space-2); cursor: pointer;
  font-size: var(--text-sm); font-weight: 600; color: var(--color-text-primary);
}
.review-heat > summary .dim { margin-inline-start: auto; font-size: var(--text-2xs); font-weight: 400; }
.review-heat__scroll { overflow-x: auto; margin-top: var(--space-3); }
.review-heat__grid { border-collapse: collapse; font-size: var(--text-2xs); }
.review-heat__grid th { padding: 4px 6px; color: var(--color-text-tertiary); font-weight: 500; text-align: start; white-space: nowrap; }
.review-heat__grid td { padding: 2px; }
.review-heat__cell {
  display: flex; align-items: center; justify-content: center; min-width: 30px; height: 22px;
  border-radius: var(--radius-xs); background: var(--color-loss); color: #fff; font-family: var(--font-mono); font-weight: 600;
}

/* Day card */
.review-day__nav { display: flex; align-items: center; gap: var(--space-2); justify-content: center; }
.review-day__date { margin: var(--space-3) 0; text-align: center; display: flex; flex-direction: column; gap: 2px; }
.review-day__tag { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.review-day__strong { font-size: var(--text-lg, 17px); color: var(--color-accent-glow); }
.review-day__date .dim { font-size: var(--text-xs); }
.review-day__list { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: flex; flex-direction: column; gap: 6px; }
.review-day__list li {
  display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: var(--space-2);
  padding: 6px 8px; border-radius: var(--radius-sm); background: var(--color-surface-inset); font-size: var(--text-xs);
}
.review-day__emotion { font-size: var(--text-2xs); color: var(--color-text-tertiary); }
.review-day__empty { margin: 0 0 var(--space-3); font-size: var(--text-xs); text-align: center; }
.review-add {
  width: 100%; padding: var(--space-3); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px dashed var(--color-accent-border); border-radius: var(--radius-sm);
  background: transparent; color: var(--color-accent-glow); font-size: var(--text-xs); font-weight: 600;
}
.review-add:hover { background: var(--color-accent-muted); }

/* Emotion chip next to the attachments eye button */
.trade-emotion-chip {
  padding: 2px 8px; border-radius: 999px; font-size: var(--text-2xs); font-weight: 600; white-space: nowrap;
  background: var(--color-accent-muted); border: 1px solid var(--color-accent-border); color: var(--color-accent-glow);
}
.attach-pop__emotion { display: flex; flex-direction: column; gap: 6px; }

/* ---- Trades table full screen ------------------------------------------- *
 * Native :fullscreen when the browser grants it, with a fixed-position
 * fallback (.is-fullscreen-fallback) toggled from JS when the API is blocked. */
.trade-table-shell:fullscreen,
.trade-table-shell.is-fullscreen-fallback {
    display: flex;
    flex-direction: column;
    background: var(--color-void);
    padding: var(--space-4) var(--space-5);
    gap: var(--space-3);
}
.trade-table-shell.is-fullscreen-fallback {
    position: fixed;
    inset: 0;
    z-index: 1000;
    overflow: auto;
}
.trade-table-shell:fullscreen .table-wrap,
.trade-table-shell.is-fullscreen-fallback .table-wrap {
    flex: 1;
    min-height: 0;
    max-height: none;   /* lift the 62vh cap so the table stretches to the bottom */
    overflow: auto;
}
body.trade-table-fullscreen { overflow: hidden; }
[data-trade-fullscreen-toggle] { white-space: nowrap; }

/* ---- Quick-entry row (Excel-style inline add) --------------------------- */
.trade-inline > td {
  background: color-mix(in srgb, var(--color-accent-primary) 8%, var(--color-surface-2));
  border-bottom: 1px solid var(--color-accent-border);
}
.trade-inline__mark { color: var(--color-accent-primary); font-size: 11px; }
.trade-inline__in {
  width: 100%; min-width: 78px; height: 26px; padding: 0 6px;
  border: 1px solid var(--color-border-mid); border-radius: var(--radius-xs);
  background: var(--color-surface-inset); color: var(--color-text-primary);
  font-size: var(--text-xs); font-family: var(--font-mono); outline: none;
}
.trade-inline__in:focus { border-color: var(--color-accent-primary); }
.trade-inline__in[type="date"], .trade-inline__in[type="time"] { min-width: 108px; font-family: var(--font-sans, inherit); }
.trade-inline__in:invalid { border-color: color-mix(in srgb, var(--color-loss) 60%, transparent); }
/* Formula cells: filled by calculatePreview, never typed into. */
.trade-inline__auto { font-family: var(--font-mono); color: var(--color-accent-glow); }

/* bulk-action bar — shown while one or more trades are selected */
.trade-bulk-bar {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
    margin-bottom: var(--space-3);
    padding: var(--space-2) var(--space-4);
    border: 1px solid var(--color-accent-primary);
    border-radius: var(--radius-md, 10px);
    background: var(--color-accent-muted);
}
.trade-bulk-bar[hidden] { display: none; }
.trade-bulk-bar__count { font-size: var(--text-sm); color: var(--color-text-primary); }
.trade-bulk-bar__count b { color: var(--color-accent-primary); }
.trade-bulk-bar__actions { display: flex; gap: var(--space-2); }

/* transfers strip — deposits and withdrawals, a band between the table and
 * its footer. Borrows the footer's border treatment (no top border, no radius)
 * so the three read as one card rather than as a box wedged between two.
 *
 * Not a table row on purpose: a transfer has no direction, no size and no
 * result, so it cannot be sorted, filtered or totalled with the trades. The
 * whole strip is hidden on a journal that has never had one. */
.trade-transfers {
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border: 1px solid var(--color-border-subtle); border-top: 0;
    background: var(--color-surface-1);
    font-size: var(--text-xs);
}
.trade-transfers[hidden] { display: none; }
.trade-transfers__title { color: var(--color-text-secondary); margin-inline-end: var(--space-1); }
/* Tabular figures so a column of amounts lines up on the decimal point. */
.trade-transfers__item { font-variant-numeric: tabular-nums; }
.trade-transfers__item.is-in  b { color: var(--color-profit); }
.trade-transfers__item.is-out b { color: var(--color-loss); }
.trade-transfers__net {
    margin-inline-start: auto;
    color: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* zebra in compact only, optional */
[data-zebra="on"] table.dt tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--color-surface-1) 50%, transparent); }
[data-zebra="on"] table.dt tbody tr:nth-child(even):hover td { background: var(--color-surface-2); }

/* table footer */
.table-foot {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-border-subtle); border-top: 0;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    background: var(--color-surface-1);
    font-size: var(--text-xs); color: var(--color-text-secondary);
    /* Row counter + pager together exceed 320px; without wrapping the whole
     * trades screen picked up a horizontal scrollbar and pushed the "next page"
     * control out of the viewport. */
    flex-wrap: wrap; row-gap: var(--space-2);
}
.table-foot > div { flex-wrap: wrap; row-gap: var(--space-2); }
.rows-per-page { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--color-text-secondary); }
/* The row count is a themed dropdown like every other select on the site — a
   native one opened an OS-drawn list in the OS's own colours. It only needs to
   be shrunk to table-foot size, and to open upwards: the foot sits at the
   bottom of the page, where a menu dropping down falls off the card. */
.rows-per-page .custom-select { width: 82px; }
.rows-per-page .custom-select__trigger {
    min-height: 28px;
    padding-inline: 8px;
    gap: var(--space-2);
    border-radius: var(--radius-xs);
    font-size: var(--text-xs);
}
.rows-per-page .custom-select__trigger i { font-size: 10px; }
.rows-per-page .custom-select__menu {
    top: auto;
    bottom: calc(100% + 6px);
    font-size: var(--text-xs);
}
.pager { display: flex; align-items: center; gap: 4px; }
.pager button { width: 28px; height: 28px; border: 1px solid var(--color-border-subtle); border-radius: var(--radius-xs); background: transparent; color: var(--color-text-secondary); cursor: pointer; }
.pager button:hover { background: var(--color-surface-2); color: var(--color-text-primary); }
.pager button.is-active { background: var(--color-accent-muted); color: var(--color-accent-glow); border-color: var(--color-accent-border); }
.pager__gap { min-width: 20px; text-align: center; color: var(--color-text-tertiary); user-select: none; }

/* ============================================================================
   COLUMN CONTROL POPOVER
   ============================================================================ */
.popover {
    position: absolute; z-index: 300;
    min-width: 220px; padding: var(--space-2);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border-mid);
    border-radius: var(--radius);
    box-shadow: var(--shadow-float);
}
.popover__title { padding: var(--space-2) var(--space-2) var(--space-1); font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--color-text-tertiary); font-weight: var(--weight-semibold); }
.popover__item { display: flex; align-items: center; gap: var(--space-2); padding: 7px var(--space-2); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-sm); }
/* Column items are real <button>s now — strip the UA chrome, keep the look. */
button.popover__item { width: 100%; border: 0; background: none; font: inherit; color: inherit; text-align: start; }
.popover__item:hover { background: var(--color-surface-3); }
/* Columns popover: cap to ~5 rows and scroll the rest; keep the title pinned. */
#colPop { max-height: 232px; overflow-y: auto; overscroll-behavior: contain; }
#colPop .popover__title { position: sticky; top: 0; z-index: 1; background: var(--color-surface-2); }

/* checkbox */
.check { position: relative; width: 16px; height: 16px; flex: 0 0 16px; border: 1px solid var(--color-border-strong); border-radius: var(--radius-xs); background: var(--color-surface-inset); cursor: pointer; display: inline-grid; place-items: center; }
.check.is-on { background: var(--color-accent-primary); border-color: var(--color-accent-primary); }
.check.is-on::after { content: "✓"; color: var(--color-accent-ink); font-size: 11px; font-weight: 700; }

/* ============================================================================
   FORMS
   ============================================================================ */
.field { display: flex; flex-direction: column; gap: 6px; }
.field__label { font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--color-text-secondary); }
.field__label .req { color: var(--color-loss); margin-inline-start: 2px; }
.field__hint { font-size: var(--text-2xs); color: var(--color-text-tertiary); }
/* A label or hint that is still English on an RTL page reads as scrambled — its
   full stop and brackets jump to the front. plaintext lets each string take its
   direction from its own first strong character, so it reads either way. */
.field__label, .field__hint { unicode-bidi: plaintext; }
.input, .select, .textarea {
    height: 38px; padding: 0 var(--space-3);
    border: 1px solid var(--color-border-mid);
    border-radius: var(--radius-sm);
    background: var(--color-surface-inset);
    color: var(--color-text-primary);
    font-size: var(--text-sm); font-family: inherit; outline: none;
    transition: border-color 110ms ease, box-shadow 110ms ease;
}
/* iOS Safari zooms the whole page when a focused input renders below 16px.
 * Hold 16px on touch-sized viewports; the 13px density stays on desktop. */
@media (max-width: 900px) {
    .input, .select, .textarea,
    .form-control,
    .topbar__search input,
    .toolbar__search input,
    .tag-field input,
    .trades-search input,
    .settings-filter input { font-size: 16px; }
}
.input.mono { font-family: var(--font-mono); }
.textarea { height: auto; min-height: 76px; padding: var(--space-2) var(--space-3); resize: vertical; line-height: 1.5; }
.input:focus, .select:focus, .textarea:focus { border-color: var(--color-accent-border); box-shadow: 0 0 0 3px var(--color-accent-muted); }

/* File inputs: keep the native field on-theme and style the browser "Browse"
   button to match the app's ghost buttons (colors, radius, hover). */
.input[type="file"] { padding: 0; display: flex; align-items: center; line-height: 36px; }
.input[type="file"]::file-selector-button {
    height: 36px; margin-inline-end: var(--space-3); padding: 0 var(--space-4);
    border: 1px solid var(--color-border-mid); border-radius: var(--radius-sm);
    background: var(--color-surface-2); color: var(--color-text-primary);
    font-size: var(--text-sm); font-weight: var(--weight-semibold); font-family: inherit;
    cursor: pointer; transition: background 110ms ease, border-color 110ms ease, color 110ms ease;
}
.input[type="file"]::file-selector-button:hover {
    background: var(--color-accent-primary); color: var(--color-accent-ink);
    border-color: var(--color-accent-primary);
}

/* Native checkboxes inherit the form-control sizing (full-width, 38px tall),
   which made the auto session/day toggles render as large blue boxes. Reset to a
   compact, themed checkbox aligned with the rest of the settings UI. */
input[type="checkbox"].form-control,
.field input[type="checkbox"] {
    width: 18px; height: 18px; min-height: 18px; flex: 0 0 18px;
    padding: 0; display: inline-grid; place-items: center;
    accent-color: var(--color-accent-primary); cursor: pointer;
}
.input::placeholder { color: var(--color-text-tertiary); }
.input.is-invalid, .select.is-invalid { border-color: var(--color-loss); box-shadow: 0 0 0 3px var(--color-loss-muted); }
.field__err { display: none; font-size: var(--text-2xs); color: var(--color-loss); align-items: center; gap: 4px; }
.field.has-error .field__err { display: flex; }
.input-group { display: flex; align-items: stretch; border-radius: var(--radius-sm); transition: box-shadow 110ms ease; }
/* An input and its addon are two boxes but one control, so they take one
   ring. The input's own focus ring stops at the input's own edges: it drew
   a bright line down the seam and left the addon outside the glow, which
   reads as a ring with a bite out of it. Ring the group instead -- the same
   treatment .topbar__search gets in components.css. */
.input-group:focus-within { box-shadow: 0 0 0 3px var(--color-accent-muted); }
.input-group:focus-within .input,
.input-group:focus-within .form-control,
.input-group:focus-within .addon { border-color: var(--color-accent-border); }
.input-group .input:focus, .input-group .form-control:focus,
.input-group .addon:focus-visible { box-shadow: none; }
/* .form-control alongside .input: the password-reveal field is a Django
   PasswordChangeForm widget (class="form-control", the Bootstrap-remap base
   style in bridge.css) rather than this app's own .input class, and
   .form-control carries its own all-corners border-radius. Left unmatched
   here, that radius wins outright and the field renders as a fully rounded
   box next to the addon instead of a flat seam — no gap in the markup, but
   two independently curved corners read as one. */
/* Corners are logical (border-<block>-<inline>-radius) rather than the
   physical border-radius shorthand, so they follow whatever direction the
   group itself is in. The phone field carries its own dir="ltr" inside an
   RTL page — the +98 belongs to the left of the digits in either language —
   so the page-level html[dir="rtl"] overrides this replaces used to round
   the seam where the two boxes meet and square the outer edges instead. */
.input-group .input, .input-group .form-control {
    border-start-start-radius: var(--radius-sm); border-end-start-radius: var(--radius-sm);
    border-start-end-radius: 0; border-end-end-radius: 0;
    flex: 1; min-width: 0;
}
.input-group .addon {
    /* gap for the one addon that holds two things, the phone icon and +98;
       every other addon has a single child, where it costs nothing. */
    display: inline-flex; align-items: center; gap: 6px; padding: 0 var(--space-3);
    background: var(--color-surface-3); border: 1px solid var(--color-border-mid);
    border-start-start-radius: 0; border-end-start-radius: 0;
    border-start-end-radius: var(--radius-sm); border-end-end-radius: var(--radius-sm);
    color: var(--color-text-secondary); font-size: var(--text-xs); font-family: var(--font-mono);
}
/* One seam, not two, and not zero: only the box that comes second drops the
   border it shares. The input keeps all four of its own sides, so its focus
   ring still closes and its outer edge is never left open. */
.input-group .input + .addon, .input-group .form-control + .addon { border-inline-start: 0; }
.input-group .addon--lead {
    border-start-start-radius: var(--radius-sm); border-end-start-radius: var(--radius-sm);
    border-start-end-radius: 0; border-end-end-radius: 0;
    border-inline-end: 0;
}
.input-group .addon--lead + .input, .input-group .addon--lead + .form-control {
    border-start-start-radius: 0; border-end-start-radius: 0;
    border-start-end-radius: var(--radius-sm); border-end-end-radius: var(--radius-sm);
}
/* An addon on both sides -- the key and the reveal eye on the login password --
   leaves the input square at both ends, not just the one the lead addon covers. */
.input-group .addon--lead + .input:has(+ .addon),
.input-group .addon--lead + .form-control:has(+ .addon) {
    border-start-end-radius: 0; border-end-end-radius: 0;
}

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.form-grid .col-span-2 { grid-column: 1 / -1; }
.form-section { padding: var(--space-5) 0; border-top: 1px solid var(--color-border-subtle); }
.form-section:first-child { border-top: 0; padding-top: 0; }
.form-section__title { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); font-weight: var(--weight-semibold); margin-bottom: var(--space-4); }
.form-section__title .step { width: 22px; height: 22px; border-radius: var(--radius-xs); background: var(--color-accent-muted); color: var(--color-accent-glow); display: grid; place-items: center; font-size: var(--text-2xs); font-family: var(--font-mono); }

/* direction toggle */
.dirtoggle { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.dirtoggle button { height: 40px; border: 1px solid var(--color-border-mid); border-radius: var(--radius-sm); background: var(--color-surface-inset); color: var(--color-text-secondary); font-weight: var(--weight-semibold); font-size: var(--text-sm); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 6px; transition: background-color 110ms ease, border-color 110ms ease, color 110ms ease; }
.dirtoggle button.is-on[data-dir="long"] { background: var(--color-profit-muted); color: var(--color-profit); border-color: color-mix(in srgb, var(--color-profit) 40%, transparent); }
.dirtoggle button.is-on[data-dir="short"] { background: var(--color-loss-muted); color: var(--color-loss); border-color: color-mix(in srgb, var(--color-loss) 40%, transparent); }

/* ============================================================================
   MODAL
   ============================================================================ */
.modal-backdrop {
    position: fixed; inset: 0; z-index: 100;
    background: color-mix(in srgb, #000 56%, transparent);
    backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
    display: grid; place-items: center; padding: var(--space-6);
    opacity: 0; pointer-events: none; transition: opacity 140ms ease;
}
.modal-backdrop.is-open { opacity: 1; pointer-events: auto; }
.modal {
    width: min(720px, 100%); max-height: 88vh;
    display: flex; flex-direction: column;
    background: var(--color-surface-1);
    border: 1px solid var(--color-border-mid);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-float);
    transform: translateY(8px) scale(0.99); transition: transform 140ms cubic-bezier(0.22,1,0.36,1);
}
.modal-backdrop.is-open .modal { transform: none; }
.modal__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); padding: var(--space-5) var(--space-5) var(--space-4); border-bottom: 1px solid var(--color-border-subtle); }
.modal__head h3 { margin: 0; font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.modal__head p { margin: 4px 0 0; color: var(--color-text-secondary); font-size: var(--text-sm); }
.modal__body { padding: var(--space-5); overflow-y: auto; }
.modal__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); row-gap: var(--space-2); flex-wrap: wrap; padding: var(--space-4) var(--space-5); border-top: 1px solid var(--color-border-subtle); }
.modal__foot .right { display: flex; gap: var(--space-2); margin-inline-start: auto; }

/* live preview strip inside modal */
.preview-strip { display: flex; gap: var(--space-5); flex-wrap: wrap; padding: var(--space-4); background: var(--color-surface-inset); border: 1px solid var(--color-border-subtle); border-radius: var(--radius); margin-top: var(--space-4); }
.preview-strip .pv { display: flex; flex-direction: column; gap: 2px; }
.preview-strip .pv .k { font-size: var(--text-2xs); color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.preview-strip .pv .v { font-family: var(--font-mono); font-size: var(--text-md); font-weight: var(--weight-semibold); }

/* ============================================================================
   JOURNAL HUB
   ============================================================================ */
.hub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-4); }
/* --journal-color is set per tile from Journal.journal_color; the accent falls back to
   the theme accent so a journal saved before the picker existed still looks right. */
.jtile { --journal-color: var(--color-accent-primary); position: relative; display: flex; flex-direction: column; background: var(--color-surface-1); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-lg); overflow: hidden; transition: border-color 120ms ease, box-shadow 120ms ease; cursor: pointer; }
.jtile::before {
    content: ""; position: absolute; inset-block-start: 0; inset-inline: 0; height: 3px;
    background: var(--journal-color);
}
.jtile__dot {
    display: inline-block; width: 8px; height: 8px; margin-inline-end: 8px; border-radius: 50%;
    background: var(--journal-color); vertical-align: middle;
}
/* Hover lifts via shadow only — no element in the app moves on hover. */
.jtile:hover { border-color: var(--journal-color); box-shadow: var(--shadow-raised); }
.jtile.is-selected { border-color: var(--journal-color); }
.jtile__body { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); flex: 1; }
.jtile__top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.jtile h3 { margin: 0; font-size: var(--text-md); font-weight: var(--weight-semibold); }
.jtile__desc { color: var(--color-text-secondary); font-size: var(--text-xs); line-height: 1.5; }
.jtile__chart { display: flex; flex-direction: column; gap: 6px; margin-top: auto; }
.jtile__chart[hidden] { display: none; }
.jtile__spark { width: 100%; height: 40px; display: block; }
.jtile__chart-caption { font-size: var(--text-2xs); color: var(--color-text-tertiary); }
.jtile__foot { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-4); border-top: 1px solid var(--color-border-subtle); background: var(--color-surface-0); font-size: var(--text-2xs); color: var(--color-text-tertiary); }

/* ============================================================================
   STATES — empty / skeleton / toast
   ============================================================================ */
.empty { display: grid; place-items: center; text-align: center; padding: var(--space-12) var(--space-6); gap: var(--space-3); }
.empty[hidden] { display: none; }
.empty__icon { width: 56px; height: 56px; border-radius: var(--radius-lg); background: var(--color-surface-2); display: grid; place-items: center; font-size: 24px; color: var(--color-text-tertiary); }
.empty h3 { margin: 0; font-size: var(--text-lg); }
.empty p { margin: 0; color: var(--color-text-secondary); font-size: var(--text-sm); max-width: 42ch; }

@keyframes shimmer { 100% { transform: translateX(100%); } }
.skel { position: relative; overflow: hidden; background: var(--color-surface-2); border-radius: var(--radius-xs); }
.skel::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--color-text-primary) 6%, transparent), transparent); animation: shimmer 1.3s infinite; }
@media (prefers-reduced-motion: reduce) { .skel::after { animation: none; } }

/* reports builder */
.builder { display: grid; grid-template-columns: 260px 1fr; gap: var(--space-5); }
.builder__panel { background: var(--color-surface-1); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-lg); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); align-self: start; }
.builder__group { display: flex; flex-direction: column; gap: var(--space-2); }
.builder__group > label { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--color-text-tertiary); font-weight: var(--weight-semibold); }
.opt-list { display: flex; flex-direction: column; gap: 2px; }
.opt { display: flex; align-items: center; gap: var(--space-2); padding: 7px var(--space-2); border-radius: var(--radius-sm); cursor: pointer; font-size: var(--text-sm); color: var(--color-text-secondary); }
.opt:hover { background: var(--color-surface-2); color: var(--color-text-primary); }
.opt.is-on { background: var(--color-accent-muted); color: var(--color-accent-glow); }

.bars { display: flex; align-items: flex-end; gap: var(--space-3); height: 240px; padding: var(--space-4) 0; }
.bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); height: 100%; justify-content: flex-end; }
.bar { width: 100%; max-width: 48px; border-radius: 6px 6px 0 0; transition: height 300ms cubic-bezier(0.22,1,0.36,1); }
.bar-col .lbl { font-size: var(--text-2xs); color: var(--color-text-tertiary); }

/* ============================================================================
   FILTER PANEL
   ============================================================================ */
.filter-shell { margin-bottom: var(--space-5); }
/* No overflow: hidden — it clipped the combo-filter dropdowns (session,
   timeframe, status…) against the panel's own bottom edge, since an
   absolutely positioned menu is clipped by any hidden-overflow ancestor no
   matter its z-index. The head rounds its own top corners instead. */
.filter-panel {
    background: var(--color-surface-1);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
}
.filter-panel__head {
    display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--color-border-subtle);
    background: var(--color-surface-0);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    flex-wrap: wrap;
}
.filter-panel__head h2 { margin: 4px 0 0; font-size: var(--text-xl); font-weight: var(--weight-semibold); }
.filter-panel__head .muted { margin: 4px 0 0; color: var(--color-text-secondary); font-size: var(--text-sm); }
.filter-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-2); }
/* Same rule as the page header's action row: one height, so the mode toggle
   and the three buttons beside it sit on one baseline. */
.filter-actions > .btn,
.filter-actions > .filter-mode-toggle { height: 32px; }
.filter-actions > .filter-mode-toggle .filter-mode-toggle__item { height: 100%; }
.filter-actions > .actions-rule { min-height: 20px; }

.filter-mode-toggle {
    display: flex; align-items: stretch;
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-sm); overflow: hidden;
    background: var(--color-surface-inset);
}
.filter-mode-toggle__item {
    height: 30px; padding: 0 var(--space-3);
    border: 0; background: transparent;
    color: var(--color-text-secondary); font-size: var(--text-xs); font-weight: var(--weight-medium);
    cursor: pointer; transition: background 110ms ease, color 110ms ease; white-space: nowrap;
}
.filter-mode-toggle__item.is-active { background: var(--color-accent-primary); color: var(--color-accent-ink); }
.filter-mode-toggle__item:hover:not(.is-active) { background: var(--color-surface-2); color: var(--color-text-primary); }

.filter-section { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--color-border-subtle); }
.filter-section:last-child { border-bottom: 0; }
.filter-section__header { display: flex; align-items: baseline; gap: var(--space-3); margin-bottom: var(--space-3); }
.filter-section__header strong { font-size: var(--text-sm); font-weight: var(--weight-semibold); }
.filter-section__header span { font-size: var(--text-xs); color: var(--color-text-secondary); }

.filter-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(175px, 1fr));
    gap: var(--space-3);
}
.filter-grid--compact { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }

.numeric-filters { padding: var(--space-4) var(--space-5); }
.numeric-filters .filter-section__header { margin-bottom: var(--space-3); }

/* ============================================================================
   REPORTS — explorer, summary cards, report groups
   ============================================================================ */
.reports-explorer { display: flex; flex-direction: column; gap: var(--space-5); }
.reports-summary-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--space-3);
}
.ref-stat-card {
    background: var(--color-surface-1); border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg); padding: var(--space-4);
    display: flex; flex-direction: column; gap: var(--space-2);
}
.ref-stat-card--featured { border-color: var(--color-accent-border); background: var(--color-accent-muted); }
.ref-stat-card__label { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--color-text-tertiary); font-weight: var(--weight-semibold); }
.ref-stat-card__value { font-family: var(--font-mono); font-size: var(--text-2xl); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; line-height: 1.1; }
.ref-stat-card--featured .ref-stat-card__value { color: var(--color-accent-glow); }
.ref-stat-card__sub { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--color-text-secondary); flex-wrap: wrap; }
.ref-stat-card__sub .is-pos { color: var(--color-profit); }
.ref-stat-card__sub .is-neg { color: var(--color-loss); }
.ref-stat-card__sub .is-neutral { color: var(--color-text-tertiary); }

.report-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(480px, 1fr)); gap: var(--space-4); }
.report-chip {
    display: inline-flex; align-items: center;
    padding: 2px 8px; border-radius: var(--radius-sm);
    background: var(--color-surface-2); border: 1px solid var(--color-border-subtle);
    font-size: var(--text-xs); font-weight: var(--weight-medium); font-family: var(--font-mono);
}
.reports-pagination { display: flex; justify-content: center; padding: var(--space-3) var(--space-4); border-top: 1px solid var(--color-border-subtle); }

/* utility */
.muted { color: var(--color-text-secondary); }
.dim { color: var(--color-text-tertiary); }
.is-pos { color: var(--color-profit); }
.is-neg { color: var(--color-loss); }
.is-neutral { color: var(--color-text-tertiary); }

/* ============================================================================
   RESPONSIVE
   ============================================================================ */
@media (max-width: 1100px) {
    .dash-grid { grid-template-columns: minmax(0,1fr); }
    .grid-2, .grid-3 { grid-template-columns: minmax(0,1fr); }
    .builder { grid-template-columns: minmax(0,1fr); }
    .kpi-strip { grid-template-columns: repeat(2, minmax(0,1fr)); }
    .kpi:nth-child(2) { border-inline-end: 0; }
    .kpi:nth-child(1), .kpi:nth-child(2) { border-bottom: 1px solid var(--color-border-subtle); }
}
@media (max-width: 820px) {
    .main { margin-inline-start: 0 !important; }
    .topbar__search { display: none; }
    .form-grid { grid-template-columns: 1fr; }
    .content { padding-inline: var(--space-4); }
    /* ≥16px stops mobile Safari's zoom-on-focus; height compensates.
       Covers both control families: hinovest (.input/.select/.textarea)
       and the bootstrap-bridged forms (.form-control/.form-select). */
    .input, .select, .textarea, .form-control, .form-select { font-size: 16px; height: 42px; }
    .textarea, textarea.form-control { height: auto; }
}
@media (max-width: 560px) {
    .kpi-strip { grid-template-columns: minmax(0,1fr); }
    .kpi { border-inline-end: 0 !important; border-bottom: 1px solid var(--color-border-subtle); }
    .kpi:last-child { border-bottom: 0; }
    .page-head h1 { font-size: var(--text-2xl); }
}

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
