
  *, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  /* Neutralise the UA stylesheet for [popover]. PositionController promotes
     floating panels to the top layer, and the UA rules for a popover include
     a solid border, padding, a canvas background and inset:0/margin:auto —
     enough to inflate a measured panel by 14px and to paint a border no
     component asked for. :where() keeps this at zero specificity so it beats
     the UA origin but loses to every rule a component writes for itself. */
  :where([popover]) {
    border: 0;
    padding: 0;
    margin: 0;
    inset: auto;
    width: auto;
    height: auto;
    background: none;
    color: inherit;
    overflow: visible;
  }

  :host {
    transition: opacity var(--transition-fast);

    
    /* Generated from shared/tokens.js by scripts/generate/host-tokens.js. */
    /* Do not edit by hand — edit the token tree instead. */

    --font-body: var(--font-body-family, 'Host Grotesk'), var(--font-body-fallback, system-ui, sans-serif);
    --font-label: var(--font-label-family, 'Tomorrow'), var(--font-label-fallback, system-ui, -apple-system, Segoe UI, sans-serif);
    --font-mono: var(--font-mono-family, 'JetBrains Mono'), var(--font-mono-fallback, ui-monospace, monospace);
    --font-quote: var(--font-quote-family, Georgia), var(--font-quote-fallback, serif);
    --font-display: var(--font-display-family, var(--font-body-family, 'Host Grotesk')), var(--font-display-fallback, var(--font-body-fallback, system-ui, sans-serif));
    --font-accent: var(--font-label);

    /* Private mirrors: components read these, consumers override --text-*. */
    --_text-xs: var(--text-xs, 12px);
    --_text-sm: var(--text-sm, 16px);
    --_text-md: var(--text-md, 17px);
    --_text-lg: var(--text-lg, clamp(18px, 1.5vw, 20px));
    --_text-xl: var(--text-xl, clamp(22px, 2.5vw, 26px));
    --_text-2xl: var(--text-2xl, clamp(28px, 3vw, 36px));
    --_text-3xl: var(--text-3xl, clamp(36px, 5vw, 52px));

    --display-xl-size: var(--_text-3xl);
    --display-xl-weight: var(--font-display-weight, 500);
    --display-xl-spacing: -1px;
    --heading-size: var(--_text-xl);
    --heading-weight: var(--font-display-weight, 500);
    --heading-lh: 1.2;
    --body-size: var(--_text-md);
    --body-weight: var(--font-body-weight, 500);
    --body-lh: 1.7;
    --wordmark-size: clamp(20px, 2.5vw, 28px);
    --wordmark-weight: var(--font-display-weight, 500);
    --wordmark-spacing: clamp(8px, 1.2vw, 14px);
    --section-title-size: var(--_text-xs);
    --section-title-weight: var(--font-label-weight, 600);
    --section-title-spacing: 2px;
    --ui-accent-size: 16px;
    --ui-accent-weight: var(--font-label-weight, 600);
    --ui-accent-spacing: 0.5px;
    --code-size: 14px;
    --code-lh: 1.8;
    --label-inline-size: 10px;
    --label-inline-spacing: 0.75px;

    /* Spacing */
    --space-xs: 4px;
    --space-sm: 8px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: 40px;
    --space-2xl: 64px;
    --space-3xl: 96px;
    --space-4xl: 128px;

    /* Radii */
    --radius-xs: 2px;
    --radius-sm: 4px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 20px;
    --radius-full: 9999px;

    /* Transitions and motion */
    --transition-fast: var(--duration-fast) var(--ease-standard);
    --transition-base: var(--duration-base) var(--ease-standard);
    --transition-slow: var(--duration-slow) var(--ease-standard);
    --transition-enter: var(--duration-enter) var(--ease-out);
    --transition-exit: var(--duration-exit) var(--ease-in);
    --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --duration-fast: 120ms;
    --duration-base: 200ms;
    --duration-slow: 400ms;
    --duration-enter: 500ms;
    --duration-exit: 300ms;
    --ease-out-expo: var(--ease-out);
    --ease-in-out: var(--ease-standard);

    /* Z-index */
    --z-base: 0;
    --z-dropdown: 1000;
    --z-tooltip: 1100;
    --z-overlay: 1200;
    --z-modal: 1300;
    --z-toast: 1400;
    --z-max: 9999;

    /* Glow and focus */
    --glow-xs: 0 0 6px rgba(var(--accent-primary-rgb), 0.3);
    --glow-sm: 0 0 8px rgba(var(--accent-primary-rgb), 0.3);
    --glow-md: 0 0 12px rgba(var(--accent-primary-rgb), 0.25);
    --glow-status: 0 0 12px rgba(var(--_status-rgb), var(--glow-status-alpha, 0.15));
    --glow-status-alpha: 0.15;
    --glow-hover: 0 0 12px rgba(var(--accent-primary-rgb), 0.15);
    --focus-ring: 0 0 0 1px rgba(var(--accent-primary-rgb),0.25);
    --focus-glow: 0 0 0 1px rgba(var(--accent-primary-rgb),0.2), 0 0 6px rgba(var(--accent-primary-rgb),0.35), 0 0 16px rgba(var(--accent-primary-rgb),0.2), 0 0 40px rgba(var(--accent-secondary-rgb),0.12);
    --focus-error: 0 0 0 2px var(--surface-base), 0 0 0 4px var(--color-error), 0 0 16px rgba(var(--color-error-rgb), 0.2);
    --focus-inset: inset 0 0 0 2px var(--interactive);
    --focus-thumb: 0 0 8px rgba(var(--interactive-rgb), 0.5), 0 0 20px rgba(var(--interactive-rgb), 0.25);

    /* Semantic aliases */
    --interactive: var(--accent-primary);
    --interactive-rgb: var(--accent-primary-rgb);
    --interactive-hover: var(--glow-hover);
    --interactive-active: var(--glow-primary);
    --interactive-focus: var(--focus-glow);
    --interactive-focus-ring: var(--focus-ring);
    --interactive-focus-error: var(--focus-error);
    --interactive-focus-inset: var(--focus-inset);
    --interactive-focus-thumb: var(--focus-thumb);
    --interactive-muted: var(--text-ghost);
    --surface-base: var(--bg-deep);
    --surface-primary: var(--bg-surface);
    --surface-raised: var(--bg-card);
    --surface-overlay: var(--bg-elevated);
    --surface-hover: var(--bg-hover);
    --divider: var(--border-subtle);
    --on-accent: var(--surface-base);

    /* Interactive and layout */
    --touch-min: 24px;
    --touch-pad: 4px;
    --max-width: 1120px;
    --max-width-sm: 720px;
    --nav-height: 64px;
    --nav-row-inset: var(--space-sm);

  }

  
  @media (pointer: coarse) {
    :host {
      --touch-min: 36px;
      --touch-pad: 8px;
    }
  }


  /* Reduced motion, once, for every component that adopts these styles.

     This was copy-pasted verbatim into sixty-nine component files while fifteen
     animating components had no guard at all — which is the usual outcome when
     a cross-cutting rule is a convention rather than a place. Components keep
     their own blocks only for what this cannot express: scroll-behavior,
     animation-play-state, a transform that must be neutralised rather than
     shortened.

     0.01ms rather than "animation: none" on purpose. A component that removes
     itself on animationend — the exiting toast and snackbar both do — would
     wait forever for an event that a canceled animation never fires. A
     duration this short is imperceptible and still completes. */
  @media (prefers-reduced-motion: reduce) {
    :host *,
    :host *::before,
    :host *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }
  }

      /* The host spans the whole annotated surface; the parent gives its
         container position: relative, so inset: 0 stretches each hotspot over
         the image and the pin lands at its percentage coordinates. Pointer
         events are re-enabled only on the pin and the open panel, so stacked
         hotspot hosts never block the image or each other. */
      :host {
        display: block;
        position: absolute;
        inset: 0;
        pointer-events: none;
      }

      /* Zero-size anchor at the pin's coordinates. Deliberately untransformed:
         a transform here would become the containing block for the panel, and
         in a browser without top-layer popover support the controller's fixed
         viewport coordinates would resolve against it instead of the viewport.
         The centring transform lives on the pin itself, whose transform cannot
         affect its panel sibling. */
      .hotspot {
        position: absolute;
        width: 0;
        height: 0;
      }

      .hotspot__pin {
        position: absolute;
        left: 0;
        top: 0;
        transform: translate(-50%, -50%);
        width: 28px;
        height: 28px;
        padding: 0;
        background: none;
        border: none;
        border-radius: var(--radius-full);
        cursor: pointer;
        pointer-events: auto;
      }

      /* The dot. */
      .hotspot__pin::before {
        content: '';
        position: absolute;
        inset: 8px;
        border-radius: var(--radius-full);
        background: var(--accent-primary);
        box-shadow:
          0 0 0 1px rgba(var(--accent-primary-rgb), 0.35),
          var(--glow-md);
        transition: box-shadow var(--transition-fast);
      }

      /* The breathing halo. The keyword curve is deliberate: loops are exempt
         from the entrance and exit curves in the token tree, and ease-in-out is
         the symmetric shape a pulse wants — see the loop note in
         scripts/checks/motion-tokens.js and the arc-avatar status pulse this
         follows. Opacity and transform only, so it stays off the layout path.
         The shared reduced-motion guard in tokenStyles shortens it to nothing;
         the explicit rule below removes it outright, matching arc-avatar. */
      .hotspot__pin::after {
        content: '';
        position: absolute;
        inset: 5px;
        border-radius: var(--radius-full);
        box-shadow: 0 0 12px 3px rgba(var(--accent-primary-rgb), 0.35);
        opacity: 0.5;
        animation: hotspot-pulse 2s ease-in-out infinite;
      }

      @keyframes hotspot-pulse {
        0%, 100% { opacity: 0.35; transform: scale(1); }
        50%      { opacity: 0.8;  transform: scale(1.25); }
      }

      .hotspot__pin:hover::before {
        box-shadow:
          0 0 0 1px rgba(var(--accent-primary-rgb), 0.5),
          0 0 16px rgba(var(--accent-primary-rgb), 0.5);
      }

      .hotspot__pin:focus-visible { outline: none; }
      .hotspot__pin:focus-visible::before {
        box-shadow: var(--interactive-focus-thumb);
      }

      /* An open pin holds a steady raised glow; the attention pulse stops
         because the popover already has the attention. */
      :host([open]) .hotspot__pin::before {
        box-shadow:
          0 0 0 1px rgba(var(--accent-primary-rgb), 0.6),
          0 0 18px rgba(var(--accent-primary-rgb), 0.55);
      }
      :host([open]) .hotspot__pin::after {
        animation: none;
        opacity: 0.7;
      }

      @media (prefers-reduced-motion: reduce) {
        .hotspot__pin::after { animation: none; }
      }

      .hotspot__panel {
        position: absolute;
        z-index: var(--z-tooltip);
        min-width: 200px;
        max-width: 280px;
        background: var(--surface-raised);
        border: 1px solid var(--border-default);
        border-radius: var(--radius-md);
        padding: var(--space-md);
        box-shadow: var(--shadow-overlay);
        font-family: var(--font-body);
        font-size: var(--_text-sm);
        line-height: 1.6;
        color: var(--text-secondary);
        overflow: hidden;
        opacity: 0;
        visibility: hidden;
        transform: scale(0.95);
        transition:
          opacity var(--transition-base),
          visibility var(--transition-base),
          transform var(--transition-base);
        pointer-events: none;
      }

      .hotspot__panel::before {
        content: '';
        position: absolute;
        top: 0;
        inset-inline-start: 0;
        inset-inline-end: 0;
        height: 1px;
        background: var(--divider-glow);
      }

      :host([open]) .hotspot__panel {
        opacity: 1;
        visibility: visible;
        transform: scale(1);
        pointer-events: auto;
      }

      /* Resting fallback placement, above the pin — for the static export,
         pre-upgrade, and anywhere PositionController has not adopted the
         panel. The centring rides on the translate property rather than on
         transform, which stays free to carry the open/closed scale. */
      .hotspot__panel:not([data-managed]) {
        bottom: var(--space-lg);
        left: 0;
        translate: -50% 0;
        transform-origin: bottom center;
      }

      .hotspot__label {
        margin: 0 0 var(--space-xs);
        font-family: var(--font-label);
        font-size: var(--_text-sm);
        font-weight: 600;
        color: var(--text-primary);
      }
    
    .hotspot__panel[data-managed] {
      /* Belt-and-braces with the inline styles: a panel promoted to the top
         layer inherits the UA's [popover] rules, whose inset:0 and margin:auto
         would centre it in the viewport if a coordinate write were ever
         missed. */
      inset: auto;
      margin: 0;
    }
    
    .hotspot__panel[data-managed] {
      opacity: 0;
      transform: scale(0.95);
      transition-property: opacity, transform, display, overlay;
      transition-duration: var(--duration-base);
      transition-timing-function: var(--ease-in);
      transition-behavior: allow-discrete;
    }
    :host([open]) .hotspot__panel[data-managed] {
      opacity: 1;
      transform: none;
      transition-timing-function: var(--ease-out);
    }
    @starting-style {
      :host([open]) .hotspot__panel[data-managed] {
        opacity: 0;
        transform: scale(0.95);
      }
    }
  

    /* Grow out of the anchored edge, and follow a flip. data-placement is the
       side the panel actually landed on, not the one that was asked for. */
    .hotspot__panel[data-managed][data-placement='bottom'] { transform-origin: top center; }
    .hotspot__panel[data-managed][data-placement='top'] { transform-origin: bottom center; }
    .hotspot__panel[data-managed][data-placement='right'] { transform-origin: center left; }
    .hotspot__panel[data-managed][data-placement='left'] { transform-origin: center right; }
  