/* Capture: the order sheet (direction A). Prefix py-, screen-local prefix py-cap-. */

.py-screen.py-cap .py-cap-modes { display: inline-flex; border: 1.5px solid var(--py-rule); border-radius: var(--py-r-ctl); padding: 2px; gap: 2px; }
.py-screen.py-cap .py-cap-modes a { padding: 0.3em 0.8em; border-radius: 3px; text-decoration: none; font-size: var(--py-s--1); font-weight: 600; color: var(--py-ink-soft); }
.py-screen.py-cap .py-cap-modes a[aria-current="page"] { background: var(--py-ink); color: var(--py-paper); }
.py-screen.py-cap .py-cap-modes a:not([aria-current]):hover { background: var(--py-paper-2); color: var(--py-ink); }

.py-screen.py-cap .py-spike {
  display: inline-grid; grid-template-columns: auto auto; align-items: center; gap: 0 var(--py-2);
  padding: var(--py-1) var(--py-3) var(--py-1) var(--py-2);
  border-radius: var(--py-r-ctl); text-decoration: none;
  background: var(--py-paper-2);
}
.py-screen.py-cap .py-spike svg { grid-row: span 2; color: var(--py-ink-soft); }
.py-screen.py-cap .py-spike b { font-family: var(--py-f-display); font-stretch: 72%; font-size: var(--py-s-1); line-height: 1; font-weight: 750; }
.py-screen.py-cap .py-spike small { color: var(--py-ink-soft); font-size: var(--py-s--1); }
.py-screen.py-cap .py-spike:hover { background: var(--py-ruling); }
.py-screen.py-cap .py-spike-bump { animation: py-bump 520ms cubic-bezier(.2,.9,.25,1.3); }
@keyframes py-bump { 30% { scale: 1.12; } }

.py-screen.py-cap .py-cap-grid {
  display: grid; gap: var(--py-5);
  grid-template-columns: minmax(0, 1fr) minmax(17rem, 21rem);
  align-items: start;
}
.py-screen.py-cap .py-cap-sheet { padding: 0; display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); overflow: clip; }

/* The talón: the stub that stays in the book, a live carbon of the sheet */
.py-screen.py-cap .py-stub {
  padding: var(--py-5) var(--py-4); display: grid; align-content: start; gap: var(--py-4);
  background: var(--py-paper-2);
  border-inline-end: 2px dashed var(--py-rule);
  position: relative;
}
.py-screen.py-cap .py-stub::before, .py-screen.py-cap .py-stub::after { /* punched holes at the ends of the perforation */
  content: ""; position: absolute; inset-inline-end: -0.55rem; width: 1rem; height: 1rem; border-radius: 50%; background: var(--py-desk);
}
.py-screen.py-cap .py-stub::before { top: -0.5rem; }
.py-screen.py-cap .py-stub::after { bottom: -0.5rem; }
.py-screen.py-cap .py-stub .py-folio { font-size: var(--py-s-3); display: grid; gap: 2px; }
.py-screen.py-cap .py-stub-dl { margin: 0; display: grid; gap: var(--py-3); font-size: var(--py-s--1); }
.py-screen.py-cap .py-stub-dl div { display: grid; gap: 1px; }
.py-screen.py-cap .py-stub-dl dt { color: var(--py-print); font-weight: 600; }
.py-screen.py-cap .py-stub-dl dd { margin: 0; font-weight: 650; color: var(--py-ink); --py-casl: 1; }
.py-screen.py-cap .py-stub-total { border-top: 1.5px solid var(--py-rule); padding-top: var(--py-2); }
.py-screen.py-cap .py-stub-total dd { font-family: var(--py-f-display); font-stretch: 70%; font-size: var(--py-s-2); font-weight: 750; --py-casl: 0; }


.py-screen.py-cap .py-remision-body { padding: var(--py-5) var(--py-5) var(--py-4); display: grid; gap: var(--py-4); align-content: start; min-width: 0; background: var(--py-paper); }

/* The letterhead: pre-printed on every sheet of the business's own book */
.py-screen.py-cap .py-lh { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--py-4); color: var(--py-print); padding-bottom: var(--py-3); border-bottom: 2px solid var(--py-print); }
.py-screen.py-cap .py-lh-name { font-family: var(--py-f-display); font-stretch: 122%; font-weight: 820; font-size: var(--py-s-2); letter-spacing: -0.01em; line-height: 1.05; }
.py-screen.py-cap .py-lh-addr { font-size: var(--py-s--1); margin-top: 2px; }
.py-screen.py-cap .py-lh-doc { font-family: var(--py-f-display); font-stretch: 122%; font-weight: 700; font-size: var(--py-s-0); padding: 0.15em 0.6em; border: 1.5px solid currentColor; border-radius: 3px; white-space: nowrap; }

