/* ============================================================================
   THE STORE — the skeleton every variation shares.

   Loaded AFTER assets/page.css and BEFORE shopassets/store.css. It owns
   structure, spacing and behaviour; store.css owns colour, type, the shape of
   a tile and the two page models (the catalogue scrolls, the rest is one
   screen). Until 2026-09-03 there were four designs over this skeleton.

   FOUR THINGS THAT ARE NOT STYLE CHOICES
   --------------------------------------
   1. THE STORE DOES NOT EDIT assets/page.css. That file's own comment warns
      that a plain rule added below its phone media block silently loses, and
      it is shared with three finished pages. Everything the store needs is
      added here, at a specificity that wins.

   2. `body.shop` UNDOES TWO PAGE RULES, both of which are right for a page
      that is one screen and wrong for a catalogue that scrolls (store.css
      puts them back on `body.fit`, the one-screen pages):
      `main{display:flex;align-items:center}` would centre a grid vertically,
      and `.copy{position:fixed}` would park the copyright on top of it.

   3. object-fit: CONTAIN, NEVER COVER. The measured aspect ratios of the real
      works run 0.67 to 1.67 — a 2.5x spread — and a `cover` tile would slice
      the top off a tall canvas. The plate absorbs the variation; the artwork
      is never cut. This is the one rule in the file that may not be traded for
      a tidier grid.

   4. EVERY NEW COMPONENT CARRIES ITS OWN HIGH-CONTRAST RULE, doubled as
      `html[data-a11y-contrast][data-a11y-contrast]` (0,2,x). page.css writes
      its contrast rules that way so they outrank per-variant palettes; a
      single-attribute rule here would lose to them at the overlaps, and a
      component with no rule at all simply gets no high-contrast treatment.
      IS 5568 is a legal requirement, not a preference.

   The phone block is LAST in this file, and must stay last. A media query adds
   no specificity.
   ========================================================================== */

:root{
  /* Tile geometry. A variation may retune these; it should not need to
     restate the grid. */
  --tile-min:220px;
  --tile-ratio:1;          /* the PLATE's box. The picture inside is contained. */
  --gap:18px;
  --pad:clamp(18px, 4vw, 46px);
  --edge:rgba(243,236,227,.38);   /* a component boundary: 3:1 minimum */
  --line:rgba(243,236,227,.16);   /* a decorative separator */
  --plate:rgba(243,236,227,.07);
}

/* ---- the scrolling document ---------------------------------------------- */

body.shop{display:block;min-height:100vh;min-height:100dvh}
body.shop main{display:block;flex:none;min-height:0;
  padding:0 0 clamp(40px, 7vw, 90px)}
body.shop .copy{position:static;text-align:center;
  margin:clamp(26px,5vw,54px) 0 0;padding:0 20px}
body.shop .bg{z-index:0}

.wrap{width:100%;max-width:1360px;margin:0 auto;padding:0 var(--pad)}

/* page.css gives .actions a desktop rule that makes a button row step OUT of
   its parent -- width:min(760px,92vw) with margin-inline:calc(50% - min(380px,
   46vw)) -- so the row can escape the 70ch reading measure of .col and centre
   on the page. That is right there and wrong here: inside the store the same
   row sits in a ~450px info column, where 50% resolves to 225 against a 380
   offset and drags the row 58px off the left edge of the document. Measured on
   the necklace page at 1280: 73px of horizontal scroll, in both languages and
   at every text step, i.e. geometry rather than type. A store row is already
   centred by justify-content and needs no escape hatch. */
body.shop .actions{width:auto;margin-inline:0}

/* ---- the grid ------------------------------------------------------------- */

.grid{list-style:none;margin:0;padding:clamp(10px,2vw,22px) 0 0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--tile-min),1fr));
  gap:var(--gap)}
.grid > li{margin:0;min-width:0}

.tile{display:flex;flex-direction:column;gap:10px;text-decoration:none;
  color:inherit;position:relative;height:100%}
.plate{display:flex;align-items:center;justify-content:center;
  aspect-ratio:var(--tile-ratio);background:var(--plate);border-radius:3px;
  overflow:hidden;padding:10px}
/* width/height 100% and NOT max-width/auto. With auto sizing, an <img> that
   carries a w-descriptor srcset takes its intrinsic width from the sizes
   attribute -- so a 260px sizes hint laid the artwork out at 260px inside a
   614px plate and left it floating in empty ground. Filling the plate and
   letting object-fit do the work means the LAYOUT is the plate and sizes only
   chooses which file to fetch, which is what sizes is for. */
