/* Vanta Supply · round 6 sketch · the collection page (particles, materials, filament, shaders)
   Sits on top of v2.css. Nothing here changes the nav, menu, tiles, item view or footer.
   Class names still say "shelf"/"band" from round 4; visitors never see them.

   Round 6: inside the stage card the words sit on the left with one action
   straight under them, the same on every page. The artwork has the right.
   html[data-layout] picks one of three arrangements (1 is the default). */

#browse { scroll-margin-top: 24px; padding-top: 32px; }

.slabel { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; line-height: 1.4; color: var(--ink); }
.slabel::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); flex: none; }
.slabel .n { color: rgba(243, 238, 231, 0.62); font-variant-numeric: tabular-nums; }
.slabel .n::before { content: "·"; margin-right: 8px; color: rgba(243, 238, 231, 0.4); }

/* ==========================================================================
   The stage card
   ========================================================================== */
.band-wrap { padding-top: 4px; }
.band {
  --glow: 0.6; --hue: 0deg; --sh: 5, 4, 4;
  position: relative; overflow: hidden; isolation: isolate;
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: 1fr auto; row-gap: 24px;
  min-height: clamp(420px, 31vw, 460px); padding: 48px 44px 36px;
  border-radius: 24px; background: #050404;
  box-shadow: inset 0 0 0 1px var(--line);
  /* a playing video (especially one blended with mix-blend-mode) is drawn on its own layer, which browsers let
     escape overflow + border-radius: the corners went square the moment the loop started. clip-path holds them. */
  clip-path: inset(0 round 24px);
}
.band__bg { position: absolute; z-index: -2; inset: 0; overflow: hidden; pointer-events: none; }
.band__bg img, .band__bg video {
  max-width: none; pointer-events: none;
  -webkit-user-drag: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
/* the left of the card is kept dark for the words; the artwork starts right of centre */
.band__shade {
  position: absolute; z-index: -1; inset: 0; pointer-events: none;
  background: linear-gradient(to right, rgba(var(--sh), 0.92) 0%, rgba(var(--sh), 0.62) 36%, rgba(var(--sh), 0) 58%);
}
.band.is-off *, .band.is-off *::before, .band.is-off *::after { animation-play-state: paused !important; }

/* ---------- the words, and the one action under them ----------
   The label, headline and line each hold a fixed height (one, two and two
   lines), so the button lands on the same spot on all four pages. */
.band__text { grid-row: 1; align-self: start; min-width: 0; }
.band .slabel { flex-wrap: wrap; row-gap: 2px; min-height: 18px; line-height: 18px; }
.band .slabel .lf { display: none; }
.band .h1 {
  margin-top: 14px; max-width: 12.5em;
  font-size: calc(clamp(36px, 3.6vw, 48px) * var(--head-s)); line-height: 1.06;
  min-height: calc(clamp(36px, 3.6vw, 48px) * 2.24);
}
.band .lead { margin-top: 12px; max-width: 46ch; min-height: calc(17px * 1.55 * 2); color: rgba(243, 238, 231, 0.72); }

.cta { margin-top: 26px; }
.cta__state { display: flex; align-items: center; min-height: 44px; }
html[data-as="member"] .as-visitor, html:not([data-as="member"]) .as-member { display: none !important; }
.btn .ic-down { width: 15px; height: 15px; margin-left: -3px; }
.cta__alt {
  display: inline-flex; align-items: center; min-height: 44px; margin-left: 8px; padding: 0 12px;
  font-size: 14.5px; color: rgba(243, 238, 231, 0.7); white-space: nowrap;
  transition: color .2s ease-out;
}
.cta__alt:hover { color: var(--ink); }
.cta__size {
  margin-left: 14px; min-width: 3.6em; font-size: 13.5px; line-height: 1;
  color: rgba(243, 238, 231, 0.62); font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* the size choice: three words, no box */
.dlseg { position: relative; display: flex; align-items: center; margin-left: 10px; padding-left: 7px; }
.dlseg::before { content: ""; position: absolute; left: 0; top: 50%; width: 1px; height: 14px; translate: 0 -50%; background: rgba(243, 238, 231, 0.16); }
.dlseg button {
  min-height: 44px; padding: 0 7px; font-size: 12.5px; font-weight: 500; line-height: 1; white-space: nowrap;
  color: rgba(243, 238, 231, 0.5);
  text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 5px;
  transition: color .2s ease-out, text-decoration-color .2s ease-out;
}
.dlseg button:hover { color: var(--ink); }
.dlseg button[aria-pressed="true"] { color: var(--ink); text-decoration-color: rgba(243, 238, 231, 0.5); }

/* the figures as one quiet line along the bottom edge (layout 3 only) */
.band__foot {
  display: none; grid-row: 2; flex-wrap: wrap; gap: 2px 22px; min-width: 0;
  font-size: 12.5px; line-height: 18px; color: rgba(243, 238, 231, 0.52); font-variant-numeric: tabular-nums;
}
.band__foot b { font-weight: 500; color: rgba(243, 238, 231, 0.82); }

/* ---------- the three arrangements ----------
   1 · top left: words start level with the notch, the rest of the left stays empty
   2 · middle left: words centred on the card's height, figures folded into the label
   3 · top left, with the figures as a line along the bottom edge */
html[data-layout="2"] .band { padding-top: 44px; padding-bottom: 44px; }
html[data-layout="2"] .band__text { grid-row: 1 / -1; align-self: center; }
html[data-layout="2"] .band .slabel .lc { display: none; }
html[data-layout="2"] .band .slabel .lf { display: inline; }
html[data-layout="3"] .band { padding-bottom: 30px; }
html[data-layout="3"] .band__foot { display: flex; }

/* ---------- the notch: the four collections, cut into the top of the card ---------- */
.notch-wrap {
  position: absolute; z-index: 3; top: 0; left: 0; right: 0;
  display: flex; justify-content: center; padding: 0 40px; pointer-events: none;
}
.notch {
  --nr: 14px;
  position: relative; display: flex; min-width: 0; max-width: 100%; pointer-events: auto;
  background: var(--bg); border-radius: 0 0 20px 20px;
  box-shadow: 0 0 0 1px var(--line);
}
/* the two small inverse corners where the notch meets the card's top edge */
.notch::before, .notch::after {
  content: ""; position: absolute; top: 0; width: var(--nr); height: var(--nr); pointer-events: none;
}
.notch::before {
  right: 100%;
  background: radial-gradient(circle at 0 100%,
    rgba(12, 10, 9, 0) calc(var(--nr) - 1.25px), rgba(243, 238, 231, 0.08) calc(var(--nr) - 0.75px),
    rgba(243, 238, 231, 0.08) calc(var(--nr) - 0.25px), var(--bg) calc(var(--nr) + 0.25px));
}
.notch::after {
  left: 100%;
  background: radial-gradient(circle at 100% 100%,
    rgba(12, 10, 9, 0) calc(var(--nr) - 1.25px), rgba(243, 238, 231, 0.08) calc(var(--nr) - 0.75px),
    rgba(243, 238, 231, 0.08) calc(var(--nr) - 0.25px), var(--bg) calc(var(--nr) + 0.25px));
}
.notch__scroll {
  position: relative; display: flex; gap: 2px; min-width: 0; padding: 0 6px;
  border-radius: 0 0 20px 20px;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
.notch__scroll::-webkit-scrollbar { display: none; }
.notch__scroll[data-edge="start"] { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent); }
.notch__scroll[data-edge="end"] { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 36px), transparent); }
.notch__scroll[data-edge="mid"] { -webkit-mask-image: linear-gradient(to right, transparent, #000 36px, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(to right, transparent, #000 36px, #000 calc(100% - 36px), transparent); }

/* each link is 44px tall to tap; the pill you see inside it is 32px */
.np { display: flex; align-items: flex-start; flex: none; height: 44px; padding-top: 5px; -webkit-tap-highlight-color: transparent; }
.np__pill {
  display: inline-flex; align-items: center; gap: 7px; height: 32px; padding: 0 13px 0 6px; border-radius: 999px;
  font-size: 13.5px; font-weight: 500; line-height: 1; color: var(--mute); white-space: nowrap;
  transition: color .2s ease-out, background-color .25s ease-out, box-shadow .25s ease-out;
}
.np img {
  display: block; flex: none; width: 20px; height: 20px; border-radius: 50%; object-fit: cover; background: #000;
  box-shadow: 0 0 0 1px rgba(243, 238, 231, 0.1);
  pointer-events: none; -webkit-user-drag: none; -webkit-user-select: none; user-select: none;
}
.np:hover .np__pill { color: var(--ink); background: var(--fill); }
.np:active .np__pill { background: var(--fill-hover); }
.np[aria-current] .np__pill {
  color: var(--ink); background: var(--fill-hover);
  box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.08);
}
.np:focus-visible { outline: none; }
.np:focus-visible .np__pill { outline: 2px solid var(--ink); outline-offset: -2px; }

/* ---------- Particles: a loop on the right, fading into the card ---------- */
.band--particles .band__bg video {
  position: absolute; top: 0; left: 42%; width: 58%; height: 100%; object-fit: cover; object-position: 50% 46%;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 44%);
  mask-image: linear-gradient(to right, transparent 0%, #000 44%);
}

/* ---------- Materials: one glossy form, warm light under it ---------- */
.band--materials { --sh: 3, 2, 2; background: #030202; }
.band--materials .band__bg {
  background:
    radial-gradient(ellipse 44% 62% at 75% 112%, rgba(240, 115, 58, 0.26) 0%, rgba(240, 115, 58, 0) 70%),
    radial-gradient(ellipse 34% 46% at 64% 30%, rgba(96, 142, 224, 0.09) 0%, rgba(96, 142, 224, 0) 70%),
    #030202;
}
.mat__form {
  /* sized so the tallest shape in the loop (the ice lolly, 84% of the frame) keeps clear air above and below it */
  position: absolute; left: 75%; top: 50%; height: 88%; aspect-ratio: 1 / 1; translate: -50% -50%;
  object-fit: cover; mix-blend-mode: screen;
  /* the box's outer 5% fades out, so a still or a frame whose black isn't quite 0 never shows its square edge
     against the glow (the WebP still's black is 1, which drew a faint square until the loop took over). The forms
     keep clear air inside that margin, so nothing of them is touched. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent), linear-gradient(to bottom, transparent, #000 5%, #000 95%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent), linear-gradient(to bottom, transparent, #000 5%, #000 95%, transparent);
  mask-composite: intersect;
}
/* the hero's still, drawn as its own picture under the loop (materials.html): sized by height like the video */
.mat__still { width: auto; }
/* …and the loop itself stays invisible until its first frame is on screen, then the two swap in one step: before
   that, some browsers draw an empty video box as an unblended dark square */
.mat__still ~ video.mat__form:not(.is-on) { opacity: 0; }

/* ---------- Filament: monochrome line drawings, Space Grotesk and Plex Mono ---------- */
.band--filament {
  --fil-w: 0.333; --fil-a: 0deg; --sh: 17, 17, 17;
  --font-head: "Space Grotesk", "Instrument Sans", "Helvetica Neue", Arial, sans-serif; --head-t: -0.035em; --head-s: 1; --head-w: 500;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  background: #111111;
}
.band--filament .band__bg { background: #111111; }
.fil { position: absolute; aspect-ratio: 1 / 1; translate: -50% -50%; rotate: var(--fil-a); mix-blend-mode: lighten; }
.fil img {
  display: block; width: 100%; height: 100%;
  /* the stills sit on #111, the same as this card; contrast drops that ground to black so only the lines remain */
  filter: brightness(calc(1 + var(--fil-w) * 1.2)) contrast(calc(1.15 + var(--fil-w) * 1.2));
  -webkit-mask-image: radial-gradient(closest-side, #000 84%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 84%, transparent 100%);
}
.fil--a { left: 76%; top: 52%; height: 120%; }
.fil--b { left: 59%; top: 30%; height: 46%; opacity: .88; }
.fil--c { left: 99%; top: 78%; height: 128%; opacity: .5; }
.fil--a img { animation: fil-spin 170s linear infinite; }
.fil--b img { animation: fil-spin 110s linear infinite reverse; }
.fil--c img { animation: fil-drift 19s ease-in-out infinite alternate; }
@keyframes fil-spin { to { rotate: 360deg; } }
@keyframes fil-drift { from { translate: 0 -3%; scale: 1; } to { translate: -2% 3%; scale: 1.05; } }
.band--filament .band__shade {
  background: linear-gradient(to right, rgba(17, 17, 17, 0.94) 0%, rgba(17, 17, 17, 0.7) 32%, rgba(17, 17, 17, 0) 52%);
}
.band--filament .band__text { color: rgba(255, 255, 255, 0.95); }
.band--filament .slabel { font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.2em; text-transform: uppercase; color: rgba(255, 255, 255, 0.92); }
.band--filament .slabel::before { width: 6px; height: 6px; border-radius: 0; background: #fff; }
.band--filament .slabel .n { color: rgba(255, 255, 255, 0.55); }
.band--filament .slabel .n::before { content: "/"; color: rgba(255, 255, 255, 0.3); }
.band--filament .lead { color: rgba(255, 255, 255, 0.68); }
.band--filament .btn--solid { background: #fff; color: #0a0a0b; }
.band--filament .cta__alt { color: rgba(255, 255, 255, 0.7); }
.band--filament .cta__alt:hover { color: #fff; }
.band--filament .cta__size { color: rgba(255, 255, 255, 0.62); }
.band--filament .band__foot { gap: 2px 26px; font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255, 255, 255, 0.5); }
.band--filament .band__foot b { color: rgba(255, 255, 255, 0.85); }

/* ---------- Shaders: a live glowing shape, drawn in CSS ---------- */
.band--shaders { --sh: 14, 13, 17; background: #131216; }
.band--shaders .band__bg { background: radial-gradient(ellipse 56% 90% at 74% 50%, #1b1922 0%, #131216 70%); }
.glow { position: absolute; left: 74%; top: 50%; height: 68%; aspect-ratio: 1 / 1; translate: -50% -50%; }
.glow i {
  position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 200deg, #3b1a8a, #a855f7 18%, #f5ecff 34%, #d8b4fe 46%, #6d28d9 62%, #e9a8fb 80%, #3b1a8a);
  animation: live-spin 26s linear infinite;
}
.glow__halo { filter: blur(calc(26px + var(--glow) * 64px)) hue-rotate(var(--hue)); opacity: calc(0.18 + var(--glow) * 0.78); scale: 1.22; animation-duration: 44s !important; animation-direction: reverse !important; }
.glow__core {
  filter: blur(calc(3px + var(--glow) * 13px)) hue-rotate(var(--hue));
  -webkit-mask-image: radial-gradient(circle at 57% 45%, transparent 0 25%, #000 36%);
  mask-image: radial-gradient(circle at 57% 45%, transparent 0 25%, #000 36%);
}
.glow--b { left: 61%; top: 80%; height: 36%; opacity: .5; animation: glow-drift 17s ease-in-out infinite alternate; }
.glow--b i { background: radial-gradient(circle at 40% 40%, #f5ecff, #c084fc 45%, rgba(124, 58, 237, 0) 72%); filter: blur(42px) hue-rotate(var(--hue)); animation: none; }
@keyframes glow-drift { from { translate: -50% -50%; } to { translate: -32% -62%; } }
.band__grain { position: absolute; inset: 0; background-image: var(--grain); background-size: 160px 160px; mix-blend-mode: overlay; opacity: .5; }
.band--shaders .band__shade {
  background: linear-gradient(to right, rgba(14, 13, 17, 0.86) 0%, rgba(14, 13, 17, 0.5) 34%, rgba(14, 13, 17, 0) 56%);
}

/* ---------- a couple of working controls in the corner (Filament, Shaders) ---------- */
.sctl { position: absolute; z-index: 2; top: 24px; right: 24px; width: 216px; display: grid; gap: 6px; }
.sctl__row { --k: 0.5; position: relative; display: flex; align-items: center; gap: 12px; height: 40px; overflow: hidden; }
.sctl__row label, .sctl__val { position: relative; z-index: 2; pointer-events: none; white-space: nowrap; }
.sctl__row label { flex: 1; }
.sctl__val { flex: none; font-variant-numeric: tabular-nums; }
.sctl__row input[type="range"] {
  position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize;
  -webkit-appearance: none; appearance: none; background: transparent; touch-action: pan-y;
}
.sctl__row input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 40px; }
.sctl__row input[type="range"]::-moz-range-thumb { width: 20px; height: 40px; border: 0; }
.sctl__row i { position: absolute; pointer-events: none; }
.sctl__cap { margin-top: 4px; font-size: 12px; line-height: 1.4; color: rgba(243, 238, 231, 0.55); text-align: right; }

/* Filament's own slider: trough, tick field, fill, bright mark */
.sctl--fil .sctl__row { padding: 0 14px; background: rgba(17, 17, 17, 0.72); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14); transition: box-shadow .15s ease-out; }
.sctl--fil .sctl__row:focus-within { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); }
.sctl--fil .ticks { inset: 0 10px; background-image: repeating-linear-gradient(to right, rgba(255, 255, 255, 0.07) 0 1px, transparent 1px 11px); }
.sctl--fil .fill { inset: 0 auto 0 0; width: calc(10px + (100% - 20px) * var(--k)); background: rgba(255, 255, 255, 0.08); }
.sctl--fil .mark { top: 50%; left: calc(10px + (100% - 20px) * var(--k)); width: 2px; height: 16px; translate: -50% -50%; background: rgba(255, 255, 255, 0.92); transition: height .2s cubic-bezier(0.23, 1, 0.32, 1), width .2s cubic-bezier(0.23, 1, 0.32, 1); }
.sctl--fil .sctl__row:hover .mark { height: 20px; }
.sctl--fil .sctl__row:has(input:active) .mark { width: 3px; height: 26px; background: #fff; }
.sctl--fil label { font-family: var(--mono); font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: rgba(255, 255, 255, 0.92); }
.sctl--fil .sctl__val { font-family: var(--mono); font-size: 10px; letter-spacing: 1px; color: rgba(255, 255, 255, 0.6); }
.sctl--fil .sctl__cap { font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255, 255, 255, 0.45); }

/* Shaders use the site's own bar */
.sctl--site .sctl__row { padding: 0 14px; border-radius: 12px; background: rgba(14, 13, 17, 0.62); box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.08); font-size: 13.5px; }
.sctl--site .fill { inset: 0 auto 0 0; width: calc(var(--k) * 100%); background: rgba(243, 238, 231, 0.12); transition: background-color .2s ease-out; }
.sctl--site .sctl__row:hover .fill, .sctl--site .sctl__row:focus-within .fill { background: rgba(243, 238, 231, 0.18); }
.sctl--site .sctl__row:focus-within { box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.3); }
.sctl--site label { color: rgba(243, 238, 231, 0.72); }
.sctl--site .sctl__val { color: var(--ink); }

/* ==========================================================================
   Filter bar: stays with you down the grid
   ========================================================================== */
.stick-sentinel { display: block; height: 1px; margin-bottom: -1px; pointer-events: none; }
.toolbar--sticky { position: sticky; top: 0; z-index: 20; isolation: isolate; margin-bottom: 4px; padding: 12px 0; }
.toolbar--sticky::before {
  content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: calc(-1 * var(--gutter)); right: calc(-1 * var(--gutter));
  background: rgba(12, 10, 9, 0.96);
  box-shadow: 0 1px 0 transparent; transition: box-shadow .25s ease-out;
}
.toolbar--sticky.is-stuck::before { box-shadow: 0 1px 0 var(--line); }
.shelf-c .countline { margin-bottom: 20px; }

/* shader tiles carry their own hue */
.tile[data-shelf="shaders"] > img { filter: hue-rotate(var(--tile-hue, 0deg)); }

/* ==========================================================================
   Review controls, bottom right: which layout, and who is looking
   ========================================================================== */
.review { position: fixed; right: 16px; bottom: 16px; z-index: 30; display: grid; justify-items: end; gap: 8px; }
.review__row {
  display: flex; align-items: center; gap: 2px; padding: 3px; border-radius: 999px;
  background: rgba(27, 24, 22, 0.94); box-shadow: 0 0 0 1px var(--line);
}
.review__label { padding: 0 8px 0 10px; font-size: 12px; color: var(--faint); white-space: nowrap; }
.review__row button {
  position: relative; height: 30px; min-width: 30px; padding: 0 11px; border-radius: 999px; flex: none;
  font-size: 12px; font-weight: 500; color: var(--mute); white-space: nowrap; text-align: center;
  transition: color .2s ease-out, background-color .2s ease-out;
}
.review__row button::after { content: ""; position: absolute; inset: -7px 0; } /* 44px tall hit area */
.review__row button:hover { color: var(--ink); }
.review__row button[aria-pressed="true"] { background: var(--ink); color: var(--bg); }
.review__row--lay button { padding: 0; width: 32px; }
.shelf-c .fontsw { max-width: calc(100vw - 296px); }

/* ---------- responsive ---------- */
@media (max-width: 1100px) {
  .band { padding-left: 32px; padding-right: 32px; }
  .sctl { top: 60px; } /* under the notch, which is now close */
}

/* iPad upright and narrower: the artwork slides further right and sits behind
   the end of the words, under a longer dark gradient */
@media (max-width: 900px) {
  .band { min-height: 420px; }
  .band .lead { max-width: 40ch; }
  .band__shade, .band--filament .band__shade, .band--shaders .band__shade {
    background: linear-gradient(to right, rgba(var(--sh), 0.95) 0%, rgba(var(--sh), 0.8) 50%, rgba(var(--sh), 0) 94%);
  }
  .band--particles .band__bg video { left: 36%; width: 64%; }
  .mat__form { left: 86%; height: 80%; }
  .fil--a { left: 88%; height: 104%; }
  .fil--b { display: none; }
  .glow { left: 85%; height: 60%; }
  .glow--b { left: 70%; }

  /* one working control, bottom right, clear of the words */
  .sctl { top: auto; bottom: 24px; right: 24px; width: 168px; }
  .sctl__row:nth-child(n+2), .sctl__cap { display: none; }
  .band--filament .band__foot, .band--shaders .band__foot { padding-right: 200px; }
}

/* phones: words and button first, artwork underneath them */
@media (max-width: 640px) {
  .band-wrap { padding-top: 0; }
  .band, html[data-layout="2"] .band, html[data-layout="3"] .band {
    min-height: 0; padding: 68px 20px 252px; border-radius: 20px; clip-path: inset(0 round 20px); row-gap: 14px; grid-template-rows: auto auto;
  }
  .band__text, html[data-layout="2"] .band__text { grid-row: 1; align-self: start; }
  .band__shade, .band--filament .band__shade, .band--shaders .band__shade {
    background: linear-gradient(to bottom, rgba(var(--sh), 0.96) 0%, rgba(var(--sh), 0.96) calc(100% - 262px), rgba(var(--sh), 0) calc(100% - 130px));
  }
  .band .h1 { max-width: none; font-size: calc(34px * var(--head-s)); min-height: 76px; }
  .band .lead { max-width: none; font-size: 16px; min-height: calc(16px * 1.55 * 2); }
  .cta { margin-top: 22px; }
  .dlseg { display: none; }
  .band__foot, .band--filament .band__foot { gap: 2px 16px; }
  .band--filament .band__foot, .band--shaders .band__foot { padding-right: 0; }

  .notch-wrap { padding: 0 30px; }
  .notch { --nr: 12px; border-radius: 0 0 18px 18px; }
  .notch__scroll { border-radius: 0 0 18px 18px; padding: 0 5px; }
  .np__pill { padding: 0 12px 0 6px; font-size: 13px; }

  .band--particles .band__bg video {
    top: auto; bottom: 0; left: 0; width: 100%; height: 264px;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 52%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 52%);
  }
  .band--materials .band__bg {
    background:
      radial-gradient(ellipse 80% 34% at 50% 108%, rgba(240, 115, 58, 0.26) 0%, rgba(240, 115, 58, 0) 70%),
      #030202;
  }
  .mat__form { left: 50%; top: auto; bottom: 10px; height: auto; width: 214px; translate: -50% 0; }
  .fil--a { left: 50%; top: auto; bottom: -30px; height: auto; width: 270px; translate: -50% 0; }
  .fil--c { display: none; }
  .band--shaders .band__bg { background: radial-gradient(ellipse 90% 40% at 50% 100%, #1b1922 0%, #131216 70%); }
  .glow { left: 50%; top: auto; bottom: -72px; height: auto; width: 190px; }
  .glow--b { left: 26%; bottom: -50px; width: 120px; }

  .sctl { bottom: 14px; right: 14px; width: 142px; }
  .sctl__row { height: 44px; }
  .sctl--fil .sctl__row, .sctl--site .sctl__row { padding: 0 12px; }

  #browse { padding-top: 24px; }
  /* one line of chips that slides, so the sticky bar stays one row tall */
  .toolbar--sticky { padding: 10px 0; margin-bottom: 8px; flex-wrap: nowrap; }
  .toolbar--sticky .chips {
    flex: 1 1 auto; min-width: 0; flex-wrap: nowrap;
    margin: -4px calc(var(--gutter) * -1); padding: 4px var(--gutter);
    overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
    scroll-snap-type: x proximity; scroll-padding: 0 var(--gutter); -webkit-overflow-scrolling: touch;
  }
  .toolbar--sticky .chips::-webkit-scrollbar { display: none; }
  .toolbar--sticky .chip { flex: none; scroll-snap-align: start; white-space: nowrap; }

  .review { right: 12px; bottom: 12px; gap: 8px; }
  .review__row--as .review__label { display: none; }
  .shelf-c .fontsw { max-width: calc(100vw - 196px); }
  .shelf-c .foot__base { padding-bottom: 116px; }
}


/* ===== Round 7 =====
   One arrangement only: the words sit vertically centred on the left, no
   figures in the card, artwork runs the full width behind them, and there is
   a much larger gap before the filters. */
.review__row--lay { display: none !important; }
.band__foot { display: none !important; }
.band .slabel .lf { display: none !important; }
.band .slabel .lc { display: inline !important; }
.band-wrap { margin-bottom: 104px; }

@media (min-width: 901px) {
  .band, html[data-layout] .band { padding-top: 44px; padding-bottom: 44px; }
  .band__text, html[data-layout] .band__text { grid-row: 1 / -1; align-self: center; }

  /* Particles: the loop fills the card again and passes behind the words */
  .band--particles .band__bg video {
    left: 0; width: 100%; object-position: 50% 46%;
    -webkit-mask-image: none; mask-image: none;
  }
  .band--particles .band__shade {
    background: linear-gradient(to right,
      rgba(5, 4, 4, 0.9) 0%, rgba(5, 4, 4, 0.72) 24%, rgba(5, 4, 4, 0.3) 46%, rgba(5, 4, 4, 0) 66%);
  }
}
@media (max-width: 900px) {
  .band-wrap { margin-bottom: 56px; }
}


/* ===== Round 8 =====
   Part 1 · one action in the card, with a quiet line under it for visitors.
   The line's height is held in every state, so the words never shift when
   you change who is looking. */
.band .cta__note { margin-top: 10px; min-height: 20px; color: rgba(243, 238, 231, 0.6); }
.band--filament .cta__note { color: rgba(255, 255, 255, 0.6); }
.shelf-c .fontsw { max-width: calc(100vw - 348px); }

/* Part 2 · Materials is split into editions. Each tile is one material. */
.tile[data-kind="material"] > img { filter: hue-rotate(var(--tile-hue, 0deg)); }

/* only the chosen edition shows (A and C). The attribute is set in the head,
   so the other one never flashes; without scripting both simply stack. */
html[data-ed="glass"] [data-editions="pick"] [data-ed-section]:not([data-ed-section="glass"]),
html[data-ed="materials-1"] [data-editions="pick"] [data-ed-section]:not([data-ed-section="materials-1"]) { display: none; }
html:not([data-ed]) [data-editions="pick"] .ed + .ed { margin-top: 64px; }
.edstage { transition: opacity .22s ease-out; }
.edstage.is-out { opacity: 0; }

/* Dark is on the way: there in the row, but plainly not a choice yet */
.chip--soon, .chip--soon:hover { background: transparent; box-shadow: inset 0 0 0 1px var(--line); color: var(--faint); }
button.chip--soon { cursor: default; }
a.chip--soon:hover { color: var(--mute); }

/* ---------- A · the edition's promo, as the first and only wide tile ---------- */
.tile--promo::before {
  content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.2);
}
.tile--promo::after {
  background: linear-gradient(to top, rgba(12, 10, 9, 0.72) 0%, rgba(12, 10, 9, 0.16) 44%, rgba(12, 10, 9, 0.16) 100%);
  opacity: 1;
}
.promo__tag {
  position: absolute; z-index: 2; left: 14px; top: 14px;
  display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: 999px;
  background: var(--ink); color: var(--bg); font-size: 12px; font-weight: 600; line-height: 1;
}
.promo__play {
  position: absolute; z-index: 2; left: 50%; top: 50%; width: 60px; height: 60px; translate: -50% -50%;
  display: grid; place-items: center; border-radius: 50%; color: var(--ink);
  background: rgba(12, 10, 9, 0.5); box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.26);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  transition: transform .3s var(--ease), background-color .25s ease-out;
}
.promo__play svg { width: 20px; height: 20px; margin-left: 2px; }
.tile--promo:hover .promo__play { transform: scale(1.06); background: rgba(12, 10, 9, 0.66); }
.tile--promo:active .promo__play { transform: scale(0.97); }
.tile--promo .tile__meta { color: var(--ink); }

/* ---------- B · editions as sections: a slim header row, then the grid ---------- */
.edstage--rows .ed + .ed { margin-top: 80px; }
.ed[id] { scroll-margin-top: 72px; }
.ed__head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 24px;
  min-height: 44px; padding: 28px 0 20px; border-top: 1px solid var(--line);
}
.edstage--rows .ed:first-child .ed__head { border-top: 0; padding-top: 10px; }
.ed__title { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.ed__name { font-family: var(--font-head); font-weight: var(--head-w); font-size: calc(21px * var(--head-s)); line-height: 1.25; letter-spacing: calc(var(--head-t) * 0.55); white-space: nowrap; }
.ed__n { font-size: 14px; color: var(--faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ed__line { min-width: 0; font-size: 14.5px; line-height: 1.5; color: var(--mute); text-wrap: pretty; }
.ed__promo { min-height: 40px; padding: 0 16px 0 13px; }
.ed__promo svg { width: 12px; height: 12px; }
.ed--soon .ed__head { padding-bottom: 0; }
.ed--soon .ed__name { color: var(--mute); }
.ed--soon .ed__n { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 12px; font-weight: 500; box-shadow: inset 0 0 0 1px var(--line); align-self: center; }

/* ---------- C · three compact cards are the switch ---------- */
.edcards { position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); margin-bottom: 28px; }
.edcard {
  position: relative; display: grid; grid-template-columns: 88px minmax(0, 1fr); align-items: center; gap: 16px;
  padding: 12px 20px 12px 12px; border-radius: 20px; background: var(--raise);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: background-color .25s ease-out, box-shadow .25s ease-out;
}
.edcard:not(.edcard--soon):hover { background: var(--raise-2); }
.edcard[data-on] { background: var(--raise-2); box-shadow: inset 0 0 0 1.5px rgba(243, 238, 231, 0.86); }
.edcard__thumb {
  position: relative; z-index: 1; display: block; width: 88px; height: 88px; overflow: hidden;
  border-radius: 12px; background: #000;
}
.edcard__thumb img, .edcard__thumb video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none;
  -webkit-user-drag: none; -webkit-user-select: none; user-select: none;
}
.edcard__play {
  position: absolute; right: 6px; bottom: 6px; width: 28px; height: 28px; display: grid; place-items: center;
  border-radius: 50%; color: var(--ink); background: rgba(12, 10, 9, 0.62);
  box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.24);
  transition: background-color .25s ease-out, transform .25s var(--ease);
}
.edcard__play svg { width: 11px; height: 11px; margin-left: 1px; }
button.edcard__thumb:hover .edcard__play { background: rgba(12, 10, 9, 0.85); transform: scale(1.08); }
.edcard__pick { display: grid; align-content: center; gap: 5px; min-width: 0; min-height: 88px; text-align: left; }
button.edcard__pick::after { content: ""; position: absolute; inset: 0; border-radius: 20px; } /* the whole card picks the edition */
button.edcard__pick:focus-visible { outline: none; }
button.edcard__pick:focus-visible::after { outline: 2px solid var(--ink); outline-offset: 2px; }
.edcard__top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.edcard__name { font-family: var(--font-head); font-weight: var(--head-w); font-size: calc(19px * var(--head-s)); line-height: 1.25; letter-spacing: calc(var(--head-t) * 0.55); color: var(--ink); }
.edcard__n { font-size: 13px; color: var(--faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
.edcard__line { font-size: 14px; line-height: 1.45; color: var(--mute); text-wrap: pretty; }
.edcard--soon .edcard__thumb, .edcard--soon .edcard__name, .edcard--soon .edcard__line { opacity: .5; }
.edcard--soon .edcard__n { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 12px; font-weight: 500; color: var(--mute); box-shadow: inset 0 0 0 1px var(--line); align-self: center; }

@media (max-width: 1023px) {
  [data-editions] .chip { min-height: 44px; }
  .ed__promo { min-height: 44px; }
}

/* iPad upright and phones: the cards keep a readable width and slide sideways in their own row */
@media (max-width: 900px) {
  .edcards {
    display: flex; margin: 0 calc(var(--gutter) * -1) 20px; padding: 4px 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;
  }
  .edcards::-webkit-scrollbar { display: none; }
  .edcard { flex: 0 0 min(304px, 80vw); scroll-snap-align: start; }
}

@media (max-width: 640px) {
  .shelf-c .fontsw { max-width: calc(100vw - 24px); }
  .shelf-c .foot__base { padding-bottom: 156px; }
  .review { right: 12px; bottom: 56px; }

  .promo__tag { left: 10px; top: 10px; }
  .promo__play { width: 52px; height: 52px; }

  .edstage--rows .ed + .ed { margin-top: 56px; }
  .ed__head { grid-template-columns: minmax(0, 1fr) auto; row-gap: 4px; column-gap: 12px; padding: 22px 0 16px; }
  .ed__title { grid-area: 1 / 1; }
  .ed__promo { grid-area: 1 / 2; }
  .ed__line { grid-area: 2 / 1 / 3 / -1; }

  .edcard { grid-template-columns: 76px minmax(0, 1fr); gap: 14px; padding: 10px 16px 10px 10px; border-radius: 18px; }
  .edcard__thumb { width: 76px; height: 76px; border-radius: 10px; }
  .edcard__pick { min-height: 76px; }
  button.edcard__pick::after { border-radius: 18px; }
}


/* ===== Round 9 · Materials: one page =====
   Edition cards are the switch; the edition's promo video is the first thing
   in its grid; the grid is six across (html[data-grid="2"], fixed since round 11).
   Everything here is scoped to body.page-m9, so the round 8 pages are as they were. */
.tile[hidden] { display: none; }
/* the card thumbnails are plain pictures now (no play mark): a press on one picks the edition like the rest of the card */
.page-m9 .edcard__thumb { pointer-events: none; }

/* ---------- the promo video: a framed player, not a material ---------- */
.page-m9 .grid--browse { --pc: 2; --pr: 1; } /* columns and rows the promo takes */
.page-m9 .tile--promo {
  grid-column: span var(--pc); grid-row: span var(--pr);
  background: var(--raise-2);
}
/* the video sits inside a thin mat, so the tile has an edge no material tile has */
.page-m9 .tile--promo > video {
  inset: 5px; width: calc(100% - 10px); height: calc(100% - 10px);
  border-radius: calc(var(--r) - 3px); background: #000;
}
.page-m9 .tile--promo:hover > video { transform: none; }
.page-m9 .tile--promo::before { box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.22); }
.page-m9 .tile--promo::after {
  inset: 5px; border-radius: calc(var(--r) - 3px); opacity: 1;
  background: linear-gradient(to top, rgba(12, 10, 9, 0.55) 0%, rgba(12, 10, 9, 0) 46%);
}
.pt {
  position: absolute; z-index: 2; left: 17px; bottom: 17px; max-width: calc(100% - 34px);
  display: inline-flex; align-items: center; gap: 12px; padding: 6px 20px 6px 6px; border-radius: 999px;
  background: rgba(12, 10, 9, 0.78); box-shadow: inset 0 0 0 1px rgba(243, 238, 231, 0.14);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  text-align: left;
}
.pt__play {
  flex: none; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: var(--ink); color: var(--bg);
  transition: transform .3s var(--ease), background-color .25s ease-out;
}
.pt__play svg { width: 16px; height: 16px; margin-left: 2px; }
.tile--promo:hover .pt__play { background: #fff; transform: scale(1.05); }
.tile--promo:active .pt__play { transform: scale(0.96); }
.pt__text { display: grid; gap: 3px; min-width: 0; }
.pt__label { font-size: 15px; font-weight: 600; line-height: 1.2; color: var(--ink); white-space: nowrap; }
.pt__ed { font-size: 12.5px; line-height: 1.2; color: var(--mute); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pt__time {
  position: absolute; z-index: 2; right: 17px; bottom: 33px;
  display: inline-flex; align-items: center; height: 24px; padding: 0 8px; border-radius: 6px;
  background: rgba(12, 10, 9, 0.78); color: var(--ink);
  font-size: 12px; font-weight: 500; line-height: 1; font-variant-numeric: tabular-nums;
}

/* ---------- the grid: six across at 1440 ---------- */
html[data-grid="2"] .page-m9 .grid--browse { --cols: 6; --pc: 3; --pr: 2; --gap: 8px; --r: 10px; }
html[data-grid="2"] .page-m9 .tile:not(.tile--promo) .tile__meta { left: 10px; right: 10px; bottom: 8px; gap: 8px; font-size: 12px; }
html[data-grid="2"] .page-m9 .tile .kind { display: none; }

@media (max-width: 1199px) {
  html[data-grid="2"] .page-m9 .grid--browse { --cols: 4; --pc: 3; }
}
@media (max-width: 900px) {
  html[data-grid="2"] .page-m9 .grid--browse { --cols: 3; --pc: 3; }
}
@media (max-width: 640px) {
  html[data-grid="2"] .page-m9 .grid--browse { --gap: 6px; --r: 8px; }
  .pt { left: 13px; bottom: 13px; gap: 10px; padding: 5px 16px 5px 5px; }
  .pt__play { width: 40px; height: 40px; }
  .pt__play svg { width: 14px; height: 14px; }
  .pt__label { font-size: 14px; }
  .pt__time { right: 13px; bottom: 26px; }
}

/* ---------- review controls: Viewing as ---------- */
/* while a piece is open the controls ride along inside the item view, in a strip under the panels */
dialog.sheet.has-review { padding-bottom: 66px; }
dialog.sheet .review { right: 28px; bottom: 15px; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
@media (max-width: 1100px) {
  dialog.sheet .review { right: 20px; }
}
@media (max-width: 900px) {
  dialog.sheet.has-review { padding-bottom: 116px; }
  dialog.sheet .review { right: 12px; bottom: 12px; max-width: calc(100vw - 24px); }
}
@media (max-width: 640px) {
  /* phones: the two rows wrap, right aligned */
  .page-m9 .review { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; max-width: calc(100vw - 24px); }
  .page-m9 .review__label { padding: 0 6px 0 9px; }
  dialog.sheet .review { right: 8px; bottom: 8px; gap: 6px; }
}

/* "Viewing as" rides along in the item view, on one line */
@media (max-width: 900px) {
  dialog.sheet.has-review { padding-bottom: 66px; }
}


/* ===== Round 13 · Materials: the grid, mixed up =====
   Still six across. A few tiles are two cells wide (a 2:1 tile, the picture
   centred and cropped top and bottom), and a few play their loop instead of
   showing a still. v2.js decides which: doubles by place in the grid, so
   every row adds up to the full width and nothing is left empty; loops by
   number. */
.page-m9 .tile--double { grid-column: span 2; }
/* a loop tile: the loop plays over its still, and carries the same tint */
.tile[data-kind="material"] > video { filter: hue-rotate(var(--tile-hue, 0deg)); }


/* ===== Round 14 · Filament: no kind chips =====
   Every piece exports as code, SVG and image, so there is nothing to filter
   by kind. One small "Free" toggle sits at the left of the count line, and
   the tiles drop their "Code" label for the same reason. */
.countrow { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.countrow .chips { flex: none; }
.countrow .countline, .shelf-c .countrow .countline { margin-bottom: 0; min-width: 0; }
.chip--mini { position: relative; min-height: 32px; padding: 0 12px; gap: 6px; font-size: 13.5px; }
.chip--mini::after { content: ""; position: absolute; inset: -6px 0; } /* 44px tall hit area */
.page-filament .tile .kind { display: none; }
@media (max-width: 640px) {
  .countrow { align-items: flex-start; gap: 12px; }
  .chip--mini { min-height: 36px; padding: 0 12px; }
  .chip--mini::after { inset: -4px 0; }
}


/* ==================================================================
   Round 18 · Filament page: the curtain hero, the frame, the collections.
   ================================================================== */
/* the notch, with more air between the collections (every page) */
.notch__scroll { gap: 12px; padding: 0 14px; }
@media (max-width: 640px) { .notch__scroll { gap: 6px; padding: 0 8px; } }

/* ---- hero: Veil hanging from the top edge, on a grained ground ---- */
.band--filament .band__bg { background: radial-gradient(ellipse 80% 120% at 70% 0%, #1a1a1a 0%, #111 55%, #0d0d0d 100%); }
.veil { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* the curtain is drawn by a script that can arrive after the card: it stays clear until its first frame, then eases in */
.js .veil { opacity: 0; transition: opacity 1.2s ease-out; }
.js .veil.is-live { opacity: var(--veil-o, 1); }
.band__noise {
  position: absolute; inset: 0; opacity: .5; mix-blend-mode: overlay; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 220px 220px;
}
/* the text keeps a quiet ground of its own, lower left; the curtain shows everywhere else */
.band--filament .band__shade {
  position: absolute; z-index: -1; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 60% 85% at 12% 78%, rgba(13, 13, 13, 0.86) 0%, rgba(13, 13, 13, 0.5) 55%, transparent 100%);
}
/* the wordmark, where the square and "Filament / 128 pieces" used to be: small */
.band__logo { height: 30px; margin-bottom: 6px; line-height: 0; }
.band__logo img { display: block; height: 30px; width: auto; }
@media (max-width: 640px) { .band__logo, .band__logo img { height: 24px; } }
/* the two sliders: bottom right, and nothing under them */
.band--filament .sctl { top: auto; bottom: 24px; right: 24px; }
@media (max-width: 640px) { .band--filament .sctl { bottom: 14px; right: 14px; } }

/* ---- the frame: a hairline rectangle with a cross on each corner, inside
   the hero only, a little in from its edges ---- */
.frame {
  position: absolute; z-index: 0; inset: 18px; pointer-events: none;
  border: 1px solid rgba(255, 255, 255, 0.13);
}
.frame i {
  position: absolute; width: 13px; height: 13px;
  background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)) 50% 0 / 1px 100% no-repeat,
              linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)) 0 50% / 100% 1px no-repeat;
}
.frame i:nth-child(1) { left: -7px; top: -7px; }
.frame i:nth-child(2) { right: -7px; top: -7px; }
.frame i:nth-child(3) { left: -7px; bottom: -7px; }
.frame i:nth-child(4) { right: -7px; bottom: -7px; }
/* the sliders sit inside the frame, with room */
.band--filament .sctl { bottom: 36px; right: 36px; }
@media (max-width: 640px) {
  .frame { inset: 10px; }
  /* Dan, 2026-11-06 mobile review: much smaller crosses on a phone (13px on desktop) */
  .frame i { width: 7px; height: 7px; }
  .frame i:nth-child(1) { left: -4px; top: -4px; }
  .frame i:nth-child(2) { right: -4px; top: -4px; }
  .frame i:nth-child(3) { left: -4px; bottom: -4px; }
  .frame i:nth-child(4) { right: -4px; bottom: -4px; }
  .band--filament .sctl { bottom: 22px; right: 22px; }
}

/* ---- the collections, as one row of small chips ---- */
.page-filament .countrow { display: block; margin-bottom: 24px; }
.chips--cols { gap: 6px; }
@media (max-width: 760px) {
  /* one line that slides, rather than four lines of chips */
  .chips--cols { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 calc(var(--gutter) * -1); padding: 6px var(--gutter); }
  .chips--cols::-webkit-scrollbar { display: none; }
  .chips--cols .chip { flex: none; }
}
@media (max-width: 640px) {
  /* on a phone the curtain hangs straight over the words: quieter, with a ground behind the text */
  .veil { opacity: .5; --veil-o: .5; }
  .band--filament .band__shade { background: linear-gradient(to bottom, rgba(13, 13, 13, 0.5) 0%, rgba(13, 13, 13, 0.35) 60%, transparent 100%); }
}


/* ==================================================================
   Round 19 · Shaders page: the real hero, the grid of 37.
   Everything here is under .page-shaders, so no other page moves.
   ================================================================== */
/* ---- the grid: as Filament's (no "Code" label, one small row of chips) ---- */
.page-shaders .tile .kind { display: none; }
.page-shaders .countrow { display: block; margin-bottom: 24px; }
/* Doubles: three tiles are double width so 37 ends on a full row four across
   (and two across). Where the grid is three across, two doubles do that, so
   the third goes back to single. */
@media (min-width: 641px) and (max-width: 1023px) {
  .page-shaders .tile--wide-x { grid-column: auto; }
}

/* ---- the hero: the preset itself, drawn live on the right of the card ----
   The card takes the preset's own ground (--sh-bg, and --sh as its r, g, b,
   both set by shaders-page.js), so the drawing has no edge; it fades out
   toward the words on the left. */
.page-shaders .band--shaders {
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace; /* the two sliders' own face */
  background: var(--sh-bg, #131216);
}
.page-shaders .band--shaders .band__bg { background: var(--sh-bg, #131216); }
.shero {
  position: absolute; top: 0; right: 0; bottom: 0; width: 64%;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 34%);
  mask-image: linear-gradient(to right, transparent 0%, #000 34%);
  opacity: 0; transition: opacity .6s ease-out;
}
.shero.is-on, .shero.is-still { opacity: 1; }
.shero canvas, .shero img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.shero img { object-fit: cover; }
.page-shaders .band--shaders .band__shade {
  background: linear-gradient(to right, rgba(var(--sh), 0.9) 0%, rgba(var(--sh), 0.55) 34%, rgba(var(--sh), 0) 56%);
}
/* the two sliders: bottom right, and nothing under them */
.page-shaders .band--shaders .sctl { top: auto; bottom: 24px; right: 24px; }

/* a pale preset in the hero: the words go dark, on a wash of its own ground */
.page-shaders .band--light .band__text, .page-shaders .band--light .slabel { color: #14110f; }
.page-shaders .band--light .lead { color: rgba(20, 17, 15, 0.74); }
.page-shaders .band--light .cta__note, .page-shaders .band--light .cta__size { color: rgba(20, 17, 15, 0.66); }
.page-shaders .band--light .btn--solid { background: #14110f; color: #f3eee7; }
.page-shaders .band--light .btn--solid:hover { background: #000; }
.page-shaders .band--light .dlseg::before { background: rgba(20, 17, 15, 0.2); }
.page-shaders .band--light .dlseg button { color: rgba(20, 17, 15, 0.58); }
.page-shaders .band--light .dlseg button:hover,
.page-shaders .band--light .dlseg button[aria-pressed="true"] { color: #14110f; text-decoration-color: rgba(20, 17, 15, 0.5); }

@media (max-width: 900px) {
  /* the drawing slides right and sits behind the end of the words, under the longer shade */
  .shero { width: 80%; right: -22%; }
  .page-shaders .band--shaders .band__shade {
    background: linear-gradient(to right, rgba(var(--sh), 0.95) 0%, rgba(var(--sh), 0.8) 50%, rgba(var(--sh), 0) 94%);
  }
}
@media (max-width: 640px) {
  /* words first, the drawing underneath them */
  .shero {
    top: auto; left: 0; right: 0; bottom: 0; width: 100%; height: 264px;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 42%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 42%);
  }
  .page-shaders .band--shaders .band__bg { background: var(--sh-bg, #131216); }
  .page-shaders .band--shaders .band__shade {
    background: linear-gradient(to bottom, rgba(var(--sh), 0.96) 0%, rgba(var(--sh), 0.96) calc(100% - 262px), rgba(var(--sh), 0) calc(100% - 130px));
  }
  .page-shaders .band--shaders .sctl { bottom: 14px; right: 14px; }
}
@media (prefers-reduced-motion: reduce) { .shero { transition: none; } }

/* ==================================================================
   Round 19b · the Shaders hero, wide: the preset fills the whole card and
   its light runs out to both sides, behind the words too. The two sliders
   take the shapes' own manner: soft, round, frosted.
   ================================================================== */
@media (min-width: 641px) {
  .shero { left: 0; width: auto; -webkit-mask-image: none; mask-image: none; }
  .page-shaders .band--shaders .band__shade {
    background: linear-gradient(to right, rgba(var(--sh), 0.5) 0%, rgba(var(--sh), 0.22) 38%, rgba(var(--sh), 0) 60%);
  }
}
@media (min-width: 641px) and (max-width: 900px) { .shero { right: 0; width: auto; } }
.page-shaders .band--shaders .sctl { width: 232px; gap: 8px; }
.sctl--sh .sctl__row {
  padding: 0 16px; border-radius: 999px; font-size: 13px; overflow: hidden;
  background: rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(22px) saturate(1.5); backdrop-filter: blur(22px) saturate(1.5);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 10px 30px -14px rgba(0, 0, 0, 0.45);
  transition: background-color .2s ease-out, box-shadow .2s ease-out;
}
.sctl--sh .sctl__row:hover, .sctl--sh .sctl__row:focus-within { background: rgba(255, 255, 255, 0.17); }
.sctl--sh .sctl__row:focus-within { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.42), 0 10px 30px -14px rgba(0, 0, 0, 0.45); }
/* the fill is light, not a block: it swells toward the knob */
.sctl--sh .fill {
  inset: 0 auto 0 0; width: calc(20px + (100% - 40px) * var(--k));
  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 100%);
}
.sctl--sh .knob {
  top: 50%; left: calc(20px + (100% - 40px) * var(--k)); width: 14px; height: 14px; border-radius: 50%; translate: -50% -50%;
  background: #fff; box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.16), 0 0 18px 4px rgba(255, 255, 255, 0.5);
  transition: width .2s cubic-bezier(0.23, 1, 0.32, 1), height .2s cubic-bezier(0.23, 1, 0.32, 1), box-shadow .2s ease-out;
}
.sctl--sh .sctl__row:hover .knob { width: 16px; height: 16px; }
.sctl--sh .sctl__row:has(input:active) .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--sh label { font-weight: 500; color: #fff; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.28); }
.sctl--sh .sctl__val { color: rgba(255, 255, 255, 0.86); text-shadow: 0 1px 6px rgba(0, 0, 0, 0.28); }
@media (prefers-reduced-motion: reduce) { .sctl--sh .knob { transition: none; } }
/* the same sliders on a pale ground: milk glass, dark lettering, a knob with a soft shadow instead of a glow */
.band--light .sctl--sh .sctl__row {
  background: rgba(255, 255, 255, 0.5);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.7), 0 10px 30px -14px rgba(60, 40, 90, 0.35);
}
.band--light .sctl--sh .sctl__row:hover, .band--light .sctl--sh .sctl__row:focus-within { background: rgba(255, 255, 255, 0.66); }
.band--light .sctl--sh .sctl__row:focus-within { box-shadow: inset 0 0 0 1px rgba(20, 17, 15, 0.35), 0 10px 30px -14px rgba(60, 40, 90, 0.35); }
.band--light .sctl--sh .fill { background: linear-gradient(to right, rgba(20, 17, 15, 0) 0%, rgba(20, 17, 15, 0.1) 100%); }
.band--light .sctl--sh .knob { box-shadow: 0 0 0 1px rgba(20, 17, 15, 0.1), 0 2px 8px rgba(20, 17, 15, 0.28); }
.band--light .sctl--sh .sctl__row:has(input:active) .knob { box-shadow: 0 0 0 1px rgba(20, 17, 15, 0.14), 0 4px 14px rgba(20, 17, 15, 0.34); }
.band--light .sctl--sh label { color: #14110f; text-shadow: none; }
.band--light .sctl--sh .sctl__val { color: rgba(20, 17, 15, 0.72); text-shadow: none; }
/* The Shaders card slides up like the other three. Mid-slide its top edge sits between pixels, and on a pale
   ground a sliver of the card showed between that edge and the notch. The notch now reaches a few pixels past
   the card's top edge (the card clips it), so there is no seam for the ground to show through. */
.page-shaders .notch { box-shadow: 0 0 0 1px var(--line), 0 -4px 0 var(--bg); }
.page-shaders .notch::before, .page-shaders .notch::after { box-shadow: 0 -4px 0 var(--bg); }
/* The card comes in on the same beat as the other three and is never empty: the hero's own picture is in it from
   the first paint (shoot-shaders.mjs hero), fitted by height so it lines up with the live shader, which fades in
   over it once it has drawn. */
.page-shaders .shero { opacity: 1; transition: none; }
.shero .shero__poster { object-fit: cover; object-position: center; }
.shero canvas { opacity: 0; transition: opacity .35s ease-out; }
.shero.is-on canvas { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .shero canvas { transition: none; } }
/* Belt and braces for the same seam: nothing pale is painted under the notch at all. The card's own ground is the
   page's dark, the pale ground lives on the layer inside it, and that layer has a shallow bite taken out exactly
   where the notch sits (shaders-page.js measures the notch and sets --nx0 and --nx1). */
.page-shaders .band--shaders { background: var(--bg); }
.page-shaders .band--shaders .band__bg, .page-shaders .band--shaders .band__shade {
  /* straight down under the notch itself; a shallow slope under each of its two small corners, inside their curve */
  clip-path: polygon(0 0, calc(var(--nx0, 50%) - var(--nc, 0px)) 0, var(--nx0, 50%) var(--nd, 0px), var(--nx0, 50%) 8px,
    var(--nx1, 50%) 8px, var(--nx1, 50%) var(--nd, 0px), calc(var(--nx1, 50%) + var(--nc, 0px)) 0, 100% 0, 100% 100%, 0 100%);
}

/* Page speed (2026-11-06): a collection's grid is drawn by script after the page first shows. Until its first tile
   is in, it holds a screen's height, so the footer isn't on screen at first and then pushed away (a layout shift). */
.grid--browse[data-grid]:not(:has(> *)) { min-height: 100vh; }

/* Dan, 2026-11-06 mobile review: on phones the hero's Join / Get access button runs the full width of the card */
@media (max-width: 640px) { .band__text .cta__state .btn { width: 100%; } }

/* Collection heroes: the Join / Get access button answers the pointer (Dan, 2026-11-06). A soft white glow
   gathers behind it, it lifts a pixel, and its label rolls up as a fresh copy rolls in from below. */
.band__text .cta .btn--solid {
  transition: background-color .25s ease-out, color .25s ease-out, transform .35s var(--ease), box-shadow .45s var(--ease);
}
.band__text .cta .btn--solid:hover, .band__text .cta .btn--solid:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35), 0 0 22px 2px rgba(255, 255, 255, 0.28), 0 10px 36px rgba(255, 255, 255, 0.14);
}
.band__text .cta .btn--solid:active { transform: translateY(0) scale(0.98); }
.btn__roll { position: relative; display: inline-block; overflow: hidden; vertical-align: top; line-height: 1.35; }
.btn__roll > span { display: block; transition: transform .5s var(--ease); }
.btn__roll > span + span { position: absolute; left: 0; top: 100%; width: 100%; }
.btn:hover .btn__roll > span, .btn:focus-visible .btn__roll > span { transform: translateY(-100%); }
/* the light Shaders hero: the same glow, in dark, so it shows */
.page-shaders .band--light .cta .btn--solid:hover, .page-shaders .band--light .cta .btn--solid:focus-visible {
  box-shadow: 0 0 0 1px rgba(20, 17, 15, 0.25), 0 0 22px 2px rgba(20, 17, 15, 0.22), 0 10px 36px rgba(20, 17, 15, 0.12);
}
/* touch screens have no hover: nothing to roll */
@media (hover: none) { .btn:hover .btn__roll > span { transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .btn__roll > span { transition: none; }
  .btn:hover .btn__roll > span, .btn:focus-visible .btn__roll > span { transform: none; }
}
