/* ==========================================================================
   Krishen Khanna — storefront add-on (editions, cart, checkout, order, contact, legal)
   Linked only on those pages; builds on the tokens in main.css. The site is always dark: every colour here is a
   main.css token (--white is the page black #0A0A0A, --ink / --ink-2 the light text, --seal the decorative red,
   --seal-text red text, --error errors). The one literal is the zoom viewer's #0a0a0a stage.
   ========================================================================== */

/* ------------------------------------------------------------ layout helpers */
.container--narrow { max-width: calc(880px + 2 * var(--gutter)); }

/* ------------------------------------------------------------ live price / availability */
.price { font-size: 1.65rem; letter-spacing: .04em; color: var(--ink); }
.price--lg { font-size: 2.1rem; }
.price:empty::before, .avail:empty::before { content: "\00a0"; }
.avail { font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); }
.avail.is-low { color: var(--seal-text); }
.avail.is-out { color: var(--seal-text); }
.avail.is-error { color: var(--grey-2); text-transform: none; letter-spacing: 0; }
.product-card__live, .product__live { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; margin: 0 0 1.2em; }
.product-card__live { margin-bottom: 12px; }   /* the catalogue card's price, the last line of the link */

/* ------------------------------------------------------------ editions index */
.shop-intro { margin-bottom: var(--gap-y); }
/* the intro's line beside the print wraps into even lines, so "of 75." never trails alone on a wide screen (Safari
   17.5+; older Safari wraps it plainly, with "75." still held to "of" by the no-break space in the curation note) */
.shop-intro .lede, .shop-preview__intro .lede { text-wrap: balance; }
/* the one GST line that closes /shop/ and every product page ("Prices are exclusive of GST."), after
   the last section or the pager: quiet, never beside a price */
.section .shop-gst { max-width: none; margin: var(--section-y) 0 0; color: var(--grey-1); text-align: center; }
/* an empty catalogue: "Editions coming soon" and the enquiry, on the page black with a hairline above */
.shop-soon { max-width: 62ch; padding-top: 30px; border-top: 1px solid var(--hairline); }
.shop-soon__title { font-size: 1.65rem; letter-spacing: var(--track); text-transform: uppercase; color: var(--ink); margin: 0 0 1em; }
.shop-soon p { color: var(--grey-1); }
.shop-soon__actions { margin: 30px 0 0; }
/* Fixed square image window so the captions of every card sit on one baseline; the print is
   letterboxed (object-fit: contain) and centred in the window both ways, on the page black with no
   band behind it (landscapes resting on the bottom edge broke the symmetry).
   Square rather than 4:5 since 2026-09-16: ten of the fourteen prints are landscape or panoramic. */
/* the whole card is one link (the image, the title and the price, nothing else): the page's focus
   ring goes round the card; on a pointer the title underlines, the work itself never moves or dims */
.product-card__link { display: block; color: inherit; text-decoration: none; -webkit-tap-highlight-color: transparent; }
@media (hover: hover) and (pointer: fine) {
  .product-card__link:hover .product-card__title { text-decoration: underline; text-underline-offset: .25em; text-decoration-thickness: 1px; }
}
.product-card__media { display: block; aspect-ratio: 1 / 1; overflow: hidden; }
.product-card__media picture { display: block; width: 100%; height: 100%; }
.product-card__media img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: 50% 50%; }
/* one card per row: no neighbour to align captions with, so each print takes its own height
   instead of floating in empty bands (a panorama would otherwise sit in ~150px of blank above and below) */
@media (max-width: 460px) {
  .product-card__media { aspect-ratio: auto; }
  .product-card__media picture, .product-card__media img { height: auto; }
}
/* two or three per row: each row's image area is as tall as its tallest print (a portrait caps it at a
   square), so a row of landscapes does not float in tall empty bands; every print stays centred in it and
   the captions of a row share one line. Card = two rows of the shop grid (subgrid): image, then text. The
   grid's own row gap moves into the text block so the 50px between rows stays exact. Without subgrid or
   container units the square windows above apply. */
@supports (grid-template-rows: subgrid) and (width: 1cqw) {
  @media (min-width: 461px) {
    .shop-grid { row-gap: 0; margin-bottom: calc(-1 * var(--gap-y)); }
    .product-card { display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 0; }
    .product-card__link { display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 0; }   /* the card's two rows, inside the link */
    .product-card__media { aspect-ratio: auto; container-type: inline-size; display: flex; align-items: center; justify-content: center; }
    .product-card__media picture { height: auto; }
    .product-card__media img { height: auto; max-height: 100cqw; }
    /* the row gap sits under the card, outside its link, so the focus ring closes under the price (a
       subgrid's padding is added to its last row, as the body's was) */
    .product-card { padding-bottom: var(--gap-y); }
  }
}
.product-card__placeholder { width: 100%; height: 100%; background: var(--bg-raised); }
/* a short last row is centred: the grid is laid out in half-columns (6 at three per
   row, 4 at two per row) and every card spans two, so the leftover cards can start half a card in.
   Card widths and the 40px gutters are exactly those of the plain three- and two-column grids. */