.plate img{display:block;width:100%;height:100%;object-fit:contain}
/* The drawn stand-in for an item with no photograph. Deliberately NOT a stock
   image and deliberately not a grey box pretending to be one: two rules and a
   dot, so it reads as "nothing here yet" rather than as a product. */
.ph{display:flex;align-items:center;justify-content:center;
  width:100%;height:100%;border-radius:2px;
  background:repeating-linear-gradient(135deg,var(--plate) 0 10px,transparent 10px 20px)}
.ph::after{content:"";width:26px;height:26px;border-radius:50%;
  box-shadow:inset 0 0 0 2px var(--edge)}

.tinfo{display:flex;flex-direction:column;gap:3px;padding:0 2px}
.tname{font-size:calc(15px * var(--a11y-scale));line-height:1.3;font-weight:600}
.tprice{font-size:calc(14px * var(--a11y-scale));opacity:.82;
  font-variant-numeric:tabular-nums}
.tflag{align-self:flex-start;margin-top:2px;padding:3px 9px;border-radius:2px;
  font-size:calc(11px * var(--a11y-scale));letter-spacing:.04em;
  text-transform:uppercase;box-shadow:inset 0 0 0 1px var(--edge)}
.tflag.is-sample{opacity:.85}

/* ---- the product page ----------------------------------------------------- */

.pprice{margin:10px 0 0;font-size:calc(clamp(20px,2.2 * var(--fit),30px) * var(--a11y-scale));
  font-variant-numeric:tabular-nums}
.pprose{margin:clamp(14px,2vw,22px) 0 0;color:var(--dim);
  font-size:calc(clamp(15px,1.55 * var(--fit),17px) * var(--a11y-scale))}
.pprose p{margin:0 0 .7em}
.pdims{margin:14px 0 0;color:var(--dim);font-size:calc(13px * var(--a11y-scale))}

/* Real radios, styled. A <select> is one tap fewer and four affordances worse:
   the chosen size has to be visible without opening anything, and the group
   needs a keyboard path that announces itself. */
.vars{margin:clamp(16px,2.4vw,24px) 0 0}
.vars legend{padding:0;margin:0 0 8px;font-size:calc(13px * var(--a11y-scale));
  letter-spacing:.03em;text-transform:uppercase;opacity:.8}
.vars fieldset{border:0;margin:0;padding:0}
.varrow{display:flex;flex-wrap:wrap;gap:9px}
/* The size chips and the quantity steppers are buttons, so they take the
   site's one button too (2026-09-03): the wash, the hairline, the blurred
   backdrop and --btn-r. They had NO FILL AT ALL before, which is precisely the
   "completely transparent" Ilai asked to be rid of. */
.varrow label{position:relative;display:inline-flex;align-items:center;gap:8px;
  min-height:44px;padding:0 15px;border-radius:var(--btn-r);cursor:pointer;
  background:var(--glass);box-shadow:inset 0 0 0 1px var(--glass-edge);
  -webkit-backdrop-filter:blur(12px) saturate(130%);
  backdrop-filter:blur(12px) saturate(130%);
  font-size:calc(14px * var(--a11y-scale))}
.varrow input{position:absolute;opacity:0;width:1px;height:1px}
/* The selected state carries WEIGHT and a thicker edge as well as colour, so
   it is not colour alone that says which size you picked. */
.varrow input:checked + .vartext{font-weight:700}
/* label, NOT .varrow. .varrow is the CONTAINER, so this rule drew a 2px box
   round the whole row -- a 605px empty rectangle beside the two chips on the
   checkout page. Caught by measuring the element, not by reading the rule. */
.varrow label:has(input:checked){box-shadow:inset 0 0 0 2px currentColor}
.varrow input:focus-visible + .vartext{outline:3px solid var(--accent);
  outline-offset:4px}
.vardim{opacity:.62;font-size:calc(12.5px * var(--a11y-scale));direction:ltr}

.addrow{display:flex;flex-wrap:wrap;align-items:center;gap:12px;
  margin:clamp(18px,2.6vw,26px) 0 0}
.addnote{margin:0;font-size:calc(13.5px * var(--a11y-scale));opacity:.85}

/* ---- the cart chip in the bar --------------------------------------------- */

/* A BAR chip, not a page button: it takes the corner and keeps the bar's own
   fill, exactly like .a11y-btn and .wa beside it. */
