/* ═══════════════════════════════════════════════════════════════════════════
   Quality Green — site stylesheet.

   Ported from the .dc.html mockup. The desktop layout is unchanged; what
   moved is WHERE it lives: the mockup declared every box inline, which is
   why its mobile.css had to fight back with !important and
   [style*="grid-template-columns"] substring matching. Here the layout is
   in classes, so the responsive layer below is ordinary cascade.

   Sections are in page order. Everything from RESPONSIVE down is the
   phone/tablet work, and each rebuilt section says why it was rebuilt.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Faces ─────────────────────────────────────────────────────────────
   NOTE: these are the TRIAL cuts (Sohne-*.otf are TestSohne-* renamed;
   Roslindale is the *-Testing build). Not licensed for a public site —
   see DEPLOY.md before going live on a real domain. */
@font-face{font-family:"Roslindale";src:url("../assets/fonts/RoslindaleVariableDisplay.ttf") format("truetype-variations"),url("../assets/fonts/RoslindaleVariableDisplay.ttf") format("truetype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Sohne";src:url("../assets/fonts/Sohne-Extraleicht.otf") format("opentype");font-weight:200;font-style:normal;font-display:swap}
@font-face{font-family:"Sohne";src:url("../assets/fonts/Sohne-Leicht.otf") format("opentype");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Sohne";src:url("../assets/fonts/Sohne-Buch.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Sohne";src:url("../assets/fonts/Sohne-Kraftig.otf") format("opentype");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Sohne";src:url("../assets/fonts/Sohne-Halbfett.otf") format("opentype");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Sohne";src:url("../assets/fonts/Sohne-Dreiviertelfett.otf") format("opentype");font-weight:700;font-style:normal;font-display:swap}

/* ── Tokens ────────────────────────────────────────────────────────────
   Design-system ramps the pages actually reference, plus the QG layer. */
:root{
  --color-neutral-100:#f8f4f4; --color-neutral-200:#eae7e7; --color-neutral-300:#d7d3d3;
  --color-neutral-400:#bab6b6; --color-neutral-500:#9b9797; --color-neutral-900:#2d2b2b;
  --color-accent:#b68235; --color-accent-200:#ffe3bf; --color-accent-300:#facb8d;

  --space-1:4.6px; --space-2:9.2px; --space-3:13.8px;
  --space-4:18.4px; --space-6:27.6px; --space-8:36.8px;

  --font-heading:"Roslindale",Georgia,serif;
  --font-body:"Sohne","Helvetica Neue",Arial,sans-serif;
  --qg-sans:"Sohne","Helvetica Neue",Arial,sans-serif;

  --qg-bg:color-mix(in srgb, var(--color-neutral-900) 58%, #000);
  --qg-surface:color-mix(in srgb, var(--color-neutral-900) 82%, #000);
  --qg-line:color-mix(in srgb, var(--color-neutral-100) 14%, transparent);
  --qg-ink:var(--color-neutral-100);
  --qg-muted:color-mix(in srgb, var(--color-neutral-100) 58%, transparent);
  --qg-brass:var(--color-accent-300);

  /* Corner scale — deliberately restrained. Only buttons go fully round;
     panels stay architectural so the cabinetry reads as square-edged. */
  --qg-r-sm:8px; --qg-r-md:12px; --qg-r-lg:18px; --qg-r-xl:24px; --qg-pill:999px;

  --qg-glass-brd:color-mix(in srgb, var(--color-neutral-100) 18%, transparent);
  --qg-glass-shadow:0 24px 70px rgba(0,0,0,.45);

  /* The two knobs the responsive layer turns. Every section reads them, so
     a breakpoint re-gutters the whole page in one declaration. */
  --qg-pad:var(--space-8);
  --qg-sec:calc(var(--space-8)*1.8);
  --qg-header-h:74px;
}

@keyframes qg-marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes qg-hero-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@keyframes qg-pulse{0%{transform:scale(.9);opacity:.55}70%{transform:scale(1.25);opacity:0}100%{opacity:0}}
@keyframes qg-drawer-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}

/* ── Base ──────────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
/* The `hidden` attribute only gets `display:none` from the UA stylesheet, so
   ANY author `display` rule silently outranks it and the element stays on
   screen with its attribute set. That is not cosmetic: it left the panorama's
   tap-to-unlock overlay sitting at inset:0 over the iframe, eating every
   touch, while the DOM claimed it was hidden. This is the one place
   !important is the right tool — it is enforcing the attribute's semantics,
   not winning a specificity fight, and every mainstream reset does it. */
[hidden]{display:none !important}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--qg-bg);color:var(--qg-ink);overflow-x:clip;
  font-family:var(--font-body);font-size:13px;font-weight:400;letter-spacing:-.005em;
  scroll-padding-top:calc(var(--qg-header-h) + var(--space-4));
}
img{display:block;max-width:100%}
figure{margin:0}
a{color:var(--qg-brass);text-decoration:none}
a:hover{color:var(--color-accent-200)}
h1,h2,h3,h4{font-family:var(--font-heading);font-weight:400;margin:0;line-height:1.12}
strong,b{font-weight:600}
:focus{outline:none}
:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}
::selection{background:color-mix(in srgb, var(--qg-brass) 30%, transparent)}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* Cover-fill image, the shape every ported <image-slot> collapses to. */
.qg-fill{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* ── Surfaces ──────────────────────────────────────────────────────────── */
.qg-glass{
  background:linear-gradient(150deg,rgba(255,255,255,.13) 0%,rgba(255,255,255,.05) 46%,rgba(255,255,255,.09) 100%);
  backdrop-filter:blur(20px) saturate(1.25);
  -webkit-backdrop-filter:blur(20px) saturate(1.25);
  border:1px solid var(--qg-glass-brd);
  border-radius:var(--qg-r-lg);
  box-shadow:var(--qg-glass-shadow), inset 0 1px 0 rgba(255,255,255,.16);
}
.qg-tint{
  background:linear-gradient(150deg,rgba(255,255,255,.055) 0%,rgba(255,255,255,.018) 55%,rgba(255,255,255,.04) 100%);
  border:1px solid var(--qg-line);border-radius:var(--qg-r-md);
}
.qg-card{border-radius:var(--qg-r-md);overflow:hidden;transition:transform .5s cubic-bezier(.2,.7,.2,1), border-color .4s ease}
.qg-media,.qg-media-lg{position:relative;overflow:hidden}
.qg-media{border-radius:var(--qg-r-sm)}
.qg-media-lg{border-radius:var(--qg-r-md)}

/* Hover lifts are a pointer affordance. On touch they latch on tap and stay
   until you tap elsewhere, so they are gated to devices that really hover. */
@media (hover:hover){
  .qg-card:hover{transform:translateY(-5px)}
  .qg-tint.qg-card:hover{border-color:color-mix(in srgb, var(--qg-brass) 45%, transparent)}
}

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  cursor:pointer;text-decoration:none;font-family:var(--qg-sans);
  border:1px solid transparent;border-radius:var(--qg-pill);line-height:1.2;
  font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;font-weight:700;
  padding:13px 24px;white-space:nowrap;
  transition:background-color .3s ease, color .3s ease, border-color .3s ease;
}
.btn-solid{background:var(--qg-ink);color:#14100c;border-color:transparent}
.btn-solid:hover{background:var(--qg-brass);color:#14100c}
.btn-brass{border-color:var(--qg-brass);color:var(--qg-brass);background:transparent}
.btn-brass:hover{background:var(--qg-brass);color:#14100c}
.btn-lg{padding:16px 30px;letter-spacing:.26em}

/* ── Shared section furniture ──────────────────────────────────────────── */
.sec{padding:var(--qg-sec) var(--qg-pad)}
.sec-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-6);margin-bottom:var(--space-8)}
.sec-title{font-size:clamp(28px,2.6vw,42px)}
.eyebrow{font-family:var(--qg-sans);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--qg-muted)}
.eyebrow-brass{font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.32em;text-transform:uppercase;color:var(--qg-brass)}
.link-caps{font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.28em;text-transform:uppercase;white-space:nowrap}
.rule-brass{display:block;width:44px;height:1px;background:var(--qg-brass);flex:none}
/* The lede paragraph style used on the homepage, collection and contact. */
.lede{font-size:1.3rem;line-height:1.55;letter-spacing:-.005em;font-weight:200;color:var(--color-neutral-300);margin:0;text-wrap:pretty}

/* ═══ HEADER ═══════════════════════════════════════════════════════════ */
/* Homepage floats a pill; inner pages use a sticky bar. Both share the
   grid, the nav and the drawer, so only the chrome differs. */
