@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('assets/fonts/inter-latin-var.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

:root {
  color-scheme: dark;
  /* THREE COLOURS, and no fourth. Jet black, frost white, and the red that was already
     here. The ground is a NEUTRAL black now, not the warm #070302 it was — against frost
     white a warm black reads as brown, and the whole point of frost is that it is cool.
     Every grey between them is on the same neutral-to-cool axis for the same reason. */
  --bg: #050506;
  --surface: #0d0e10;
  --surface-2: #141619;
  --border: #23262a;
  --border-light: #3a3e45;
  --text: #eef4f8;
  --text-muted: #99a3ac;

  --text-faint: #6a737b;
  --red: #ff4f3f;

  /* Blood. The banner, the sky, the sash. Used where the artwork uses it: the
     support bar, the cart badge, scarcity, and the moment the gate opens. */
  --blood: #a81f1a;
  --blood-hi: #e0483a;
  --blood-deep: #4b0a09;
  --blood-metal: linear-gradient(178deg, #e07a6c 0%, #c53a2c 14%, #9c1a15 44%, #6d0f0d 72%, #45090a 100%);
  --blood-glow: 0 0 26px rgba(168,31,26,.55);

  /* Frost. Ice rather than chrome: the ramp never reaches a true grey at the bottom,
     it cools into blue, which is what stops a white metal reading as dirty plastic.
     The RAMP matters as much here as it did for the brass — bright edge, body, a
     darker band at 52-68% where the surface turns, then a second highlight. A flat
     white fill on jet black looks like paper. */
  --frost: #c6d2db;
  --frost-hi: #f5fafd;
  --frost-deep: #67727b;
  --frost-ink: #050506;

  --frost-metal: linear-gradient(177deg, #ffffff 0%, #dde6ed 30%, #a3b1bd 54%, #7a8792 68%, #f2f8fc 100%);
  --frost-glow: 0 0 24px rgba(198,210,219,.42);
  --frost-emboss: inset 0 1px 0 rgba(255,255,255,.75), inset 0 -1px 0 rgba(0,0,0,.45);

  --radius: 0px;
  --radius-sm: 0px;
  --radius-lg: 0px;
  --shadow: 0 12px 28px rgba(0,0,0,.6);
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --container: 1280px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4 { font-family: var(--font-body); margin: 0; font-weight: 800; letter-spacing: -.01em; }
.container { max-width: var(--container); margin: 0 auto; padding: 0 24px; }
.section { padding: 56px 0; }

.section.section--tight { padding: 16px 0; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--text-muted);
}
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 24px; flex-wrap: wrap; border-bottom: 1px solid var(--border); padding-bottom: 16px; }
/* Page headings are METAL-poured rather than metal-coloured. The shop and cart
   headings carry inline font sizing from their templates and sit outside
   .section-head, so they opt in with .frost-head. */
.section-head h2,
.frost-head {
  background: var(--frost-metal); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 16px rgba(198,210,219,.32));
}
.section-head h2 { font-size: 20px; letter-spacing: 1px; text-transform: uppercase; }
.section-head .view-all { font-size: 12px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase; color: var(--text-muted); white-space: nowrap; }
.section-head .view-all:hover { color: var(--text); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 12px 26px; border-radius: 0; border: 1px solid var(--frost);
  font-size: 12.5px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  transition: background .15s ease, color .15s ease, box-shadow .15s ease; white-space: nowrap;
}

.btn-primary {
  background: var(--frost-metal); color: var(--frost-ink); border-color: var(--frost-hi);
  box-shadow: var(--frost-emboss), 0 3px 16px rgba(198,210,219,.32);
  text-shadow: 0 1px 0 rgba(255,255,255,.35);
}
.btn-primary:hover {
  background: transparent; color: var(--frost-hi);
  box-shadow: var(--frost-glow); text-shadow: none;
}
.btn-outline { background: transparent; color: var(--frost-hi); }
.btn-outline:hover {
  background: var(--frost-metal); color: var(--frost-ink);
  box-shadow: var(--frost-emboss), 0 3px 16px rgba(198,210,219,.32);
}
.btn-sm { min-height: 38px; padding: 8px 16px; font-size: 11px; }
.btn-block { width: 100%; }

.ticker { border-bottom: 1px solid var(--border); background: var(--bg); overflow: hidden; }
.ticker .container { display: flex; align-items: center; justify-content: center; height: 38px; }
.ticker-text {
  font-size: 11px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.utility-bar { border-bottom: 1px solid var(--border); }
.utility-bar .container { display: flex; align-items: center; justify-content: flex-end; gap: 20px; height: 38px; }
.utility-link { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--text-muted); display: flex; align-items: center; gap: 6px; }
.utility-link:hover { color: var(--text); }
.utility-link svg { width: 14px; height: 14px; }

.support-bar {
  background: var(--blood-metal); color: var(--text);
  box-shadow: inset 0 -1px 0 rgba(0,0,0,.4), 0 2px 22px rgba(168,31,26,.3);
  font-size: 11px; letter-spacing: .5px; text-transform: uppercase;
}
.support-bar .container {
  display: flex; align-items: center; justify-content: center;
  padding: 0; flex-wrap: wrap;
}

.support-bar-link {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  width: 100%; gap: 2px 8px; min-height: 26px; padding: 3px 14px;
  color: var(--text); text-align: center;
}
.support-bar-label { font-weight: 600; }
.support-bar-hours { opacity: .8; font-weight: 600; }
.support-bar-num { font-weight: 800; letter-spacing: 1px; white-space: nowrap; }
.support-bar-link:hover .support-bar-num { text-decoration: underline; text-underline-offset: 3px; }
/* A phone gets the same bar, only narrower: it is a standing offer, not a headline,
   so it should cost one line of screen and no more. Shrinking the type rather than
   the touch area keeps the whole strip a working tap target. */
@media (max-width: 680px) {
  .support-bar { font-size: 10px; letter-spacing: .3px; }
  .support-bar-link { gap: 1px 6px; min-height: 24px; padding: 2px 12px; }
}
@media (max-width: 380px) {
  .support-bar { font-size: 9.5px; }
  .support-bar-link { gap: 1px 5px; padding: 2px 10px; }
}

.header {
  position: sticky; top: 0; z-index: 50; background: var(--bg); border-bottom: 1px solid var(--border);
}
.header-logo-row { display: flex; align-items: center; justify-content: center; position: relative; padding: 8px 24px; }
.logo { font-size: clamp(24px, 4.5vw, 38px); font-weight: 900; letter-spacing: 2px; color: var(--frost-hi); text-transform: uppercase; text-shadow: var(--frost-glow); }

.header-left { position: absolute; left: 24px; top: 50%; transform: translateY(-50%); display: flex; align-items: center; gap: 2px; }
.burger { display: none; background: none; border: none; color: var(--text); width: 40px; height: 40px; align-items: center; justify-content: center; }
.header-icons { position: absolute; right: 24px; top: 50%; transform: translateY(-50%); display: flex; align-items: center; gap: 14px; }
.icon-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; color: var(--text); }
.icon-btn svg { width: 19px; height: 19px; }

