/* Catalog screen (catalog.js). Components shared with other screens live in
   components.css. */

/* minmax(0,1fr), never a bare 1fr: a bare track takes min-content, and a long
   item title would push the table off-screen. */
.cat-layout { display: grid; grid-template-columns: minmax(200px, 240px) minmax(0, 1fr); gap: var(--space-4); align-items: start; }
/* Put away (catalog.js setTreeHidden): the items take the whole width and the
   toolbar's .tree-show brings the panel back. Phones fold the panel into its
   own toggle row instead, so neither control shows there. */
@media (min-width: 768px) {
    .cat-layout.tree-hidden { grid-template-columns: minmax(0, 1fr); }
    .cat-layout.tree-hidden .tree-panel { display: none; }
}
.tree-show { flex: none; max-width: 240px; }
.tree-show-current { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tree-panel {
    position: sticky; top: calc(var(--header-height) + var(--space-3));
    background: var(--card); border: 1px solid var(--outline-variant); border-radius: var(--shape-md);
    display: flex; flex-direction: column; max-height: calc(100vh - var(--header-height) - 32px); min-height: 360px;
}
.tree-head { padding: var(--space-3); display: flex; flex-direction: column; align-items: stretch; gap: var(--space-2); border-bottom: 1px solid var(--outline-variant); }
.tree-head h3 { margin: 0; font-size: var(--typo-title-sm); display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.tree-head h3 .chip { margin-inline-start: 4px; }
.tree-tools { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.tree-list { overflow: auto; padding: var(--space-1) 0 var(--space-2); }
.tree-row {
    display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: 4px;
    padding-block: 2px; padding-inline: calc(8px + var(--depth, 0) * 14px) 10px;
    font-size: var(--typo-body-md);
}
.tree-row:hover { background: color-mix(in srgb, var(--on-surface) calc(var(--state-hover) * 100%), transparent); }
.tree-row[aria-selected="true"] { background: var(--secondary-container); color: var(--on-secondary-container); }
.tree-row.special .tree-name { font-weight: 600; }
.tree-row .chev {
    width: 24px; height: 24px; border: 0; background: transparent; color: var(--on-surface-variant);
    display: inline-grid; place-items: center; border-radius: var(--shape-full); cursor: pointer; padding: 0;
}
.tree-name {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: start;
    background: none; border: 0; font: inherit; color: inherit; cursor: pointer; padding-block: 5px; border-radius: var(--shape-xs, 4px);
}
.tree-name mark { background: var(--tertiary-container); color: var(--on-tertiary-container); border-radius: 2px; }
.tree-meta { display: flex; align-items: center; gap: 6px; font-size: var(--typo-label-md); color: var(--on-surface-variant); font-variant-numeric: tabular-nums; }
.tree-row[aria-selected="true"] .tree-meta { color: inherit; }
.rule-pip { width: 8px; height: 8px; border-radius: 50%; flex: none; box-sizing: border-box; display: inline-block; }
.rule-pip.pub { background: var(--success); }
.rule-pip.hide { border: 1.5px solid var(--outline); }
.rule-pip.inh-pub { background: color-mix(in srgb, var(--success) 45%, transparent); }
.tree-empty { padding: var(--space-4); color: var(--on-surface-variant); font-size: var(--typo-body-md); }
.tree-foot { border-top: 1px solid var(--outline-variant); padding: var(--space-2) var(--space-3); font-size: var(--typo-body-sm); color: var(--on-surface-variant); display: flex; gap: var(--space-3); flex-wrap: wrap; }
.tree-foot > span { display: inline-flex; align-items: center; gap: 6px; }

.cat-pane { min-width: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.cat-pane #catalog-items { display: flex; flex-direction: column; gap: var(--space-3); }
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: var(--typo-body-sm); color: var(--on-surface-variant); }
.crumbs button { background: none; border: 0; font: inherit; color: var(--primary); cursor: pointer; padding: 0; }
.crumbs .sep { opacity: .6; }
html[dir="rtl"] .crumbs .sep { transform: scaleX(-1); display: inline-block; }
.tree-toggle { display: none; }
.cat-title-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.cat-title { margin: 0; font-family: var(--font-headline); font-size: var(--typo-title-lg); line-height: var(--typo-title-lg-lh); font-weight: 600; }

.rule-card { background: var(--card); border: 1px solid var(--outline-variant); border-radius: var(--shape-md); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.rule-card .top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.rule-card h4 { margin: 0; font-size: var(--typo-title-sm); }
.rule-card .why { margin: 0; font-size: var(--typo-body-md); color: var(--on-surface-variant); }
.rule-card .effect { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; font-size: var(--typo-body-md); }
.rule-card .effect .delta { font-weight: 600; }
.rule-card .effect .delta.down { color: var(--error); }
.rule-card .foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.rule-card .foot .actions { display: flex; gap: var(--space-2); }

.toolbar { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
/* Search and filters stay reachable while scrolling a 49k-item catalogue.
   Flush under the header, NOT at .tree-panel's `+ var(--space-3)` offset: the
   panel is a bordered card whose own edge covers that gap, while this is a bare
   --surface band, so the gap became a strip of rows scrolling under a
   translucent header. Alignment between two columns a gutter apart is worth
   less than the seam costs. */
.sticky-tools {
    position: sticky; top: var(--header-height); z-index: 2;
    background: var(--background); padding-block: var(--space-2);
}
.toolbar .searchbox { flex: 1 1 220px; }
.toolbar .chips { display: flex; gap: 6px; flex-wrap: wrap; }

.items-card { background: var(--card); border: 1px solid var(--outline-variant); border-radius: var(--shape-md); overflow: hidden; }
.table-scroll { overflow-x: auto; }
/* Fixed layout: the item column takes what's left, and its one-line parts
   ellipsise instead of widening the table. min-width scrolls on a phone. */
.catalog-table { table-layout: fixed; min-width: 560px; }
.catalog-table td { vertical-align: middle; }
.catalog-table tbody tr { cursor: pointer; }
.catalog-table tbody tr.is-selected { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.catalog-table .col-check { width: 44px; }
.catalog-table .col-price { width: 110px; text-align: end; white-space: nowrap; font-weight: 600; }
.catalog-table .col-vis { width: 150px; }
.item-cell { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.item-cell .thumb {
    flex: none; width: 56px; height: 56px; border-radius: var(--shape-sm); object-fit: cover;
    background: var(--surface-container); border: 1px solid var(--outline-variant);
}
.item-cell .thumb.empty { display: grid; place-items: center; color: var(--outline); }
.item-text { min-width: 0; flex: 1; }
/* Edara item names run long (whole spec lines); two lines keep a 50-row page scannable. */
.item-title {
    background: none; border: 0; padding: 0; font: inherit; font-weight: 500; color: inherit; cursor: pointer; text-align: start;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere;
}
.item-title:hover { text-decoration: underline; text-underline-offset: 2px; }
.item-sub { font-size: var(--typo-body-sm); color: var(--on-surface-variant); display: flex; gap: var(--space-2); align-items: center; margin-top: 2px; min-width: 0; }
.item-sub > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-sub > .code, .item-sub > .stock, .item-sub > .chip { flex: none; }
/* The separator is the UI's, so it sits between the names whichever script they are in. */
.item-sub > .cat::before { content: '· '; }
.item-sub > .stock.out { color: var(--error); }
.price-zero { color: var(--warning); font-weight: 500; }
.price-stack { display: inline-grid; justify-items: end; gap: 2px; }
.price-sale { font-weight: 600; }
.price-was { color: var(--on-surface-variant); font-size: var(--typo-body-sm); font-weight: 400; }
.vis-cell { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; }
.vis-cell .why { font-size: var(--typo-body-sm); color: var(--on-surface-variant); }
.table-foot { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-top: 1px solid var(--outline-variant); font-size: var(--typo-body-sm); color: var(--on-surface-variant); flex-wrap: wrap; }
.table-foot .pager { display: flex; gap: var(--space-2); }
.items-card .empty-state strong { display: block; color: var(--on-surface); margin-bottom: 4px; }

.selbar {
    position: sticky; bottom: var(--space-3); z-index: 5;
    display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
    background: var(--inverse-surface); color: var(--inverse-on-surface); border-radius: var(--shape-md); padding: var(--space-2) var(--space-3); box-shadow: var(--elev-2);
}
.selbar .grow { flex: 1; min-width: 0; font-size: var(--typo-body-md); }
.selbar .btn.ghost { color: var(--inverse-on-surface); }
.selbar .btn.ghost:hover:not(:disabled) { background: color-mix(in srgb, var(--inverse-on-surface) 12%, transparent); }
.selbar .tip { font-size: var(--typo-body-sm); opacity: .85; flex-basis: 100%; }
.selbar .tip .linkbtn { color: inherit; }

.impact { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.impact div { background: var(--surface-container); border-radius: var(--shape-sm); padding: var(--space-3); }
.impact b { display: block; font-family: var(--font-headline); font-size: var(--typo-title-lg); font-variant-numeric: tabular-nums; }
.impact span { font-size: var(--typo-body-sm); color: var(--on-surface-variant); }

.img-slot { display: grid; place-items: center; aspect-ratio: 4 / 3; border-radius: var(--shape-md); border: 1.5px dashed var(--outline); color: var(--on-surface-variant); font-size: var(--typo-body-md); background: var(--surface-container); text-align: center; padding: var(--space-3); overflow: hidden; }
.img-slot.has { border-style: solid; padding: 0; }
.img-slot img { width: 100%; height: 100%; object-fit: contain; }
.upload-btn { align-self: flex-start; cursor: pointer; }

@media (max-width: 991px) {
    .cat-layout { grid-template-columns: minmax(0, 1fr); }
    .tree-panel { position: static; max-height: 420px; }
    .catalog-table .col-vis { width: auto; }
}
@media (max-width: 767px) {
    /* No sticky header at this tier (.topbar goes static), so a sticky
       toolbar would park mid-screen with rows scrolling above it. */
    .sticky-tools { position: static; }
    .tree-show, .tree-hide { display: none; }
    /* The fixed bottom bar owns the viewport's last --bottom-nav-h here; a
       selection bar stuck at the bare edge sat behind it, actions and all.
       main's padding-bottom does not help: a stuck element offsets from the
       viewport, not from its padded container. */
    .selbar { bottom: calc(var(--bottom-nav-h) + var(--space-3)); }
    /* The category panel folds to one row: on a phone it filled the first screen
       before a single item showed. The row says which category is showing. */
    .tree-panel { min-height: 0; }
    .tree-toggle {
        display: flex; align-items: center; gap: var(--space-2); width: 100%;
        min-height: var(--min-touch-target); padding: var(--space-2) var(--space-4);
        background: none; border: 0; color: var(--on-surface); font: inherit; font-weight: 600; cursor: pointer; text-align: start;
    }
    .tree-toggle-current { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--primary); font-weight: 500; text-align: end; }
    .tree-toggle svg { flex: none; transition: transform .15s; }
    .tree-panel.is-open .tree-toggle svg { transform: rotate(180deg); }
    .tree-panel:not(.is-open) > :not(.tree-toggle) { display: none; }
    .tree-panel.is-open .tree-toggle { border-bottom: 1px solid var(--outline-variant); }
}
@media (max-width: 640px) {
    /* Each item becomes a compact card row: it still is the table (selection,
       row clicks, the header checkbox), only laid out as a grid -- the fixed
       560px table scrolled sideways here and cut off price and visibility. */
    .catalog-table { min-width: 0; }
    .catalog-table, .catalog-table thead, .catalog-table tbody { display: block; }
    .catalog-table thead th:not(.col-check) { display: none; }
    .catalog-table tr { display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; align-items: center; column-gap: var(--space-2); row-gap: 4px; padding: var(--space-3); border-bottom: 1px solid var(--outline-variant); }
    .catalog-table thead tr { padding-block: var(--space-2); background: var(--surface-container); }
    .catalog-table :is(th, td) { display: block; padding: 0; border: 0; width: auto; background: none; }
    .catalog-table td.col-check { grid-row: 1 / span 2; }
    .catalog-table td.col-item { grid-column: 2 / span 2; }
    .catalog-table td.col-price { grid-column: 2; text-align: start; }
    .catalog-table td.col-vis { grid-column: 3; }
    .catalog-table .why { display: none; }
}