@media (min-width: 769px) {
  .grid.shop-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .shop-grid > .product-card { grid-column: span 2; }
  .shop-grid > .product-card:nth-child(3n+1):nth-last-child(2) { grid-column: 2 / span 2; }   /* two left over */
  .shop-grid > .product-card:nth-child(3n+1):last-child { grid-column: 3 / span 2; }          /* one left over */
}
@media (min-width: 461px) and (max-width: 768px) {
  .grid.shop-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .shop-grid > .product-card { grid-column: span 2; }
  .shop-grid > .product-card:nth-child(2n+1):last-child { grid-column: 2 / span 2; }          /* one left over */
}
.product-card__note { font-size: var(--fs-meta); line-height: 2rem; color: var(--grey-1); margin: -4px 0 12px; }
.product-card__body { padding-top: var(--cap-gap); display: flex; flex-direction: column; }
.product-card__body > .product-card__live { margin-top: auto; }   /* the prices line up across a row even when one title runs to two lines */
/* the title and the price centred under the work, which is centred in its window (left-aligned, a
   portrait's or a watch's caption started up to 90 px left of the picture) */
.shop-grid .product-card__body { align-items: center; text-align: center; }
.shop-grid .product-card__live { justify-content: center; }
.product-card__title { font-size: 1.65rem; line-height: 2.4rem; margin: 0 0 .3em; }
/* the buy row waits for /api/products: the enquiry keeps its place, unseen, until cart.js knows which control applies */
.js [data-pending] { visibility: hidden; }

/* ------------------------------------------------------------ product */
.product__media img { width: 100%; height: auto; }
/* the order page's facts (order.html) */
.spec { margin: 0 0 30px; border-top: 1px solid var(--hairline); }
.spec__row { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 0 20px; padding: 10px 0; border-bottom: 1px solid var(--hairline); }
.spec dt { font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); line-height: 2.1rem; padding-top: .35em; }
.spec dd { margin: 0; }
/* the "Signed" line (with a signature box): zoom.js makes it a button that opens the print zoomed in on the signature;
   the padding gives it the row's height as a hit area without moving the text */
.spec__zoom { font: inherit; color: inherit; text-align: left; background: none; border: 0; border-radius: 0; margin: -10px 0; padding: 10px 0; cursor: zoom-in;
  text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 1px; -webkit-tap-highlight-color: transparent; }
.spec__zoom:focus-visible { outline: 2px solid var(--ink-2); outline-offset: 2px; }
.spec__zoom.is-quiet-focus:focus-visible { outline: none; }
.product__buy { padding: 26px 0; border-bottom: 1px solid var(--hairline); margin-bottom: 30px; }
.product__form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 16px; margin: 0 0 1.2em; }
.product__form .btn { margin: 0; }
.product__legal { max-width: 52ch; }
.product__blurb p { max-width: 62ch; }
.product__blurb > :last-child { margin-bottom: 0; }   /* the column's last block: 120 to the footer, not 143 */

/* ------------------------------------------------------------ the print: tap to zoom (zoom.js), AR badge (ar.js) */
.product__frame { position: relative; }
.has-zoom .product__zoom { cursor: zoom-in; }
.product__zoom:focus-visible { outline: 2px solid var(--ink-2); outline-offset: 4px; }
.product__zoom.is-quiet-focus:focus-visible { outline: none; }   /* closed with a pointer: focus is back, without the keyboard ring */
/* the media column is pinned (main.css .split__media): a tall print is capped so it fits inside it, uncropped
   and centred in the column; the frame is the image's own width so the AR badge sits on the image's corner. The width
   comes from the print's ratio (--ratio, set by product.html), not the loaded image, so the print's box (and
   its dominant-colour background) is there before the file arrives */
@media (min-width: 1024px) {
  .product__frame { width: min(100%, calc((100vh - var(--header-h) - 40px) * var(--ratio, 1))); max-width: 100%; margin-inline: auto; }   /* centred in its column */
  .product__media .product__zoom img { width: 100%; height: auto; }
}
.zoomer:focus { outline: none; }   /* focus starts on the dialog itself; its controls show their own ring */

