/* The Online Store engine (src/examples/ex-store.js): catalogue, product, cart, demo
   checkout, the customer's order and the staff's order list. Every colour, radius and
   display face is the business's own (--x-* on main#main), so the same rules dress any
   shop, whatever it sells. Phone first; wider screens add columns, never a different
   page. No amount of money is laid out anywhere. */

/* ---- shared pieces -------------------------------------------------------------------- */
.xs-kicker { color: var(--x-muted); font-size: .8125rem; font-weight: 700; letter-spacing: var(--x-caps-track); text-transform: var(--x-caps); }
.xs-lead { max-width: 44rem; font-size: 1.0625rem; }
.xs-fine { max-width: 56rem; }
.xs-sum { color: var(--x-muted); }
.xs-plain { display: grid; gap: 4px; padding-inline-start: 1.25em; list-style: disc; }
.xs-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.xs-tags .x-pill { white-space: normal; }
.xs-st { white-space: nowrap; }
/* A status keeps to one line, except where a line is too short for its words: the smallest phones at a larger text size. */
@media (max-width: 19.99em) { .xs-st { white-space: normal; } }
.xs-bar-n { font-weight: 600; }
.xs-ways h2, .xs-set h2, .xs-notes h2, .xs-detail h2, .xs-block h2, .xs-switches h2, .xs-aside h2 { font-size: 1.125rem; }
.xs-shop, .xs-product { display: grid; align-content: start; gap: clamp(18px, 3vw, 28px); }
.xs-shop > *, .xs-product > * { min-width: 0; }
/* A list of facts whose labels were given a width of their own (the terms of a guide, a specification) gives that
   width up where the row is narrower than it, as on a small phone with the text size doubled: the label takes the
   whole row, its value goes under it, and nothing runs off the side. */
.xs-frame .x-fact dt { max-width: 100%; }

/* The number in the cart button, and the step an order has just reached, move once when they change
   (the engine asks for that movement; it is opacity and scale only, so each needs a box of its own). */
.xs-n { display: inline-block; }

/* Where the header shows its own cart button, the bar at the foot of the screen would only say it twice. */
@media (min-width: 30em) { .xs-bar--narrow { display: none; } }

/* Two columns from a small laptop up: the thing being worked on, and what it is about beside it. */
.xs-cols { display: grid; align-items: start; gap: 20px clamp(24px, 4vw, 56px); }
.xs-cols > * { min-width: 0; }
.xs-aside { display: none; }
@media (min-width: 64em) {
  .xs-cart .xs-cols { grid-template-columns: minmax(0, 7fr) minmax(17rem, 4fr); }
  .xs-checkout--cols > .xs-cols, .xs-review > .xs-cols { grid-template-columns: minmax(0, 44rem) minmax(17rem, 22rem); justify-content: space-between; }
  .xs-checkout--cols .xs-aside, .xs-review-act { display: grid; gap: 14px; padding: clamp(14px, 2vw, 20px); border: 1px solid var(--x-hair); border-radius: var(--x-radius, 8px); background: var(--x-surface); }
  .xs-checkout--cols .xs-aside { gap: 10px; }
  .xs-checkout--cols > .xs-sum { display: none; }
}