/* Blank ruled lines waiting for the next renglón */
.py-screen.py-cap .py-blank-lines { display: grid; }
.py-screen.py-cap .py-blank-lines span { block-size: 3.1rem; border-bottom: 1px solid var(--py-ruling); }
.py-screen.py-cap .py-blank-lines span:nth-child(2) { opacity: 0.66; }
.py-screen.py-cap .py-blank-lines span:nth-child(3) { opacity: 0.33; }
.py-screen.py-cap .py-cap-side { display: grid; gap: var(--py-4); position: sticky; top: var(--py-4); }

/* Search: the instrument of the screen */
.py-screen.py-cap .py-cap-search { display: grid; gap: var(--py-1); }
.py-screen.py-cap .py-cap-search-label { font-weight: 650; font-size: var(--py-s--1); color: var(--py-ink-soft); display: flex; justify-content: space-between; gap: var(--py-3); }
.py-screen.py-cap .py-cap-search-box { position: relative; }
.py-screen.py-cap .py-cap-search-input {
  width: 100%; min-height: 3.5rem; padding: var(--py-2) 7.5rem var(--py-2) var(--py-4);
  border: 2px solid var(--py-ink); border-radius: var(--py-r-ctl);
  background: var(--py-paper); font-size: var(--py-s-1); font-weight: 520;
}
.py-screen.py-cap .py-cap-search-box:has([aria-expanded="true"]) .py-cap-search-input { border-radius: var(--py-r-ctl) var(--py-r-ctl) 0 0; }
.py-screen.py-cap .py-cap-search-input::placeholder { color: var(--py-ink-faint); --py-casl: 1; }
.py-screen.py-cap .py-cap-search-input:focus-visible { outline-offset: 3px; }
.py-screen.py-cap .py-cap-parse { /* what the server understood: the quantity, before the product */
  position: absolute; inset-block: 0; inset-inline-end: var(--py-3); margin-block: auto; height: max-content;
  display: inline-flex; align-items: baseline; gap: 0.3em;
  padding: 0.15em 0.6em; border-radius: var(--py-r-pill);
  background: var(--py-paper-2); color: var(--py-ink); font-weight: 650; font-size: var(--py-s--1);
}
.py-screen.py-cap .py-cap-parse span { color: var(--py-ink-soft); font-weight: 500; }

/* Lines: quantity × price = amount, read left to right (B's anatomy) */
.py-screen.py-cap .py-cap-lines { margin-top: var(--py-1); }
.py-screen.py-cap .py-cap-lines th { color: var(--py-print); border-bottom-color: var(--py-print); }
.py-screen.py-cap .py-cap-lines th:first-child, .py-screen.py-cap .py-cap-lines td:first-child { padding-inline-start: 0; }
.py-screen.py-cap .py-cap-lines th:last-child, .py-screen.py-cap .py-cap-lines td:last-child { padding-inline-end: 0; width: 2.75rem; }
.py-screen.py-cap .py-cap-qty { white-space: nowrap; font-weight: 650; }
.py-screen.py-cap .py-cap-qty span { font-weight: 450; color: var(--py-ink-soft); }
.py-screen.py-cap .py-cap-name { font-weight: 560; }
.py-screen.py-cap .py-cap-name .py-tag { margin-inline-start: var(--py-2); }
.py-screen.py-cap .py-cap-name small { display: block; font-weight: 420; color: var(--py-ink-soft); font-size: var(--py-s--1); }
.py-screen.py-cap .py-cap-free { --py-casl: 1; font-weight: 520; }
.py-screen.py-cap .py-cap-price { white-space: nowrap; }
.py-screen.py-cap .py-cap-price span { color: var(--py-ink-soft); font-size: var(--py-s--1); }
.py-screen.py-cap .py-cap-amount { font-weight: 700; white-space: nowrap; }
.py-screen.py-cap .py-cap-x { inline-size: 2.5rem; block-size: 2.5rem; display: grid; place-items: center; border: 0; background: none; border-radius: var(--py-r-ctl); color: var(--py-ink-faint); cursor: pointer; }
.py-screen.py-cap .py-cap-x:hover { color: var(--py-danger); background: var(--py-danger-bg); }
.py-screen.py-cap .py-cap-lines tbody tr { transition: background-color 600ms ease; }
.py-screen.py-cap .py-cap-lines tbody tr.py-is-new { background: color-mix(in oklch, var(--py-canary) 70%, transparent); transition: none; }

/* Ghost row: something visible within 100 ms; no computed numbers yet */
.py-screen.py-cap .py-cap-ghost td { color: var(--py-ink-soft); border-bottom-style: dashed; }
.py-screen.py-cap .py-cap-ghost .py-cap-name { --py-casl: 1; font-style: oblique 8deg; }
.py-screen.py-cap .py-cap-spin { display: inline-block; inline-size: 0.9em; block-size: 0.9em; border-radius: 50%; border: 2px solid var(--py-rule); border-top-color: var(--py-ink); vertical-align: -0.1em; animation: py-spin 800ms linear infinite; margin-inline-end: 0.4em; }
@keyframes py-spin { to { rotate: 1turn; } }

