:root{--bg:#060606;--s1:#0c0c0c;--s2:#101010;--border:#1c1c1c;--border2:#282828;--red:#ff3a2d;--orange:#f5a520;--yellow:#eab308;--text:#f0f0f0;--muted:#999;--muted2:#555}
body{font-family:'IBM Plex Mono','Consolas','Courier New',monospace;background:var(--bg);color:var(--text);overflow-x:hidden}
#page{padding:70px 20px 20px;max-width:600px;margin:0 auto;text-align:center}
.coming-box{background:var(--s2);border:2px solid var(--border);border-radius:2px;padding:48px 32px;margin-bottom:24px}
.coming-box .logo{width:80px;height:80px;margin:0 auto 20px;object-fit:contain}
.coming-box h2{font-size:1.8rem;font-weight:900;margin-bottom:12px;color:var(--yellow)}
.coming-box p{font-size:.85rem;color:var(--muted);line-height:1.65;margin-bottom:16px}
.coming-box .cta{display:inline-block;padding:10px 24px;background:transparent;border:2px solid var(--yellow);color:var(--yellow);font-size:.82rem;font-weight:700;text-decoration:none;border-radius:2px;transition:all var(--t-med);cursor:pointer;font-family:inherit}
.coming-box .cta:hover{background:rgba(234,179,8,.08)}
@media(max-width:520px){.coming-box{padding:32px 20px}}

/* ── v0.15.2 — node background behind everything ── */
#page{position:relative;z-index:2}
.topbar{background:rgba(var(--bg-rgb),.35);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.coming-box{background:rgba(var(--s2-rgb),.5);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.shared-footer{position:relative;z-index:2;background:var(--bg)}

/* ── Catalogue ──
   Shown only once the store API returns something active; until then the
   coming-soon box above is the honest state of the page. */
#store-catalog[hidden]{display:none}
#page:has(#store-catalog:not([hidden])){max-width:1100px;text-align:start}
/* The "no product catalog yet" line that follows the section. Once the grid
   has products in it, that line is contradicted by everything above it.
   Targeted as the adjacent sibling so neither page's markup has to change,
   which keeps the two language twins identical element for element. */
#store-catalog:not([hidden])+p{display:none}
.store-h2{font-size:1.1rem;font-weight:800;margin:16px 0 4px;color:var(--text)}
.store-sub{font-size:.76rem;color:var(--muted);margin:0 0 16px}
.store-search{width:100%;background:var(--s1);border:2px solid var(--border2);padding:10px 14px;
  font-size:.82rem;color:var(--text);outline:none;font-family:inherit;border-radius:2px;margin-bottom:12px}
.store-search:focus{border-color:var(--orange)}
.store-filters{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:16px}
.store-filter{background:var(--s2);border:1px solid var(--border2);color:var(--muted);
  font-family:inherit;font-size:.68rem;font-weight:600;padding:6px 12px;cursor:pointer;border-radius:2px;
  transition:border-color var(--t-fast),color var(--t-fast)}
.store-filter:hover,.store-filter:focus-visible{border-color:var(--orange);color:var(--text)}
.store-filter.on{border-color:var(--orange);color:var(--text);background:rgba(245,165,32,.08)}
.store-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:12px}

/* The wrapper holds the grid slot open while the card inside it is lifted out
   of flow on hover, so one hover overlaps its neighbours instead of reflowing
   every row beneath it -- the same trick as the vintage listings.

   Its height comes from --store-slot, which store.js measures from the tallest
   resting card. A number written here cannot be right for both a card with a
   photo and one without, and guessing high leaves a band of dead space under
   every row. */
.store-card-wrap{display:flex;align-items:flex-start;min-width:0;position:relative}
.store-card{background:var(--s1);border:1px solid var(--border);border-radius:3px;overflow:hidden;
  display:flex;flex-direction:column;text-align:start;width:100%;
  color:inherit;text-decoration:none;
  transition:box-shadow .22s ease,border-color var(--t-med)}
.store-card.is-out{opacity:.55}
a.store-card{cursor:pointer}
a.store-card:hover,a.store-card:focus-visible{border-color:var(--orange)}

/* "View details" only earns its space once the card is open. */
.store-more{font-size:.66rem;color:var(--orange);font-weight:600;display:none}

@media (hover: hover) and (min-width: 641px) {
  .store-card-wrap{z-index:1;min-height:var(--store-slot,0px)}
  .store-card-wrap:hover{z-index:150}
  .store-card-wrap:hover .store-card{
    position:absolute;top:-6px;inset-inline-start:-6px;width:calc(100% + 12px);
    box-shadow:0 24px 60px rgba(0,0,0,.75);
    border-color:var(--orange);
    z-index:150;
  }
  /* The description is clamped on a resting card so every card is the same
     height; opening one is what reveals the rest of it. */
  .store-card .store-desc{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
  .store-card-wrap:hover .store-card .store-desc{-webkit-line-clamp:unset;display:block}
  .store-card-wrap:hover .store-card .store-more{display:block}
}
/* Keyboard users get the same expansion, since they cannot hover. */
@media (min-width: 641px) {
  .store-card-wrap:focus-within{z-index:150}
  .store-card-wrap:focus-within .store-card:focus-visible{
    position:absolute;top:-6px;inset-inline-start:-6px;width:calc(100% + 12px);
    box-shadow:0 24px 60px rgba(0,0,0,.75);border-color:var(--orange);z-index:150;
  }
  .store-card-wrap:focus-within .store-card:focus-visible .store-desc{-webkit-line-clamp:unset;display:block}
  .store-card-wrap:focus-within .store-card:focus-visible .store-more{display:block}
}
/* The image is shown whole, not cropped to a fixed 4:3 -- a spool shot and a
   printer shot have different proportions, and the card takes the height of
   whatever it holds. sizeSlots() measures the result, so variable heights are
   fine. max-height caps a freakishly tall image so one product cannot own the
   whole column. */
/* The image fills the card's full width and takes its natural height -- no
   object-fit letterbox, so the card hugs the photo with no bars down the sides.
   Per-row slot sizing (store.js) keeps a tall photo from stretching its row. */
.store-img{width:100%;height:auto;display:block}
/* The accent bar rides the top of every card now, image or not -- a brand
   strip the seller colours per product (--accent, set inline from
   attrs.accent), falling back to the section orange. */
.store-accent{height:5px;background:linear-gradient(90deg,var(--accent,var(--orange)),transparent)}
.store-currency-note{font-size:.7rem;color:var(--muted2);margin:0 0 12px;line-height:1.5}
.store-body{padding:10px 12px 12px;display:flex;flex-direction:column;gap:6px;flex:1}
.store-name{font-size:.8rem;font-weight:700;margin:0;color:var(--text);line-height:1.35}
.store-desc{font-size:.7rem;color:var(--muted);margin:0;line-height:1.5}
.store-tags{display:flex;flex-wrap:wrap;gap:4px}
.store-tag{background:var(--s2);border-radius:2px;padding:2px 6px;font-size:.6rem;color:var(--muted)}
.store-foot{margin-top:auto;display:flex;align-items:baseline;justify-content:space-between;gap:8px;padding-top:6px}
.store-price{font-size:.9rem;font-weight:800;color:var(--orange)}
.store-out{font-size:.62rem;font-weight:700;color:var(--muted2);text-transform:uppercase;letter-spacing:.04em}
.store-none{display:none;text-align:center;color:var(--muted);font-size:.78rem;padding:26px;
  border:1px dashed var(--border2);margin-top:14px}
@media(max-width:520px){.store-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}}
