/*
 * components.css — reusable component classes.
 *
 * Buttons, inputs, cards, chips, badges, tables, share-panel tabs,
 * view toggles, photo uploader, help-article rendering, QR thumbnails,
 * item-card checkboxes, bulk-action bar, etc.
 *
 * Layout chrome (topbar, sidebar/nav, user menu, nav badges) lives
 * in layout.css.
 */
/* ─── Buttons ──────────────────────────────────────────────────────────── */
.st-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.5rem;
  padding: 0.625rem 1.25rem;
  border-radius: var(--st-radius-pill);
  font-weight: 500; font-size: 0.875rem;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease,
              color 120ms ease, box-shadow 120ms ease;
  white-space: nowrap;
  text-decoration: none;
}
.st-btn:focus-visible {
  outline: 2px solid var(--st-primary);
  outline-offset: 2px;
}
.st-btn-primary {
  background: var(--st-primary); color: #fff;
}
.st-btn-primary:hover { background: var(--st-primary-hover); }
.st-btn-secondary {
  background: var(--st-bg); color: var(--st-text);
  border-color: var(--st-border-strong);
}
.st-btn-secondary:hover { background: var(--st-bg-soft); }
.st-btn-ghost {
  background: transparent; color: var(--st-text);
}
.st-btn-ghost:hover { background: var(--st-bg-soft); }
.st-btn-danger {
  background: var(--st-bg); color: var(--st-danger);
  border-color: var(--st-border-strong);
}
.st-btn-danger:hover { background: var(--st-danger-soft); border-color: var(--st-danger); }
.st-btn-sm { padding: 0.375rem 0.875rem; font-size: 0.8125rem; }
.st-btn-lg { padding: 0.875rem 1.75rem; font-size: 1rem; }

/* ─── Inputs ──────────────────────────────────────────────────────────── */
.st-input, .st-select, .st-textarea {
  display: block; width: 100%;
  padding: 0.625rem 0.875rem;
  border-radius: var(--st-radius-sm);
  border: 1px solid var(--st-border-strong);
  background: var(--st-bg);
  color: var(--st-text);
  font-size: 0.9375rem;
  font-family: inherit;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.st-input:focus, .st-select:focus, .st-textarea:focus {
  outline: none;
  border-color: var(--st-primary);
  box-shadow: 0 0 0 3px var(--st-primary-soft);
}
.st-textarea { min-height: 6rem; resize: vertical; }
.st-label {
  display: block; font-size: 0.8125rem; font-weight: 500;
  color: var(--st-text); margin-bottom: 0.375rem;
}
.st-help {
  font-size: 0.75rem; color: var(--st-text-muted); margin-top: 0.25rem;
}

/* ─── Cards ───────────────────────────────────────────────────────────── */
.st-card {
  background: var(--st-bg-card);
  border: 1px solid var(--st-border);
  border-radius: var(--st-radius);
  padding: 1.25rem 1.5rem;
}
/* v13.9.0: on authenticated pages (inside the shell), use the layered
   soft-tonal-shadow technique instead of a hard border. This is the
   Linear / Vercel / Notion look — cards feel lifted off the page
   instead of boxed in. Logged-out marketing pages keep the original
   border-only treatment. */
body.st-has-shell .st-card {
  border-color: var(--st-border-soft);
  box-shadow: var(--st-shadow-card);
}
.st-card-soft { background: var(--st-bg-soft); border-color: var(--st-border); }
.st-card-tight { padding: 1rem; }

/* ─── Chips / pills ──────────────────────────────────────────────────── */
.st-chip {
  display: inline-flex; align-items: center; gap: 0.375rem;
  padding: 0.375rem 0.875rem;
  border-radius: var(--st-radius-pill);
  border: 1px solid var(--st-border-strong);
  background: var(--st-bg);
  color: var(--st-text);
  font-size: 0.8125rem;
  text-decoration: none;
}
.st-chip-active {
  background: var(--st-primary); color: #fff;
  border-color: var(--st-primary);
}
.st-chip-soft {
  background: var(--st-bg-soft); border-color: var(--st-border);
}

/* ─── Badges (status pills) ──────────────────────────────────────────── */
.st-badge {
  display: inline-flex; align-items: center;
  padding: 0.125rem 0.5rem;
  border-radius: var(--st-radius-pill);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.st-badge-ok    { background: var(--st-ok-soft);     color: var(--st-ok); }
.st-badge-warn  { background: var(--st-warn-soft);   color: var(--st-warn); }
.st-badge-info  { background: var(--st-primary-soft); color: var(--st-primary); }
.st-badge-muted { background: var(--st-bg-soft);     color: var(--st-text-muted); }

/* ─── Tables ──────────────────────────────────────────────────────────── */
.st-table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.st-table th, .st-table td {
  text-align: left; padding: 0.875rem 0.75rem;
  border-bottom: 1px solid var(--st-border);
}
.st-table th {
  font-weight: 500; color: var(--st-text-muted); font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.04em;
}


/* ─── v13.7.2: Unified share panel tabs (CSS-only) ───────────────────
 * Radio-driven tabs: hidden radio inputs control which tab-panel
 * shows via :checked + general-sibling combinator. No JS needed,
 * tab state survives form submissions naturally. */
.st-share-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--st-border);
  margin-bottom: 1rem;
}
.st-share-tab-radio {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0;
  height: 0;
}
.st-share-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.65rem 1rem;
  cursor: pointer;
  color: var(--st-muted);
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.1s, border-color 0.1s;
  user-select: none;
}
.st-share-tab:hover { color: var(--st-text); }
.st-share-tab .st-nav-icon { width: 16px; height: 16px; }
/* Active state on the LABEL when its radio is :checked */
.st-share-tab-radio:checked + .st-share-tab {
  color: var(--st-primary);
  border-bottom-color: var(--st-primary);
}
/* Show only the panel matching the checked radio.
 * The radios occur in order: t1 (user), t2 (public).
 * The panels follow in the same order, so general-sibling combinator
 * lets us toggle visibility per checked-state. */
