/* The App Store badge, fixed at the bottom-left of every page (owner,
 * 2026-10-13: "a little button that floats on the bottom-left corner of the
 * page, whether we're on browser or mobile ... it sticks to the page and
 * doesn't move ... it is a link to the App Store listing").
 *
 * The artwork is Apple's own "Download on the App Store" badge, US English,
 * black, bundled byte for byte as Apple serves it:
 *   /badges/download-on-the-app-store-black-en-us.svg
 *   from https://toolbox.marketingtools.apple.com/api/v2/badges/download-on-the-app-store/black/en-us
 *   (Apple Marketing Tools; the same bytes as
 *   https://developer.apple.com/assets/elements/badges/download-on-the-app-store.svg),
 *   downloaded 2026-10-13, sha256 a26fc5b3...b9fb99f (README, "App Store badge").
 * The old tools.applemarketingtools.com host no longer resolves; Apple's
 * guidelines page links the toolbox host.
 *
 * Apple's rules (https://developer.apple.com/app-store/marketing/guidelines/,
 * read 2026-10-13), and how this sheet keeps them:
 * - "Use the preferred black badge": the black badge in BOTH themes. Its gray
 *   (#A6A6A6) border "is part of the badge artwork" and is what carries it on
 *   a dark ground; the guidelines name no other badge for dark backgrounds,
 *   and the white one is only an alternative for layouts where black looks
 *   heavy. So night pages, and the night footer under paper pages, show the
 *   same black badge.
 * - Minimum 40 px tall on screen: it is 44 px (the site's touch target), so
 *   119.66407 x 40 scales to 131.64 x 44.
 * - Clear space of one quarter of its height (11 px): nothing of ours comes
 *   closer than 12 px (the note sits 12 px to its right), it is 16 px from
 *   the viewport's edges, and the pages' last content scrolls to 11 px or
 *   more above it (the padding below).
 * - "Don't modify, angle, or animate": the image is never recoloured,
 *   filtered, scaled, cropped or moved, and has no hover effect. Only the
 *   site's own focus ring is drawn round the link, outside the artwork. In
 *   the collapse below it only fades, whole and in place, to nothing.
 *
 * Collapse on scroll (owner, 2026-10-13: "should collapse onto just apple
 * logo button as soon as user starts scrolling ... can expand back if user
 * goes back to top of page"). At the top (scrollY <= 24 px, app-store.js)
 * the full badge shows; anywhere else the control is a 44 px round button
 * showing OUR app icon (/icon.svg, the multi-green S on its tile, the same
 * file as the favicon), not the Apple logo: Apple's trademark guidelines
 * let third parties show the Apple logo only inside the official badge
 * artwork, never on its own. The link (its hit box and focus ring) narrows
 * from the badge's width to a circle, the badge fades out and the icon
 * fades and grows in (280 ms); returning to the top reverses it. The badge
 * is position: fixed, so nothing on the page moves. Reduce Motion: the two
 * images cross-fade (--yb-motion-quick), no growth, the frame snaps.
 * Transitions start only once the first state is drawn (.is-ready), so a
 * page opened part-way down starts collapsed instead of animating.
 *
 * Stacking: z-index 20, above page content (its sections use 0 to 2) and
 * below the header and its menu (30), the listbox popups (45), the skip link
 * (50) and the listbox sheet and its scrim (70, 71). A listbox nested in a
 * section's stacking context (z-index 1) cannot rise above a root-level 20,
 * so the badge also steps aside while any listbox is open.
 *
 * The "Coming soon" note (app-store.js) is the one place the site says it
 * (the owner's request of 2026-10-13 overrides the 2026-10-02 "no coming
 * soon" rule for this note only). Yardage: monoSmall in note, a hairline,
 * card radius, on the ground; it settles in from the leading edge (settle)
 * and leaves with a quick fade. Reduce Motion: no slide, it just appears.
 */

:root {
  --app-badge-h: 44px;                                   /* >= Apple's 40 px */
  --app-badge-w: calc(var(--app-badge-h) * 119.66407 / 40); /* the artwork's own ratio */
  --app-badge-clear: calc(var(--app-badge-h) / 4);       /* Apple's clear space */
  --app-badge-edge: 16px;
  /* the strip at the foot of the viewport the badge and its clear space use */
  --app-badge-zone: calc(var(--app-badge-edge) + var(--app-badge-h) + var(--app-badge-clear));
  --app-badge-morph: 280ms;
  --app-badge-ease: var(--yb-ease-in-out);
}