.icon-btn--chat svg { width: 17px; height: 17px; }
.icon-btn--chat { color: var(--text-muted); }
.icon-btn--chat:hover { color: var(--text); }
.badge { position: absolute; top: 0; right: 0; background: var(--blood-metal); box-shadow: 0 0 10px rgba(168,31,26,.7); color: var(--text); font-size: 10px; font-weight: 800; width: 15px; height: 15px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.mobile-only { display: none; }

.main-nav-row { border-top: 1px solid var(--border); }
.main-nav { display: flex; align-items: center; justify-content: center; gap: 0; flex-wrap: wrap; }
.main-nav > li > a {
  display: block; padding: 16px 18px; font-size: 12.5px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  color: var(--text-muted); transition: color .15s;
}
.main-nav > li > a:hover { color: var(--frost-hi); }

.main-nav > li.has-sub { position: relative; }
.main-nav > li.has-sub > a::after {
  content: '▾'; font-size: 9px; margin-left: 6px; vertical-align: middle; opacity: .7;
}
.nav-sub {
  position: absolute; top: 100%; left: 0; min-width: 230px; z-index: 60;
  background: var(--surface); border: 1px solid var(--border); border-top: none;
  display: none; box-shadow: var(--shadow);
}
.main-nav > li.has-sub:hover > .nav-sub,
.main-nav > li.has-sub:focus-within > .nav-sub,
.main-nav > li.has-sub.open > .nav-sub { display: block; }
.nav-sub a {
  display: block; padding: 12px 16px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .8px; text-transform: uppercase; color: var(--text-muted);
  border-bottom: 1px solid var(--border-light);
}
.nav-sub li:last-child a { border-bottom: none; }
.nav-sub a:hover { color: var(--text); background: var(--surface-2); }

.drawer-sub { margin: 2px 0 6px 14px; border-left: 2px solid var(--border); }
.drawer-sub a { font-size: 12px; opacity: .9; }

.header-logo-row .logo { display: inline-flex; align-items: center; gap: 11px; }
.header-logo-img { height: clamp(46px, 5.2vw, 64px); width: auto; display: block; }
/* The crest is SQUARE, so the header carries the name as text beside it rather than
   relying on the emblem alone: the ribbon lettering inside the artwork is ~6px tall at
   header height and reads as texture, not as a word. Stacked on two lines the lockup
   stays narrower than either icon group, so the centre column cannot collide with them
   at any width above the phone breakpoint. */
.header-logo-word {
  font-size: clamp(14px, 1.5vw, 19px); line-height: 1.06; letter-spacing: 2.5px;
  white-space: nowrap; text-align: left;
}
/* Phone: the row is already space-between with three groups in it, so the word is what
   gives. The drawer shows the full crest, banner and all, one tap away. */
@media (max-width: 560px) { .header-logo-word { display: none; } }

.drawer { position: fixed; inset: 0; z-index: 100; display: none; }
.drawer.open { display: block; }
.drawer-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.72); }
.drawer-panel { position: absolute; top: 0; left: 0; bottom: 0; width: 82%; max-width: 320px; background: var(--surface); border-right: 1px solid var(--border); padding: 24px; overflow-y: auto; }
.drawer-panel .logo { margin-bottom: 24px; font-size: 22px; display: block; }

.drawer-logo-img { width: 100%; max-width: 152px; height: auto; display: block; margin-bottom: 22px; }
.drawer-panel li a { display: block; padding: 14px 0; font-weight: 700; text-transform: uppercase; font-size: 13px; letter-spacing: .5px; border-bottom: 1px solid var(--border); }

.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--border); border: 1px solid var(--border); }

.card { background: var(--surface-2); display: flex; flex-direction: column; }
.card-media { position: relative; aspect-ratio: 1/1; overflow: hidden; }
.card-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.card-media--clickable { cursor: zoom-in; }

.card-media--album { display: grid; grid-template-columns: 2fr 1fr; gap: 2px; }
.card-media--album .album-side { display: grid; grid-auto-rows: 1fr; gap: 2px; }

.album-cell { position: relative; overflow: hidden; }

.album-cell--soon { background: var(--surface-2); cursor: default; }
.album-cell--soon img { object-fit: contain; }

.card-media--soon { background: var(--surface-2); }
.card-media--soon img { object-fit: contain; }
.gallery-main--soon .gallery-frame { background: var(--surface-2); }
.gallery-main--soon .gallery-frame img { object-fit: contain; cursor: default; }

.card-tags { position: absolute; top: 10px; left: 10px; display: flex; flex-direction: column;
             gap: 6px; align-items: flex-start; max-width: calc(100% - 20px); }
.tag { font-size: 10px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase; padding: 4px 8px; }
.tag-out { background: #000; color: #fff; border: 1px solid rgba(255,255,255,.55); }

.tag-low {
  background: #000; color: var(--red); border: 1px solid var(--red);
  animation: tag-low-pulse 1.8s ease-in-out infinite;
}
@keyframes tag-low-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(216,31,42,.5); }
  50% { box-shadow: 0 0 0 4px rgba(216,31,42,0); }
}
@media (prefers-reduced-motion: reduce) {
  .tag-low { animation: none; }
}

.tag-note {
  background: #000; color: #fff; border: 1px solid #fff;

  white-space: normal; line-height: 1.25;
}
@media (max-width: 520px) {

  .tag-note { font-size: 9px; padding: 3px 6px; }
}
.card-quick { position: absolute; top: 10px; right: 10px; display: flex; flex-direction: column; gap: 6px; opacity: 0; transition: opacity .15s; }
.card:hover .card-quick { opacity: 1; }
.qbtn { width: 30px; height: 30px; background: rgba(10,10,12,.86); border: 1px solid var(--frost); display: flex; align-items: center; justify-content: center; color: var(--frost-hi); }

.qbtn:hover { background: var(--frost); color: var(--frost-ink); border-color: var(--frost-hi); }
.qbtn svg { width: 13px; height: 13px; }
.card-body { padding: 14px 16px 20px; display: flex; flex-direction: column; gap: 4px; flex: 1; }
.card-cat { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .5px; color: var(--text-faint); }
.card-title { font-size: 12.5px; font-weight: 700; letter-spacing: .2px; text-transform: uppercase; color: var(--text); }
.card-title a:hover { color: var(--text-muted); }
/* The price is bare text when nothing is discounted and only wraps itself in
   .now when there is a .was to sit beside — so the frost goes on the container,
   or every full-price item on the site stays off-brand cream. */
.card-price { font-size: 13px; font-weight: 700; margin-top: 2px; color: var(--frost-hi); text-shadow: 0 0 14px rgba(198,210,219,.28); }
.card-price .was { color: var(--text-faint); text-decoration: line-through; font-weight: 500; font-size: 12px; margin-right: 6px; text-shadow: none; }
.card-price .now { color: var(--frost-hi); }
.card-add { margin-top: auto; padding-top: 12px; }

