/* rackview.css — the rack as it sits.
 *
 * Same tokens as style.css (this file is loaded after it and defines no
 * colour of its own): --surface/--rule/--ink etc. carry both themes by
 * construction, and the swatch fills reach the page through the CSSOM
 * exactly like `.org-sw` does — this site's CSP is style-src 'self' with no
 * 'unsafe-inline', so a style="" attribute would be silently dropped.
 *
 * The wall borrows `views/organizer.js`'s row/band/divider structure
 * (`.org-row`, `.org-band`, `.org-rackend`) almost line for line — it is
 * the same plan drawn a second way — but the cell itself is rebuilt: fewer
 * words, a much bigger swatch, because this page is read at a glance rather
 * than worked through with a pointer.
 */

/* ── head: tabs + names toggle ────────────────────────────────────────────── */
.rv-head-acts {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* A segmented control, same shape as `.segbar`/`.seg` elsewhere on the site —
 * two tabs are not five, so it stays a fixed-width pair rather than growing
 * to fill a row. */
.rv-tabs {
  display: flex;
  gap: 4px;
  background: var(--sunken);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 4px;
}
.rv-tab {
  font: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  padding: 8px 16px;
  min-height: 36px;
  display: flex;
  align-items: center;
  border-radius: var(--r-sm);
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
}
.rv-tab:hover { color: var(--ink); }
.rv-tab[aria-current="page"] {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--rule-2);
}

/* A real toggle button, not a bare link — same face as `.btn-secondary` at
 * rest, the pressed state reusing the site's own "on" fill so it reads the
 * same as every other toggle here (`.chip-on`, `.seg-on`). */
.rv-names {
  font: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  padding: 9px 14px;
  min-height: 42px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule-2);
  background: var(--btn-quiet);
  color: var(--btn-quiet-ink);
  cursor: pointer;
}
/* Hover is a quieter step than selected below it — never the same fill, or a
 * passing cursor reads as the pressed state itself. */
.rv-names:hover { border-color: var(--muted); background: color-mix(in srgb, var(--surface) 50%, var(--sunken)); }
/* Selected, not "press to do a thing" — M7/L11. A filled primary means an
 * action everywhere else on the site; the same fill on a toggle that is
 * already in its pressed state reads as a button waiting to be pressed
 * again. The site's own selected-pill idiom (a --surface fill plus an
 * ink-coloured edge — same as `.seg-on` and `.rv-tab[aria-current="page"]`)
 * says "this is the current state" instead. */
.rv-names[aria-pressed="true"] {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--ink);
}
.rv-names[disabled] { opacity: 0.45; cursor: not-allowed; }

.rv-empty-cta { max-width: 320px; }

/* ── the nested organizer ─────────────────────────────────────────────────── */
/* Breathing room between the head and the embedded page — `views/organizer.js`
 * supplies its own `.card` rhythm underneath; its own page head is gone when
 * embedded (M6), so this is only the seam between the shared head above and
 * the first card below. */
.rv-embed { margin-top: 4px; }

/* Save layout / Undo changes / the dirty note, appended by `views/organizer.js`
 * straight into this page's OWN action row (`.rv-head-acts`) when the
 * Organize tab is open — see `renderOrganize`. `.org-savebar` itself keeps its
 * standalone (non-embedded) rules in style.css; this modifier is what makes it
 * behave as one more flex item in a row it does not own the layout of, rather
 * than as its own `.page-head`. */
.org-savebar-embedded {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.org-savebar-embedded .org-dirty { margin-top: 0; }

@media (max-width: 560px) {
  .org-savebar-embedded { width: 100%; justify-content: space-between; }
  .org-savebar-embedded .org-saveacts { flex: 1 1 auto; justify-content: flex-end; }
}

/* ── the wall ──────────────────────────────────────────────────────────────── */
/* One wall per RACK, stacked. Each keeps its own scroll box below, because the
 * shelves are different widths and a wide one must not drag a narrow one
 * sideways with it. */
.rv-walls { display: block; }
/* The shelf's name, outside the scroll box so it cannot slide away from the
 * pots it names. Drawn only when there is more than one rack — on a single
 * shelf it would be a heading over the whole page saying nothing. */
.rv-rackname {
  margin: 26px 0 0;
  padding-bottom: 8px;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  border-bottom: 1px solid var(--rule-2);
}
.rv-rackname:first-child { margin-top: 10px; }
.rv-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  max-width: 100%;
  margin-top: 14px;
  padding-bottom: 6px;
}
/* min-content, not max-content: see the identical comment on `.org-rack` —
 * a rack that fits the card should not scroll just because one pot's name
 * is long. */
.rv-wall { width: min-content; min-width: 100%; display: grid; gap: 8px; }

.rv-row { display: flex; gap: 10px; align-items: stretch; }
.rv-row-start { border-top: 2px solid var(--ink); padding-top: 10px; }
.rv-band {
  font-size: 0.66rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 10px;
  padding-left: 40px;
}
.rv-row-brand { border-top-width: 4px; padding-top: 14px; }
.rv-band-brand {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--ink);
  margin-top: 24px;
}

/* The divider between the real rack and the rows the plan keeps going into
 * past its bottom — same shape as `.org-rackend`, left-aligned for the same
 * phone-width reason: the row is as wide as the wall, which is a scrolling
 * box, and a centred caption would sit off-screen on a narrow one. */