.st-share-tab-panel { display: none; }
/* When the first radio is checked, show the user panel (the FIRST
   .st-share-tab-panel sibling after the tabs container). */
.st-share-panel:has(.st-share-tab-radio[value="user"]:checked) .st-share-tab-panel-user   { display: block; }
.st-share-panel:has(.st-share-tab-radio[value="public"]:checked) .st-share-tab-panel-public { display: block; }
/* Fallback for browsers without :has() (Safari pre-15.4) — show the
   user panel by default. CSS-only tabs degrade gracefully. */
@supports not (selector(:has(*))) {
  .st-share-tab-panel-user { display: block; }
  .st-share-tab-panel-public { display: none; }
}


/* ─── View toggle (grid/list) ─── v13.4
 * Used on box and location views to let the user switch between the
 * thumbnail grid (default after a QR scan) and a compact list. The pair
 * of buttons is bordered as a single segmented-control unit for clarity. */
.st-view-toggle {
  display: inline-flex;
  border: 1px solid var(--st-border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--st-bg);
}
.st-view-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.65rem;
  font-size: 0.825rem;
  color: var(--st-text-muted);
  text-decoration: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}
.st-view-toggle-btn + .st-view-toggle-btn {
  border-left: 1px solid var(--st-border);
}
.st-view-toggle-btn:hover { background: var(--st-bg-soft); color: var(--st-text); }
.st-view-toggle-active {
  background: var(--st-primary-soft);
  color: var(--st-primary);
}
.st-view-toggle-active:hover { background: var(--st-primary-soft); color: var(--st-primary); }
.st-view-toggle-btn .st-nav-icon { width: 14px; height: 14px; }

/* ── Language autodetect banner ───────────────────────────────── */
.st-lang-banner {
  background: var(--st-primary-soft);
  border: 1px solid color-mix(in srgb, var(--st-primary) 25%, transparent);
  border-radius: 10px;
  padding: 0.55rem 0.85rem;
  margin-bottom: 1rem;
  font-size: 0.85rem;
  color: var(--st-text);
}
.st-lang-banner-inner {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
}
.st-lang-banner-icon { font-size: 1.05rem; line-height: 1; flex: 0 0 auto; }
.st-lang-banner-text { flex: 1 1 200px; line-height: 1.5; }
.st-lang-banner-link {
  background: white;
  border: 1px solid var(--st-border);
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  font-size: 0.8125rem;
  color: var(--st-text);
  cursor: pointer;
  font-family: inherit;
  margin: 0 0.05rem;
  transition: border-color 0.15s, background 0.15s;
}
.st-lang-banner-link:hover {
  border-color: var(--st-primary);
  background: white;
  color: var(--st-primary);
}
.st-lang-banner-dismiss-form { margin: 0; line-height: 0; flex: 0 0 auto; }
.st-lang-banner-dismiss {
  background: transparent;
  border: 0;
  color: var(--st-soft);
  cursor: pointer;
  font-size: 1.4rem;
  line-height: 1;
  padding: 0 0.25rem;
  font-family: inherit;
  border-radius: 4px;
}
.st-lang-banner-dismiss:hover { color: var(--st-text); background: rgba(0,0,0,0.04); }