/* ------------------------------------------------------------ deep zoom (zoom.js); dark like the lightbox */
.zoomer {
  position: fixed; inset: 0; z-index: 150;
  width: 100%; height: auto; max-width: none; max-height: none;   /* inset 0 fills the visible viewport, toolbars included, in every Safari */
  margin: 0; padding: 0; border: 0;
  background: #0a0a0a; color: var(--ink-2);   /* opaque: nothing of the page ghosts through the detail */
  overflow: hidden; overscroll-behavior: contain;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
.zoomer[open], div.zoomer { display: block; }
.zoomer::backdrop { background: #0a0a0a; }
/* its padding is the frame the image fits into at "fit" (clear of the close button and the bottom bar) */
.zoomer__stage { position: absolute; inset: 0; overflow: hidden; padding: 64px var(--gutter) 76px; touch-action: none; cursor: zoom-in; }
.zoomer.is-zoomed .zoomer__stage { cursor: grab; }
.zoomer.is-zoomed.is-dragging .zoomer__stage { cursor: grabbing; }
.zoomer__canvas { position: absolute; left: 0; top: 0; }
.zoomer__img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: none; pointer-events: none; -webkit-user-drag: none; }
.zoomer__full { opacity: 0; }
.zoomer__full.is-loaded { opacity: 1; }
.zoomer__btn {
  min-width: 44px; min-height: 44px; padding: 0 16px;
  font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase;
  color: var(--ink); background: var(--white);   /* opaque page black: reads as a control, not a tint on the art */
}
.zoomer__btn:focus-visible { color: var(--ink-2); }
/* hover only where there is a pointer that hovers: on a touch screen a tapped control would keep the hover look */
@media (hover: hover) and (pointer: fine) {
  .zoomer__btn:hover { color: var(--ink-2); }
}
.zoomer__btn[aria-disabled="true"] { color: var(--grey-3); cursor: default; }
.zoomer :focus-visible { outline-color: var(--ink-2); }
.zoomer__close { position: absolute; z-index: 2; top: 12px; right: var(--gutter); }
.zoomer__loading {
  position: absolute; z-index: 2; top: 12px; left: var(--gutter); margin: 0; line-height: 44px;
  font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-2);
  animation: zoomer-pulse 1.6s ease-in-out infinite alternate;
}
@keyframes zoomer-pulse { from { opacity: 1; } to { opacity: .35; } }
.zoomer__bar {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 8px 30px;
  padding: 14px var(--gutter) 16px;
  pointer-events: none;   /* a drag that starts on the empty bar still moves the image */
}
.zoomer__caption { display: flex; flex-wrap: wrap; gap: 0 20px; margin: 0; font-size: var(--fs-meta); line-height: 2.1rem; letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); }
.zoomer__hint { text-transform: none; letter-spacing: 0; color: var(--grey-2); }
/* zoomed in, the bar lies over the print: the caption steps aside (the title stays the dialog's name) */
.zoomer.is-zoomed .zoomer__caption { visibility: hidden; }
.zoomer__zoom { display: flex; gap: 2px; flex: 0 0 auto; pointer-events: auto; }
.zoomer__zoom .zoomer__btn { font-size: 1.6rem; letter-spacing: 0; }
.zoomer__zoom [data-zoom="fit"] { font-size: var(--fs-meta); letter-spacing: var(--track); }
@media (max-width: 640px) {
  .zoomer__stage { padding: 60px var(--gutter) 70px; }
  .zoomer__close { top: 8px; }
  .zoomer__loading { top: 8px; }
  .zoomer__bar { padding: 10px var(--gutter) 12px; }
  .zoomer__caption { flex-direction: column; }
}
/* a phone on its side gives the print the height */
@media (max-height: 500px) {
  .zoomer__stage { padding: 52px var(--gutter) 54px; }
  .zoomer__close, .zoomer__loading { top: 4px; }
  .zoomer__bar { padding-block: 5px; }
  .zoomer__hint { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .zoomer__loading { animation: none; }
}

/* ------------------------------------------------------------ buttons (states) */
.btn[disabled], .btn[aria-disabled="true"] { opacity: .35; cursor: not-allowed; pointer-events: none; }
.btn.is-busy { opacity: .6; cursor: progress; pointer-events: none; }
.btn.is-added { background: var(--seal); border-color: var(--seal); color: var(--ink-2); }

/* ------------------------------------------------------------ forms */
.field { display: block; margin-bottom: 22px; }
.field__label { display: block; font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); margin-bottom: 8px; }
.field__opt { text-transform: none; letter-spacing: 0; color: var(--grey-2); }
.field__hint { display: block; font-size: var(--fs-meta); line-height: 2rem; color: var(--grey-2); margin-top: 6px; }
.field input:not([type="checkbox"]), .field select, .field textarea {
  display: block; width: 100%;
  font: inherit; color: var(--ink);
  font-size: max(16px, 1em); /* never below 16px: iOS Safari zooms the page into any smaller control */
  background: var(--bg-raised);
  border: 1px solid var(--grey-3);   /* a field's edge is its only outline: 3:1 against the page, unlike the hairline */
  border-radius: 0;
  color-scheme: dark;   /* the native select list, date pickers and spelling menus follow the dark site */
  padding: 12px 14px;
  line-height: 1.6;
  transition: border-color var(--t-hover) ease;
  -webkit-appearance: none; appearance: none;
}
.field select {
  padding-right: 40px;
  background-image: linear-gradient(45deg, transparent 50%, var(--grey-1) 50%), linear-gradient(135deg, var(--grey-1) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
.field textarea { resize: vertical; min-height: 160px; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--ink-2); }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--ink-2); outline-offset: 2px; }
.field.is-invalid input, .field.is-invalid select, .field.is-invalid textarea { border-color: var(--error); }
/* browser autofill paints its own light fill: keep the field dark and its text light */
.field input:-webkit-autofill, .field input:-webkit-autofill:hover, .field input:-webkit-autofill:focus,
.field select:-webkit-autofill, .field textarea:-webkit-autofill {
  box-shadow: 0 0 0 1000px var(--bg-raised) inset; -webkit-text-fill-color: var(--ink); caret-color: var(--ink);
}
.field__error { display: block; font-size: var(--fs-meta); line-height: 2rem; color: var(--error); margin-top: 6px; }
.field--inline { display: inline-block; margin: 0 0 8px; min-width: 110px; }
.field--inline select { width: auto; min-width: 90px; }
.field--check { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 12px; align-items: start; margin: 30px 0; }
.field--check input { width: 18px; height: 18px; margin: .45em 0 0; accent-color: var(--ink-2); color-scheme: dark; }
.field--check label { max-width: 62ch; }
.field--check a { text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 1px; }   /* the policy links read as links */
.field--check .field__error { grid-column: 2; margin-top: 0; }
.fieldset { border: 0; padding: 0; margin: 0 0 20px; min-width: 0; }
.fieldset legend { padding: 0; margin-bottom: 18px; }
.form-grid { display: grid; grid-template-columns: 1fr; gap: 0 var(--gap-x); }
@media (min-width: 640px) {
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .form-grid__full { grid-column: 1 / -1; }
}
.hp { position: absolute !important; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* ------------------------------------------------------------ notices */
.notice {
  font-size: 1.45rem; line-height: 2.6rem;
  border-left: 1px solid var(--ink-2);
  padding: 10px 0 10px 20px;
  margin: 0 0 24px;
  max-width: 62ch;
}
.notice--info { border-color: var(--grey-2); color: var(--grey-1); }
.notice--error { border-color: var(--error); color: var(--error); }
.notice--ok { border-color: var(--ink-2); color: var(--ink); }

/* ------------------------------------------------------------ cart table */
.cart-table { width: 100%; border-collapse: collapse; margin: 10px 0 24px; }
.cart-table th, .cart-table td { text-align: left; vertical-align: middle; padding: 16px 12px 16px 0; border-bottom: 1px solid var(--hairline); }
.cart-table thead th { font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); font-weight: var(--fw); padding-top: 0; }
.cart-table tfoot th { font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); font-weight: var(--fw); border-bottom: 0; }
.cart-table tfoot td { border-bottom: 0; }
.cart-table__num { text-align: right !important; white-space: nowrap; }
.cart-table__th-item { width: 50%; }
.cart-item { display: flex; align-items: center; gap: 18px; }
.cart-thumb { flex: 0 0 72px; width: 72px; }
.cart-thumb img { width: 72px; height: auto; }
.cart-thumb--empty { height: 90px; background: var(--bg-raised); }
.cart-item__title { font-size: 1.45rem; text-transform: uppercase; letter-spacing: var(--track); margin: 0 0 .2em; }
.cart-item__title a { text-decoration: none; }
.cart-item__meta { font-size: var(--fs-meta); line-height: 2rem; color: var(--grey-1); margin: 0; }
.cart-item__warn { font-size: var(--fs-meta); line-height: 2rem; color: var(--error); margin: .3em 0 0; }
.qty { display: inline-flex; align-items: center; border: 1px solid var(--grey-3); }
.qty__btn { width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.6rem; color: var(--grey-1); } /* 44 x 44 tap target */
.qty__btn:focus-visible { color: var(--ink); background: var(--bg-raised); }
.qty__btn[disabled] { opacity: .3; cursor: not-allowed; }
.qty__val { min-width: 32px; text-align: center; font-variant-numeric: tabular-nums; }
.cart-remove { display: inline-flex; align-items: center; min-height: 44px; padding: 0; font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-2); text-decoration: underline; text-underline-offset: .2em; } /* >= 44px hit area */
.cart-remove:focus-visible { color: var(--seal-text); }
@media (hover: hover) and (pointer: fine) {   /* as the zoomer's buttons: no hover look stuck on after a tap */
  .qty__btn:hover { color: var(--ink); background: var(--bg-raised); }
  .cart-remove:hover { color: var(--seal-text); }
}
.cart-limit { margin-bottom: 16px; }
.cart-table tfoot tr[hidden] { display: none; }
.cart-table__total th, .cart-table__total td { color: var(--ink); }
.cart-actions { margin: 0; }   /* the paragraph's own 23 above; nothing after the page's last block */
.cart-empty > :last-child { margin-bottom: 0; }
@media (max-width: 640px) {
  /* stacked rows: the column headers stay for screen readers (visually hidden, not display:none), and the
     markup carries explicit table roles, which a display change would otherwise strip */
  .cart-table thead { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .cart-table, .cart-table tbody, .cart-table tfoot, .cart-table tr, .cart-table td, .cart-table th { display: block; }
  .cart-table tr { border-bottom: 1px solid var(--hairline); padding: 14px 0; }
  .cart-table td, .cart-table th { border: 0; padding: 4px 0; }
  .cart-table td[data-label]::before { content: attr(data-label); display: inline-block; min-width: 90px; font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); }
  .cart-table__num { text-align: left !important; }
  .cart-table tfoot tr { display: flex; align-items: baseline; }
  .cart-table tfoot th { min-width: 90px; }   /* the subtotal lines up with the Price and Total values */
  .cart-table tfoot tr { gap: 14px; }         /* "Shipping (India)", "Includes GST": label and value never touch */
  .cart-table__spare { display: none !important; }
}

