/* Vanta Supply · the phone menu, on every page (round 25, 2026-10-21). Built by menu.js.
   Below 641px the header keeps only the wordmark and a two-line button; the sheet unrolls from the
   top under the header. The header never moves, so nothing on the page shifts when the menu opens. */

.burger, .msheet { display: none; }

@media (max-width: 640px) {
  .nav__links, .nav__right .btn, .nav__right .signin, html[data-as="member"] .nav__right .signin { display: none !important; }
  .nav { grid-template-columns: 1fr auto; }

  .burger {
    position: relative; display: grid; place-content: center; gap: 6px;
    width: 44px; height: 44px; margin-right: -10px; border-radius: 999px;
  }
  .burger span { display: block; width: 20px; height: 1.5px; border-radius: 2px; background: var(--ink); transition: transform .4s var(--ease); }
  .burger[aria-expanded="true"] span:first-child { transform: translateY(3.75px) rotate(45deg); }
  .burger[aria-expanded="true"] span:last-child { transform: translateY(-3.75px) rotate(-45deg); }

  /* the sheet: fixed over the page, just under the header (the header sits one layer above it) */
  .msheet {
    display: block; position: fixed; inset: 0; z-index: 39;
    overflow-y: auto; overscroll-behavior: contain;
    background: var(--bg);
    clip-path: inset(0 0 100% 0); visibility: hidden; /* rolled up */
    transition: clip-path .5s cubic-bezier(.76, 0, .24, 1) .08s, visibility 0s linear .58s;
  }
  .msheet.is-open { clip-path: inset(0); visibility: visible; transition: clip-path .55s cubic-bezier(.76, 0, .24, 1); }
  /* a solid strip behind the header, so the menu's own scrolling slides under the wordmark and the X */
  .msheet::before { content: ""; position: sticky; top: 0; z-index: 1; display: block; height: 68px; margin-bottom: -68px; background: var(--bg); }
  html.m-open, html.m-open body { overflow: hidden; }

  .msheet__in { display: grid; align-content: start; min-height: 100%; padding-top: 84px; padding-bottom: 0; }
  .msheet__label { font-size: 13px; color: var(--faint); margin-bottom: 8px; }
  .mrow { display: flex; align-items: center; gap: 16px; min-height: 76px; padding: 8px 0; border-bottom: 1px solid var(--line); }
  .mrow__th { width: 56px; height: 56px; border-radius: 12px; overflow: hidden; flex: none; background: var(--raise); }
  .mrow__th img { width: 100%; height: 100%; object-fit: cover; }
  .mrow__tx { display: grid; gap: 3px; min-width: 0; }
  .mrow__name { font-family: var(--font-head); font-weight: var(--head-w); font-size: calc(24px * var(--head-s)); letter-spacing: calc(var(--head-t) * 0.6); line-height: 1.1; }
  .mrow[aria-current="page"] .mrow__name::after { content: ""; display: inline-block; width: 6px; height: 6px; margin-left: 10px; border-radius: 50%; background: var(--accent); vertical-align: middle; }
  .mrow__line { font-size: 14px; color: var(--mute); text-wrap: balance; }
  .msheet__links { display: grid; margin-top: 16px; }
  .msheet__links a { display: flex; align-items: center; min-height: 52px; font-size: 18px; color: var(--ink); border-bottom: 1px solid var(--line); }
  /* Join for free stays in reach at the foot of the sheet, clear of the phone's home bar */
  .msheet__cta {
    position: sticky; bottom: 0; margin-top: auto; padding: 28px 0 calc(16px + env(safe-area-inset-bottom));
    display: grid; gap: 10px; text-align: center;
    background: linear-gradient(to bottom, rgba(12, 10, 9, 0) 0%, var(--bg) 28%);
  }
  @media (max-height: 720px) {
    .msheet__in { padding-top: 76px; }
    .mrow { min-height: 64px; gap: 14px; }
    .mrow__th { width: 48px; height: 48px; border-radius: 10px; }
    .msheet__links a { min-height: 48px; font-size: 17px; }
  }

  /* the rows follow the sheet down one after another; on the way out they go first, all at once */
  .msheet .mrow, .msheet__links, .msheet__cta, .msheet__label { opacity: 0; transform: translateY(-12px); transition: opacity .18s ease-in, transform .25s ease-in; }
  .msheet.is-open .mrow, .msheet.is-open .msheet__links, .msheet.is-open .msheet__cta, .msheet.is-open .msheet__label {
    opacity: 1; transform: none; transition: opacity .4s ease-out, transform .55s var(--ease); transition-delay: calc(var(--i, 0) * 50ms + 160ms);
  }
}