.qg-header{
  z-index:60;display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;gap:var(--space-4);
}
.qg-header--float{
  position:fixed;top:var(--space-3);left:var(--space-4);right:var(--space-4);
  padding:var(--space-2);border-radius:var(--qg-pill);
}
.qg-header--bar{
  position:sticky;top:0;padding:var(--space-3) var(--space-6);
  border-radius:0;border:0;border-bottom:1px solid var(--qg-glass-brd);
  box-shadow:none;
}
.qg-header__logo{display:flex;align-items:center;justify-self:start;margin-left:3px}
.qg-header__logo img{height:38px;width:74px;flex:none;object-fit:contain}

.qg-nav-desktop{
  justify-self:center;display:flex;align-items:center;gap:var(--space-6);
  font-family:var(--qg-sans);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;white-space:nowrap;
}
.qg-nav-desktop > a{color:var(--qg-ink)}
.qg-nav-desktop > a:hover,.qg-nav-desktop > a[aria-current=page]{color:var(--qg-brass)}
.qg-navgroup{position:relative}
.qg-navgroup__btn{
  background:none;border:0;padding:0;cursor:pointer;color:var(--qg-ink);
  font:inherit;letter-spacing:inherit;text-transform:inherit;
  display:inline-flex;align-items:center;gap:6px;
}
.qg-navgroup__btn:hover,.qg-navgroup__btn[aria-current=page]{color:var(--qg-brass)}
.qg-navgroup__btn i{font-style:normal;font-size:8px;color:var(--qg-brass)}
/* Padding-top bridges the gap so the pointer never crosses dead space. */
.qg-navgroup__flyout{
  position:absolute;top:100%;left:50%;transform:translateX(-50%);
  padding-top:20px;min-width:320px;display:none;
}
.qg-navgroup:hover .qg-navgroup__flyout,
.qg-navgroup:focus-within .qg-navgroup__flyout{display:block}
.qg-menu{
  padding:var(--space-3);border-radius:var(--qg-r-lg);display:flex;flex-direction:column;gap:1px;
  background:
    linear-gradient(150deg, color-mix(in srgb, var(--qg-brass) 9%, transparent) 0%, transparent 55%),
    linear-gradient(180deg, color-mix(in srgb, var(--color-neutral-900) 86%, var(--qg-brass)) 0%, color-mix(in srgb, var(--color-neutral-900) 94%, #000) 100%);
  backdrop-filter:blur(22px) saturate(1.2);
  -webkit-backdrop-filter:blur(22px) saturate(1.2);
  border:1px solid color-mix(in srgb, var(--qg-brass) 26%, transparent);
  box-shadow:0 28px 70px rgba(10,8,7,.55), inset 0 1px 0 color-mix(in srgb, var(--qg-brass) 22%, transparent);
}
.qg-menu a{
  display:block;padding:11px var(--space-4);color:var(--qg-ink);
  letter-spacing:.18em;border-radius:var(--qg-r-sm);
  transition:background-color .25s ease,color .25s ease;
}
.qg-menu a:hover{background:color-mix(in srgb, var(--qg-brass) 14%, transparent);color:var(--qg-brass)}

.qg-nav-cta{justify-self:end;display:flex;align-items:center;gap:var(--space-4);white-space:nowrap}
.qg-nav-cta__tel{font-family:var(--qg-sans);font-size:11.5px;letter-spacing:.12em;color:var(--qg-ink)}

/* ── Burger + drawer ───────────────────────────────────────────────────── */
.qg-burger{
  display:none;align-items:center;justify-content:center;justify-self:end;
  width:46px;height:46px;flex:none;padding:0;cursor:pointer;
  background:transparent;border:1px solid var(--qg-line);
  border-radius:var(--qg-pill);color:var(--qg-ink);
  -webkit-tap-highlight-color:transparent;
}
.qg-drawer{
  position:fixed;inset:0;z-index:90;display:flex;flex-direction:column;
  padding:var(--space-4) 20px calc(env(safe-area-inset-bottom,0px) + 24px);
  background:
    linear-gradient(150deg, color-mix(in srgb, var(--qg-brass) 8%, transparent) 0%, transparent 52%),
    linear-gradient(180deg, color-mix(in srgb, var(--color-neutral-900) 90%, var(--qg-brass)) 0%, color-mix(in srgb, var(--color-neutral-900) 96%, #000) 100%);
  backdrop-filter:blur(24px) saturate(1.2);
  -webkit-backdrop-filter:blur(24px) saturate(1.2);
  overflow-y:auto;overscroll-behavior:contain;
  animation:qg-drawer-in .32s cubic-bezier(.2,.7,.2,1);
}
body.nav-open{overflow:hidden}
.qg-drawer-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:calc(var(--space-8)*.9)}
.qg-drawer-top img{height:38px;width:74px;object-fit:contain}
.qg-drawer-close{
  width:46px;height:46px;flex:none;display:flex;align-items:center;justify-content:center;
  background:transparent;border:1px solid var(--qg-line);border-radius:var(--qg-pill);
  color:var(--qg-ink);cursor:pointer;padding:0;
}
.qg-drawer-label{
  font-family:var(--font-heading);font-size:10.5px;font-weight:500;
  letter-spacing:.26em;text-transform:uppercase;color:var(--qg-brass);
  margin:0 0 var(--space-2);
}
.qg-drawer-label + .qg-drawer-label,
.qg-drawer-link + .qg-drawer-label{margin-top:calc(var(--space-8)*.9)}
.qg-drawer-link{
  display:block;padding:15px 0;border-bottom:1px solid var(--qg-line);
  font-family:var(--qg-sans);font-size:13px;font-weight:400;
  letter-spacing:.16em;text-transform:uppercase;color:var(--qg-ink);
}
.qg-drawer-link:active,.qg-drawer-link[aria-current=page]{color:var(--qg-brass)}
.qg-drawer-foot{margin-top:auto;padding-top:calc(var(--space-8)*.9);display:flex;flex-direction:column;gap:var(--space-4)}
.qg-drawer-foot .btn{min-width:0;white-space:normal;text-align:center;padding:16px 20px}
.qg-drawer-foot__tel{font-family:var(--qg-sans);font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--qg-muted)}

/* ═══ HOME — HERO ══════════════════════════════════════════════════════ */
/* 450vh of scroll drives a 145-frame canvas sequence. The frames are NOT
   referenced from markup — site.js builds the URLs and only above the phone
   breakpoint, so a phone never fetches the 17MB set. */
.qg-hero{position:relative;height:450vh}
.qg-hero__stage{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;background:#000}
/* Desktop: the photograph fills the stage and the copy floats over it.
   Phone: this becomes a fixed-height box with the copy below — see RESPONSIVE. */
.qg-hero__media{position:absolute;inset:0;overflow:hidden}
.qg-hero__posterwrap{display:block;position:absolute;inset:0}
.qg-hero__canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* Poster is under the canvas, not instead of it: it gives the section a
   real LCP image immediately, then site.js adds .is-painted once a frame
   has actually drawn and it is retired. */
.qg-hero__poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.qg-hero.is-painted .qg-hero__poster{display:none}
.qg-hero__top{
  position:absolute;left:0;right:0;top:0;height:210px;pointer-events:none;opacity:.45;
  background:linear-gradient(to bottom, rgba(10,8,7,.5) 0%, rgba(10,8,7,.26) 46%, rgba(10,8,7,0) 100%);
}
.qg-hero__vignette{
  position:absolute;inset:0;pointer-events:none;opacity:.6;
  background:radial-gradient(ellipse 85% 80% at 0% 100%, rgba(10,8,7,.88) 0%, rgba(10,8,7,.62) 34%, rgba(10,8,7,.26) 64%, rgba(10,8,7,0) 100%);
}
/* bottom:-470px is the mockup's optical nudge — it pushes the centred stack
   up off the vertical middle without changing the flex centring. */
.qg-hero__copy{
  position:absolute;inset:0;bottom:-470px;display:flex;flex-direction:column;
  justify-content:center;padding:0 var(--qg-pad);pointer-events:none;
}
.qg-hero__kicker{
  display:flex;align-items:center;gap:var(--space-3);margin:0 0 var(--space-4);
  opacity:0;animation:qg-hero-rise 1.1s cubic-bezier(.16,1,.3,1) .35s both;
}
.qg-hero__kicker span:last-child{font-family:var(--qg-sans);font-size:10px;letter-spacing:.34em;text-transform:uppercase;color:var(--qg-brass)}
.qg-hero__title{
  font-size:clamp(46px,6.4vw,104px);line-height:1.02;letter-spacing:-.02em;max-width:15ch;
  opacity:0;animation:qg-hero-rise 1.25s cubic-bezier(.16,1,.3,1) .6s both;
}
.qg-hero__cta{display:none}
.qg-hero__bar{
  position:absolute;left:var(--qg-pad);right:var(--qg-pad);bottom:var(--space-6);
  height:2px;background:rgba(255,255,255,.16);border-radius:var(--qg-pill);
  overflow:hidden;pointer-events:none;
}
.qg-hero__bar i{display:block;height:100%;width:0;background:var(--qg-brass);border-radius:var(--qg-pill)}
/* site.js adds this when it decides not to fetch the frame sequence — touch
   tablets, Save-Data, 2g, reduced motion. The 450vh scroll stage collapses
   to a single screen so there is no dead scroll over a still image. */
.qg-hero--static{height:100svh}
.qg-hero--static .qg-hero__stage{height:100svh}
.qg-hero--static .qg-hero__canvas,
.qg-hero--static .qg-hero__bar{display:none}
.qg-hero--static .qg-hero__poster{display:block}
.qg-hero--static.is-painted .qg-hero__poster{display:block}

/* ═══ HOME — INTRO + STATS ═════════════════════════════════════════════ */
.qg-intro{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);
  gap:var(--space-8);padding:calc(var(--space-8)*1.5) var(--qg-pad);
}
.qg-intro h2{font-size:clamp(30px,3vw,50px);line-height:1.15;max-width:25ch}
.qg-intro .lede{margin-bottom:var(--space-4);max-width:56ch}
.qg-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-4);margin-top:var(--space-8)}
.qg-stat{padding:var(--space-4)}
.qg-stat:first-child{border-top:1px solid var(--qg-brass)}
.qg-stat b{display:block;font-family:var(--font-heading);font-weight:400;font-size:42px;line-height:1;font-variant-numeric:tabular-nums;white-space:nowrap}
.qg-stat--sm b{font-size:clamp(30px,2.6vw,42px)}
.qg-stat span{display:block;font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--qg-muted);margin-top:10px}