/* Error row: keeps what was typed, says what happened, offers the fix */
.py-screen.py-cap .py-cap-errrow td { background: var(--py-danger-bg); border-bottom-color: color-mix(in oklch, var(--py-danger) 30%, transparent); }
.py-screen.py-cap .py-cap-errrow .py-cap-errmsg { color: var(--py-danger); font-weight: 650; display: flex; flex-wrap: wrap; align-items: center; gap: var(--py-2) var(--py-3); }
.py-screen.py-cap .py-cap-errrow .py-cap-errmsg span { color: var(--py-ink); font-weight: 450; }

.py-screen.py-cap .py-cap-foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--py-2) var(--py-4); color: var(--py-ink-soft); font-size: var(--py-s--1); }

.py-screen.py-cap .py-cap-empty { padding: var(--py-6) var(--py-2); display: grid; gap: var(--py-2); justify-items: start; }
.py-screen.py-cap .py-cap-empty p:first-child { --py-casl: 1; font-size: var(--py-s-2); font-weight: 600; color: var(--py-ink); }
.py-screen.py-cap .py-cap-empty p { color: var(--py-ink-soft); }

/* Customer: the canary copy */
.py-screen.py-cap .py-cap-customer { display: grid; gap: var(--py-3); padding: var(--py-4) var(--py-4) var(--py-3); }
.py-screen.py-cap .py-cap-customer h2 { font-size: var(--py-s--1); font-weight: 650; color: var(--py-canary-ink); display: flex; justify-content: space-between; align-items: baseline; gap: var(--py-2); }
.py-screen.py-cap .py-cap-cust-name { font-family: var(--py-f-display); font-stretch: 92%; font-weight: 750; font-size: var(--py-s-1); line-height: 1.15; }
.py-screen.py-cap .py-cap-cust-addr { color: var(--py-ink-soft); font-size: var(--py-s--1); }
.py-screen.py-cap .py-cap-cust-row { display: flex; align-items: center; justify-content: space-between; gap: var(--py-3); border-top: 1px solid color-mix(in oklch, var(--py-canary-ink) 22%, transparent); padding-top: var(--py-2); }
.py-screen.py-cap .py-cap-owed { font-size: var(--py-s--1); color: var(--py-canary-ink); }
.py-screen.py-cap .py-cap-owed b { color: var(--py-ink); }

/* Totals and saving */
.py-screen.py-cap .py-cap-totals { padding: var(--py-4); display: grid; gap: var(--py-3); }
.py-screen.py-cap .py-cap-totals dl { margin: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--py-2) var(--py-4); align-items: baseline; }
.py-screen.py-cap .py-cap-totals dl > div { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; align-items: baseline; }
.py-screen.py-cap .py-cap-totals dt { color: var(--py-ink-soft); }
.py-screen.py-cap .py-cap-totals dd { margin: 0; text-align: end; font-variant-numeric: tabular-nums; font-weight: 600; }
.py-screen.py-cap .py-cap-disc-wrap { display: inline-flex; align-items: baseline; gap: 2px; justify-self: end; }
.py-screen.py-cap .py-cap-discount { inline-size: 6.5rem; min-height: 2.25rem; text-align: end; padding-inline: var(--py-1); }
.py-screen.py-cap .py-cap-total-row { border-top: 2px solid var(--py-ink); padding-top: var(--py-2); }
.py-screen.py-cap .py-cap-total-row dt { color: var(--py-ink); font-weight: 700; align-self: center; }
.py-screen.py-cap .py-cap-total {
  font-family: var(--py-f-display); font-stretch: 68%; font-weight: 750;
  font-size: var(--py-s-5); line-height: 0.95; letter-spacing: -0.01em;
}
.py-screen.py-cap .py-cap-totals[aria-busy="true"] dd { opacity: 0.45; }
.py-screen.py-cap .py-cap-calc { display: none; font-size: var(--py-s--1); color: var(--py-ink-soft); }
.py-screen.py-cap .py-cap-totals[aria-busy="true"] .py-cap-calc { display: inline-flex; align-items: center; }

