/* ============================================================
   CONCRETE — "THE EVIDENCE WALL"  (cases index · Option C v2)
   A pinned evidence wall: case cards as physical artifacts tacked
   up — varied size, overlap, real cast shadow, parallax by depth.
   One ignited anchor per cluster carries the verdict; mono scraps
   support it. Transforms / opacity / box-shadow / clip-path only —
   no animated blur. Lives alongside styles.css (HUD + .btn reused).
   ============================================================ */

/* ---- the wall surface: lit plaster + drifting services-palette
   shapes + a spotlight vignette, so it reads as a board under a lamp
   (a lit diorama the cards float against), not a void. The colour
   shapes stay deep + screened + behind the vignette so the wall has
   life without going RGB-loud — only the anchor ignites. ---- */
.wall-page{ background:#0a0a0d; }
/* the ambient glow colour is animatable so it can cross-fade between cases */
@property --wall-glow{ syntax:'<color>'; inherits:true; initial-value:#FF2E1F; }
.wall-bg{
  position:fixed; inset:0; z-index:-2; pointer-events:none; overflow:hidden;
  --wall-glow:#E5342B; transition:--wall-glow .9s linear;
  /* glow baked into the background (a plain layer, not a blurred blend child) so it paints on every
     GPU. background-color fallback keeps the wall dark if color-mix isn't supported. */
  background-color:#0a0a0d;
  background-image:
    radial-gradient(64% 56% at 50% 40%, color-mix(in srgb, var(--wall-glow) 34%, transparent) 0%, transparent 62%),
    linear-gradient(180deg,#0d0d11 0%,#0a0a0e 50%,#070709 100%);
}
/* drifting ABSTRACT SHAPES — Services palette. Each is an organic blob
   (asymmetric border-radius) that morphs: its silhouette warps while it
   slowly rotates, scales and drifts, so it reads as a transforming shape,
   not a static gradient. Soft-edged (static blur) + screen blend keeps
   them ambient so the cards still own the foreground. */
/* ambient room glow — soft, dim bloom in the ACTIVE case's colour (var set by
   JS), centred behind the focused card. It morphs + drifts slowly so the room
   feels alive, but stays low + neutral-surrounded so the verdict ignite still
   detonates against it. Colour follows the case you're on; it never floods. */
.wb-glow{ display:none;   /* retired — the glow is now the page background (see .wall-page) */
  position:absolute; left:50%; top:46%; width:96vw; height:96vw;
  transform:translate(-50%,-50%);
  background:radial-gradient(circle, color-mix(in srgb,var(--wall-glow) 60%, transparent) 0%, transparent 62%);
  opacity:.6; filter:blur(52px);
  border-radius:46% 54% 52% 48% / 50% 46% 54% 50%;
  animation:glowMorph 28s ease-in-out infinite; will-change:transform,border-radius;
}
@keyframes glowMorph{
  0%,100%{ transform:translate(-50%,-50%) scale(1)    rotate(0deg);   border-radius:46% 54% 52% 48% / 50% 46% 54% 50%; }
  50%    { transform:translate(-46%,-54%) scale(1.12) rotate(40deg);  border-radius:56% 44% 46% 54% / 44% 56% 48% 52%; }
}
/* fine plaster grain — static SVG fractal noise */
.wb-grain{
  position:absolute; inset:0; opacity:.05;   /* no blend layer (see .wb-glow); kept subtle as plain grain */
  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='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* spotlight vignette — centre lit, edges fall to black (under a lamp) */
.wb-spot{
  position:absolute; inset:0;
  background:radial-gradient(125% 95% at 50% 38%, rgba(255,247,235,.06) 0%, transparent 30%, rgba(0,0,0,.45) 76%, rgba(0,0,0,.72) 100%);
}
@media (prefers-reduced-motion: reduce){ .wb-glow{ animation:none !important; } }

/* ---- intro caption (reuses .cf-cap rhythm, but in flow not fixed) ---- */
.wall-cap{ text-align:center; padding:clamp(96px,13vh,150px) 16px clamp(64px,10vh,120px); }
.wall-cap .k{ font-family:var(--mono); font-size:11px; letter-spacing:.28em; text-transform:uppercase; color:var(--dim); }
.wall-cap h1{ font-family:var(--disp); text-transform:uppercase; font-size:clamp(30px,6vw,68px); line-height:.98; letter-spacing:.012em; color:#fff; margin-top:10px; }
.wall-cap p{ max-width:52ch; margin:16px auto 0; color:#cbc8bf; font-size:clamp(14px,1.7vw,19px); }

/* ---- the wall + clusters ---- */
.wall{ position:relative; padding-bottom:clamp(60px,10vh,120px); }
/* GUARD: styles.css styles a homepage-decorative background layer that is ALSO called
   `.wall` (position:absolute, opacity:.6, filter:blur, z-index:-1 under 720px). Those rules
   leak onto THIS page's <main class="wall"> and blur/dim the whole case grid on mobile.
   Neutralise them here — scoped to body.wall-page so only the case-studies main is affected. */
body.wall-page main.wall{ position:relative !important; inset:auto !important; z-index:auto !important;
  opacity:1 !important; filter:none !important; -webkit-filter:none !important; display:block !important; }
body.wall-page main.wall > *{ filter:none; }
.wall-cluster{
  position:relative; width:100%; max-width:min(1380px,95vw); margin:0 auto; height:var(--h,520px);
}
.wall-cluster + .wall-cluster{ margin-top:clamp(80px,10vw,170px); } /* generous air between cases */
/* the first VISIBLE case (after a filter) sits at the top with no leading margin, so it
   lands in the same hero position/size as Jagiya — overrides the adjacent-sibling margin
   that a hidden previous sibling would otherwise still apply. */
.wall .wall-cluster.wf-first{ margin-top:0; }

/* ---- every pinned object: outer = parallax translate, inner = rest/rotate/hover ---- */
.wall-item{
  position:absolute; left:var(--x,0); top:var(--y,0); width:var(--w,auto);
  z-index:var(--z,1); transform:translate3d(0,var(--py,0px),0); will-change:transform;
}
/* one transform, composed from independent custom props so parallax
   (outer), resting rotation, 3D tilt, lift and hover-scale never fight:
   --tiltX/--tiltY = pointer tilt · --liftY = lift off wall · --sc = scale */
.item-inner{
  position:relative; opacity:1;
  transform:
    perspective(1100px)
    rotateX(var(--tiltX,0deg)) rotateY(var(--tiltY,0deg))
    rotate(var(--r,0deg)) translateY(var(--liftY,0px)) scale(var(--sc,1)) scale(var(--zoom,1));
  transition:transform .6s var(--ease), opacity .5s var(--ease), box-shadow .45s var(--ease);
}
/* pin-in: only when JS arms the wall; no-JS shows everything at rest */
html.wall-anim .wall-item:not(.pinned) .item-inner{ opacity:0; transform:perspective(1100px) translateY(-18px) rotate(0deg) scale(.96); }
/* hover = peel off the wall higher, straighten a touch, shadow blooms */
.wall-item:hover{ z-index:40; }
.wall-item:hover .item-inner{ --liftY:-9px; --sc:1.03; }
/* anchors carry a faint resting 3D lean (lit from above) + bloom higher on hover */
.wall-anchor .item-inner{
  transform:
    perspective(1100px)
    rotateX(calc(2deg + var(--tiltX,0deg))) rotateY(var(--tiltY,0deg))
    rotate(calc(var(--r,0deg) * (1 - var(--focus,0)))) translateY(var(--liftY,0px)) scale(var(--sc,1)) scale(var(--zoom,1));
}
.wall-anchor:hover .item-inner{ --liftY:-13px; --sc:1.045; }
/* all main cards share one larger size (overrides per-anchor inline --w) */
.wall-anchor{ width:clamp(330px,34vw,460px); }

/* ============================================================
   FOCUS ZOOM — when a case becomes the active one, its card zooms
   up big, 3 bullets unfurl, and the surrounding scraps fade out so
   the focused case owns the screen. Opt-in per cluster via .has-zoom.
   ============================================================ */
/* --focus (0..1) is set per cluster by JS from its distance to viewport centre:
   the card scales up gradually as it nears centre, straightens, and lifts above
   the rest, while the scraps fade out in lock-step. Scroll-tied, no snap. */
.wall-anchor .item-inner{ --zoom:calc(1 + var(--focus,0) * 0.36); }
.wall-cluster.is-active .wall-anchor{ z-index:30; }
/* supporting materials now live as thumbnails under the bullets panel, so the
   old scattered background scraps are retired (glow + grain + vignette carry the ambiance). */
.scrap{ display:none; }
.cf-materials{ display:flex; gap:10px; margin-top:26px; flex-wrap:wrap; }
.cf-materials img{ width:clamp(60px,6.6vw,88px); height:clamp(44px,4.9vw,66px); object-fit:cover; border-radius:3px;
  border:1px solid rgba(239,239,236,.16); box-shadow:0 6px 18px rgba(0,0,0,.45); filter:grayscale(.35) brightness(.9); }
/* the 3 case facts live BESIDE the card (opposite side), big + light on the dark
   wall, fading in with --focus as the case is scrolled to centre. Positioned per
   cluster via --x/--y; cards alternate sides so facts land on the open side. */
.case-facts{
  position:absolute; top:clamp(40px,5vw,70px); width:clamp(280px,30vw,440px);
  z-index:6; opacity:var(--focus,0); pointer-events:none; transition:opacity .45s var(--ease);
}
/* testimonial comment under the bullets */
.cf-quote{ margin:26px 0 0; padding:0; font-family:var(--sans); font-size:clamp(13px,1.45vw,17px); font-style:italic;
  color:#d8d5cd; line-height:1.45; max-width:34ch; text-shadow:0 1px 10px rgba(0,0,0,.6); }
.cf-quote cite{ display:block; font-style:normal; font-family:var(--sans); font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--c); margin-top:9px; }
/* cards alternate sides by case order; facts sit on the open side opposite the card.
   nth-of-type is the no-JS default; JS assigns .alt-a/.alt-b by VISIBLE order so the
   mirror layout still alternates after a filter hides some cards (these come last → win). */
.wall .wall-cluster:nth-of-type(odd)  .wall-anchor{ left:6%;  }
.wall .wall-cluster:nth-of-type(even) .wall-anchor{ left:52%; }
.wall .wall-cluster:nth-of-type(odd)  .case-facts{ left:54%; }
.wall .wall-cluster:nth-of-type(even) .case-facts{ left:5%;  }
.wall .wall-cluster.alt-a .wall-anchor{ left:6%;  }
.wall .wall-cluster.alt-a .case-facts{ left:54%; }
.wall .wall-cluster.alt-b .wall-anchor{ left:52%; }
.wall .wall-cluster.alt-b .case-facts{ left:5%;  }
.case-facts ul{ list-style:none; margin:0; padding:0; width:100%; }
.cf-logo, .cf-word{ position:relative; }
/* dossier structure — no decorative markers; meaning carried by hierarchy:
   quiet "what we did" credit lines, then the RESULT ignited in the case colour */
.cf-k{ font-family:var(--mono); font-size:10px; letter-spacing:.22em; text-transform:uppercase; color:var(--dim); margin:0 0 12px; }
.cf-k-res{ color:var(--c); margin:30px 0 0; }
.cf-did{ list-style:none; margin:0; padding:0; width:100%; }
.cf-did li{ display:flex; align-items:flex-start; gap:15px;
  font-family:var(--sans); font-size:clamp(15px,1.7vw,21px); font-weight:600; letter-spacing:-.01em;
  color:#d2cfc7; line-height:1.3; padding:11px 0; border-top:1px solid rgba(239,239,236,.1); }
.cf-did li:first-child{ border-top:none; padding-top:0; }
/* marker: a cycle of geometric primitives — triangle, then circle, then rectangle —
   one per line, in the case colour. Clean, brutalist, the basic shapes. */
.cf-did li::before{ content:''; flex:none; background:var(--c); transition:transform .4s var(--ease); }
.cf-did li:nth-child(1)::before{ width:12px; height:11px; margin-top:.4em; clip-path:polygon(50% 0,100% 100%,0 100%); } /* triangle */
.cf-did li:nth-child(2)::before{ width:11px; height:11px; margin-top:.42em; border-radius:50%; }                        /* circle */
.cf-did li:nth-child(3)::before{ width:10px; height:10px; margin-top:.44em; border-radius:1px; }                       /* square */
/* the focused case's shapes scale up a touch */
.wall-cluster.is-active .cf-did li::before{ transform:scale(1.14); }
@media (prefers-reduced-motion: reduce){ .wall-cluster.is-active .cf-did li::before{ transform:none; } }
/* result reads like the other two lines (the card header carries the big verdict) */
.cf-result{ font-family:var(--sans); font-size:clamp(15px,1.7vw,21px); font-weight:600; letter-spacing:-.01em;
  color:#d2cfc7; line-height:1.3; margin:0; padding:11px 0 0; }
/* the read-full-case-study CTA reuses the unique site button, tinted to the
   case's own colour (override --a1 → --c so border/fill/badge ignite to match) */
.anchor-cta{ display:none; }
.case-facts .cf-cta{ margin-top:28px; pointer-events:auto; --a1:var(--c); }
/* client logo as the panel header, above the bullets */
.cf-logo{ display:block; width:clamp(200px,24vw,300px); height:var(--logo-h,46px);
  background-position:left center; background-repeat:no-repeat; background-size:contain;
  margin:0 0 22px; filter:drop-shadow(0 2px 8px rgba(0,0,0,.55)); }
.cf-logo.cf-logo-dark{ filter:brightness(0) invert(1) drop-shadow(0 2px 8px rgba(0,0,0,.5)); } /* dark marks → light */
.cf-logo.cf-logo-bright{ filter:brightness(1.7) drop-shadow(0 2px 8px rgba(0,0,0,.55)); }       /* faint marks */
.cf-word{ display:block; font-family:var(--disp); text-transform:uppercase; font-size:clamp(26px,3.2vw,44px);
  letter-spacing:.02em; color:#f1eee8; margin:0 0 20px; line-height:1; }

/* ============================================================
   THE ANCHOR CARD — light stock, lit work image, ignited verdict
   ============================================================ */
.wall-anchor .item-inner{
  background:linear-gradient(168deg,#fbf8f1 0%,#f3ede0 76%,#ebe3d3 100%);
  border-radius:4px; padding:13px 13px 15px;
  /* big soft GAP shadow offset down-right (one light, top-left) lifts the
     card off the wall; + a tighter contact shadow; + lit-paper insets */
  box-shadow:
    26px 42px 72px -18px rgba(0,0,0,.62),
    10px 16px 30px -10px rgba(0,0,0,.42),
    inset 0 1.5px 0 rgba(255,255,255,.85),
    inset 0 -18px 26px -18px rgba(70,58,36,.18);
}
.wall-anchor:hover .item-inner{
  box-shadow:
    44px 70px 108px -22px rgba(0,0,0,.66),
    16px 26px 44px -12px rgba(0,0,0,.48),
    inset 0 1.5px 0 rgba(255,255,255,.9),
    inset 0 -18px 26px -18px rgba(70,58,36,.18);
}
/* paper-bow: soft highlight where the clip/pin holds the top edge */
.wall-anchor .item-inner::before{
  content:''; position:absolute; top:0; left:50%; width:84px; height:24px;
  transform:translateX(-50%); border-radius:0 0 50% 50%; pointer-events:none; z-index:2;
  background:radial-gradient(70% 100% at 50% 0, rgba(255,255,255,.7), transparent 72%);
}
/* the flagship sits closest to the lamp — even bigger relief */
.v-flag .wall-anchor .item-inner{
  box-shadow:
    34px 56px 92px -20px rgba(0,0,0,.66),
    12px 20px 38px -10px rgba(0,0,0,.46),
    inset 0 1.5px 0 rgba(255,255,255,.9),
    inset 0 -20px 30px -20px rgba(70,58,36,.2);
}
.anchor-link{ display:block; color:#1a1a1a; }

.anchor-tab{
  display:flex; align-items:center; gap:9px; flex-wrap:wrap;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.12em; text-transform:uppercase;
  color:#7F7D76; padding-bottom:9px; margin-bottom:11px; border-bottom:1px solid rgba(0,0,0,.12);
}
.anchor-tab .cno{ display:none; }                                   /* no case number */
.anchor-tab .client{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; } /* brand name hidden (kept for a11y + JS) */
.anchor-tab .disc{ color:#8a877f; } /* only the services we provided */

/* box matches the 4:3 image ratio → full photo shows, no crop, reliable height */
.anchor-shot{ position:relative; border-radius:2px; overflow:hidden; background:#e4e0d6; aspect-ratio:4/3; }
.anchor-shot img, .anchor-shot video{
  width:100%; height:100%; object-fit:cover; display:block;
  filter:grayscale(.66) brightness(.82) contrast(.96); transition:filter .65s var(--ease);
}
.wall-cluster.is-active .anchor-shot img,
.wall-cluster.is-active .anchor-shot video{ filter:none; }

.anchor-verdict{
  font-family:var(--disp); text-transform:uppercase; line-height:.98;
  font-size:clamp(19px,2.1vw,27px); letter-spacing:.01em; margin-top:13px; color:#3b3a36;
  transition:color .6s var(--ease);
}
.anchor-verdict em{ font-style:normal; color:color-mix(in srgb, var(--c,#888) 50%, #6f6d66); transition:color .6s var(--ease), text-shadow .6s var(--ease); }
.wall-cluster.is-active .anchor-verdict{ color:#15140f; }
.wall-cluster.is-active .anchor-verdict em{ color:var(--c); text-shadow:0 0 24px color-mix(in srgb, var(--c) 42%, transparent); }

.anchor-stat{ font-family:var(--mono); font-size:11px; letter-spacing:.04em; color:#7F7D76; margin-top:9px; }
/* no button on the card itself — the whole card links, and the side panel
   carries the unique "Read the full case study" CTA */
.anchor-cta{ display:none; }

/* ============================================================
   SCRAPS — mono supporting evidence (stay quiet, never ignite)
   ============================================================ */
.scrap .item-inner{ filter:grayscale(1) brightness(.34) blur(3.5px); opacity:.28; box-shadow:none; }

/* sticky-note testimonial (real proof text) */
.scrap-note .item-inner{
  background:linear-gradient(165deg,#f2ecd6,#e8e1c6); color:#26241d; padding:13px 14px 14px; border-radius:2px;
  box-shadow:
    18px 28px 50px -14px rgba(0,0,0,.55),
    6px 10px 18px -6px rgba(0,0,0,.36),
    inset 0 1px 0 rgba(255,255,255,.6),
    inset 0 -12px 18px -14px rgba(70,58,36,.16);
}
.scrap-note .stars{ font-family:var(--mono); font-size:12px; letter-spacing:.1em; color:#3a382f; }
.scrap-note blockquote{ font-size:13px; line-height:1.4; font-weight:500; margin-top:7px; }
.scrap-note figcaption{ display:flex; align-items:center; gap:7px; margin-top:10px; font-family:var(--sans); font-size:9.5px; letter-spacing:.06em; text-transform:uppercase; color:#5d5b50; }
.scrap-note figcaption img{ width:22px; height:22px; border-radius:50%; object-fit:cover; }

/* desaturated polaroid */
.scrap-polaroid .item-inner{
  background:linear-gradient(168deg,#f7f5ee,#ece9df); padding:9px 9px 30px; border-radius:1px;
  box-shadow:
    18px 28px 50px -14px rgba(0,0,0,.55),
    6px 10px 18px -6px rgba(0,0,0,.36),
    inset 0 1px 0 rgba(255,255,255,.7),
    inset 0 -12px 18px -14px rgba(70,58,36,.14);
}
.scrap-polaroid img{ width:100%; aspect-ratio:1/1; object-fit:cover; display:block; }
.scrap-polaroid figcaption{ position:absolute; left:0; right:0; bottom:9px; text-align:center; font-family:var(--sans); font-size:9px; letter-spacing:.08em; text-transform:uppercase; color:#56544b; }

/* rubber stamp (decorative ink) */
.scrap-stamp .item-inner{
  border:2.5px solid #8a3b34; color:#8a3b34; border-radius:4px; padding:5px 12px;
  font-family:var(--disp); text-transform:uppercase; font-size:clamp(15px,1.7vw,21px); letter-spacing:.05em;
  opacity:.8; box-shadow:none; background:transparent;
}
.scrap-stamp .item-inner::before{ content:''; position:absolute; inset:-3px; border:1px solid #8a3b34; border-radius:5px; opacity:.35; }

/* circled / underlined stat (real proof text) */
.scrap-stat .item-inner{
  background:linear-gradient(166deg,#f4f1e9,#e9e5db); color:#222018; padding:12px 16px; border-radius:2px; text-align:center;
  box-shadow:
    18px 28px 50px -14px rgba(0,0,0,.55),
    6px 10px 18px -6px rgba(0,0,0,.36),
    inset 0 1px 0 rgba(255,255,255,.65),
    inset 0 -12px 18px -14px rgba(70,58,36,.15);
}
.scrap-stat .stat-num{ display:block; font-family:var(--disp); font-size:clamp(22px,2.6vw,32px); line-height:1; letter-spacing:.01em; }
.scrap-stat .stat-num::after{ content:''; display:block; height:6px; margin:3px auto 0; width:80%; border-radius:50%; border-bottom:2.5px solid #8a3b34; opacity:.55; }
.scrap-stat .stat-lbl{ display:block; font-family:var(--mono); font-size:9.5px; letter-spacing:.08em; text-transform:uppercase; color:#5d5b50; margin-top:7px; }

/* logo mark — the client's real logo, pinned bare to the wall (no
   frame). The one exception to "scraps stay mono": it ignites WITH its
   cluster (quiet light-grey when the case rests → full brand colour
   when active), so the logos light up one at a time as you scroll. */
.scrap-logo .item-inner{
  background:none; padding:0; box-shadow:none; filter:none; opacity:1;
  display:flex; align-items:center; justify-content:center;
}
/* bound BOTH dimensions so wide and tall marks normalise to one size band */
.scrap-logo img{
  width:auto; height:auto; display:block;
  max-width:clamp(124px,15vw,184px); max-height:clamp(44px,5.2vw,66px);
  filter:grayscale(1) brightness(1.75) opacity(.82) drop-shadow(0 3px 9px rgba(0,0,0,.6));
  transition:filter .6s var(--ease);
}
.wall-cluster.is-active .scrap-logo img{
  filter:grayscale(0) brightness(1) opacity(1) drop-shadow(0 4px 13px rgba(0,0,0,.62));
}
/* Pete's mark is light + faint — give it more size and brightness so it reads */
.scrap-logo.logo-petes img{ max-width:clamp(150px,18vw,210px); max-height:clamp(54px,6.4vw,82px); filter:grayscale(1) brightness(2.1) opacity(.88) drop-shadow(0 3px 9px rgba(0,0,0,.6)); }
.wall-cluster.is-active .scrap-logo.logo-petes img{ filter:grayscale(0) brightness(1.18) opacity(1) drop-shadow(0 4px 13px rgba(0,0,0,.62)); }
/* dark marks (e.g. Clear Vision's dark-green logo) are invisible on the dark
   wall, so render them as a LIGHT silhouette — dim grey when quiet, white when active */
.scrap-logo.logo-glow img{ filter:brightness(0) invert(.72) drop-shadow(0 3px 8px rgba(0,0,0,.55)); }
.wall-cluster.is-active .scrap-logo.logo-glow img{ filter:brightness(0) invert(1) drop-shadow(0 3px 8px rgba(0,0,0,.55)); }
/* typographic wordmark fallback (clients with no logo file on hand) */
.scrap-logo .wordmark{
  font-family:var(--disp); text-transform:uppercase; font-size:clamp(24px,3vw,40px); letter-spacing:.02em; line-height:1;
  color:#cfcbc2; opacity:.58; text-shadow:none; transition:color .6s var(--ease), opacity .6s var(--ease);
}
.wall-cluster.is-active .scrap-logo .wordmark{ color:#f6f3ec; opacity:1; }

/* ============================================================
   FASTENERS — varied, so the wall reads as collected over time
   ============================================================ */
.fastener{ position:absolute; z-index:3; pointer-events:none; }
/* pushpin */
.fast-pin{ top:-9px; left:50%; width:16px; height:16px; margin-left:-8px; border-radius:50%;
  background:radial-gradient(circle at 36% 32%, #fff 0%, #d8d4cc 30%, #8f8b82 70%, #6a675f 100%);
  box-shadow:0 4px 7px rgba(0,0,0,.5), inset 0 -1px 2px rgba(0,0,0,.3); }
.fast-pin::after{ content:''; position:absolute; top:13px; left:50%; width:2px; height:7px; margin-left:-1px; background:#3a382f; border-radius:0 0 1px 1px; }
/* tape strip across a corner */
.fast-tape{ top:-12px; left:-14px; width:74px; height:24px; transform:rotate(-38deg);
  background:linear-gradient(180deg, rgba(232,228,214,.72), rgba(214,210,196,.58));
  border-left:1px solid rgba(255,255,255,.35); border-right:1px solid rgba(0,0,0,.06);
  box-shadow:0 2px 5px rgba(0,0,0,.25); }
/* bulldog clip at top */
.fast-clip{ top:-11px; left:50%; width:42px; height:16px; margin-left:-21px;
  background:linear-gradient(180deg,#cfccc4,#8d8a82); border-radius:3px 3px 2px 2px;
  box-shadow:0 5px 9px rgba(0,0,0,.45), inset 0 1px 1px rgba(255,255,255,.4); }
.fast-clip::before, .fast-clip::after{ content:''; position:absolute; top:12px; width:2px; height:12px; background:#6f6c64; }
.fast-clip::before{ left:9px; transform:rotate(8deg); }
.fast-clip::after{ right:9px; transform:rotate(-8deg); }
/* staple */
.fast-staple{ top:-3px; left:50%; width:26px; height:11px; margin-left:-13px; border:2px solid #777269; border-bottom:none; border-radius:2px 2px 0 0; opacity:.85; }

/* ============================================================
   closing
   ============================================================ */
.wall-foot{ text-align:center; padding:clamp(40px,8vh,90px) 16px clamp(60px,10vh,110px); }
.wall-foot .k{ font-family:var(--mono); font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--dim); margin-bottom:18px; }

/* ============================================================
   RESPONSIVE — under 900px the wall stacks into a clean column,
   anchors full-width, one supporting note kept, rest hidden.
   ============================================================ */
@media (max-width:900px){
  .wall-cap{ padding:92px 16px 18px !important; }                /* tighten the oversized gap under the title */
  .wall{ padding-bottom:104px; }                                 /* room so the fixed filter bar never covers the last case */
  .wall-cluster{ height:auto !important; display:flex; flex-direction:column; align-items:center; gap:20px; padding:0 16px; margin-top:38px !important; }
  .wall-item{ position:static !important; width:min(440px,88vw) !important; transform:none !important; }
  .item-inner{ transform:rotate(0deg) !important; }
  .scrap:not(.keep-sm){ display:none; }
  .scrap-note .item-inner, .wall-anchor .item-inner{ transform:rotate(0deg) !important; }
  html.wall-anim .wall-item:not(.pinned) .item-inner{ opacity:1; transform:none; }
  /* mobile has no hover/scroll-focus — show every case in its full, readable (ignited)
     state instead of the dimmed + blurred resting state (that's what read as "unusable") */
  .wall-cluster .anchor-shot img, .wall-cluster .anchor-shot video{ filter:none !important; }
  .wall-cluster .anchor-verdict{ color:#15140f !important; }
  .wall-cluster .anchor-verdict em{ color:var(--c) !important; text-shadow:0 0 24px color-mix(in srgb, var(--c) 42%, transparent) !important; }
  .scrap.keep-sm .item-inner{ filter:none !important; opacity:1 !important; }
  .scrap-logo img{ filter:grayscale(0) brightness(1) opacity(1) drop-shadow(0 4px 13px rgba(0,0,0,.5)) !important; }
  .scrap-logo.logo-glow img{ filter:brightness(0) invert(1) drop-shadow(0 3px 8px rgba(0,0,0,.55)) !important; }
  .scrap-logo .wordmark{ color:#f6f3ec !important; opacity:1 !important; }
}

/* ============================================================
   REDUCED MOTION — static wall: items at resting rotation,
   no parallax, no pin-in. Fully readable.
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  .wall-item{ transform:none !important; }
  .item-inner{ transition:none !important; opacity:1 !important; }
  html.wall-anim .wall-item:not(.pinned) .item-inner{ opacity:1; transform:rotate(var(--r,0deg)); }
  .wall-item:hover .item-inner{ transform:rotate(var(--r,0deg)); }
}

/* ============================================================
   SERVICE FILTER — right-side rail; pick a discipline to show
   only those cases. Hidden cases collapse out of the flow.
   ============================================================ */
/* --- OG Xbox dashboard menu, as a LOOPING WHEEL: items are positioned around the
   viewport centre by JS; the selected one sits dead-centre, magnified + ignited,
   and items pushed off one end wrap around to the other (infinite, no empty space).
   Brand red instead of that dashboard's green. --- */
:root{ --xb-ease:cubic-bezier(.2,.9,.25,1); --wf-pitch:clamp(42px,5.6vh,60px); }
.wall-filter{
  position:fixed; right:clamp(18px,2.6vw,46px); top:50%; z-index:45; height:0; /* items absolute around this centre */
  transition:transform .5s cubic-bezier(.5,0,.18,1), opacity .42s ease;
}
.wall-filter.wf-gone{ transform:translateX(max(460px,36vw)); opacity:0; pointer-events:none; } /* slides off the right edge once the footer is reached */
.wf-label{
  position:absolute; right:2px; bottom:calc(3.15 * var(--wf-pitch)); white-space:nowrap;
  font-family:var(--mono); font-size:9px; letter-spacing:.36em; text-transform:uppercase;
  color:var(--a1); opacity:.85; text-shadow:0 0 14px color-mix(in srgb,var(--a1) 60%,transparent);
}
.wf-btn{
  position:absolute; right:0; top:0; appearance:none; -webkit-appearance:none; background:none; border:0; cursor:pointer; white-space:nowrap;
  font-family:var(--disp); text-transform:uppercase; letter-spacing:.015em; font-size:clamp(13px,1.55vw,21px); line-height:1;
  color:rgba(239,239,236,.42); padding:7px 16px 7px 30px;
  transform-origin:right center; transform:translateY(-50%); /* JS overrides with wheel offset + scale */
  transition:transform .5s var(--xb-ease), color .35s ease, text-shadow .35s ease, opacity .45s ease;
}
.wall-filter.wf-instant .wf-btn{ transition:none; } /* no fan-out animation on first paint (kills the load jump) */
/* the selection "blade" — translucent red lens that sweeps in from the right */
.wf-btn::before{
  content:''; position:absolute; z-index:-1; right:-8px; top:50%; height:132%; width:122%;
  transform:translateY(-50%) scaleX(.18); transform-origin:right center; opacity:0;
  background:radial-gradient(120% 82% at 100% 50%, color-mix(in srgb,var(--a1) 62%,transparent) 0%, color-mix(in srgb,var(--a1) 24%,transparent) 40%, transparent 74%);
  border-radius:64px 10px 10px 64px;
  transition:transform .44s var(--xb-ease), opacity .4s ease;
}
/* bright edge cursor on the right rail (the dashboard's selection indicator) */
.wf-btn::after{
  content:''; position:absolute; right:-8px; top:50%; transform:translateY(-50%) scaleY(0);
  width:3px; height:64%; background:var(--a1); border-radius:3px;
  box-shadow:0 0 14px var(--a1), 0 0 32px color-mix(in srgb,var(--a1) 70%,transparent);
  transition:transform .34s var(--xb-ease);
}
.wf-btn:hover{ color:#fff; text-shadow:0 0 16px color-mix(in srgb,var(--a1) 55%,transparent); } /* scale owned by JS */
.wf-btn:hover::before{ opacity:.55; transform:translateY(-50%) scaleX(1); }
.wf-btn.is-on{ color:#fff; text-shadow:0 0 22px var(--a1), 0 0 6px rgba(255,255,255,.5); }
.wf-btn.is-on::before{ opacity:1; transform:translateY(-50%) scaleX(1); animation:xbPulse 2.6s ease-in-out infinite; }
.wf-btn.is-on::after{ transform:translateY(-50%) scaleY(1); }
@keyframes xbPulse{ 0%,100%{ filter:brightness(1); } 50%{ filter:brightness(1.4); } }
.wf-btn:focus-visible{ outline:2px solid var(--a1); outline-offset:4px; }
@media (prefers-reduced-motion: reduce){ .wf-btn.is-on::before{ animation:none; } }

/* a filtered-out case is removed from the wall entirely */
.wall-cluster.wf-hidden{ display:none; }

/* mobile: drop the wheel, lay the rail out as a horizontal scrolling bar at the bottom */
@media (max-width:900px){
  /* only the filter bar scrolls sideways — never the page. `clip` on the root also contains
     the fixed filter bar (which body's overflow-x:hidden can't), on the x-axis only so vertical
     scroll and the bar's own internal scroll are untouched. (wall.css is loaded on wall.html only.) */
  html{ overflow-x:clip; }
  .wall-filter{
    position:fixed; top:auto; bottom:0; left:0; right:0; height:auto;
    display:flex; flex-direction:row; align-items:center; gap:8px;
    overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch;
    scroll-snap-type:x proximity; scrollbar-width:none;
    padding:11px 16px calc(12px + env(safe-area-inset-bottom));
    background:linear-gradient(0deg, rgba(7,7,9,.97) 64%, rgba(7,7,9,.7) 88%, transparent);
    /* fade both edges so it's obvious the row scrolls for the rest of the filters */
    -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 30px), transparent 100%);
            mask-image:linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 30px), transparent 100%);
  }
  .wall-filter::-webkit-scrollbar{ display:none; }
  .wall-filter.wf-gone{ transform:translateY(115%) !important; opacity:0; }   /* slide DOWN out of view at the footer, not sideways */
  .wf-label{ display:none; }
  .wf-btn{
    position:static; transform:none !important; opacity:1 !important; flex:0 0 auto; scroll-snap-align:start;
    padding:8px 14px; font-size:13px; line-height:1; white-space:nowrap; border-radius:999px; transform-origin:center;
    background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.1); color:rgba(239,239,236,.66);
  }
  .wf-btn.is-on{ background:color-mix(in srgb,var(--a1) 22%,transparent); border-color:color-mix(in srgb,var(--a1) 58%,transparent); color:#fff; text-shadow:none; }
  .wf-btn::before, .wf-btn::after{ display:none !important; }
}

/* ============================================================
   INTRO — the visible elements assemble in from around the screen on load
   ============================================================ */
@keyframes asmDown{ from{ opacity:0; transform:translateY(-46px) } to{ opacity:1; transform:none } }
@keyframes asmUp{   from{ opacity:0; transform:translateY(42px) }  to{ opacity:1; transform:none } }
@keyframes asmRight{from{ opacity:0; transform:translateX(72px) }  to{ opacity:1; transform:translateX(0) } }
@keyframes asmLeft{ from{ opacity:0; transform:translateX(-72px) } to{ opacity:1; transform:translateX(0) } }
@keyframes asmIn{   from{ opacity:0; transform:scale(.9) }         to{ opacity:1; transform:scale(1) } }
.hud{ animation:asmDown .7s cubic-bezier(.2,.85,.25,1) both; }
.wall-cap h1{ animation:asmIn .85s cubic-bezier(.2,.85,.25,1) .12s both; }
.wall-cap p{ animation:asmUp .7s cubic-bezier(.2,.85,.25,1) .28s both; }
.wall-filter{ animation:asmRight .85s cubic-bezier(.2,.85,.25,1) .42s backwards; } /* backwards, not both — so it doesn't hold opacity/transform and block the slide-out */
@media (prefers-reduced-motion: reduce){ .hud,.wall-cap h1,.wall-cap p,.wall-filter{ animation:none; } }