/* ------------------------------------------------------------ checkout */
.checkout { display: grid; grid-template-columns: 1fr; gap: var(--gap-y) var(--gap-x); align-items: start; }
@media (max-width: 1024px) {
  .checkout__summary { order: -1; } /* on phones the summary comes first, above the form and the payment CTA */
}
@media (min-width: 1025px) {
  .checkout { grid-template-columns: minmax(0, 7fr) minmax(280px, 4fr); }
  .checkout__summary { position: sticky; top: calc(var(--header-h) + 20px); }
}
.checkout__summary { background: var(--bg-raised); padding: 30px; }
.checkout__summary-title { font-size: 1.65rem; margin-bottom: 1em; }
.summary { border-top: 1px solid var(--hairline); }
.summary li { display: flex; align-items: center; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--hairline); }
.summary .cart-thumb { flex-basis: 56px; width: 56px; }
.summary .cart-thumb img { width: 56px; }
.summary__body { flex: 1 1 auto; min-width: 0; }
.summary__title { margin: 0; font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; }
.summary__meta { margin: 0; font-size: var(--fs-meta); line-height: 2rem; color: var(--grey-1); }
.summary__line { white-space: nowrap; }
.summary__total { display: flex; justify-content: space-between; align-items: baseline; padding-top: 16px; font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); }
.summary__total .price { font-size: 2.1rem; }
/* prices listed "+ GST": the GST added at checkout, one line above the total */
.summary__gst { display: flex; justify-content: space-between; align-items: baseline; padding-top: 16px; margin: 0; font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); }
.summary__gst[hidden] { display: none; }
.summary__gst > :last-child { text-transform: none; letter-spacing: 0; }   /* the value ("Free", "₹…") as the cart writes it */
.summary__gst .price { font-size: 1.65rem; }
.checkout__actions { margin: 0 0 var(--para); }   /* the last field's own 22px above, a paragraph's gap below */
.checkout__pay { padding-top: 10px; }
.checkout__form form > :last-child, .checkout__pay > :last-child { margin-bottom: 0; }   /* 120 to the footer, not 143 */