.p1 { background: #1d1b1e; }
.p2 { background: #201d19; }
.p3 { background: #1a1c1e; }
.p4 { background: #211d21; }
.p5 { background: #1b1e1a; }
.p6 { background: #221d1b; }

.category-grid {
  /* ONE COLUMN now. The new art is a set of wide banner plates -- 4.26:1 for the six,
     3.74:1 for the two rails -- and a 4.26:1 plate dropped into the old 1.872:1 paired
     slot would have been cropped to about half its width, taking the skull off one end
     and the type off the other. The 1-2-2-2-1 rhythm existed to make three-ish shapes
     tile neatly; these are all the same shape already. */
  display: grid; grid-template-columns: 1fr;

  row-gap: clamp(6px, 1.1vh, 14px);

  --tile-cap: 360px;
  --pack-w: 96%;
  max-width: min(var(--tile-cap), 94vw);
  margin-left: auto; margin-right: auto;

  align-items: center;
  justify-items: center;
}

.category-card { width: var(--pack-w); }

/* No border and no background of its own. Each plate is cropped to its OWN frame now,
   so that frame IS the tile edge -- the card used to add a second border outside it, with
   27px of the art's black margin showing in between, and you saw both. */
.category-card {
  display: block; background: none; border-radius: 11px; overflow: hidden;
  border: 0;
  transition: box-shadow .18s ease;
}

/* Flat tiles: the art already carries the depth, so the card behind it does not.
   Pointing at one lights its edge rather than lifting it off the page. */
.category-card:hover,
.category-card:focus-visible {
  box-shadow: 0 0 22px rgba(168,31,26,.45);
}

/* One aspect PER PLATE, measured off the cropped file, so object-fit: cover has nothing
   left to trim. The plates are not all the same depth in the source artwork, and forcing
   them to a shared box is what would crop a frame edge off. */
.category-media { display: block; aspect-ratio: 3.9438; }
.category-card:nth-child(1) .category-media { aspect-ratio: 3.3743; }
.category-card:nth-child(2) .category-media { aspect-ratio: 4.0191; }
.category-card:nth-child(6) .category-media,
.category-card:nth-child(7) .category-media { aspect-ratio: 3.8476; }
.category-card:nth-child(8) .category-media { aspect-ratio: 3.5650; }

.category-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.category-blob { width: 100%; height: 100%; border-radius: 50%; filter: blur(1px); opacity: .9; }

/* Fallback swatches for a category with no photograph. Currently unreferenced -- every
   tile on the homepage has real art -- but kept because that is what they are FOR, and a
   missing tile should still land on-theme. They used to be a rainbow, one hue per
   category; with three colours to play with the identity has to come from VALUE instead,
   frost stepping down from bright to dark, and the red reserved for the fire sale. */
.cat-firesale { background: radial-gradient(circle at 40% 25%, #e0483a, #a81f1a 45%, #4b0a09); }
.cat-flower { background: radial-gradient(circle at 35% 30%, #f5fafd, #94a1ad); }
.cat-wax { background: radial-gradient(circle at 35% 30%, #dde6ed, #7a8792); }
.cat-snowballs { background: radial-gradient(circle at 35% 30%, #ffffff, #a3b1bd); }
.cat-moonrocks { background: radial-gradient(circle at 35% 30%, #c6d2db, #67727b); }
.cat-vapes { background: radial-gradient(circle at 35% 30%, #aebcc7, #58636c); }
.cat-prerolls { background: radial-gradient(circle at 35% 30%, #d4dde4, #6f7b85); }
.cat-edibles { background: radial-gradient(circle at 35% 30%, #b9c6d1, #4e5860); }
.cat-mushies { background: radial-gradient(circle at 35% 30%, #9fadb8, #434c54); }
.cat-merch { background: radial-gradient(circle at 35% 30%, #8a959e, #3a4249); }

@media (max-width: 680px) {
  .category-grid { row-gap: clamp(6px, 1.2vh, 10px); column-gap: clamp(2px, 0.5vh, 6px); }
  .category-card { border-radius: 12px; }
  .section.section--tight { padding: 10px 0; }

}

/* No hover on a touch screen, so the edge lights on press instead. */
@media (hover: none) and (pointer: coarse) {
  .category-card:active { border-color: var(--blood-hi); }
}

/* Above the drawer breakpoint there is more width going spare, so the grid keeps
   the same 1-2-2-2-1 rhythm on a wider canvas and the pairs get bigger. */
@media (min-width: 681px) {
  .category-grid {
    --tile-cap: 420px;
    --pack-w: 88%;
  }
  /* They ran at 66% when they were tall — full width made each one twice the pair
     beneath it. As a thin strip that no longer applies, so they stretch the whole
     width of the grid and read as the top and bottom rails of it. */
}

/* Landscape phone and short laptops: a column of eight banners cannot fit a 420px-tall
   viewport at any readable size, so they go two across instead of shrinking. TWO, not the
   four this used to run: every tile is a 4.26:1 plate now, and four across at 1100px makes
   each one 250px wide, where the type is the height of a full stop. Gated on width too --
   two across on a 375px-wide phone would be worse than scrolling. */
@media (max-height: 620px) and (min-width: 680px) {
  .category-grid {
    grid-template-columns: repeat(2, 1fr);
    column-gap: clamp(3px, 0.6vh, 8px);
    max-width: min(1100px, 94vw);
  }
  /* Side by side the rails are not rails, so they take the same box as the rest and the
     rows stay level. Cropping 3.74:1 art into a 4.26:1 box trims 12% off the sides, which
     is inside the plate's own border rather than into the lettering. */
  .category-grid .category-card:nth-child(n) .category-media { aspect-ratio: 3.9438; }
  .category-grid .category-card:nth-child(n) { width: 100%; justify-self: stretch; }
}

@media (max-height: 760px) {
  .section.section--tight { padding: 10px 0; }
}

.cta-band { border: 0; }
.cta-band .container { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 40px 24px; flex-wrap: wrap; }
.cta-band h3 { font-size: 18px; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 4px; }
.cta-band p { color: var(--text-muted); font-size: 13.5px; }
.cta-band .actions { display: flex; gap: 10px; flex-wrap: wrap; }

.cta-band.cta-band--links .container { justify-content: center; align-items: center; padding: 10px 24px; }
/* The two links are the band. Slimmer than a page button, still 44px to the thumb. */
.cta-band.cta-band--links .btn { min-height: 44px; padding: 10px 22px; font-size: 12px; }
.cta-band.cta-band--links .actions { justify-content: center; }

body.page-home { min-height: 100vh; display: flex; flex-direction: column; }
@supports (height: 100dvh) {
  body.page-home { min-height: 100dvh; }
}

.page-home .section.section--tight {
  flex: 1 1 auto; min-height: 0;
  display: flex; align-items: center;
  padding: clamp(10px, 2.4vh, 30px) 0;
}
.page-home .section.section--tight > .container { width: 100%; }

.page-home .cta-band.cta-band--links .container {
  padding: clamp(8px, 1.5vh, 18px) 24px;
}

.page-home::after {
  content: ''; display: block; flex: 1 1 0; max-height: clamp(0px, 5vh, 56px);
}

.footer { border-top: 1px solid var(--border); padding-top: 44px; font-size: 14px; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: 32px; padding-bottom: 32px; border-bottom: 1px solid var(--border); }
.footer h4 { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: var(--text); margin-bottom: 16px; font-weight: 800; }
.footer-grid p { color: var(--text-muted); font-size: 13px; line-height: 1.7; max-width: 320px; }
.footer-grid li { margin-bottom: 9px; }
.footer-grid a { color: var(--text-muted); font-size: 13px; }
.footer-grid a:hover { color: var(--text); }
.footer-contact { display: flex; flex-direction: column; gap: 10px; }
.footer-contact a { display: inline-flex; align-items: center; gap: 8px; color: var(--text-muted); font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: .3px; }
.footer-contact a:hover { color: var(--text); }
.footer-contact .dot { width: 5px; height: 5px; background: var(--frost); box-shadow: 0 0 8px rgba(198,210,219,.7); flex-shrink: 0; }
.pay-row { font-size: 11px; letter-spacing: .5px; text-transform: uppercase; color: var(--text-faint); margin-top: 14px; }
.footer-legal { padding: 22px 0 26px; color: var(--text-faint); font-size: 11px; line-height: 1.8; }
.footer-legal p { margin: 0 0 10px; }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; padding: 18px 0; border-top: 1px solid var(--border); color: var(--text-faint); font-size: 11.5px; text-transform: uppercase; letter-spacing: .3px; flex-wrap: wrap; gap: 10px; }
.footer-bottom .links { display: flex; gap: 18px; }
.footer-bottom .links a:hover { color: var(--text); }

.breadcrumb { padding: 16px 0; font-size: 11.5px; text-transform: uppercase; letter-spacing: .3px; color: var(--text-faint); border-bottom: 1px solid var(--border); }
.breadcrumb .container { display: flex; flex-wrap: wrap; row-gap: 4px; }
.breadcrumb a:hover { color: var(--text); }
.breadcrumb .sep { margin: 0 8px; }
.breadcrumb .current { color: var(--text-muted); overflow-wrap: anywhere; }

@media (max-width: 520px) {
  .breadcrumb { font-size: 10.5px; letter-spacing: .2px; }
  .breadcrumb .sep { margin: 0 5px; }
}

.shop-layout { display: grid; grid-template-columns: 230px 1fr; gap: 32px; align-items: start; }
.filter-box { border: 1px solid var(--border); padding: 18px; margin-bottom: 14px; }
.filter-box h4 { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 14px; color: var(--text-muted); }
.filter-row { display: flex; align-items: center; justify-content: space-between; padding: 7px 0; font-size: 13px; color: var(--text-muted); min-height: 32px; }
.filter-row:hover { color: var(--text); }
.filter-row input { accent-color: var(--frost); width: 15px; height: 15px; }
.filter-row .count { font-size: 11px; color: var(--text-faint); }
.range-slider { width: 100%; accent-color: var(--frost); margin: 10px 0; }
.shop-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; flex-wrap: wrap; gap: 12px; border-bottom: 1px solid var(--border); padding-bottom: 18px; }
.shop-toolbar .count-txt { color: var(--text-muted); font-size: 12.5px; text-transform: uppercase; letter-spacing: .3px; }

.shop-tools { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.search-box { position: relative; display: flex; align-items: center; }
.search-input {
  -webkit-appearance: none; appearance: none;
  background: transparent; border: 1px solid var(--border-light); color: var(--text);
  padding: 10px 34px 10px 14px; border-radius: 0; font-size: 12px; font-weight: 700;
  min-height: 40px; width: 220px; letter-spacing: .5px; text-transform: uppercase;
}
.search-input::placeholder { color: var(--text-muted); font-weight: 700; letter-spacing: .5px; }
.search-input:focus { outline: none; border-color: var(--frost); }

.search-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.search-clear {
  position: absolute; right: 2px; top: 50%; transform: translateY(-50%);
  width: 30px; min-height: 34px; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; color: var(--text-muted); font-size: 20px; line-height: 1; cursor: pointer;
}
.search-clear:hover { color: var(--text); }

.search-clear[hidden] { display: none; }
.select {
  background: transparent; border: 1px solid var(--border-light); color: var(--text);
  padding: 10px 14px; border-radius: 0; font-size: 12px; font-weight: 700; min-height: 40px;
  text-transform: uppercase; letter-spacing: .5px;
}
.pagination { display: flex; gap: 0; justify-content: center; margin-top: 36px; border: 1px solid var(--border); width: fit-content; margin-left: auto; margin-right: auto; }
.pagination a, .pagination span { min-width: 38px; height: 38px; display: flex; align-items: center; justify-content: center; border-right: 1px solid var(--border); font-size: 12px; font-weight: 700; padding: 0 6px; }
.pagination a:last-child, .pagination span:last-child { border-right: none; }
.pagination .active { background: var(--frost-metal); color: var(--frost-ink); box-shadow: var(--frost-emboss); }
.pagination a:hover { color: var(--frost-hi); background: var(--surface-2); }

.product-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; }
.gallery-main { aspect-ratio: 1/1; margin-bottom: 10px; border: 1px solid var(--border); }

.gallery-main--photo { aspect-ratio: auto; border: none; }
.gallery-frame { position: relative; aspect-ratio: 1/1; border: 1px solid var(--border); overflow: hidden; }
.gallery-frame img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.gallery-thumbs { display: flex; gap: 8px; margin-top: 8px; }
.gallery-thumb { width: 64px; height: 64px; flex-shrink: 0; padding: 0; border: 1px solid var(--border); background: none; opacity: .6; }
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-thumb:hover { opacity: .85; }
.gallery-thumb.active { opacity: 1; border-color: var(--frost); }

.gallery-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; border-radius: 50%;
  background: rgba(10,10,12,.85); border: 1px solid var(--frost);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; line-height: 1; color: var(--frost-hi); cursor: pointer;
}
.gallery-nav:hover { background: var(--frost); color: var(--frost-ink); }
.gallery-nav--prev { left: 10px; }
.gallery-nav--next { right: 10px; }

.lightbox { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; }
.lightbox[hidden] { display: none; }
.lightbox:not([hidden]) { animation: lightbox-fade .18s ease; }
@keyframes lightbox-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .lightbox:not([hidden]) { animation: none; } }
body.lightbox-open { overflow: hidden; }
.lightbox-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.9); }
.lightbox-img { position: relative; z-index: 1; max-width: 90vw; max-height: 88vh; object-fit: contain; }
.lightbox-close {
  position: absolute; top: 16px; right: 16px; z-index: 2;
  width: 44px; height: 44px; background: transparent; border: none;
  color: #fff; font-size: 30px; line-height: 1; cursor: pointer;
}
.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 52px; height: 52px; border-radius: 50%;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.35);
  color: #fff; font-size: 28px; line-height: 1;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.lightbox-nav:hover { background: rgba(255,255,255,.24); }
.lightbox-nav--prev { left: 12px; }
.lightbox-nav--next { right: 12px; }
@media (max-width: 520px) {
  .lightbox-nav { width: 44px; height: 44px; font-size: 24px; }
  .lightbox-nav--prev { left: 6px; }
  .lightbox-nav--next { right: 6px; }
}
.product-info .card-cat { font-size: 11px; }
.product-title { font-size: 20px; font-weight: 800; margin: 8px 0 12px; letter-spacing: .3px; text-transform: uppercase; }
.product-price { font-size: 18px; font-weight: 700; color: var(--frost-hi); margin-bottom: 14px; text-shadow: var(--frost-glow); }

.stock-meter { margin-bottom: 20px; max-width: 280px; }
.stock-meter-track { height: 6px; background: var(--surface-2); border: 1px solid var(--border); overflow: hidden; }
.stock-meter-fill { height: 100%; width: 0%; background: var(--frost-metal); box-shadow: 0 0 10px rgba(198,210,219,.5); transition: width .5s ease; }
.stock-meter-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); margin-top: 7px; }
.stock-meter--low .stock-meter-fill { background: var(--red); animation: stock-fill-pulse 1.8s ease-in-out infinite; }
.stock-meter--low .stock-meter-label { color: var(--red); }
.stock-meter--out .stock-meter-fill { background: var(--text-faint); }
.stock-meter--out .stock-meter-label { color: var(--text-faint); }
@keyframes stock-fill-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .5; }
}
@media (prefers-reduced-motion: reduce) {
  .stock-meter--low .stock-meter-fill { animation: none; }
}

.qty-add { display: flex; gap: 10px; align-items: center; margin-bottom: 22px; }
.qty-box { display: flex; align-items: center; border: 1px solid var(--border-light); }
.qty-box button { width: 40px; height: 46px; background: transparent; border: none; color: var(--text); font-size: 16px; }
.qty-box button:hover { color: var(--text-muted); }
.qty-box input { width: 40px; text-align: center; background: transparent; border: none; color: var(--text); font-size: 14px; }
.product-meta-row { display: flex; gap: 20px; font-size: 12px; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); border-top: 1px solid var(--border); padding-top: 16px; flex-wrap: wrap; }

.cart-layout { display: grid; grid-template-columns: 1fr 360px; gap: 40px; align-items: start; }
.cart-row { display: grid; grid-template-columns: 80px 1fr auto auto auto; gap: 16px; align-items: center; padding: 18px 0; border-bottom: 1px solid var(--border); }

.cart-block {
  font-size: 12px; font-weight: 700; letter-spacing: .3px; text-align: center; margin-top: 10px;
  color: var(--red); text-transform: uppercase;
}
.cart-note { font-size: 11px; font-weight: 600; letter-spacing: .3px; margin-top: 4px; color: var(--text-muted); }
.cart-note--gone { color: var(--red); }
.cart-row--gone .cart-thumb, .cart-row--gone .card-title { opacity: .55; }
.cart-thumb { width: 72px; height: 72px; position: relative; overflow: hidden; }
.cart-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cart-remove { display: inline-flex; padding: 8px; color: var(--text-faint); }
.cart-remove:hover { color: var(--text); }
.summary-box { border: 1px solid var(--border); padding: 24px; }
.summary-box h3 { font-size: 14px; letter-spacing: 1px; text-transform: uppercase; margin-bottom: 18px; font-weight: 800; }
.summary-row { display: flex; justify-content: space-between; padding: 10px 0; font-size: 13px; text-transform: uppercase; letter-spacing: .3px; color: var(--text-muted); border-bottom: 1px solid var(--border); }
.summary-row.total { color: var(--text); font-weight: 800; font-size: 15px; border-bottom: none; padding-top: 14px; }
.coupon-row { display: flex; gap: 8px; margin: 16px 0; }
.coupon-row input { flex: 1; background: transparent; border: 1px solid var(--border-light); padding: 11px 14px; color: var(--text); font-size: 12.5px; min-height: 40px; text-transform: uppercase; letter-spacing: .3px; }
.empty-cart { text-align: center; padding: 72px 24px; color: var(--text-muted); }

.order-note-label {
  display: block; margin-top: 16px; margin-bottom: 6px;
  font-size: 10px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
  color: var(--text-muted);
}
.order-note {
  width: 100%; background: transparent; border: 1px solid var(--border-light);
  padding: 10px 12px; color: var(--text); font-family: inherit; font-size: 13px;
  resize: vertical;
}
.order-note:focus { outline: none; border-color: var(--frost); }

.send-panel { margin-top: 18px; border-top: 1px solid var(--border); padding-top: 16px; }
.send-panel[hidden] { display: none; }
.send-panel h4 {
  font-size: 11px; letter-spacing: 1px; text-transform: uppercase;
  margin-bottom: 8px; color: var(--text);
}
.send-hint { font-size: 12px; line-height: 1.6; color: var(--text-muted); margin: 0 0 12px; }
.send-actions { display: flex; flex-direction: column; gap: 8px; }


@media (max-width: 520px) {
}


.btn-plain {
  display: block; width: 100%; min-height: 44px; margin-top: 10px;
  background: none; border: 0; padding: 12px 8px;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .3px;
  text-transform: uppercase; color: var(--text-muted); text-decoration: underline;
  cursor: pointer;
}
.btn-plain:hover { color: var(--text); }

.invoice-modal { position: fixed; inset: 0; z-index: 1100; display: flex; align-items: center; justify-content: center; padding: 16px; }
.invoice-modal[hidden] { display: none; }
.invoice-modal:not([hidden]) { animation: lightbox-fade .18s ease; }
@media (prefers-reduced-motion: reduce) { .invoice-modal:not([hidden]) { animation: none; } }
body.invoice-open { overflow: hidden; }
.invoice-modal-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.7); }
.invoice-modal-box {
  position: relative; z-index: 1; width: 100%; max-width: 460px;
  max-height: 88vh; display: flex; flex-direction: column;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-light);
  border-radius: 14px; padding: 18px 16px 16px;
  box-shadow: 0 18px 50px rgba(0,0,0,.7);
}
@supports (height: 1dvh) { .invoice-modal-box { max-height: 88dvh; } }
.invoice-modal-box h4 { font-size: 14px; letter-spacing: .5px; text-transform: uppercase; margin: 0 0 6px; }

.invoice-modal-text {
  flex: 0 1 auto; min-height: 0; margin-bottom: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere;
  overflow-x: hidden; overflow-y: auto; resize: none;
}

@media (max-width: 420px) {
  .invoice-modal-box { padding: 16px 12px 12px; }
  .invoice-modal-text { font-size: 11px; }
}
.invoice-modal-close {
  position: absolute; top: 6px; right: 8px; width: 40px; height: 40px;
  background: none; border: 0; font-size: 26px; line-height: 1;
  color: var(--text-muted); cursor: pointer;
}
.invoice-modal-close:hover { color: var(--text); }

.send-actions .btn { width: 100%; }

#checkout-btn[disabled] { opacity: .45; cursor: not-allowed; }

.filter-toggle-btn { display: none; }
@media (max-width: 1080px) {
  .grid { grid-template-columns: repeat(3, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .product-layout { grid-template-columns: 1fr; }
  .cart-layout { grid-template-columns: 1fr; }
}
@media (max-width: 860px) {
  .main-nav-row { display: none; }
  .burger { display: flex; }
  .mobile-only { display: inline-flex !important; }

  .header-logo-row { padding: 4px 14px; justify-content: space-between; gap: 6px; flex-wrap: wrap; }
  .header-left,
  .header-icons { position: static; transform: none; }
  .header-icons { gap: 6px; }
  /* The 44px tap targets either side already set the row's height, so the mark can
     come down to meet them and the padding does the rest. */
  .header-logo-img { height: clamp(44px, 9vw, 52px); }
  .icon-btn--chat { width: 30px; }
  .utility-bar .container { justify-content: center; gap: 16px; }
  .grid { grid-template-columns: repeat(2, 1fr); }
  .shop-layout { grid-template-columns: 1fr; }
  .cta-band .container { flex-direction: column; align-items: flex-start; }
  /* ...but not the links band. That rule is for the copy-plus-buttons band, which reads
     better left-aligned once it stacks; the links band is a single centred button and
     inherits flex-start from it otherwise. Only 681-860px was affected -- the <=680px
     block already re-centres -- which is exactly the width nobody opens by hand. */
  .cta-band.cta-band--links .container { flex-direction: row; align-items: center; justify-content: center; }
  .filter-toggle-btn { display: inline-flex; }

  .shop-tools { width: 100%; justify-content: flex-start; }
  .search-box { flex: 1 1 100%; order: -1; }
  .search-input { width: 100%; }

  .search-input,
  .select { font-size: 16px; }
  .filters-col { display: none; }
  .filters-col.open { display: block; }
  .section { padding: 40px 0; }
  .product-title { font-size: 17px; }
}
@media (max-width: 520px) {
  .footer-grid { grid-template-columns: 1fr; }
  .container { padding: 0 16px; }
  .cart-row { grid-template-columns: 60px 1fr; row-gap: 10px; }
  .cart-row > *:nth-child(3) { grid-column: 2; }
  .cart-row > *:nth-child(4) { grid-column: 2; }
  .cart-row > *:nth-child(5) { grid-column: 2; justify-self: start; }
  .qty-add { flex-wrap: wrap; }
  .qty-add .btn { width: 100%; order: 3; }
}

@media (max-width: 680px) {
  .cta-band.cta-band--links .container { padding: 6px 16px; align-items: center; gap: 8px; }
  .cta-band.cta-band--links .btn { padding: 10px 18px; font-size: 11.5px; }
}
@media (max-height: 760px) {
  .cta-band.cta-band--links .container { padding: 8px 24px; }
}

@media (hover: none) and (pointer: coarse) {
  .burger { width: 44px; height: 44px; }
  /* Square crest: the home link is no wider than it is tall, so it gets padded out
     to a 44px target rather than growing the emblem past the row height. */
  .header-logo-row .logo { min-height: 44px; padding-inline: 5px; }

  .icon-btn:not(.icon-btn--chat) { width: 44px; height: 44px; }
  .icon-btn--chat { height: 44px; }
  .cart-remove { padding: 14px; }
  .btn-sm { min-height: 44px; }

  .pagination a, .pagination span { min-width: 44px; min-height: 44px; }
  .filter-row { min-height: 44px; }
  .filter-row input { width: 20px; height: 20px; }

  .order-note,
  .coupon-row input,
  .qty-box input,
  .search-input,
  .select { font-size: 16px; }
}

.gate-wrap { min-height: 82vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.lock-card {
  max-width: 460px; width: 100%; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 32px;
  position: relative; z-index: 2;
}
/* The hero is STEADY. It used to breathe -- an animated filter: drop-shadow plus a 1.5%
   scale pulse -- and on a 700px alpha illustration that is two expensive things per frame:
   the shadow is re-rasterised from the alpha channel, and the bitmap is resampled at a new
   sub-pixel size, so the detail crawls. Against the smoke rising off it, that reads as the
   picture flickering rather than as anything glowing.

   The glow stays; it is simply painted once and left alone. Nothing here animates now, so
   the only moving thing on the splash is the smoke, which is where the movement belongs. */
.gate-logo {
  width: clamp(230px, 46vw, 400px); height: auto; display: block;
  filter: drop-shadow(0 0 30px rgba(168,31,26,.40));
}
.lock-form { display: flex; flex-direction: column; align-items: center; gap: 26px; width: 100%; }
.gate-group { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; }
.lock-label {
  font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
  color: var(--text-muted); margin: 0;
}
.lock-input {
  width: 100%; max-width: 260px; text-align: center;
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
  padding: 13px 16px; font-size: 15px; letter-spacing: 3px; font-family: inherit;
}
.lock-input::placeholder { color: var(--text-faint); letter-spacing: 1px; }
.lock-input:focus { outline: none; border-color: var(--frost); }
.lock-input.is-shaking { animation: lock-shake .32s ease; }
.lock-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 46px; min-width: 200px; padding: 12px 26px;
  border: 1px solid var(--frost); background: transparent; color: var(--frost-hi);
  font-size: 12.5px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  cursor: pointer; transition: background .15s ease, color .15s ease;
}
.lock-btn:hover { background: var(--blood-metal); color: var(--text); box-shadow: var(--frost-emboss), 0 4px 24px rgba(168,31,26,.5); }
.lock-btn[disabled] { opacity: .6; cursor: default; }

.lock-btn.is-nudged { animation: lock-nudge .5s ease; }
@keyframes lock-nudge {
  0%, 100% { background: transparent; color: var(--frost-hi); transform: none; }
  25%      { background: var(--blood); color: var(--text); transform: scale(1.04); }
  60%      { background: var(--blood); color: var(--text); transform: none; }
}
.lock-error {
  margin: 0; font-size: 12px; letter-spacing: .3px; text-transform: uppercase;
  color: var(--red); font-weight: 600;
}
.lock-error[hidden] { display: none; }
.lock-note {
  font-size: 11px; color: var(--text-faint); letter-spacing: .3px; max-width: 340px;
  line-height: 1.6; margin: 0;
}

@media (max-height: 760px) {
  .gate-wrap { min-height: 100vh; padding: 16px; }
  .lock-card { gap: 18px; }
  .lock-form { gap: 16px; }
  .gate-group { gap: 8px; }
  .gate-logo { width: clamp(170px, 32vw, 250px); }
}
@media (max-height: 560px) {
  .lock-card { gap: 12px; }
  .lock-form { gap: 12px; }
  .gate-logo { width: clamp(120px, 24vw, 170px); }
  .lock-note { font-size: 10px; line-height: 1.45; max-width: 420px; }
}
@keyframes lock-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-8px); }
  75% { transform: translateX(8px); }
}

/* The gate IS a wall — a plain dark screen hiding the shop until the password is
   right. This overlay is that same wall rendered on the page behind it: two halves
   sharing one jagged seam, covering it exactly (same --bg), so showing it changes
   nothing the visitor can see. Verifying age is what cracks it open. Hidden by
   default and only shown by the inline script in home.part.php when the gate just
   redirected here — a plain later visit to the homepage never sees it. */
/* The gate is a wall; verifying age SHATTERS it onto the shop.
   Cracks race out from the impact point first, then the wall itself breaks into
   chunks that fly away — inner ones first, so the hole opens at the middle and grows,
   the way a real wall gives. Every shard is a full-viewport box clipped to one
   polygon; PHP emits the geometry, so the whole thing is declarative CSS that starts
   on its own the instant it renders, with no JS in the path to mistime or skip. */
/* The shop, pulled in behind the wall before it breaks. A snapshot with its scripts
   inert -- it is on screen for well under a second, mostly behind flying chunks, and
   the real page replaces it the moment the break finishes. Mirrors body.page-home's
   own column layout so the shop lands where it will land for real. */
.lk-reveal {
  position: fixed; inset: 0; z-index: 1; overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--bg);
  /* Hidden until the smoke has actually covered the screen. visibility as well as
     opacity, so nothing in here can be tabbed to or read out while it is invisible. */
  opacity: 0; visibility: hidden;
}
.lk-reveal.is-shown { opacity: 1; visibility: visible; }
/* ---- Smoke -------------------------------------------------------------------
   One fixed canvas for both jobs: the wisps that ooze off the artwork while the gate
   is idle, and the billow that swallows the screen once the password lands. It sits
   BEHIND the gate card at rest (z-index 0 against the card's 2) so the smoke reads as
   coming off the picture rather than floating over it, and is promoted above
   everything for the burst, which has to cover the card as well as the page. */
.lk-smoke {
  /* ABOVE the gate card (z-index 2), not behind it. The cigar is in the middle of an
     opaque illustration, so a canvas underneath draws a perfectly good plume that
     nobody can ever see -- it is hidden by the picture it is supposed to be coming out
     of. Safe to sit on top because idle particles only ever rise: they leave the ember,
     climb past the hat and are gone, and never reach the password field below. */
  position: fixed; inset: 0; z-index: 3; pointer-events: none;
  width: 100%; height: 100%;
  /* Its own compositor layer. Without it, a full-viewport canvas repainting at 60fps
     forces the layer beneath to repaint too, and the hero's drop-shadow is the most
     expensive thing on the page to re-rasterise. */
  transform: translateZ(0);
  will-change: transform;
}
.lk-smoke.is-burst { z-index: 600; }

.promo-pop { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 20px; }
.promo-pop[hidden] { display: none; }
.promo-pop-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.82); }
.promo-pop-box {
  position: relative; width: 100%; max-width: 620px; text-align: center;
  background: linear-gradient(158deg, #c53a2c 0%, #a4201a 26%, #7d1210 55%, #5a0d0c 72%, #b22a22 100%);
  color: var(--text); border: 4px solid var(--frost);
  padding: 46px 34px 40px; box-shadow: 0 24px 60px rgba(0,0,0,.7);
  animation: promo-pop-in .32s cubic-bezier(.2,.9,.3,1.2);
  max-height: calc(100vh - 40px); overflow-y: auto;
}
.promo-pop-kicker { font-size: clamp(28px, 7vw, 54px); font-weight: 900; line-height: .98; letter-spacing: -1px; text-transform: uppercase; margin: 0 0 14px; }
.promo-pop-line { font-size: clamp(15px, 2.6vw, 21px); font-weight: 800; letter-spacing: .5px; text-transform: uppercase; line-height: 1.35; margin: 0 0 8px; }
.promo-pop-deals { display: flex; flex-direction: column; gap: 6px; margin: 14px 0 4px; }
.promo-pop-deal { display: flex; align-items: baseline; justify-content: center; gap: 10px; flex-wrap: wrap; }
.promo-pop-off { font-size: clamp(30px, 7.4vw, 56px); font-weight: 900; line-height: 1.05; letter-spacing: -2px; }
.promo-pop-per { font-size: clamp(12px, 2.3vw, 17px); font-weight: 800; letter-spacing: 1px; text-transform: uppercase; opacity: .95; }
.promo-pop-terms { font-size: clamp(11px, 2vw, 13.5px); font-weight: 700; letter-spacing: .6px; text-transform: uppercase; line-height: 1.35; opacity: .9; margin: 10px 0 0; }
.promo-pop-cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 22px; min-height: 54px; padding: 14px 34px;
  background: var(--bg); color: var(--frost-hi); border: 1px solid var(--frost);
  font-size: 17px; font-weight: 900; letter-spacing: 1.5px; text-transform: uppercase;
}
.promo-pop-cta:hover { background: var(--frost-hi); color: var(--frost-ink); }
.promo-pop-num { display: block; margin-top: 14px; font-size: 13px; font-weight: 700; letter-spacing: 1px; color: var(--text); opacity: .92; }
.promo-pop-close {
  position: absolute; top: 6px; right: 10px; width: 44px; height: 44px;
  background: none; border: none; color: var(--text); font-size: 30px; line-height: 1; cursor: pointer;
}
.promo-pop-close:hover { opacity: .7; }
.promo-pop-dismiss {
  display: block; margin: 16px auto 0; background: none; border: none; color: var(--text);
  font-size: 11px; letter-spacing: .8px; text-transform: uppercase; opacity: .8;
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
@keyframes promo-pop-in {
  from { transform: scale(.88) translateY(14px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .category-card { transition: border-color .15s ease; }

  .lock-input.is-shaking { animation: none; }

  .lock-btn.is-nudged { animation: none; background: var(--blood); color: var(--text); }
  .promo-pop-box { animation: none; }
  /* The smoke canvas is never created under reduced motion -- the gate navigates
     straight through -- so there is nothing here to switch off. */
}

/* ======================== LIQUID METAL =========================
   Third pass. The first two built the metal out of a many-banded
   gradient, and the bands were the problem: a gradient can only make
   STRAIGHT lines, so the surface read as a striped ramp sliding
   sideways. Straight stripes are what cheap metal looks like.

   Real pattern-welded steel -- damascus -- has folded, flowing grain, and
   no gradient of any number of stops can produce it. So the grain is now
   a texture: assets/metal-grain.webp, 256px, 10.8KB, neutral grey so it
   retints with whatever body ramp it is blended over, generated by
   domain-warping a periodic field and then contouring it. Every term in
   that field is a sinusoid at an integer frequency over the tile, so it
   wraps exactly and the flow never shows a seam.

   Three layers, and only two of them move:

     BODY   the metal itself, a GENTLE gradient held STILL. Nothing about
            the body slides any more. That single change is most of what
            makes this read as a solid metal object catching light rather
            than as a video playing inside a button.
     GRAIN  the damascus tile, blended soft-light so it MODULATES the
            body instead of painting over it -- mid grey in the texture is
            a no-op, which is why it is histogram-centred when generated.
            It drifts one whole tile per cycle, diagonally, so the grain
            flows along its own lines. Movement ALONG the grain is far
            quieter than bands crossing it.
            The tile is mostly narrow specular glints with only a whisper
            of broad figure, and that ratio is the whole trick: wood grain
            and damascus grain have nearly the same geometry, and what
            separates them to the eye is that metal throws thin bright
            lines while timber has broad soft bands. Rendered bold, the
            figure read as maple veneer on every button. See
            tools/make-metal-grain.py --river / --ridge.
     GLOSS  one soft specular band, sized in percent so a large surface
            gets a large highlight, crossing once per cycle.

   The separate speck layers are gone. The grain carries fine detail of
   its own, and confetti on top of flowing steel is the opposite of
   subtle. Restoring them is one line if they are missed.
   ============================================================== */
:root {
  /* THE SPEED KNOB -- every metal surface is tied to it. */
  --frost-cycle: 22s;
  --frost-halo-cycle: 11s;
  /* Tile scale. The animation below moves the grain by exactly this much,
     so the two have to change together or the loop gains a seam. */
  --frost-grain: 110px;

  /* The BODY is now light-from-above rather than a bright band sliding
     across, and its range is deliberately narrow. Three versions of this
     were rendered against the real 26px support bar and compared:
       a wide horizontal ramp put an arbitrary bright blob mid-bar;
       a flat fill with no ramp at all read as matte paint, not metal;
       gentle top-lighting read as a strip catching light.
     2deg off vertical, because a perfectly axis-aligned ramp looks
     printed. The grain carries the character; this gives the form.

     BRIGHTNESS, second pass. The first palette was sandy -- around 66-79%
     saturation with a pale top -- and next to the tile trim it read as
     Frost rather than chrome: a neutral grey ramp reads as dirty plastic on
     black, so the shadow end cools into blue instead.
  */
  --frost-body: linear-gradient(178deg,
    #ffffff 0%, #f0f6fa 8%, #c8d4de 34%, #94a1ad 66%, #5c666f 100%);
  --frost-grain-img: url('assets/metal-grain.webp?v=590e2ab6a8');
  --frost-gloss: linear-gradient(102deg,
    rgba(255,255,255,0) 40%, rgba(255,255,255,.14) 46%,
    rgba(255,255,255,.52) 50%, rgba(255,255,255,.14) 54%,
    rgba(255,255,255,0) 60%);

  --blood-body: linear-gradient(178deg,
    #f0a99c 0%, #d4584a 8%, #b0201a 34%, #7a100e 66%, #3d0807 100%);
  --blood-layers: var(--frost-gloss), var(--frost-grain-img), var(--blood-body);

  --frost-layers: var(--frost-gloss), var(--frost-grain-img), var(--frost-body);
  --frost-layer-size: 240% 100%, var(--frost-grain) var(--frost-grain), 100% 100%;
  --frost-layer-repeat: no-repeat, repeat, no-repeat;
  --frost-layer-blend: screen, soft-light, normal;
}

/* The grain steps exactly one tile in each axis, so the loop is seamless;
   the gloss sweeps the element; the body never moves. */
@keyframes frost-live {
  from { background-position: -70% 0, 0 0, 0 0; }
  to   { background-position: 180% 0, calc(var(--frost-grain) * -1) var(--frost-grain), 0 0; }
}

/* FROST fills -- all of these previously said `background: var(--frost-metal)`. */
.btn-primary,
.btn-outline:hover,
.qbtn:hover,
.gallery-nav:hover,
.pagination .active,
.stock-meter-fill {
  background-image: var(--frost-layers);
  background-size: var(--frost-layer-size);
  background-repeat: var(--frost-layer-repeat);
  background-blend-mode: var(--frost-layer-blend);
  animation: frost-live var(--frost-cycle) linear infinite;
}

/* BLOOD fills — same material, red body. The support bar is the shop's banner and
   the gate button is the moment the doors open, which is exactly where the artwork
   puts red. */
.support-bar,
.badge,
.lock-btn:hover,
.lock-btn.is-nudged {
  background-image: var(--blood-layers);
  background-size: var(--frost-layer-size);
  background-repeat: var(--frost-layer-repeat);
  background-blend-mode: var(--frost-layer-blend);
  animation: frost-live var(--frost-cycle) linear infinite;
  color: var(--text);
}

/* FROST text. Same material clipped to the glyphs. A text-shadow cannot be
   used on transparent text -- it draws the shadow of a shape nobody can
   see -- so the outer glow is a drop-shadow filter, which follows the
   visible pixels. */
.section-head h2,
.frost-head,
.product-price,
.card-price,
.card-price .now {
  background-image: var(--frost-layers);
  background-size: var(--frost-layer-size);
  background-repeat: var(--frost-layer-repeat);
  background-blend-mode: var(--frost-layer-blend);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 0 12px rgba(198,210,219,.34));
}
/* Headings and the single product price animate. Card prices do not: that
   one repeats dozens of times per screen, and sixty small elements
   repainting every frame costs real battery for something illegible at
   13px. They keep the material, still. */
.section-head h2,
.frost-head,
.product-price {
  animation: frost-live var(--frost-cycle) linear infinite;
}

/* FROST borders: a 1px ring of the same material, as a masked pseudo-
   element, because a border cannot hold a gradient. The grain is left out
   -- at one pixel there is nothing of it to see.

   Geometry: the border stays 1px and only turns transparent, so nothing
   reflows. The ring sits at inset:-1px, the BORDER box; an absolutely
   positioned child is offset from the PADDING box, so inset:0 would draw
   it a pixel inside the border and leave a transparent hairline outside.

   GUARDED, and the guard is not decoration. Without mask compositing the
   two mask layers UNION instead of subtracting, so the ring would paint
   as a SOLID METAL RECTANGLE over the whole control -- covering the label
   on every outline button, the checkout send buttons included. This site
   is opened inside Instagram and TikTok webviews on purpose, which is
   exactly where an old engine turns up. No mask support, no ring, and the
   original solid border is left exactly as it was. */
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .btn,
  .qbtn,
  .gallery-nav,
  .lock-btn {
    position: relative;
    border-color: transparent;
  }
  .btn::after,
  .qbtn::after,
  .gallery-nav::after,
  .lock-btn::after {
    content: ''; position: absolute; inset: -1px; padding: 1px;
    border-radius: inherit; pointer-events: none;
    background-image: var(--frost-gloss), var(--frost-body);
    background-size: 240% 100%, 100% 100%;
    background-repeat: no-repeat, no-repeat;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
    animation: frost-edge var(--frost-cycle) linear infinite;
  }
  .gallery-nav::after { border-radius: 50%; }
}
@keyframes frost-edge {
  from { background-position: -70% 0, 0 0; }
  to   { background-position: 180% 0, 0 0; }
}

/* Thin frost trim on the category tiles.
   NOT the masked ring above, and it cannot be: .category-card sets
   overflow:hidden, which clips a pseudo-element at inset:-1px straight off
   the card. This rides the card's OWN background instead -- a solid fill
   clipped to the padding box, the metal clipped to the border box, so the
   metal paints in the 1px border channel and nowhere else.
   background-origin/background-clip ignore overflow, and the corner radius
   comes along for free. */
.category-card {
  border-color: transparent;
  background-image: linear-gradient(#16151a, #16151a), var(--frost-gloss), var(--frost-body);
  background-size: auto, 240% 100%, 100% 100%;
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-origin: border-box;
  background-clip: padding-box, border-box, border-box;
  animation: frost-trim var(--frost-cycle) linear infinite;
}
@keyframes frost-trim {
  from { background-position: 0 0, -70% 0, 0 0; }
  to   { background-position: 0 0, 180% 0, 0 0; }
}

/* The logo is a PNG, not text, so there are no glyphs to clip a gradient
   to. It gets a slow breathing halo instead, on its own clock so the
   header does not pulse in lockstep with the bar above it. */
@keyframes frost-halo {
  0%, 100% { filter: drop-shadow(0 0 6px rgba(198,210,219,.28)); }
  50%      { filter: drop-shadow(0 0 15px rgba(236,244,250,.52)); }
}
.header-logo-img,
.drawer-logo-img {
  animation: frost-halo var(--frost-halo-cycle) ease-in-out infinite;
}

/* ---- Breathing glow, the same idea as the logo halo ----
   A metal surface on jet black wants to look LIT, not printed, and the
   cheapest honest way to say that is an outer glow that breathes. This is
   filter: drop-shadow rather than box-shadow deliberately: every one of
   these elements already carries a box-shadow (emboss insets, lift), and
   animating that property would have to restate all of it and would drop
   whatever it forgot. A filter composes on top and touches nothing.

   All of it runs on --frost-halo-cycle, the LOGO's clock, so the header
   mark and the metal around it breathe together instead of drifting in and
   out of phase.

   WHY IT IS NOT ON EVERY METAL THING. Counted live: the shop grid renders
   25 .btn-primary and 24 .card-price on one screen. A blurred shadow
   repainting 25 times a frame is a real cost on a phone, for a glow
   nobody looks at on a card button. So the breathing glow goes on the
   handful of one-off surfaces, and the grid buttons get a stronger STATIC
   glow instead. .btn-sm is the tell -- it is only ever on the grid
   cards. */
@keyframes frost-breathe {
  0%, 100% { filter: drop-shadow(0 0 5px rgba(188,201,211,.26)); }
  50%      { filter: drop-shadow(0 0 17px rgba(238,246,251,.54)); }
}
/* The tiles sit in a grid with gaps as small as 3px, so a full-strength
   glow on each would pool into one warm haze instead of reading as eight
   lit objects. Theirs is deliberately about a third as strong. */
@keyframes frost-breathe-soft {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(188,201,211,.16)); }
  50%      { filter: drop-shadow(0 0 11px rgba(238,246,251,.32)); }
}
.support-bar,
.badge,
.pagination .active,
.btn-primary:not(.btn-sm) {
  animation: frost-live var(--frost-cycle) linear infinite,
             frost-breathe var(--frost-halo-cycle) ease-in-out infinite;
}
.category-card {
  animation: frost-trim var(--frost-cycle) linear infinite,
             frost-breathe-soft var(--frost-halo-cycle) ease-in-out infinite;
}
/* The 25 grid buttons: same warmth, no per-frame cost. */
.btn-primary.btn-sm {
  box-shadow: var(--frost-emboss), 0 0 18px rgba(188,201,211,.34), 0 3px 14px rgba(0,0,0,.5);
}

/* Reduced motion: the material, none of the movement. Still metal, just
   standing still. */
@media (prefers-reduced-motion: reduce) {
  .btn-primary, .btn-primary:not(.btn-sm), .btn-outline:hover, .qbtn:hover, .gallery-nav:hover,
  .lock-btn:hover, .lock-btn.is-nudged, .support-bar, .badge,
  .pagination .active, .stock-meter-fill,
  .section-head h2, .frost-head, .product-price,
  .btn::after, .qbtn::after, .gallery-nav::after, .lock-btn::after,
  .category-card,
  .header-logo-img, .drawer-logo-img {
    animation: none;
  }
}