.pcart{position:relative;display:flex;align-items:center;justify-content:center;
  width:44px;height:34px;border-radius:var(--btn-r);background:#f2f2f4;
  color:var(--bar-ink);text-decoration:none;
  -webkit-tap-highlight-color:transparent;transition:background .15s ease}
.pcart:active{background:#e6e6ea}
.pcart svg{width:20px;height:20px}
.pcart-n{position:absolute;top:-5px;inset-inline-end:-5px;min-width:19px;height:19px;
  padding:0 5px;border-radius:10px;background:#b3491d;color:#fff;
  font:700 11px/19px var(--sans);text-align:center;font-variant-numeric:tabular-nums}

/* ---- the cart page --------------------------------------------------------- */

.clines{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.cline{display:grid;grid-template-columns:88px minmax(0,1fr) auto;gap:16px;
  align-items:center;padding:16px 0;border-bottom:1px solid var(--line)}
.cthumb{display:flex;align-items:center;justify-content:center;width:88px;
  aspect-ratio:1;background:var(--plate);border-radius:3px;overflow:hidden;padding:6px}
.cthumb img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}
.cph{display:block;width:100%;height:100%;
  background:repeating-linear-gradient(135deg,var(--plate) 0 8px,transparent 8px 16px)}
.cmid{min-width:0}
.cname{display:block;color:inherit;text-decoration:none;font-weight:600;
  font-size:calc(15px * var(--a11y-scale))}
.cname:hover{text-decoration:underline}
.cmeta{margin:3px 0 0;color:var(--dim);font-size:calc(13px * var(--a11y-scale))}
.cqty{display:flex;align-items:center;gap:8px;margin:9px 0 0;flex-wrap:wrap}
.qbtn{appearance:none;-webkit-appearance:none;border:0;cursor:pointer;
  width:34px;height:34px;border-radius:var(--btn-r);background:var(--glass);color:inherit;
  box-shadow:inset 0 0 0 1px var(--glass-edge);font:600 17px/1 var(--sans);
  -webkit-backdrop-filter:blur(12px) saturate(130%);
  backdrop-filter:blur(12px) saturate(130%);
  -webkit-tap-highlight-color:transparent}
.qbtn:hover{background:var(--glass-hi)}
.qbtn:active{background:var(--glass-on)}
.qn{min-width:26px;text-align:center;font-variant-numeric:tabular-nums;
  font-size:calc(15px * var(--a11y-scale))}
.crm{appearance:none;-webkit-appearance:none;border:0;background:none;cursor:pointer;
  color:var(--dim);font:inherit;font-size:calc(13px * var(--a11y-scale));
  text-decoration:underline;padding:8px 4px;min-height:34px}
.crm:hover{color:inherit}
.cone{font-size:calc(12.5px * var(--a11y-scale));opacity:.85;
  padding:4px 9px;border-radius:2px;box-shadow:inset 0 0 0 1px var(--edge)}
.cprice{margin:0;text-align:end;font-variant-numeric:tabular-nums;
  font-size:calc(15px * var(--a11y-scale));white-space:nowrap}
.cfree{font-weight:700}
.cempty{margin:clamp(30px,6vw,60px) 0;text-align:center;color:var(--dim);
  font-size:calc(clamp(16px,1.8 * var(--fit),20px) * var(--a11y-scale))}
.ctotals{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  padding:20px 0 0;font-size:calc(clamp(17px,1.9 * var(--fit),22px) * var(--a11y-scale))}
.ctval{font-variant-numeric:tabular-nums;font-weight:700}
.cnote{margin:12px 0 0;color:var(--dim);font-size:calc(13px * var(--a11y-scale))}

/* ---- checkout -------------------------------------------------------------- */

.colines{list-style:none;margin:0;padding:0}
.colines li{display:flex;justify-content:space-between;gap:14px;padding:9px 0;
  border-bottom:1px solid var(--line);font-size:calc(14.5px * var(--a11y-scale))}
.coname{min-width:0}
.coprice{white-space:nowrap;font-variant-numeric:tabular-nums}
.field{display:block;margin:0 0 14px}
.field > span{display:block;margin:0 0 6px;font-size:calc(13.5px * var(--a11y-scale));
  opacity:.9}
.field input{width:100%;min-height:46px;padding:0 13px;border:0;border-radius:2px;
  background:transparent;color:inherit;font:inherit;
  font-size:calc(15px * var(--a11y-scale));
  box-shadow:inset 0 0 0 1px var(--edge)}
.field input:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
.delivery{border:0;margin:0 0 16px;padding:0}
.delivery legend{padding:0;margin:0 0 8px;font-size:calc(13.5px * var(--a11y-scale));
  opacity:.9}
.payplus{margin:clamp(18px,2.6vw,24px) 0 0;padding:clamp(16px,2.4vw,22px);
  border-radius:3px;box-shadow:inset 0 0 0 2px var(--accent)}
.payplus h3{margin:0 0 8px;font-size:calc(15px * var(--a11y-scale))}
.payplus p{margin:0 0 10px;font-size:calc(13.5px * var(--a11y-scale));color:var(--dim)}
.payplus pre{margin:0;padding:12px;border-radius:2px;background:rgba(0,0,0,.28);
  overflow-x:auto;direction:ltr;text-align:left;
  font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.colegal{margin:14px 0 0;font-size:calc(12.5px * var(--a11y-scale));color:var(--dim)}
.colegal a{color:inherit}

/* No backdrop-filter, no surface. Same trade page.css makes for .btn. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){
  .varrow label,.qbtn{background:var(--glass-solid)}
}

/* ---- accessibility --------------------------------------------------------- */

html[data-a11y-contrast][data-a11y-contrast] .plate,
html[data-a11y-contrast][data-a11y-contrast] .cthumb{
  background:#000;box-shadow:inset 0 0 0 2px #fff}
html[data-a11y-contrast][data-a11y-contrast] .tflag,
html[data-a11y-contrast][data-a11y-contrast] .cone,
html[data-a11y-contrast][data-a11y-contrast] .qbtn,
html[data-a11y-contrast][data-a11y-contrast] .varrow label,
html[data-a11y-contrast][data-a11y-contrast] .field input{
  background:#000;color:#fff;box-shadow:inset 0 0 0 2px #fff;
  -webkit-backdrop-filter:none;backdrop-filter:none}
html[data-a11y-contrast][data-a11y-contrast] .varrow label:has(input:checked){
  box-shadow:inset 0 0 0 4px #fff}
html[data-a11y-contrast][data-a11y-contrast] .pcart{
  background:#000;color:#fff;box-shadow:inset 0 0 0 2px #fff}
html[data-a11y-contrast][data-a11y-contrast] .pcart-n{background:#fff;color:#000}
html[data-a11y-contrast][data-a11y-contrast] .payplus{box-shadow:inset 0 0 0 3px #fff}
html[data-a11y-contrast][data-a11y-contrast] .payplus pre{background:#000;color:#fff}
html[data-a11y-contrast][data-a11y-contrast] .tprice,
html[data-a11y-contrast][data-a11y-contrast] .cmeta,
html[data-a11y-contrast][data-a11y-contrast] .cnote,
html[data-a11y-contrast][data-a11y-contrast] .pprose{opacity:1;color:#fff}

html[data-a11y-links] .tile,
html[data-a11y-links] .cname{text-decoration:underline}

/* Nothing in this file animates anything into visibility, so "stop animations"
   cannot strand a component the way it once did on the walk. The only
   transitions are hover/press washes, which have a resting state declared
   outside any keyframe. */

/* ============================================================================
   THE PHONE. LAST IN THE FILE, ON PURPOSE — a media query adds no specificity,
   so a phone rule placed above a plain rule it means to override loses
   silently and the page deploys looking perfect on a desktop.
   ========================================================================== */

@media (max-width: 900px){
  :root{--tile-min:150px;--gap:12px;--pad:16px}

  /* 88px of thumbnail plus 16px of gap is a quarter of a 360px screen before
     the name has any room. The line goes two-up: picture and name on the top
     row, quantity and price beneath. */
  .cline{grid-template-columns:64px minmax(0,1fr);grid-template-areas:"t m" ". p";
    gap:10px 12px;align-items:start}
  .cthumb{width:64px;grid-area:t}
  .cmid{grid-area:m}
  .cprice{grid-area:p;text-align:start;margin-top:2px}

  .payplus pre{font-size:11px}
  body.shop main{padding-bottom:34px}

  /* The chip kept its desktop ground here while page.css turned --bar-ink
     white for the black bar: a white icon on a near-white pill, measured
     rgb(242,242,244) under rgb(255,255,255) on every phone. Same wash as
     the language and accessibility buttons beside it. */
  .pcart{height:40px;background:rgba(255,255,255,.13)}
  .pcart:active{background:rgba(255,255,255,.26)}
}

/* A short phone gives the fit unit almost nothing to work with, so the running
   sizes come down a little rather than the page running past the fold. */
@media (max-width: 900px) and (max-height: 700px){
  :root{--gap:10px}
}
