/* Epic 0048 — HQ Store area (§6). All store-owned selectors are store-
   prefixed (module isolation rule, §2); core classes (.card, .data-table,
   .btn, .page-header…) are reused, never modified. Sizing follows the
   design mockup (docs/epics/0048-online-store/mockup-hq-store.html):
   compact controls, one-row toolbars, card tables. */

/* ── The stacked second store sidebar (§6 shell) ───────────────────── */
.store-area {
  display: flex;
  gap: 0;
  min-height: calc(100vh - 60px);
  margin: -1rem;                   /* bleed to .main-container's 1rem padding */
}
.store-sidebar {
  flex: 0 0 168px;
  border-right: 1px solid var(--line);
  background: var(--surface);
  padding: 1rem 0.5rem;
}
.store-sidebar__title {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  padding: 0 0.6rem 0.5rem;
}
.store-sidebar__link {
  display: block;
  padding: 0.4rem 0.6rem;
  border-radius: 8px;
  color: var(--ink-2);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.86rem;
  margin-bottom: 2px;
}
.store-sidebar__link:hover { background: var(--surface-2); color: var(--ink); }
.store-sidebar__link.is-active { background: var(--accent-subtle); color: var(--accent); }
.store-sidebar__hint {
  padding: 0.5rem 0.6rem 0;
  font-size: 0.7rem;
  color: var(--ink-3);
}
.store-content {
  flex: 1;
  min-width: 0;
  padding: 1.1rem 1.4rem 2rem;
}
@media (max-width: 800px) {
  .store-area { flex-direction: column; }
  .store-sidebar {
    flex: none;
    display: flex;
    align-items: center;
    gap: 2px;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line);
    padding: 0.5rem;
  }
  .store-sidebar__title { display: none; }
  .store-sidebar__link { white-space: nowrap; margin-bottom: 0; }
}

/* ── Page top row (mockup .top): title left, primary action right ──── */
.store-page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.9rem;
}
.store-page-head .page-crumb { margin-bottom: 0.1rem; }
.store-page-head .page-title { font-size: 1.35rem; margin: 0; }

/* ── Compact controls inside the store area & store modals ──────────
   The app-wide .form-input is a full-width 1rem-padded field; the store's
   list toolbars and card stacks use the mockup's compact sizing. */
.store-content .form-input,
.store-modal .form-input {
  padding: 0.42rem 0.6rem;
  font-size: 0.86rem;
  border-radius: var(--r-sm, 6px);
}
.store-content select.form-input,
.store-modal select.form-input { width: auto; font-weight: 600; color: var(--ink-2); }

/* ── List toolbar (mockup .tb): tabs · search (pushed right) · selects ── */
.store-toolbar {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 0.8rem;
}
/* One GET form holds search + filters + sort; display:contents lets its
   controls sit as direct flex items of the toolbar row. */
.store-toolbar form { display: contents; }
.store-toolbar .store-toolbar__search {
  margin-left: auto;
  width: 190px;
}
/* Orders (Kyle, 2026-09-03): tabs + date range + search on one row, sort
   on the next. The toolbar itself is the GET form here. */