/* ═══ HOME — COLLECTIONS DECK ══════════════════════════════════════════ */
.qg-collections{padding:calc(var(--space-8)*1.7) var(--qg-pad) 0}
.qg-collections__head{
  display:flex;align-items:end;justify-content:space-between;gap:var(--space-8);
  margin-bottom:var(--space-8);border-bottom:1px solid var(--qg-line);padding-bottom:var(--space-6);
}
.qg-collections__grid{
  display:grid;grid-template-columns:minmax(0,.62fr) minmax(0,1.38fr);
  gap:calc(var(--space-8)*1.2);align-items:stretch;
}
.qg-cat-list{display:flex;flex-direction:column;border-top:1px solid var(--qg-line)}
.qg-cat-row{
  position:relative;display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:var(--space-3);
  padding:calc(var(--space-4)*1.7) var(--space-3);
  border-bottom:1px solid var(--qg-line);color:var(--qg-ink);text-decoration:none;
  transition:padding-left .4s cubic-bezier(.2,.7,.2,1),color .3s ease;
}
.qg-cat-row:hover{padding-left:var(--space-6)}
.qg-cat-row:focus-visible{outline:2px solid var(--color-accent);outline-offset:3px}
.qg-cat-row__edge{position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--qg-brass);opacity:0;transition:opacity .3s ease}
.qg-cat-row.is-active .qg-cat-row__edge{opacity:1}
.qg-cat-row__n{font-family:var(--qg-sans);font-size:10.5px;letter-spacing:.2em;color:var(--qg-brass);font-variant-numeric:tabular-nums}
.qg-cat-row__name{
  font-family:var(--font-heading);font-size:clamp(19px,1.5vw,25px);line-height:1.2;
  display:block;color:var(--qg-muted);
  transition:transform .5s cubic-bezier(.16,1,.3,1), color .4s ease;
}
.qg-cat-row.is-active .qg-cat-row__name{color:var(--qg-ink);transform:translateX(10px)}
.qg-cat-row__arrow{font-family:var(--qg-sans);font-size:15px;color:var(--qg-brass);opacity:0;transform:translateX(-6px);transition:opacity .35s ease,transform .35s ease}
.qg-cat-row:hover .qg-cat-row__arrow{opacity:1;transform:translateX(0)}

.qg-deck{position:relative;align-self:stretch;height:100%;min-height:612px;cursor:pointer}
/* Each card's transform is a pure function of its circular distance from the
   active index, so cycling is a single class/state write. */
.qg-deck__card{
  position:absolute;top:0;left:50%;width:88%;height:100%;
  border-radius:14px;overflow:hidden;background:transparent;
  transform:translateX(-50%) translateX(var(--dx)) scale(var(--sc)) rotate(var(--rot));
  opacity:var(--op);filter:var(--fl);box-shadow:var(--sh);z-index:var(--z);
  transition:transform .6s cubic-bezier(.34,1.56,.64,1), opacity .5s ease;
  will-change:transform;
}
.qg-deck__card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.qg-deck__hint{display:none}

/* ═══ HOME — GALLERY BAND ══════════════════════════════════════════════ */
.qg-work{padding:calc(var(--space-8)*2.4) var(--qg-pad)}
.qg-work__hero{margin:0 0 var(--space-8);position:relative}
.qg-work__hero .qg-media-lg{aspect-ratio:21/9;background:var(--qg-surface);border-radius:var(--qg-r-lg)}
.qg-work__pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-6)}
.qg-work__pair .qg-media-lg{aspect-ratio:4/3;background:var(--qg-surface);border-radius:var(--qg-r-lg)}
/* No margin reset here: `.qg-work figure` (0,1,1) would outrank
   `.qg-work__hero` (0,1,0) and eat the space below the feature image. The
   base `figure{margin:0}` already zeroes the UA default. */
.qg-work figure{position:relative}
.qg-cap{
  position:absolute;left:var(--space-4);bottom:var(--space-4);
  display:flex;align-items:baseline;gap:var(--space-4);
  padding:var(--space-3) var(--space-4);border-radius:var(--qg-r-lg);
  max-width:calc(100% - var(--space-8));color:var(--qg-ink);
}
.qg-cap b{font-family:var(--font-heading);font-weight:400;font-size:21px;line-height:1.2}
.qg-cap span{font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;color:color-mix(in srgb, var(--color-neutral-100) 75%, transparent);white-space:nowrap}

/* ═══ HOME — PROCESS ═══════════════════════════════════════════════════ */
.qg-process{padding:calc(var(--space-8)*1.6) var(--qg-pad) 160px}
.qg-process h2{font-size:clamp(28px,2.6vw,42px);margin:0 0 var(--space-8)}
.qg-steps{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--space-4)}
.qg-step{padding:var(--space-6);border-radius:var(--qg-r-lg)}
.qg-step:first-child{border-top:1px solid var(--qg-brass)}
.qg-step i{font-style:normal;display:block;font-family:var(--qg-sans);font-size:10px;letter-spacing:.28em;color:var(--qg-brass);font-variant-numeric:tabular-nums}
.qg-step h3{font-size:23px;margin:var(--space-3) 0}
.qg-step p{font-size:15px;line-height:1.85;color:var(--qg-muted);margin:0}

/* ═══ HOME — 360 BAND ══════════════════════════════════════════════════ */
.qg-tour-wrap{padding:0 var(--qg-pad) calc(var(--space-8)*2.4)}
.qg-tour{
  position:relative;overflow:hidden;border-radius:var(--qg-r-xl);
  min-height:74vh;height:780px;display:flex;align-items:center;
  padding:calc(var(--space-8)*1.6);
}
.qg-tour__bg{position:absolute;inset:0;overflow:hidden;background:#0a0807}
/* Oversized and offset so the panorama's own UI chrome sits outside the frame. */
.qg-tour__bg iframe{position:absolute;top:-8%;left:-8%;width:116%;height:118%;border:0;pointer-events:none}
.qg-tour__bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.qg-tour__scrim{
  position:absolute;inset:0;pointer-events:none;opacity:.15;
  background:linear-gradient(to right, rgba(10,8,7,.86) 0%, rgba(10,8,7,.5) 46%, rgba(10,8,7,.14) 100%);
}
/* Centred with margins, not translate: reveal.js clears inline transforms
   when an entrance finishes, which would wipe a translate-based centring. */
.qg-play{
  position:absolute;top:50%;left:50%;margin:-49px 0 0 -49px;
  width:98px;height:98px;border-radius:50%;z-index:3;
  display:flex;align-items:center;justify-content:center;color:var(--qg-ink);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16);
  transition:transform .45s cubic-bezier(.2,.7,.2,1);
}
.qg-play:hover{transform:scale(1.07);color:var(--qg-ink)}
.qg-play svg{display:block;margin-left:4px}
.qg-play::after{
  content:"";position:absolute;inset:-16px;border-radius:50%;pointer-events:none;
  border:1px solid color-mix(in srgb, var(--color-neutral-100) 34%, transparent);
  animation:qg-pulse 3.2s ease-out infinite;
}
.qg-tour__card{position:relative;width:min(460px,46%);padding:var(--space-8);box-shadow:inset 0 1px 0 rgba(255,255,255,.16)}
.qg-tour__card h2{font-size:clamp(28px,2.8vw,44px);line-height:1.12;margin:var(--space-4) 0}
.qg-tour__card .btn{margin-top:var(--space-6);padding:15px 28px;letter-spacing:.24em}

