/* Pixel Rack - the one stylesheet for the whole website. */

/* ---------- tokens ---------- */
:root {
  --bg: #17171e;
  --panel: #1d1d25;
  --ash: #9090a0;
  --smoke: #bebecb;
  --paper: #f4f4f0;
  --rim: #36363f;
  --line: rgba(244, 244, 240, 0.12);
  --bad: #e6a0a0;
  --d: "Manrope", system-ui, sans-serif;
  --b: "Inter", system-ui, sans-serif;
  --m: "IBM Plex Mono", ui-monospace, monospace;
  --col: min(1500px, 92vw);
  --gut: calc((100vw - var(--col)) / 2);
  /* background glow positions (purple, blue); each page sets its own, see "page glows" */
  --glow-1: 22% 26%;
  --glow-2: 84% 62%;
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
html, body { margin: 0; }
html { scroll-padding-top: 70px; scrollbar-gutter: stable; }   /* anchors land below the fixed header; space for the scrollbar is always kept, so pages without one do not shift */
body {
  background: var(--bg); color: var(--paper); font-family: var(--b);
  font-size: clamp(15px, 0.95vw, 18px); line-height: 1.6; -webkit-font-smoothing: antialiased;
  overflow-x: hidden; min-height: 100vh; display: flex; flex-direction: column;
}
canvas, img { display: block; }
img { max-width: 100%; }
a { color: inherit; }
.container { width: var(--col); margin: 0 auto; }

/* ---------- main page (v010 design) ---------- */
.hero {
  position: relative;
  padding: clamp(80px, 9vh, 130px) 0 clamp(60px, 7vh, 110px);
}
.hero-glow {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 120vh;
  z-index: 0;
  pointer-events: none;
  will-change: transform;
}
/* the site's background glow: the main page's hero, and the top of every other page */
.hero-glow,
.page::before {
  background:
    radial-gradient(46% 40% at var(--glow-1), rgba(74, 56, 112, 0.6), transparent 70%),
    radial-gradient(46% 40% at var(--glow-2), rgba(28, 66, 98, 0.55), transparent 72%);
}
.hero-rack {
  position: relative;
  z-index: 1;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  height: 20vw;
  will-change: transform;
}
.hero-rack canvas {
  width: 100%;
  height: 100%;
}
.hero-copy {
  position: relative;
  z-index: 2;
  padding-top: clamp(34px, 4vh, 72px);
}
/* the intro on the left, the waitlist on the right, their bottoms level */
.hero-copy { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(28px, 4vw, 90px); align-items: end; }
.waitlist .lead { margin-top: 0; }
.waitlist h2 { margin-bottom: clamp(14px, 1.3vw, 24px); }
@media (max-width: 900px) { .hero-copy { grid-template-columns: 1fr; } }
.eyebrow {
  font-family: var(--m);
  font-size: clamp(10px, 0.66vw, 13px);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--smoke);
  margin: 0 0 clamp(14px, 1.2vw, 24px);
}
h1 {
  font-family: var(--d);
  font-weight: 200;
  font-size: clamp(40px, 4.6vw, 92px);
  line-height: 1.02;
  letter-spacing: -0.04em;
  margin: 0;
  max-width: 16ch;
}
h1 i {
  font-style: normal;
  color: var(--ash);
}
h2 {
  font-family: var(--d);
  font-weight: 200;
  font-size: clamp(28px, 3.1vw, 62px);
  line-height: 1.04;
  letter-spacing: -0.035em;
  margin: 0;
  max-width: 17ch;
}
h3 {
  font-family: var(--d);
  font-weight: 200;
  font-size: clamp(22px, 2.1vw, 42px);
  line-height: 1.06;
  letter-spacing: -0.03em;
  margin: 0 0 clamp(12px, 1vw, 20px);
  max-width: 20ch;
}
.lead {
  color: var(--smoke);
  max-width: 50ch;
  margin: clamp(16px, 1.5vw, 28px) 0 0;
}
.showcase {
  position: relative;
  overflow-x: clip; /* the zoomed rack is wider than the viewport; clip sideways only */
}
.showcase-stage {
  position: relative; /* free-scrolling: no pin, no runway */
  height: auto; /* set by layout(): rack + scrubber + caption */
  overflow: visible; /* never clip: the glow layer fades out on its own; a clip draws a hard line */
  z-index: 1;
}
.showcase-glow {
  position: absolute;
  inset: -25% 0;
  z-index: 0;
  pointer-events: none;
  will-change: transform;
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 19%,
    #000 40%,
    #000 60%,
    transparent 81%
  );
  mask-image: linear-gradient(180deg, transparent 19%, #000 40%, #000 60%, transparent 81%);
  background:
    radial-gradient(48% 42% at 76% 26%, rgba(102, 44, 54, 0.55), transparent 70%),
    radial-gradient(46% 40% at 16% 78%, rgba(34, 52, 104, 0.52), transparent 72%);
}
.showcase-rack {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 1;
  will-change: transform;
  transform-origin: 50% 50%; /* zoom scales about the rack's centre */
}
.showcase-rack canvas {
  width: 100vw;
  height: calc(100vw * 200 / 1920 + 120px); /* frame aspect + 60px each side for the halo */
}
.showcase-captions {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  pointer-events: none;
}
.caption {
  position: absolute;
  left: 0;
  right: 0;
  opacity: 0;
  transition: opacity 0.22s ease;
}
.caption.is-active {
  opacity: 1;
}
.caption .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
  transition:
    opacity 0.6s cubic-bezier(0.72, 0, 0.12, 1),
    transform 0.6s cubic-bezier(0.72, 0, 0.12, 1);
}
.caption.is-active .word {
  opacity: 1;
  transform: none;
}
.caption p {
  color: var(--smoke);
  max-width: 44ch;
  margin: clamp(12px, 1.1vw, 20px) 0 0;
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.5s cubic-bezier(0.72, 0, 0.12, 1) 0.3s,
    transform 0.5s cubic-bezier(0.72, 0, 0.12, 1) 0.3s;
}
.caption.is-active p {
  opacity: 1;
  transform: none;
}
.caption h2 {
  max-width: 19ch;
}
.led-count {
  position: absolute;
  right: 0;
  top: 0;
  text-align: right;
  font-family: var(--m);
  color: var(--ash);
  opacity: 0;
  transition: opacity 0.25s ease;
  line-height: 1;
}
.led-count.is-active {
  opacity: 1;
}
.led-count span {
  display: block;
  font-size: clamp(38px, 3.4vw, 68px);
  color: var(--paper);
  letter-spacing: -0.03em;
}
.led-count em {
  font-style: normal;
  display: block;
  font-size: clamp(9px, 0.6vw, 12px);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-top: 0.7em;
}
.scrubber {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.1vw, 22px);
  font-family: var(--m);
  font-size: clamp(9px, 0.6vw, 12px);
  letter-spacing: 0.16em;
  color: var(--ash);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.scrubber.is-active {
  opacity: 1;
}
.scrubber-track {
  flex: 1;
  height: 1px;
  background: var(--rim);
  position: relative;
  cursor: grab;
  touch-action: none;
}
/* a taller invisible hit area so the 1px track is easy to grab */
.scrubber-track::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -14px;
  bottom: -14px;
}
.scrubber-track.is-dragging {
  cursor: grabbing;
}
.scrubber-handle {
  position: absolute;
  top: -2px;
  height: 5px;
  width: clamp(22px, 1.7vw, 34px);
  background: var(--paper);
  transform: translateX(-50%);
  pointer-events: none;
}
.band {
  position: relative;
  padding: clamp(40px, 4vw, 80px) 0;
  /* explicit, permanent blending group: the band paints its own background and isolates,
     so the screened ground layer always has a complete backdrop (bg + glow) to blend
     against, regardless of which compositing layers Safari keeps or prunes */
  background: var(--bg);
  isolation: isolate;
}
.band-glow {
  position: absolute;
  inset: -25% 0;
  z-index: 0;
  pointer-events: none;
  will-change: transform;
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 19%,
    #000 40%,
    #000 60%,
    transparent 81%
  );
  mask-image: linear-gradient(180deg, transparent 19%, #000 40%, #000 60%, transparent 81%);
  background:
    radial-gradient(44% 40% at 24% 74%, rgba(30, 80, 84, 0.5), transparent 70%),
    radial-gradient(42% 38% at 82% 24%, rgba(78, 48, 104, 0.48), transparent 72%);
}
/* the last section: at least a screen tall, less the anchor height, so the page can always scroll it up to its anchor */
.faq-band { min-height: calc(100vh - 100px); display: flex; flex-direction: column; }   /* now the last section (see below); with the overview's glow */
/* the questions in two columns, left to right, each row as tall as its taller answer */
.faq-band .faq { margin-top: clamp(24px, 2.4vw, 40px); display: grid; grid-template-columns: 1fr 1fr; column-gap: clamp(28px, 4vw, 90px); }
.faq-band .faq > div:nth-child(2) { border-top: 0; padding-top: 0; }
/* the 10" rack, top right (js/rack10.js): its label level with the top of the heading (so it is in view when the
   menu brings the FAQ up), the rack under it beside the first question, wider than its column and reaching left over
   the first question's empty space, never closer than 400px to the left column's start. It rises above the list by
   the heading's height and the gap under it; the first row is as tall as what is left of it. */
