/* ============================================================
   COPYLAND ARCHIVE — STUDIO LAYOUT (test)
   Black gloss kept. Header, selection and project pages rebuilt
   to the reference layout.
   ============================================================ */
:root{
  --void:#050506; --deep:#0D0E10; --card:#101114;
  --bone:#F4F5F6; --soft:#C9CCD1; --muted:#8B9096; --dim:#63676D;
  --line:rgba(255,255,255,.14); --line-2:rgba(255,255,255,.08); --line-3:rgba(255,255,255,.045);
  --f-mark:"Syne","Helvetica Neue",Arial,sans-serif;
  --f-x:"Archivo","Helvetica Neue",Arial,sans-serif;   /* the gate's expanded face */
  --f-disp:"Outfit",-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;
  --f-mono:"IBM Plex Mono",ui-monospace,Consolas,monospace;
  --pad:clamp(20px,3.4vw,52px);
  --r:0px;            /* photos sit square - no rounded corners */
  color-scheme:dark;
}
*{box-sizing:border-box}
html{overflow-x:clip;scroll-behavior:smooth}
body{
  margin:0;min-height:100vh;color:var(--bone);font-family:var(--f-disp);font-weight:300;
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(255,255,255,.035), transparent 52%),
    var(--void);
  background-attachment:fixed;-webkit-font-smoothing:antialiased;
}
[hidden]{display:none!important}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;padding:0}
input{font:inherit;color:inherit}
img{display:block}
svg{display:block;flex:none}

/* ?plain turns every ambient layer off - a single switch for testing
   whether they are what makes a phone struggle with the grid. */
html.plain #field,html.plain #weave,html.plain #bloom{display:none!important}
html.plain .tile .shot::after,html.plain .frame::after{display:none!important}

/* ---------- atmosphere ---------- */
#field{position:fixed;inset:0;z-index:0;pointer-events:none;opacity:0;transition:opacity 1.6s ease;
  -webkit-mask-image:radial-gradient(130% 100% at 50% 40%,#000 28%,rgba(0,0,0,.4) 74%,transparent);
  mask-image:radial-gradient(130% 100% at 50% 40%,#000 28%,rgba(0,0,0,.4) 74%,transparent)}
html.ready #field{opacity:1}
#weave{position:fixed;inset:-20%;z-index:0;pointer-events:none;opacity:.28;
  background-image:repeating-linear-gradient(118deg,rgba(255,255,255,.030) 0 1px,transparent 1px 132px);
  animation:weave 60s linear infinite}
@keyframes weave{to{transform:translate3d(-132px,244px,0)}}
#bloom{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
#bloom i{position:absolute;inset:-25%;display:block;
  background:radial-gradient(40% 34% at 50% 16%,rgba(255,255,255,.035),transparent 70%);
  animation:bloom 28s ease-in-out infinite alternate}
@keyframes bloom{from{transform:translate3d(-5%,-3%,0) scale(1)}to{transform:translate3d(5%,4%,0) scale(1.14)}}
/* own compositor layers: without this the fixed backdrop is re-rastered
   during scroll, which reads as a flicker */
#field,#weave,#bloom{transform:translateZ(0);backface-visibility:hidden}

/* ---------- wordmark ---------- */
.mark{
  font-family:var(--f-mark);font-weight:800;letter-spacing:-.045em;line-height:.9;
  background:linear-gradient(176deg,#FFF 0%,#FAFAFB 24%,#9EA3AA 52%,#F2F3F5 68%,#6E737A 100%);
  background-size:100% 260%;-webkit-background-clip:text;background-clip:text;color:transparent;
  white-space:nowrap;animation:chrome 11s ease-in-out infinite alternate;
}
@keyframes chrome{from{background-position:50% 14%}to{background-position:50% 86%}}

/* ============================================================
   GATE  —  the opening scene
   Expanded grotesk, a stage floor running to a horizon, and a
   shutdown that collapses the whole picture into the line it
   opened from. Every moving part is a transform, so there is
   nothing to recompute frame by frame.
   ============================================================ */
#gate{position:fixed;inset:0;z-index:200;overflow:hidden;background:#020203}
.gstage{position:absolute;inset:0;overflow:hidden;isolation:isolate;
  transform-origin:50% 50%}

/* the site's own backdrop stays off until the gate is done with the screen */
html:not(.in) #field,html:not(.in) #weave,html:not(.in) #bloom{display:none}

/* ---------- the floor ---------- */
#gate .floor{position:absolute;left:-55%;right:-55%;bottom:0;height:72%;
  overflow:hidden;opacity:0;
  transform:perspective(900px) rotateX(64deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.6) 42%,transparent 84%);
  mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.6) 42%,transparent 84%)}
#gate .floor i{position:absolute;left:0;right:0;top:-90px;bottom:-90px;display:block;
  background-image:
    linear-gradient(to right,rgba(255,255,255,.175) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(255,255,255,.175) 1px,transparent 1px);
  background-size:90px 90px;animation:drive 2.6s linear infinite}
@keyframes drive{to{transform:translate3d(0,90px,0)}}

/* ---------- a searchlight turning overhead ---------- */
#gate .beam{position:absolute;inset:0;pointer-events:none;opacity:0}
#gate .beam i{position:absolute;inset:-70%;display:block;
  background:conic-gradient(from 0deg at 50% 50%,
    transparent 0deg,rgba(255,255,255,.055) 16deg,transparent 44deg,
    transparent 168deg,rgba(255,255,255,.04) 184deg,transparent 214deg);
  animation:turn 30s linear infinite}
@keyframes turn{to{transform:rotate(360deg)}}

#gdust{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity 1.4s ease}

/* grain: rasterised once, then only ever moved */
#gate .grain{position:absolute;inset:-160px;pointer-events:none;opacity:0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 1.1s steps(1) infinite}
@keyframes grain{
  0%{transform:translate3d(0,0,0)}        14%{transform:translate3d(-32px,18px,0)}
  28%{transform:translate3d(24px,-26px,0)}42%{transform:translate3d(-18px,-14px,0)}
  56%{transform:translate3d(30px,22px,0)} 70%{transform:translate3d(-26px,28px,0)}
  84%{transform:translate3d(16px,-20px,0)}100%{transform:translate3d(0,0,0)}}

/* a light passing down the room */
#gate .scan{position:absolute;left:-10%;right:-10%;height:34vh;top:-40vh;pointer-events:none;
  background:linear-gradient(to bottom,transparent,rgba(255,255,255,.045) 46%,rgba(255,255,255,.07) 50%,rgba(255,255,255,.045) 54%,transparent);
  animation:pass 11s cubic-bezier(.5,0,.5,1) 4s infinite}