.store-toolbar--orders { flex-direction: column; align-items: stretch; gap: 0.5rem; }
.store-toolbar__row { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.store-toolbar__right { margin-left: auto; display: flex; align-items: center; gap: 0.4rem; }
.store-toolbar--orders .store-toolbar__search { margin-left: 0.4rem; }
.store-toolbar__date { width: 150px; }
.store-toolbar__sort { width: auto; }
.store-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.store-tab {
  padding: 0.22rem 0.8rem;
  border-radius: var(--r-pill, 999px);
  border: 1px solid var(--line);
  background: var(--surface);
  font-weight: 700;
  font-size: 0.78rem;
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
}
.store-tab:hover { border-color: var(--ink-4); color: var(--ink); }
.store-tab.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.store-tab b { font-weight: 800; opacity: 0.7; margin-left: 0.25rem; }

/* ── Chips (§6 status vocabulary; soft states grey, never danger) ──── */
.store-chip {
  display: inline-block;
  padding: 1px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
  background: var(--bg-2);
  color: var(--ink-3);
  vertical-align: middle;
}
.store-chip--success { background: var(--success-soft); color: var(--success-dark); }
.store-chip--warn    { background: var(--warning-soft); color: var(--warning-dark); }
.store-chip--danger  { background: var(--danger-soft);  color: var(--danger-dark); }
.store-chip--accent  { background: var(--accent-light); color: var(--accent); }

/* ── Table trimmings ───────────────────────────────────────────────── */
.store-thumb {
  width: 32px;
  height: 32px;
  border-radius: var(--r-sm, 6px);
  border: 1px solid var(--line);
  object-fit: cover;
  background: var(--bg-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
  font-size: 0.9rem;
  vertical-align: middle;
}
.store-cell-sub { font-size: 0.75rem; color: var(--ink-3); margin-top: 1px; }
.store-cell-money { text-align: right; white-space: nowrap; }
td.store-cell-money, th.store-cell-money { text-align: right; }

/* ── The store's near-full-screen modal (playoff-editor precedent) ─── */
.store-modal {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(1240px, 96vw);
  height: min(92vh, 1000px);
  overflow: hidden;
  background: var(--bg);
  border-radius: var(--r-lg, 12px);
  box-shadow: var(--shadow-lg);
}
.store-modal__header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 1.25rem;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.store-modal__title { font-size: 1.15rem; font-weight: 700; }
.store-modal__title small { font-weight: 600; color: var(--ink-3); font-size: 0.78rem; margin-left: 0.4rem; }
.store-modal__spacer { flex: 1; }
.store-modal__close {
  background: none;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--ink-3);
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  border-radius: var(--r-sm, 6px);
}
.store-modal__close:hover { background: var(--bg-2); color: var(--ink); }
.store-modal__content { flex: 1; overflow-y: auto; padding: 1.1rem 1.25rem 2rem; }

/* ── Editor cards (mockup card stack + right rail) ─────────────────── */
.store-editor { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 1rem; align-items: start; }
@media (max-width: 1000px) { .store-editor { grid-template-columns: 1fr; } }
.store-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md, 10px); margin-bottom: 0.9rem; }
/* Section headers follow the playoff editor's panel head (.pe-panel__head /
   .pe-panel__title): a grey band with an all-caps label. Interactive
   children inside the head opt back out of the caps treatment. */
.store-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.55rem 0.9rem;
  border-bottom: 1px solid var(--line-2);
  background: var(--surface-2);
  border-radius: var(--r-md, 10px) var(--r-md, 10px) 0 0;
  font-weight: 800;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-2);
}
.store-card__head .store-chip,
.store-card__head .store-hint,
.store-card__head label,
.store-card__head button,
.store-card__head a,
.store-card__head input,
.store-card__head select {
  text-transform: none;
  letter-spacing: 0;
}
.store-card__body { padding: 0.8rem 0.9rem; }
.store-card__rule { border-top: 1px solid var(--line-2); margin: 0.8rem -0.9rem; }
.store-subhead { font-weight: 800; font-size: 0.78rem; margin-bottom: 0.3rem; }
.store-field { margin-bottom: 0.7rem; }
.store-field:last-child { margin-bottom: 0; }
.store-field > label, .store-field__label {
  display: block;
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--ink-2);
  margin-bottom: 3px;
}
.store-hint { font-size: 0.72rem; color: var(--ink-3); margin-top: 3px; }
.store-inline { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.store-money-input { max-width: 130px; }

/* ── Media picker: thumbs + ✕ + a "+ Add" tile ─────────────────────── */
.store-media { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: flex-start; }
.store-media__item { position: relative; }
.store-media__item img {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--r-md, 8px);
  border: 1px solid var(--line);
  display: block;
}
.store-media__remove {
  position: absolute;
  top: -7px;
  right: -7px;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  border: 0;
  background: var(--ink);
  color: var(--surface);
  cursor: pointer;
  font-size: 0.7rem;
  line-height: 1;
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,0.2));
}
/* Removal is immediate in the UI (the thumbnail goes) and staged on the
   server — nothing is purged until Save. There is no "restore" state. */
.store-media__add {
  width: 72px;
  height: 72px;
  border: 1.5px dashed var(--line);
  border-radius: var(--r-md, 8px);
  background: var(--surface);
  color: var(--accent);
  font-weight: 800;
  font-size: 0.78rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  text-align: center;
}
.store-media__add:hover { border-color: var(--accent); background: var(--accent-subtle); }

/* ── On/off switch ─────────────────────────────────────────────────
   The store-namespaced twin of .fe-switch (form editor) — the app's one
   switch shape. Label sits to the RIGHT of the track and reads the current
   state, so a card head says "● On" / "○ Off" without a second control. */