.py-screen.py-cap .py-cap-pay { border: 0; margin: 0; padding: 0; display: grid; gap: var(--py-1); }
.py-screen.py-cap .py-cap-pay legend { font-size: var(--py-s--1); font-weight: 650; color: var(--py-ink-soft); padding: 0; margin-bottom: var(--py-1); }
.py-screen.py-cap .py-cap-pay-opts { display: flex; flex-wrap: wrap; gap: var(--py-1); }
.py-screen.py-cap .py-cap-pay label { flex: 1 1 auto; text-align: center; padding: 0.45em 0.6em; border: 1.5px solid var(--py-rule); border-radius: var(--py-r-ctl); cursor: pointer; font-size: var(--py-s--1); font-weight: 600; min-height: 2.25rem; display: grid; place-items: center; }
.py-screen.py-cap .py-cap-pay label:has(input:checked) { border-color: var(--py-stamp); color: var(--py-stamp); background: color-mix(in oklch, var(--py-stamp) 9%, transparent); }
.py-screen.py-cap .py-cap-pay label:has(input:focus-visible) { outline: 3px solid var(--py-focus); outline-offset: 2px; }
.py-screen.py-cap .py-cap-pay input { position: absolute; opacity: 0; pointer-events: none; }

.py-screen.py-cap .py-cap-save { inline-size: 100%; min-height: 3.25rem; font-size: var(--py-s-1); }
.py-screen.py-cap .py-cap-print { display: flex; align-items: center; gap: var(--py-2); font-size: var(--py-s--1); color: var(--py-ink-soft); cursor: pointer; }
.py-screen.py-cap .py-cap-print input { inline-size: 1.15rem; block-size: 1.15rem; accent-color: var(--py-ink); }

/* ---------- Laptops and tablets (pass 2: laptop first, tablets supported) ---------- */

/* Short screens (a 1366×768 laptop, a tablet on its side): the side column fits whole, Save included */
@media (max-height: 50rem) and (min-width: 60.01rem) {
  .py-screen.py-cap .py-cap-customer { gap: var(--py-2); padding: var(--py-3) var(--py-4); }
  .py-screen.py-cap .py-cap-totals { gap: var(--py-2); padding: var(--py-3) var(--py-4); }
  .py-screen.py-cap .py-cap-totals dl { row-gap: 0.15rem; }
  .py-screen.py-cap .py-cap-total { font-size: var(--py-s-4); }
  .py-screen.py-cap .py-cap-pay legend { margin-bottom: 0; }
  .py-screen.py-cap .py-cap-pay label { min-height: 2rem; padding-block: 0.25em; }
  .py-screen.py-cap .py-cap-save { min-height: 2.75rem; font-size: var(--py-s-0); }
}

/* Narrow laptops and tablets on their side: the talón runs across the top of the sheet,
   so the lines keep their width and the totals keep their column */
@media (min-width: 48rem) and (max-width: 72rem) {
  .py-screen.py-cap .py-cap-grid { grid-template-columns: minmax(0, 1fr) 16rem; gap: var(--py-4); }
  .py-screen.py-cap .py-cap-sheet { grid-template-columns: minmax(0, 1fr); }
  .py-screen.py-cap .py-cap-cust-row { flex-wrap: wrap; row-gap: 0; }
  .py-screen.py-cap .py-cap-totals dl { grid-template-columns: max-content minmax(0, 1fr); }
  .py-screen.py-cap .py-stub {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--py-2) var(--py-5);
    padding: var(--py-3) var(--py-5); border-inline-end: 0; border-bottom: 2px dashed var(--py-rule);
  }
  .py-screen.py-cap .py-stub::before, .py-screen.py-cap .py-stub::after { top: auto; bottom: -0.55rem; inset-inline-end: auto; }
  .py-screen.py-cap .py-stub::before { left: -0.5rem; }
  .py-screen.py-cap .py-stub::after { right: -0.5rem; left: auto; }
  .py-screen.py-cap .py-stub .py-folio { display: flex; align-items: baseline; gap: 0.2em; font-size: var(--py-s-2); }
  .py-screen.py-cap .py-stub-dl { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--py-2) var(--py-5); }
  .py-screen.py-cap .py-stub-dl div:first-child { display: none; } /* the date is already in the page head */
  .py-screen.py-cap .py-stub-total { border: 0; padding: 0; }
  .py-screen.py-cap .py-remision-body { padding: var(--py-4) var(--py-4) var(--py-3); }
}

/* Tablets on their side: title and controls share one row, so the side column starts higher */
@media (min-width: 60.01rem) and (max-width: 72rem) {
  .py-screen.py-cap .py-cap-head { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: var(--py-5); }
  .py-screen.py-cap .py-cap-head .py-title { grid-area: 1 / 1; }
  .py-screen.py-cap .py-cap-head .py-head-meta { grid-area: 2 / 1; }
  .py-screen.py-cap .py-cap-head .py-head-end { grid-area: 1 / 2 / span 2; flex-wrap: nowrap; }
}
@media (max-height: 50rem) and (min-width: 60.01rem) and (max-width: 72rem) {
  .py-screen.py-cap .py-cap-cust-row .py-hint { display: none; }
}

