/* ============================================================
   Password gate — the dialog that opens when a locked case study
   is clicked.

   THE CARD, THE SCRIM, THE ✕, THE OPENING AND THE MOBILE SHEET ARE
   NOT HERE — they are the shared Dialog (styles/dialog.css), which
   this only supplies a body to. What's below is the body and the
   wrong-code feedback — the card itself is not touched here at all.

   From Figma "Handover 2" (node 35055:1755): inside the shared card,
   centred and 16px apart, the lock badge (the same .lock circle the
   cover uses), the line "Password protected case study", and four
   8px-radius boxes for a four-digit code.

   Markup is built by scripts/passgate.js — there is no dialog in the
   page source, since it only ever exists once and only on demand.

     <div class="dialog dialog--keyboard passgate">
       …shell…
       <div class="dialog__body">
         <span class="lock">…</span>
         <p class="passgate__title">Password protected case study</p>
         <div class="passgate__code"> …four inputs… </div>
         <p class="passgate__status" role="status"></p>
       </div>
     </div>

   IT IS A `--keyboard` DIALOG. The code boxes summon the on-screen
   keyboard, so on a phone the sheet runs the full height of the
   screen rather than hugging its content — see the long note on that
   modifier in styles/dialog.css for why stopping short doesn't work.
   ============================================================ */

.passgate__title {
  margin: 0;
  font-size: var(--text-md);           /* 20px */
  line-height: var(--lh-md);           /* 32px */
  letter-spacing: var(--tracking-tight); /* Figma −0.4px on 20px = −0.02em */
  font-weight: var(--weight-regular);
  text-align: center;
}

.passgate__code {
  display: flex;
  gap: var(--space-8);
}

/* Figma sizes the box by its content (16px padding around a 16px/24px
   glyph). An <input> can't size to content, so the box is given that
   measured size outright — 56px tall, and a width that keeps the
   design's portrait proportion. */
.passgate__digit {
  width: 44px;
  height: 56px;
  box-sizing: border-box;
  padding: 0;
  border: 0;
  border-radius: var(--radius);        /* 8px — on-system */
  background: rgb(0 0 0 / 0.05);       /* Figma's 5% black */
  color: #000000;

  font-family: var(--font-sans);
  font-size: var(--text-sm);           /* 16px */
  line-height: var(--lh-sm);           /* 24px */
  letter-spacing: var(--tracking-tight);
  text-align: center;
}
.passgate__digit:focus-visible { outline: 2px solid #000; outline-offset: 2px; }

/* --- Wrong code -------------------------------------------------
   The design has no error state, and the DLS is monochrome, so there
   is no red to reach for. Feedback is therefore a shake plus clearing
   the boxes — the clearing is what carries it when motion is reduced,
   and .passgate__status announces it to screen readers.
   ---------------------------------------------------------------- */
@keyframes passgate-shake {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-6px); }
  40%      { transform: translateX(6px); }
  60%      { transform: translateX(-4px); }
  80%      { transform: translateX(4px); }
}
.passgate--wrong .dialog__card { animation: passgate-shake 320ms ease; }

@media (prefers-reduced-motion: reduce) {
  .passgate--wrong .dialog__card { animation: none; }
}

/* Announced, not shown — adding a visible error line would reflow the
   card, and the design has no slot for one. */
.passgate__status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- Mobile ------------------------------------------------------
   The sheet itself comes from `.dialog--keyboard`. The one thing the
   gate adds: shake the BOXES, not the sheet. A full-bleed sheet that
   slides sideways opens a sliver down its edge and reads as broken;
   the iOS passcode shakes its dots for the same reason.
   ---------------------------------------------------------------- */
@media (max-width: 640px) {
  .passgate--wrong .dialog__card { animation: none; }
  .passgate--wrong .passgate__code { animation: passgate-shake 320ms ease; }
}

@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  .passgate--wrong .passgate__code { animation: none; }
}