/* ═══ HOME — FINISHES ══════════════════════════════════════════════════ */
/* Twelve Shinnoki veneers as a skewed catalogue. Panels skew as a set; each
   one's contents counter-skew so the grain stays upright. The strip is drawn
   wider than its frame and pulled left, so the outer slants are clipped
   rather than leaving triangular gaps. 5deg holds the cover-scale at 1.38
   across twelve narrow slats — 7deg would need ~1.50 and over-zoom the grain.
   The phone replaces the whole mechanism; see RESPONSIVE. */
.qg-finishes{padding:calc(var(--space-8)*2.4) var(--qg-pad) 0}
.qg-slats-frame{overflow:hidden;border-radius:var(--qg-r-lg)}
.qg-slats{display:flex;gap:2px;height:460px;width:calc(100% + 60px);margin-left:-30px}
.qg-slat{
  position:relative;flex:1 1 0;min-width:0;overflow:hidden;
  transform:skewX(-5deg);background:var(--qg-surface);
  transition:flex-grow .55s cubic-bezier(.2,.7,.2,1);
}
.qg-slat-inner{position:absolute;inset:0;transform:skewX(5deg) scale(1.38);transition:transform .55s cubic-bezier(.2,.7,.2,1)}
.qg-slat-inner img{width:100%;height:100%;object-fit:cover}
.qg-slat-scrim{
  position:absolute;inset:0;pointer-events:none;transform:skewX(5deg) scale(1.38);
  background:linear-gradient(to top, rgba(10,8,7,.88) 0%, rgba(10,8,7,.24) 44%, rgba(10,8,7,.08) 100%);
  transition:opacity .5s ease;
}
.qg-slat-face{position:absolute;inset:0;transform:skewX(5deg);pointer-events:none}
.qg-slat-num{position:absolute;top:var(--space-4);left:50%;transform:translateX(-50%);font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.24em;color:var(--qg-brass);font-variant-numeric:tabular-nums}
/* rotate(180deg) on top of vertical-rl flips the run so it reads bottom-to-top */
.qg-slat-label{
  position:absolute;left:50%;bottom:var(--space-6);transform:translateX(-50%) rotate(180deg);
  writing-mode:vertical-rl;white-space:nowrap;
  font-family:var(--qg-sans);font-weight:300;font-size:15px;letter-spacing:.1em;
  color:var(--color-neutral-300);text-shadow:0 1px 12px rgba(10,8,7,.6);
}
@media (hover:hover){
  .qg-slat{cursor:pointer}
  .qg-slat:hover{flex-grow:3.4}
  .qg-slat:hover .qg-slat-inner{transform:skewX(5deg) scale(1.46)}
  .qg-slat:hover .qg-slat-scrim{opacity:.55}
}

/* ═══ VENDORS ══════════════════════════════════════════════════════════ */
/* Marks are pre-flattened to white on transparent, so one opacity governs
   the row. Per-logo sizes are alpha-weighted to a common optical mass;
   heights differ on purpose because aspect ratios run 3.8:1 to 8:1. */
.qg-vendors{
  margin-top:calc(var(--space-8)*1.7);padding:calc(var(--space-8)*1.9) 0;
  border-top:1px solid var(--qg-line);border-bottom:1px solid var(--qg-line);overflow:hidden;
}
.qg-vendors__head{padding:0 var(--qg-pad);margin-bottom:var(--space-6);display:flex;justify-content:flex-end}
.qg-marquee{display:flex;width:max-content;animation:qg-marquee 46s linear infinite}
.qg-vendor{display:flex;align-items:center;justify-content:center;flex:none;width:220px;height:66px}
.qg-vendor img{object-fit:contain;opacity:.44;transition:opacity .35s ease}
.qg-vendor:hover img{opacity:.92}
.qg-vendor img[data-v=blum]{width:109px;height:28px}
.qg-vendor img[data-v=cove]{width:130px;height:33px}
.qg-vendor img[data-v=egger]{width:102px;height:26px}
.qg-vendor img[data-v=haefele]{width:126px;height:20px}
.qg-vendor img[data-v=salice]{width:126px;height:20px}
.qg-vendor img[data-v=shinnoki]{width:164px;height:25px}
.qg-vendor img[data-v=subzero]{width:147px;height:32px}
.qg-vendor img[data-v=tafisa]{width:127px;height:33px}
.qg-vendor img[data-v=wolf]{width:127px;height:34px}

/* ═══ CONTACT FORM ═════════════════════════════════════════════════════ */
.qg-contact{padding:calc(var(--space-8)*2.4) var(--qg-pad)}
.qg-contact__box{border-radius:var(--qg-r-xl);padding:calc(var(--space-8)*1.3)}
.qg-contact__grid{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:calc(var(--space-8)*1.4);align-items:start}
.qg-contact__grid h2{font-size:clamp(34px,3.6vw,58px);line-height:1.05;margin:var(--space-4) 0;max-width:14ch}
.qg-contact__intro .lede{max-width:56ch}
.qg-form{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4)}
.qg-form .field{display:flex;flex-direction:column;min-width:0}
.qg-form .field--full{grid-column:span 2}
.qg-form label{font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--qg-muted);margin-bottom:9px}
.qg-form .input{
  width:100%;min-height:48px;padding:13px 15px;border-radius:var(--qg-r-sm);
  background:rgba(255,255,255,.04);border:1px solid var(--qg-line);color:var(--qg-ink);
  /* 16px minimum — anything smaller makes iOS Safari zoom the page on focus. */
  font-family:var(--font-body);font-size:16px;
  transition:border-color .3s ease, background-color .3s ease;
}
.qg-form .input:hover{border-color:color-mix(in srgb, var(--color-neutral-100) 30%, transparent)}
.qg-form .input:focus-visible{border-color:var(--qg-brass);background:rgba(255,255,255,.06);outline:none}
.qg-form .input::placeholder{color:color-mix(in srgb, var(--color-neutral-100) 34%, transparent)}
.qg-form textarea.input{min-height:118px;resize:vertical}
.qg-form__status{
  margin:0;padding:14px 18px;border-radius:var(--qg-r-md);
  border:1px solid var(--qg-brass);color:var(--qg-ink);
  background:rgba(250,203,141,.10);font-size:15px;line-height:1.6;
}
.qg-form__status.is-bad{border-color:#c96a5a;background:rgba(201,106,90,.12)}
.qg-form select.input{
  appearance:none;-webkit-appearance:none;padding-right:44px;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23b68235' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 16px center;
}
.qg-form select.input option{background:#1a1715;color:var(--qg-ink)}
.qg-form__submit{grid-column:span 2;display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);margin-top:var(--space-2)}
.qg-form__note{font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--qg-muted)}
.qg-form__submit button{padding:17px 34px;letter-spacing:.26em}

/* ═══ FOOTER ═══════════════════════════════════════════════════════════ */
.qg-footer{border-top:1px solid var(--qg-line);padding:calc(var(--space-8)*1.8) var(--qg-pad) calc(var(--space-8)*1.1)}
.qg-footer__grid{display:grid;grid-template-columns:minmax(0,1.3fr) repeat(3,minmax(0,1fr));gap:var(--space-8) calc(var(--space-8)*1.2);align-items:start}
.qg-footer__brand img{height:38px;width:auto;opacity:.95}
.qg-footer__tag{font-family:var(--qg-sans);font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--qg-muted);margin-top:var(--space-4);line-height:1.7}
.qg-footer__brand p{font-family:var(--qg-sans);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;line-height:2;color:color-mix(in srgb, var(--color-neutral-100) 86%, transparent);margin:var(--space-4) 0 0;max-width:30ch}
.qg-footer__h{font-family:var(--font-heading);font-size:11px;font-weight:500;letter-spacing:.26em;text-transform:uppercase;color:var(--qg-brass);margin:0 0 var(--space-4)}
.qg-footer__col a,.qg-footer__col div.qg-footer__txt{
  font-family:var(--qg-sans);font-size:10.5px;font-weight:400;letter-spacing:.16em;
  text-transform:uppercase;line-height:1.5;display:block;padding:8px 0;
}
.qg-footer__col a{color:color-mix(in srgb, var(--color-neutral-100) 86%, transparent)}
.qg-footer__txt{color:var(--qg-muted)}
.qg-foot-link{transition:color .3s ease}
.qg-foot-link:hover{color:var(--qg-ink)}
.qg-footer__ig{display:inline-flex;align-items:center;justify-content:center;margin-top:var(--space-4);color:var(--qg-ink);padding:8px 0}
.qg-footer__rule{height:1px;background:var(--qg-line);margin:calc(var(--space-8)*1.5) 0 var(--space-6)}
.qg-footer__base{
  display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:var(--space-4);
  font-family:var(--qg-sans);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:color-mix(in srgb, var(--color-neutral-100) 40%, transparent);
}