/* ── Photo uploader (camera + files) ──────────────────────────── */
.st-photo-uploader {
  border: 1px dashed var(--st-border-strong);
  border-radius: var(--st-radius-sm);
  padding: 0.85rem;
  background: var(--st-bg-soft);
}
.st-photo-uploader-buttons {
  display: flex; gap: 0.5rem; flex-wrap: wrap;
}
.st-photo-btn {
  flex: 1 1 auto;
  min-width: 140px;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem;
  padding: 0.65rem 1rem;
  background: white;
  border: 1px solid var(--st-border-strong);
  border-radius: var(--st-radius-sm);
  font-size: 0.9rem; font-weight: 500;
  color: var(--st-text);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.05s;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
.st-photo-btn:hover {
  border-color: var(--st-primary);
  color: var(--st-primary);
}
.st-photo-btn:active { transform: scale(0.98); }
.st-photo-btn input[type="file"] {
  /* hide the native file input but keep it focusable for a11y */
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.st-photo-btn svg { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; }
.st-photo-status {
  font-size: 0.8rem;
  color: var(--st-soft);
  margin-top: 0.5rem;
  min-height: 1rem;
}
.st-photo-status:not(:empty) {
  color: var(--st-primary);
  font-weight: 500;
}
/* On non-touch devices (desktop), the camera button is misleading because
   capture="environment" doesn't open a webcam in any sensible way. Hide it. */
@media (hover: hover) and (pointer: fine) {
  .st-photo-btn-camera { display: none; }
}

/* ── Help center article rendering ──────────────────────────── */
.st-help-article { font-size: 0.95rem; line-height: 1.65; color: var(--st-text); }
.st-help-article > :first-child { margin-top: 0; }
.st-help-article h1 { font-size: 1.6rem; font-weight: 600; letter-spacing: -0.01em;
  margin: 0 0 1rem; color: var(--st-text); }
.st-help-article h2 { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.005em;
  margin: 1.75rem 0 0.6rem; color: var(--st-text); }
.st-help-article h3 { font-size: 1.05rem; font-weight: 600;
  margin: 1.4rem 0 0.4rem; color: var(--st-text); }
.st-help-article h4 { font-size: 0.95rem; font-weight: 600;
  margin: 1.1rem 0 0.3rem; color: var(--st-text); }
.st-help-article p  { margin: 0 0 1rem; }
.st-help-article ul, .st-help-article ol { margin: 0 0 1rem 0; padding-left: 1.4rem; }
.st-help-article li { margin: 0.25rem 0; }
.st-help-article ul li::marker { color: var(--st-soft); }
.st-help-article a { color: var(--st-primary); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px; }
.st-help-article a:hover { text-decoration-thickness: 2px; }
.st-help-article code { background: var(--st-bg-soft);
  padding: 0.1rem 0.35rem; border-radius: 4px; font-size: 0.875em;
  border: 1px solid var(--st-border); }
.st-help-article pre { background: var(--st-bg-soft);
  border: 1px solid var(--st-border); border-radius: var(--st-radius-sm);
  padding: 0.85rem 1rem; overflow-x: auto; font-size: 0.85rem;
  line-height: 1.55; margin: 0 0 1rem; }
.st-help-article pre code { background: transparent; border: 0; padding: 0; font-size: inherit; }
.st-help-article blockquote { margin: 1rem 0; padding: 0.75rem 1rem;
  background: var(--st-bg-soft); border-left: 3px solid var(--st-primary);
  border-radius: 0 6px 6px 0; color: var(--st-text); font-style: normal; }
.st-help-article blockquote p { margin: 0; }
.st-help-article hr { border: 0; border-top: 1px solid var(--st-border); margin: 2rem 0; }
.st-help-article strong { font-weight: 600; }
.st-help-article mark { background: #fef3c7; padding: 0 2px; border-radius: 2px; }
.st-help-article table.st-help-table {
  border-collapse: collapse;
  width: 100%;
  margin: 1rem 0;
  font-size: 0.9rem;
}
.st-help-article table.st-help-table th,
.st-help-article table.st-help-table td {
  text-align: left;
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--st-border);
  vertical-align: top;
}
.st-help-article table.st-help-table th {
  background: var(--st-bg-soft);
  font-weight: 600;
  border-bottom: 2px solid var(--st-border-strong);
}
.st-help-article table.st-help-table tr:last-child td {
  border-bottom: 0;
}

.st-help-side-active { /* sidebar active state — colors set inline for theming */ }

/* ── Encrypted-fields section divider (items form) ────────────── */
/* Used instead of <fieldset> to avoid the padding-induced indent that
   misaligned the inner inputs vs the inputs above/below. The section
   is now flush with the rest of the form; visual separation comes from
   the heading row and a subtle background tint that bleeds full-width. */
.st-private-section {
  /* Negative inline margin pulls the tinted band to the form-card edges
     so the band is full-bleed without the inner content moving. The
     padding restores the input position to match other inputs above. */
  margin-left: -1.5rem;
  margin-right: -1.5rem;
  padding: 1rem 1.5rem 1.25rem;
  background: var(--st-bg-soft);
  border-top: 1px solid var(--st-border);
  border-bottom: 1px solid var(--st-border);
}
.st-private-header {
  display: flex; align-items: center; gap: 0.5rem;
  margin-bottom: 0.25rem;
}
.st-private-header svg { width: 1rem; height: 1rem; flex-shrink: 0; }
.st-private-title {
  font-size: 0.95rem; font-weight: 600;
  margin: 0; color: var(--st-text);
}
.st-private-intro {
  font-size: 0.8125rem;
  color: var(--st-soft);
  margin: 0 0 0.85rem;
  line-height: 1.45;
}

/* ── QR thumbnails (on /qr/ list page) ────────────────────────── */
.st-qr-thumb {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  background: white;
  border: 1px solid var(--st-border);
  border-radius: var(--st-radius-sm);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  padding: 0.4rem;
}
.st-qr-thumb img {
  display: block;
  width: 100%; height: auto;
  max-width: 100%;
  image-rendering: pixelated; /* keep QR modules crisp at small sizes */
}

/* ── Bulk-action sticky bar (items list) ──────────────────────── */
.st-bulk-bar {
  position: sticky;
  top: 0.5rem;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.8rem;
  margin-bottom: 1rem;
  background: var(--st-primary);
  color: white;
  border-radius: var(--st-radius-sm);
  box-shadow: 0 4px 12px -4px rgba(0,0,0,0.15);
  font-size: 0.875rem;
  flex-wrap: wrap;
}
.st-bulk-bar[hidden] { display: none; }
.st-bulk-bar .st-bulk-count { font-weight: 600; }
.st-bulk-bar .st-input { color: var(--st-text); }
.st-bulk-bar .st-btn-primary {
  background: white; color: var(--st-primary); border-color: white;
}
.st-bulk-bar .st-btn-primary:hover {
  background: var(--st-bg-soft); color: var(--st-primary);
}
.st-bulk-bar .st-btn-ghost {
  color: white; border-color: rgba(255,255,255,0.4);
}
.st-bulk-bar .st-btn-ghost:hover {
  background: rgba(255,255,255,0.1); color: white;
}

/* ── Item card with checkbox overlay ────────────────────────── */
.st-item-card-wrap { position: relative; }
.st-item-card-check {
  position: absolute;
  top: 0.5rem; left: 0.5rem;
  z-index: 5;
  width: 1.6rem; height: 1.6rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  border: 1.5px solid var(--st-border-strong);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.05s;
  -webkit-tap-highlight-color: transparent;
  backdrop-filter: blur(4px);
}
.st-item-card-check:hover {
  border-color: var(--st-primary);
  background: white;
}
.st-item-card-check input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 100%; height: 100%;
  margin: 0; cursor: pointer;
}
.st-item-card-check .st-check-visual {
  font-size: 0.95rem;
  color: transparent;
  font-weight: 700;
  line-height: 1;
}
.st-item-card-check input[type="checkbox"]:checked + .st-check-visual {
  color: white;
}
.st-item-card-check:has(input[type="checkbox"]:checked) {
  background: var(--st-primary);
  border-color: var(--st-primary);
}


/* ════════════════════════════════════════════════════════════════════
 * v13.9.0 — card link pattern for inventory index pages
 *
 * Used by /locations/, /boxes/, /closets/ (and could be reused by
 * any "list of named entities with an icon + secondary metadata"
 * page). Items use a different pattern (photo-first card) since they
 * have images.
 *
 * Visual: rounded card with soft tonal shadow, icon on the left,
 * title + meta line on the right. Lifts on hover. Replaces the
 * earlier `block st-card hover:shadow-md` + flex-row pattern.
 * ════════════════════════════════════════════════════════════════════ */

.st-grid-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--st-space-3);
}
@media (min-width: 640px) {
  .st-grid-cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .st-grid-cards { grid-template-columns: repeat(3, 1fr); }
}