.store-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
}
.store-switch { position: absolute; opacity: 0; width: 1px; height: 1px; }
.store-switch__track {
  width: 26px;
  height: 15px;
  border-radius: 999px;
  background: var(--ink-4);
  position: relative;
  display: inline-block;
  transition: background 0.15s;
  flex-shrink: 0;
}
.store-switch__track::after {
  content: "";
  position: absolute;
  top: 1.5px;
  left: 1.5px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  transition: left 0.15s;
}
.store-switch:checked + .store-switch__track { background: var(--accent); }
.store-switch:checked + .store-switch__track::after { left: 12.5px; }
.store-switch:focus-visible + .store-switch__track { box-shadow: var(--focus-ring); }
/* The state word swaps with the switch — no JS. */
.store-toggle__on, .store-toggle__off { text-transform: none; letter-spacing: 0; }
.store-toggle__on { display: none; }
.store-toggle:has(.store-switch:checked) .store-toggle__on { display: inline; }
.store-toggle:has(.store-switch:checked) .store-toggle__off { display: none; }

/* ── Segmented radio group (status) ────────────────────────────────
   The app's .segmented shell driven by real radios, so it submits without
   JS and keeps keyboard semantics. */
.store-segmented .segmented__btn { position: relative; font-size: 0.78rem; padding: 0.28rem 0.7rem; }
.store-segmented input[type="radio"] { position: absolute; opacity: 0; width: 1px; height: 1px; }
.store-segmented .segmented__btn:has(input:checked) {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}