/* ------------------------------------------------------------ order */
.order__head { margin-bottom: 30px; }
.status { font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; }
.status--paid { color: var(--ink); }
.status--created, .status--pending { color: var(--grey-1); }
.order__retry { margin-top: 12px; }
.status--failed, .status--cancelled, .status--refunded { color: var(--error); }
.order__items { margin-bottom: 30px; }

/* ------------------------------------------------------------ contact */
.contact__media picture { width: 100%; }
.contact__media img { width: 100%; height: auto; }
/* the photograph is 1024 px wide: no wider than it is sharp on a retina screen */
.contact__media picture { max-width: 512px; }
.contact__form { margin-top: 0; }
.contact__form > :last-child, .contact__done > :last-child { margin-bottom: 0; }
/* closing strip, as .prevnext: 60 → hairline → 30 (the split's own 50px row gap + 10) */
.contact__links { margin-top: 10px; padding-top: 30px; border-top: 1px solid var(--hairline);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 30px 40px; }
.contact__group > :last-child { margin-bottom: 0; }
.contact__address { font-style: normal; }
.contact__ids { margin-top: 12px; }
.contact__list li { margin-bottom: .4em; }
.contact__list li:last-child { margin-bottom: 0; }
/* desktop: photograph with the links beneath it | heading and form. Both columns start and end on the
   same lines at any width — the message box takes up the slack when the photograph column is the
   taller one, the links drop to the foot of their column when the form is */