@keyframes pass{0%{transform:translate3d(0,0,0)}55%,100%{transform:translate3d(0,180vh,0)}}

#gate .shaft{position:absolute;left:50%;top:-14%;width:min(1180px,128vw);height:128%;
  margin-left:min(-590px,-64vw);pointer-events:none;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.028) 26%,rgba(255,255,255,.05) 50%,rgba(255,255,255,.028) 74%,transparent);
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 22%,#000 58%,transparent 94%);
  mask-image:linear-gradient(to bottom,transparent,#000 22%,#000 58%,transparent 94%)}
#gate .vig{position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(118% 82% at 50% 40%,transparent 44%,rgba(0,0,0,.6) 100%),
    radial-gradient(60% 40% at 50% 8%,rgba(255,255,255,.05),transparent 70%)}

/* ---------- the core ---------- */
#gate .core{position:absolute;inset:0;z-index:4;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:calc(40px + env(safe-area-inset-top)) clamp(18px,4.4vw,56px)
          calc(52px + env(safe-area-inset-bottom)) clamp(18px,4.4vw,56px)}

#gate .status{display:flex;align-items:center;gap:9px;opacity:0;
  font-family:var(--f-mono);font-size:9.5px;letter-spacing:.44em;text-indent:.44em;
  text-transform:uppercase;color:var(--muted);margin-bottom:clamp(20px,3.4vw,30px)}
#gate .status i{width:5px;height:5px;border-radius:50%;background:#FF3A2F;flex:none;
  box-shadow:0 0 0 0 rgba(255,58,47,.55);animation:live 2.1s ease-out infinite}
@keyframes live{
  0%{box-shadow:0 0 0 0 rgba(255,58,47,.5);opacity:1}
  70%{box-shadow:0 0 0 7px rgba(255,58,47,0);opacity:.75}
  100%{box-shadow:0 0 0 0 rgba(255,58,47,0);opacity:1}}

/* the wordmark — four stacked copies: chrome, two fringes, one sweep */
#gate .markwrap{position:relative;width:100%;max-width:1080px;display:flex;justify-content:center}
.gmark{position:relative;margin:0;display:block;line-height:.86;
  font-family:var(--f-x);font-weight:900;font-stretch:125%;
  font-size:64px;letter-spacing:-.012em;white-space:nowrap;
  clip-path:inset(0 100% 0 0)}
.gmark .lay{display:block;position:relative;z-index:1;
  -webkit-background-clip:text;background-clip:text;color:transparent}
.gmark .lay:not(.base){position:absolute;inset:0}
.gmark .sweep{z-index:2}
.gmark .base{background-image:linear-gradient(178deg,#FFF 0%,#F4F5F7 22%,#8E939A 49%,#FDFDFE 62%,#6A6F76 82%,#B9BDC3 100%);
  background-size:100% 240%;animation:gchrome 9s ease-in-out infinite alternate}
@keyframes gchrome{from{background-position:50% 12%}to{background-position:50% 88%}}
/* the fringes sit on black, so normal compositing looks the same as screen
   and costs a phone nothing to blend */
.gmark .red{background-image:linear-gradient(0deg,#FF4A3A,#FF4A3A);opacity:.24;
  transform:translate3d(-1.5px,0,0);z-index:-1}
.gmark .cyan{background-image:linear-gradient(0deg,#3AD8FF,#3AD8FF);opacity:.2;
  transform:translate3d(1.5px,0,0);z-index:-1}
.gmark .sweep{background-image:linear-gradient(96deg,transparent 40%,rgba(255,255,255,.95) 49%,rgba(255,255,255,.95) 51%,transparent 60%);
  background-size:280% 100%;mix-blend-mode:screen;
  animation:gsweep 7.5s cubic-bezier(.62,0,.3,1) 3.2s infinite}
@keyframes gsweep{0%{background-position:170% 0}34%,100%{background-position:-70% 0}}
/* the bar that draws the wordmark on */
#gate .edge{position:absolute;top:-4%;bottom:-4%;width:2px;left:0;opacity:0;
  background:linear-gradient(to bottom,transparent,#FFF 14%,#FFF 86%,transparent);
  box-shadow:0 0 22px 5px rgba(255,255,255,.5)}
#gate .ring{position:absolute;left:50%;top:50%;width:52px;height:52px;margin:-26px 0 0 -26px;
  border:1px solid rgba(255,255,255,.5);border-radius:50%;opacity:0;pointer-events:none}

.grule{width:100%;max-width:1080px;height:1px;
  margin:clamp(20px,3vw,30px) 0 clamp(15px,2.2vw,21px);
  background:linear-gradient(90deg,transparent,var(--line) 12%,var(--line) 88%,transparent);
  transform:scaleX(0);transform-origin:50% 50%}
#gate .meta{display:flex;align-items:center;gap:clamp(9px,1.8vw,16px);opacity:0;flex-wrap:wrap;
  justify-content:center;font-family:var(--f-mono);font-size:clamp(9px,2.1vw,10.5px);
  letter-spacing:.3em;text-indent:.3em;text-transform:uppercase;color:var(--muted);text-align:center}
#gate .meta b{width:3px;height:3px;border-radius:50%;background:rgba(255,255,255,.26);flex:none}

/* ---------- the entry ---------- */
#gate .entry{width:100%;max-width:400px;margin-top:clamp(34px,5.6vw,58px);opacity:0}
#gate .entry label{display:block;font-family:var(--f-mono);font-size:9px;letter-spacing:.42em;
  text-indent:.42em;text-transform:uppercase;color:var(--dim);text-align:center;margin-bottom:12px}
#gate .field{position:relative}
/* 16px minimum: iOS Safari zooms the page in on any input smaller than this
   and never zooms back out, which left the whole site off-centre after
   entering the code. */
#code{width:100%;background:transparent;border:0;outline:none;text-align:center;
  font-family:var(--f-mono);font-weight:500;font-size:16px;letter-spacing:.42em;text-indent:.42em;
  text-transform:uppercase;padding:13px 4px 15px;caret-color:#FF3A2F}
#code::placeholder{color:#3D4147;letter-spacing:.42em}
#gate .uline{position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--line)}
#gate .uline::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,transparent,#FFF,transparent);
  transform:scaleX(0);transition:transform .45s cubic-bezier(.16,1,.3,1)}
#code:focus~.uline::after{transform:scaleX(1)}
#err{height:15px;margin-top:9px;text-align:center;font-family:var(--f-mono);font-size:9.5px;
  letter-spacing:.24em;text-indent:.24em;text-transform:uppercase;color:#FF3A2F;opacity:0;
  transition:opacity .2s}
#err.on{opacity:1}