.st-card-link {
  display: flex;
  align-items: flex-start;
  gap: var(--st-space-3);
  padding: var(--st-space-4) var(--st-space-5);
  background: var(--st-bg-elevated);
  border: 1px solid var(--st-border-soft);
  border-radius: var(--st-radius);
  box-shadow: var(--st-shadow-card);
  text-decoration: none;
  color: inherit;
  transition: transform var(--st-duration-fast) var(--st-ease),
              box-shadow var(--st-duration-fast) var(--st-ease),
              border-color var(--st-duration-fast) var(--st-ease);
}
.st-card-link:hover {
  transform: translateY(-1px);
  box-shadow: var(--st-shadow-lift);
  border-color: var(--st-border);
}
.st-card-link:focus-visible {
  outline: 2px solid var(--st-primary);
  outline-offset: 2px;
}

.st-card-link-icon {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--st-radius-sm);
  background: var(--st-primary-soft);
  color: var(--st-primary);
}
.st-card-link-icon svg {
  width: 20px;
  height: 20px;
}

.st-card-link-body {
  flex: 1 1 auto;
  min-width: 0;
}
.st-card-link-title {
  font-weight: var(--st-weight-medium);
  font-size: var(--st-text-md);
  color: var(--st-text);
  line-height: var(--st-leading-snug);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.st-card-link-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
  font-size: var(--st-text-sm);
  color: var(--st-text-muted);
}
.st-card-link-meta svg,
.st-card-link-meta-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.st-card-link-meta-sep {
  margin: 0 4px;
  color: var(--st-text-soft);
}
.st-card-link-desc {
  margin-top: var(--st-space-2);
  font-size: var(--st-text-sm);
  color: var(--st-text-muted);
  line-height: var(--st-leading-snug);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ════════════════════════════════════════════════════════════════════
 * v13.9.1 — items index card grid + search form
 *
 * Different from .st-card-link (which is icon-first text-row) — items
 * have a photo as the primary visual, so the card is photo-first with
 * title + brand below. The bulk-select checkbox overlay (.st-item-card-check)
 * was already in place and continues to work; this just replaces the
 * inline-styled .st-card with a proper class.
 * ════════════════════════════════════════════════════════════════════ */

.st-grid-items {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--st-space-3);
}
@media (min-width: 768px) {
  .st-grid-items { grid-template-columns: repeat(3, 1fr); gap: var(--st-space-4); }
}
@media (min-width: 1024px) {
  .st-grid-items { grid-template-columns: repeat(4, 1fr); }
}

