/*
 * House of Ruby: the order pages, in the room's look.
 *
 * The direction is design/direction-contract.md and the drawn board is
 * design/order-page-layouts/OneAtATime.dc.html. The room (public/room) is the
 * source: its ground, its soft gold, its wine on gold button. Libre Caslon Display sets the
 * headlines and the shop's name, and DM Sans sets everything else.
 * Only the dogs shine. Everything here is matte: no shadows, and no gradient.
 *
 * order.js depends on these ids and classes: #order-form, #photo-input,
 * #previews, #photo-label, #photos-field, #form-error, #submit, #next, #back,
 * #bar, #back-note, #rush, #sum-postage, #sum-total-label, #bar-postage,
 * #multibuy-line, #sum-discount, #sum-discount-label, #sum-discount-amount,
 * .step, .preview, .remove, .file, .shot, .is-typing, .has-photos,
 * .is-entering, .is-leaving, .is-moving.
 */

/*
 * Stand-ins while the web fonts load. Each is a font that computers and
 * iPhones already have (or its Linux twin, which has the same widths),
 * resized to take the same room as the real font, so the words do not reflow
 * and the page does not jump when the real one arrives. Without them, a
 * wide stand-in moved the delivery page by 0.17 on a computer.
 * Measured on 12 November 2026 in Chrome, on the shop's own words.
 */
@font-face { font-family: 'DM Sans stand-in'; src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('Arimo'); font-weight: 100 549; size-adjust: 103.43%; ascent-override: 95.72%; descent-override: 29.97%; }
@font-face { font-family: 'DM Sans stand-in'; src: local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'), local('Arimo Bold'); font-weight: 550 900; size-adjust: 101.44%; ascent-override: 97.59%; descent-override: 30.56%; }
@font-face { font-family: 'Caslon Display stand-in'; src: local('Times New Roman'), local('TimesNewRomanPSMT'), local('Liberation Serif'), local('Tinos'); size-adjust: 91.57%; ascent-override: 105.92%; descent-override: 29.48%; }

:root {
  /* the room's colours */
  --night: #121412;
  --ground: #131b16;
  --well: #0e1410;
  --wine: #4a0e17;
  --soft: #e9d6a8;
  --ink: #f6ede6;
  --muted: #d9d2c6;
  --quiet: #c9c2b4;
  /* soft gold at low strength, for hairlines and the wash behind a chosen option */
  --hair: rgba(233, 214, 168, 0.22);
  --hair-faint: rgba(233, 214, 168, 0.2);
  --edge: rgba(233, 214, 168, 0.4);
  --edge-faint: rgba(233, 214, 168, 0.25);
  --wash: rgba(233, 214, 168, 0.09);
  /* a mistake: the wine, lifted until it reads on the dark ground */
  --alert: #f0b2bc;
  /* the two figure colours, as the room paints them */
  --gold: #d8ae48;
  --copper: #b8653d;
  --serif: 'Libre Caslon Text', Georgia, 'Times New Roman', serif;
  --display: 'Libre Caslon Display', 'Caslon Display stand-in', Georgia, serif;
  /* DM Sans carries the words. Caslon Display is for headlines and the shop's name. */
  --sans: 'DM Sans', 'DM Sans stand-in', system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
  --side: max(20px, env(safe-area-inset-left, 0px));
  /* the pinned bar: 12 above its 50 pixel buttons, and 18 below or enough to clear the phone's home indicator */
  --bar-foot: max(18px, calc(env(safe-area-inset-bottom, 0px) + 8px));
  --bar-height: calc(62px + var(--bar-foot));
  color-scheme: dark;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; background: var(--ground); scrollbar-color: var(--edge) transparent; }
body { margin: 0; background: var(--ground); color: var(--ink); font: 16px/1.5 var(--sans); caret-color: var(--soft); }
::selection { background: var(--soft); color: var(--wine); }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--soft); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { color: var(--ink); }
/* Libre Caslon Display sets every headline and the shop's name. DM Sans sets everything else.
   The scale: a page heading (36, or 44 on a wide screen), a section heading (26), the product name (30), body (16),
   small (14), and fine print (12 to 13). Headlines are 400 with no tightening. Words are 400. Buttons and prices are 700. */