#gate .go{position:relative;overflow:hidden;width:100%;margin-top:14px;display:block;
  border:1px solid rgba(255,255,255,.34);background:rgba(255,255,255,.015);
  padding:17px 22px;color:var(--bone);
  transition:border-color .3s ease,transform .16s cubic-bezier(.3,1.4,.4,1)}
#gate .go span{position:relative;z-index:2;display:flex;align-items:center;justify-content:center;gap:12px;
  font-family:var(--f-x);font-weight:900;font-stretch:112%;font-size:11.5px;
  letter-spacing:.3em;text-indent:.3em;text-transform:uppercase;transition:color .32s ease}
#gate .go svg{flex:none;transition:transform .32s cubic-bezier(.16,1,.3,1)}
#gate .go::before{content:"";position:absolute;inset:0;background:#FBFBFC;
  transform:translate3d(-101%,0,0);transition:transform .42s cubic-bezier(.16,1,.3,1)}
#gate .go:hover{border-color:#FFF}
#gate .go:hover::before{transform:translate3d(0,0,0)}
#gate .go:hover span{color:#08080A}
#gate .go:hover svg{transform:translate3d(5px,0,0)}
#gate .go:active{transform:scale(.985)}
#gate .go.fire::before{transform:translate3d(0,0,0);transition-duration:.13s}
#gate .go.fire span{color:#08080A;transition-duration:.13s}
@media (hover:none){
  #gate .go{border-color:rgba(255,255,255,.5)}
  #gate .go:active::before{transform:translate3d(0,0,0);transition-duration:.18s}
  #gate .go:active span{color:#08080A}
}

/* If scripting fails, index.html adds .up after 2.5s and the scene simply
   appears. When scripting works the opening animations hold their own end
   state, so these rules never fight them. */
html.up #gate .floor,html.up #gate .beam,html.up #gate .shaft,
html.up #gate .status,html.up #gate .meta,html.up #gate .entry{opacity:1}
html.up .gmark{clip-path:inset(0 0 0 0)}
html.up .grule{transform:scaleX(1)}