.rv-rackend { display: flex; align-items: center; gap: 10px; margin: 20px 0 6px; }
.rv-rackend::before, .rv-rackend::after { content: ''; border-top: 2px dashed var(--rule-2); }
.rv-rackend::before { flex: 0 0 40px; }
.rv-rackend::after { flex: 1 1 auto; }
.rv-rackend-t {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.rv-row-extra {
  background: var(--sunken);
  border-radius: var(--r-sm);
  padding: 8px 0;
}
.rv-row-extra .rv-cell { border-style: dashed; border-color: var(--rule-2); }
.rv-row-extra .rv-cell-empty { background: transparent; border-color: var(--faint); }
.rv-row-extra .rv-rownum { color: var(--muted); }
.rv-band-extra { color: var(--ink-2); }

.rv-rownum {
  flex: none;
  width: 32px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  font-size: 0.78rem;
  color: var(--ink-2);
  padding-right: 2px;
}

/* ── find bar ──────────────────────────────────────────────────────────── */
.rv-find { display: grid; gap: 6px; margin-bottom: 14px; }
.rv-find-row { display: flex; gap: 9px; align-items: center; }
.rv-find-row input { flex: 2 1 200px; min-width: 0; }
.rv-find-row select { flex: 1 1 130px; min-width: 0; }
.rv-find-row .btn { flex: none; }
.rv-count { font-size: 0.72rem; color: var(--muted); min-height: 1em; }
/* A non-match fades rather than disappears: the wall is a map of the shelf,
 * and removing cells would move every other pot's apparent place. */
.rv-cell.rv-dim { opacity: 0.18; }
.rv-cell.rv-hit { border-color: var(--ink); box-shadow: 0 0 0 2px var(--ink); }
.rv-wall.rv-hide-names .rv-cell.rv-hit .rv-name { display: block; }
@media (max-width: 560px) {
  .rv-find-row { flex-wrap: wrap; }
  .rv-find-row input { flex-basis: 100%; }
}

/* The column count arrives through the CSSOM as `--cols`. 72px is the
 * "big swatch" desktop size the brief asks for; the phone breakpoint below
 * drops it to the ≥56px floor so a 12-column rack stays usable without
 * either scrolling sideways for every row or shrinking the swatch to
 * nothing. */
.rv-cells {
  flex: 1;
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: repeat(var(--cols, 12), minmax(72px, 1fr));
  grid-auto-columns: minmax(72px, 1fr);
  gap: 8px;
}

.rv-cell {
  font: inherit;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  padding: 6px;
  cursor: pointer;
  display: grid;
  gap: 5px;
  align-content: start;
  min-width: 0;
}
.rv-cell:hover { border-color: var(--rule-2); }
.rv-cell:active { transform: translateY(1px); }
.rv-cell-empty {
  background: var(--sunken);
  border-style: dashed;
  border-color: var(--faint);
  min-height: 64px;
  cursor: default;
}
/* L1: an unplaced slot below the rack, past the first row's width of genuine
 * dashed sockets (`.rv-cell-empty`) — see the budget in `buildWall()`. Still a
 * grid track, so the columns keep lining up, but drawn as nothing: the "rack
 * ends here" caption already said how many rows and pots are left, and a wall
 * of identical dashed tiles past that point is furniture, not information. */
.rv-cell-filler { background: transparent; border-color: transparent; box-shadow: none; min-height: 64px; }
/* Where one band starts inside a row — `newRowPerGroup` off packs bands end
 * to end, and a linked band lands straight after the one it follows, so the
 * seam is not always at the row's own edge. Same idea as `.org-cell-bandstart`. */
.rv-cell-bandstart { border-left: 3px solid var(--ink); padding-left: 4px; }
.rv-row-extra .rv-cell-bandstart { border-left-color: var(--ink); }

.rv-swatch {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 4px;
  background: var(--c, var(--sunken));
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.14);
}
.rv-swatch-none {
  background: repeating-linear-gradient(45deg, var(--sunken) 0 5px, var(--chrome) 5px 10px);
}
/* A colour guessed from the paint's NAME rather than measured — a real tint
 * so the wall still reads colour-first, ringed in a dashed line so a guess
 * is never mistaken for a swatch someone actually recorded. */
.rv-swatch-guessed {
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.14);
  outline: 2px dashed var(--muted);
  outline-offset: -3px;
}

.rv-name { font-size: 0.72rem; font-weight: 500; line-height: 1.25; color: var(--ink); }
/* The Names toggle hides the label only — the swatch, the cell and the tap
 * target are unchanged, so a pure colour wall is still fully clickable. */
.rv-wall.rv-hide-names .rv-name { display: none; }

@media (max-width: 560px) {
  .rv-cells {
    grid-template-columns: repeat(var(--cols, 12), minmax(56px, 1fr));
    grid-auto-columns: minmax(56px, 1fr);
    gap: 6px;
  }
  .rv-band { padding-left: 0; }
  .rv-rackend::before { flex: 0 0 0; }
  .rv-rackend { gap: 8px; }
  .rv-rackend-t { font-size: 0.62rem; letter-spacing: 0.05em; }
  /* The head is a nowrap flex row (`.page-head`), so at 390px the title takes
     half of it and the tabs and the Names toggle wrap against each other
     INSIDE the remaining half — Names ends up orphaned on a line of its own,
     left-aligned under the tabs, reading as an unrelated control. Letting the
     head itself wrap drops the whole action group onto its own full-width
     line, tabs at one end and Names at the other. */
  .rv-head { flex-wrap: wrap; }
  .rv-head-acts { width: 100%; justify-content: space-between; }
}