.st-item-card {
  display: block;
  background: var(--st-bg-elevated);
  border: 1px solid var(--st-border-soft);
  border-radius: var(--st-radius);
  box-shadow: var(--st-shadow-card);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: transform var(--st-duration-fast) var(--st-ease),
              box-shadow var(--st-duration-fast) var(--st-ease);
}
.st-item-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--st-shadow-lift);
}
.st-item-card:focus-visible {
  outline: 2px solid var(--st-primary);
  outline-offset: 2px;
}

.st-item-card-photo {
  aspect-ratio: 1;
  background: var(--st-bg-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.st-item-card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.st-item-card-photo-empty {
  color: var(--st-text-soft);
  opacity: 0.4;
}
.st-item-card-photo-empty svg {
  width: 32px;
  height: 32px;
}

.st-item-card-body {
  padding: var(--st-space-3);
}
.st-item-card-title {
  font-weight: var(--st-weight-medium);
  font-size: var(--st-text-base);
  line-height: var(--st-leading-snug);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.st-item-card-brand {
  font-size: var(--st-text-xs);
  color: var(--st-text-muted);
  margin-top: 2px;
}

/* ─── Search form (used on items index, can be reused) ─────────────── */
.st-search-form {
  display: flex;
  gap: var(--st-space-2);
  margin-bottom: var(--st-space-6);
}
.st-search-wrap {
  flex: 1 1 auto;
  position: relative;
}
.st-search-icon {
  position: absolute;
  left: var(--st-space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--st-text-soft);
  pointer-events: none;
  display: inline-flex;
}
.st-search-icon svg {
  width: 16px;
  height: 16px;
}
.st-search-input {
  padding-left: 2.5rem;
}

/* Auto-fill variant for items-in-box grids — fits as many tiles as
   possible at ~140px min width. Used when the parent container doesn't
   need a fixed column count. */
.st-grid-items-auto {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--st-space-3);
}

/* Recent activity feed icons (dashboard) — neutral tint */
.st-recent-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  color: var(--st-text-soft);
  flex-shrink: 0;
}

/* ────────────────────────────────────────────────────────────────────
 * v13.9.1 — empty-state pattern
 *
 * Used when a list is empty (no boxes, no items, no search results).
 * Centered icon + message + optional CTA. Soft-shadow card backing
 * matches the rest of the v13.9 aesthetic.
 * ──────────────────────────────────────────────────────────────────── */

.st-empty {
  background: var(--st-bg-elevated);
  border: 1px solid var(--st-border-soft);
  border-radius: var(--st-radius);
  box-shadow: var(--st-shadow-card);
  padding: var(--st-space-12) var(--st-space-6);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--st-space-4);
}
.st-empty-icon {
  width: 64px;
  height: 64px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--st-bg-soft);
  color: var(--st-text-soft);
}
.st-empty-icon svg {
  width: 28px;
  height: 28px;
}
.st-empty-message {
  font-size: var(--st-text-md);
  color: var(--st-text-muted);
  margin: 0;
  max-width: 28rem;
  line-height: var(--st-leading-snug);
}
.st-empty-action {
  display: inline-flex;
  justify-content: center;
}