/* ---------- the opening line, and the doors it becomes ---------- */
#gate .boot{position:absolute;left:0;right:0;top:50%;height:4px;margin-top:-2px;z-index:9;
  background:linear-gradient(to bottom,transparent,#FFF 38%,#FFF 62%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  transform:scaleX(0)}
.seamline{position:fixed;left:0;right:0;top:50%;height:3px;margin-top:-1.5px;z-index:220;
  opacity:0;pointer-events:none;
  background:linear-gradient(90deg,transparent,#FFF 7%,#FFF 93%,transparent);
  box-shadow:0 0 26px 6px rgba(255,255,255,.45)}

@media (max-width:640px){
  #gate .core{padding-top:calc(34px + env(safe-area-inset-top));
              padding-bottom:calc(42px + env(safe-area-inset-bottom))}
  .grule{margin:22px 0 15px}
  #gate .floor{height:58%}
}

/* ------------------------------------------------------------------
   PHONE LAYER BUDGET
   Measured on a 393x852 screen at 3x, the lock screen was holding about
   139MB of continuously animating compositor layers - and 66MB of that
   was the searchlight alone, because inset:-70% makes it 2.4x the
   viewport in BOTH directions and it never stops turning. All of it is
   still on the GPU while the archive is being built and while its first
   tiles need to rasterise, which is why the first few products were
   always the slow ones.
   The searchlight and the grain are the two nobody can really see on a
   phone, and they are the two biggest. They come off, and the shaft is
   cut to the screen. That is ~95MB back.
   ------------------------------------------------------------------ */
@media (pointer:coarse),(max-width:640px){
  #gate .beam,#gate .grain{display:none!important}
  #gate .shaft{width:100vw;margin-left:-50vw;top:0;height:100%}
}

/* ------------------------------------------------------------------
   LIVE BLUR OVER THE GRID
   .head is sticky and carries backdrop-filter:blur(18px) - a blur that
   is recomputed from whatever is behind it, sitting permanently over
   the TOP of the archive. On iOS that pins the content behind it into
   its own layer and re-blurs it every time anything there changes, so
   the tiles nearest the header are the slowest to settle. That is the
   "only the top few products" everyone keeps seeing.
   On a near-black page an opaque bar is indistinguishable from a
   blurred one, so phones get the bar.
   ------------------------------------------------------------------ */
@media (pointer:coarse),(max-width:760px){
  .head{background:rgba(6,6,8,.97);
    backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
  .frame .stamp,.frame .grow{
    background:rgba(8,8,10,.88);
    backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
}
@media (prefers-reduced-motion:reduce){
  #gate .floor i,#gate .beam i,#gate .grain,#gate .scan,
  .gmark .base,.gmark .sweep,#gate .status i{animation:none!important}
  #gate .scan{display:none}
}

/* ============================================================
   START A PROJECT
   ============================================================ */
#ask{position:fixed;inset:0;z-index:300;display:flex;align-items:center;justify-content:center;
  padding:clamp(14px,3vw,40px)}
.ask-back{position:absolute;inset:0;background:rgba(3,3,4,.82);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.ask-panel{position:relative;width:100%;max-width:620px;max-height:100%;overflow:auto;
  -webkit-overflow-scrolling:touch;
  background:#0B0C0E;border:1px solid var(--line-2);
  padding:clamp(24px,3.6vw,44px);
  box-shadow:0 60px 120px -50px #000}
.ask-x{position:absolute;top:14px;right:14px;width:38px;height:38px;display:grid;place-items:center;
  color:var(--muted);border:1px solid transparent;transition:color .2s,border-color .2s}
.ask-x:hover{color:var(--bone);border-color:var(--line-2)}

.ask-kicker{display:block;font-family:var(--f-mono);font-size:9.5px;letter-spacing:.42em;
  text-indent:.42em;text-transform:uppercase;color:var(--dim);margin-bottom:14px}
.ask-head h2{margin:0;font-family:var(--f-disp);font-weight:300;
  font-size:clamp(22px,3.4vw,31px);letter-spacing:-.01em;line-height:1.14}
.ask-sub{margin:10px 0 0;color:var(--muted);font-size:14.5px}

#ask-form{margin-top:clamp(22px,3vw,32px);display:flex;flex-direction:column;gap:18px}
.fld{display:block}
.fld-row{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.lab{display:block;font-family:var(--f-mono);font-size:9.5px;letter-spacing:.3em;text-indent:.3em;
  text-transform:uppercase;color:var(--muted);margin-bottom:9px}
.lab i{color:#FF3A2F;font-style:normal}
/* 16px minimum or iOS Safari zooms the page and never zooms back */
.fld input,.fld textarea{width:100%;background:rgba(255,255,255,.028);color:var(--bone);
  border:1px solid var(--line-2);border-radius:0;padding:13px 14px;font-size:16px;
  font-family:var(--f-disp);font-weight:300;outline:none;
  transition:border-color .25s ease,background .25s ease}
.fld textarea{resize:vertical;min-height:104px;line-height:1.5}
.fld input:focus,.fld textarea:focus{border-color:rgba(255,255,255,.44);background:rgba(255,255,255,.05)}
.fld.bad input,.fld.bad textarea,.fld.bad .qty{border-color:#FF3A2F}
.msg{display:block;min-height:0;font-family:var(--f-mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:#FF3A2F;opacity:0;transition:opacity .2s}
.fld.bad .msg{opacity:1;min-height:14px;margin-top:7px}

.qty{display:flex;flex-wrap:wrap;gap:8px}
.qty button{border:1px solid var(--line-2);padding:11px 14px;color:var(--soft);
  font-family:var(--f-mono);font-size:11px;letter-spacing:.1em;
  transition:color .2s,border-color .2s,background .2s}
.qty button:hover{color:var(--bone);border-color:rgba(255,255,255,.34)}
.qty button[aria-pressed="true"]{background:#F4F5F6;border-color:#F4F5F6;color:#08080A}

#f-hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}

.ask-go{position:relative;overflow:hidden;width:100%;margin-top:4px;display:block;
  border:1px solid rgba(255,255,255,.34);background:rgba(255,255,255,.015);padding:17px 22px;
  color:var(--bone);transition:border-color .3s ease,transform .16s cubic-bezier(.3,1.4,.4,1),opacity .2s}
.ask-go span{position:relative;z-index:2;display:flex;align-items:center;justify-content:center;gap:12px;
  font-family:var(--f-x);font-weight:900;font-stretch:112%;font-size:11.5px;letter-spacing:.3em;
  text-indent:.3em;text-transform:uppercase;transition:color .32s ease}
.ask-go svg{flex:none;transition:transform .32s cubic-bezier(.16,1,.3,1)}
.ask-go::before{content:"";position:absolute;inset:0;background:#FBFBFC;
  transform:translate3d(-101%,0,0);transition:transform .42s cubic-bezier(.16,1,.3,1)}
.ask-go:hover{border-color:#FFF}
.ask-go:hover::before{transform:translate3d(0,0,0)}
.ask-go:hover span{color:#08080A}
.ask-go:hover svg{transform:translate3d(5px,0,0)}
.ask-go:active{transform:scale(.99)}
.ask-go[disabled]{opacity:.55;pointer-events:none}
@media (hover:none){
  .ask-go:active::before{transform:translate3d(0,0,0);transition-duration:.18s}
  .ask-go:active span{color:#08080A}
}
.ask-note{margin:0;text-align:center;font-family:var(--f-mono);font-size:9.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--dim);min-height:13px}
.ask-note.bad{color:#FF3A2F}

.ask-done{text-align:center;padding:clamp(18px,3vw,30px) 0}
.ask-done .tick{width:58px;height:58px;margin:0 auto 20px;display:grid;place-items:center;
  border:1px solid rgba(255,255,255,.3);border-radius:50%;color:var(--bone)}
.ask-done h3{margin:0;font-family:var(--f-disp);font-weight:300;font-size:clamp(20px,3vw,26px)}
.ask-done p{margin:10px auto 24px;max-width:38ch;color:var(--muted);font-size:14.5px;line-height:1.55}
.ask-again{border:1px solid var(--line-2);padding:13px 22px;color:var(--soft);
  font-family:var(--f-mono);font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;
  transition:color .2s,border-color .2s}
.ask-again:hover{color:var(--bone);border-color:rgba(255,255,255,.34)}

@media (max-width:560px){
  #ask{padding:0}
  .ask-panel{max-width:none;height:100%;max-height:none;border:0;
    padding:calc(26px + env(safe-area-inset-top)) 20px calc(26px + env(safe-area-inset-bottom))}
  .fld-row{grid-template-columns:1fr}
}

/* ============================================================
   SHELL
   ============================================================ */
#shell{position:relative;z-index:5}
.wrap{max-width:1460px;margin:0 auto;padding:0 var(--pad)}

/* ---------- header ---------- */
.head{position:sticky;top:0;z-index:60;background:rgba(6,6,8,.82);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border-bottom:1px solid var(--line-3)}
.head .wrap{display:flex;align-items:center;gap:clamp(12px,1.6vw,22px);
  padding-top:clamp(16px,2vw,26px);padding-bottom:clamp(16px,2vw,26px)}
.head .mark{font-size:clamp(22px,2.9vw,40px)}
.head .vr{width:1px;height:clamp(20px,2.4vw,32px);background:var(--line);flex:none}
.head .tag{font-family:var(--f-mono);font-size:clamp(9px,1vw,11px);letter-spacing:.34em;
  text-transform:uppercase;color:var(--muted)}
.sp{flex:1}
.cta{display:inline-flex;align-items:center;gap:10px;border-radius:8px;padding:13px 18px;
  background:#fff;color:#0A0A0C;font-size:15px;font-weight:400;white-space:nowrap;
  transition:transform .2s cubic-bezier(.2,.8,.3,1),box-shadow .3s ease}
.cta:hover{transform:translateY(-1px);box-shadow:0 14px 34px -18px rgba(255,255,255,.7)}
.cta:active{transform:translateY(0) scale(.98)}
.ghost{display:inline-flex;align-items:center;gap:9px;font-size:15px;color:var(--soft);
  padding:13px 6px;transition:color .25s}
.ghost:hover{color:#fff}

/* ---------- toolbar ---------- */
.toolbar{padding-top:clamp(26px,3.4vw,44px)}
.searchrow{display:flex;align-items:center;gap:14px;padding-bottom:18px;border-bottom:1px solid var(--line-3)}
.searchrow .mag{color:var(--muted)}
#q{flex:1;min-width:0;background:transparent;border:0;outline:none;font-size:clamp(16px,1.5vw,18px);
  font-weight:300;color:var(--bone);padding:8px 0}
#q::placeholder{color:var(--dim)}
kbd.slash{font-family:var(--f-mono);font-size:12px;color:var(--muted);border:1px solid var(--line-2);
  border-radius:6px;padding:5px 11px;line-height:1}
.seg{display:flex;gap:4px;border:1px solid var(--line-2);border-radius:9px;padding:4px;flex:none}
.seg button{border-radius:6px;padding:9px 18px;font-size:14px;color:var(--muted);white-space:nowrap;
  transition:color .25s,background .25s}
.seg button[aria-pressed="true"]{background:#F2F3F5;color:#0A0A0C}

.filterrow{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:20px 0}
.sel{position:relative;flex:none}
.sel > button{display:inline-flex;align-items:center;gap:14px;border:1px solid var(--line-2);
  border-radius:9px;padding:13px 16px;font-size:15px;color:var(--soft);min-width:190px;
  justify-content:space-between;transition:border-color .25s,background .25s,color .25s}
.sel > button:hover{border-color:var(--line);background:rgba(255,255,255,.04);color:#fff}
.sel.open > button{border-color:var(--line);background:rgba(255,255,255,.05);color:#fff}
.sel .chev{transition:transform .3s cubic-bezier(.2,.8,.3,1)}
.sel.open .chev{transform:rotate(180deg)}
.menu{position:absolute;top:calc(100% + 8px);left:0;z-index:70;min-width:100%;max-height:310px;
  overflow:auto;border:1px solid var(--line-2);border-radius:10px;padding:6px;
  background:rgba(14,15,18,.97);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  box-shadow:0 30px 60px -28px rgba(0,0,0,.95);
  opacity:0;transform:translateY(-6px) scale(.985);pointer-events:none;
  transition:opacity .22s ease,transform .28s cubic-bezier(.2,.8,.3,1)}
.sel.open .menu{opacity:1;transform:none;pointer-events:auto}
.menu button{display:flex;width:100%;align-items:center;gap:12px;justify-content:space-between;
  border-radius:7px;padding:10px 12px;font-size:14px;color:var(--soft);text-align:left;
  white-space:nowrap;transition:background .18s,color .18s}
.menu button:hover{background:rgba(255,255,255,.07);color:#fff}
.menu button[aria-pressed="true"]{background:rgba(255,255,255,.12);color:#fff}
.menu button .n{font-family:var(--f-mono);font-size:11px;color:var(--dim)}
.tally{font-family:var(--f-mono);font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim)}

.chips{display:flex;flex-wrap:wrap;gap:10px;padding-bottom:clamp(26px,3.4vw,42px)}
.chip{display:inline-flex;align-items:center;gap:10px;border:1px solid var(--line-2);border-radius:9px;
  padding:12px 16px;font-size:14px;color:var(--soft);position:relative;overflow:hidden;
  transition:border-color .25s,background .25s,color .25s,transform .2s cubic-bezier(.2,.8,.3,1)}
.chip:hover{border-color:var(--line);background:rgba(255,255,255,.05);color:#fff}
.chip:active{transform:scale(.96)}
.chip[aria-pressed="true"]{background:#F2F3F5;border-color:#F2F3F5;color:#0A0A0C}
.chip .n{font-family:var(--f-mono);font-size:11px;color:var(--dim)}
.chip[aria-pressed="true"] .n{color:rgba(10,10,12,.55)}
.chip::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(104deg,transparent 38%,rgba(255,255,255,.26) 50%,transparent 62%);
  transform:translateX(-110%)}
.chip:hover::after{opacity:1;animation:btnsheen .7s cubic-bezier(.3,0,.2,1)}
@keyframes btnsheen{to{transform:translateX(110%)}}

/* ---------- grid ---------- */
.grid{display:grid;gap:clamp(18px,2.2vw,30px);grid-template-columns:repeat(auto-fill,minmax(290px,1fr));
  padding-bottom:clamp(40px,5vw,80px)}
/* A tile is VISIBLE by default. It used to start at opacity:0 and wait for
   JavaScript to reveal it, which meant any hiccup - or simply scrolling
   faster than the observer could keep up - left blank squares on screen.
   Entrance animations are now applied deliberately (on unlock, and when the
   filters change) instead of being a precondition for being seen at all.
   Scrolling triggers no work of any kind. */
.tile{display:flex;flex-direction:column;gap:14px;text-align:left;width:100%}
.shot{position:relative;display:block;width:100%;aspect-ratio:4/3;overflow:hidden;
  border-radius:var(--r);background:var(--card);
  transition:transform .2s cubic-bezier(.2,.8,.3,1),box-shadow .35s ease}
.shot img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s cubic-bezier(.19,1,.22,1)}
.tile:hover .shot img{transform:scale(1.045)}
.tile:hover .shot{box-shadow:0 30px 58px -32px rgba(0,0,0,.96)}
/* a flare travels across the photo when you point at it.
   inset is oversized so the band enters and leaves off-frame; .shot clips it. */
.shot::after{content:"";position:absolute;inset:-30% -55%;z-index:3;pointer-events:none;opacity:0;
  background:linear-gradient(104deg,transparent 32%,rgba(255,255,255,.10) 42%,
    rgba(255,255,255,.26) 50%,rgba(255,255,255,.10) 58%,transparent 68%);
  transform:translateX(-84%)}
.tile:hover .shot::after{animation:flare 3.6s linear infinite}

/* A slow, even glide across the photo, then a rest before it comes round
   again. Every keyframe carries a transform and the travel is spaced to match
   the time, so the band moves at one constant speed with no hitch - easing
   here would restart at each keyframe and stutter mid-sweep. */
@keyframes flare{
  0%{transform:translateX(-96%);opacity:0}
  9%{transform:translateX(-60%);opacity:1}
  48%{transform:translateX(96%);opacity:1}
  57%{transform:translateX(96%);opacity:0}
  100%{transform:translateX(96%);opacity:0}
}
.shot::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;opacity:0;
  border-radius:var(--r);transition:opacity .3s ease;
  background:radial-gradient(30% 42% at var(--mx,50%) var(--my,50%),rgba(255,255,255,.2),transparent 72%)}
.tile:hover .shot::before{opacity:1}
.tile .who{font-family:var(--f-mono);font-size:12.5px;letter-spacing:.17em;text-transform:uppercase;
  color:var(--bone);transition:color .25s}
.tile .what{font-size:17px;font-weight:300;color:var(--muted);line-height:1.35;transition:color .25s}
.tile:hover .what{color:var(--soft)}
.groupwrap{padding-bottom:10px}
.grouphead{display:flex;align-items:baseline;gap:18px;padding:22px 0 18px}
.grouphead h2{margin:0;font-size:clamp(20px,2.2vw,28px);font-weight:300;letter-spacing:-.01em}
.grouphead .ln{flex:1;height:1px;background:var(--line-3)}
.grouphead .n{font-family:var(--f-mono);font-size:11px;letter-spacing:.2em;color:var(--dim);text-transform:uppercase}
.none{padding:80px 0;font-family:var(--f-mono);font-size:13px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--dim)}

/* ============================================================
   PROJECT
   ============================================================ */
.crumb{display:flex;align-items:center;gap:16px;padding:clamp(20px,2.6vw,34px) 0}
.crumb .back{display:inline-flex;align-items:center;gap:12px;font-size:16px;color:var(--soft);
  transition:color .25s,gap .25s}
.crumb .back:hover{color:#fff;gap:16px}
.crumb .idx{font-family:var(--f-mono);font-size:12px;letter-spacing:.22em;text-transform:uppercase;color:var(--dim)}

.snum{font-family:var(--f-mono);font-size:12px;letter-spacing:.24em;text-transform:uppercase;
  color:var(--dim);margin-bottom:18px}
.snum b{color:var(--soft);font-weight:400}

.frame{position:relative;border-radius:var(--r);overflow:hidden;background:var(--card);cursor:zoom-in}
.frame img{width:100%;height:auto}
.frame.cover{aspect-ratio:16/10}
.frame.cover img{height:100%;object-fit:cover}
/* same flare on the cover, the spread and the process shots */
.frame::after{content:"";position:absolute;inset:-45% -70%;z-index:1;pointer-events:none;opacity:0;
  background:linear-gradient(104deg,transparent 34%,rgba(255,255,255,.07) 43%,
    rgba(255,255,255,.18) 50%,rgba(255,255,255,.07) 57%,transparent 66%);
  transform:translateX(-84%)}
.frame:hover::after{animation:flare 4.4s linear infinite}
.frame img{transition:transform 1.2s cubic-bezier(.19,1,.22,1)}
.frame:hover img{transform:scale(1.02)}
.frame .stamp{position:absolute;left:18px;bottom:18px;z-index:2;
  font-family:var(--f-mono);font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--bone);
  background:rgba(8,8,10,.62);border:1px solid rgba(255,255,255,.18);border-radius:8px;padding:10px 14px;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.frame .grow{position:absolute;right:18px;bottom:18px;z-index:2;display:grid;place-items:center;
  width:46px;height:46px;border:1px solid rgba(255,255,255,.2);border-radius:9px;color:var(--bone);
  background:rgba(8,8,10,.5);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  transition:background .25s,transform .2s cubic-bezier(.2,.8,.3,1),border-color .25s}
.frame .grow:hover{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.4);transform:scale(1.06)}

.pcat{display:inline-flex;align-items:center;border:1px solid var(--line-2);border-radius:8px;
  padding:10px 15px;margin:22px 0 0;font-family:var(--f-mono);font-size:11px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--soft)}
.ptitle{margin:20px 0 0;font-size:clamp(30px,5vw,58px);font-weight:300;letter-spacing:-.025em;line-height:1.02}
.psub{margin:12px 0 0;font-size:clamp(17px,2vw,24px);font-weight:300;color:var(--muted)}

.cols{display:grid;grid-template-columns:minmax(0,1.04fr) minmax(0,1fr);
  gap:clamp(28px,4.4vw,72px);padding:clamp(40px,5vw,78px) 0 0;align-items:start}
.story{margin:0;font-size:clamp(17px,1.45vw,21px);line-height:1.72;font-weight:300;color:#DCDEE2}
.specs{margin-top:clamp(30px,3.6vw,48px)}
.spec{display:flex;align-items:baseline;gap:20px;justify-content:space-between;
  padding:20px 0;border-top:1px solid var(--line-3)}
.spec .k{font-size:15px;color:var(--muted);font-weight:300}
.spec .v{font-size:15px;color:var(--bone);text-align:right}

.gal{display:grid;gap:clamp(14px,1.6vw,22px);grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
/* ============================================================
   SWIPE DECK - products with several shots put them all in the
   catalog slot, one at a time, swipeable.
   ============================================================ */
.deck{position:relative;touch-action:pan-y;user-select:none;-webkit-user-select:none}
.deck-win{position:relative;overflow:hidden;background:var(--card)}
.deck-track{display:flex;align-items:flex-start;will-change:transform}
.deck-track.glide{transition:transform .62s cubic-bezier(.16,1,.3,1)}
.slide{flex:0 0 100%;display:block;width:100%;padding:0;cursor:zoom-in;position:relative}
.slide img{width:100%;height:auto;display:block;pointer-events:none}
.deck.dragging .slide{cursor:grabbing}

/* the flare sweeps the deck the same way it sweeps any other photo */
.deck-win::after{content:"";position:absolute;inset:-45% -70%;z-index:2;pointer-events:none;opacity:0;
  background:linear-gradient(104deg,transparent 34%,rgba(255,255,255,.07) 43%,
    rgba(255,255,255,.18) 50%,rgba(255,255,255,.07) 57%,transparent 66%);
  transform:translateX(-84%)}
.deck:hover .deck-win::after{animation:flare 4.4s linear infinite}
.deck-win.lit::after{animation:flare 4.2s linear var(--fd,0s) infinite}

.deck-arw{position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  display:grid;place-items:center;width:48px;height:48px;border-radius:50%;
  color:var(--bone);background:rgba(8,8,10,.55);border:1px solid rgba(255,255,255,.18);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);opacity:0;
  transition:opacity .28s ease,background .25s ease,transform .25s cubic-bezier(.2,.8,.3,1)}
.deck-arw.prev{left:16px} .deck-arw.next{right:16px}
.deck:hover .deck-arw{opacity:1}
.deck-arw:hover{background:rgba(255,255,255,.16)}
.deck-arw.prev:hover{transform:translateY(-50%) translateX(-3px)}
.deck-arw.next:hover{transform:translateY(-50%) translateX(3px)}
.deck-arw[disabled]{opacity:0!important;pointer-events:none}
@media (pointer:coarse){.deck-arw{display:none}}

.deck-foot{display:flex;align-items:flex-start;gap:20px;justify-content:space-between;
  padding:16px 2px 0}
.deck-cap{min-width:0}
.deck-cap .dl{display:block;font-family:var(--f-mono);font-size:11px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--soft)}
.deck-cap .dd{display:block;font-size:14px;line-height:1.55;color:var(--muted);margin-top:6px;
  max-width:52ch}
.dots{display:flex;gap:7px;flex:none;padding-top:3px}
.dot{width:26px;height:3px;border-radius:2px;background:rgba(255,255,255,.18);
  transition:background .3s ease,width .35s cubic-bezier(.2,.8,.3,1)}
.dot[aria-current="true"]{background:var(--bone);width:34px}
.dot:hover{background:rgba(255,255,255,.45)}
@media (max-width:760px){
  .deck-foot{flex-direction:column;gap:12px}
  .dots{padding-top:0}
  .dot{width:22px}
  .dot[aria-current="true"]{width:30px}
}

/* ---------- lightbox gallery ---------- */
.box-arw{position:absolute;top:50%;transform:translateY(-50%);z-index:4;
  display:grid;place-items:center;width:52px;height:52px;border-radius:50%;
  color:var(--bone);background:rgba(20,20,24,.7);border:1px solid rgba(255,255,255,.2);
  transition:background .25s ease}
.box-arw.prev{left:clamp(10px,2vw,28px)} .box-arw.next{right:clamp(10px,2vw,28px)}
.box-arw:hover{background:rgba(255,255,255,.18)}
.box-arw[hidden]{display:none}
.boxstage{position:relative}
@media (pointer:coarse){.box-arw{width:44px;height:44px}}

.vers{display:grid;gap:clamp(18px,2.2vw,30px);grid-template-columns:repeat(auto-fill,minmax(265px,1fr))}
.vcard{display:flex;flex-direction:column;gap:12px;min-width:0}
.vlab{font-family:var(--f-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--soft)}
.vdesc{font-size:14px;line-height:1.55;color:var(--muted);margin-top:-5px}
.psec{padding:clamp(40px,5vw,78px) 0 0}

/* Picked Up By - only rendered for products that actually have press */
.pressrow{display:flex;align-items:baseline;gap:20px;justify-content:space-between;
  padding:20px 0;border-top:1px solid var(--line-3)}
.pressrow:last-child{border-bottom:1px solid var(--line-3)}
.pressrow .who{font-size:16px;color:var(--bone);min-width:0}
.pressrow .what{font-size:15px;color:var(--muted);text-align:right;min-width:0}

.pager{display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:center;
  margin-top:clamp(46px,6vw,90px);padding:clamp(34px,4.4vw,60px) 0;
  border-top:1px solid var(--line-3);border-bottom:1px solid var(--line-3)}
.pnav{display:flex;align-items:center;gap:22px;text-align:left;min-width:0}
.pnav.next{justify-content:flex-end;text-align:right}
.pnav .arw{display:grid;place-items:center;width:44px;height:44px;flex:none;color:var(--soft);
  transition:transform .3s cubic-bezier(.2,.8,.3,1),color .25s}
.pnav:hover .arw{color:#fff}
.pnav.prev:hover .arw{transform:translateX(-7px)}
.pnav.next:hover .arw{transform:translateX(7px)}
.pnav .lab{display:block;font-family:var(--f-mono);font-size:11px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--dim)}
.pnav .nm{display:block;font-size:clamp(20px,2.7vw,34px);font-weight:300;letter-spacing:-.02em;
  color:var(--bone);margin-top:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transition:color .25s}
.pnav:hover .nm{color:#fff}
.pnav .col{display:flex;flex-direction:column;min-width:0}

/* ---------- footer ---------- */
.foot .wrap{display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  padding-top:clamp(28px,3.4vw,46px);padding-bottom:clamp(34px,4vw,56px)}
.foot .mark{font-size:clamp(28px,4.4vw,56px)}
.foot .fbtn{display:inline-flex;align-items:center;gap:10px;font-size:15px;font-weight:300;
  color:var(--muted);transition:color .25s}
.foot #totop{font-family:var(--f-mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase}
.foot .fbtn:hover{color:#fff}

/* ---------- lightbox ---------- */
#box{position:fixed;inset:0;z-index:200;background:rgba(4,4,5,.97);display:none;
  flex-direction:column;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
#box.on{display:flex}
.boxtop{display:flex;align-items:center;gap:16px;padding:18px var(--pad);border-bottom:1px solid var(--line-3)}
.boxtop .c{font-family:var(--f-mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)}
.boxstage{flex:1;display:grid;place-items:center;padding:22px var(--pad);min-height:0}
.boxstage img{max-width:100%;max-height:100%;object-fit:contain}

/* ---------- the photo in flight ---------- */
/* #flip is built entirely in JS now and animates transform only.
   will-change:width,height was actively harmful here - it forced a fresh
   raster at a new size on every frame. */
#flip{backface-visibility:hidden}

/* ---------- toast ---------- */
#toast{position:fixed;left:50%;bottom:34px;z-index:300;transform:translate(-50%,16px);
  background:rgba(16,17,20,.97);border:1px solid var(--line-2);border-radius:10px;
  padding:14px 20px;font-size:14px;color:var(--soft);opacity:0;pointer-events:none;
  transition:opacity .3s ease,transform .4s cubic-bezier(.2,.8,.3,1);
  box-shadow:0 26px 50px -26px rgba(0,0,0,.95)}
#toast.on{opacity:1;transform:translate(-50%,0)}


/* ---------- the way back to the piece you came from ---------- */
#returnbar{padding:0 0 clamp(18px,2.4vw,26px)}
.rback{
  display:inline-flex;align-items:center;gap:12px;max-width:100%;
  border:1px solid var(--line-2);border-radius:9px;padding:11px 16px;
  font-size:14px;color:var(--soft);
  transition:border-color .25s ease,background .25s ease,color .25s ease,gap .25s ease;
}
.rback:hover{border-color:var(--line);background:rgba(255,255,255,.06);color:#fff;gap:16px}
.rback:active{transform:scale(.98)}
.rback .lab{font-family:var(--f-mono);font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--dim);flex:none}
.rback .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
@media (max-width:760px){
  .rback{width:100%;padding:12px 14px;font-size:13.5px}
}

/* ---------- things you can tap into a filter ---------- */
.head .mark{cursor:pointer;transition:filter .25s ease}
.head .mark:hover{filter:brightness(1.18)}
.head .mark:active{filter:brightness(.92)}

/* spec values that link into the archive */
.spec .v.link{
  position:relative;cursor:pointer;font:inherit;color:var(--bone);
  text-align:right;transition:color .2s ease;
}
.spec .v.link::after{
  content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:100% 50%;
  transition:transform .35s cubic-bezier(.2,.8,.3,1);
}
.spec .v.link:hover{color:#fff}
.spec .v.link:hover::after{transform:scaleX(1);transform-origin:0 50%}
.spec .v.link:active{opacity:.7}

/* the category tag under the cover */
.pcat.link{cursor:pointer}
.pcat.link:hover{border-color:var(--line);background:rgba(255,255,255,.06);color:#fff}
.pcat.link:active{transform:scale(.97)}
.pcat{transition:border-color .25s ease,background .25s ease,color .25s ease,transform .18s ease}

/* on touch there is no hover, so the links carry a permanent quiet underline */
@media (pointer:coarse){
  .spec .v.link::after{transform:scaleX(1);opacity:.32}
}

/* ============================================================
   TRANSITIONS
   ============================================================ */
/* a band of light travelling down the screen on a page change */
#sweep{
  position:fixed; left:0; right:0; top:0; height:100%; z-index:200; pointer-events:none;
  background:linear-gradient(180deg,
    transparent 0%, rgba(255,255,255,.015) 38%, rgba(255,255,255,.10) 50%,
    rgba(255,255,255,.015) 62%, transparent 100%);
  will-change:transform;
}
/* the flare that rakes across a photo as it lands */
#landflare{
  position:fixed; z-index:151; pointer-events:none; overflow:hidden;
  will-change:transform;
}
#landflare i{
  position:absolute; inset:-40% -70%; display:block;
  background:linear-gradient(104deg,transparent 34%,rgba(255,255,255,.14) 44%,
    rgba(255,255,255,.42) 50%,rgba(255,255,255,.14) 56%,transparent 66%);
  transform:translateX(-90%);
}
/* a soft bloom that pulses out from the cover as it settles */
#landglow{
  position:fixed; z-index:149; pointer-events:none; border-radius:50%;
  background:radial-gradient(closest-side, rgba(255,255,255,.20), transparent 72%);
  will-change:transform,opacity;
}
@media (prefers-reduced-motion:reduce){
  #sweep,#landflare,#landglow{display:none}
}

/* ---------- reveal ---------- */
.rise{opacity:0;transform:translateY(26px)}
.rise.on{opacity:1;transform:none;
  transition:opacity .85s cubic-bezier(.16,1,.3,1),transform .85s cubic-bezier(.16,1,.3,1)}

@media (max-width:900px){
  .cols{grid-template-columns:minmax(0,1fr)}
  .pager{grid-template-columns:1fr;gap:30px}
  .pnav.next{justify-content:flex-start;text-align:left;flex-direction:row-reverse}
  .pnav.next .col{flex:1}
}
/* the Filters button only exists on phones */
.filtoggle{display:none;align-items:center;gap:10px;border:1px solid var(--line-2);
  border-radius:9px;padding:11px 15px;font-size:14px;color:var(--soft);
  transition:border-color .25s,background .25s,color .25s}
.filtoggle[aria-expanded="true"]{background:rgba(255,255,255,.07);border-color:var(--line);color:#fff}
.filtoggle svg{transition:transform .3s cubic-bezier(.2,.8,.3,1)}
.filtoggle[aria-expanded="true"] svg{transform:rotate(180deg)}

/* On a phone there is nothing to hover, so the flare plays on the
   products that are actually on screen, each on its own offset. */
.tile.lit .shot::after,.frame.lit::after{
  animation:flare 4.2s linear var(--fd,0s) infinite}
/* ambient motion holds still while a scroll is in flight, so the scroll
   itself gets the whole frame budget */
html.scrolling .tile.lit .shot::after,
html.scrolling .frame.lit::after,
html.scrolling #weave,
html.scrolling #bloom i{animation-play-state:paused}



/* ============================================================
   PHONE
   The desktop toolbar stacked to ~700px tall here, which pushed
   every product off the first screen. On a phone the filters
   collapse, the chips scroll sideways in one row, and the grid
   runs two across so work is the first thing you see.
   ============================================================ */
@media (max-width:760px){

  /* ---- header: one compact row ---- */
  .head .wrap{flex-wrap:nowrap;gap:10px;padding-top:12px;padding-bottom:12px}
  .head .mark{font-size:19px}
  .head .vr,.head .tag{display:none}
  .cta{padding:10px 13px;font-size:13.5px;gap:7px;border-radius:7px}
  .ghost{padding:10px 2px;gap:0}
  .ghost span{display:none}          /* padlock only */

  /* ---- search ---- */
  .toolbar{padding-top:14px}
  .searchrow{flex-wrap:wrap;gap:10px;padding-bottom:12px}
  kbd.slash{display:none}            /* no keyboard to press it with */
  #q{flex:1;font-size:16px}          /* 16px keeps iOS from zooming on focus */
  .seg{order:3;width:100%;margin-top:10px}
  .seg button{flex:1;text-align:center;padding:10px 12px;font-size:13.5px}

  /* ---- artists / product types fold away behind Filters ---- */
  .filterrow{flex-wrap:wrap;gap:10px;padding:12px 0 10px}
  .filtoggle{display:inline-flex;order:0}
  .filterrow .sp{order:1}
  .tally{order:2;font-size:11px}
  .sel{order:3;flex:0 0 100%;display:none}
  .filterrow.open .sel{display:block}
  .sel > button{width:100%;min-width:0}
  .menu{position:static;display:none;max-height:240px;margin-top:6px;
    opacity:1;transform:none;pointer-events:auto;box-shadow:none;
    background:rgba(255,255,255,.04)}
  .sel.open .menu{display:block}

  /* ---- categories: one sideways strip, bleeding to both edges ---- */
  .chips{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;gap:8px;
    padding-bottom:16px;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    margin-left:calc(var(--pad) * -1);margin-right:calc(var(--pad) * -1);
    padding-left:var(--pad);padding-right:var(--pad)}
  .chips::-webkit-scrollbar{display:none}
  .chip{flex:0 0 auto;padding:10px 14px;font-size:13.5px;gap:8px}

  /* ---- two products across ---- */
  .grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;
    padding-left:0;padding-right:0}
  .tile{gap:9px}
  .tile .who{font-size:10px;letter-spacing:.14em}
  .tile .what{font-size:13.5px}
  .grouphead{padding:18px 0 14px}
  .grouphead h2{font-size:19px}

  /* ---- project page ---- */
  .spec,.pressrow{flex-direction:column;align-items:flex-start;gap:6px;padding:16px 0}
  .spec .v,.pressrow .what{text-align:left}
  .vers{grid-template-columns:minmax(0,1fr);gap:26px}
  .gal{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
  .ptitle{font-size:clamp(28px,8.4vw,40px)}
  .frame.cover{aspect-ratio:4/3}
  .frame .stamp{left:12px;bottom:12px;padding:8px 11px;font-size:10px}
  .frame .grow{right:12px;bottom:12px;width:40px;height:40px}
  .crumb{padding:16px 0}
}



/* Narrow phones (360px Androids, older SE). The header row is nowrap, so
   below about 380px the wordmark + CTA + padlock ran past the edge. */
@media (max-width:400px){
  .head .wrap{gap:8px}
  .head .mark{font-size:17px}
  .cta{padding:9px 11px;font-size:12.5px;gap:5px}
  .ghost{padding:9px 0}
}


/* Very narrow phones (320-360px). The CTA collapses to its arrow so the
   header row can never push past the edge. */
@media (max-width:360px){
  .ctalabel{display:none}
  .cta{padding:9px 10px}
  .head .mark{font-size:16px}
  .head .wrap{gap:6px}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
  .tile,.rise{opacity:1;transform:none}
  #field{opacity:1}
}
