/* chrome/badge.css — the ID card on its lanyard. Spec: 097 §2/§5, 099 B1/B5.

   ⚠️ THE PAGE SCROLLS BEHIND THE OPEN BADGE, DELIBERATELY (097 §2). This is
   the OPPOSITE of the projects modal, which locks scroll. Do NOT port
   .pmodal's wheel/touchmove braces here — the bar and badge are the site's
   topmost layer and content is simply occluded until the visitor retracts. */

.badge {
  /* ⚠️ FULL VIEWPORT, AND 099 B5's ENVELOPE IS RETIRED. Sizing the canvas to
     "what the swing needs plus margin" put a hard rectangular edge in the
     middle of the scene: any swing carried the card across it and it was cut
     by a straight vertical line. There is no envelope large enough to be safe
     and small enough to be an envelope — the drag is unbounded, so the canvas
     has to be the viewport.

     `svh`, never `vh` (000 §3.1). pointer-events:none is what buys back the
     cost of covering the page: the canvas eats nothing, and a single tracked
     hit target below carries the interaction. */
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100svh;
  z-index: 70;

  visibility: hidden;
  pointer-events: none;
}

.badge[data-open='true'] { visibility: visible; }

.badge__canvas {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ⚠️ THE ONLY INTERACTIVE SURFACE, AND IT FOLLOWS THE CARD PER FRAME.
   Sized from the card's projected rect each frame, so it is only ever as big
   as the card actually is. Everything else in .badge is pointer-events:none,
   so a touch a few pixels outside this box reaches the page untouched.

   ⚠️ `none`, NOT `pan-y`, AND THIS IS A DELIBERATE REVERSAL OF PART OF E3.
   pan-y was not a bug — it worked exactly as measured on Xinlu's phone, handing
   vertical to the page. He has chosen drag over scroll ON THE CARD'S OWN
   FOOTPRINT: a touch that starts inside this box drags the badge in any
   direction, and a touch that starts outside it scrolls the page normally.
   E3's finding stands for the rest of the page; it is overridden here, on
   purpose, for a box the size of the card.

   ⚠️ COUPLED TO THE GESTURE GATE in badge/index.js. Under `none` the page
   cannot scroll from this box, so the gate must NOT decline a vertical touch —
   declining would strand the gesture and nothing would move. Reverting this
   line to pan-y requires restoring the directional branch there. */
.badge__hit {
  position: absolute;
  pointer-events: auto;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
}

.badge[data-open='true'] .badge__hit { display: block; }
.badge:not([data-open='true']) .badge__hit { display: none; }

/* ⚠️ .badge__sr's DECLARATIONS MOVED TO css/base.css ON 2026-08-31 (106 §3.2),
   where they are shared with .u-sr-only. The class name is unchanged and no
   badge markup moved — only the recipe's home did, so the hero's new heading
   and the badge's two hidden strings cannot drift apart. base.css is linked
   before this sheet, so the cascade position is earlier; nothing in this file
   or any other overrides those nine properties for .badge__sr, checked. */

/* Grab affordance on hover-capable pointers only — 097 §5 branches on
   CAPABILITY, not width, and 098 §7.3 concurs: a landscape phone is
   desktop-width with no hover and must still get tap-flip. */
@media (hover: hover) and (pointer: fine) {
  .badge[data-open='true'] .badge__hit { cursor: grab; }
  .badge[data-grabbing='true'] .badge__hit { cursor: grabbing; }
}

/* ⚠️ Reduced motion: the badge arrives SETTLED — no drop, no arrival flip
   (097 §4). The arrival flip is what advertises the back face, so removing it
   leaves a sighted reduced-motion visitor with no cue that the card turns.
   098 §7.4 proposes a static front-face mark; that is Xinlu's call at the
   design gate and is NOT implemented here. Flagged, not decided. */