/* ════════════════════════════════════════════════════════════════════
 * v13.9.2 — photo gallery tiles for item detail
 *
 * 3-column grid, hover overlay with primary/delete actions. Replaces
 * the inline-styled flex/group/absolute pattern that was hard to
 * maintain because of the rgba background literal and per-action
 * inline styles.
 * ════════════════════════════════════════════════════════════════════ */

.st-photos-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--st-space-2);
  margin-bottom: var(--st-space-4);
}

.st-photo-tile {
  position: relative;
  border-radius: var(--st-radius-sm);
  overflow: hidden;
  aspect-ratio: 1;
  background: var(--st-bg-soft);
  border: 1px solid var(--st-border-soft);
}
.st-photo-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.st-photo-tile-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  padding: 2px 8px;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(4px);
  border-radius: var(--st-radius-pill);
  font-size: var(--st-text-xs);
  font-weight: var(--st-weight-semi);
  color: var(--st-primary);
  z-index: 1;
}
.st-photo-tile-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--st-space-1);
  background: rgba(17, 24, 39, 0.55);
  opacity: 0;
  transition: opacity var(--st-duration-fast) var(--st-ease);
}
.st-photo-tile:hover .st-photo-tile-overlay,
.st-photo-tile:focus-within .st-photo-tile-overlay {
  opacity: 1;
}
.st-photo-tile-form { margin: 0; }
.st-photo-tile-btn {
  background: white;
  color: var(--st-text);
  font-size: var(--st-text-xs);
  font-weight: var(--st-weight-medium);
  padding: 4px 10px;
  border: 0;
  border-radius: var(--st-radius-sm);
  cursor: pointer;
}
.st-photo-tile-btn:hover { background: var(--st-bg-soft); }
.st-photo-tile-btn-danger {
  background: var(--st-danger);
  color: white;
}
.st-photo-tile-btn-danger:hover { background: #991B1B; }

.st-photos-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--st-space-2);
  padding: var(--st-space-8) var(--st-space-4);
  background: var(--st-bg-soft);
  border-radius: var(--st-radius);
  margin-bottom: var(--st-space-4);
  color: var(--st-text-muted);
}
.st-photos-empty-icon {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--st-bg);
  color: var(--st-text-soft);
}
.st-photos-empty p {
  margin: 0;
  font-size: var(--st-text-sm);
}