.app-badge {
  position: fixed; z-index: 20;
  left: calc(var(--app-badge-edge) + env(safe-area-inset-left, 0px));
  bottom: calc(var(--app-badge-edge) + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: var(--yb-space-m);
  margin: 0;
  /* the box spans the note's slot too; only the link and a shown note take clicks */
  pointer-events: none;
}

.app-badge-link {
  position: relative; display: block; flex: none;
  width: var(--app-badge-w); height: var(--app-badge-h);
  /* the artwork's own corner (about 9.5 of 40 units), so the focus ring follows it */
  border-radius: calc(var(--app-badge-h) * 9.5 / 40);
  pointer-events: auto; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Both images sit at the link's leading corner. They take no pointer, so a
   press lands on the link's own box: the badge's 132 x 44 at the top, the
   44 px circle when collapsed (the faded badge then covers nothing). */
.app-badge-link img { position: absolute; left: 0; top: 0; display: block; pointer-events: none; }
.app-badge-art { width: var(--app-badge-w); height: var(--app-badge-h); }
.app-badge-icon {
  width: var(--app-badge-h); height: var(--app-badge-h);
  /* the tile's dark ground fills the circle (its own corners are outside
     it); a hairline ring, as the badge's gray border does, carries it on
     the night ground */
  border-radius: 50%;
  box-shadow: 0 0 0 var(--yb-line-hair) var(--yb-rule-strong);
  opacity: 0; transform: scale(.6);
}

/* Collapsed (app-store.js, scrollY > 24 px): the round Striped button. */
.app-badge.is-collapsed .app-badge-link { width: var(--app-badge-h); border-radius: calc(var(--app-badge-h) / 2); }
.app-badge.is-collapsed .app-badge-art { opacity: 0; }
.app-badge.is-collapsed .app-badge-icon { opacity: 1; transform: none; }

/* The morph. Each direction lets the leaving image go first and brings the
   arriving one in 80 ms later, so mid-way they overlap without either
   reading as a second button. The badge only ever fades. */
@media (prefers-reduced-motion: no-preference) {
  .app-badge.is-ready .app-badge-link { transition: width var(--app-badge-morph) var(--app-badge-ease), border-radius var(--app-badge-morph) var(--app-badge-ease); }
  .app-badge.is-ready .app-badge-icon { transition: opacity 180ms ease, transform var(--app-badge-morph) var(--app-badge-ease); }
  .app-badge.is-ready .app-badge-art { transition: opacity 200ms ease 80ms; }
  .app-badge.is-ready.is-collapsed .app-badge-art { transition: opacity 180ms ease; }
  .app-badge.is-ready.is-collapsed .app-badge-icon { transition: opacity 200ms ease 80ms, transform var(--app-badge-morph) var(--app-badge-ease); }
}
/* Reduce Motion: a quick cross-fade, nothing grows, the frame snaps. */
@media (prefers-reduced-motion: reduce) {
  .app-badge-icon { transform: none; }
  .app-badge.is-ready .app-badge-art, .app-badge.is-ready .app-badge-icon { transition: opacity var(--yb-motion-quick) ease; }
}

/* "Coming soon": a note beside the badge, outside its clear space. Hidden,
   it stays rendered (opacity 0, visibility hidden after the fade), so the
   live region is in the accessibility tree before its words change. */
.app-badge-note {
  margin: 0; white-space: nowrap;
  padding: var(--yb-space-s) var(--yb-space-m);
  background: var(--yb-ground);
  border: var(--yb-line-hair) solid var(--yb-rule-strong);
  border-radius: var(--yb-radius-card);
  font: normal 400 var(--yb-type-mono-small-size)/var(--yb-type-mono-small-line) var(--yb-font-mono);
  color: var(--yb-note);
  opacity: 0; visibility: hidden;
  transition: opacity var(--yb-motion-quick) ease-out, visibility 0s linear var(--yb-motion-quick);
}
.app-badge-note.is-shown {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity var(--yb-motion-quick) ease-out, visibility 0s;
}
@media (prefers-reduced-motion: no-preference) {
  .app-badge-note.is-shown { animation: app-badge-settle var(--yb-motion-settle) both; }
}
@keyframes app-badge-settle { from { opacity: 0; transform: translateX(calc(-1 * var(--yb-space-s))); } to { opacity: 1; transform: none; } }

/* Step aside while a listbox (a popup or the phone's bottom sheet) is open. */
:root:has(.yb-listbox.is-open) .app-badge { visibility: hidden; }

/* Room at the foot of every page, so the last lines and links scroll clear
   of the badge and its clear space (the footer's own 40 px is less), with
   4 px to spare for sub-pixel page heights. */
.yb-footer { padding-bottom: max(var(--yb-space-x4), calc(var(--app-badge-zone) + var(--yb-space-xs) + env(safe-area-inset-bottom, 0px))); }
/* The metronome is one screen with its start button at the foot: lift the
   column so the button and the practice selector sit above the badge. */
.yb-metro { padding-bottom: calc(var(--app-badge-zone) + var(--yb-space-xs) + env(safe-area-inset-bottom, 0px)); }

/* The 404 is shorter than a desktop window, so its footer brand loaded
   right under the badge (1400 x 900: "Striped" at the foot of the window).
   Its feature page fills the window instead, and the footer starts below
   the fold like every other page's. */
.yb-notfound { display: flex; flex-direction: column; min-height: calc(100vh - var(--yb-header-height)); }
.yb-notfound > .yb-feature-screen { flex: 1 0 auto; }

/* The legal pages' "On this page" index is sticky in the left column from
   960 px and taller than a 900 px window (14 entries on privacy, 25 on
   terms), so its lower entries sat under the badge for the whole read.
   It ends above the badge's strip instead and scrolls inside itself; the
   padding keeps the links' focus halo inside that scrollport. */
@media (min-width: 960px) {
  .yb-toc {
    max-height: calc(100vh - var(--yb-header-height) - var(--yb-space-l) - var(--app-badge-zone) - env(safe-area-inset-bottom, 0px));
    overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
    padding-left: var(--yb-focus-halo); margin-left: calc(-1 * var(--yb-focus-halo));
  }
}

@media print { .app-badge { display: none; } }