@media (min-width: 1024px) {
  .split.contact { grid-template-rows: auto 1fr; row-gap: 0; align-items: stretch; }
  .contact__media { grid-column: 1; grid-row: 1; position: static; }
  .contact__links { grid-column: 1; grid-row: 2; align-self: end; margin-top: var(--section-y); }
  .contact__body { grid-column: 2; grid-row: 1 / span 2; display: flex; flex-direction: column; }
  .contact__form { flex: 1 1 auto; display: flex; flex-direction: column; }
  .contact__form .form-grid { flex: 1 1 auto; grid-template-rows: auto auto 1fr; }
  .contact__form .field--message { display: flex; flex-direction: column; }
  .contact__form .field--message textarea { flex: 1 1 auto; }
}
.contact__list a { text-decoration: none; }
.contact__list a:hover { color: var(--grey-1); text-decoration: underline; }
/* the groups' labels are h2s for the heading outline, drawn exactly as the eyebrows they were (the body's line height,
   not the h2's) */
.contact__group h2.eyebrow { line-height: inherit; }
/* the answer to a post sent without JavaScript (/api/contact redirects to #sent or #not-sent): shown by :target */
.contact__result { display: none; }
.contact__result:target { display: block; }
#sent:target ~ .contact__form { display: none; }   /* sent: no form to send twice */

/* ------------------------------------------------------------ legal */
.legal h1 { margin-bottom: .6em; }
.legal__updated { margin-bottom: 40px; }   /* the same gap as between sections */
/* an open question inside the policy text, should one ever come back (the build fails on it): the seal's text red (4.8:1), set apart from the binding wording */
.legal__confirm { background: none; color: var(--seal-text); font-style: italic; }
.legal p a { color: inherit; text-decoration: underline; text-decoration-color: var(--grey-3); text-underline-offset: .2em; text-decoration-thickness: 1px; }
.legal p a:hover, .legal p a:focus-visible { color: var(--ink); text-decoration-color: currentColor; }
.legal h2[id] { scroll-margin-top: calc(var(--header-h) + 20px); }
.legal__section { margin-bottom: 40px; }
.legal__section h2 { font-size: 1.65rem; line-height: 1.6; margin-bottom: .8em; }
.legal p { max-width: 70ch; }
.legal__nav { display: flex; flex-wrap: wrap; gap: 0 24px; padding-top: 30px; border-top: 1px solid var(--hairline); font-size: var(--fs-meta); letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); }
.legal__nav a { display: inline-flex; align-items: center; min-height: 44px; }   /* a 44px tap target, same text */
.legal__nav a[aria-current="page"] { color: var(--ink); }

/* ------------------------------------------------------------ the editions to come (no prints in the shop yet)
   The cards are the shop's own (.product-card in .shop-grid: three to a row, two, then one on a phone, every print
   centred in its row's image band). Each card reads in steps, with room between them: only the title and the price
   (the details and Enquire are on the work's page). */
.shop-preview__intro { margin-bottom: var(--gap-y); max-width: 62ch; }
.shop-preview__intro .lede { margin-bottom: 0; }
.shop-preview .product-card__body { padding-top: 24px; }
.shop-preview .product-card__title { margin-bottom: 0; }
.shop-preview .product-card__live { margin: auto 0 0; padding-top: 8px; }
.price data, data.price { color: inherit; }
/* 320px (iPhone SE, Display Zoom): a long word in tracked capitals breaks rather than run past the card */
@media (max-width: 359px) {
  .shop-preview .product-card__title { overflow-wrap: anywhere; -webkit-hyphens: auto; hyphens: auto; letter-spacing: .1em; }
}

/* an edition to come's own page (product.html, .product--enquiry): the details, the price, Enquire and View on your
   wall, each block a step apart */
