/* ==========================================================================
   Features page: detail visuals. Loaded by features.html after
   assets/styles.css (the homepage's assets/home.css follows the same
   pattern). Uses the tokens from styles.css section 1; the pass-type accent
   themes (html[data-pass]) apply here too.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Scanner app preview (Stow Cards Merchant)
   -------------------------------------------------------------------------- */
/* [feat-scanner] */
/* Two phones running the real Stow Cards Merchant app (stow-frontend/apps/merchant-mobile):
   the scanner (ScannerScreen CameraView "full" + Reticle) and the member screen it opens
   (MemberDetailScreen with fromScan, which auto-opens the Adjust points ActionSheet).
   Inside the screens the app keeps its own palette, type and spacing: the tokens of
   src/styles/base.css in the default emerald colour theme, and the sizes of src/styles/v3.css.
   Each screen is drawn on the app's 390 x 844 pt canvas: --a is one point (100cqw / 390 of the
   screen), so every size scales with the phone, the way .pass-card derives --u from its width.
   The frames and the stage around them stay Roastery. Geist is set in Inter (already loaded);
   Instrument Serif is self-hosted from @fontsource (OFL, assets/fonts/instrument-serif-OFL.txt). */
@font-face {
  font-family: "Instrument Serif";
  src: url("fonts/instrument-serif-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Stage: two overlapping phones, the scanner behind and the member screen in front, lower.
   Beside the copy the stage borrows half of the split's 60px gap so the screens stay larger. */
@media (min-width: 861px) {
  .mx-scan { margin-left: -30px; }
}
.mx-scan__stage {
  container-type: inline-size;
  position: relative;
  display: flex;
  align-items: flex-start;
  max-width: 600px;
  margin-inline: auto;
  padding-bottom: 6px;
}
.mx-phone {
  --pw: 51.5cqw;
  position: relative;
  flex: none;
  width: var(--pw);
  padding: calc(var(--pw) * .032);
  border-radius: calc(var(--pw) * .165);
  background: linear-gradient(155deg, #4A3021, #1C110B 45%, #33211A);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .1), inset 0 0 0 3px rgba(0, 0, 0, .35), var(--shadow-pop);
}
.mx-phone--scan { z-index: 1; }
.mx-phone--member { z-index: 2; margin-left: -3cqw; margin-top: 11cqw; }
.mx-phone__screen {
  container-type: inline-size;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  aspect-ratio: 390 / 844;
  border-radius: calc(var(--pw) * .135);
  background: #0B0A07;
}
/* Narrow stages: bigger phones that overlap more, so the screens stay readable */
@container (max-width: 440px) {
  .mx-phone { --pw: 58cqw; }
  .mx-phone--member { margin-left: -16cqw; margin-top: 13cqw; }
}

/* The app canvas and its tokens (base.css :root + [data-color-theme="emerald"]) */
.mx-app {
  --a: calc(100cqw / 390);
  --m-bg: #F7F4EC;
  --m-surface: #FFFFFF;
  --m-surface-2: #FBF8F1;
  --m-surface-3: #F0EADB;
  --m-ink: #0F0E0B;
  --m-ink-2: #2A271F;
  --m-muted: #6B665A;
  --m-line: #E5DECC;
  --m-line-2: #D2C9B0;
  --m-line-strong: #B8AE92;
  --m-accent: #0F6F5C;
  --m-gold: #B68329;
  --m-gold-soft: #F8EFD6;
  --m-cam-ink: #F2EBD7;
  --m-serif: "Instrument Serif", "Times New Roman", Georgia, serif;
  --m-sans: Geist, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
  --m-mono: "JetBrains Mono", ui-monospace, monospace;
  position: absolute;
  inset: 0;
  overflow: hidden;
  font-family: var(--m-sans);
  font-size: calc(14 * var(--a));
  line-height: 1.45;
  letter-spacing: -.005em;
  color: var(--m-ink);
  text-align: left;
  -webkit-font-smoothing: antialiased;
}
.mx-app b { font-weight: 600; }
.mx-app svg { display: block; flex: none; }
.mx-serif { font-family: var(--m-serif); font-weight: 400 !important; }

/* iOS status bar + Dynamic Island (the device, not the app) */
.mx-sb {
  position: absolute;
  z-index: 30;
  top: calc(100cqw / 390 * 13);
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: calc(100cqw / 390 * 34);
  padding: 0 calc(100cqw / 390 * 30) 0 calc(100cqw / 390 * 44);
  font: 600 calc(100cqw / 390 * 16) / 1 var(--font-wallet);
  letter-spacing: -.01em;
  color: #0F0E0B;
}
.mx-sb--light { color: #FFFFFF; }
.mx-sb__icons { display: flex; align-items: center; gap: calc(100cqw / 390 * 6); }
.mx-sb__icons svg { display: block; height: calc(100cqw / 390 * 12); width: auto; }
.mx-sb__icons svg:first-child { height: calc(100cqw / 390 * 11.5); }
.mx-island {
  position: absolute;
  z-index: 31;
  top: calc(100cqw / 390 * 11);
  left: 50%;
  width: calc(100cqw / 390 * 122);
  height: calc(100cqw / 390 * 36);
  translate: -50% 0;
  border-radius: 999px;
  background: #000;
}

/* ---- Phone 1: the scanner (v3.css .v3top / .v3hint / .v3detecting + ScannerScreen Reticle) ---- */
.mx-cam { background: #0B0A07; color: var(--m-cam-ink); }
/* The camera feed: the customer holds up their phone at the counter, the Harbor Coffee pass open
   in Wallet and its QR code inside the frame (the real, scannable assets/passes/qr-7K2Q9FMRDC.svg) */
.mx-cam__feed {
  position: absolute;
  inset: 0;
  background: radial-gradient(80% 58% at 50% 54%, #574435 0%, #33271E 52%, #15100C 100%);
}
.mx-cam__held {
  position: absolute;
  left: calc(43 * var(--a));
  top: calc(104 * var(--a));
  width: calc(304 * var(--a));
  height: calc(700 * var(--a));
  border-radius: calc(52 * var(--a));
  background: #0B0B0C;
  box-shadow: inset 0 0 0 calc(7 * var(--a)) #232326, inset 0 0 0 calc(8 * var(--a)) rgba(255, 255, 255, .07), 0 calc(24 * var(--a)) calc(44 * var(--a)) rgba(0, 0, 0, .55);
  rotate: -3deg;
}
.mx-cam__held .mx-cam__pass {
  position: absolute;
  left: calc(17 * var(--a));
  top: calc(76 * var(--a));
  width: calc(270 * var(--a));
  max-width: none;
  margin: 0;
  filter: none;
}
.mx-ret { position: absolute; inset: 0; display: grid; place-items: center; }
.mx-ret__box {
  position: relative;
  width: 72%;
  aspect-ratio: 1;
  border-radius: calc(18 * var(--a));
  box-shadow: 0 0 0 999px rgba(11, 10, 7, .45);
}
.mx-ret__box i {
  position: absolute;
  width: calc(34 * var(--a));
  height: calc(34 * var(--a));
  border: 0 solid var(--m-accent);
}
.mx-ret__box i:nth-child(1) { top: -1px; left: -1px; border-top-width: calc(3 * var(--a)); border-left-width: calc(3 * var(--a)); border-top-left-radius: calc(18 * var(--a)); }
.mx-ret__box i:nth-child(2) { top: -1px; right: -1px; border-top-width: calc(3 * var(--a)); border-right-width: calc(3 * var(--a)); border-top-right-radius: calc(18 * var(--a)); }
.mx-ret__box i:nth-child(3) { bottom: -1px; left: -1px; border-bottom-width: calc(3 * var(--a)); border-left-width: calc(3 * var(--a)); border-bottom-left-radius: calc(18 * var(--a)); }
.mx-ret__box i:nth-child(4) { bottom: -1px; right: -1px; border-bottom-width: calc(3 * var(--a)); border-right-width: calc(3 * var(--a)); border-bottom-right-radius: calc(18 * var(--a)); }
/* The scan line sits still, as in the app */
.mx-ret__box b {
  position: absolute;
  left: 8%;
  right: 8%;
  top: 50%;
  height: calc(2 * var(--a));
  background: linear-gradient(90deg, transparent, var(--m-accent), transparent);
  box-shadow: 0 0 calc(16 * var(--a)) var(--m-accent);
}
.mx-top {
  position: absolute;
  z-index: 6;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(56 * var(--a)) calc(18 * var(--a)) calc(14 * var(--a));
  background: linear-gradient(180deg, rgba(0, 0, 0, .55), transparent);
}
.mx-dbtn {
  display: grid;
  place-items: center;
  width: calc(42 * var(--a));
  height: calc(42 * var(--a));
  border-radius: calc(12 * var(--a));
  background: rgba(255, 255, 255, .12);
  color: var(--m-cam-ink);
}
.mx-dbtn svg { width: calc(20 * var(--a)); height: calc(20 * var(--a)); }
.mx-pill {
  display: inline-flex;
  align-items: center;
  gap: calc(8 * var(--a));
  height: calc(34 * var(--a));
  padding: 0 calc(12 * var(--a));
  border-radius: 999px;
  background: rgba(255, 255, 255, .12);
  font-size: calc(12.5 * var(--a));
  font-weight: 500;
  white-space: nowrap;
}
.mx-pill i { width: calc(7 * var(--a)); height: calc(7 * var(--a)); border-radius: 50%; background: var(--m-accent); }
.mx-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(80 * var(--a));
  text-align: center;
  font: 500 calc(11 * var(--a)) / 1.45 var(--m-mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(242, 235, 215, .7);
}
.mx-detect {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: calc(12 * var(--a));
  padding: calc(18 * var(--a)) calc(16 * var(--a)) calc(24 * var(--a));
  border-top: 1px solid #1F1D17;
  background: #0B0A07;
  font-size: calc(13.5 * var(--a));
  font-weight: 500;
}
.mx-sp {
  flex: none;
  width: calc(18 * var(--a));
  height: calc(18 * var(--a));
  border-radius: 50%;
  border: calc(2.5 * var(--a)) solid rgba(242, 235, 215, .25);
  border-top-color: var(--m-accent);
  animation: mx-spin .8s linear infinite;
}
@keyframes mx-spin { to { rotate: 360deg; } }
.mx-lk {
  display: inline-flex;
  align-items: center;
  gap: calc(7 * var(--a));
  height: calc(38 * var(--a));
  margin-left: auto;
  padding: 0 calc(13 * var(--a));
  border-radius: 999px;
  background: rgba(255, 255, 255, .1);
  font-size: calc(12.5 * var(--a));
}
.mx-lk svg { width: calc(18 * var(--a)); height: calc(18 * var(--a)); }

/* ---- Phone 2: member detail + the Adjust points sheet (base.css, v3.css, MemberDetailScreen) ---- */
.mx-det { background: var(--m-bg); }
.mx-nav { display: flex; align-items: center; gap: calc(10 * var(--a)); padding: calc(52 * var(--a)) calc(16 * var(--a)) calc(12 * var(--a)); }
.mx-nav b { flex: 1; min-width: 0; font-size: calc(20 * var(--a)); line-height: 1.05; letter-spacing: -.01em; }
.mx-ib { display: grid; place-items: center; flex: none; width: calc(44 * var(--a)); height: calc(44 * var(--a)); color: var(--m-ink); }
.mx-ib svg { width: calc(20 * var(--a)); height: calc(20 * var(--a)); }
.mx-ib--lg svg { width: calc(22 * var(--a)); height: calc(22 * var(--a)); }
.mx-body { padding: calc(8 * var(--a)) calc(16 * var(--a)); }
.mx-id { display: flex; align-items: center; gap: calc(14 * var(--a)); padding: calc(2 * var(--a)) calc(2 * var(--a)) calc(12 * var(--a)); }
.mx-id > div { min-width: 0; }
.mx-av {
  display: grid;
  place-items: center;
  flex: none;
  width: calc(60 * var(--a));
  height: calc(60 * var(--a));
  border-radius: 50%;
  background: var(--m-gold-soft);
  color: var(--m-gold);
  font: italic 400 calc(20 * var(--a)) / 1 var(--m-serif);
}
.mx-nm { font: 400 calc(24 * var(--a)) / 1.45 var(--m-serif); white-space: nowrap; }
.mx-code { font: 500 calc(14 * var(--a)) / 1.45 var(--m-mono); letter-spacing: 0; }
.mx-tiers { display: flex; gap: calc(6 * var(--a)); margin-top: calc(6 * var(--a)); }
.mx-tier {
  display: inline-flex;
  align-items: center;
  padding: calc(3 * var(--a)) calc(9 * var(--a));
  border-radius: 999px;
  background: var(--m-surface-3);
  color: var(--m-ink-2);
  font: 500 calc(10 * var(--a)) / 1.45 var(--m-mono);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.mx-tier--gold { background: var(--m-gold-soft); color: var(--m-gold); }
.mx-eb { display: block; font: 500 calc(10.5 * var(--a)) / 1.45 var(--m-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--m-muted); }
.mx-prog { display: flex; align-items: flex-start; gap: calc(12 * var(--a)); padding: 0 calc(2 * var(--a)) calc(14 * var(--a)); }
.mx-prog > div { flex: 1; min-width: 0; }
.mx-prog b { display: block; font-size: calc(15 * var(--a)); white-space: nowrap; }
.mx-prog small { display: block; margin-top: calc(1 * var(--a)); font-size: calc(12 * var(--a)); color: var(--m-muted); }
.mx-kpis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: calc(8 * var(--a)); }
.mx-kpi {
  display: flex;
  flex-direction: column;
  gap: calc(3 * var(--a));
  padding: calc(15 * var(--a));
  border: 1px solid var(--m-line);
  border-radius: calc(16 * var(--a));
  background: var(--m-surface);
}
.mx-kpi span { font: 500 calc(10 * var(--a)) / 1.45 var(--m-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--m-muted); }
.mx-kpi b { font-size: calc(15 * var(--a)); line-height: 1.1; }
.mx-kpi b.mx-serif { font-size: calc(26 * var(--a)); line-height: 1; letter-spacing: -.025em; }
.mx-tabs { display: flex; margin: calc(18 * var(--a)) 0 calc(16 * var(--a)); border-bottom: 1px solid var(--m-line); }
.mx-tabs span { position: relative; flex: 1; padding: calc(11 * var(--a)) 0; text-align: center; font-size: calc(13 * var(--a)); font-weight: 500; color: var(--m-muted); }
.mx-tabs .is-on { color: var(--m-ink); }
.mx-tabs .is-on::after { content: ""; position: absolute; left: 20%; right: 20%; bottom: -1px; height: calc(2 * var(--a)); background: var(--m-accent); }
.mx-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(8 * var(--a));
  height: calc(48 * var(--a));
  padding: 0 calc(12 * var(--a));
  border-radius: calc(12 * var(--a));
  font-size: calc(15 * var(--a));
  font-weight: 500;
  white-space: nowrap;
}
.mx-btn--primary { background: var(--m-accent); color: #FFFFFF; }
.mx-btn--outline { box-shadow: inset 0 0 0 1px var(--m-line-strong); color: var(--m-ink); }
.mx-btn svg { width: calc(22 * var(--a)); height: calc(22 * var(--a)); }
/* The action sheet the scan opens (v3.css .sheet-scrim / .sheet) */
.mx-scrim { position: absolute; z-index: 20; inset: 0; background: rgba(11, 10, 7, .45); }
.mx-sheet {
  position: absolute;
  z-index: 21;
  left: 0;
  right: 0;
  bottom: 0;
  padding: calc(10 * var(--a)) calc(18 * var(--a)) calc(26 * var(--a));
  border-radius: calc(24 * var(--a)) calc(24 * var(--a)) 0 0;
  background: var(--m-surface);
  box-shadow: 0 calc(28 * var(--a)) calc(60 * var(--a)) calc(-20 * var(--a)) rgba(0, 0, 0, .5);
}
.mx-grip { width: calc(42 * var(--a)); height: calc(4 * var(--a)); margin: 0 auto calc(14 * var(--a)); border-radius: 99px; background: var(--m-line-2); }
.mx-sheet__head { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: calc(10 * var(--a)); }
.mx-sheet__head b { font-size: calc(22 * var(--a)); line-height: 1.45; letter-spacing: -.01em; }
.mx-sheet__head .mx-ib { margin: calc(-6 * var(--a)) calc(-8 * var(--a)) 0 0; }
.mx-sheet > .mx-eb { margin-top: calc(2 * var(--a)); }
.mx-bal { display: flex; align-items: baseline; gap: calc(8 * var(--a)); margin: calc(2 * var(--a)) 0 calc(16 * var(--a)); }
.mx-bal b { font-size: calc(30 * var(--a)); line-height: 1; }
.mx-bal span { font: 500 calc(12 * var(--a)) / 1 var(--m-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--m-muted); }
.mx-field { display: flex; flex-direction: column; gap: calc(6 * var(--a)); margin-bottom: calc(14 * var(--a)); }
.mx-field__l { font: 500 calc(12 * var(--a)) / 1.45 var(--m-mono); letter-spacing: .04em; text-transform: uppercase; color: var(--m-muted); }
.mx-step { display: flex; gap: calc(8 * var(--a)); }
.mx-step span,
.mx-step b { display: grid; place-items: center; height: calc(50 * var(--a)); border: 1px solid var(--m-line); border-radius: calc(12 * var(--a)); }
.mx-step span { flex: none; width: calc(54 * var(--a)); background: var(--m-surface); font-size: calc(24 * var(--a)); line-height: 1; }
.mx-step b { flex: 1; background: var(--m-surface-2); font-size: calc(18 * var(--a)); }
.mx-input {
  display: flex;
  align-items: center;
  height: calc(48 * var(--a));
  padding: 0 calc(14 * var(--a));
  border: 1px solid var(--m-line);
  border-radius: calc(11 * var(--a));
  background: var(--m-surface);
  font-size: calc(16 * var(--a));
  color: var(--m-muted);
}
.mx-acts { display: grid; grid-template-columns: 1fr 1.5fr; gap: calc(10 * var(--a)); margin-top: calc(4 * var(--a)); }

/* After the section reveals, the sheet slides up the way the app opens it (v3up), as if the scan
   just landed. Scripts off, reduced motion or no reveal: it is simply open. */
html.js .mx-scan .mx-sheet { transition: translate .42s cubic-bezier(.2, .8, .2, 1) .75s; }
html.js .mx-scan .mx-scrim { transition: opacity .3s linear .7s; }
html.js .mx-scan:not(.in) .mx-sheet { translate: 0 105%; }
html.js .mx-scan:not(.in) .mx-scrim { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .mx-sp { animation: none; }
  html.js .mx-scan .mx-sheet,
  html.js .mx-scan .mx-scrim { transition: none; }
  html.js .mx-scan:not(.in) .mx-sheet { translate: none; }
  html.js .mx-scan:not(.in) .mx-scrim { opacity: 1; }
}

/* --------------------------------------------------------------------------
   2. NFC tap-to-redeem
   -------------------------------------------------------------------------- */
/* [feat-nfc] */
/* The tap at the till, drawn top-down on a maple counter: the customer's phone held flat over a
   generic countertop NFC reader, the reader cabled to the till. Facts from docs/nfc-passes.md,
   docs/apple-nfc-roadmap.md, docs/google-nfc-roadmap.md and docs/vtap100-nfc-operations.md: Wallet
   sends an encrypted STOW:{serial}:{HMAC tag} token (pass-service services/nfcPayload.ts), the
   reader decrypts it, Stow resolves the member (merchant-service readerRoutes.ts
   extractScanIdentifier) and staff pick the loyalty action. The Merchant app reads no NFC, so the
   till is drawn unbranded. Wallet strings: only Apple's "Hold Near Reader" and "Done".
   --nfc-s is one scene unit: the counter is 540 units wide (336 in the narrow layout), so the whole
   scene scales with its column, the way .pass-card derives --u from its width. The radios switch
   Apple and Google without JS; the animation plays once when the column reveals (and again on a
   switch), and the resting state is the finished tap, so no-JS and reduced motion get it whole. */
@property --nfc-s { syntax: "<length>"; inherits: true; initial-value: 1px; }

.nfc-demo { container: nfc / inline-size; max-width: 560px; margin-inline: auto; }

/* Wallet switch: a segmented pill of two native radios */
.nfc-switch-wrap { display: flex; justify-content: center; margin-bottom: 18px; }
.nfc-switch {
  display: inline-flex;
  min-inline-size: 0;
  margin: 0;
  padding: 3px;
  border: 0;
  border-radius: 999px;
  box-shadow: inset 0 0 0 2px var(--ink);
}
.nfc-switch label {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 8px 16px;
  border-radius: 999px;
  font: 700 13.5px / 1 var(--font-body);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .2s ease, color .2s ease;
}
.nfc-switch input:checked + label { background: var(--ink); color: var(--paper); }
.nfc-switch input:focus-visible + label { outline: 2.5px solid var(--brand); outline-offset: 3px; }
.nfc-switch input:not(:checked) + label:hover { background: rgba(43, 26, 18, .08); }

/* One scene per wallet; the Google one shows when its radio is checked */
.nfc-scene {
  --nfc-cw: 540;
  --nfc-ch: 568;
  --nfc-cx: 152;
  --nfc-s: calc(100cqw / var(--nfc-cw));
  position: relative;
}
.nfc-scene--google,
.nfc-g { display: none; }
.nfc-demo:has(#nfc-w-google:checked) .nfc-scene--apple,
.nfc-demo:has(#nfc-w-google:checked) .nfc-a { display: none; }
.nfc-demo:has(#nfc-w-google:checked) .nfc-scene--google { display: block; }
.nfc-demo:has(#nfc-w-google:checked) .nfc-g { display: inline; }

/* The counter: maple with a hard lip, grain on top */
.nfc-counter {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  aspect-ratio: var(--nfc-cw) / var(--nfc-ch);
  border-radius: calc(26 * var(--nfc-s));
  background:
    radial-gradient(90% 60% at 18% 0%, rgba(255, 248, 238, .38), transparent 62%),
    repeating-linear-gradient(93deg, rgba(120, 78, 42, .055) 0 3px, transparent 3px 11px, rgba(120, 78, 42, .03) 11px 13px, transparent 13px 23px),
    linear-gradient(168deg, #D9BD93, #C9A67A);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 calc(7 * var(--nfc-s)) 0 #AC875C, 0 30px 44px -28px rgba(43, 26, 18, .6);
}
.nfc-counter::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--grain);
  opacity: .2;
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* The USB cable from the reader to the till */
.nfc-cable { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; max-width: none; overflow: visible; fill: none; }
.nfc-cable path { stroke: #2B1A12; stroke-width: 7; stroke-linecap: round; filter: drop-shadow(2px 3px 2px rgba(43, 26, 18, .3)); }

/* The reader: a generic countertop pad, no vendor marks. Status light, a check when it has read a
   pass, and the tap target the phone covers */
.nfc-reader {
  position: absolute;
  z-index: 2;
  left: calc((var(--nfc-cx) - 118) * var(--nfc-s));
  top: calc(28 * var(--nfc-s));
  width: calc(236 * var(--nfc-s));
  height: calc(204 * var(--nfc-s));
  border-radius: calc(44 * var(--nfc-s));
  background: linear-gradient(160deg, #43342B, #1F1712 72%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14), 0 calc(5 * var(--nfc-s)) 0 #140D09, calc(6 * var(--nfc-s)) calc(16 * var(--nfc-s)) calc(22 * var(--nfc-s)) rgba(26, 14, 8, .38);
}
.nfc-reader::before {
  content: "";
  position: absolute;
  inset: calc(11 * var(--nfc-s));
  border-radius: calc(34 * var(--nfc-s));
  background: linear-gradient(170deg, #2F241E, #251B16);
  box-shadow: inset 0 calc(1 * var(--nfc-s)) calc(3 * var(--nfc-s)) rgba(0, 0, 0, .45);
}
.nfc-reader__led {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: calc(20 * var(--nfc-s));
  width: calc(58 * var(--nfc-s));
  height: calc(6 * var(--nfc-s));
  margin-left: calc(-29 * var(--nfc-s));
  border-radius: 99px;
  background: #86D97F;
  box-shadow: 0 0 calc(12 * var(--nfc-s)) calc(2 * var(--nfc-s)) rgba(134, 217, 127, .55);
}
.nfc-reader__ok {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: calc(36 * var(--nfc-s));
  display: grid;
  place-items: center;
  width: calc(30 * var(--nfc-s));
  height: calc(30 * var(--nfc-s));
  margin-left: calc(-15 * var(--nfc-s));
  border-radius: 50%;
  background: #3B8A39;
  box-shadow: 0 0 0 calc(3 * var(--nfc-s)) rgba(134, 217, 127, .22);
}
.nfc-reader__ok svg { width: 72%; height: 72%; fill: none; stroke: #FFFFFF; stroke-width: 2.8; stroke-linecap: round; stroke-linejoin: round; }
.nfc-reader__ring {
  position: absolute;
  z-index: 1;
  left: calc(66 * var(--nfc-s));
  top: calc(70 * var(--nfc-s));
  width: calc(104 * var(--nfc-s));
  height: calc(104 * var(--nfc-s));
  border-radius: 50%;
  background: radial-gradient(circle, rgba(243, 233, 218, .06), transparent 70%);
  box-shadow: inset 0 0 0 calc(2 * var(--nfc-s)) rgba(243, 233, 218, .16);
}

/* The field: rings that spread from the contact point while the phone talks to the reader */
.nfc-field {
  position: absolute;
  z-index: 3;
  left: calc((var(--nfc-cx) - 125) * var(--nfc-s));
  top: calc(25 * var(--nfc-s));
  width: calc(250 * var(--nfc-s));
  height: calc(250 * var(--nfc-s));
  pointer-events: none;
}
.nfc-field span {
  position: absolute;
  inset: 0;
  border: calc(2 * var(--nfc-s)) solid color-mix(in srgb, var(--brand-bright) 70%, #FFF8EE);
  border-radius: 50%;
  opacity: 0;
}

/* A flat white of Harbor Coffee's, for scale */
.nfc-cup {
  position: absolute;
  z-index: 2;
  left: calc(396 * var(--nfc-s));
  top: calc(452 * var(--nfc-s));
  width: calc(104 * var(--nfc-s));
  height: calc(104 * var(--nfc-s));
  border-radius: 50%;
  background: radial-gradient(circle, #F7F1E7 56%, #E9DDC9 58%, #F3EADC 68%);
  box-shadow: calc(4 * var(--nfc-s)) calc(8 * var(--nfc-s)) calc(12 * var(--nfc-s)) rgba(26, 14, 8, .26), inset 0 0 0 1px rgba(92, 58, 33, .12);
}
.nfc-cup::before {
  content: "";
  position: absolute;
  z-index: 1;
  inset: calc(17 * var(--nfc-s));
  border: calc(6 * var(--nfc-s)) solid #FFFDF8;
  border-radius: 50%;
  background: radial-gradient(circle at 46% 44%, #E4C29A 0 16%, #B07A4B 34%, #6E4225 62%, #4A2A16 80%);
  box-shadow: calc(2 * var(--nfc-s)) calc(4 * var(--nfc-s)) calc(6 * var(--nfc-s)) rgba(26, 14, 8, .25);
}
.nfc-cup::after {
  content: "";
  position: absolute;
  right: calc(3 * var(--nfc-s));
  top: 50%;
  width: calc(22 * var(--nfc-s));
  height: calc(13 * var(--nfc-s));
  margin-top: calc(-6.5 * var(--nfc-s));
  border-radius: calc(7 * var(--nfc-s));
  background: #FFFDF8;
  box-shadow: calc(2 * var(--nfc-s)) calc(3 * var(--nfc-s)) calc(4 * var(--nfc-s)) rgba(26, 14, 8, .2);
}

/* The phone, held flat with its top over the tap target (where an iPhone's NFC antenna sits) */
.nfc-phone {
  position: absolute;
  z-index: 4;
  left: calc((var(--nfc-cx) - 94) * var(--nfc-s));
  top: calc(150 * var(--nfc-s));
  width: calc(188 * var(--nfc-s));
  height: calc(396 * var(--nfc-s));
  transform: rotate(-4deg);
  transform-origin: 50% 0;
}
/* The contactless field at the contact point: plain arcs, not a payment mark */
.nfc-arcs {
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: calc(48 * var(--nfc-s));
  height: calc(32 * var(--nfc-s));
  max-width: none;
  margin: 0 0 calc(2 * var(--nfc-s)) calc(-24 * var(--nfc-s));
  overflow: visible;
  fill: none;
  stroke: var(--brand-bright);
  stroke-width: 3.4;
  stroke-linecap: round;
}
.nfc-phone__body {
  --nfc-bez: inset 0 0 0 calc(1.5 * var(--nfc-s)) rgba(255, 255, 255, .1);
  --nfc-low: calc(8 * var(--nfc-s)) calc(14 * var(--nfc-s)) calc(16 * var(--nfc-s)) rgba(26, 14, 8, .42), calc(2 * var(--nfc-s)) calc(3 * var(--nfc-s)) calc(4 * var(--nfc-s)) rgba(26, 14, 8, .3);
  --nfc-high: calc(26 * var(--nfc-s)) calc(46 * var(--nfc-s)) calc(40 * var(--nfc-s)) rgba(26, 14, 8, .26), calc(10 * var(--nfc-s)) calc(18 * var(--nfc-s)) calc(16 * var(--nfc-s)) rgba(26, 14, 8, .16);
  width: 100%;
  height: 100%;
  padding: calc(7 * var(--nfc-s));
  border-radius: calc(36 * var(--nfc-s));
  background: linear-gradient(155deg, #4A3021, #1C110B 45%, #33211A);
  box-shadow: var(--nfc-bez), var(--nfc-low);
}
.nfc-phone--android .nfc-phone__body { border-radius: calc(24 * var(--nfc-s)); background: linear-gradient(155deg, #3E3935, #171514 48%, #2B2724); }
.nfc-phone__screen {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border-radius: calc(29 * var(--nfc-s));
  background: #15100D;
  color: #F5F5F7;
}
.nfc-phone--android .nfc-phone__screen { border-radius: calc(17 * var(--nfc-s)); background: #141211; }
.nfc-phone__status {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: calc(28 * var(--nfc-s));
  padding: 0 calc(17 * var(--nfc-s)) 0 calc(20 * var(--nfc-s));
  font: 600 calc(10.5 * var(--nfc-s)) / 1 var(--font-wallet);
}
.nfc-phone--android .nfc-phone__status { font-family: var(--font-google); font-weight: 500; padding-left: calc(14 * var(--nfc-s)); }
/* Dynamic Island on the iPhone, a punch-hole camera on the Android phone */
.nfc-phone__cam {
  position: absolute;
  left: 50%;
  top: calc(7 * var(--nfc-s));
  width: calc(46 * var(--nfc-s));
  height: calc(14 * var(--nfc-s));
  margin-left: calc(-23 * var(--nfc-s));
  border-radius: 99px;
  background: #000000;
}
.nfc-phone--android .nfc-phone__cam { top: calc(8 * var(--nfc-s)); width: calc(10 * var(--nfc-s)); height: calc(10 * var(--nfc-s)); margin-left: calc(-5 * var(--nfc-s)); box-shadow: 0 0 0 calc(1.5 * var(--nfc-s)) #2A2624; }
.nfc-phone__bat {
  position: relative;
  width: calc(17 * var(--nfc-s));
  height: calc(8 * var(--nfc-s));
  border-radius: calc(2.5 * var(--nfc-s));
  box-shadow: inset 0 0 0 calc(1.2 * var(--nfc-s)) rgba(245, 245, 247, .75);
  background: linear-gradient(90deg, #F5F5F7 0 70%, transparent 70%) calc(2.2 * var(--nfc-s)) 50% / calc(12.6 * var(--nfc-s)) calc(3.6 * var(--nfc-s)) no-repeat;
}
.nfc-phone__home {
  position: absolute;
  left: 50%;
  bottom: calc(6 * var(--nfc-s));
  width: calc(62 * var(--nfc-s));
  height: calc(4 * var(--nfc-s));
  margin-left: calc(-31 * var(--nfc-s));
  border-radius: 99px;
  background: rgba(245, 245, 247, .6);
}
.nfc-phone--android .nfc-phone__home { width: calc(52 * var(--nfc-s)); height: calc(3.5 * var(--nfc-s)); margin-left: calc(-26 * var(--nfc-s)); }

/* Apple Wallet presenting the pass: the face at its real proportions, then the prompt under it */
.nfc-phone__pass { flex: none; margin: calc(4 * var(--nfc-s)) calc(8 * var(--nfc-s)) 0; }
/* No filter here: on the rotated phone a filter layer resamples the barcode twice and blurs it
   past scanning at 1x; a box-shadow on the face does not */
.nfc-phone__pass .pass-card { max-width: none; margin: 0; filter: none; }
.nfc-phone__pass .pass-card__face { box-shadow: 0 calc(4 * var(--nfc-s)) calc(8 * var(--nfc-s)) rgba(0, 0, 0, .35); }
.nfc-ios {
  flex: 1;
  display: grid;
  place-items: center;
  padding-bottom: calc(14 * var(--nfc-s));
  font: 600 calc(13 * var(--nfc-s)) / 1.2 var(--font-wallet);
  letter-spacing: -.005em;
}
.nfc-ios > span { grid-area: 1 / 1; }
.nfc-ios__hold { opacity: 0; color: rgba(245, 245, 247, .9); }
.nfc-ios__done { display: flex; flex-direction: column; align-items: center; gap: calc(6 * var(--nfc-s)); }
.nfc-ios__done svg { width: calc(30 * var(--nfc-s)); height: calc(30 * var(--nfc-s)); fill: none; stroke: #F5F5F7; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* Google Wallet: the same member's card, 156 of the screen's 172 units, 380 dp wide on Google's grid */
.nfc-phone__gcard { flex: none; margin: auto calc(8 * var(--nfc-s)); }
.nfc-phone__gcard .google-pass { --u: calc(var(--nfc-s) * 156 / 380); box-shadow: 0 calc(4 * var(--nfc-s)) calc(10 * var(--nfc-s)) rgba(0, 0, 0, .35); }

/* The till: a tablet on the counter, cabled to the reader */
.nfc-till {
  position: absolute;
  z-index: 5;
  left: calc(298 * var(--nfc-s));
  top: calc(138 * var(--nfc-s));
  width: calc(222 * var(--nfc-s));
  padding: calc(9 * var(--nfc-s));
  border-radius: calc(22 * var(--nfc-s));
  background: linear-gradient(155deg, #3A2519, #1C110B 55%, #2E1D14);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .08), 0 calc(5 * var(--nfc-s)) 0 #140D09, calc(6 * var(--nfc-s)) calc(14 * var(--nfc-s)) calc(18 * var(--nfc-s)) rgba(26, 14, 8, .4);
  text-align: left;
}
.nfc-till__screen {
  display: grid;
  gap: calc(12 * var(--nfc-s));
  padding: calc(12 * var(--nfc-s)) calc(13 * var(--nfc-s)) calc(14 * var(--nfc-s));
  border-radius: calc(14 * var(--nfc-s));
  background: var(--paper);
  font-family: var(--font-body);
  color: var(--ink);
}
.nfc-till__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding-bottom: calc(10 * var(--nfc-s));
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.nfc-till__bar > span:first-child { display: inline-flex; align-items: center; gap: 6px; }
.nfc-till__bar svg { width: 15px; height: 10px; overflow: visible; fill: none; stroke: var(--brand); stroke-width: 4; stroke-linecap: round; }
.nfc-till__states { display: grid; }
.nfc-till__states > div { grid-area: 1 / 1; }
.nfc-till__idle {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  opacity: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-3);
}
.nfc-till__idle i { display: block; width: 78%; height: 8px; border-radius: 4px; background: rgba(92, 58, 33, .1); }
.nfc-till__idle i:last-child { width: 52%; }
.nfc-till__match { display: grid; grid-template-areas: "pill" "who" "pts" "btn"; gap: calc(11 * var(--nfc-s)); }
.nfc-till__pill {
  grid-area: pill;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  border-radius: 999px;
  background: rgba(63, 106, 44, .14);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.3;
  color: #355A25;
}
.nfc-till__pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #3F8A33; }
.nfc-till__who { grid-area: who; display: flex; align-items: center; gap: 10px; min-width: 0; }
.nfc-till__who > span:last-child { min-width: 0; }
.nfc-till__av {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: #7B4A2A;
  color: #FFF8EE;
  font: 700 14px / 1 var(--font-head);
}
.nfc-till__who b { display: block; font-size: 15px; line-height: 1.25; color: var(--ink); white-space: nowrap; }
.nfc-till__who small,
.nfc-till__pts small { display: block; font-size: 12px; line-height: 1.35; color: var(--ink-3); }
.nfc-till__who small { white-space: nowrap; }
.nfc-till__pts small { text-wrap: balance; }
.nfc-till__pts { grid-area: pts; display: flex; align-items: baseline; gap: 8px; }
.nfc-till__pts b { font: 700 26px / 1 var(--font-head); color: var(--ink); }
.nfc-till__btn { grid-area: btn; font-size: 12.5px; padding: 9px 13px; }

/* The three beats, under the scene */
.nfc-steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
  text-align: left;
}
.nfc-step {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 14px 16px;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--shadow-card);
}
.nfc-step__n {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin-bottom: 6px;
  border-radius: 50%;
  background-color: var(--brand-btn);
  box-shadow: 0 2px 0 var(--brand-lip);
  font: 700 14px / 1 var(--font-head);
  color: var(--paper);
}
.nfc-step__t { font-size: 14.5px; font-weight: 700; line-height: 1.3; color: var(--ink); }
.nfc-step__d { font-size: 13.5px; line-height: 1.45; color: var(--ink-2); }

/* Mid columns: the beats stack under the scene */
@container nfc (max-width: 539px) {
  .nfc-steps { grid-template-columns: minmax(0, 1fr); gap: 10px; margin-top: 22px; }
  .nfc-step { display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: 12px; row-gap: 2px; padding: 12px 14px; }
  .nfc-step__n { grid-row: span 2; margin: 0; }
}
/* Narrow columns: the till moves under the counter, which stops growing at 380px */
@container nfc (max-width: 439px) {
  .nfc-scene { --nfc-cw: 336; --nfc-cx: 168; --nfc-s: calc(min(100cqw, 380px) / var(--nfc-cw)); }
  .nfc-counter { max-width: 380px; margin-inline: auto; }
  .nfc-cable { display: none; }
  .nfc-cup { left: calc(-8 * var(--nfc-s)); top: calc(462 * var(--nfc-s)); transform: scale(.74); }
  .nfc-till { position: relative; left: auto; top: auto; width: auto; max-width: 360px; margin: 20px auto 0; padding: 8px; }
  .nfc-till__screen { gap: 10px; padding: 12px 14px 14px; }
  .nfc-till__bar { padding-bottom: 9px; }
  .nfc-till__match { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "pill pill" "who pts" "btn btn"; align-items: center; gap: 10px 12px; }
  .nfc-till__pts { flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
  .nfc-till__pts small { max-width: 11em; }
}

/* The tap, once, when the column reveals (about 4.9 s, then it rests on the finished tap).
   Switching wallets shows the other scene, which plays it again. */
@media (prefers-reduced-motion: no-preference) {
  html.js .reveal.in .nfc-phone__body { animation: nfc-lower 4.6s var(--soft) .3s both; }
  html.js .reveal.in .nfc-arcs path { animation: nfc-arc 4.6s linear .3s both; }
  html.js .reveal.in .nfc-arcs path:nth-child(2) { animation-delay: .4s; }
  html.js .reveal.in .nfc-arcs path:nth-child(3) { animation-delay: .5s; }
  html.js .reveal.in .nfc-field span { animation: nfc-ring 4.6s var(--soft) .3s both; }
  html.js .reveal.in .nfc-field span:nth-child(2) { animation-delay: .52s; }
  html.js .reveal.in .nfc-field span:nth-child(3) { animation-delay: .74s; }
  html.js .reveal.in .nfc-reader__led { animation: nfc-led 4.6s ease .3s both; }
  html.js .reveal.in .nfc-reader__ok { animation: nfc-pop 4.6s var(--soft) .3s both; }
  html.js .reveal.in .nfc-ios__hold { animation: nfc-hide 4.6s ease .3s both; }
  html.js .reveal.in .nfc-ios__done { animation: nfc-show 4.6s var(--soft) .3s both; }
  html.js .reveal.in .nfc-till__idle { animation: nfc-hide-late 4.6s ease .3s both; }
  html.js .reveal.in .nfc-till__match { animation: nfc-show-late 4.6s var(--soft) .3s both; }
  html.js .reveal.in .nfc-step:nth-child(1) .nfc-step__n { animation: nfc-s1 4.6s ease .3s both; }
  html.js .reveal.in .nfc-step:nth-child(2) .nfc-step__n { animation: nfc-s2 4.6s ease .3s both; }
  html.js .reveal.in .nfc-step:nth-child(3) .nfc-step__n { animation: nfc-s3 4.6s ease .3s both; }
  html.js .reveal.in .nfc-demo:has(#nfc-w-google:checked) .nfc-step:nth-child(1) .nfc-step__n { animation-name: nfc-s1g; }
  html.js .reveal.in .nfc-demo:has(#nfc-w-google:checked) .nfc-step:nth-child(2) .nfc-step__n { animation-name: nfc-s2g; }
  html.js .reveal.in .nfc-demo:has(#nfc-w-google:checked) .nfc-step:nth-child(3) .nfc-step__n { animation-name: nfc-s3g; }
}
@keyframes nfc-lower {
  0% { transform: translate(calc(-12 * var(--nfc-s)), calc(-28 * var(--nfc-s))) scale(1.08); box-shadow: var(--nfc-bez), var(--nfc-high); }
  34%, 100% { transform: none; box-shadow: var(--nfc-bez), var(--nfc-low); }
}
@keyframes nfc-arc { 0%, 30% { opacity: 0; } 38% { opacity: 1; } 46% { opacity: .25; } 54%, 100% { opacity: 1; } }
@keyframes nfc-ring {
  0%, 30% { opacity: 0; transform: scale(.28); }
  34% { opacity: .9; }
  58%, 100% { opacity: 0; transform: scale(1); }
}
@keyframes nfc-led {
  0%, 50% { background-color: rgba(243, 233, 218, .2); box-shadow: 0 0 0 0 rgba(134, 217, 127, 0); }
  56%, 100% { background-color: #86D97F; box-shadow: 0 0 calc(12 * var(--nfc-s)) calc(2 * var(--nfc-s)) rgba(134, 217, 127, .55); }
}
@keyframes nfc-pop {
  0%, 50% { opacity: 0; transform: scale(.4); }
  58% { opacity: 1; transform: scale(1.14); }
  64%, 100% { opacity: 1; transform: none; }
}
@keyframes nfc-hide { 0%, 52% { opacity: 1; } 57%, 100% { opacity: 0; } }
@keyframes nfc-show {
  0%, 55% { opacity: 0; transform: translateY(calc(6 * var(--nfc-s))); }
  63%, 100% { opacity: 1; transform: none; }
}
@keyframes nfc-hide-late { 0%, 58% { opacity: 1; } 63%, 100% { opacity: 0; } }
@keyframes nfc-show-late {
  0%, 60% { opacity: 0; transform: translateY(8px); }
  70%, 100% { opacity: 1; transform: none; }
}
/* The beat being played is filled; the others wait as outlines, then all fill again at the end */
@keyframes nfc-s1 {
  0%, 32% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
  36%, 92% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  100% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
}
@keyframes nfc-s2 {
  0%, 32% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  36%, 58% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
  62%, 92% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  100% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
}
@keyframes nfc-s3 {
  0%, 58% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  62%, 100% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
}
/* Same beats under another name, so a switch of wallet restarts them */
@keyframes nfc-s1g {
  0%, 32% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
  36%, 92% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  100% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
}
@keyframes nfc-s2g {
  0%, 32% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  36%, 58% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
  62%, 92% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  100% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
}
@keyframes nfc-s3g {
  0%, 58% { background-color: transparent; color: var(--ink-2); box-shadow: inset 0 0 0 2px var(--line-strong); }
  62%, 100% { background-color: var(--brand-btn); color: var(--paper); box-shadow: 0 2px 0 var(--brand-lip); }
}