@media (prefers-reduced-motion: reduce) {
  .msheet, .msheet .mrow, .msheet__links, .msheet__cta, .msheet__label, .burger span { transition: none !important; }
}

/* ======================================================================
   Collection pages on phones (round 26, 2026-10-21)
   ====================================================================== */
.cchips { display: none; }
/* the collection heroes carry no "Free pieces from every collection." line (Dan, 2026-10-21), at any size */
.band .cta__note { display: none !important; }
/* the page waits for its typefaces before it plays its entrance, so the words never jump from a stand-in font
   (html.fw is set in each page's head and cleared by menu.js once the fonts are in, or after 2 s at most) */
html.fw .enter, html.fw .grid.animate .tile { animation-play-state: paused !important; }
/* the hero sliders: press anywhere and drag (menu.js); the range input underneath keeps the keyboard */
.sctl__row { cursor: ew-resize; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.sctl__row input[type="range"] { pointer-events: none; }
.sctl--fil .sctl__row.is-drag .mark { width: 3px; height: 26px; background: #fff; }
.sctl--sh .sctl__row.is-drag .knob { width: 18px; height: 18px; box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.2), 0 0 26px 8px rgba(255, 255, 255, 0.6); }
.sctl--site .sctl__row.is-drag .fill { background: rgba(243, 238, 231, 0.2); }
/* Filament's phone label, the same kind as the other collections' (the logo shows from 641px up) */
.slabel--fil { display: none; }
/* Shaders' label now carries a count too; on its pale card the count goes dark */
.page-shaders .band--light .slabel .n { color: rgba(20, 17, 15, 0.55); }
.page-shaders .band--light .slabel .n::before { color: rgba(20, 17, 15, 0.35); }
/* both of a piece's sliders show on tablets and phones too (they used to drop to one) */
@media (max-width: 900px) { html[lang] .sctl__row:nth-child(n+2) { display: flex; } }
@media (max-width: 640px) {
  /* the four collections leave the notch: a row of chips between the header and the card, sliding off the edge */
  .notch-wrap { display: none !important; }
  .cchips {
    display: flex; gap: 6px; margin: 0 calc(var(--gutter) * -1) 26px; padding: 0 var(--gutter);
    overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; scroll-padding: 0 var(--gutter); -webkit-overflow-scrolling: touch;
  }
  .cchips::-webkit-scrollbar { display: none; }
  .cchips .np { scroll-snap-align: start; padding-top: 6px; touch-action: manipulation; }
  .cchips .np__pill { box-shadow: inset 0 0 0 1px var(--line); }
  /* every collection's filter pills are the same 44px to tap */
  html[lang] .chip { min-height: 44px; }

  /* the card: no notch to clear, more air round the words, and the picture larger, rising behind the button */
  html[lang] .band, html[lang][data-layout] .band { padding: 32px 22px 196px; row-gap: 0; min-height: 600px; }
  html[lang] .band .slabel { margin-bottom: 16px; }
  html[lang] .band .h1 { min-height: 0; line-height: 1.08; }
  html[lang] .band .lead { min-height: 0; margin-top: 14px; }
  html[lang] .band .cta { margin-top: 28px; position: relative; z-index: 2; }
  html[lang] .band__shade, html[lang] .band--filament .band__shade, html[lang] .band--shaders .band__shade {
    background: linear-gradient(to bottom, rgba(var(--sh), 0.96) 0%, rgba(var(--sh), 0.96) calc(100% - 300px), rgba(var(--sh), 0) calc(100% - 175px));
  }
  html[lang] .mat__form { width: 296px; bottom: -18px; }
  /* the picture still rises behind the button, but its bright parts stay below the small line under it */
  html[lang] .band--particles .band__bg video { height: 360px; -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 56%); mask-image: linear-gradient(to bottom, transparent 0%, #000 56%); }
  html[lang] .shero { height: 360px; }
  html[lang] .page-shaders .band--shaders .band__shade {
    background: linear-gradient(to bottom, rgba(var(--sh), 0.96) 0%, rgba(var(--sh), 0.96) calc(100% - 300px), rgba(var(--sh), 0) calc(100% - 175px));
  }
  /* Filament's curtain fills the whole card already, so it only needs room for its slider */
  html[lang] .band--filament { padding-bottom: 132px; }
  /* Filament: the same small label as the other collections, in place of the logo */
  html[lang] .band--filament .band__logo { display: none; }
  html[lang] .band--filament .slabel--fil { display: inline-flex; }
  html[lang] .band--filament .slabel--fil { font-family: var(--sans); font-size: 13px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--ink); }
  html[lang] .band--filament .slabel--fil::before { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
  html[lang] .band--filament .slabel--fil .n { color: rgba(243, 238, 231, 0.62); }
  html[lang] .band--filament .slabel--fil .n::before { content: "·"; color: rgba(243, 238, 231, 0.4); }
  /* and its moving curtain stays visible: a lighter shade over it, and the curtain itself stronger */
  html[lang] .band--filament .band__shade { background: linear-gradient(to bottom, rgba(13, 13, 13, 0.62) 0%, rgba(13, 13, 13, 0.4) 46%, rgba(13, 13, 13, 0) 74%); }
  html[lang] .veil { --veil-o: .85; }
  /* the two sliders: full width along the foot of the card, one above the other */
  html[lang] .band .sctl { left: 22px; right: 22px; bottom: 20px; top: auto; width: auto; gap: 8px; }
  html[lang] .band .sctl__row { height: 44px; }

  /* Materials: the edition cards keep just the name, with the count underneath */
  .edcard__line { display: none; }
  .edcard { flex: 0 0 224px !important; grid-template-columns: 52px minmax(0, 1fr) !important; gap: 12px !important; padding: 8px 18px 8px 8px !important; border-radius: 16px !important; }
  .edcard__thumb { width: 52px !important; height: 52px !important; border-radius: 10px !important; }
  .edcard__pick { min-height: 52px !important; gap: 1px; }
  .edcard__top { flex-direction: column; align-items: flex-start; gap: 1px; }
  .edcard__name { font-size: calc(17px * var(--head-s)); }
  .edcard--soon .edcard__n { height: auto; padding: 0; box-shadow: none; font-size: 13px; }
  button.edcard__pick::after { border-radius: 16px !important; }
}

/* ======================================================================
   The footer on phones (every page): one column, links spaced like lines of text
   ====================================================================== */
@media (max-width: 640px) {
  .foot__in { padding-top: 40px; }
  .foot__grid { grid-template-columns: minmax(0, 1fr); row-gap: 28px; }
  .foot__col h3 { margin-bottom: 6px; }
  .foot__col a, html[lang] .foot__col a { display: block; min-height: 0; padding: 3px 0; font-size: 15px; line-height: 1.55; }
  html[lang] .foot__base, html[lang] .shelf-c .foot__base { margin-top: 32px; padding: 20px 0 env(safe-area-inset-bottom); }
  .foot__glow { height: 180px; }
}
@media (hover: none) {
  .cchips .np:not([aria-current]):hover .np__pill { color: var(--mute); background: none; }
}

/* ======================================================================
   Round 29 (2026-10-21): the orange glows, on phones, each on an on/off review switch (menu.js)
   html[data-fglow="off"] hides the footer's; html[data-tglow="off"] hides the collection pages' top one.
   ====================================================================== */
html[data-fglow="off"] .foot__glow { display: none; }
@media (max-width: 640px) {
  /* the footer's glow: much larger, rising through most of the footer instead of a small patch at its foot */
  .foot__glow { height: 620px; }
  .foot__glow::before {
    background:
      radial-gradient(ellipse 95% 55% at 50% 100%, rgba(251, 146, 60, 0.26) 0%, rgba(251, 146, 60, 0) 72%),
      radial-gradient(ellipse 150% 100% at 50% 100%, rgba(249, 115, 22, 0.34) 0%, rgba(249, 115, 22, 0.13) 45%, rgba(249, 115, 22, 0) 76%);
  }

  /* the collection pages: the same glow turned upside down, falling from the top of the page behind the header,
     the chips and the hero card, so the dark card has a lit edge to stand against */
  /* a big, soft glow reaching down to about the foot of the hero card, with a fine grain over it like the footer's.
     The body's own ground is made see-through (the html behind it is the same colour), so these two layers
     can sit behind the whole page. */
  body.shelf-c { background: transparent; }
  body.shelf-c::before, body.shelf-c::after {
    content: ""; position: absolute; z-index: -1; left: 0; right: 0; top: 0; height: 900px; pointer-events: none;
  }
  body.shelf-c::before {
    background:
      radial-gradient(ellipse 120% 560px at 50% 0%, rgba(251, 146, 60, 0.13) 0%, rgba(251, 146, 60, 0) 75%),
      radial-gradient(ellipse 190% 840px at 50% 0%, rgba(249, 115, 22, 0.17) 0%, rgba(249, 115, 22, 0.07) 48%, rgba(249, 115, 22, 0) 82%);
    mix-blend-mode: plus-lighter;
  }
  body.shelf-c::after {
    opacity: .3; mix-blend-mode: screen;
    background-image: var(--grain); background-size: 160px 160px;
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.55) 50%, transparent 92%);
    mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.55) 50%, transparent 92%);
  }
  html:not([data-tglow="on"]) body.shelf-c::before, html:not([data-tglow="on"]) body.shelf-c::after { display: none; }
}