/* ═══ COLLECTION PAGE ══════════════════════════════════════════════════ */
.col-hero{position:relative;height:72vh;min-height:520px;background:#000}
.col-hero__scrim{position:absolute;inset:0;pointer-events:none;background:linear-gradient(to right, rgba(10,8,7,.8) 0%, rgba(10,8,7,.35) 60%, rgba(10,8,7,.1) 100%)}
.col-hero__copy{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:var(--qg-pad);pointer-events:none}
.col-hero__kicker{display:flex;align-items:center;gap:var(--space-3);margin-bottom:var(--space-4);font-family:var(--qg-sans);font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--qg-brass)}
.col-hero__kicker .rule-brass{width:40px}
.col-hero__copy h1{font-size:clamp(44px,6vw,96px);line-height:1;letter-spacing:-.02em}
.col-lede{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr);gap:var(--space-8);padding:calc(var(--space-8)*1.6) var(--qg-pad);border-bottom:1px solid var(--qg-line)}
.col-lede h2{font-size:clamp(26px,2.4vw,40px);line-height:1.18;max-width:18ch}
.col-lede .lede{max-width:52ch}
.col-tour{background:var(--qg-surface);border-bottom:1px solid var(--qg-line);padding:calc(var(--space-8)*1.4) var(--qg-pad)}
.col-tour__frame{position:relative;width:100%;aspect-ratio:16/7.65;border:1px solid var(--qg-line);background:#000;border-radius:18px;overflow:hidden}
.col-tour__frame iframe{width:100%;height:100%;border:0;display:block}
.col-tour__frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* The tour starts locked so a scroll never lands the wheel inside the
   panorama; it re-locks when it leaves the viewport. */
.col-tour__lock{
  position:absolute;inset:0;cursor:pointer;display:flex;align-items:flex-end;justify-content:center;
  padding:var(--space-6);background:linear-gradient(to top, rgba(10,8,7,.45) 0%, rgba(10,8,7,0) 42%);
}
.col-tour__lock span{
  font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.28em;text-transform:uppercase;color:var(--qg-ink);
  border:1px solid color-mix(in srgb, var(--color-neutral-100) 34%, transparent);
  background:rgba(10,8,7,.5);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  padding:12px 22px;border-radius:999px;
}
/* Phone only — see the phone block. */
.col-tour__play{display:none}
/* Bento — two columns packed shortest-first in script, each item spanning a
   whole number of 4px rows so the columns stay flush at the top. */
.qg-bento{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:4px;column-gap:24px;row-gap:0}
.qg-bento-item{margin:0;position:relative}
/* The packing script assigns each img an explicit pixel height, so the
   height attribute must not win here either — see .qg-masonry img. */
.qg-bento-item img{display:block;width:100%;height:auto;border-radius:18px;background:var(--qg-surface);cursor:zoom-in;object-fit:cover;transition:transform .6s cubic-bezier(.2,.7,.2,1),opacity .4s ease}
@media (hover:hover){.qg-bento-item:hover img{transform:translateY(-4px)}}
.qg-bento-item figcaption{
  position:absolute;left:var(--space-4);bottom:var(--space-4);
  font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--qg-ink);background:rgba(10,8,7,.6);padding:7px 11px;border-radius:999px;
}
.col-facts{border-top:1px solid var(--qg-line);padding:calc(var(--space-8)*1.4) var(--qg-pad)}
.col-facts__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-6);margin:0}
.col-fact{border-top:1px solid var(--qg-line);padding-top:var(--space-4);margin:0}
.col-fact:first-child{border-top-color:var(--qg-brass)}
.col-fact dt{font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.26em;text-transform:uppercase;color:var(--qg-muted)}
.col-fact dd{margin:10px 0 0;font-size:1.3rem;line-height:1.55;letter-spacing:-.005em;font-weight:200;color:var(--color-neutral-300)}
.col-cta{border-top:1px solid var(--qg-line);padding:calc(var(--space-8)*1.8) var(--qg-pad);display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-6)}
.col-cta h2{font-size:clamp(24px,2.9vw,52px);line-height:1.06;white-space:nowrap}

/* ═══ LIGHTBOX ═════════════════════════════════════════════════════════ */
.qg-lb{position:fixed;inset:0;z-index:200;background:rgba(8,6,5,.94);display:flex;align-items:center;justify-content:center}
.qg-lb img{max-width:92vw;max-height:86vh;object-fit:contain;border-radius:18px;display:block}
.qg-lb-nav{
  position:absolute;top:50%;transform:translateY(-50%);width:52px;height:52px;border-radius:999px;
  display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--qg-ink);
  border:1px solid color-mix(in srgb, var(--color-neutral-100) 24%, transparent);
  background:rgba(255,255,255,.06);font-size:20px;
  transition:background-color .3s ease,border-color .3s ease;
}
.qg-lb-nav:hover{background:rgba(255,255,255,.12);border-color:var(--qg-brass);color:var(--qg-ink)}
.qg-lb-prev{left:var(--space-6)}
.qg-lb-next{right:var(--space-6)}
.qg-lb-close{position:absolute;top:var(--space-6);left:var(--space-6)}
.qg-lb-count{position:absolute;top:var(--space-6);right:var(--space-6);font-family:var(--qg-sans);font-size:10.5px;letter-spacing:.2em;color:var(--qg-muted);font-variant-numeric:tabular-nums}

/* ═══ GALLERY PAGE ═════════════════════════════════════════════════════ */
.gal-head{padding:calc(var(--space-8)*1.8) var(--qg-pad) var(--space-8)}
.gal-head h1{font-size:clamp(38px,6vw,86px);line-height:1.02;letter-spacing:-.02em}
.qg-filter{display:flex;flex-wrap:wrap;gap:var(--space-2);padding:0 var(--qg-pad) var(--space-8)}
.qg-filter button{
  font-family:var(--qg-sans);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  padding:11px 18px;border-radius:999px;cursor:pointer;
  background:transparent;border:1px solid var(--qg-line);color:var(--qg-muted);
  transition:color .3s ease,border-color .3s ease,background-color .3s ease;
}
.qg-filter button:hover{color:var(--qg-ink);border-color:var(--qg-brass)}
.qg-filter button[aria-pressed=true]{color:var(--qg-brass);border-color:var(--qg-brass);background:color-mix(in srgb, var(--qg-brass) 12%, transparent)}
.qg-masonry{column-count:3;column-gap:var(--space-6);padding:0 var(--qg-pad) var(--qg-sec)}
.qg-masonry figure{break-inside:avoid;margin:0 0 var(--space-6);position:relative}
/* height:auto is load-bearing. These carry width/height attributes so the
   browser can reserve the box (without them the whole column counts as
   in-viewport and every photograph downloads at once). But the height
   attribute also becomes the used height unless auto overrides it — which
   rendered a 1342x1080 photo as 350x1080. */
.qg-masonry img{width:100%;height:auto;border-radius:18px;background:var(--qg-surface);cursor:zoom-in;display:block}


/* ═══ ABOUT PAGE ═══════════════════════════════════════════════════════ */
/* stretch, not center: the photograph is the left half of the band and runs
   the full height of the copy beside it. A fixed ratio here cropped it to a
   narrow portrait that left a gap down the middle of the page. */
.about-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--space-8);padding:calc(var(--space-8)*1.6) var(--qg-pad);align-items:stretch}
.about-split .qg-media-lg{background:var(--qg-surface);min-height:520px;height:100%}
/* Rules, not cards — the tint reads as a button next to three plain numbers. */
.about-split .qg-stat{border-top:1px solid var(--qg-line);padding:var(--space-3) 0 0}
.about-split .qg-stat:first-child{border-top-color:var(--qg-brass)}
/* ═══ ABOUT — AREAS SERVED ══════════════════════════════════════════
   One markup, two shapes. Here display:contents lifts every dt and dd out of
   its wrapper into the same flex row, so order puts all seven names on the
   first line and the open borough's list on its own line beneath them. On a
   phone (see the phone block) the wrappers come back and it reads as a plain
   stacked list with every borough open — no tab is worth a tap there. */
/* The home page ends on Process, so it carries 160px of air. Here the next
   section is right behind it. */
.about-process{border-top:1px solid var(--qg-line);padding-bottom:calc(var(--space-8)*1.6)}
/* Process sits between the copy and the shop photographs, so the images need
   the rule and the air the section above no longer provides. */
.about-process + .about-trio{border-top:1px solid var(--qg-line);padding-top:var(--qg-sec)}
.about-areas{border-top:1px solid var(--qg-line);padding:calc(var(--space-8)*1.4) var(--qg-pad)}
.area-tabs{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-6) calc(var(--space-8)*.9);margin:0;padding:var(--space-4) 0}
.area{display:contents}
.area-tabs dt{order:1}
.area-tabs dt button{
  font-family:var(--font-heading);font-weight:400;font-size:clamp(19px,1.6vw,26px);line-height:1.15;
  background:none;border:0;border-bottom:1px solid transparent;padding:0 0 4px;cursor:pointer;
  color:var(--qg-muted);transition:color .3s ease,border-color .3s ease;
}
.area.is-on dt button{color:var(--qg-brass);border-bottom-color:var(--qg-brass)}
.area-tabs dd{
  order:2;flex-basis:100%;display:none;margin:var(--space-6) auto 0;max-width:104ch;text-align:center;
  font-size:1.2rem;line-height:2.1;letter-spacing:.01em;font-weight:200;color:var(--color-neutral-500);text-wrap:pretty;
}
.area.is-on dd{display:block}