/* Tablets upright: one column, the customer card on top, the totals as a tray pinned to the bottom */
@media (min-width: 48rem) and (max-width: 60rem) {
  .py-screen.py-cap .py-cap-grid { grid-template-columns: minmax(0, 1fr); }
  .py-screen.py-cap .py-cap-side { display: contents; }
  .py-screen.py-cap .py-cap-customer { order: -1; grid-template-columns: minmax(0, 1fr) auto; align-items: start; column-gap: var(--py-5); }
  .py-screen.py-cap .py-cap-customer h2 { grid-column: 1 / -1; }
  .py-screen.py-cap .py-cap-cust-row { grid-column: 2; grid-row: 2; }
  .py-screen.py-cap .py-cap-owed { grid-column: 1 / -1; }
  .py-screen.py-cap .py-cap-totals {
    position: sticky; bottom: 0; z-index: 10;
    grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "sums sums" "pay save" "pay print";
    align-items: center; gap: var(--py-2) var(--py-4); padding: var(--py-3) var(--py-4);
    border-radius: var(--py-r-ctl) var(--py-r-ctl) 0 0;
    box-shadow: 0 -12px 24px -18px oklch(0.2 0.05 262 / 0.5);
  }
  .py-screen.py-cap .py-cap-totals dl { grid-area: sums; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--py-1) var(--py-5); }
  .py-screen.py-cap .py-cap-totals dl > div { display: flex; align-items: baseline; gap: var(--py-2); }
  .py-screen.py-cap .py-cap-total-row { margin-inline-start: auto; border: 0; padding: 0; }
  .py-screen.py-cap .py-cap-total { font-size: var(--py-s-3); }
  .py-screen.py-cap .py-cap-pay { grid-area: pay; }
  .py-screen.py-cap .py-cap-save { grid-area: save; inline-size: auto; }
  .py-screen.py-cap .py-cap-print { grid-area: print; justify-self: end; }
  .py-screen.py-cap .py-blank-lines span:nth-child(n+2) { display: none; }
}

/* Touch screens: no keyboard hints next to the controls (the Atajos list stays, for tablets with a keyboard) */
@media (pointer: coarse) {
  .py-screen.py-cap .py-cap-search-label .py-faint, .py-screen.py-cap .py-listbox-keys, .py-screen.py-cap .py-cap-save .py-kbd, .py-screen.py-cap .py-cap-customer .py-kbd { display: none; }
  .py-screen.py-cap .py-cap-pay label { min-height: 2.75rem; }
}
@media (max-width: 47.99rem) {
  .py-screen.py-cap .py-cap-sheet { grid-template-columns: minmax(0, 1fr); }
  .py-screen.py-cap .py-stub { border-inline-end: 0; border-bottom: 2px dashed var(--py-rule); padding: var(--py-3) var(--py-4); grid-auto-flow: column; justify-content: space-between; align-items: center; }
  .py-screen.py-cap .py-stub::before, .py-screen.py-cap .py-stub::after { top: auto; bottom: -0.55rem; inset-inline-end: auto; }
  .py-screen.py-cap .py-stub::before { left: -0.5rem; }
  .py-screen.py-cap .py-stub::after { right: -0.5rem; left: auto; }
  .py-screen.py-cap .py-stub-dl { grid-auto-flow: column; gap: var(--py-4); }
  .py-screen.py-cap .py-stub-dl div:not(.py-stub-total) { display: none; }
  .py-screen.py-cap .py-stub-total { border: 0; padding: 0; text-align: end; }
  .py-screen.py-cap .py-remision-body { padding: var(--py-4) var(--py-3) var(--py-3); }
  .py-screen.py-cap .py-lh { flex-wrap: wrap; }
  .py-screen.py-cap .py-lh-name { font-size: var(--py-s-1); }
  .py-screen.py-cap .py-lh-addr { display: none; }
  .py-screen.py-cap .py-blank-lines span:nth-child(n+2) { display: none; }
  .py-screen.py-cap .py-cap-save .py-kbd { display: none; }
  .py-screen.py-cap .py-cap-grid { grid-template-columns: minmax(0, 1fr); gap: var(--py-3); }
  .py-screen.py-cap .py-cap-side { display: contents; }
  .py-screen.py-cap .py-cap-customer { order: -1; }
  .py-screen.py-cap .py-cap-lines thead { display: none; }
  .py-screen.py-cap .py-cap-lines tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto 2.5rem; grid-template-areas: "name amount x" "qty price x"; column-gap: var(--py-3); padding: var(--py-2) 0; border-bottom: 1px solid var(--py-ruling); }
  .py-screen.py-cap .py-cap-lines td { border: 0; padding: 0; }
  .py-screen.py-cap .py-cap-lines td.py-cap-qty { grid-area: qty; font-size: var(--py-s--1); }
  .py-screen.py-cap .py-cap-lines td.py-cap-name { grid-area: name; }
  .py-screen.py-cap .py-cap-lines td.py-cap-price { grid-area: price; text-align: end; font-size: var(--py-s--1); }
  .py-screen.py-cap .py-cap-lines td.py-cap-amount { grid-area: amount; text-align: end; }
  .py-screen.py-cap .py-cap-lines td:last-child { grid-area: x; align-self: center; }
  .py-screen.py-cap .py-cap-lines tbody tr.py-cap-errrow { grid-template-columns: minmax(0, 1fr); grid-template-areas: none; }
  .py-screen.py-cap .py-cap-lines tbody tr.py-cap-errrow td { grid-area: auto; }
    .py-screen.py-cap .py-cap-totals { position: sticky; bottom: 3.6rem; z-index: 10; box-shadow: 0 -12px 24px -18px oklch(0.2 0.05 262 / 0.5); }
  .py-screen.py-cap .py-cap-totals dl > div:not(.py-cap-total-row) { display: none; }
  .py-screen.py-cap .py-cap-totals .py-cap-pay, .py-screen.py-cap .py-cap-totals .py-cap-print { display: none; }
  .py-screen.py-cap .py-cap-total { font-size: var(--py-s-4); }
  .py-screen.py-cap .py-cap-search-input { padding-inline-end: 6.5rem; font-size: var(--py-s-0); }
  .py-screen.py-cap .py-spike, .py-screen.py-cap .py-cap-keys-btn { display: none; }
}