h1, h2, h3 { font-family: var(--display); font-weight: 400; text-wrap: balance; margin: 0; }
p { margin: 0; text-wrap: pretty; }
:focus-visible { outline: 2px solid var(--soft); outline-offset: 3px; border-radius: 2px; }
.step-title:focus { outline: none; }
.skip { position: absolute; left: -9999px; }
.skip:focus { left: 16px; top: 16px; z-index: 40; display: inline-flex; align-items: center; min-height: 44px; background: var(--ink); color: var(--wine); padding: 0 14px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.icon { flex: none; color: var(--soft); }

/* the frame every page shares: the shop's name, the page, the small print */
header.site, main, footer.site { max-width: 1100px; margin: 0 auto; padding-left: var(--side); padding-right: max(20px, env(safe-area-inset-right, 0px)); }
header.site { padding-top: calc(env(safe-area-inset-top, 0px) + 8px); }
/* the name's letters and spacing are in name.css; here, its size, and 44 pixels to press */
header.site .name { display: inline-block; padding: 12px 0; font-size: 20px; color: var(--ink); }
/* the header: the shop's name, and the basket's link once there is something in it */
header.site { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.basket-link { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--ink); font-size: 15px; font-weight: 600; text-decoration: none; }
.basket-count { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px; background: var(--soft); color: var(--wine); font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
footer.site { margin-top: 72px; padding-top: 12px; padding-bottom: 40px; border-top: 1px solid var(--hair); color: var(--quiet); font-size: 13px; line-height: 1.5; }
footer.site nav { display: flex; flex-wrap: wrap; column-gap: 24px; }
footer.site nav a { display: inline-flex; align-items: center; min-width: 44px; min-height: 44px; color: var(--muted); }
footer.site nav a:hover { color: var(--ink); }

/* buttons: the room's, soft gold with wine words, 50 pixels high */
.btn { display: inline-flex; align-items: center; justify-content: center; height: 50px; padding: 0 clamp(28px, 10vw, 44px); border: 0; border-radius: 6px; background: var(--soft); color: var(--wine); font: 700 16px/1 var(--sans); text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color 120ms ease-out, border-color 120ms ease-out; }
.btn:hover { background: #f2e4c0; color: var(--wine); }
.btn:active { background: #dcc790; }
.btn.ghost { padding: 0 22px; border: 1px solid rgba(233, 214, 168, 0.5); background: transparent; color: var(--ink); font-weight: 600; }
.btn.ghost:hover { border-color: var(--soft); background: var(--wash); color: var(--ink); }
.btn.ghost:active { background: rgba(233, 214, 168, 0.16); }
.btn.wide { width: 100%; }
.btn[disabled] { opacity: 0.6; cursor: progress; }

/* words that help, and a mistake named at its field */
.hint { color: var(--muted); font-size: 14px; line-height: 1.45; }
.hint.lead { font-size: 15px; }
.field-error { display: flex; align-items: flex-start; gap: 8px; color: var(--alert); font-size: 14px; line-height: 1.4; }
.field-error .icon { color: var(--alert); margin-top: 1px; }
.form-error { border: 1px solid var(--alert); border-radius: 6px; padding: 12px 14px; color: var(--alert); font-size: 15px; line-height: 1.45; }
.back-note, p.done { border: 1px solid var(--edge); border-radius: 6px; padding: 10px 14px; color: var(--soft); font-size: 14px; line-height: 1.45; }
.back-note { margin-top: 16px; }

/* fields: 48 pixels high, set into the ground */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label, .qty-row label { color: var(--muted); font-size: 14px; }
.order input:not([type='radio']):not([type='checkbox']):not([type='file']):not([type='number']), .order textarea { width: 100%; border: 1px solid var(--edge); border-radius: 6px; background: var(--well); color: var(--ink); font: 17px/1.4 var(--sans); }
.order input:not([type='radio']):not([type='checkbox']):not([type='file']):not([type='number']) { height: 48px; padding: 0 14px; }
.order textarea { min-height: 96px; padding: 12px 14px; resize: vertical; }
.order input:focus-visible, .order textarea:focus-visible { outline-offset: 2px; border-color: var(--soft); }
.order [aria-invalid='true'] { border-color: var(--alert) !important; }
fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend { padding: 0; }

/* the order page */
.order-page { display: flex; flex-direction: column; }
/* What the figure is: its picture, name, price, size and description. On a wide screen it is held on the
   left of the steps. On a phone the step is followed at once by "How it works", so only its name is kept,
   for a screen reader, hidden the same way as .visually-hidden. Without JavaScript the page is one long
   form, and the whole block shows under it (the page's own noscript styles put it back). */
.figure-panel { order: 2; }
.figure-panel .held { display: none; }
.figure-panel .description { margin-top: 18px; max-width: 34rem; color: var(--muted); font-size: 15px; line-height: 1.55; }
@media (max-width: 899.98px) {
  .figure-panel h1 { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
  .figure-panel .panel-part { display: none; }
}

/* The buy block (design/buy-section/Shop.dc.html): a picture and its label, the name and one line, the two
   prices as tiles, the button, and three facts in a row. A price is a number, never a sentence. */
.buy-block { display: flex; flex-direction: column; gap: 14px; }
.made-photos { margin: 0; }
.made-row { display: grid; grid-template-columns: repeat(var(--shots, 1), minmax(0, 1fr)); gap: 10px; align-items: start; }
.made-photos[data-count='2'] { --shots: 2; }
.made-photos[data-count='3'] { --shots: 3; }
/* in the strip the hairline is drawn inside each photograph, so a border never adds to its size and the row stays one height */
.made-row img.photograph { border: 0; outline: 1px solid var(--edge); outline-offset: -1px; }
.made-photos figcaption, .photo-label { margin: 8px 0 0; color: #c9c2b4; font-size: 12px; line-height: 1.4; }
.buy-title { display: flex; flex-direction: column; gap: 4px; }
.buy-name { margin: 0; font-family: var(--display); font-weight: 400; font-size: 30px; line-height: 1.1; }
.buy-line { margin: 0; color: #d9d2c6; font-size: 15px; line-height: 1.4; }
.tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.tiles[data-count='1'] { grid-template-columns: minmax(0, 1fr); }
.tile { position: relative; display: flex; flex-direction: column; gap: 6px; height: 100%; min-height: 44px; padding: 12px; border: 1px solid rgba(233, 214, 168, 0.28); border-radius: 6px; }
/* where the tiles are a choice: the chosen one takes the gold border, the faint wash and a tick, as the colour rows do */
.tile-set { min-width: 0; margin: 0; padding: 0; border: 0; }
.tile-pick { display: block; cursor: pointer; }
.tile-pick:hover .tile { border-color: rgba(233, 214, 168, 0.5); }
.tile-pick input:checked + .tile { padding: 11.5px; border: 1.5px solid #e9d6a8; background: rgba(233, 214, 168, 0.09); }
.tile-pick input:focus-visible + .tile { outline: 2px solid #e9d6a8; outline-offset: 3px; }
.tile-tick { position: absolute; top: 11px; right: 11px; color: #e9d6a8; visibility: hidden; }
.tile-pick input:checked + .tile .tile-tick { visibility: visible; }
/* Past step 1 the product block's tiles are no longer a control. They show the choice and cannot be changed:
   no pointer, no hover, and the one not chosen is quieter. */
.tile-set.is-fixed .tile-pick { cursor: default; }
.tile-set.is-fixed .tile-pick:hover .tile { border-color: rgba(233, 214, 168, 0.28); }
.tile-set.is-fixed .tile-pick input:checked + .tile, .tile-set.is-fixed .tile-pick:hover input:checked + .tile { border-color: #e9d6a8; }
.tile-set.is-fixed .tile-pick input:not(:checked) + .tile { opacity: 0.5; }
.dots { display: flex; align-items: center; gap: 6px; height: 16px; }
.dot { width: 16px; height: 16px; border-radius: 50%; }
.dot-gold { background: #d8ae48; }
.dot-copper { background: #b8653d; }
.dot-request { width: 14px; height: 14px; border: 1.5px dashed #e9d6a8; }
.tile-label { color: #d9d2c6; font-size: 14px; line-height: 1.3; }
.tile-price { margin-top: auto; font-size: 24px; font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; }
.facts { list-style: none; margin: 0; padding: 14px 0 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; border-top: 1px solid rgba(233, 214, 168, 0.22); color: #d9d2c6; font-size: 12px; line-height: 1.3; text-align: center; }
.facts[data-count='2'] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.facts[data-count='1'] { grid-template-columns: minmax(0, 1fr); }
.facts b { display: block; color: #f6ede6; font-size: 13px; font-weight: 700; }
.btn.buy-go { height: 54px; font-size: 17px; }

/* the progress: four parts, the count, and how many are left */
.progress { display: flex; flex-direction: column; gap: 14px; padding-top: 6px; }
.progress-bar { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.progress-bar span { height: 4px; border-radius: 2px; background: var(--hair); }
.progress-bar span.on { background: var(--soft); }
.progress-count { display: flex; justify-content: space-between; font-size: 13px; line-height: 1.3; }
#step-count { color: var(--soft); font-weight: 700; }
#step-left { color: var(--quiet); }

/* the steps: one to a screen. While two cross-fade they share one cell. */
.steps { display: grid; }
.steps.is-moving { overflow: hidden; }
/* A page opened at a step's address (#step-4) is scrolled to that step by the browser. The margin is
   everything that sits above a step, so the page opens at its very top, with the shop's name in view. */
.step { grid-area: 1 / 1; min-width: 0; display: flex; flex-direction: column; gap: 14px; padding-top: 18px; scroll-margin-top: 200px; }
.step-title { font-size: 36px; line-height: 1.06; }
@media (prefers-reduced-motion: no-preference) {
  .step.is-entering { animation: step-in 220ms cubic-bezier(0.16, 1, 0.3, 1) both; }
  .step.is-leaving { animation: step-out 220ms cubic-bezier(0.16, 1, 0.3, 1) both; pointer-events: none; }
}
@keyframes step-in { from { opacity: 0; transform: translateX(calc(12px * var(--way, 1))); } to { opacity: 1; transform: none; } }
@keyframes step-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(calc(-12px * var(--way, 1))); } }

/* step 1: the photo */
.photos-field { display: flex; flex-direction: column; gap: 14px; }
.photo-zone { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; height: 176px; border: 1.5px dashed var(--soft); border-radius: 6px; background: rgba(233, 214, 168, 0.06); font-size: 18px; font-weight: 700; cursor: pointer; transition: background-color 120ms ease-out; }
.photo-zone:hover, .photo-zone.is-over { background: rgba(233, 214, 168, 0.12); }
.photo-zone:has(:focus-visible) { outline: 2px solid var(--soft); outline-offset: 3px; }
@supports not selector(:has(*)) { .photo-zone:focus-within { outline: 2px solid var(--soft); outline-offset: 3px; } }
/* once a photo is in, the ask for another is a single line */
.has-photos .photo-zone { flex-direction: row; gap: 10px; height: 56px; font-size: 16px; }
.has-photos .photo-zone .icon { width: 22px; height: 22px; }
.previews { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.previews:empty { display: none; }
.preview { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: 13px; line-height: 1.35; }
.preview img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 3px; border: 1px solid var(--edge-faint); }
.preview.uploading img { opacity: 0.5; }
.preview .file { color: var(--muted); overflow-wrap: anywhere; }
.preview.failed .file { color: var(--alert); }
.preview .remove { align-self: flex-start; min-height: 44px; padding: 0; border: 0; background: none; color: var(--soft); font: inherit; text-decoration: underline; text-underline-offset: 0.18em; text-decoration-thickness: 1px; cursor: pointer; }
.preview .remove:hover { color: var(--ink); }
.later-hint { color: var(--soft); }
.tips { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.tips li { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; line-height: 1.4; }
.tips .icon { margin-top: 1px; }
/* the photo tips wait behind a small link, and open in place */
.more summary { display: inline-flex; align-items: center; min-height: 44px; color: var(--soft); font-size: 14px; text-decoration: underline; text-underline-offset: 0.18em; text-decoration-thickness: 1px; cursor: pointer; list-style: none; }
.more summary::-webkit-details-marker { display: none; }
.more summary:hover { color: var(--ink); }
.more .tips { padding: 4px 0 6px; }

/* step 2: the colour. A picture of the figure, then a row for each choice. */
.shot.is-capture img, .figure-page-picture img { width: 100%; height: 250px; object-fit: cover; object-position: 50% 40%; border-radius: 3px; background: var(--well); }
/* A real photograph is set as a photograph: its own shape, never cropped, inside a soft gold hairline.
   Until it has arrived its frame holds the tone of a field, so it reads as a plate waiting, not a hole. */
img.photograph { width: 100%; height: auto; border: 1px solid var(--edge); border-radius: 2px; background: var(--well); }
.options { display: flex; flex-direction: column; gap: 8px; }
.opt { display: block; cursor: pointer; }
.opt-box { display: flex; align-items: center; gap: 12px; height: 58px; padding: 0 14px; border: 1px solid var(--edge-faint); border-radius: 6px; font-size: 16px; line-height: 1.2; }
.opt-name { flex: 1; min-width: 0; }
.opt-price { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* the tick's place is always kept, and the name keeps its weight, so the longest name sits the same chosen or not */
.opt .tick { visibility: hidden; }
.opt:hover .opt-box { border-color: var(--edge); }
/* chosen: a soft gold border, a faint gold wash, and a tick */
.opt input:checked + .opt-box { padding: 0 13.5px; border: 1.5px solid var(--soft); background: var(--wash); }
.opt input:checked + .opt-box .tick { visibility: visible; }
.opt input:focus-visible + .opt-box { outline: 2px solid var(--soft); outline-offset: 3px; }
.swatch { flex: none; width: 24px; height: 24px; border-radius: 50%; }
.swatch-gold { background: var(--gold); }
.swatch-copper { background: var(--copper); }
.swatch-request { width: 22px; height: 22px; margin: 0 1px; border: 1.5px dashed var(--soft); }
#colour-request-field { margin-top: 6px; }

/* step 3: the last details, as rows under soft gold hairlines */
.rows { display: flex; flex-direction: column; }
.tick-row, .qty-row { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 8px 0; border-top: 1px solid var(--hair-faint); font-size: 15px; line-height: 1.25; }
.tick-row { cursor: pointer; }
.tick-row > span { flex: 1; }
.box { appearance: none; -webkit-appearance: none; flex: none; width: 22px; height: 22px; margin: 0; border: 1.5px solid rgba(233, 214, 168, 0.6); border-radius: 3px; background: transparent center / 16px 16px no-repeat; cursor: pointer; }
.box:checked { border-color: var(--soft); background-color: var(--wash); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e9d6a8' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E"); }
#gift-field { padding: 0 0 14px; }
.qty-row label { flex: 1; color: var(--ink); font-size: 15px; }
.stepper { display: flex; align-items: center; gap: 4px; }
.step-btn { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; border: 1px solid var(--edge); border-radius: 6px; background: transparent; color: var(--ink); cursor: pointer; }
.step-btn .icon { color: var(--ink); }
.step-btn:hover { border-color: var(--soft); background: var(--wash); }
.step-btn[disabled] { opacity: 0.35; cursor: default; background: transparent; border-color: var(--edge); }
.order .stepper input { width: 44px; height: 44px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--ink); font: 17px/1 var(--sans); text-align: center; appearance: textfield; -moz-appearance: textfield; }
.stepper input::-webkit-inner-spin-button, .stepper input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
#quantity-hint, #rush-hint { padding: 0 0 14px 32px; }
#quantity-error, #rush-error { padding: 0 0 14px 32px; }
.rows + .field { padding-top: 16px; border-top: 1px solid var(--hair-faint); }

/* step 4: check the order */
.summary { margin: 0; }
.sum-row { padding: 10px 0 6px; border-top: 1px solid var(--hair-faint); }
.sum-row dt { color: var(--quiet); font-size: 13px; }
.sum-row dd { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin: 0; }
.sum-value { flex: 1; min-width: 0; padding-top: 2px; font-size: 16px; line-height: 1.4; overflow-wrap: anywhere; white-space: pre-line; }
.sum-value.thumbs { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 6px; white-space: normal; }
.sum-value.thumbs img { width: 40px; height: 52px; object-fit: cover; border-radius: 2px; border: 1px solid var(--edge-faint); }
.change { display: inline-flex; align-items: center; min-height: 44px; margin-top: -8px; padding: 0 2px; font-size: 14px; }
/* what the multi-buy takes off, set like the total's row but quieter, just above it */
.discount { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin: 0; padding: 12px 0; border-top: 1px solid var(--hair); font-size: 15px; color: var(--soft); }
.discount strong { font-weight: 700; font-size: 17px; font-variant-numeric: tabular-nums; }
.discount + .total { border-top-color: var(--hair-faint); }
.total { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 14px 0; border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair); font-size: 15px; }
.total strong { font-weight: 700; font-size: 24px; line-height: 1; font-variant-numeric: tabular-nums; }
/* the four notes: the same pattern as the photo tips on step 1, an icon and a line */
.notes { gap: 12px; }
.notes li { line-height: 1.45; }
.christmas { color: var(--soft); font-size: 14px; line-height: 1.5; }

/* the basket: one box for the parcel, each pet a row, then the parcel's own choices (design/basket-layouts/, The basket page) */
.basket { max-width: 38rem; padding-top: 16px; display: flex; flex-direction: column; gap: 20px; }
/* The basket is drawn by basket.js from what this browser holds, so the page arrives with only its heading.
   A screen's height keeps the foot below the fold until the basket is drawn, so it never jumps down in view
   (it jumped 0.22 on a phone when the script came late). */
body.basketing main { min-height: 100vh; }
.basket h1 { font-size: 36px; line-height: 1.06; }
.basket-note { display: flex; align-items: center; gap: 10px; margin: 0; padding: 4px 4px 4px 12px; min-height: 44px; border-radius: 6px; background: var(--wash); color: var(--soft); font-size: 15px; line-height: 1.35; }
.basket-note .undo { margin-left: auto; min-height: 44px; padding: 0 10px; border: 0; background: transparent; color: var(--soft); font: 600 15px var(--sans); text-decoration: underline; text-underline-offset: 0.18em; text-decoration-thickness: 1px; cursor: pointer; }
.basket-note > span { min-width: 0; overflow-wrap: anywhere; }
.basket-empty p { margin: 0; }
.basket-empty .made-photos { max-width: 22rem; margin-top: 32px; }
.basket-form { display: flex; flex-direction: column; gap: 16px; }
.parcel { padding: 0 14px; border: 1px solid var(--hair); border-radius: 6px; }
.pets { list-style: none; margin: 0; padding: 0; }
.pet { display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; column-gap: 14px; align-items: start; padding: 14px 0; }
.pet + .pet { border-top: 1px solid var(--hair-faint); }
.pet .thumb { width: 56px; height: 72px; border-radius: 3px; object-fit: cover; border: 1px solid var(--edge-faint); background: var(--well); }
.pet .later, .pet .blank { box-sizing: border-box; display: flex; align-items: center; justify-content: center; padding: 2px; border: 1.5px dashed var(--edge); text-align: center; color: var(--quiet); font-size: 12px; line-height: 1.2; }
.pet.is-gone { display: flex; align-items: center; }
.gone-words { margin: 0; display: flex; flex-wrap: wrap; align-items: center; column-gap: 12px; color: var(--soft); font-size: 15px; line-height: 1.35; }
.gone-words span { min-width: 0; overflow-wrap: anywhere; }
.gone-words .undo { min-height: 44px; padding: 0; border: 0; background: transparent; color: var(--soft); font: 600 15px var(--sans); text-decoration: underline; text-underline-offset: 0.18em; text-decoration-thickness: 1px; cursor: pointer; }
.pet-words { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pet-name { margin: 0; font-family: var(--sans); font-size: 17px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; text-wrap: wrap; }
.pet-what { margin: 0; color: var(--muted); font-size: 14px; line-height: 1.4; overflow-wrap: anywhere; }
.pet-actions { margin: 0; display: flex; gap: 18px; }
.pet-actions a, .pet-actions button { display: inline-flex; align-items: center; min-height: 44px; margin: 0; padding: 0; border: 0; background: transparent; color: var(--soft); font: 14px var(--sans); text-decoration: underline; text-underline-offset: 0.18em; text-decoration-thickness: 1px; cursor: pointer; }
.pet-error { margin: 4px 0 0; }
.pet-price { margin: 0; font-size: 16px; font-weight: 700; line-height: 1.3; font-variant-numeric: tabular-nums; }
.add-more { display: flex; flex-direction: column; gap: 4px; padding: 10px 0 14px; border-top: 1px solid var(--hair-faint); }
.add-pet { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; color: var(--soft); font-size: 16px; font-weight: 600; text-decoration: none; }
.add-pet .icon { color: currentColor; }
.nudge { margin: 0 0 0 30px; color: var(--quiet); font-size: 14px; line-height: 1.4; }
.basket-full { margin: 0; padding: 14px 0; border-top: 1px solid var(--hair-faint); color: var(--muted); font-size: 14px; }
.basket .page-action { margin-top: 20px; }
/* under the box: the saving on its own line, then the total between two rules */
.basket-sum { display: flex; flex-direction: column; gap: 16px; }
.basket .discount { padding: 0; border-top: none; }
.basket #gift-field { padding-left: 32px; }
.basket-made { display: none; }
/* hover only where there is a pointer that hovers, so a tapped link never stays lit */
@media (hover: hover) {
  .basket-link:hover { color: var(--soft); }
  .basket-note .undo:hover, .gone-words .undo:hover, .pet-actions a:hover, .pet-actions button:hover, .add-pet:hover { color: var(--ink); }
}
.basket .discount + .total { border-top-color: var(--hair); }

/* the bar pinned to the bottom of the screen: the price, and the way back and on */
body.ordering { padding-bottom: var(--bar-height); }
html:has(body.ordering) { scroll-padding-bottom: calc(var(--bar-height) + 20px); }
.bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px max(20px, env(safe-area-inset-right, 0px)) var(--bar-foot) var(--side); border-top: 1px solid var(--hair); background: var(--well); }
.bar-price { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.bar-price .amount { font-size: 22px; font-weight: 700; line-height: 1.2; white-space: nowrap; font-variant-numeric: tabular-nums; }
.bar-postage { color: var(--quiet); font-size: 12px; line-height: 1.3; }
/* on the last step a phone has room for the two buttons only; the total is in the summary above */
.bar[data-last] .bar-price { display: none; }
/* "Opening the payment page" is the longest thing this button says: on the narrowest phones it takes two lines */
.bar[data-last] #submit { flex: 1; min-width: 0; padding: 0 8px; font-size: 15px; line-height: 1.15; white-space: normal; text-align: center; text-wrap: balance; }
@media (max-width: 379.98px) { .bar[data-last] #back { padding: 0 14px; } }
/* the basket's bar: its total beside the payment button, at every width */
.basket-form .bar .bar-price { display: flex; }
.basket-form .bar #submit { flex: none; padding: 0 20px; font-size: 16px; line-height: 1.15; white-space: nowrap; text-align: center; }
.basket-form .bar .bar-postage { text-wrap: balance; }
@media (max-width: 359.98px) { .basket-form .bar #submit { flex: 0 1 auto; min-width: 0; white-space: normal; } }
/* While a field is being typed in on a phone, the bar leaves the bottom of the screen and waits at the
   end of the step, so it can never sit between the keyboard and the field. */
@media (hover: none) and (pointer: coarse) {
  .is-typing .bar { position: static; margin: 28px calc(var(--side) * -1) 0; padding-bottom: 18px; }
}

/* the prompt when Next is pressed with no photo: a sheet at the foot of a phone's screen */
.prompt { width: 100%; max-width: none; margin: auto 0 0; padding: 26px var(--side) calc(24px + env(safe-area-inset-bottom, 0px)); border: 0; border-top: 1px solid var(--edge); background: var(--well); color: var(--ink); }
.prompt::backdrop { background: rgba(8, 10, 8, 0.66); }
.prompt h2 { font-size: 26px; line-height: 1.12; }
.prompt p { margin-top: 10px; color: var(--muted); font-size: 15px; line-height: 1.5; }
.prompt-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 22px; }
.prompt-actions .btn { width: 100%; }

/* under the steps: how it works, who makes them, the questions */
.how, .maker, .faq { margin-top: 56px; padding-top: 36px; border-top: 1px solid var(--hair); }
.how h2, .faq h2 { font-size: 26px; line-height: 1.12; }
.how ol { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 16px; }
.how li { display: flex; align-items: flex-start; gap: 14px; font-size: 17px; line-height: 1.35; }
.how li .icon { margin-top: 1px; }
.maker .made-row { max-width: calc(var(--shots, 1) * 30rem); }
.faq h2 { margin-bottom: 18px; }
.faq details { border-top: 1px solid var(--hair-faint); }
.faq details:last-of-type { border-bottom: 1px solid var(--hair-faint); }
.faq summary { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 56px; padding: 12px 0; font-size: 17px; line-height: 1.3; cursor: pointer; list-style: none; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--soft); }
.faq details[open] .upright { display: none; }
.faq details p { max-width: 36rem; padding: 0 0 18px; color: var(--muted); font-size: 15px; line-height: 1.55; }

/* the thank-you page, the send-a-photo page, the legal pages and the pages for when something is wrong */
.page { max-width: 38rem; padding-top: 32px; }
.page h1 { font-size: 36px; line-height: 1.06; }
.page h1 + p, .page .ref + p { margin-top: 16px; }
.page .ref { margin-top: 10px; color: var(--soft); font-size: 15px; letter-spacing: 0.04em; }
.page .ref strong { font-weight: 700; }
/* the line under the thank-you words that says where the confirmation email is */
.page .mail-note { margin-top: 12px; color: var(--muted); }
.page-action { margin-top: 28px; }
/* After paying, and after a photo is sent: the figure in the colour ordered, then the words. */
.figure-page-picture { margin-bottom: 26px; }
.sent { margin-top: 22px; }
.new-photo .order { display: flex; flex-direction: column; gap: 14px; margin-top: 22px; }
.legal h2 { margin: 36px 0 10px; font-size: 24px; line-height: 1.15; }
.legal p, .legal li { line-height: 1.6; }
.legal p + p, .legal ul + p, .legal p + ul { margin-top: 12px; }
.legal ul { margin: 0; padding-left: 20px; }
.legal li + li { margin-top: 8px; }
.legal li::marker { color: var(--soft); }
.legal .draft { margin: 18px 0; border: 1px solid var(--alert); border-radius: 6px; padding: 10px 14px; color: var(--alert); font-size: 15px; }
.trader { margin-top: 4px; }
.credit { margin: 4px 0 0; }
/* the studio's name is 44 pixels to press, like the links above it */
.credit a { display: inline-flex; align-items: center; min-height: 44px; color: var(--muted); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
.credit a:hover { color: var(--ink); }

/* a wide screen: the step sits to the right of a held picture of the figure */
@media (min-width: 900px) {
  .page h1 { font-size: 44px; }
  header.site, main, footer.site { padding-left: 32px; padding-right: 32px; }
  header.site { padding-top: 18px; }
  header.site .name { padding: 9px 0; font-size: 26px; }
  .order-page { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); column-gap: 72px; align-items: start; padding-top: 20px; }
  .figure-panel { order: 0; position: sticky; top: 24px; }
  .figure-panel .held { display: block; }
  .figure-panel .held .is-capture img { height: auto; aspect-ratio: 4 / 5; min-height: 320px; max-height: calc(100vh - 320px); object-position: 50% 62%; }
  .step-picture { display: none; }
  .step-title { font-size: 44px; }
  body.ordering { padding-bottom: 0; }
  html:has(body.ordering) { scroll-padding-bottom: 110px; }
  /* the bar stays in the step's own column, and holds to the bottom of the screen while the step is longer than it */
  .progress { padding-top: 0; }
  .bar, .is-typing .bar { position: sticky; margin: 28px 0 0; padding: 12px 20px 18px; border: 1px solid var(--hair); }
  .bar[data-last] .bar-price { display: flex; }
  .bar[data-last] #submit { flex: none; padding: 0 28px; font-size: 16px; white-space: nowrap; }
  /* the figure held on the left and the words on the right, on the order page's own grid */
  .page.figure-page.thanks, .page.figure-page.is-sent { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); column-gap: 72px; align-items: start; max-width: none; padding-top: 20px; }
  .figure-page-picture { margin-bottom: 0; }
  .figure-page-picture img { height: auto; aspect-ratio: 4 / 5; min-height: 320px; max-height: calc(100vh - 150px); object-position: 50% 62%; }
  .figure-page-words { max-width: 34rem; padding-top: 12px; }
  /* in the middle of the screen, as a small panel */
  .prompt { width: 440px; margin: auto; padding: 30px 30px 28px; border: 1px solid var(--edge); border-radius: 6px; }
  .how ol { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
  .how, .maker, .faq { margin-top: 72px; padding-top: 44px; }
  .faq details, .faq h2 { max-width: 46rem; }
}
/* on a wide screen the basket is two columns: the pets and the parcel's choices on the left, and on the right the
   total and the payment button, held on screen while the list is longer than it */
@media (min-width: 900px) {
  .basket { max-width: none; padding-top: 20px; }
  .basket h1 { font-size: 44px; }
  .basket-said { max-width: calc(100% - 22.5rem - 56px); }
  .basket-empty { max-width: 38rem; }
  .basket-form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 22.5rem); column-gap: 56px; align-items: start; }
  .basket-sum { position: sticky; top: 24px; }
  .basket-sum .bar { position: static; margin: 4px 0 0; padding: 0; border: none; background: none; }
  .basket-made { display: block; margin-top: 8px; }
  .basket-sum .bar .bar-price { display: none; }
  .basket-sum .bar #submit { flex: 1; padding: 0 22px; }
}
/* between a phone and a wide screen there is room for the price beside the last step's two buttons */
@media (min-width: 480px) and (max-width: 899.98px) {
  .bar[data-last] .bar-price { display: flex; }
  .bar[data-last] #submit { flex: none; padding: 0 22px; font-size: 16px; white-space: nowrap; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}