.about-trio{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-6);padding:0 var(--qg-pad) var(--qg-sec)}
.about-trio .qg-media-lg{aspect-ratio:4/3;background:var(--qg-surface)}

/* ═══ SIMPLE PAGES (contact / privacy / 404) ═══════════════════════════ */
.page-head{padding:calc(var(--space-8)*1.8) var(--qg-pad) var(--space-8)}
.page-head__kicker{display:flex;align-items:center;gap:var(--space-3);margin-bottom:var(--space-6)}
.page-head h1{font-size:clamp(38px,6vw,86px);line-height:1.02;letter-spacing:-.02em;max-width:16ch}
.contact-facts{display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--qg-line);border-bottom:1px solid var(--qg-line);margin:0 var(--qg-pad)}
.contact-facts > dl{padding:var(--space-6);margin:0}
.contact-facts > dl:first-child{padding-left:0}
.contact-facts > dl + dl{border-left:1px solid var(--qg-line)}
.contact-facts dt{font-family:var(--qg-sans);font-size:9.5px;letter-spacing:.26em;text-transform:uppercase;color:var(--qg-muted);margin-bottom:12px}
.contact-facts dd{margin:0;font-size:15px;line-height:1.7}
.contact-split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:calc(var(--space-8)*1.4);padding:calc(var(--space-8)*1.6) var(--qg-pad)}
.contact-aside{display:flex;flex-direction:column;gap:var(--space-4)}
.contact-aside .qg-media-lg{background:var(--qg-surface);min-height:420px}
.prose{padding:0 var(--qg-pad) var(--qg-sec);max-width:74ch}
.prose h2{font-size:clamp(22px,2vw,30px);margin:var(--space-8) 0 var(--space-3)}
.prose p,.prose li{font-size:15px;line-height:1.9;color:var(--qg-muted);margin:0 0 var(--space-3)}
.err-split{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:calc(var(--space-8)*1.2);padding:0 var(--qg-pad) var(--qg-sec);align-items:center}

/* Reveal-on-scroll. The no-js / reduced-motion fallback is "already shown",
   so content is never trapped invisible if the observer never runs. */
.reveal{opacity:0;transform:translateY(14px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1)}
.reveal.is-in{opacity:1;transform:none}

/* ═══════════════════════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Laptop / tablet ───────────────────────────────────────────────────── */
@media (max-width:1100px){
  :root{--qg-pad:var(--space-6);--qg-sec:calc(var(--space-8)*1.4)}
  .qg-nav-desktop{gap:var(--space-4);font-size:9.5px}
  .qg-nav-cta__tel{display:none}
  .qg-intro{grid-template-columns:1fr;gap:var(--space-6)}
  .qg-collections__grid{grid-template-columns:1fr;gap:var(--space-8)}
  .qg-deck{min-height:420px}
  .qg-steps{grid-template-columns:repeat(2,1fr)}
  .qg-contact__grid{grid-template-columns:1fr;gap:var(--space-8)}
  .qg-tour{height:auto;min-height:600px;padding:calc(var(--space-8)*1.2)}
  .qg-tour__card{width:min(460px,60%)}
  .col-lede,.about-split{grid-template-columns:1fr;gap:var(--space-6)}
  .about-split .qg-media-lg{min-height:0;height:auto;aspect-ratio:4/3}
  .col-facts__grid{grid-template-columns:1fr 1fr}
  .contact-facts{grid-template-columns:repeat(2,1fr)}
  .contact-facts > dl:nth-child(3){border-left:0;padding-left:0}
  .contact-split,.err-split{grid-template-columns:1fr}
  .contact-aside .qg-media-lg{min-height:0}
  .qg-masonry{column-count:2}
  .qg-slats{height:380px}
  .qg-slat-label{font-size:14px}
  .col-cta h2{white-space:normal}
}