.py-screen.py-cap .py-listbox ul { list-style: none; margin: 0; padding: 0; }
.py-screen.py-cap .py-option-note { display: block; font-size: var(--py-s--1); color: var(--py-ink-soft); font-weight: 420; }
.py-screen.py-cap .py-option[aria-selected="true"] .py-option-note { color: color-mix(in oklch, var(--py-paper) 78%, var(--py-ink)); }

/* ---------- What the product draws beyond the design ---------- */

/* Each in its resting state, plain. The design's script fakes these; the product draws
   them as forms that post, in the design's language, until the interactions' wave builds
   the combobox and the keys. */

/* A blank sheet: the server marks the empty table, and the blank sheet's words take its place. */
.py-screen.py-cap .py-cap-lines.py-is-empty { display: none; }

/* The line's field adds with its own button, where the parse chip sits in the design. */
.py-screen.py-cap .py-cap-add { position: absolute; inset-block: 0; inset-inline-end: var(--py-2); margin-block: auto; height: max-content; min-height: 2.5rem; }

/* The items that match, open under the field: each one a form, the free-text line last. */
.py-screen.py-cap .py-cap-listbox-wrap .py-option { grid-template-columns: minmax(0, 1fr) auto; cursor: default; }
.py-screen.py-cap .py-cap-listbox-wrap .py-option > form { display: contents; }
.py-screen.py-cap .py-cap-listbox-wrap li.py-option:hover { background: var(--py-paper-2); }
.py-screen.py-cap .py-cap-listbox-wrap p.py-option { display: block; }
.py-screen.py-cap .py-cap-free { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); align-items: end; }
.py-screen.py-cap .py-cap-free-wide { grid-column: 1 / -1; }
.py-screen.py-cap .py-cap-free .py-btn { justify-self: start; }

/* A line's own form: change it in a fold anchored to its row, or take it off. */
.py-screen.py-cap .py-cap-lines th:last-child, .py-screen.py-cap .py-cap-lines td:last-child { width: 5.25rem; }
.py-screen.py-cap .py-cap-act { position: relative; }
.py-screen.py-cap .py-cap-act form { display: flex; justify-content: flex-end; gap: var(--py-1); }
.py-screen.py-cap .py-cap-edit summary { list-style: none; }
.py-screen.py-cap .py-cap-edit summary::-webkit-details-marker { display: none; }
.py-screen.py-cap .py-cap-edit[open] summary { color: var(--py-ink); background: var(--py-paper-2); }
.py-screen.py-cap .py-cap-edit-pop {
  position: absolute; inset: calc(100% - var(--py-2)) 0 auto auto; z-index: 20;
  inline-size: 17rem; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--py-2) var(--py-3);
  padding: var(--py-3); border: 2px solid var(--py-ink); border-radius: var(--py-r-ctl);
  background: var(--py-paper); box-shadow: 0 22px 40px -26px oklch(0.2 0.05 262 / 0.6);
}
.py-screen.py-cap .py-cap-edit-pop .py-error-text, .py-screen.py-cap .py-cap-edit-pop .py-btn { grid-column: 1 / -1; }
.py-screen.py-cap .py-cap-edit-pop .py-btn { justify-self: start; }

/* The client's card: its heading beside *Cambiar cliente*, the search when there is none. */
.py-screen.py-cap .py-cap-cust-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--py-2); }
.py-screen.py-cap .py-cap-cust-find { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: var(--py-2); }
.py-screen.py-cap .py-cap-cust-found { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--py-1); }
.py-screen.py-cap .py-cap-cust-found form { display: flex; justify-content: space-between; align-items: center; gap: var(--py-2); font-weight: 600; }