/* the first row has twice the usual space under it, so the rack has room above the line */
.faq-band .faq > div:nth-child(-n+2) { padding-bottom: calc(2 * clamp(14px, 1.2vw, 22px)); }
.faq-band .faq-rack { position: relative; }
.faq-band .faq-rack { --rack-w: min(130%, calc(200% + clamp(28px, 4vw, 90px) - 400px)); }
.faq-band .faq-rack-in { width: var(--rack-w); margin: calc(-1.04 * clamp(28px, 3.1vw, 62px) - clamp(24px, 2.4vw, 40px)) 0 0 calc(100% - var(--rack-w)); padding: 0; border: 0; }
.faq-band .faq-rack .rack-10 { padding: 0; border: 0; }
.faq-band .faq-rack .eyebrow { text-align: right; margin-bottom: clamp(7px, 0.6vw, 12px); }   /* as on the API page */
@media (max-width: 900px) {
  .faq-band .faq { grid-template-columns: 1fr; }
  .faq-band .faq > div:nth-child(2) { border-top: 1px solid var(--line); padding-top: clamp(14px, 1.2vw, 22px); }
  .faq-band .faq-rack-in { width: 100%; margin: 0; }
  .faq-band .faq > div:nth-child(-n+2) { padding-bottom: clamp(14px, 1.2vw, 22px); }
}
/* made in Australia: at the foot of the section, however tall it is (it is the page's last), just above the footer */
.made-in { margin-top: auto; padding-top: clamp(40px, 4vw, 80px); }
.made-in p { margin: 0; color: var(--smoke); text-align: center; }
.faq-band dd p { margin: 0; }
.faq-band dd p + p { margin-top: 0.6em; }
.sizes-band {
  background: #000;
  padding: clamp(24px, 2.4vw, 48px) 0;
}
.sizes-band h2 + .split { margin-top: clamp(24px, 2.4vw, 40px); }   /* under the section heading, as the FAQ's list */
.sizes-band .split {
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.6fr); /* left column 10% wider */
}
.sizes-band .feature {
  border-top: 0;
  padding: 0;
}
/* the last band's glow must not hang below the footer: its per-frame parallax transform
   would keep changing the page's scrollable height at the very bottom (jerky bounce) */
section.band:last-of-type {
  overflow: clip; /* the drifting glow must never make the page taller (scroll past the footer, then snap back) */
}
section.band:last-of-type .band-glow {
  bottom: 0;
}
.band .container {
  position: relative;
}
/* Overview (the functionality section): no background of its own, so the hero's glow runs on into it
   with no hard edge; it starts a screen's worth below the hero, as the old Overview's text did */
.band.functionality { background: transparent; padding-top: calc((216px + 16.5vw) / 6); }
/* with the page at the very top, everything below the hero is pushed down (by --hero-push, set in
   js/home.js) just past the bottom of the window, whatever its size, so the first screen is the hero
   alone; as soon as the page moves, it all rises into place */