/* "(height × width)" moves as one piece: beside the size where it fits, under it where it does not (320 px; the
   wrap point is the space before the note, product.html) */
.spec__note { color: var(--grey-2); font-size: var(--fs-meta); letter-spacing: 0; white-space: nowrap; }
.product--enquiry .product__buy { padding: 34px 0 30px; margin-bottom: 0; }
/* the buy block is the last thing beside the work since the seller lines and the shipping and policy
   lines left: no rule under it, so it does not double the previous / next rule below, nor
   keep the padding that spaced that rule */
.product--enquiry .product__buy { border-bottom: 0; padding-bottom: 0; }
.product__price { margin: 0 0 22px; }
.product__price .price--lg { line-height: 1.2; }
.product__panel .price--lg { font-size: 1.65rem; }   /* quieter than the title it stands under */
.product__actions { margin: 0 0 20px; }
.product__actions .btn { margin: 0; }
/* ------------------------------------------------------------ the pieces (watches and jewellery)
   Before the prints, a section per kind (Timepieces, Jewellery): the shop's cards and price markup, each piece's studio
   photograph whole in a 4:5 window at every width. The two cards of a kind are the centred "two left over" row of the
   shop grid. */
/* the links row under the title (Timepieces · Jewellery · Prints): a step below it */
.shop-kinds { margin-top: 18px; }
.shop-prints { margin-top: calc(1.5 * var(--section-y)); }
.shop-pieces { margin-top: var(--section-y); }
/* the second kind: no rule of its own (the first kind's facts line and the heading's own rule already frame it) */
.shop-pieces + .shop-pieces { margin-top: calc(1.5 * var(--section-y)); }
/* every piece is a 4:5 studio photograph, and fills its window */
.product-card--piece .product-card__media { aspect-ratio: 4 / 5; display: flex; align-items: center; justify-content: center; }
.product-card--piece .product-card__media picture { width: 100%; height: 100%; }
.product-card--piece .product-card__media img { width: 100%; height: 100%; max-height: none; object-fit: contain; object-position: 50% 50%; }
/* not on the shop grid's subgrid rows: WebKit sizes a subgrid row holding a 3:4 box shorter than the box (the watch ran
   under its title, 2026-11-07); the two cards of a kind are alike, so a plain column lines their captions up anyway */
.product-card.product-card--piece { display: flex; flex-direction: column; grid-row: auto; }
.product-card--piece .product-card__link { display: flex; flex-direction: column; flex: 1 1 auto; }
.product-card--piece .product-card__body { flex: 1 1 auto; }
/* a piece's own page below 1024 px: capped at 75 % of the screen's height (its frame takes the piece's ratio, so the
   zoom target is the piece itself), centred; product.html's sizes follow this cap */
@media (max-width: 1023px) {
  .product--watch .product__frame { width: min(100%, calc(75svh * var(--ratio, 1))); margin-inline: auto; }
  .product--jewellery .product__frame { width: min(100%, calc(70svh * var(--ratio, 1))); margin-inline: auto; }
}
/* a piece's views (a brooch's front and back): a row of thumbnails under the image, each opening the lightbox at that
   view; from 1024 px the pinned column keeps the image and the row on one screen (the image gives up the row's height) */
.product__views { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; list-style: none; margin: 20px 0 0; padding: 0; }
.product__views li { margin: 0; }
.product__view { display: block; width: 84px; height: 84px; padding: 0; background: none; border: 1px solid transparent;
  border-radius: 0; cursor: zoom-in; -webkit-tap-highlight-color: transparent; }
@media (hover: hover) and (pointer: fine) { .product__view:hover { border-color: var(--grey-2); } }
.product__view:focus-visible { outline: 2px solid var(--ink-2); outline-offset: 2px; }
.product__view picture, .product__view img { display: block; width: 100%; height: 100%; }
.product__view img { object-fit: contain; }
@media (min-width: 1024px) {
  .product--views .product__frame { width: min(100%, calc((100vh - var(--header-h) - 40px - 104px) * var(--ratio, 1))); }
}

/* ------------------------------------------------------------ the work page
   The image owns the first screen, beside a small panel: title, price, Enquire, a print's AR link. Below: the details as
   plain lines, the story behind the work, the close-up across the content width. Nothing stays pinned: the panel is
   no taller than the image. */