/* ── Phone ─────────────────────────────────────────────────────────────── */
@media (max-width:760px){
  :root{
    --qg-pad:20px;
    --qg-sec:calc(var(--space-8)*1.15);
    --qg-header-h:62px;
  }

  /* Header collapses to logo + burger; the nav and the tel/quote pair move
     into the drawer. */
  .qg-header{grid-template-columns:1fr auto}
  .qg-header--float{top:var(--space-2);left:var(--space-3);right:var(--space-3);padding:var(--space-2)}
  /* Inner pages use the sticky bar, and it sat noticeably taller than the
     floating pill on the homepage. The burger is what sets the floor. */
  .qg-header--bar{padding:var(--space-1) var(--qg-pad)}
  .qg-header--bar .qg-burger{width:40px;height:40px}
  .qg-header__logo img{height:30px;width:58px}
  .qg-nav-desktop,.qg-nav-cta{display:none}
  .qg-burger{display:flex}

  /* ── Hero ────────────────────────────────────────────────────────────
     The photograph is a 72svh box and the copy sits under it, rather than a
     full-height image with text laid over the bottom third. Two reasons,
     and the second is the important one:

       - the buttons land immediately below the picture instead of on it;
       - a shorter box is a WIDER crop. These stills are 16:9; cover-fitting
         them into a full-height portrait viewport showed only the middle
         26% of the frame, which is why the walking figure was barely in
         shot. At 72svh it shows ~36%, and she is on screen throughout.

     site.js pairs this with a trimmed frame range (46-131) so every frame
     of the scroll has her in it. No stride — all 86 ship, which is what
     makes the scrub smooth rather than steppy. */
  .qg-hero{height:280vh}
  .qg-hero__stage{height:100svh;display:flex;flex-direction:column;background:var(--qg-bg)}
  .qg-hero__media{
    position:relative;inset:auto;flex:none;width:100%;background:#000;
    /* 72% of the screen, but never so much that the copy block gets
       squeezed off the bottom — on a 568px-tall SE, 72svh left the buttons
       below the fold. The floor reserves room for kicker + headline + CTAs. */
    height:min(72svh, calc(100svh - 230px));
  }
  .qg-hero__top{display:none}
  .qg-hero__vignette{
    opacity:1;
    /* Only has to soften the bottom edge into the copy block now — the text
       is no longer sitting on the photograph. */
    background:linear-gradient(to top, rgba(10,8,7,.85) 0%, rgba(10,8,7,.25) 14%, rgba(10,8,7,0) 34%);
  }
  .qg-hero__copy{
    position:relative;inset:auto;flex:1 1 auto;justify-content:center;
    padding:var(--space-4) var(--qg-pad) calc(var(--space-4) + env(safe-area-inset-bottom,0px));
    pointer-events:auto;
  }
  .qg-hero__kicker{margin-bottom:var(--space-2)}
  .qg-hero__kicker .rule-brass{width:26px}
  .qg-hero__kicker span:last-child{font-size:9px;letter-spacing:.24em}
  .qg-hero__title{font-size:clamp(30px,8.4vw,42px);max-width:none;animation-delay:.3s}
  /* The desktop headline hard-breaks with <br> for its own measure; at
     phone width the line box decides. */
  .qg-hero__title br{display:none}
  .qg-hero__cta{display:flex;gap:var(--space-2);margin-top:var(--space-3);flex-wrap:nowrap}
  .qg-hero__cta .btn{flex:1 1 0;min-width:0;padding:14px 10px;font-size:9.5px;letter-spacing:.14em}
  /* Progress bar sits on the bottom edge of the photograph. It lives inside
     __media, so it tracks that box whatever height the clamp gives it. */
  .qg-hero__bar{display:block;top:auto;bottom:0;left:0;right:0;border-radius:0}

  /* ── Intro / stats ───────────────────────────────────────────────────
     Stats become a label:value row rather than three stacked cards — the
     numbers are short and the tall stack wasted a whole screen. */
  .qg-intro{padding:var(--qg-sec) var(--qg-pad)}
  .qg-intro h2 br,.qg-intro .lede br{display:none}
  .qg-intro h2{font-size:clamp(26px,7vw,34px)}
  .qg-intro .lede{font-size:1.05rem}
  .qg-stats{grid-template-columns:1fr;gap:var(--space-2);margin-top:var(--space-6)}
  .qg-stat{display:flex;align-items:baseline;gap:var(--space-4);padding:var(--space-3) var(--space-4)}
  .qg-stat b,.qg-stat--sm b{font-size:30px;flex:none}
  .qg-stat span{margin-top:0}

  .sec-head,.qg-collections__head{flex-direction:column;align-items:flex-start;gap:var(--space-3);margin-bottom:var(--space-6)}

  /* ── Collections, rebuilt ────────────────────────────────────────────
     The desktop deck is driven by onMouseEnter on the list rows. A phone
     has no hover, so six of the seven cards were unreachable — only the
     whole-deck tap-to-cycle worked. Replaced with a swipeable snap
     carousel where each card IS its collection link, and the list below
     stays as a plain index. Nothing depends on hover. */
  .qg-collections{padding:var(--qg-sec) var(--qg-pad) 0}
  .qg-collections__grid{display:flex;flex-direction:column-reverse;gap:var(--space-6)}
  .qg-deck{
    display:flex;min-height:0;height:auto;cursor:default;
    gap:var(--space-3);overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    margin:0 calc(var(--qg-pad)*-1);padding:0 var(--qg-pad) var(--space-3);
    scrollbar-width:none;scroll-padding-inline:var(--qg-pad);
  }
  .qg-deck::-webkit-scrollbar{display:none}
  .qg-deck__card{
    position:relative;top:auto;left:auto;flex:0 0 78%;width:auto;
    height:auto;aspect-ratio:4/5;scroll-snap-align:center;
    transform:none;opacity:1;filter:none;z-index:auto;
    box-shadow:0 18px 40px rgba(10,8,7,.4);
  }
  /* The card carries its own label on a phone — off the deck there is no
     hovered row to say which collection you are looking at. */
  .qg-deck__hint{
    display:flex;align-items:baseline;gap:var(--space-3);
    position:absolute;left:var(--space-3);right:var(--space-3);bottom:var(--space-3);
    padding:11px 14px;border-radius:var(--qg-r-md);
    background:rgba(10,8,7,.62);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  }
  .qg-deck__hint i{font-style:normal;font-family:var(--qg-sans);font-size:9px;letter-spacing:.2em;color:var(--qg-brass)}
  .qg-deck__hint b{font-family:var(--font-heading);font-weight:400;font-size:16px;color:var(--qg-ink);line-height:1.2}
  .qg-cat-row{padding:var(--space-4) var(--space-2)}
  .qg-cat-row:hover{padding-left:var(--space-2)}
  .qg-cat-row__name{font-size:17px;color:var(--qg-ink)}
  .qg-cat-row.is-active .qg-cat-row__name{transform:none}
  .qg-cat-row__arrow{opacity:1;transform:none}

  /* ── Gallery band ────────────────────────────────────────────────────
     Caption stays on the photograph, as on desktop — a card underneath cost
     a whole extra block of height per project. Crop 21:9 to 4:3 so there is
     room for it, and drop the place/year: at this size one line of title is
     what fits, and the detail is on the collection page anyway. */
  .qg-work{padding:var(--qg-sec) var(--qg-pad)}
  .qg-work__hero .qg-media-lg{aspect-ratio:4/3}
  .qg-work__pair{grid-template-columns:1fr;gap:var(--space-4)}
  .qg-cap{
    left:var(--space-3);right:var(--space-3);bottom:var(--space-3);
    max-width:none;padding:10px var(--space-3);border-radius:var(--qg-r-md);
  }
  .qg-cap b{font-size:14.5px;line-height:1.25}
  .qg-cap span{display:none}

  /* ── Process ─────────────────────────────────────────────────────────── */
  .qg-process{padding:0 var(--qg-pad) var(--qg-sec)}
  .qg-steps{grid-template-columns:1fr;gap:var(--space-2)}
  .qg-step{padding:var(--space-4)}
  .qg-step h3{font-size:19px;margin:var(--space-2) 0}
  .qg-step h3 br{display:none}
  .qg-step p{font-size:14px}

  /* ── 360 band, rebuilt ───────────────────────────────────────────────
     The desktop band boots a live Panoee iframe at 116%x118% behind a
     glass card. On a phone that is a third-party tour loading on cellular
     purely as wallpaper, and the card would sit on top of it. site.js
     swaps the iframe for a still, and the two stack: text card first, then
     the image with the play button centred on it. */
  .qg-tour-wrap{padding:0 var(--qg-pad) var(--qg-sec)}
  /* Extra air after the process cards — they end flush and the band was
     reading as part of the same block. */
  .qg-process{padding-bottom:calc(var(--qg-sec) * 1.6)}
  .qg-tour{
    flex-direction:column;height:auto;min-height:0;padding:0;
    border-radius:0;background:transparent;overflow:visible;
  }
  .qg-tour__card{order:1;width:100%;margin:0 0 var(--space-4);padding:var(--space-6)}
  .qg-tour__bg{order:2;position:relative;inset:auto;width:100%;aspect-ratio:4/3;border-radius:var(--qg-r-lg)}
  .qg-tour__scrim{opacity:.25;border-radius:var(--qg-r-lg);background:linear-gradient(to top, rgba(10,8,7,.6) 0%, rgba(10,8,7,.05) 62%)}
  /* Dead centre of the photograph — the play button is a child of __bg, so
     50/50 tracks the image wherever the order puts it. */
  .qg-play{top:50%;left:50%;width:64px;height:64px;margin:-32px 0 0 -32px}
  .qg-play svg{width:22px;height:24px}
  .qg-play::after{inset:-10px}
  .qg-tour__card h2{font-size:25px;margin:var(--space-3) 0}
  .qg-tour__card .btn{width:100%;margin-top:var(--space-4)}

  /* ── Finishes, rebuilt ───────────────────────────────────────────────
     The skewed catalogue is a hover mechanism. Twelve slats across a 320px
     screen are ~26px wide, the labels run vertically inside them, and there
     is no hover to open one. The mockup's mobile.css narrowed the slats but
     never reset writing-mode, so the labels stayed rotated in an 84px
     column. Here they become upright swipe cards with the name underneath,
     which is what the hover-to-open was standing in for. */
  .qg-finishes{padding:var(--qg-sec) var(--qg-pad) 0}
  .qg-slats-frame{
    overflow-x:auto;overflow-y:hidden;border-radius:0;
    margin:0 calc(var(--qg-pad)*-1);padding:0 var(--qg-pad) var(--space-3);
    scroll-snap-type:x mandatory;overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
    /* Without this, mandatory snap aligns the first slat to the scrollport
       edge and swallows the leading gutter — the strip loads scrolled 20px
       in, with card 01 clipped. scroll-padding moves the snapport instead. */
    scroll-padding-left:var(--qg-pad);
  }
  .qg-slats-frame::-webkit-scrollbar{display:none}
  .qg-slats{width:max-content;height:auto;margin-left:0;gap:var(--space-3)}
  .qg-slat{
    flex:0 0 auto;width:130px;transform:none;overflow:visible;
    background:transparent;scroll-snap-align:start;
  }
  .qg-slat-inner{position:relative;inset:auto;height:186px;transform:none;border-radius:var(--qg-r-sm);overflow:hidden}
  .qg-slat-scrim{height:186px;transform:none;border-radius:var(--qg-r-sm);background:linear-gradient(to top, rgba(10,8,7,.45) 0%, rgba(10,8,7,0) 48%)}
  .qg-slat-face{position:static;transform:none}
  .qg-slat-num{position:static;transform:none;display:block;margin-top:var(--space-3);font-size:9px;letter-spacing:.2em}
  .qg-slat-label{
    position:static;transform:none;writing-mode:horizontal-tb;display:block;
    margin-top:3px;font-size:13.5px;letter-spacing:.01em;white-space:normal;
    text-shadow:none;color:var(--qg-ink);
  }

  /* ── Vendors ─────────────────────────────────────────────────────────── */
  .qg-vendors{margin-top:var(--qg-sec);padding:var(--qg-sec) 0}
  .qg-vendors__head{padding:0 var(--qg-pad)}
  .qg-vendor{width:148px;height:50px}
  .qg-vendor img{transform:scale(.76);opacity:.5}
  .qg-marquee{animation-duration:32s}

  /* ── Contact form ────────────────────────────────────────────────────── */
  .qg-contact{padding:var(--qg-sec) var(--qg-pad)}
  .qg-contact__box{padding:var(--space-6);border-radius:var(--qg-r-lg)}
  .qg-contact__grid h2{font-size:clamp(28px,8vw,38px)}
  .qg-form{grid-template-columns:1fr;gap:var(--space-3)}
  .qg-form .field--full,.qg-form__submit{grid-column:span 1}
  .qg-form__submit{flex-direction:column-reverse;align-items:stretch;gap:var(--space-3)}
  .qg-form__submit button{width:100%}
  .qg-form__note{text-align:center}

  /* ── Footer ──────────────────────────────────────────────────────────── */
  .qg-footer{padding:var(--qg-sec) var(--qg-pad) var(--space-8)}
  .qg-footer__grid{grid-template-columns:1fr 1fr;gap:var(--space-6) var(--space-4)}
  .qg-footer__brand{grid-column:span 2}
  /* Stack the credit under the copyright, both centred. flex-direction
     column does the centring properly — text-align could not reach the
     anchor once it became a flex item for its tap target. */
  .qg-footer__base{flex-direction:column;align-items:center;text-align:center;gap:var(--space-2)}
  .qg-footer__base span,.qg-footer__base a{flex:0 0 auto}

  /* Tap targets. These three sit at 13–26px tall on the desktop scale —
     under the 24px WCAG 2.5.8 floor and well under a comfortable thumb.
     Padding rather than font-size, so the type scale is untouched. */
  .qg-header__logo,.sec-head .link-caps,.qg-footer__base a{
    display:inline-flex;align-items:center;min-height:44px;
  }
  .sec-head .link-caps{padding:0 var(--space-2);margin-left:calc(var(--space-2)*-1)}

  /* ── Collection page ───────────────────────────────────────────────────
     16/15 is the 4/5 portrait crop with a quarter of its height taken out:
     h = w x 0.9375 instead of w x 1.25. It was eating most of the first
     screen before a word of copy. */
  .col-hero{height:auto;min-height:0;aspect-ratio:16/15}
  .col-hero__scrim{background:linear-gradient(to top, rgba(10,8,7,.9) 0%, rgba(10,8,7,.35) 55%, rgba(10,8,7,.15) 100%)}
  .col-hero__copy{padding:var(--qg-pad)}
  .col-hero__copy h1{font-size:clamp(34px,10vw,52px)}
  .col-lede,.col-tour,.col-facts{padding:var(--qg-sec) var(--qg-pad)}
  .col-lede h2{font-size:clamp(22px,6.5vw,30px)}
  .col-lede .lede,.col-fact dd{font-size:1.05rem}
  /* Half the screen, not a ratio: 4/3 of a phone width eats most of the view.
     svh so the address bar collapsing does not resize the tour mid-drag. */
  .col-tour__frame{aspect-ratio:auto;height:50vh;height:50svh}
  /* The phone tour is wallpaper, not an instrument. Oversized and offset the
     same way as the home band so the tour's own top bar sits outside the
     frame, and inert so a scroll is never swallowed by the panorama. */
  .col-tour__frame iframe{position:absolute;top:-8%;left:-8%;width:116%;height:118%;pointer-events:none}
  /* The lock stays as the scrim that keeps the play button legible over a
     bright kitchen — only its pill and its job go. */
  .col-tour__lock{pointer-events:none;background:rgba(10,8,7,.25)}
  .col-tour__lock span{display:none}
  .col-tour__play{display:flex}
  .col-facts__grid{grid-template-columns:1fr;gap:var(--space-4)}
  .col-cta{padding:var(--qg-sec) var(--qg-pad);align-items:stretch}
  .col-cta h2{white-space:normal;font-size:clamp(22px,6.5vw,30px)}
  .col-cta .btn{width:100%}
  /* One full-width column. The script already packs to a single column
     below 600px, but it only sets grid-column on the items — the track
     list lives here, and left at repeat(2,...) every photograph stacked
     into column one at half width. */
  .qg-bento{grid-template-columns:1fr;column-gap:0}

  /* ── Gallery page ────────────────────────────────────────────────────── */
  .gal-head,.page-head{padding:var(--qg-sec) var(--qg-pad) var(--space-6)}
  .qg-filter{padding:0 var(--qg-pad) var(--space-6);gap:7px}
  .qg-filter button{font-size:9.5px;letter-spacing:.14em;padding:10px 14px}
  .qg-masonry{column-count:1;padding:0 var(--qg-pad) var(--qg-sec)}
  .qg-masonry figure{margin-bottom:var(--space-4)}

  /* ── About ───────────────────────────────────────────────────────────── */
  .about-split{padding:var(--qg-sec) var(--qg-pad)}
  .about-split .qg-media-lg{aspect-ratio:4/3}
  .about-trio{grid-template-columns:1fr;gap:var(--space-4);padding:0 var(--qg-pad) var(--qg-sec)}
  /* The phone keeps the pills — three rules stacked in one column read as a
     broken table, three pills read as three facts. */
  .about-split .qg-stat{
    border:1px solid var(--qg-line);border-radius:var(--qg-r-md);padding:var(--space-3) var(--space-4);
    background:linear-gradient(150deg,rgba(255,255,255,.055) 0%,rgba(255,255,255,.018) 55%,rgba(255,255,255,.04) 100%);
  }
  .about-areas{padding:var(--qg-sec) var(--qg-pad)}
  .area-tabs{display:block;padding:0}
  .area{display:block;border-top:1px solid var(--qg-line);padding-top:var(--space-4);margin-top:var(--space-4)}
  /* The script unwraps the button to plain text here, so the type lives on
     the dt; the button rule is what a no-JS phone falls back to. */
  .area-tabs dt{margin:0;font-family:var(--font-heading);font-size:19px;line-height:1.15;color:var(--qg-brass)}
  .area-tabs dt button{color:inherit;font:inherit;padding:0;border-bottom:0;cursor:default}
  .area-tabs dd{display:block;margin:10px 0 0;max-width:none;text-align:left;font-size:14px;line-height:2}

  /* ── Contact / privacy / 404 ─────────────────────────────────────────── */
  .contact-facts{grid-template-columns:1fr;margin:0 var(--qg-pad)}
  .contact-facts > dl{padding:var(--space-4) 0}
  /* Address, phone and email are the page's primary actions on a phone —
     give them a real target instead of a 20px line of text. */
  .contact-facts dd a{display:inline-flex;align-items:center;min-height:44px}
  .contact-facts > dl + dl{border-left:0;border-top:1px solid var(--qg-line);padding-left:0}
  .contact-facts > dl:nth-child(3){padding-left:0}
  .contact-split,.err-split{padding:var(--qg-sec) var(--qg-pad);gap:var(--space-8)}
  .prose{padding:0 var(--qg-pad) var(--qg-sec)}

  /* ── Lightbox: arrows to the bottom, out from under the thumbs ───────── */
  .qg-lb img{max-width:94vw;max-height:74vh}
  .qg-lb-nav{top:auto;bottom:calc(env(safe-area-inset-bottom,0px) + 20px);transform:none;width:48px;height:48px}
  .qg-lb-prev{left:22%}
  .qg-lb-next{right:22%}
  .qg-lb-close,.qg-lb-count{top:var(--space-4)}
  .qg-lb-close{left:var(--space-4)}
  .qg-lb-count{right:var(--space-4)}
}