/* ---- the catalogue ---------------------------------------------------------------------- */
.xs-hero { display: grid; align-items: center; gap: 16px clamp(24px, 4vw, 56px); }
.xs-hero-text { display: grid; gap: 10px; }
.xs-hero-media { overflow: hidden; border-radius: var(--x-radius, 8px); }
.xs-hero-media .x-img { max-height: 168px; }
.xs-tools { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px 36px; padding-block: 16px; border-block: 1px solid var(--x-hair); }
.xs-tools > .x-filter:first-child { flex: 1 1 100%; }
.xs-tools > .x-search { flex: 1 1 17rem; }
.xs-result { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 16px; min-height: 44px; }
.xs-grid { --x-min: 232px; --x-gap: clamp(14px, 2vw, 22px); }
.xs-card-sum { font-size: .9375rem; }
.xs-card .xs-tags { margin-top: 2px; }
/* A phone shows the list as rows: the photograph beside the words, so more of the shop fits a screen. */
@media (min-width: 340px) and (max-width: 519px) {
  .xs-card { flex-direction: row; }
  .xs-card .x-card-media { flex: 0 0 34%; border-radius: calc(var(--x-radius, 8px) - 1px) 0 0 calc(var(--x-radius, 8px) - 1px); }
  .xs-card .x-card-media .x-img { height: 100%; min-height: 120px; aspect-ratio: auto !important; }
  .xs-card .x-card-body { min-width: 0; padding: 12px 14px 14px; }
}
@media (min-width: 760px) {
  .xs-hero { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .xs-hero-media .x-img { max-height: 280px; }
}

/* ---- one product ---------------------------------------------------------------------------- */
.xs-pd { display: grid; align-items: start; gap: 20px clamp(24px, 4vw, 56px); }
.xs-pd-media { display: grid; gap: 10px; }
.xs-pd-media > .x-img { border-radius: var(--x-radius, 8px); }
/* An upright photograph is not given the whole width of a phone: the name and the choices stay near. */
.xs-pd-media[data-tall] > .x-img { width: min(100%, 18rem); margin-inline: auto; }
.xs-thumbs { display: flex; flex-wrap: wrap; gap: 8px; }
.xs-thumb { width: 64px; padding: 0; overflow: hidden; border: 2px solid transparent; border-radius: var(--x-radius, 8px); background: none; }
.xs-thumb .x-img { width: 100%; }
.xs-thumb[aria-pressed="true"] { border-color: var(--x-ink); }
.xs-pd-main { display: grid; align-content: start; gap: 14px; min-width: 0; }
.xs-desc { max-width: 40rem; }
.xs-buy { display: grid; gap: 14px; padding: clamp(14px, 3vw, 20px); border: 1px solid var(--x-hair); border-radius: var(--x-radius, 8px); background: var(--x-surface); }
.xs-opt .x-chip-face { min-height: 40px; border-radius: var(--x-radius, 8px); }
.xs-opt-out { font-weight: 400; }
.xs-opt-beside { margin-top: -8px; font-size: .9375rem; }
.xs-swatch { width: 14px; height: 14px; border-radius: 50%; box-shadow: inset 0 0 0 1px var(--x-line); }
.xs-vnote, .xs-pack { font-size: .9375rem; }
.xs-vnote { color: var(--x-muted); }
.xs-why { display: flex; gap: 10px; padding: 12px 14px; border-radius: var(--x-radius, 8px); background: var(--x-warn-soft); }
.xs-why > .x-i { margin-top: .28em; color: var(--x-warn); }
.xs-why > div { display: grid; gap: 4px; min-width: 0; }
.xs-why-near { display: grid; gap: 6px; padding-top: 4px; }
.xs-why-near .x-row { --x-gap: 8px; }
.xs-why-near .x-btn { min-width: 44px; background: var(--x-surface); }
/* Nothing is wrong yet: a choice is simply still to be made. */
.xs-why--hint { background: var(--x-surface-2); }
.xs-why--hint > .x-i { color: var(--x-muted); }
.xs-buy-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.xs-add { flex: 1 1 12rem; }
.xs-ways, .xs-set { display: grid; gap: 8px; }
.xs-way { display: flex; gap: 10px; padding: 10px 0; border-top: 1px solid var(--x-hair); }
.xs-way > .x-i { margin-top: .3em; color: var(--x-ok); }
.xs-way--no > .x-i { color: var(--x-warn); }
.xs-way strong { font-weight: 600; }
.xs-set-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; min-height: 44px; padding-block: 6px; border-top: 1px solid var(--x-hair); }
.xs-set-list li > :first-child { font-weight: 600; }
.xs-details { display: grid; gap: 20px clamp(24px, 4vw, 48px); grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); padding-top: clamp(18px, 3vw, 28px); border-top: 1px solid var(--x-hair); }
.xs-detail { display: grid; align-content: start; gap: 6px; min-width: 0; }
.xs-detail--wide { grid-column: 1 / -1; }
.xs-detail-list { display: grid; gap: 4px; padding-inline-start: 1.25em; list-style: disc; }
@media (min-width: 860px) {
  .xs-pd { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
  .xs-pd-media[data-tall] > .x-img { width: 100%; }
}

/* ---- the cart ---------------------------------------------------------------------------------- */
.xs-lines, .xs-cart .xs-ways { max-width: 52rem; }
.xs-lines { border-bottom: 1px solid var(--x-hair); }
.xs-line { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 12px 16px; padding: 16px 0; border-top: 1px solid var(--x-hair); }
.xs-line-img .x-img { width: 72px; border-radius: var(--x-radius, 8px); }
.xs-line--out .xs-line-img { opacity: .6; }
.xs-line-main { display: grid; align-content: start; gap: 6px; min-width: 0; }
.xs-line-name { font: 600 1.0625rem/var(--x-lh-label) var(--x-text); }
.xs-line-opt { color: var(--x-muted); }
.xs-line-msg { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; color: var(--x-danger); font-size: .9375rem; }
.xs-line-vars { display: flex; flex-wrap: wrap; gap: 10px 14px; }
.xs-line-var { flex: 1 1 9rem; max-width: 20rem; }
.xs-line-act { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.xs-cols-side { display: grid; gap: 14px; }
@media (min-width: 700px) {
  .xs-line { grid-template-columns: 96px minmax(0, 1fr) auto; }
  .xs-line-img .x-img { width: 96px; }
  .xs-line-act { grid-column: auto; flex-direction: column; align-items: flex-end; justify-content: flex-start; }
}

/* ---- the demo checkout ---------------------------------------------------------------------------- */
/* A box for several lines of text that takes focus at the foot of the screen is otherwise scrolled only until
   its first line shows: this keeps the whole of it, and the button after it, in view. */
html:has(.xs-frame textarea) { scroll-padding-bottom: 10rem; }
.xs-checkout .x-form, .xs-summary, .xs-track, .xs-orders, .xs-related, .xs-review-act { max-width: 44rem; }
.xs-review-act { display: grid; gap: 14px; }
.xs-modes > legend, .xs-windows > legend { margin-bottom: 8px; }
.xs-modes:focus { outline: none; }
.xs-mode { display: flex; align-items: flex-start; gap: 12px; min-height: 44px; padding: 14px 16px; border: 1px solid var(--x-line); border-radius: var(--x-radius, 8px); background: var(--x-surface); cursor: pointer; }
.xs-mode + .xs-mode { margin-top: 10px; }
.xs-mode input, .xs-win input { flex: none; width: 22px; height: 22px; }
.xs-mode input { margin-top: 2px; }
.xs-mode--on, .xs-win:has(input:checked) { border-color: var(--x-ink); box-shadow: inset 0 0 0 1px var(--x-ink); }
.xs-mode-text { display: grid; gap: 2px; }
.xs-mode-warn { color: var(--x-warn); font-weight: 600; }
.xs-fixes { display: grid; gap: 10px; }
.xs-fixes li { display: grid; justify-items: start; gap: 6px; }
.xs-day { padding-top: 12px; }
.xs-day-name { margin-bottom: 6px; font-weight: 600; }
.xs-day-wins { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.xs-win { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 8px 14px; border: 1px solid var(--x-line); border-radius: var(--x-radius, 8px); background: var(--x-surface); cursor: pointer; }
.xs-win--no { border-style: dashed; background: none; color: var(--x-muted); cursor: default; }
.xs-win-time { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.xs-place { display: grid; gap: 18px; }
.xs-notes { display: grid; gap: 8px; padding: 14px 16px; border-radius: var(--x-radius, 8px); background: var(--x-surface-2); }

/* ---- an order in words: the review, the customer's page, the staff's sheet --------------------------- */
.xs-summary { border-bottom: 1px solid var(--x-hair); }
.xs-block { display: grid; gap: 6px; padding: 12px 0 14px; border-top: 1px solid var(--x-hair); }
.xs-block-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 12px; min-height: 44px; }
.xs-block .x-fact:first-child { padding-top: 0; border-top: 0; }
/* What a customer typed can be one long word: an e-mail address, a note with no spaces. In an order's summary it
   breaks where it must, so the review, the order page and the staff's sheet are never wider than their screen. */
.xs-summary .x-fact dd, .xs-summary .xs-items li { overflow-wrap: anywhere; }
.xs-items { display: grid; gap: 4px; }
.xs-items-q { font-weight: 600; font-variant-numeric: tabular-nums; }
.xs-items-o { color: var(--x-muted); }
.xs-status { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: 1.0625rem; }
.xs-track-step { display: flex; align-items: center; gap: 12px; min-height: 40px; color: var(--x-muted); }
.xs-track-dot { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border: 1px solid var(--x-line); border-radius: 50%; font-size: .8125rem; font-weight: 700; }
.xs-track-step--done, .xs-track-step--now { color: var(--x-ink); }
.xs-track-step--done .xs-track-dot { border-color: var(--x-ink); }
.xs-track-step--now { font-weight: 700; }
.xs-track-step--now .xs-track-dot { border-color: transparent; background: var(--x-accent); color: var(--x-on-accent); }
.xs-orders-item { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; min-height: 56px; padding: 10px 0; border-top: 1px solid var(--x-hair); }
.xs-related { display: grid; gap: 6px; padding-top: 14px; border-top: 1px solid var(--x-hair); }
@media (min-width: 640px) {
  .xs-track { display: flex; flex-wrap: wrap; gap: 4px 8px; }
  .xs-track-step + .xs-track-step::before { content: ""; width: clamp(14px, 3vw, 40px); height: 1px; background: var(--x-line); }
}

/* ---- the staff's list -------------------------------------------------------------------------------- */
.xs-recv-when { display: block; }
.xs-kept { display: block; margin-top: 4px; }
.xs-moves { --x-gap: 8px; }
/* A time and a button's words each keep to one line wherever a line has room for them: everywhere but the smallest phones. */
@media (min-width: 30em) { .xs-nb, .xs-moves .x-btn { white-space: nowrap; } }
.xs-ask { display: grid; gap: 8px; }
.xs-ask > p { font-weight: 600; }
/* A reference is one word, on a desk and on the counter's tablet alike. It is a link 44 px high that takes its
   own room in the cell, so it is never half out of view when focus reaches it. */
.xs-staff .x-table tbody th { padding-block: 0; }
.xs-staff .x-table tbody th .x-link { margin-block: 0; white-space: nowrap; }
/* An order that has left this list keeps its place, set back, until another list is chosen. */
.xs-staff .x-table tr:has(.xs-kept) { background: var(--x-surface-2); }
/* A desk's screen has room for every column. An order's next step and Cancel stay side by side there in every row,
   so the rows are even and Cancel is always found in the same place. Each cell gives up a little of its side
   padding to make that room, and where a shop's own words are long the column of items is the one that gives way. */
@media (min-width: 75em) {
  .xs-staff .x-table .xs-items { min-width: 8rem; }
  .xs-staff .x-table td:last-child { min-width: 13.5rem; }
  .xs-staff .x-table :not(.xs-ask) > .xs-moves { flex-wrap: nowrap; }
  .xs-staff .x-table th, .xs-staff .x-table td { padding-inline: 11px; }
}
/* Between a phone's cards and that desk (a counter's tablet on its side, a small laptop) the columns do not fit
   side by side. Each order is a ticket there: its reference across the top, then its cells three to a line, each
   under its column's name. Nothing runs off the side, so the next step is always on the screen. */
@media (min-width: 56.25em) and (max-width: 74.99em) {
  .xs-staff .x-table-wrap--wide { overflow: visible; background: none; }
  .xs-staff .x-table-wrap--wide .x-table, .xs-staff .x-table-wrap--wide tbody { display: block; }
  .xs-staff .x-table-wrap--wide thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .xs-staff .x-table-wrap--wide tr { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 24px; margin-bottom: 10px; padding: 10px 16px 16px; border: 1px solid var(--x-hair); border-radius: var(--x-radius, 8px); background: var(--x-surface); }
  .xs-staff .x-table-wrap--wide tbody th { grid-column: 1 / -1; padding: 0 0 2px; border: 0; border-bottom: 1px solid var(--x-hair); font-size: 1.0625rem; }
  .xs-staff .x-table-wrap--wide tbody td { display: grid; align-content: start; gap: 4px; min-width: 0; padding: 0; border: 0; }
  .xs-staff .x-table-wrap--wide td::before { content: attr(data-label); color: var(--x-muted); font-size: .875rem; }
}
.xs-switches { display: grid; gap: 12px; max-width: 56rem; padding: clamp(14px, 3vw, 20px); border: 1px dashed var(--x-line); border-radius: var(--x-radius, 8px); }
.xs-stock > summary { padding-block: 10px; font-weight: 600; cursor: pointer; }
.xs-stock-list { display: grid; gap: 4px 28px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); padding-top: 4px; }
.xs-stock-group legend { padding-top: 8px; font-weight: 600; }

/* ---- how goods are received, in full ------------------------------------------------------------------- */
.xs-info-sec { display: grid; gap: 8px; max-width: 46rem; padding-top: 18px; border-top: 1px solid var(--x-hair); }

@media (hover: hover) and (pointer: fine) {
  .xs-mode:hover, .xs-win:hover:not(.xs-win--no), .xs-thumb:hover { border-color: var(--x-ink); }
}
@media (forced-colors: active) {
  .xs-mode--on, .xs-win:has(input:checked), .xs-thumb[aria-pressed="true"] { border-color: Highlight; }
}