.hero ~ section, body:has(.hero) .site-footer { transform: translate3d(0, var(--hero-push, 0px), 0); }
/* the Specs and all after them are also pushed by --specs-push (js/home.js): out of sight while the Overview is in place */
#specs, #specs ~ section, body:has(#specs) .site-footer { transform: translate3d(0, calc(var(--hero-push, 0px) + var(--specs-push, 0px)), 0); }
/* functionality: a small menu of topics, one shown at a time (js/site.js) */
.feature-tabs { display: flex; flex-wrap: wrap; gap: 6px clamp(18px, 2vw, 40px); margin: clamp(28px, 2.6vw, 48px) 0 clamp(22px, 2vw, 36px); border-bottom: 1px solid var(--line); }
.feature-tabs button {
  position: relative; background: none; border: 0; padding: 12px 0 14px; cursor: pointer; color: var(--ash);
  font-family: var(--m); font-size: clamp(10px, 0.68vw, 13px); letter-spacing: 0.18em; text-transform: uppercase;
  transition: color 0.18s ease;
}
.feature-tabs button:hover, .feature-tabs button[aria-selected="true"] { color: var(--paper); }
.feature-tabs button::after {
  content: ""; position: absolute; left: 0; right: 0.18em; bottom: -1px; height: 2px; background: var(--tab-colour);
  transform: scaleX(0); transform-origin: left; transition: transform 0.25s ease;
}
.feature-tabs button[aria-selected="true"]::after { transform: scaleX(1); }
.feature-tabs button:nth-child(1) { --tab-colour: #ff4d5e; }
.feature-tabs button:nth-child(2) { --tab-colour: #ffb020; }
.feature-tabs button:nth-child(3) { --tab-colour: #3ddc84; }
.feature-tabs button:nth-child(4) { --tab-colour: #2ec5ff; }
#tab-push { --tab-colour: #2ec5ff; }   /* Push & broadcast keeps its blue now that Editor's tab has gone */
#tab-editor { --tab-colour: #3ddc84; }
/* the Editor tab has its own layout: no display, no ruler, no LED count */
/* the Editor topic has its own layout: the display and ruler close up (and the LED count fades) quickly,
   and open again when another topic is chosen */
.overview-display { display: grid; grid-template-rows: 1fr; grid-template-columns: minmax(0, 1fr); transition: grid-template-rows 0.3s ease, opacity 0.3s ease; }
.overview-display > div { display: flow-root; min-height: 0; overflow: visible clip; }
.overview-count { transition: opacity 0.3s ease; }
.functionality:has(#tab-editor[aria-selected="true"]) .overview-display { grid-template-rows: 0fr; opacity: 0; }
.functionality:has(#tab-editor[aria-selected="true"]) .overview-count { opacity: 0; }
.functionality[data-layout="plain"] .overview-display { display: none; }   /* while js/home.js measures the Editor topic's height */
.sizes-band .feature .lead { font-family: var(--d); font-weight: 200; font-size: clamp(18px, 1.4vw, 26px); line-height: 1.4; color: var(--paper); }
.sizes-band .feature h3 + .lead { margin-top: clamp(28px, 2.6vw, 48px); }
.sizes-band .feature .lead + .lead { margin-top: 0.8em; }
.sizes-band .feature h3 + p:not(.lead) { margin-top: clamp(16px, 1.5vw, 28px); }   /* body text under the heading */
/* a sub-heading in the text, as "LAN-only mode" under Security */
.sizes-band .feature .sub { font: inherit; color: var(--paper); margin: 1.4em 0 4px; }
.specs-network .feature-points { margin-top: clamp(20px, 1.8vw, 32px); }
.lead-list { color: var(--smoke); margin: 10px 0 0; padding-left: 1.2em; }
.lead-list li { margin: 2px 0; }
.lead-list + .lead { margin-top: 10px; }
.specs-network .lead + .lead { margin-top: 0.8em; }
.specs-network dd p { margin: 0; }
.specs-network dd p + p { margin-top: 0.6em; }
/* Editor: its points on the left under the intro, the screenshot of the one in focus on the right. The item
   in focus has a line down its side; the others are dimmed. js/home.js moves the focus on hover. */
.feature-points.editor-points { margin-top: clamp(14px, 1.2vw, 22px); }   /* with the first point's own padding: twice the gap it had under the intro */
.feature-points.editor-points > div { padding-left: 0; padding-right: 0; box-shadow: inset 0 0 0 transparent; cursor: default; transition: box-shadow 0.25s ease, opacity 0.25s ease, padding-left 0.25s ease; opacity: 0.55; outline: none; }
.feature-points.editor-points > div:first-child { padding-top: clamp(14px, 1.2vw, 22px); }
.feature-points.editor-points > div.is-focus { box-shadow: inset 2px 0 0 #3ddc84; padding-left: 16px; opacity: 1; }   /* only the one in focus moves over, beside its line */
.feature-points.editor-points dd p { margin: 0; }
.feature-points.editor-points dd p + p { margin-top: 0.6em; }
.feature-points.editor-points dt { font-family: var(--d); font-weight: 200; font-size: clamp(20px, 1.6vw, 30px); line-height: 1.15; letter-spacing: -0.02em; margin-bottom: 8px; }
/* above the screenshot: size and theme toggles, styled like the topics' menu (the chosen one underlined) */
.shot-toggles { display: flex; justify-content: space-between; gap: 24px; margin-bottom: 14px; padding: 0 50px; }
.shot-toggles [role="group"] { display: flex; gap: clamp(18px, 2vw, 40px); }
.shot-toggles button {
  position: relative; background: none; border: 0; padding: 4px 0 10px; cursor: pointer; color: var(--ash);
  font-family: var(--m); font-size: clamp(10px, 0.68vw, 13px); letter-spacing: 0.18em; text-transform: uppercase; transition: color 0.18s ease;
}
.shot-toggles button:hover, .shot-toggles button[aria-pressed="true"] { color: var(--paper); }
.shot-toggles button::after {
  content: ""; position: absolute; left: 0; right: 0.18em; bottom: 0; height: 2px; background: #3ddc84;
  transform: scaleX(0); transform-origin: left; transition: transform 0.25s ease;
}
.shot-toggles button[aria-pressed="true"]::after { transform: scaleX(1); }
.editor-shots { position: relative; aspect-ratio: 2600 / 2480; border-radius: 10px; overflow: hidden; border: 1px solid var(--line); }
.editor-shots img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.35s ease; }
.editor-shots img.is-shown { opacity: 1; }
.feature-tabs button:nth-child(5) { --tab-colour: #a974ff; }
.feature-tabs button:nth-child(6) { --tab-colour: #ff6ac1; }
.rack-strip.functionality-rack { margin-bottom: 0; }
/* the big LED count sits at the right end of the topics' line: its "LEDs" on the same line as the topic names */
.feature-tabs { align-items: flex-end; }
.led-count.overview-count { position: relative; opacity: 1; margin-left: auto; padding-bottom: 14px; }
/* the count itself hangs just under the topics' line, at its right end; it takes no room, so the
   spacing between the line and the rack stays as it is */
.led-count.overview-count [data-scrub-big] { position: absolute; right: 0; top: calc(100% + 1px + 8px - 0.161em); font-weight: 200; }   /* the digits' tops 8px under the line (0.161em: the space above them in the font) */
.led-count.overview-count em { font-size: clamp(10px, 0.68vw, 13px); letter-spacing: 0.18em; line-height: normal; margin-top: 0.4em; }
/* narrow screens: the count is at its smallest (38px) but the gap under the line is too, so the gap grows to hold the
   digits (8px under the line, about 27px tall) with room under them */
@media (max-width: 900px) { .functionality .feature-tabs { margin-bottom: 48px; } }
/* the old Overview's LED ruler, in the flow under the Overview display (not placed over a stage) */
.feature-scrubber { position: relative; opacity: 1; margin-bottom: clamp(36px, 3.4vw, 64px); }
/* a newly chosen topic rises in, its points one after another */
.feature-panel:not([hidden]) { animation: feature-in 0.55s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.feature-panel:not([hidden]) .feature-points:not(.is-staged) div { animation: feature-in 0.55s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.feature-points div:nth-child(2) { animation-delay: 0.06s; }
.feature-points div:nth-child(3) { animation-delay: 0.12s; }
.feature-points div:nth-child(4) { animation-delay: 0.18s; }
.feature-points div:nth-child(5) { animation-delay: 0.24s; }
.feature-points div:nth-child(6) { animation-delay: 0.3s; }
@keyframes feature-in { from { opacity: 0; transform: translateY(16px); } }
@media (prefers-reduced-motion: reduce) { .feature-panel:not([hidden]), .feature-panel:not([hidden]) .feature-points div { animation: none; } }
.feature-panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: clamp(28px, 4vw, 90px); align-items: start; }
.feature-panel[hidden] { display: none; }
@media (max-width: 900px) { .feature-panel { grid-template-columns: 1fr; } }
.feature-panel h3 { max-width: none; }   /* each topic's heading on one line (it only wraps when the column is too narrow) */
.feature-panel .lead { margin-top: 0; }
.feature-panel .lead + .lead { margin-top: 1em; }
/* a smaller block under a topic's heading and intro (Design: the unit of content) */
.feature-unit { margin-top: clamp(28px, 2.6vw, 44px); padding-top: clamp(20px, 1.8vw, 30px); border-top: 1px solid var(--line); color: var(--smoke); max-width: 50ch; }
.feature-unit h4 { font-family: var(--d); font-weight: 200; font-size: clamp(22px, 1.8vw, 32px); line-height: 1.1; letter-spacing: -0.02em; color: var(--paper); margin: 0 0 12px; }
.feature-unit p:not(.label) { margin: 0 0 10px; }
.feature-unit b { color: var(--paper); font-weight: 400; }
.feature-points { margin: 0; }
.feature-points div { padding: clamp(14px, 1.2vw, 22px) 0; border-top: 1px solid var(--line); }
.feature-points div:first-child { border-top: 0; padding-top: 0; }
.feature-points dt { color: var(--paper); margin-bottom: 4px; }
.feature-points dd { color: var(--smoke); margin: 0; }
/* Live data: the list as big text that comes in with the clips (js/home.js). Each item comes in at the
   top as its clip starts and pushes the ones before it down; the list's height is all of them, so
   nothing under it moves. Placed by the clip's frame, so scrubbing back runs it in reverse. */
.feature-stack dt { font-family: var(--d); font-weight: 200; font-size: clamp(28px, 3.1vw, 62px); line-height: 1.04; letter-spacing: -0.035em; margin-bottom: clamp(10px, 0.9vw, 16px); }
.feature-stack dt .word { display: inline-block; }
.feature-stack dd p { margin: 0; }
.feature-stack dd p + p { margin-top: 0.6em; }
.feature-stack dd { max-width: 64ch; } /* wide enough for two lines, not the whole column */
.feature-stack.is-staged { position: relative; }
.feature-stack.is-staged > div { position: absolute; top: 0; left: 0; right: 0; border-top: 0; padding: 0 0 clamp(28px, 2.6vw, 48px); }
/* an item once the next one has pushed it down (js/home.js eases each title between the two sizes) */
.feature-stack.is-staged > div dd { font-size: clamp(17px, 1.25vw, 23px); }
.feature-stack.is-staged > div.is-pushed dt { font-size: clamp(18px, 1.5vw, 28px); }
.feature-stack.is-staged > div.is-pushed dd { font-size: clamp(15px, 0.95vw, 18px); }
/* under the newest one's title: a hairline whose pulse of LED colour runs from its start to its end over
   that clip's time on the timeline, as the buy page's lines do (js/home.js places it from the frame) */
.feature-stack { --pulse: #ff4d5e; }
/* each topic's own colour (its tab's), unless an item has its clip's colour below */
.feature-stack[data-cues="design"] { --pulse: #ffb020; }
.feature-stack[data-cues="editor"] { --pulse: #3ddc84; }
.feature-stack[data-cues="push"] { --pulse: #2ec5ff; }
.feature-stack[data-cues="network"] { --pulse: #a974ff; }
/* each line in a colour from its own clip on the display */
.feature-stack [data-cue="builtin"] { --pulse: #f59e0b; }   /* the YouTube subscriber count */
.feature-stack [data-cue="own"] { --pulse: #3ddc84; }       /* LAUNCH SUCCESSFUL */
.feature-stack [data-cue="mqtt"] { --pulse: #f87215; }      /* LOUNGE */
.feature-stack [data-cue="snmp"] { --pulse: #2ec5ff; }      /* 2.4GB/S */
.feature-stack [data-cue="unifi"] { --pulse: #22c55e; }     /* the download MB */
.feature-stack [data-cue="text"] { --pulse: #a974ff; }      /* "yours." and "is" */
.feature-stack [data-cue="motion"] { --pulse: #ffb020; }    /* the bars and the temperature */
.feature-stack [data-cue="pixel"] { --pulse: #3ddc84; }     /* the arrow */
.feature-stack [data-cue="fx"] { --pulse: #2ec5ff; }        /* the tunnel */
.feature-stack [data-cue="gauges"] { --pulse: #22c55e; }    /* the gauges' green */
.feature-stack [data-cue="rest"] { --pulse: #a974ff; }      /* Commit */
.feature-stack [data-cue="broadcast"] { --pulse: #ff4d5e; } /* NETWORK REBOOT IN 5 MINS */
.cue-line {
  display: block; height: 1px; margin: 0 0 clamp(10px, 0.9vw, 16px);   /* the full width: under the pause / play button too */
  background: linear-gradient(90deg, transparent, var(--pulse), transparent) no-repeat 0 0 / 120px 100%, var(--line);
}
.feature-stack.is-staged > div.is-pushed .cue-line { margin-bottom: 0; }
/* under the list: the ones still to come (js/home.js), each gone as it comes in */
.cue-next { margin-top: clamp(4px, 0.6vw, 12px); transition: opacity 0.4s ease; }
.cue-next.is-empty { opacity: 0; }
.cue-next .label { display: block; margin-bottom: 10px; opacity: 0.6; }
.cue-next ol { list-style: none; margin: 0; padding: 0; }
.cue-next li { display: flex; align-items: center; gap: 12px; max-height: 2em; margin-bottom: 6px; overflow: hidden; color: var(--smoke); opacity: 0.55; font-size: 14px; transition: opacity 0.4s ease, max-height 0.5s ease, margin 0.5s ease; }
.cue-next li button { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; transition: color 0.18s ease; }
.cue-next li button:hover, .cue-next li button:focus-visible { color: var(--paper); }
.cue-next li::before { content: ""; flex: none; width: 14px; height: 1px; background: var(--pulse); }
.cue-next li.is-in { opacity: 0; max-height: 0; margin-bottom: 0; visibility: hidden; }   /* gone: not clickable or focusable either */
.cue-next li:hover, .cue-next li:focus-within { opacity: 1; }
/* pause / play at the right end of the newest one's title: holds the clip, and its text, where it is */
.feature-stack.is-staged dt { position: relative; padding-right: 96px; }
.cue-play {
  position: absolute; top: 50%; right: 0; margin-top: -18px; width: 36px; height: 36px; padding: 0; display: grid; place-items: center;
  color: var(--paper); background: none; border: 1px solid var(--rim); border-radius: 999px; cursor: pointer;
  transition: border-color 0.18s ease;
}
.cue-play:hover { border-color: var(--paper); }
.cue-play:not(.cue-skip) { right: 44px; }   /* pause / play, with next to its right at the end of the title */
.cue-play svg { width: 12px; height: 12px; fill: currentColor; }
.cue-play .play, .feature-stack.is-paused .cue-play .pause { display: none; }
.feature-stack.is-paused .cue-play .play { display: block; }
.rack-strip {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  aspect-ratio: 6/1;
  margin-bottom: clamp(30px, 3vw, 60px);
  will-change: transform;
}
.rack-strip canvas {
  width: 100%;
  height: 100%;
}
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
  gap: clamp(28px, 4vw, 90px);
  align-items: start;
}
/* right-hand column text widened by the same ratio as the column (1.05fr -> 1.6fr, +52%) */
.split > div:last-child p {
  max-width: 85ch;
}
.split > div:last-child p.lead {
  max-width: 76ch;
}
@media (max-width: 900px) {
  .split {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}
.feature {
  padding: clamp(24px, 2.4vw, 46px) 0;
  border-top: 1px solid rgba(244, 244, 240, 0.16);
}
.feature:first-child {
  border-top: 0;
}
.feature p {
  color: var(--smoke);
  max-width: 56ch;
  margin: 0 0 0.7em;
}
/* standard body text is the default (100%). Add .text-dim to any element - paragraph or
   span - for the same text at 80%. Colour alpha, not opacity, so it nests cleanly. */
.text-dim,
p.text-dim,
.feature p.text-dim {
  color: color-mix(in srgb, currentColor 80%, transparent);
}
.feature p b {
  color: var(--paper);
  font-weight: 400;
}
.label {
  font-family: var(--m);
  font-size: clamp(10px, 0.66vw, 13px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--smoke);
  margin: 0 0 clamp(12px, 1vw, 20px);
}
.spec-list {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(8px, 0.8vw, 14px) clamp(26px, 2.6vw, 56px);
  font-family: var(--m);
  font-size: clamp(10px, 0.68vw, 13px);
  color: var(--ash);
  padding-top: clamp(22px, 2.2vw, 40px);
  border-top: 1px solid rgba(244, 244, 240, 0.16);
  margin: 0;
}
.spec-note {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(8px, 0.8vw, 14px) clamp(26px, 2.6vw, 56px);
  font-family: var(--m);
  font-size: clamp(10px, 0.68vw, 13px);
  color: var(--ash);
  /* padding-top: clamp(22px, 2.2vw, 40px); */
  /* border-top: 1px solid rgba(244, 244, 240, 0.16); */
  margin: 0;
}
.waitlist form {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  max-width: 620px;
  margin-top: clamp(22px, 2.2vw, 40px);
}
.waitlist input {
  flex: 1 1 260px;
  background: #21212b;
  border: 1px solid var(--rim);
  border-radius: 9999px;
  color: var(--paper);
  font-family: var(--m);
  font-size: clamp(11px, 0.72vw, 14px);
  padding: clamp(12px, 1vw, 18px) clamp(18px, 1.5vw, 28px);
}
.waitlist input:focus {
  outline: none;
  border-color: #5c5c6e;
}
.waitlist button {
  border: 1px solid var(--paper);
  background: var(--paper);
  color: var(--bg);
  cursor: pointer;
  font-family: var(--m);
  font-size: clamp(10px, 0.68vw, 13px);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: clamp(12px, 1vw, 18px) clamp(22px, 1.9vw, 36px);
  border-radius: 9999px;
}
/* honeypot field: off-screen, never seen by people */
.honeypot {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
}
.waitlist form.is-sending button {
  opacity: 0.5;
  pointer-events: none;
}
.form-note.is-success {
  color: var(--paper);
}
.form-note.is-error {
  color: #e6a0a0;
}
.form-note {
  font-family: var(--m);
  font-size: clamp(9px, 0.62vw, 12px);
  color: var(--ash);
  margin: clamp(14px, 1.2vw, 24px) 0 0;
}
/* block reveal for non-text elements (cta, form, spec) */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.reveal.is-revealed {
  opacity: 1;
  transform: none;
}
/* word-by-word build-in for text */
.reveal.reveal-words {
  opacity: 1;
  transform: none;
  transition: none;
}
.reveal-words .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
  transition:
    opacity 0.7s cubic-bezier(0.72, 0, 0.12, 1),
    transform 0.7s cubic-bezier(0.72, 0, 0.12, 1);
}
.reveal-words.is-revealed .word {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal-words .word {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
/* fade the whole block in, as v016 did. While fading, the wrapper is a stacking context
   (blend isolated); at opacity 1 it is not, and the blend reaches the page. */
.sizes {
  position: relative;
  width: 100%;
  margin-top: -56px;   /* up into the empty top of the pictures (the 19" rack starts 31px down), so the table under them
                          ends level with the text in the left column */
  overflow: hidden;
  opacity: 0; /* driven per frame by the scrub once the section has built */
}
.sizes.is-active {
  opacity: 1;
}
.sizes-track {
  display: flex;
  align-items: flex-end;
  gap: 0;
}
/* one stack per size, three layers, bottom to top:
   .size-ground = full render (ground + rack over black), screened onto the page
   .size-dim    = 25% page-colour veil over the ground only -> net 75% screen
   .size-rack   = rack only with alpha, normal composite on top
   Images, not canvases: Safari composites canvases on the GPU and the blend dies. */
.size {
  position: relative;
  width: 400px;
  height: 250px;
}
.size + .size {
  margin-left: -120px; /* 30% overlap */
}
.size-image {
  display: block;
  background: transparent;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
}
/* blend on the div (opacity 1, no mask) - the edge-fade mask sits on the img inside it */
.size-ground {
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
}
.size-ground .size-image,
.size-dim {
  /* faded border: edges fall off to transparent to blend into the page */
  -webkit-mask-image:
    linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent),
    linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent),
    linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
  mask-composite: intersect;
}
.size-dim {
  position: absolute;
  inset: 0;
  background: #000; /* matches the black section */
  opacity: 0.5; /* ground layer at 30% */
}
/* focus: content in the vertical middle of the viewport is at 100%, content above and below at 50%
   (driven per frame in js/home.js) */
.focus-fade {
  transition: opacity 0.15s linear;
}

/* ---------- shared header, footer, shop pages ---------- */
.text-muted { color: var(--ash); }
.text-small { font-size: .85em; }
.visually-hidden { position: absolute; left: -9999px; }
h3 a { text-decoration: none; }
/* site header: menu and cart, on every page */
.site-header {
  /* the v010 header: fixed over the page, fading gradient, on every page */
  position: fixed; top: 0; left: 0; right: 0; z-index: 90; display: flex; justify-content: flex-end; align-items: center;
  padding: clamp(16px, 1.4vw, 26px) var(--gut); font-family: var(--m); font-size: clamp(10px, .68vw, 13px);
  letter-spacing: .2em; text-transform: uppercase;
  background: linear-gradient(180deg, rgba(23, 23, 30, 0.92), transparent);
  pointer-events: none;
}
.site-header * { pointer-events: auto; }
/* Content scrolling under the header goes blurry, fading out with the header's own gradient: four
   stacked blur layers (7px at the top down to under 1px), each masked to end a little lower, so the
   blur tapers smoothly instead of a single blur that smears where its mask fades. Each layer is twice
   the header's height and masked back: Chrome (Mac) only blurs the pixels directly behind an element,
   so a layer ending at the header's edge flickers as content crosses it. */
/* --header-blur (0..1, js/site.js) grows the blur in as the page scrolls: content resting at the top is never blurred */
.header-blur[hidden] { display: none; }
.header-blur { position: absolute; left: 0; right: 0; top: 0; height: 400%; z-index: -1; pointer-events: none; }
/* the blur tapers over twice the header height */
.header-blur i { position: absolute; inset: 0; pointer-events: none; }   /* the blur reaches far below the header: it must never take clicks */
.header-blur i:nth-child(1) { -webkit-backdrop-filter: blur(calc(0.9px * var(--header-blur, 0))); backdrop-filter: blur(calc(0.9px * var(--header-blur, 0)));
  -webkit-mask-image: linear-gradient(to bottom, #000 30%, transparent 50%); mask-image: linear-gradient(to bottom, #000 30%, transparent 50%); }
.header-blur i:nth-child(2) { -webkit-backdrop-filter: blur(calc(1.75px * var(--header-blur, 0))); backdrop-filter: blur(calc(1.75px * var(--header-blur, 0)));
  -webkit-mask-image: linear-gradient(to bottom, #000 22%, transparent 42%); mask-image: linear-gradient(to bottom, #000 22%, transparent 42%); }
.header-blur i:nth-child(3) { -webkit-backdrop-filter: blur(calc(3.5px * var(--header-blur, 0))); backdrop-filter: blur(calc(3.5px * var(--header-blur, 0)));
  -webkit-mask-image: linear-gradient(to bottom, #000 14%, transparent 34%); mask-image: linear-gradient(to bottom, #000 14%, transparent 34%); }
.header-blur i:nth-child(4) { -webkit-backdrop-filter: blur(calc(7px * var(--header-blur, 0))); backdrop-filter: blur(calc(7px * var(--header-blur, 0)));
  -webkit-mask-image: linear-gradient(to bottom, #000 6%, transparent 26%); mask-image: linear-gradient(to bottom, #000 6%, transparent 26%); }
.site-header a { color: var(--smoke); text-decoration: none; }
/* content scrolling up under the menu fades out (js/site.js: --fade-at is where the window's top is) */
.is-faded {
  -webkit-mask-image: linear-gradient(to bottom, #000 var(--fade-at), transparent var(--fade-at), transparent calc(var(--fade-at) + 40px), #000 calc(var(--fade-at) + 100px));
  mask-image: linear-gradient(to bottom, #000 var(--fade-at), transparent var(--fade-at), transparent calc(var(--fade-at) + 40px), #000 calc(var(--fade-at) + 100px));
}
.site-header .site-brand { color: var(--paper); }
.site-menu { display: flex; gap: clamp(18px, 2vw, 40px); align-items: center; }
/* menu indicator: a thin solid line under the current page / section; each link has its own colour (js/site.js) */
.site-menu a { position: relative; padding: 12px 0; margin: -12px 0; }   /* taller hit area; the negative margin keeps the header the same height */
.site-menu a::after {
  content: ""; position: absolute; left: 0; right: 0.2em; bottom: 6px; height: 1px;   /* right: the letter-spacing after the last letter */
  background: var(--indicator, var(--paper)); transform: scaleX(0); transform-origin: left; transition: transform 0.25s ease;
}
.site-menu a[aria-current]::after { transform: scaleX(1); }
.cart-button {
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: var(--paper); background: none;
  border: 1px solid var(--rim); border-radius: 999px; padding: 7px 14px; cursor: pointer;
}
.cart-button span { display: inline-block; min-width: 1.2em; text-align: center; margin-left: 4px; color: var(--bg); background: var(--paper); border-radius: 999px; padding: 0 5px; }
.cart-button.is-bumped { animation: bump .5s ease; }
@keyframes bump { 30% { transform: scale(1.12); } }
.page { position: relative; overflow: clip; flex: 1; padding: calc(clamp(14px, 1.6vw, 30px) + 70px) 0 clamp(60px, 7vw, 120px); }
/* + room for the fixed header */
/* the main page's background glow, behind the content; drifts with the scroll like the main page's (js/site.js).
   .page clips it, so the glow never makes the page taller (same as #join) */
.page::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 120vh; z-index: -1; pointer-events: none;
  transform: translate3d(0, var(--glow-shift, 0px), 0); will-change: transform;
}
/* page glows: same glow, placed differently on each page (body data-page = the page's file name) */
[data-page="pixel-rack"] { --glow-1: 78% 22%; --glow-2: 14% 58%; }
[data-page="shop"]       { --glow-1: 30% 18%; --glow-2: 76% 48%; }
[data-page="product"]    { --glow-1: 70% 30%; --glow-2: 20% 66%; }
[data-page="cart"]       { --glow-1: 85% 20%; --glow-2: 25% 55%; }
[data-page="checkout"]   { --glow-1: 12% 40%; --glow-2: 80% 18%; }
[data-page="order"]      { --glow-1: 50% 15%; --glow-2: 15% 70%; }
[data-page="interface"]  { --glow-1: 65% 18%; --glow-2: 30% 64%; }
[data-page="tutorials"]  { --glow-1: 18% 55%; --glow-2: 72% 22%; }
[data-page="faq"]        { --glow-1: 82% 34%; --glow-2: 38% 72%; }
[data-page="contact"]    { --glow-1: 40% 22%; --glow-2: 88% 68%; }
[data-page="privacy"]    { --glow-1: 60% 12%; --glow-2: 10% 50%; }
[data-page="terms"]      { --glow-1: 26% 62%; --glow-2: 78% 30%; }
[data-page="refunds"]    { --glow-1: 90% 50%; --glow-2: 34% 20%; }
.page-header { margin-bottom: clamp(30px, 3.4vw, 64px); }
.category-filters { display: flex; gap: 8px; flex-wrap: wrap; margin: clamp(18px, 1.6vw, 30px) 0 0; font-family: var(--m); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; }
.category-filters a { text-decoration: none; color: var(--smoke); border: 1px solid var(--rim); border-radius: 999px; padding: 6px 14px; }
.category-filters a.is-active { background: var(--paper); color: var(--bg); border-color: var(--paper); }
/* buttons: one style for the whole site */
.button {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: max-content;
  font-family: var(--m); font-size: clamp(10px, 0.68vw, 13px); letter-spacing: 0.14em; text-transform: uppercase;
  padding: clamp(11px, 0.9vw, 17px) clamp(20px, 1.7vw, 34px); border-radius: 9999px; cursor: pointer;
  border: 1px solid var(--paper); background: transparent; color: var(--paper); text-decoration: none;
  transition: background 0.18s ease, color 0.18s ease, opacity 0.18s ease;
}
.button:hover { background: var(--paper); color: var(--bg); }
.button-solid { background: var(--paper); color: var(--bg); }
.button-solid:hover { background: #fff; }
.button-outline { border-color: var(--rim); }
.button[disabled], .button.is-busy { opacity: .45; pointer-events: none; }
.button-full { width: 100%; }
.text-button { background: none; border: 0; color: var(--ash); font: inherit; font-size: .85em; cursor: pointer; padding: 0; text-decoration: underline; }
.text-button:hover { color: var(--paper); }
/* badges: this site's own look; the colour comes from the shop */
.badges { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.badge {
  font-family: var(--m); font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: #fff;
  background: var(--bc, #444); padding: 4px 9px 3px; border-radius: 2px;
}
.badges.badges-overlay { position: absolute; left: 14px; top: 14px; }
/* catalogue */
.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: clamp(18px, 2vw, 36px); }
.product-card { background: var(--panel); border: 1px solid var(--line); border-radius: 6px; overflow: hidden; display: flex; flex-direction: column; }
.product-card-image { position: relative; aspect-ratio: 4 / 3; background: #111117; display: grid; place-items: center; }
.product-card-image img { width: 100%; height: 100%; object-fit: contain; }
.product-card-body { padding: clamp(16px, 1.4vw, 26px); display: flex; flex-direction: column; gap: 4px; flex: 1; }
.product-card-body p { margin: 0; }
.product-card-footer { margin-top: auto; padding-top: 16px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.price { font-family: var(--m); letter-spacing: .04em; }
.stock-status { font-family: var(--m); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ash); }
/* product */
.product-layout { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: clamp(28px, 4vw, 90px); align-items: start; }
@media (max-width: 900px) { .product-layout { grid-template-columns: 1fr; } }
.gallery-main { aspect-ratio: 4 / 3; background: #111117; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; display: grid; place-items: center; }
.gallery-main img { width: 100%; height: 100%; object-fit: contain; }
.gallery-main iframe { width: 100%; height: 100%; border: 0; }
.gallery-thumbs { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.gallery-thumbs button { width: 84px; height: 64px; padding: 0; border: 1px solid var(--rim); background: #111117; border-radius: 4px; cursor: pointer; overflow: hidden; display: grid; place-items: center; color: var(--paper); }
.gallery-thumbs button.is-active { border-color: var(--paper); }
.gallery-thumbs img { width: 100%; height: 100%; object-fit: contain; }
.buy { position: sticky; top: 110px; }
.buy .badges { margin-bottom: 18px; }
.price-large { font-family: var(--d); font-weight: 200; font-size: clamp(28px, 2.4vw, 46px); letter-spacing: -.02em; margin: clamp(18px, 1.6vw, 30px) 0; }
.price-large s { color: var(--ash); font-size: .55em; margin-left: 10px; }
.option { margin-bottom: 20px; }
.option-values { display: flex; flex-wrap: wrap; gap: 8px; }
.option-button {
  font-family: var(--m); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--smoke);
  background: transparent; border: 1px solid var(--rim); border-radius: 999px; padding: 9px 18px; cursor: pointer;
}
.option-button:hover { border-color: var(--smoke); }
.option-button.is-active { background: var(--paper); color: var(--bg); border-color: var(--paper); }
.option-button.is-unavailable { opacity: .35; text-decoration: line-through; }
.bundle-contents ul { margin: 0 0 16px; padding-left: 18px; color: var(--smoke); }
.buy .stock-status { margin: 6px 0 18px; }
.add-to-cart { display: flex; gap: 12px; align-items: stretch; }
/* back in stock: shown while the chosen variant is sold out or on pre-order */
.notify-form { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.notify-form .label { margin: 0 0 10px; }
.notify-fields { display: flex; gap: 8px; }
.notify-fields input {
  flex: 1; min-width: 0; background: #21212b; border: 1px solid var(--rim); border-radius: 999px; color: var(--paper);
  font: inherit; font-size: 15px; padding: 11px 16px;
}
.notify-fields input:focus { outline: none; border-color: #6c6c80; }
.notify-fields .button { flex: none; }
.product-sku { font-family: var(--m); font-size: 11px; letter-spacing: .12em; margin-top: 14px; }
.description { margin-top: clamp(50px, 6vw, 110px); padding-top: clamp(30px, 3vw, 60px); border-top: 1px solid var(--line); max-width: 900px; color: var(--smoke); }
.description h2, .description h3 { color: var(--paper); font-family: var(--d); font-weight: 200; letter-spacing: -.02em; }
.description h2 { font-size: clamp(26px, 2.2vw, 40px); }
.description img, .description iframe, .description video { max-width: 100%; }
.description .video-embed iframe { width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; }
/* quantity stepper */
.stepper { display: inline-flex; align-items: center; border: 1px solid var(--rim); border-radius: 999px; font-family: var(--m); font-size: 13px; }
.stepper button { background: none; border: 0; color: var(--paper); width: 32px; height: 30px; cursor: pointer; font-size: 16px; }
.stepper span { min-width: 22px; text-align: center; }
.stepper.stepper-large button { width: 42px; height: 100%; }
.stepper.stepper-large span { min-width: 26px; }
/* cart lines (drawer and cart page) */
.cart-line { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--line); align-items: center; }
.cart-line-image { width: 72px; height: 56px; background: #111117; border-radius: 4px; overflow: hidden; display: block; }
.cart-line-image img { width: 100%; height: 100%; object-fit: contain; }
.cart-line-name { text-decoration: none; font-family: var(--d); font-weight: 300; font-size: 17px; }
.cart-line-meta { color: var(--ash); font-size: 13px; margin: 2px 0 8px; }
.cart-line-end { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; font-family: var(--m); font-size: 13px; }
.preorder-tag { font-family: var(--m); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--bg); background: var(--smoke); padding: 1px 6px; border-radius: 2px; }
.cart-line-meta .preorder-tag:empty, [data-f="preorder"][hidden] { display: none; }
/* drawer */
.cart-drawer { position: fixed; inset: 0; z-index: 100; }
.cart-drawer[hidden] { display: none; }
.cart-drawer-backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, .55); }
.cart-drawer-panel {
  position: absolute; right: 0; top: 0; bottom: 0; width: min(440px, 100vw); background: var(--bg);
  border-left: 1px solid var(--rim); padding: 22px 26px; display: flex; flex-direction: column;
  animation: slide .25s ease;
}
@keyframes slide { from { transform: translateX(40px); opacity: 0; } }
.cart-drawer-header { display: flex; justify-content: space-between; align-items: center; }
.cart-drawer-header .label { margin: 0; }
.close-button { background: none; border: 0; color: var(--paper); font-size: 26px; cursor: pointer; line-height: 1; }
.cart-drawer-lines { flex: 1; overflow-y: auto; margin: 10px 0; }
.cart-drawer-empty { flex: 1; color: var(--ash); padding-top: 20px; }
.cart-drawer-footer { display: flex; flex-direction: column; gap: 10px; border-top: 1px solid var(--line); padding-top: 16px; }
.cart-drawer-footer .button { width: 100%; }
.summary-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 6px 0; }
.summary-row .label { margin: 0; }
.summary-row.summary-total { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 14px; font-size: 1.15em; }
/* cart page / checkout */
.cart-layout, .checkout-layout, .order-layout { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(300px, 1fr); gap: clamp(28px, 4vw, 90px); align-items: start; }
@media (max-width: 900px) { .cart-layout, .checkout-layout, .order-layout { grid-template-columns: 1fr; } }
.summary { background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: clamp(18px, 1.6vw, 30px); position: sticky; top: 110px; }
.summary .button { width: 100%; margin-top: 14px; }
.discount-form { display: flex; gap: 8px; margin-bottom: 8px; }
.discount-form input { flex: 1; min-width: 0; }
.summary .discount-form .button { width: auto; margin-top: 0; flex: none; }   /* Apply sits beside the code field, not full width like the summary's main button */
.summary-line { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 8px 0; font-size: 14px; border-bottom: 1px solid var(--line); }
.summary-line img { width: 48px; height: 38px; object-fit: contain; background: #111117; border-radius: 3px; }
.order-layout .summary-line { grid-template-columns: minmax(0, 1fr) auto auto; }
.summary-lines { margin-bottom: 14px; }
:is(.checkout-form, .discount-form) :is(input[type=text], input[type=email], input[type=tel], select, textarea) {
  width: 100%; background: #21212b; border: 1px solid var(--rim); border-radius: 6px; color: var(--paper);
  font: inherit; font-size: 15px; padding: 11px 13px; margin-top: 6px;
}
.checkout-form select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ash) 50%), linear-gradient(135deg, var(--ash) 50%, transparent 50%); background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%; background-size: 5px 5px; background-repeat: no-repeat; }
:is(.checkout-form, .discount-form) :is(input, select, textarea):focus { outline: none; border-color: #6c6c80; }
.discount-form input[type=text] { margin-top: 0; border-radius: 999px; }
fieldset { border: 0; padding: 0; margin: 0 0 clamp(26px, 2.4vw, 44px); }
legend { padding: 0; }
.checkout-form label { display: block; font-size: 13px; color: var(--smoke); margin-bottom: 14px; }
.checkout-form .checkbox-label { display: flex; gap: 10px; align-items: center; }
.checkout-form .checkbox-label input { width: auto; margin: 0; }
.fields-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.fields-3 { display: grid; grid-template-columns: 1.3fr 1fr .8fr; gap: 14px; }
@media (max-width: 600px) { .fields-2, .fields-3 { grid-template-columns: 1fr; } }
.checkout-form .is-invalid input, .checkout-form .is-invalid select { border-color: var(--bad); }
.field-error { display: block; color: var(--bad); font-size: 12px; margin-top: 4px; }
.shipping-options, .payment-options { display: flex; flex-direction: column; gap: 8px; }
.shipping-option, .payment-option { display: flex !important; align-items: center; gap: 12px; border: 1px solid var(--rim); border-radius: 6px; padding: 13px 15px; cursor: pointer; margin: 0 !important; color: var(--paper) !important; font-size: 15px !important; }
.shipping-option input, .payment-option input { accent-color: var(--paper); margin: 0; }
.shipping-option .option-price { margin-left: auto; font-family: var(--m); font-size: 13px; }
.shipping-option small { color: var(--ash); }
.shipping-option:has(input:checked), .payment-option:has(input:checked) { border-color: var(--paper); }
.payment-panel { margin-top: 14px; }
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 120; background: var(--paper); color: var(--bg);
  font-family: var(--m); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; padding: 12px 20px; border-radius: 999px;
}
.toast.is-error { background: var(--bad); }
.site-footer {
  border-top: 1px solid var(--line); padding: clamp(20px, 2vw, 36px) var(--gut); display: flex; justify-content: space-between;
  font-family: var(--m); font-size: clamp(9px, .62vw, 12px); letter-spacing: .14em; text-transform: uppercase; color: var(--ash);
}
/* Pixel Rack product page */
.buy-hero { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(320px, 1fr); column-gap: clamp(28px, 4vw, 90px); align-items: center; }
/* left: the picture and the specs under it, the picture's top level with the product name.
   right: the panel, with the back-in-stock form in a row of its own beneath it */
.buy-media { grid-column: 1; grid-row: 1 / span 2; align-self: start; margin-top: 10px; }
.buy-panel { grid-column: 2; grid-row: 1; align-self: start; }
.buy-notify { grid-column: 2; grid-row: 2; align-self: start; }
@media (max-width: 900px) {
  /* one column: picture, panel, back-in-stock form, then the specs */
  .buy-hero { grid-template-columns: 1fr; row-gap: clamp(28px, 4vw, 90px); }
  .buy-media { display: contents; }
  .buy-visual { order: 1; } .buy-panel { order: 2; } .buy-notify { order: 3; } .buy-specs { order: 4; }
  .buy-panel, .buy-notify { grid-column: 1; grid-row: auto; }
}
.buy-visual { position: relative; }
.buy-visual img { width: 100%; height: auto; -webkit-mask-image: radial-gradient(75% 75% at 50% 50%, #000 60%, transparent 100%); mask-image: radial-gradient(75% 75% at 50% 50%, #000 60%, transparent 100%); }
.buy-panel h1 { margin-top: 10px; }
/* badges sit on the product name's line, on the right, outside the flow: they never move anything */
.buy-title { position: relative; }
.buy-title .badges { position: absolute; right: 0; top: 50%; transform: translateY(-50%); justify-content: flex-end; }
.buy-panel .option .text-muted.text-small { margin: 8px 0 0; font-family: var(--m); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.buy-specs { margin-top: clamp(24px, 2.4vw, 44px); padding-top: clamp(24px, 2.4vw, 44px); border-top: 1px solid var(--line); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: clamp(28px, 4vw, 90px); }
/* buy page motion (js/buy.js): build in on load, on a new size, on a new colour; the picture tilts with the pointer */
@keyframes buy-rise { from { opacity: 0; translate: 0 14px; } }
@keyframes buy-picture-in { from { opacity: 0; scale: 0.96; translate: 0 12px; } }
.buy-visual { perspective: 1200px; }
.buy-visual img { transform: rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1); }
.is-entering .buy-visual img, .is-switching .buy-visual img { animation: buy-picture-in 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.is-entering .buy-panel [data-live="buy"] > * { animation: buy-rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.is-entering .buy-panel [data-live="buy"] > :nth-child(2) { animation-delay: 0.08s; }
.is-entering .buy-panel [data-live="buy"] > :nth-child(3) { animation-delay: 0.16s; }
.is-entering .buy-panel [data-live="buy"] > :nth-child(4) { animation-delay: 0.24s; }
.is-entering .buy-panel [data-live="buy"] > :nth-child(5) { animation-delay: 0.32s; }
.is-entering .buy-panel [data-live="buy"] > :nth-child(6) { animation-delay: 0.4s; }
.is-entering .buy-panel [data-live="buy"] > :nth-child(n+7) { animation-delay: 0.48s; }
.is-entering .buy-specs > div:first-child, .is-entering .spec-row,
.is-switching .spec-row { animation: buy-rise 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.is-entering .buy-specs > div:first-child { animation-delay: 0.3s; }
.is-entering .spec-row { animation-delay: 0.4s; }
.spec-row:nth-child(2) { animation-delay: 0.05s; } .spec-row:nth-child(3) { animation-delay: 0.1s; }
.spec-row:nth-child(4) { animation-delay: 0.15s; } .spec-row:nth-child(5) { animation-delay: 0.2s; }
.is-entering .spec-row:nth-child(n+2) { animation-delay: 0.5s; }
.is-switching .price-large, .is-switching .stock-status, .is-switching .add-to-cart, .is-switching .product-sku, .is-switching .notify-form,
.is-recolouring .price-large, .is-recolouring .stock-status, .is-recolouring .add-to-cart, .is-recolouring .product-sku, .is-recolouring .notify-form {
  animation: buy-rise 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.is-switching .stock-status, .is-recolouring .stock-status { animation-delay: 0.05s; }
.is-switching .add-to-cart, .is-recolouring .add-to-cart { animation-delay: 0.1s; }
.is-switching .product-sku, .is-recolouring .product-sku { animation-delay: 0.15s; }
.is-switching .notify-form, .is-recolouring .notify-form { animation-delay: 0.2s; }
/* quiet life (js/buy.js): a pulse of LED colour travels along a hairline; a label lights up and fades back */
.spec-row, .buy-specs, .notify-form { position: relative; }
/* the pulse lies along the whole line and its light moves inside it, from the line's start to its end */
.line-pulse {
  position: absolute; left: 0; right: 0; top: -1px; height: 1px; pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--pulse), transparent) no-repeat;
  background-size: 120px 100%;
  animation: line-pulse 2.6s linear both;   /* duration set per line by js/buy.js: one speed everywhere */
}
.line-pulse.at-bottom { top: auto; bottom: -1px; }
.line-pulse.reverse { animation-direction: reverse; }
@keyframes line-pulse { from { background-position: 0% 0; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } to { background-position: 100% 0; opacity: 0; } }
.buy-page .label { transition: color 0.9s ease; }
.buy-page .label.is-lit { color: color-mix(in srgb, var(--lit) 40%, var(--smoke)); transition-duration: 0.6s; }   /* a tint, not the full colour */
@media (prefers-reduced-motion: reduce) {
  .buy-visual, .buy-page [class] { animation: none !important; }
  .buy-visual img { transform: none; }
}
@media (max-width: 900px) { .buy-specs { grid-template-columns: 1fr; } }
.buy-specs h2 { font-family: var(--d); font-weight: 200; font-size: clamp(28px, 2.6vw, 52px); letter-spacing: -.035em; margin: 0 0 16px; line-height: 1.05; }
.spec-table { font-size: 15px; }
.spec-row { display: grid; grid-template-columns: 1fr 2fr; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--line); align-items: baseline; }
.spec-row .label { margin: 0; }
/* the main page's specs (.sizes-band .split): two columns, each flowing on its own. Left: the sizes, then networking.
   Right (.spec-compare): the two sizes' pictures, then the spec table under them: the labels first, then each size's
   values under its picture (the 10" from 20% across, the 19" from 50.5%, where the two racks sit) */
.sizes-band .specs-network { margin-top: clamp(40px, 4vw, 72px); }
.spec-compare .spec-table { margin-top: clamp(16px, 1.6vw, 32px); }
/* the left column's text a little wider than its column (6%, into the gap; the pictures and the table keep their size
   and place) */
.sizes-band .split > div:first-child { margin-right: -6%; }
.specs-network .lead { max-width: none; }
/* 19" column 30% narrower than it was (49.5% -> 34.65% of the column), the table still ending at the right
   edge: so it all moves over to the right by what the 19" column gave up */
.spec-compare .spec-table { width: 85.15%; margin-left: auto; }
/* the table's columns: the labels (--c1), the 10" (--c2), the 19" (the rest); the lines under the values follow them */
.spec-compare { --c1: 23.49%; --c2: 35.82%; }
.spec-compare .spec-row { grid-template-columns: var(--c1) var(--c2) 1fr; }
.spec-compare .spec-same { grid-column: 2 / -1; }   /* the same on both sizes: once, across both columns */
/* lines under the values instead of across the row: blue under a 10" value, pink-purple under a 19" one, white under
   one shared by both (across both columns). Drawn from the row's bottom, starting where the value's cell starts. */
.spec-compare .spec-row:not(.spec-head) { border-bottom: 0; }
.spec-compare .spec-row:not(.spec-head) > span:not(.label)::after { content: ""; display: block; position: absolute; bottom: 0; height: 1px; }
.spec-compare .spec-row:not(.spec-head) > span:nth-child(2):not(.spec-same)::after { width: var(--c2); background: #2ec5ff; }
.spec-compare .spec-row:not(.spec-head) > span:nth-child(3)::after { width: calc(100% - var(--c1) - var(--c2) - 32px); background: #d36cf2; }
.spec-compare .spec-row:not(.spec-head) > .spec-same::after { width: calc(100% - var(--c1) - 16px); background: rgba(244, 244, 240, 0.5); }
/* the coloured lines pulse now and then: each brightens and glows for a moment, each on its own slow cycle, so they
   never pulse together and the pattern never quite repeats */
@keyframes spec-pulse { 0%, 70%, 100% { opacity: 0.7; box-shadow: none; } 82% { opacity: 1; box-shadow: 0 0 6px 1px currentColor; } }
.spec-compare .spec-row:not(.spec-head) > span:nth-child(2):not(.spec-same)::after { color: #2ec5ff; }
.spec-compare .spec-row:not(.spec-head) > span:nth-child(3)::after { color: #d36cf2; }
.spec-compare .spec-row > span:not(.label):not(.spec-same)::after { animation: spec-pulse 8s ease-in-out infinite both; }
.spec-compare .spec-row:nth-child(2) > span:nth-child(2)::after { animation-duration: 7s; animation-delay: -1s; }
.spec-compare .spec-row:nth-child(2) > span:nth-child(3)::after { animation-duration: 9.5s; animation-delay: -4s; }
.spec-compare .spec-row:nth-child(3) > span:nth-child(2)::after { animation-duration: 8.3s; animation-delay: -6s; }
.spec-compare .spec-row:nth-child(3) > span:nth-child(3)::after { animation-duration: 6.7s; animation-delay: -2.5s; }
.spec-compare .spec-row:nth-child(5) > span:nth-child(2)::after { animation-duration: 10.1s; animation-delay: -3s; }
.spec-compare .spec-row:nth-child(5) > span:nth-child(3)::after { animation-duration: 7.9s; animation-delay: -7.5s; }
@media (prefers-reduced-motion: reduce) { .spec-compare .spec-row > span::after { animation: none; } }
.spec-compare .spec-note { margin-top: 16px; }
/* phones and narrow windows: one column (the specs' own two-column rule would otherwise win over .split's), the
   pictures scaled to the width, the table full width with a wider label column */
@media (max-width: 900px) {
  .sizes-band .split { grid-template-columns: minmax(0, 1fr); gap: clamp(32px, 8vw, 56px); }
  .sizes-band .split > div:first-child { margin-right: 0; }
  .sizes { margin-top: 0; }
  .size { width: 56%; height: auto; aspect-ratio: 8 / 5; }
  .size + .size { margin-left: -16.8%; }   /* the same 30% overlap */
  .spec-compare .spec-table { width: 100%; margin-left: 0; }
  /* each row's label on its own line, the two sizes' values under it, half the width each (nothing wraps) */
  .spec-compare .spec-row { grid-template-columns: 1fr 1fr; row-gap: 4px; }
  .spec-compare .spec-row > .label { grid-column: 1 / -1; }
  .spec-compare .spec-row.spec-head > span:first-child { display: none; }
  .spec-compare .spec-row > .spec-same { grid-column: 1 / -1; }
  .spec-compare .spec-row:not(.spec-head) > span:nth-child(2):not(.spec-same)::after,
  .spec-compare .spec-row:not(.spec-head) > span:nth-child(3)::after { width: calc(50% - 8px); }
  .spec-compare .spec-row:not(.spec-head) > .spec-same::after { width: 100%; }
}
.spec-row.spec-head span { font-family: var(--d); font-weight: 300; font-size: 22px; }
.is-busy { opacity: .45; pointer-events: none; }
/* contact form */
.contact-form { max-width: 640px; }
/* written docs (api.php): headings, code blocks and tables in the site's own type */
.doc { max-width: 900px; color: var(--smoke); }
.doc h2 { font-size: clamp(24px, 2vw, 36px); margin: clamp(40px, 4vw, 72px) 0 16px; color: var(--paper); }
.doc h3 { font-size: clamp(18px, 1.4vw, 24px); margin: 28px 0 12px; color: var(--paper); }
.doc p { margin: 0 0 14px; max-width: 72ch; }
.doc code { font-family: var(--m); font-size: 0.86em; color: var(--paper); }
.doc pre { background: #101015; border: 1px solid var(--line); border-radius: 8px; padding: 16px 18px; overflow-x: auto; margin: 0 0 16px; line-height: 1.55; }
.doc pre code { font-size: 13px; color: #d6d6de; }
.doc table { width: 100%; border-collapse: collapse; margin: 0 0 16px; font-size: 14px; }
.doc th { text-align: left; font-family: var(--m); font-weight: 400; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ash); padding: 10px 12px 10px 0; border-bottom: 1px solid var(--line); }
.doc td { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.doc td:first-child { white-space: nowrap; }
.page-header .lead { max-width: 64ch; }
/* a doc page builds in as it opens, the way the buy page does (its heading, then the doc's first blocks rising
   in one after another; blocks further down are already in place when they're scrolled to) */
.doc-page .page-header > *, .doc-page .doc > * { animation: buy-rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.doc-page .page-header > :nth-child(2) { animation-delay: 0.08s; }
.doc-page .page-header > :nth-child(3) { animation-delay: 0.16s; }
.doc-page .page-header > :nth-child(4) { animation-delay: 0.2s; }
/* two columns: heading and blurb on the left, the rack on the right */
.doc-page .page-header { display: grid; grid-template-columns: 40% 1fr; column-gap: 4%; }
.doc-page .page-header > :not(.doc-rack-col) { grid-column: 1; }
/* the faceplate with its acrylic over it (both 948x168, aligned) */
.doc-rack-col { grid-column: 2; grid-row: 1 / span 3; align-self: end; }
.doc-rack-col .eyebrow { text-align: right; margin-bottom: clamp(7px, 0.6vw, 12px); }   /* half the usual gap: the label belongs to the rack */
.rack-10 { position: relative; }
.rack-10 img { display: block; width: 100%; height: auto; }
.rack-10 img + img { position: absolute; inset: 0; }
/* the LEDs, over the acrylic (x 71..879, y 18..149 of the 948x168 images) */
.rack-10-leds { position: absolute; left: 7.489%; top: 10.714%; width: 85.338%; height: 78.571%; }
@media (max-width: 900px) {
  .doc-page .page-header { grid-template-columns: 1fr; }
  .doc-rack-col { grid-column: 1; grid-row: auto; margin-top: 24px; }
}
.doc-page .doc > :nth-child(1) { animation-delay: 0.26s; }
.doc-page .doc > :nth-child(2) { animation-delay: 0.32s; }
.doc-page .doc > :nth-child(3) { animation-delay: 0.38s; }
.doc-page .doc > :nth-child(4) { animation-delay: 0.44s; }
.doc-page .doc > :nth-child(n+5) { animation-delay: 0.5s; }
@media (prefers-reduced-motion: reduce) { .doc-page .page-header > *, .doc-page .doc > * { animation: none; } }
/* an important note in a doc: a coloured line down its left side, set apart from the text around it */
.doc .doc-note { border-left: 2px solid #ffb020; padding: 4px 0 4px 16px; margin: 20px 0; color: var(--paper); }
/* contact: the words on the left, the form on the right */
.contact-split .lead { margin-top: 0; }
.contact-split h3 { margin-top: clamp(32px, 3vw, 56px); }
.contact-form textarea { resize: vertical; }
.contact-form .button { margin-top: 6px; }
/* tutorials page */
.tutorial-section h2 { font-size: clamp(28px, 2.4vw, 44px); max-width: none; margin: 0 0 clamp(22px, 2vw, 36px); }
.tutorial-list + .label { margin-top: clamp(40px, 4vw, 72px); }   /* Basic, Advanced */
.tutorial-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: clamp(18px, 2vw, 36px); }
.tutorial-card {
  display: flex; flex-direction: column; gap: 12px; height: 100%; padding: clamp(20px, 1.8vw, 34px);
  background: var(--panel); border: 1px solid var(--line); border-radius: 6px; color: inherit; text-decoration: none;
  transition: border-color 0.18s ease;
}
.tutorial-card:hover { border-color: var(--smoke); }
.tutorial-card h4 { font-family: var(--d); font-weight: 300; font-size: clamp(22px, 1.8vw, 34px); line-height: 1.06; letter-spacing: -0.03em; margin: 0; }
.tutorial-card p { color: var(--smoke); margin: 0; }
.tutorial-meta { display: flex; justify-content: space-between; font-family: var(--m); font-size: clamp(10px, 0.66vw, 13px); letter-spacing: 0.18em; text-transform: uppercase; }
.tutorial-card .tutorial-meta { color: var(--ash); }
.tutorial-thumb { display: block; aspect-ratio: 1300 / 1240; margin: 4px 0 6px; background: #111117; border-radius: 4px; overflow: hidden; }
.tutorial-thumb img { width: 100%; height: 100%; object-fit: cover; }

/* tutorial pop-up: the tutorial runs over the page, as large as fits while keeping its shape (1300 x 1320) */
/* width and height are both set outright (no aspect-ratio): Safari only centres a modal dialog, and only
   lets the iframe fill it, when its height is definite */
.tutorial-dialog {
  --tw: min(94vw, calc((100vh - 120px) * 1300 / 1320));
  position: fixed; inset: 0; width: var(--tw); height: calc(var(--tw) * 1320 / 1300); max-width: none; max-height: none;
  padding: 0; border: 1px solid var(--rim); border-radius: 6px; background: #000; overflow: visible; margin: auto;
}
.tutorial-dialog::backdrop { background: rgba(10, 10, 14, 0.78); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.tutorial-dialog iframe { display: block; width: 100%; height: 100%; border: 0; border-radius: 6px; }
.tutorial-dialog .close-button { position: absolute; right: -4px; bottom: 100%; padding: 6px 4px; }
html:has(.tutorial-dialog[open]) { overflow: hidden; }
/* filling the browser window (the tutorial's own button): the close button moves inside, top right */
.tutorial-dialog.is-expanded { width: auto; height: auto; border: 0; border-radius: 0; padding-top: 36px; }   /* inset: 0 - the whole window */
.tutorial-dialog.is-expanded iframe { border-radius: 0; }
.tutorial-dialog.is-expanded .close-button { bottom: auto; top: 2px; right: 12px; }   /* the page behind stays put */

/* policy pages (privacy, terms, refunds): long-form reading text */
.policy { max-width: 75ch; color: var(--smoke); }
.policy h2 { font-size: clamp(22px, 1.7vw, 32px); max-width: none; color: var(--paper); margin: clamp(40px, 3.4vw, 64px) 0 clamp(12px, 1vw, 18px); }
.policy h2:first-child { margin-top: 0; }
.policy h3 { font-family: var(--m); font-weight: 400; font-size: clamp(10px, 0.66vw, 13px); letter-spacing: 0.18em; text-transform: uppercase; line-height: 1.6; color: var(--paper); max-width: none; margin: 24px 0 8px; }
.policy p, .policy address { margin: 0 0 1em; }
.policy address { font-style: normal; color: var(--paper); }
.policy a { color: var(--paper); }
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { color: var(--paper); }
.footer-links { display: flex; gap: clamp(18px, 2vw, 40px); }

/* catalogue card heading */
.product-card h3 { font-weight: 300; font-size: clamp(20px, 1.5vw, 28px); letter-spacing: -.02em; margin: 0 0 4px; max-width: none; }