/* ── Very narrow (iPhone SE, 320px) ────────────────────────────────────── */
@media (max-width:380px){
  :root{--qg-pad:16px}
  .qg-hero__title{font-size:34px}
  .qg-header__logo img{height:26px;width:51px}
  .qg-deck__card{flex-basis:84%}
  .qg-slat{width:116px}
  .qg-footer__grid{grid-template-columns:1fr}
  .qg-footer__brand{grid-column:span 1}
  .qg-drawer-link{font-size:12px}
}

/* ── Landscape phone: no room for a full-height hero or a tall drawer ──── */
@media (max-width:900px) and (orientation:landscape) and (max-height:520px){
  /* No room to stack: a 390px-tall screen cannot carry a 72% photograph and
     a copy block underneath. Revert to the desktop arrangement — image
     fills the stage, copy floats over the bottom. */
  .qg-hero__media{position:absolute;inset:0;height:auto}
  .qg-hero__copy{
    position:absolute;inset:0;justify-content:flex-end;
    padding:calc(var(--qg-header-h) + var(--space-4)) var(--qg-pad) var(--space-4);
  }
  .qg-hero__vignette{background:linear-gradient(to top, rgba(10,8,7,.92) 0%, rgba(10,8,7,.55) 34%, rgba(10,8,7,0) 66%)}
  .qg-hero__bar{bottom:0}
  .qg-hero__stage{min-height:0}
  .qg-hero__title{font-size:30px}
  .qg-hero__cta{margin-top:var(--space-2)}
  .qg-drawer{padding-top:var(--space-3)}
  .qg-drawer-top{margin-bottom:var(--space-4)}
  .qg-drawer-link{padding:10px 0;font-size:12px}
  .qg-drawer-label + .qg-drawer-label,
  .qg-drawer-link + .qg-drawer-label{margin-top:var(--space-4)}
  .col-hero{aspect-ratio:auto;min-height:80svh}
}

/* ── Reduced motion ────────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms;animation-iteration-count:1;transition-duration:.001ms}
  .reveal{opacity:1;transform:none}
  .qg-hero__kicker,.qg-hero__title{opacity:1;animation:none}
}

/* ── Print ─────────────────────────────────────────────────────────────── */
@media print{
  .qg-header,.qg-drawer,.qg-hero,.qg-vendors,.qg-lb,.qg-filter{display:none}
  body{background:#fff;color:#000}
  .qg-masonry{column-count:2}
}