/* ════════════════════════════════════════════════════════════════════
 * v13.9.2 — dashboard KPI tiles
 *
 * 5-up tile grid (2-up on mobile). Each tile: tinted icon top-left,
 * uppercase label, big number. Click navigates to the corresponding
 * index page.
 * ════════════════════════════════════════════════════════════════════ */

.st-kpi-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--st-space-3);
  margin-bottom: var(--st-space-8);
}
@media (min-width: 768px) {
  .st-kpi-grid { grid-template-columns: repeat(5, 1fr); }
}

.st-kpi {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--st-space-2);
  padding: var(--st-space-4) var(--st-space-5);
  background: var(--st-bg-elevated);
  border: 1px solid var(--st-border-soft);
  border-radius: var(--st-radius);
  box-shadow: var(--st-shadow-card);
  text-decoration: none;
  color: inherit;
  transition: transform var(--st-duration-fast) var(--st-ease),
              box-shadow var(--st-duration-fast) var(--st-ease);
}
.st-kpi:hover {
  transform: translateY(-1px);
  box-shadow: var(--st-shadow-lift);
}
.st-kpi:focus-visible {
  outline: 2px solid var(--st-primary);
  outline-offset: 2px;
}
.st-kpi-icon {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--st-radius-sm);
  background: var(--st-primary-soft);
  color: var(--st-primary);
}
.st-kpi-icon svg {
  width: 18px;
  height: 18px;
}
.st-kpi-label {
  font-size: var(--st-text-xs);
  font-weight: var(--st-weight-medium);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--st-text-muted);
}
.st-kpi-value {
  font-size: var(--st-text-3xl);
  font-weight: var(--st-weight-semi);
  line-height: 1;
  color: var(--st-text);
}
.st-kpi-aux {
  font-size: var(--st-text-sm);
  font-weight: var(--st-weight-normal);
  color: var(--st-text-muted);
  margin-left: var(--st-space-2);
}

/* ────────────────────────────────────────────────────────────────────
 * v13.10.0 — tab filter strip (used on /shared/, could be reused for
 * any page with a small set of state filters).
 * ──────────────────────────────────────────────────────────────────── */

.st-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--st-bg-soft);
  border-radius: var(--st-radius-pill);
}
.st-tab {
  padding: 6px 14px;
  border-radius: var(--st-radius-pill);
  font-size: var(--st-text-sm);
  font-weight: var(--st-weight-medium);
  color: var(--st-text-muted);
  text-decoration: none;
  transition: background var(--st-duration-fast) var(--st-ease),
              color var(--st-duration-fast) var(--st-ease);
}
.st-tab:hover {
  color: var(--st-text);
}
.st-tab.is-active {
  background: var(--st-bg);
  color: var(--st-text);
  box-shadow: var(--st-shadow-sm);
}

/* Inactive-card variant for .st-card-link — used on /shared/ for
   pending or revoked shares which can't be navigated to. */
.st-card-link-inactive {
  opacity: 0.62;
  cursor: not-allowed;
}
.st-card-link-inactive:hover {
  transform: none;
  box-shadow: var(--st-shadow-card);
}

/* ════════════════════════════════════════════════════════════════════
 * v13.10.5 — lightbox for clickable thumbnails
 *
 * Any <img data-lightbox-src="..."> opens this overlay when clicked.
 * Pure CSS — JS only swaps the src and toggles the hidden attribute.
 * ════════════════════════════════════════════════════════════════════ */

.st-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.92);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--st-space-4);
  cursor: zoom-out;
  animation: stLightboxFadeIn 0.15s ease-out;
}
.st-lightbox[hidden] {
  display: none;
}
@keyframes stLightboxFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.st-lightbox-img {
  max-width: 95vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: var(--st-radius);
  box-shadow: 0 12px 60px rgba(0, 0, 0, 0.6);
  cursor: default;
}
.st-lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  color: white;
  border: 0;
  font-size: 22px;
  font-weight: 300;
  line-height: 1;
  cursor: pointer;
  transition: background var(--st-duration-fast) var(--st-ease);
  z-index: 1;
}
.st-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.22);
}

/* ════════════════════════════════════════════════════════════════════
 * v13.10.6 — thumbnail collage in card-link icon slots
 *
 * Used on /boxes/index.php to show item photos inside the box,
 * filling the same 40×40 icon slot that previously held the box icon.
 * 1, 2, 3, or 4 thumbnails arranged with no layout shift.
 * ════════════════════════════════════════════════════════════════════ */