/* "Top glow" on the collection pages' hero block (2026-10-29, Dan): a soft warm glow INSIDE the block, starting at its
   top edge and fading down, with a faint bright line along the top. No edge line round the block, no halo outside.
   On or off per collection: the list is in menu.js ("Top glow"); on, it sets html[data-tglow="top"]. Collections
   with it off keep the block's plain edge line. Desktop values tuned by Dan 2026-10-29. */
:root {
  --band-top-rgb: 249, 115, 22;    /* Material orange #F97316 */
  --band-top: 0.14;                /* strength at the top edge */
  --band-top-depth: 240px;         /* how far down it fades */
  --band-top-width: 60%;           /* how far it spreads either side of the middle */
  --band-top-line: 0.35;           /* the bright line along the top edge */
  --band-top-edge: 0;              /* the light edge line round the block */
}
/* on phones: shorter and wider, to suit the narrow block */
@media (max-width: 640px) {
  :root {
    --band-top-depth: 200px;
    --band-top-width: 80%;
  }
}
html[data-tglow="top"] .band { box-shadow: inset 0 0 0 1px rgba(243, 238, 231, var(--band-top-edge)); }
/* the glow: over the artwork, under the words and the notch (the block clips it to its rounded corners) */
html[data-tglow="top"] .band::after {
  content: ""; position: absolute; z-index: -1; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse var(--band-top-width) 1.5px at 50% 0%, rgba(var(--band-top-rgb), var(--band-top-line)) 0%, rgba(var(--band-top-rgb), 0) 100%),
    radial-gradient(ellipse var(--band-top-width) var(--band-top-depth) at 50% 0%,
      rgba(var(--band-top-rgb), var(--band-top)) 0%,
      rgba(var(--band-top-rgb), calc(var(--band-top) * 0.4)) 45%,
      rgba(var(--band-top-rgb), 0) 100%);
  mix-blend-mode: plus-lighter;
}