/* The order's details above its totals: the day, where it goes, the discount and the coupon. */
.py-screen.py-cap .py-cap-facts { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--py-2) var(--py-3); align-items: end; }
.py-screen.py-cap .py-cap-facts > :first-child, .py-screen.py-cap .py-cap-facts > .py-switch, .py-screen.py-cap .py-cap-facts > .py-field:has(select) { grid-column: 1 / -1; }
.py-screen.py-cap .py-cap-facts .py-switch { min-height: 2rem; font-size: var(--py-s--1); font-weight: 600; }
.py-screen.py-cap .py-cap-facts .py-input { inline-size: 100%; min-inline-size: 0; }
.py-screen.py-cap .py-cap-recalc { justify-self: start; }
.py-screen.py-cap .py-cap-quote { inline-size: 100%; }

@media (max-height: 50rem) and (min-width: 60.01rem) {
  .py-screen.py-cap .py-cap-facts { row-gap: var(--py-1); }
  .py-screen.py-cap .py-cap-facts .py-input { min-height: 2.25rem; padding-block: 0.2em; }
}
@media (min-width: 48rem) and (max-width: 60rem) {
  .py-screen.py-cap .py-cap-totals { grid-template-areas: "facts facts" "sums recalc" "pay save" "pay quote"; }
  .py-screen.py-cap .py-cap-cust-head { grid-column: 1 / -1; }
  .py-screen.py-cap .py-cap-facts { grid-area: facts; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--py-1) var(--py-2); }
  .py-screen.py-cap .py-cap-facts .py-input { min-height: 2.25rem; padding-block: 0.2em; font-size: var(--py-s--1); }
  .py-screen.py-cap .py-cap-facts > :first-child, .py-screen.py-cap .py-cap-facts > .py-switch, .py-screen.py-cap .py-cap-facts > .py-field:has(select) { grid-column: auto; }
  .py-screen.py-cap .py-cap-recalc { grid-area: recalc; justify-self: end; }
  .py-screen.py-cap .py-cap-quote { grid-area: quote; inline-size: auto; justify-self: end; }
}

/* ---------- As the person types (the interactions' wave) ---------- */

/* The sheet, and the banner above it, are elements of their own that an answer fills again. */
.py-screen.py-cap .py-cap-hoja, .py-screen.py-cap .py-cap-renglones { display: grid; gap: inherit; }
.py-screen.py-cap .py-cap-renglones { gap: var(--py-4); }
.py-screen.py-cap .py-cap-aviso:not(:has(*)) { display: none; }

/* The line's field: its label beside the key that brings the focus back. The keys are written
   in the sheet's own type, never the browser's monospace. */
.py-screen.py-cap .py-cap-search-label label { color: inherit; }
.py-screen.py-cap .py-cap-hint { font-weight: 450; }
.py-screen.py-cap kbd { font-family: inherit; }

/* The listbox of what the field matches: each item, its unit and today's price. */
.py-screen.py-cap .py-cap-listbox-wrap [role="listbox"] > .py-option { grid-template-columns: minmax(0, 1fr) auto auto; }
.py-screen.py-cap .py-cap-listbox-wrap [role="listbox"] > .py-option--free { grid-template-columns: minmax(0, 1fr); }
.py-screen.py-cap .py-cap-nomatch { padding: var(--py-2) var(--py-3) 0; }
.py-screen.py-cap .py-cap-customer .py-listbox { border-top-width: 2px; border-radius: var(--py-r-ctl); margin-top: var(--py-1); }