.st-card-link-thumbs {
  display: grid;
  gap: 2px;
  padding: 0;
  background: var(--st-bg-soft);
  overflow: hidden;
}
/* 1 thumb fills the slot */
.st-card-link-thumbs[data-thumb-count="1"] {
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
}
/* 2 thumbs side-by-side */
.st-card-link-thumbs[data-thumb-count="2"] {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
}
/* 3 thumbs: one tall + two stacked */
.st-card-link-thumbs[data-thumb-count="3"] {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}
.st-card-link-thumbs[data-thumb-count="3"] > .st-card-link-thumb:first-child {
  grid-row: span 2;
}
/* 4 thumbs: 2×2 */
.st-card-link-thumbs[data-thumb-count="4"] {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}

.st-card-link-thumb {
  display: block;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-color: var(--st-bg-soft);
}

/* ════════════════════════════════════════════════════════════════════
 * v13.10.6 — items grid density picker
 *
 * Three modes selectable via ?density= on /items/index.php:
 *   compact     — many small tiles, title only
 *   comfortable — default — title + brand
 *   spacious    — fewer larger tiles, all metadata
 * ════════════════════════════════════════════════════════════════════ */

.st-density-picker {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  background: var(--st-bg-soft);
  border-radius: var(--st-radius-pill);
  margin-bottom: var(--st-space-4);
}
.st-density-picker-label {
  font-size: var(--st-text-xs);
  color: var(--st-text-muted);
  padding: 0 var(--st-space-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.st-density-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--st-radius-pill);
  font-size: var(--st-text-sm);
  font-weight: var(--st-weight-medium);
  color: var(--st-text-muted);
  text-decoration: none;
  transition: background var(--st-duration-fast) var(--st-ease),
              color var(--st-duration-fast) var(--st-ease);
}
.st-density-btn:hover { color: var(--st-text); }
.st-density-btn.is-active {
  background: var(--st-bg);
  color: var(--st-text);
  box-shadow: var(--st-shadow-sm);
}
.st-density-icon {
  display: inline-block;
  width: 14px;
  height: 14px;
  background-image:
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  opacity: 0.7;
}
/* Compact: 4 tiny dots in a 2×2 of finer grain */
.st-density-icon-compact {
  background-size: 5px 5px;
  background-position: 0 0, 9px 0, 0 9px, 9px 9px;
}
/* Comfortable: 4 medium squares 2×2 */
.st-density-icon-comfortable {
  background-size: 6px 6px;
  background-position: 0 0, 8px 0, 0 8px, 8px 8px;
}
/* Spacious: 1 big square */
.st-density-icon-spacious {
  background-size: 14px 14px;
  background-position: 0 0;
  background-image: linear-gradient(currentColor, currentColor);
}
.st-density-label {
  display: none;
}
@media (min-width: 640px) {
  .st-density-label { display: inline; }
}

/* Density modifiers on the items grid */
.st-grid-items-compact {
  grid-template-columns: repeat(3, 1fr);
  gap: var(--st-space-2);
}
@media (min-width: 640px) {
  .st-grid-items-compact { grid-template-columns: repeat(5, 1fr); }
}
@media (min-width: 1024px) {
  .st-grid-items-compact { grid-template-columns: repeat(7, 1fr); gap: var(--st-space-3); }
}
.st-grid-items-compact .st-item-card-body {
  padding: var(--st-space-2) var(--st-space-2);
}
.st-grid-items-compact .st-item-card-title {
  font-size: var(--st-text-xs);
  font-weight: var(--st-weight-medium);
  -webkit-line-clamp: 1;
}
.st-grid-items-compact .st-item-card-brand {
  display: none;
}

/* Spacious: bigger tiles, fewer per row, all metadata visible */
.st-grid-items-spacious {
  grid-template-columns: 1fr;
  gap: var(--st-space-4);
}
@media (min-width: 640px) {
  .st-grid-items-spacious { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .st-grid-items-spacious { grid-template-columns: repeat(3, 1fr); }
}
.st-grid-items-spacious .st-item-card-body {
  padding: var(--st-space-4);
}
.st-grid-items-spacious .st-item-card-title {
  font-size: var(--st-text-md);
  -webkit-line-clamp: 2;
}
.st-grid-items-spacious .st-item-card-brand {
  font-size: var(--st-text-sm);
  margin-top: 4px;
}

/* Comfortable is the default — uses the unprefixed .st-grid-items rules */