/* Desktop (2026-10-25): the homepage's Dark Materials "coming soon" cards (visitor and member) get a soft warm halo
   and faint edge, as on phones, so the black card doesn't melt into the page. On a review switch (menu.js):
   html[data-dglow="off"] hides it. Tried on the collection pages' hero cards too and dropped: the glow can't follow
   the notch cut into their top edge (the notch is painted over the card, not cut out of it). */
@media (min-width: 641px) {
  html:not([data-dglow="off"]):not([data-dglow="line"]) :is(.soon-card, .mh-next__card) {
    box-shadow:
      inset 0 0 0 1px rgba(243, 238, 231, 0.09),
      0 0 24px 0 rgba(249, 115, 22, 0.16),
      0 0 56px 2px rgba(249, 115, 22, 0.08);
  }
}
/* "Outline" (2026-10-29, Dan wants to compare): no glow, just a thin grey edge round the card. "Off": nothing.
   Both on phones too (they beat the phone glow below and in home.css). */
html[data-dglow="line"] :is(.soon-card, .mh-next__card) {
  box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.14);
}
html[data-dglow="off"] :is(.soon-card, .mh-next__card) { box-shadow: none; }
/* the member's Dark Materials card on phones: the phone glow the visitor's card already has */
@media (max-width: 640px) {
  html .mh-next__card {
    box-shadow:
      inset 0 0 0 1px rgba(243, 238, 231, 0.07),
      0 0 28px 0 rgba(249, 115, 22, 0.10),
      0 0 70px 6px rgba(249, 115, 22, 0.06);
  }
}