/* Lines on their way, or not added: the table shows, the blank sheet's words step aside. */
.py-screen.py-cap .py-cap-lines.py-is-empty:has(#renglones-pendientes > tr) { display: table; }
.py-screen.py-cap .py-cap-renglones:has(#renglones-pendientes > tr) .py-cap-empty { display: none; }
.py-screen.py-cap .py-cap-errrow .py-cap-errmsg p { flex: 1 1 14rem; }
.py-screen.py-cap .py-cap-errrow .py-banner-actions { margin-inline-start: auto; }

/* The totals while a change is on its way. */
.py-screen.py-cap .py-cap-sums { display: grid; gap: var(--py-2); }
.py-screen.py-cap .py-cap-sums[aria-busy="true"] dd { opacity: 0.45; }
.py-screen.py-cap .py-cap-sums[aria-busy="true"] .py-cap-calc { display: inline-flex; align-items: center; gap: var(--py-1); }

/* Saving: the button says it at once. */
.py-screen.py-cap .py-cap-save[aria-busy="true"] { cursor: progress; }

/* The keys' hints show only where there is a keyboard; the sheet of shortcuts keeps its keys. */
@media not (pointer: fine) {
  .py-screen.py-cap .py-kbd, .py-screen.py-cap .py-cap-hint { display: none; }
  .py-screen.py-cap .py-pop .py-kbd { display: inline-grid; }
}

/* The tear-off (HTMX-320): while a save's blank sheet arrives, the saved sheet is named, and
   leaves toward the day's orders, up and to the end; the blank one settles in its place. Under
   reduced motion the view transition's animations are none (py.css). The two rules on the
   transition's pseudo-elements, which no screen's scope reaches, are in shell.css. */
.py-screen.py-cap .py-cap-hoja.py-is-tearing .py-cap-sheet { view-transition-name: py-order; }
@keyframes py-tear { to { translate: 30vw -55vh; rotate: 7deg; scale: 0.4; opacity: 0; } }
@keyframes py-settle { from { opacity: 0; translate: 0 0.75rem; } }

/* The sheet of shortcuts slides in and out, but is never drawn see-through: a sheet fading in is
   read at the fade's contrast (axe measured 1.2:1 while the entrance ran). Its behaviours are
   listed again with its properties, so `display` and `overlay` keep `allow-discrete` (UI-443). */
.py-screen.py-cap .py-pop { transition-property: translate, display, overlay; transition-behavior: normal, allow-discrete, allow-discrete; }

/* The totals and Guardar pedido stay where they are while lines come and go (docs/specs/sales.md,
   *Saving*; UI-432). The side column keeps its own height when the sheet grows past it, so its rows
   never stretch; «calculando…» always has its room and is only seen while busy; the totals keep a
   row's room for each tax rate a line may still bring (`py-cap-held-N`, drawn by the server), one
   row and its gap each, so a line that lands takes a room kept and nothing below moves. */
.py-screen.py-cap .py-cap-side { align-self: start; }
.py-screen.py-cap .py-cap-totals { align-content: start; }
/* A press shows on Guardar pedido by its shade, never by the pixel every other button sinks. */
.py-screen.py-cap .py-cap-save:active { translate: none; box-shadow: inset 0 3px 0 oklch(0 0 0 / 0.35); }
.py-screen.py-cap .py-cap-sums .py-cap-calc { display: inline-flex; align-items: center; gap: var(--py-1); visibility: hidden; }
.py-screen.py-cap .py-cap-sums[aria-busy="true"] .py-cap-calc { visibility: visible; }
/* Busy figures fade to the soft ink, which still reads (AA), never to a see-through grey: the blank
   sheet's $0.00 is on screen whenever a first change is on its way. */
.py-screen.py-cap .py-cap-sums[aria-busy="true"] dd { opacity: 1; color: var(--py-ink-soft); }
.py-screen.py-cap .py-cap-totals dl { --py-cap-gap: var(--py-2); row-gap: var(--py-cap-gap); }
.py-screen.py-cap .py-cap-totals dl.py-cap-held-1 { padding-block-end: calc(1lh + var(--py-cap-gap)); }
.py-screen.py-cap .py-cap-totals dl.py-cap-held-2 { padding-block-end: calc(2 * (1lh + var(--py-cap-gap))); }
.py-screen.py-cap .py-cap-totals dl.py-cap-held-3 { padding-block-end: calc(3 * (1lh + var(--py-cap-gap))); }
@media (max-height: 50rem) and (min-width: 60.01rem) {
  .py-screen.py-cap .py-cap-totals dl { --py-cap-gap: 0.15rem; }
}

/* Tablets upright: the tray pinned to the bottom holds the details, the totals on one line, then
   the payment beside the saves, every part in an area of its own, so the tray's height never
   changes with the lines. */
@media (min-width: 48rem) and (max-width: 60rem) {
  .py-screen.py-cap .py-cap-grid { grid-template-rows: auto minmax(0, 1fr) auto; min-block-size: 100dvh; }
  .py-screen.py-cap .py-cap-totals {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "facts facts" "sums sums" "pay save" "pay quote" "recalc print";
  }
  .py-screen.py-cap .py-cap-totals > .py-banner { grid-column: 1 / -1; }
  .py-screen.py-cap .py-cap-facts { grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); }
  .py-screen.py-cap .py-cap-sums { grid-area: sums; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; column-gap: var(--py-4); }
  .py-screen.py-cap .py-cap-sums .py-cap-calc { grid-column: 1; grid-row: 1; }
  .py-screen.py-cap .py-cap-totals dl[class] { grid-column: 2; grid-row: 1; flex-wrap: nowrap; padding-block-end: 0; }
  .py-screen.py-cap .py-cap-recalc { grid-area: recalc; justify-self: start; }
  .py-screen.py-cap .py-cap-quote { grid-area: quote; }
  .py-screen.py-cap .py-cap-print { grid-area: print; }
}