/* ── Storefront URL (auto-generated, editable) ─────────────────────── */
.store-slug { font-family: var(--mono, ui-monospace, monospace); font-size: 0.76rem; color: var(--ink-3); }
.store-slug__value { color: var(--ink); font-weight: 700; word-break: break-all; }
.store-slug__status { font-size: 0.72rem; font-weight: 700; margin-top: 0.3rem; }
.store-slug__status--ok { color: var(--success-dark, #047857); }
.store-slug__status--bad { color: var(--danger-dark, #b91c1c); }

/* ── Option builder + variant table (§8) ───────────────────────────── */
.store-options__row { display: flex; align-items: flex-start; gap: 0.5rem; margin-bottom: 0.5rem; }
.store-options__name { flex: 0 0 140px; }
.store-options__values {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  padding: 4px 6px;
  background: var(--surface);
}
.store-options__values input {
  border: 0;
  outline: none;
  min-width: 70px;
  flex: 1;
  font-size: 0.85rem;
  background: transparent;
  color: var(--ink);
}
.store-value-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1.5px solid var(--accent);
  color: var(--accent);
  background: var(--accent-light);
  border-radius: 999px;
  padding: 0 8px;
  font-size: 0.75rem;
  font-weight: 700;
}
.store-value-chip button {
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  font-size: 0.8rem;
  padding: 0;
  line-height: 1;
}
.store-variant-table td input { max-width: 110px; }
.store-variant-table .is-inactive td { color: var(--ink-3); }
.store-variant-group td {
  background: var(--surface-2);
  font-weight: 700;
}

/* ── The order modal (§11 D-O1): near-full-screen, 3 columns that fill
   the height; cards grow and scroll internally; stacks below ~1100px. ── */
.store-order-modal { width: min(1560px, 97vw); height: min(92vh, 1040px); }
.store-order-modal .store-modal__content { display: flex; flex-direction: column; padding-bottom: 0.75rem; }
/* Active | Archived in the header: the app's segmented control, one size
   down to sit on the 48px bar. */
.store-order-modal__seg .segmented__btn { padding: 0.2rem 0.75rem; font-size: 0.8rem; text-decoration: none; }
/* Item thumbnails in the Items card (Kyle, 2026-09-03). */
.store-order-thumb-cell { width: 52px; padding-right: 0 !important; }
.store-order-thumb {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  border: 1px solid var(--line);
  object-fit: cover;
  display: block;
  background: var(--bg-2);
}
.store-order-thumb--empty { display: flex; align-items: center; justify-content: center; font-size: 1.1rem; }
/* Header block (Kyle, 2026-09-03): title + stage chips, then buyer · email
   · team, then the placed date; the toggle and close hang off the top. */
.store-order-modal__header { align-items: flex-start; }
.store-order-modal__titleblock { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.store-order-modal__header .store-modal__spacer + .segmented,
.store-order-modal__header .store-modal__close { margin-top: 0.15rem; }
.store-order-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.84rem;
  color: var(--ink-2);
}
/* Cards are as tall as their contents (Kyle, 2026-09-03) — no stretching
   to fill the column; a long order scrolls the columns area instead. */
.store-order-cols {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1.1fr 1fr 1.1fr;
  gap: 0.9rem;
  align-items: start;
  overflow-y: auto;
}
.store-order-col { display: flex; flex-direction: column; gap: 0.9rem; }
.store-order-col .store-card { margin-bottom: 0; }
@media (max-width: 1100px) {
  .store-order-modal { height: min(94vh, 1200px); }
  .store-order-cols { grid-template-columns: 1fr; }
}
.store-modal__footer {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 1.25rem;
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.store-stage {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 10px;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 800;
  background: var(--bg-2);
  color: var(--ink-3);
}
.store-stage--good { background: var(--success-soft); color: var(--success-dark); }
.store-stage--warn { background: var(--warning-soft); color: var(--warning-dark); }
.store-stage--accent { background: var(--accent-light); color: var(--accent); }
.store-stage--danger { background: var(--danger-soft); color: var(--danger-dark); }
.store-seg { display: inline-flex; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }
.store-seg > * {
  padding: 0.15rem 0.7rem;
  font-size: 0.74rem;
  font-weight: 700;
  color: var(--ink-3);
  background: var(--surface);
  border: 0;
  cursor: pointer;
  text-decoration: none;
}
.store-seg > .is-on { background: var(--accent); color: #fff; cursor: default; }
/* The theme segment switches off while the preview frame shows the LIVE
   store, which follows each buyer's own theme (Kyle, 2026-09-02). */
.store-seg > :disabled { opacity: 0.45; cursor: not-allowed; }
.store-seg > .is-on:disabled { background: var(--ink-4, #9ca3af); }
.store-sum { display: flex; justify-content: space-between; padding: 0.12rem 0; font-size: 0.86rem; color: var(--ink-2); }
.store-sum--total { font-weight: 800; color: var(--ink); border-top: 1px solid var(--line); margin-top: 0.25rem; padding-top: 0.3rem; }
.store-activity { font-size: 0.8rem; color: var(--ink-2); }
.store-activity div { padding: 0.15rem 0; }
.store-activity span { color: var(--ink-3); margin-right: 6px; white-space: nowrap; }
.store-dialog {
  /* Centred on screen (Kyle, 2026-09-03): the global reset zeroes margins,
     which stranded the dialog top-left; the UA centring is margin: auto. */
  position: fixed;
  inset: 0;
  margin: auto;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 0;
  max-width: 460px;
  width: 92vw;
  max-height: 92vh;
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-lg);
}
.store-dialog::backdrop { background: rgba(17, 24, 39, 0.4); }
.store-dialog--email { max-width: 620px; }
.store-dialog__form { display: flex; flex-direction: column; max-height: 92vh; }
.store-dialog__form .store-card__body { overflow-y: auto; }
.store-dialog__footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.7rem 1rem;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
.store-dialog__email {
  display: block;
  width: 100%;
  height: 300px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  margin: 0.2rem 0 0.6rem;
}
.store-dialog .store-toggle-row { margin-top: 0.2rem; }
/* The email preview only shows while the send switch is on (Kyle,
   2026-09-03): off means no email, so there is nothing to preview. */
.store-dialog__preview { margin-top: 0.6rem; }
.store-dialog__form:has(.store-switch:not(:checked)) .store-dialog__preview { display: none; }

/* ── Print pages (pickup slip / list) ──────────────────────────────── */
.store-print { max-width: 720px; margin: 0 auto; padding: 1.5rem; font-family: -apple-system, sans-serif; color: #111; }
.store-print h1 { font-size: 1.2rem; margin-bottom: 0.2rem; }
.store-print table { width: 100%; border-collapse: collapse; margin: 0.6rem 0; }
.store-print th, .store-print td { text-align: left; padding: 4px 6px; border-bottom: 1px solid #ddd; font-size: 0.9rem; }
.store-print .muted { color: #666; font-size: 0.85rem; }
@media print { .store-print__noprint { display: none; } }

/* ── The Storefront design editor (§16): rail + live preview ───────── */
.store-editor-shell { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 0.9rem; align-items: start; }
@media (max-width: 1000px) { .store-editor-shell { grid-template-columns: 1fr; } }
.store-editor-rail { min-width: 0; }
.store-editor-preview { min-width: 0; }
.store-editor-frame-wrap {
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-2);
  height: min(72vh, 900px);
  display: flex;
  /* Desktop: the frame is a wide box scaled from its top-left corner, so it
     must START at the wrapper's corner — centring would place the unscaled
     1280px box and leave the visible result off to one side. Mobile is 1:1
     and centres. (See fitFrame in store_editor_controller.) */
  justify-content: flex-start;
  align-items: flex-start;
}
.store-editor-frame-wrap.is-mobile { justify-content: center; }
.store-editor-frame-wrap iframe {
  width: 100%;
  height: 100%;
  border: 0;
  background: #fff;
  transform-origin: top left;
  /* flex-shrink: 0 is load-bearing. As a shrinkable flex item the 1280px
     desktop frame was squeezed back down to the panel's width, so it laid
     out at a MOBILE viewport and was then scaled down again on top of that
     — a small, narrow render in the corner (Kyle, 2026-09-02). */
  flex: none;
}
.store-editor-frame-wrap.is-mobile iframe { width: 390px; }
.store-ed-group {
  font-size: 0.7rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  margin: 0.5rem 0 0.2rem;
}
.store-ed-item {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  text-align: left;
  padding: 0.32rem 0.5rem;
  border: 0;
  background: none;
  border-radius: 7px;
  color: var(--ink-2);
  font-weight: 600;
  font-size: 0.84rem;
  cursor: pointer;
}
.store-ed-item:hover { background: var(--surface-2); color: var(--ink); }
.store-ed-item.is-on { background: var(--accent-subtle); color: var(--accent); }
.store-ed-item .store-ed-warn { color: var(--warning); font-weight: 900; }
.store-ed-item .store-ed-drag { cursor: grab; color: var(--ink-4); }
.store-ed-add {
  display: block;
  padding: 0.3rem 0.5rem;
  color: var(--accent);
  font-weight: 700;
  font-size: 0.82rem;
  background: none;
  border: 0;
  cursor: pointer;
}
.store-ed-swatches { display: flex; gap: 0.5rem; margin-top: 0.4rem; }
.store-ed-swatch {
  flex: 1;
  border-radius: 8px;
  padding: 0.4rem 0.5rem;
  font-size: 0.72rem;
  font-weight: 700;
  border: 1px solid var(--line);
}

/* ── Settings inline tables & template cards ───────────────────────── */
.store-settings-table td { vertical-align: middle; }
.store-settings-table input[type="text"] { width: 100%; }
.store-settings-table .num-input { max-width: 90px; }
.store-template-card textarea { min-height: 70px; width: 100%; }

/* ── Line amounts (Kyle 2026-09-01) ────────────────────────────────
   A discounted line shows all three figures; the summary's Subtotal stays
   pre-discount so the two reconcile. Undiscounted lines render one figure
   and none of these classes appear. */
.store-amount__was { color: var(--ink-4); font-weight: 500; }
.store-amount__off { color: var(--danger-dark, #b91c1c); font-weight: 600; font-size: 0.78rem; }
.store-amount__net { font-weight: 700; }

/* ── Label-left / switch-right rows (Kyle 2026-09-01) ──────────────── */
.store-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.18rem 0;
}
.store-toggle-row__label { font-size: 0.82rem; font-weight: 600; color: var(--ink); }
.store-toggle-row .store-toggle { flex-shrink: 0; }

/* The buyer-facing rendering of a sale, shown live under the entry field. */
.store-sale-preview {
  margin-top: 0.4rem;
  font-size: 0.86rem;
  min-height: 1.1rem;
}
.store-sale-preview s { color: var(--ink-4); font-weight: 500; margin-right: 0.35rem; }
.store-sale-preview b { font-weight: 800; }
.store-sale-preview span { color: var(--danger-dark, #b91c1c); font-weight: 600; margin-left: 0.3rem; }

/* Status segments carry their meaning: draft amber, active green, archived
   grey (the §6 soft-state rule — never danger red). */
.store-segmented--status .segmented__btn:has(input:checked).store-status-opt--draft {
  background: var(--warning-soft); color: var(--warning-dark);
}
.store-segmented--status .segmented__btn:has(input:checked).store-status-opt--active {
  background: var(--success-soft); color: var(--success-dark);
}
.store-segmented--status .segmented__btn:has(input:checked).store-status-opt--archived {
  background: var(--bg-2); color: var(--ink-2);
}

/* The option-name field offers suggestions via <datalist>, but it is a free
   text field — Chrome's picker triangle made it read as a select. */
.store-options__name::-webkit-calendar-picker-indicator { display: none !important; }
.store-options__name { appearance: none; }

/* ── Inventory table (Kyle 2026-09-01) ─────────────────────────────
   Every column but the product/variant name centres; the On-hand column
   swaps between a number and a field in place, so they share a width. */
/* `.data-table thead th` sets text-align:left at (0,1,2), so a bare
   `th.store-cell-center` at (0,1,1) lost the cascade — match its weight. */
.store-cell-center { text-align: center; }
th.store-cell-center, td.store-cell-center,
.data-table thead th.store-cell-center,
.data-table tbody td.store-cell-center { text-align: center; }
.store-inventory-table .store-count-input {
  width: 68px;
  padding: 0.2rem 0.4rem;
  text-align: center;
  margin: 0 auto;
}

/* Draggable media tiles + option-value chips (Kyle 2026-09-01). */
.store-media__item { cursor: grab; }
.store-media__item:active { cursor: grabbing; }
.store-value-chip { cursor: grab; }
/* display:block so the auto margins actually centre the field. */
.store-variant-table td.store-cell-center .form-input,
.store-inventory-table td.store-cell-center .form-input {
  display: block;
  margin: 0 auto;
  text-align: center;
}

/* ── Storefront editor: nav link rows + the two-level target picker ──
   (Kyle 2026-09-01 — the browser prompt is gone.) */
.store-ed-links { margin-top: 0.4rem; }
.store-ed-link {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0;
}
.store-ed-link .form-input { min-width: 0; flex: 1; }
.store-ed-link .store-ed-drag { cursor: grab; color: var(--ink-4); }

.store-picker { position: relative; flex: 1.2; min-width: 0; }
.store-picker__button {
  width: 100%;
  text-align: left;
  padding: 0.42rem 0.6rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.store-picker__button:hover { border-color: var(--ink-4); }
.store-picker__menu {
  display: none;
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  z-index: 60;
  min-width: 180px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md, 10px);
  box-shadow: var(--shadow-lg);
  padding: 4px;
}
.store-picker.is-open .store-picker__menu { display: block; }
/* Near the foot of the page a dropped menu ran off the bottom of the
   window; is-up (set by flipIfClipped) drops it upward instead — the first
   layer above its button, the second layer above its own row (Kyle,
   2026-09-02). */
.store-picker.is-up .store-picker__menu { top: auto; bottom: calc(100% + 2px); }
.store-picker__group { position: relative; }
.store-picker__head {
  display: block;
  padding: 0.35rem 0.55rem;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--ink-2);
  border-radius: 6px;
  cursor: default;
}
.store-picker__group:hover > .store-picker__head { background: var(--bg-2); color: var(--ink); }
.store-picker__sub {
  display: none;
  position: absolute;
  top: 0;
  left: 100%;
  min-width: 190px;
  max-height: 260px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md, 10px);
  box-shadow: var(--shadow-lg);
  padding: 4px;
}
.store-picker__group:hover > .store-picker__sub { display: block; }
.store-picker__group.is-up > .store-picker__sub { top: auto; bottom: 0; }
.store-picker__option {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.32rem 0.55rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink-2);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
.store-picker__option:hover { background: var(--accent-subtle); color: var(--accent); }

/* A preview that failed validation is showing the LAST GOOD render — mark
   it, so it can never be mistaken for the current config. */
.store-editor-frame-wrap.is-stale { opacity: 0.45; outline: 2px dashed var(--warning-dark, #92400e); }
.store-hint--error { color: var(--danger-dark, #b91c1c); font-weight: 600; }

/* ── The shared product picker (Kyle 2026-09-01) ────────────────────
   Source rail · search · results · selection tray — the arrangement staff
   already know from other commerce tools, so nothing has to be learned. */
.store-picker-modal { width: min(920px, 94vw); height: min(80vh, 760px); }
.store-picker-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
}
.store-picker-rail {
  border-right: 1px solid var(--line);
  background: var(--surface-2);
  padding: 0.6rem 0.5rem;
  overflow-y: auto;
}
.store-picker-rail__title {
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-3);
  padding: 0.7rem 0.5rem 0.3rem;
}
.store-picker-rail__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 0.35rem 0.55rem;
  border-radius: 8px;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ink-2);
  text-decoration: none;
}
.store-picker-rail__link:hover { background: var(--bg-2); color: var(--ink); }
.store-picker-rail__link.is-on { background: var(--accent-subtle); color: var(--accent); }
.store-picker-rail__count { font-size: 0.72rem; color: var(--ink-4); }

.store-picker-results { display: flex; flex-direction: column; min-height: 0; background: var(--surface); }
.store-picker-search { padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--line); }
.store-picker-list { flex: 1; overflow-y: auto; padding: 0.4rem 0.5rem 0.8rem; }
.store-picker-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.5rem;
  border-radius: 10px;
  cursor: pointer;
}
.store-picker-row:hover { background: var(--bg-2); }
.store-picker-row__main { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.store-picker-row__title { font-weight: 700; font-size: 0.88rem; }
.store-picker-row .store-thumb { width: 40px; height: 40px; }

.store-picker-tray { display: flex; flex-wrap: wrap; gap: 4px; flex: 1; min-width: 0; max-height: 56px; overflow-y: auto; }
.store-chip__x { border: 0; background: none; color: inherit; cursor: pointer; padding: 0 0 0 4px; font-weight: 800; }

/* The status segment fills its card (Kyle 2026-09-02) — a three-way choice
   reads better spanning the rail than hugging the left edge. */
.store-segmented--status { display: flex; width: 100%; }
.store-segmented--status .segmented__btn { flex: 1; justify-content: center; }

/* ── Tag field: chips for what's chosen, type-to-find for the rest ──── */
.store-tagfield { position: relative; }
.store-tagfield__menu {
  position: absolute;
  top: calc(100% + 3px);
  left: 0;
  right: 0;
  z-index: 60;
  max-height: 220px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md, 10px);
  box-shadow: var(--shadow-lg);
  padding: 4px;
}
.store-tagfield__option {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.34rem 0.55rem;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ink-2);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
.store-tagfield__option:hover { background: var(--accent-subtle); color: var(--accent); }
.store-tagfield__chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 0.45rem; }
.store-tagfield__chips:empty { margin-top: 0; }

/* ── Products list: row selection + the shared bulk bar ────────────── */
.store-select-col { width: 34px; text-align: center; }
.store-row--selected { background: var(--accent-subtle); }

/* Both store editor modals now share one shell (Kyle 2026-09-02): header
   with the identity, a grey body whose sections read as cards, and a footer
   carrying Cancel / Save like the rest of the app. */
.store-modal__footer--actions { justify-content: flex-end; }
.store-modal--md { width: min(900px, 94vw); height: min(84vh, 860px); }

/* ── Product search results (Kyle 2026-09-02) ───────────────────────
   An overlay list on the app's own type scale, with a branded checkbox and
   a thumbnail — not a stack of browser defaults. */
.store-pickerlist { padding: 4px; max-height: 300px; }
.store-pickerlist__row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.3rem 0.45rem;
  border-radius: 8px;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}
.store-pickerlist__row:hover { background: var(--bg-2); }
.store-pickerlist__row .store-thumb { width: 28px; height: 28px; font-size: 0.8rem; }
.store-pickerlist__title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The app's checkbox: the native input drives state, the box draws it. */
.store-check { position: absolute; opacity: 0; width: 1px; height: 1px; }
.store-check__box {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border: 1.5px solid var(--ink-4);
  border-radius: 4px;
  background: var(--surface);
  position: relative;
  transition: background 0.12s, border-color 0.12s;
}
.store-check__box::after {
  content: "";
  position: absolute;
  left: 4.5px;
  top: 1px;
  width: 4px;
  height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 0.12s;
}
.store-check:checked + .store-check__box { background: var(--accent); border-color: var(--accent); }
.store-check:checked + .store-check__box::after { transform: rotate(45deg) scale(1); }
.store-check:focus-visible + .store-check__box { box-shadow: var(--focus-ring); }

/* "+ Add section" uses the app's own dropdown (Kyle 2026-09-02); it just
   needs to sit as a block in the rail and open leftward under its trigger. */
.store-ed-adddrop { display: block; }
.store-ed-adddrop .action-menu { left: 0; right: auto; min-width: 180px; }

/* ── Preview header (Kyle 2026-09-02) ───────────────────────────────
   The width/theme toggles and Save belong to the preview, so they sit in
   its own header rather than floating above the page. */
.store-editor-preview {
  border: 1px solid var(--line);
  border-radius: var(--r-md, 10px);
  background: var(--surface);
  overflow: hidden;
}
.store-preview-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.store-preview-bar__spacer { margin-left: auto; }
.store-preview-bar .btn[disabled] {
  background: var(--bg-2);
  color: var(--ink-4);
  border-color: var(--line);
  cursor: default;
  box-shadow: none;
}
/* The frame already sits inside the bordered panel. */
.store-editor-preview .store-editor-frame-wrap { border: 0; border-radius: 0; }

/* ── Branding form (Kyle 2026-09-02) ────────────────────────────────
   One logo, a header background, a title, and an accent per theme. The
   logo previews on the picked header background — the only ground it is
   ever seen on. */
.store-logo-preview {
  max-width: 150px;
  max-height: 44px;
  object-fit: contain;
  display: block;
  margin: 0.3rem 0 0.4rem;
  border-radius: 6px;
}
.store-logo-preview--on-header { padding: 6px 8px; max-height: 56px; }

/* ── Section images + the crop modal (Kyle 2026-09-03) ──────────────
   The hero / image-banner picture shows in its form, then Replace / Crop /
   Remove. The modal is the app's generic panel with Cropper.js inside; the
   picture area is capped so a tall upload never pushes the buttons off
   screen. Cropper's own stylesheet is loaded on first open. */
.store-section-image {
  display: block;
  width: 100%;
  height: auto;
  max-height: 180px;
  object-fit: contain;
  object-position: left center;
  margin-top: 0.3rem;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--bg-2);
}
/* Group titles inside one section's form (Overlay / Media). */
.store-ed-subhead {
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0.9rem 0 0.1rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--line-2, var(--line));
}
.store-ed-subhead:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.store-ed-position { gap: 0.5rem; margin-top: 0.3rem; }
.store-ed-range { gap: 0.6rem; margin-top: 0.3rem; }
.store-ed-range input[type="range"] { flex: 1; min-width: 0; }
.store-ed-range .store-hint { margin: 0; min-width: 2.6em; font-variant-numeric: tabular-nums; }
/* The banner's pictures: the product modal's Media grid, plus a hover
   Crop over each thumbnail. Dead references show as a labelled blank. */
.store-ed-media { margin-top: 0.4rem; }
.store-ed-media .store-media__item img { width: 84px; height: 56px; }
.store-ed-media__crop {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-md, 8px);
  background: rgba(17, 24, 39, 0.55);
  color: #fff;
  font-weight: 700;
  font-size: 0.76rem;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s;
}
.store-ed-media .store-media__item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-md, 8px); }
.store-ed-media .store-media__item:hover .store-ed-media__crop,
.store-ed-media .store-media__item:focus-visible .store-ed-media__crop { opacity: 1; }
.store-ed-media .store-media__item.sortable-chosen .store-ed-media__crop { opacity: 0; }
.store-ed-media__gone {
  width: 84px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-md, 8px);
  border: 1px dashed var(--danger);
  color: var(--danger-dark);
  font-size: 0.72rem;
  font-weight: 700;
}
.store-ed-media .store-media__add { width: 84px; height: 56px; }
.store-crop .modal__body { display: flex; flex-direction: column; gap: 0.6rem; }
.store-crop__ratios { display: flex; align-items: center; gap: 0.6rem; }
.store-crop__ratios-label { font-size: 0.78rem; font-weight: 600; color: var(--ink-3); }
.store-crop__area {
  background: #1a1a1a;
  border-radius: var(--r-md);
  overflow: hidden;
  /* The panel is capped at 92vh; this leaves the header, presets and
     footer their room on a laptop screen. */
  max-height: min(62vh, 640px);
}
.store-crop__area img { display: block; max-width: 100%; }
.store-crop__hint { margin: 0; text-align: center; }
.store-crop__footer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
  border-top: 1px solid var(--line);
}
.store-crop__footer-spacer { flex: 1; }
.store-header-bg-row { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.3rem; }
.store-header-bg-row input[type="color"] { height: 34px; padding: 2px; width: 72px; flex-shrink: 0; }
.store-header-bg-row .store-hint { margin: 0; font-variant-numeric: tabular-nums; }
.store-accent-row { display: flex; gap: 0.5rem; margin-top: 0.3rem; }
.store-accent-slot { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.store-accent-slot span {
  font-size: 0.7rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-3);
}
.store-accent-slot input[type="color"] { height: 34px; padding: 2px; width: 100%; }