/* the review switches for the glows (made by menu.js; on the home page they sit in a small panel of their own) */
.review--glow { position: fixed; right: 12px; bottom: 16px; z-index: 30; display: grid; justify-items: end; gap: 8px; }html.m-open .review { visibility: hidden; }

/* ======================================================================
   Round 33 (2026-10-21): touch screens (iPhone, iPad)
   ====================================================================== */
@media (hover: none) {
  /* the viewer's panels and preview: Safari on iOS can fail to clip moving or blurred layers to rounded corners,
     leaving a square edge behind the round one. A clip that follows the corners fixes it; the hairline that the
     clip would cut off is drawn as an inset outline instead. */
  dialog.sheet .stage, dialog.sheet .side { clip-path: inset(0 round 20px); outline: 1px solid var(--line); outline-offset: -1px; }
  dialog.sheet .pv__frame { -webkit-mask-image: -webkit-radial-gradient(white, black); }

  /* the dim behind the viewer: no blur (heavy on iOS), and painted as a gradient rather than a flat colour, so
     Safari doesn't take it for page colour and turn its status and address bars solid black while it is open */
  dialog.sheet, dialog.vbox, dialog.ask {
    -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
    background-color: transparent !important;
    background-image: linear-gradient(rgba(5, 4, 3, 0.86), rgba(5, 4, 3, 0.86)) !important;
  }
}

/* No focus rings after a tap or click (html.tapped, set by menu.js); they still show for the keyboard */
html.tapped :focus-visible, html.tapped :focus-visible::after, html.tapped :focus-visible .np__pill { outline: none !important; }

/* The viewer's format switch on phones: full width, the formats share it equally */
@media (max-width: 640px) {
  .mbar--top > .fmtsw { justify-self: stretch; }
  .fmtsw { width: 100% !important; }
  .fmtsw__thumb { width: calc((100% - 8px) / var(--n)) !important; transform: translateX(calc(var(--at) * 100%)) !important; }
  .fmtsw button { flex: 1 1 0 !important; width: auto !important; min-width: 0; padding: 0 6px !important; font-size: 13px; }
}

/* Pictures that load as you scroll fade in when they arrive, instead of popping in (menu.js marks them) */
img.img-wait { opacity: 0; }
img.img-in { animation: img-in .45s ease-out both; }
@keyframes img-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { img.img-wait { opacity: 1; } img.img-in { animation: none; } }

/* Scroll reveals on touch screens: a shorter, lighter rise, so they keep up with a flicked scroll */
@media (hover: none) {
  .rv-on .rv { transform: translateY(10px); transition-duration: .55s, .7s, .3s; transition-delay: calc(var(--i, 0) * 45ms), calc(var(--i, 0) * 45ms), 0s; }
}

/* Videos in tiles: hidden over their still frame until they are really playing, then a short fade (menu.js) */
video.v-wait { opacity: 0; }
video.v-in { animation: img-in .35s ease-out both; }

/* Round 35 · a live piece playing its demo: the bar being moved lights up as a recorded demo's does (v2.js autoTick) */
.bar.is-auto::before, .bar.is-auto:hover::before { background: rgba(243, 238, 231, 0.2); }
.bar.is-auto .bar__name { color: var(--ink); }
dialog.sheet[data-sh] .bar--hue.is-auto::before { opacity: .34; }

/* ---------- "Try me" chip over the hero sliders (Filament, Shaders, Particles) ----------
   A small light pill with a down arrow, bobbing gently just above the sliders so people notice they can drag them.
   It fades in once the hero has settled and fades away for good the first time someone uses a slider (menu.js). */
.tryme {
  position: absolute; left: 50%; bottom: calc(100% + 12px); z-index: 4;
  translate: -50% 0;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px 7px 13px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  font: 500 13px/1 var(--sans); white-space: nowrap;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  pointer-events: none;
  opacity: 0;
  transition: opacity .4s ease-out;
}
.tryme svg { width: 11px; height: 11px; flex: none; }
.tryme.is-in { opacity: 1; animation: tryme-bob 1.8s cubic-bezier(0.45, 0, 0.55, 1) infinite; }
.tryme.is-out { opacity: 0; transition: opacity .2s ease-out; }
@keyframes tryme-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
/* on a pale hero card (some Shaders pieces) the chip goes dark */
.band--light .tryme { background: #14110f; color: var(--ink); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18); }
@media (prefers-reduced-motion: reduce) { .tryme.is-in { animation: none; } }