.section--work { padding-top: 20px; }
.split.product { row-gap: 26px; }
.product__panel h1 { margin-bottom: .6em; }
.product__panel .product__buy { padding: 0; margin: 0; border-bottom: 0; }
.product__panel .product__price { margin-bottom: 18px; }
.product__panel .product__actions { margin-bottom: 0; }
@media (min-width: 1024px) {
  .split.product { grid-template-columns: minmax(0, 1fr) minmax(220px, 300px); column-gap: 60px; align-items: center;
    min-height: calc(100vh - var(--header-h) - 40px); }
  .product .split__media { position: static; }
}
/* the AR link: words only, under Enquire; ar.js shows it only where the device can show AR */
.product__ar-row { margin: 8px 0 0; }
.product__ar-link { position: relative; display: inline-flex; align-items: center; min-height: 44px; font-size: var(--fs-meta); color: var(--grey-1);
  text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 1px; }
.product__ar-link[hidden] { display: none; }
.product__ar-link img { position: absolute; left: 0; top: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.work-info { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap-y) 60px; align-items: start; margin-top: calc(1.5 * var(--section-y)); }
@media (min-width: 1024px) { .work-info { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); } }
.work-lines li { margin: 0; }
.work-ref { margin: 1.4em 0 0; font-size: var(--fs-meta); line-height: 2.1rem; color: var(--grey-2); }
.work-blurb { margin: 1.4em 0 0; }
.work-story h2 { margin-bottom: 1em; }
.work-detail { margin: calc(1.5 * var(--section-y)) 0 0; }
.work-detail img { width: 100%; height: auto; }
.work-detail .figcaption { padding-top: 10px; }

/* ------------------------------------------------------------ the Shop's second view
   Lies over the first in the card's window (absolute, so no layout shift), fades in where the pointer hovers; the first
   never moves or dims. Everywhere else display:none, so a touch screen shows the first image and fetches nothing. */
.product-card__media { position: relative; }
.product-card__media picture.product-card__alt { display: none; position: absolute; inset: 0; width: 100%; height: 100%; }
.product-card__media .product-card__alt img { width: 100%; height: 100%; max-height: none; object-fit: cover; }
@media (hover: hover) and (pointer: fine) {
  .product-card__media picture.product-card__alt { display: block; opacity: 0; transition: opacity var(--t-hover) ease; pointer-events: none; }
  .product-card__link:hover .product-card__alt, .product-card__link:focus-visible .product-card__alt { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .product-card__media picture.product-card__alt { transition: none; } }
/* a print's card: the frame is the painting's own rectangle (--r, its width / height), so the close-up fades in inside
   the painting's shape and the picture never appears to swell on hover. The square-window fallback keeps its 100% */
.product-card__frame { display: block; position: relative; width: 100%; height: 100%; }
@media (max-width: 460px) { .product-card__frame { height: auto; aspect-ratio: var(--r); } }
@supports (grid-template-rows: subgrid) and (width: 1cqw) {
  @media (min-width: 461px) { .product-card__frame { width: min(100%, calc(100cqw * var(--r))); height: auto; aspect-ratio: var(--r); } }
}
/* the watches' straps run out of the photograph at top and bottom: their cut ends dissolve into the page. On the display
   only (the file is untouched), and the fade stops far short of the case and the dial */
.shop-pieces--watch .product-card__pic img, .product--watch .product__zoom img {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 8%, #000 92%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 8%, #000 92%, transparent 100%);
}
/* the Shop's hero holds its place before the photograph arrives (it is 1959 × 1510, drawn whole, at the split hero's limits) */
.shop-intro .page-hero__pic { width: min(100%, calc(min(62svh, 560px) * 1959 / 1510)); aspect-ratio: 1959 / 1510; }
.shop-intro .page-hero__pic img { width: 100%; height: auto; max-height: none; }
@media (min-width: 1024px) {
  .shop-intro .page-hero__pic { width: min(100%, calc(min(calc(100svh - var(--header-h) - 170px), 720px) * 1959 / 1510)); }
}

/* the editorial picture that breaks the prints' grid: a whole row of its own, no link, no caption */
.shop-editorial { margin: calc(1.2 * var(--gap-y)) 0; }
.shop-editorial img { width: 100%; height: auto; }
@media (max-width: 460px) { .shop-editorial { margin-inline: calc(-1 * var(--gutter)); } }   /* edge to edge on a phone, or it reads as one more card */

/* ------------------------------------------------------------ the delivery line
   One quiet centred row just above the footer's rule, on the Shop, the cart and the work pages only */
.delivery-line { margin: 0; padding: 14px var(--gutter) 16px; text-align: center; text-wrap: balance; font-size: var(--fs-meta); line-height: 2.1rem;
  letter-spacing: var(--track); text-transform: uppercase; color: var(--grey-1); }
.delivery-line + .site-footer { margin-top: 0; }
.delivery-line p { margin: 0; }   /* the line sits in its own <aside> landmark */
