/* SHELEG Design — Pigeonhole token layer (a white sorting wall: nine categories
   drawn from an eleven-ramp pastel system, where a hue is a category, a display face that never goes
   bolder than 400, and one italic word in the headline).
   Copy verbatim; consume only var(--…) in components.

   Extracted from https://www.getinboxzero.com/ on 2026-08-12 by reading the
   server-rendered HTML of / (399,558 bytes) together with the two shipped
   stylesheets (/_next/static/immutable/chunks/0dfx_zuu6iahb.css and
   26l20pon7rs4c.css, 599,990 bytes combined, 152 custom properties), and then by
   reading computed styles off the live page through CDP at 1440x900, 768x1024 and
   390x844 — 912 rendered elements. Ratios were computed by importing this
   repository's own palette gate, test/validate_palette.py.

   Four families of value appear below and they are not the same kind of claim:

   MEASURED — the literal was in the reference's stylesheet, its markup, or its
   computed styles.
   COMPOSITED — the reference paints an alpha over a known field; the value below
   is that composite resolved in sRGB, so a component never has to know what sat
   underneath it.
   SELECTED — the reference paints no value in this role (it is a marketing page
   and has no error state), so the value is a different *step* of a hue the
   reference already ships, chosen for WCAG AA on the field it sits on.
   DERIVED — a value walked down OKLab L from a hue the reference ships, holding
   hue and chroma, until the ROUNDED hex clears 4.5:1. Two cases: the reference
   paints this role and its value fails the floor (every category ink), or the
   reference paints no such role and the nearest hue it does ship is too light for
   one (--good, --warn). A substitution that holds neither hue nor chroma is not a
   derivation and is not labelled as one -- see --ink-lede. Eight bits per channel is where the
   derivation finishes: an earlier pass of this file read its ratios off the
   unrounded candidates and would have shipped #007b22 claiming its parent's
   4.50:1 where the hex itself measures 4.38:1.

   Eight of the reference's nine category inks fail 4.5:1 against the very tints
   it paints them on — worst #49d1fa at 1.53:1 — so every category ink here is
   DERIVED. The register survives; the ink does not. Every correction is recorded
   with its number in the pack's Gotchas.

   No dark theme. The reference's stylesheet carries a .dark block, but it is the
   *application's* stock shadcn slate theme and nothing on the marketing page
   consumes it: the page is white at every viewport measured. A dark twin no prose
   documents is a defect this library already carries once (see field-notes, board
   B-018), so this pack ships light only and says so. */

:root {
  color-scheme: light;

  /* ---- The wall --------------------------------------------------------- */
  /* White on 51 elements, the alt band on 12, the third step on 6. */
  --bg: #ffffff; /* MEASURED — the page field at every viewport */
  --surface: #ffffff; /* MEASURED — cards sit at field level and separate by hairline, not by fill */
  --surface-2: #f9fafb; /* MEASURED — the alternating section band */
  --surface-3: #fcfcfc; /* MEASURED — the third, barely-there step */
  --surface-grad-from: #ffffff; /* MEASURED — 19 surfaces carry linear-gradient(#fff, #f9f9f9) */
  --surface-grad-to: #f9f9f9; /* MEASURED — the same gradient's foot */

  /* ---- Ink -------------------------------------------------------------- */
  /* The reference ships two neutral families at once: a bespoke ramp for the
     display and the ledes, and Tailwind's gray/slate defaults for the dominant
     body copy (#6b7280 on 79 elements against the bespoke #848484 on 47). Both
     are kept, because both are load-bearing on the page. */
  --ink: #242424; /* 15.52:1 on --bg — MEASURED: display, section heads, every h2 */
  --ink-body: #3d3d3d; /* 10.86:1 on --bg — MEASURED: body copy that must carry weight */
  --ink-soft: #6b7280; /* 4.83:1 on --bg — MEASURED: the dominant body ink, and the one that clears AA */
  --ink-faint: #9ca3af; /* 2.54:1 on --bg — MEASURED: an icon, a decorative glyph, or the label of a DISABLED control — which WCAG 1.4.3 exempts and which is the only word this token may carry. Never live text. */

  /* The reference's own lede ink is #848484 at 3.74:1 — below AA for the 18px
     regular it is painted at. This pack does not ship it. The replacement is not a
     derivation: nothing was walked down a lightness axis, and the two are not the
     same hue (#848484 is achromatic; this one has a blue-slate cast). It is the
     reference's OWN dominant body ink, measured on 79 elements, promoted into a
     role the reference fills with something that fails. The promotion is the pack's
     decision; the value is a reading. */
  --ink-lede: #6b7280; /* 4.83:1 on --bg — MEASURED, role SELECTED: the reference's own body ink, promoted to the lede */

  /* ---- Lines: this pack divides with hairlines, not with shadow ---------- */
  --rule: #f3f3f3; /* COMPOSITED — its 1px rgba(231,231,231,0.5) resolved over --bg, on 43 elements */
  --rule-soft: #f7f7f7; /* MEASURED — the 19-element hairline */
  --rule-strong: #e3e3e3; /* MEASURED — the single 2px border on the page */

  /* ---- The accent: a two-stop gradient, never a flat fill --------------- */
  /* The primary CTA is linear-gradient(#2965ec, #5c89f8) with a shadow tinted to
     its own hue. White on the upper stop is 5.04:1 and on the LOWER stop 3.29:1,
     so the label passes at the top of the button and fails at the bottom of the
     same button. The pack's Components section fixes the direction of the ramp
     rather than the colours; see Gotchas. */
  --accent: #2965ec; /* MEASURED — the CTA gradient's upper stop */
  --accent-2: #5c89f8; /* MEASURED — the gradient's lower stop; what white costs on it is in the pack's Gotchas */
  --accent-strong: #2965ec; /* 5.04:1 on --bg — MEASURED: the accent that may carry a word */
  --accent-wash: #eff3ff; /* MEASURED — its new-blue-50, the palest step of the same hue */
  --accent-edge: #d9e2ff; /* MEASURED — its new-blue-100 */
  --cta-shadow-tint: rgba(75, 131, 253, 0.2); /* MEASURED — the accent tint the CTA's shadow is mixed from. A COLOUR, not a shadow: the shadow itself is --shadow-cta, and `box-shadow: var(--cta-shadow-tint)` would be dropped by CSS in silence. */
  --on-accent: #ffffff; /* 5.04:1 on --accent — MEASURED: the label colour the reference paints */

  /* ---- Status ----------------------------------------------------------- */
  /* SELECTED, all four. A marketing page paints no error state, so each is a
     darker step of a hue the reference does ship: the open-source tick's green,
     the Calendar chip's amber, the Notification chip's red, the CTA's blue.
     Separation, computed by the gate: the tightest pair is --danger/--warn at
     13.9 at full colour, above the hard floor of 10; under deuteranopia
     --danger/--good fall to 3.4 and --good/--warn to 5.0, which is legal only
     because this pack states that status is never by colour alone. */
  --good: #008931; /* 4.54:1 on --bg — DERIVED from its #17a34a: hue and chroma held, L walked to the floor */
  --warn: #9f6d00; /* 4.50:1 on --bg — DERIVED from its #d8a40c, the same way */
  --danger: #c94244; /* 4.83:1 on --bg — MEASURED: the Notification chip's ink, which already clears AA on the field */
  --info: #2965ec; /* 5.04:1 on --bg — MEASURED: an alias of --accent, on purpose */

  /* ---- The taxonomy ----------------------------------------------------- */
  /* THE POINT OF THIS PACK. Nine categories were measured on the reference, each
     as an ink plus a four-step tint ramp of its own hue; the stylesheet declares
     eleven such ramps in total (new-brown and new-pink ship unused as
     categories). A chip is built from two of the steps — an outer chip in the
     deeper pair holding an inner chip in the paler one.

     These tokens are deliberately OUTSIDE the palette gate's semantic peer set,
     and that is a decision rather than an oversight. Eleven hues cannot be
     simultaneously AA-compliant and mutually distinguishable under dichromacy:
     darkening them to clear 4.5:1 drops the worst deuteranopic pair
     (marketing/notification) from ΔE 4.42 to 1.24, well under the gate's hard
     floor of 10, and no re-stepping fixes that — a dichromatic reader sees a
     one-dimensional axis where this system wants nine points. So the hue here is
     a REDUNDANT channel: the chip's label word carries the category, and the pack
     bans a chip without one. When board B-017's widening reaches the peer set,
     read this paragraph before adding these tokens to it. */

  /* Every ink below: DERIVED. Ratio stated against the DEEPEST tint of its own
     ramp (-200), which is the worst surface the hue can sit on. */
  /* The reference paints #124dff here. It measures 3.89:1 against the deepest tint
     of this same ramp, so it fails AA where the chip puts it. */
  --cat-reply-ink: #0940f3; /* 4.51:1 on --cat-reply-200 — DERIVED, hue and chroma held */
  --cat-reply-50: #eff3ff; /* MEASURED */
  --cat-reply-100: #d9e2ff; /* MEASURED */
  --cat-reply-150: #d5defc; /* MEASURED */
  --cat-reply-200: #c2d0fc; /* MEASURED */

  /* The reference paints #6410ff here. It measures 4.28:1 against the deepest tint
     of this same ramp, so it fails AA where the chip puts it. */
  --cat-newsletter-ink: #6100fb; /* 4.52:1 on --cat-newsletter-200 — DERIVED, hue and chroma held */
  --cat-newsletter-50: #f3eafe; /* MEASURED */
  --cat-newsletter-100: #e7daff; /* MEASURED */
  --cat-newsletter-150: #e1d5fc; /* MEASURED */
  --cat-newsletter-200: #d7c3fc; /* MEASURED */

  /* The reference paints #17a34a here. It measures 2.72:1 against the deepest tint
     of this same ramp, so it fails AA where the chip puts it. */
  --cat-marketing-ink: #007b22; /* 4.50:1 on --cat-marketing-200 — DERIVED, hue and chroma held */
  --cat-marketing-50: #f3ffef; /* MEASURED */
  --cat-marketing-100: #e1ffd8; /* MEASURED */
  --cat-marketing-150: #ddf4d3; /* MEASURED */
  --cat-marketing-200: #cff4c0; /* MEASURED */

  /* The reference paints #d8a40c here. It measures 1.65:1 against the deepest tint
     of this same ramp and is the second-worst on the page, so it fails AA where the chip puts it. */
  --cat-calendar-ink: #875600; /* 4.53:1 on --cat-calendar-200 — DERIVED, hue and chroma held */
  --cat-calendar-50: #fffbef; /* MEASURED */
  --cat-calendar-100: #fff3da; /* MEASURED */
  --cat-calendar-150: #e7e0cb; /* MEASURED */
  --cat-calendar-200: #e7dbb9; /* MEASURED */

  /* The reference paints #c94244 here. It measures 3.09:1 against the deepest tint
     of this same ramp, so it fails AA where the chip puts it. */
  --cat-notification-ink: #aa222b; /* 4.52:1 on --cat-notification-200 — DERIVED, hue and chroma held */
  --cat-notification-50: #ffeef0; /* MEASURED */
  --cat-notification-100: #ffdadb; /* MEASURED */
  --cat-notification-150: #fdd3d4; /* MEASURED */
  --cat-notification-200: #fcc0c0; /* MEASURED */

  /* The reference paints #49d1fa here. It measures 1.53:1 against the deepest tint
     of this same ramp and is the worst on the page, so it fails AA where the chip puts it. */
  --cat-cold-ink: #00759a; /* 4.50:1 on --cat-cold-200 — DERIVED, hue and chroma held */
  --cat-cold-50: #feffff; /* MEASURED */
  --cat-cold-100: #e5f9ff; /* MEASURED */
  --cat-cold-150: #e5f9ff; /* MEASURED — the reference repeats the step; kept rather than invented */
  --cat-cold-200: #d0f4ff; /* MEASURED */

  /* The reference paints #e65707 here. It measures 2.71:1 against the deepest tint
     of this same ramp, so it fails AA where the chip puts it. */
  --cat-team-ink: #ba2b00; /* 4.53:1 on --cat-team-200 — DERIVED, hue and chroma held */
  --cat-team-50: #fff5ef; /* MEASURED */
  --cat-team-100: #ffe7da; /* MEASURED */
  --cat-team-150: #fce2d5; /* MEASURED */
  --cat-team-200: #fcd6c2; /* MEASURED */

  /* The reference paints #c942b2 here. It measures 2.79:1 against the deepest tint
     of this same ramp, so it fails AA where the chip puts it. */
  --cat-urgent-ink: #a2138e; /* 4.54:1 on --cat-urgent-200 — DERIVED, hue and chroma held */
  --cat-urgent-50: #ffeef8; /* MEASURED */
  --cat-urgent-100: #ffdaec; /* MEASURED */
  --cat-urgent-150: #fdd3eb; /* MEASURED */
  --cat-urgent-200: #fdbfe0; /* MEASURED */

  /* The neutral category — the reference spends it on STEP 1/2/3, and it is the
     one ink that already clears the floor everywhere on its own ramp. */
  --cat-step-ink: #525252; /* 6.26:1 on --cat-step-200 — MEASURED, no derivation needed */
  --cat-step-50: #ffffff; /* MEASURED */
  --cat-step-100: #f6f6f6; /* MEASURED */
  --cat-step-150: #eeeeee; /* MEASURED */
  --cat-step-200: #e6e6e6; /* MEASURED */

  /* ---- Type ------------------------------------------------------------- */
  /* Two families over 912 elements: Geist on 878, Aeonik on 34. The display face
     is rare AND light — weight 400 at every size it appears at. Both are
     commercial webfonts on the reference; the stacks below name them first and
     fall through to the system, so a consumer without a licence still gets the
     rhythm. */
  /* MEASURED family, SELECTED tail: the reference names aeonikFont first and falls
     through to its own Fallback face; the system tail below is this pack's, so a
     consumer without the licence still gets the rhythm. */
  --font-display: aeonikFont, "Aeonik", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: Geist, "Geist Fallback", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; /* MEASURED — the reference's own stack, on 878 of 912 elements */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* MEASURED — declared, and spent on nothing the page shows */

  --weight-display: 400; /* MEASURED — never 500, never 600, at any display size */
  --weight-body: 400; /* MEASURED */
  --weight-label: 500; /* MEASURED — control labels and every chip */
  --weight-emphasis: 600; /* MEASURED — inline emphasis in body copy */

  /* Fluid. The SIZES below are measured — display 60px at 1440 and at 768, 34px at
     390; section heads 40px, 40px, 27.2px — but the RAMPS are FITTED to those three
     points rather than copied from a declaration, and that is a pack decision.
     The reference ships seven clamp() ramps and its display resolves from none of
     them alone: its widest, clamp(40px, 5.6vw, 60px), yields 43.01px at 768 where
     60px was measured, and its 40px floor cannot reach the 34px measured at 390.
     So the vw term here is the one that reproduces all three readings — 7.82vw
     caps at exactly 768 — and the same method gives the section head 5.21vw.
     Change a viewport and re-measure; do not trust the coefficient. */
  --size-display: clamp(34px, 7.82vw, 60px); /* SELECTED ramp over MEASURED sizes: 34 / 60 / 60 at 390 / 768 / 1440 */
  --lh-display: 1; /* MEASURED — 60px on 60px at 1440 and 768, the tightest in the library */
  --size-head: clamp(27.2px, 5.21vw, 40px); /* SELECTED ramp over MEASURED sizes: 27.2 / 40 / 40 */
  --lh-head: 1.25; /* MEASURED — 50px on 40px */
  /* A size never travels alone in this library, so every pairing the pack states
     has a token here. Five of these were stated in the pack and missing from the
     layer until a fresh-context read of the pack asked for the lede's 28px. */
  --size-sub: 20px; /* MEASURED — 20px/24px, 9 elements */
  --lh-sub: 1.2; /* MEASURED — 24px on 20px */
  --size-lede: 18px; /* MEASURED — 18px/28px */
  --lh-lede: 1.556; /* MEASURED — 28px on 18px */
  --size-body: 14px; /* MEASURED — 14px/24px, the dominant pairing on 59 elements */
  --lh-body: 1.714; /* MEASURED — 24px on 14px */
  --size-body-lg: 16px; /* MEASURED — 16px/24px */
  --lh-body-lg: 1.5; /* MEASURED — 24px on 16px */
  --size-chip: 12px; /* MEASURED — 12px/16px, weight 500 */
  --lh-chip: 1.333; /* MEASURED — 16px on 12px */
  --size-micro: 10px; /* MEASURED — 10px/15px, the smallest on the page */
  --lh-micro: 1.5; /* MEASURED — 15px on 10px */

  /* ---- Texture ---------------------------------------------------------- */
  /* Radii by frequency: 9999 (35), 32 (21), 20 (12), 13 (10), 8 and 7 (12 each),
     52 (8). The 8/7 pair is the chip's two layers and the reason both are here. */
  --radius-chip: 8px; /* MEASURED — the outer chip */
  --radius-chip-inner: 7px; /* MEASURED — the inner chip, 1px inside its parent */
  --radius-control: 13px; /* MEASURED — every button in the hero and the nav */
  --radius-control-lg: 14px; /* MEASURED — the same button in-page; the reference is not consistent and this records both */
  --radius-panel-sm: 20px; /* MEASURED — the third most frequent radius on the page, on 12 elements */
  --radius-panel: 32px; /* MEASURED — cards, FAQ rows, product frames */
  --radius-band: 52px; /* MEASURED — the full-width enterprise band */
  --radius-pill: 9999px; /* MEASURED — badges */

  /* One shadow does almost all the work: 40 elements carry it. */
  --shadow-card: 0 3px 12.9px rgba(151, 151, 151, 0.08); /* MEASURED */
  --shadow-soft: 0 2px 16px rgba(0, 0, 0, 0.03); /* MEASURED — 5 elements */
  --shadow-hero: 0 14.3px 38.74px 3.9px rgba(0, 0, 0, 0.1), 0 0 4.16px rgba(0, 0, 0, 0.05); /* MEASURED — the one big lift, on the hero frame */
  --shadow-cta: 0 2px 10.1px rgba(75, 131, 253, 0.2); /* MEASURED — tinted to the accent */

  /* A tinted card's shadow is mixed toward its OWN hue, which is how the page
     reads coloured while staying white. Measured on the green and blue cards;
     the pattern generalises and the pack states the rule rather than shipping a
     token per hue. */
  /* These two are the measured INSTANCE, off the green card. The RULE they stand
     for is mechanical and does not need a token per hue: a tinted card's shadow is
     `0 2px 3.4px var(--cat-X-150), 0 1px 1px var(--cat-X-200)` — its own two deeper
     steps, which every category ships. The kit's .pg-wash--* rules are that rule
     written out nine times; do not reach for these two literals to tint a card that
     is not green. */
  --shadow-tint-a: 0 2px 3.4px rgba(207, 249, 222, 0.22); /* MEASURED — the green card's near shadow */
  --shadow-tint-b: 0 1px 1px rgba(118, 217, 143, 0.11); /* MEASURED — and its contact shadow */

  /* ---- Measure ---------------------------------------------------------- */
  --container: 1152px; /* MEASURED — the section container at 1440 */
  --measure-hero: 780px; /* MEASURED — the display column */
  --measure-lede: 640px; /* MEASURED */
  --measure-body: 650px; /* MEASURED — on 10 elements, the body measure */
  --gutter: 24px; /* MEASURED at 390 */

  /* ---- Motion ----------------------------------------------------------- */
  /* Entrance and hover only. There is NO scroll clock on the reference: zero
     elements with animation-timeline, zero sticky, zero fixed. */
  --dur-quick: 0.15s; /* MEASURED — 10 elements, the default transition */
  --dur-base: 0.2s; /* MEASURED */
  --dur-slow: 0.3s; /* MEASURED */
  --ease: cubic-bezier(0.4, 0, 0.2, 1); /* MEASURED — every transition but one */
  --ease-overshoot: cubic-bezier(0.175, 0.885, 0.32, 2.2); /* MEASURED — exactly one element on the page */
  --dur-marquee: 100s; /* MEASURED — the logo wall, linear, the page's only keyframe animation */
  --blur-enter: 6px; /* SELECTED — the hero enters word by word through filter: blur(); the settled state measures 0px and the start value is inside a motion library rather than in CSS */
  --stagger-word: 0.04s; /* SELECTED — same reason: 20 word spans enter in sequence, the interval is not in the stylesheet */
}

/* The display's line-height is not one number. It is exactly 1 where the ramp is
   capped (60px on 60px at 1440 and at 768) and 1.25 below that, measured at 390 as
   34px on 42.5px. A single value would make one of the two viewports wrong. */
@media (max-width: 767px) {
  :root {
    --lh-display: 1.25; /* MEASURED at 390 — 42.5px on 34px */
  }
}

/* The reference honours reduced motion globally — its first rule collapses
   transition-duration and animation-duration to 0.01ms on *. A pack that
   regressed that would be worse than its own source, so the collapse is part of
   the token layer rather than advice in the prose. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-quick: 0.01ms; /* MEASURED — the reference collapses * to 0.01ms !important */
    --dur-base: 0.01ms; /* MEASURED — same rule */
    --dur-slow: 0.01ms; /* MEASURED — same rule */
    /* 0.01ms is what the reference's global rule sets, and for the marquee it is
       WRONG: an infinite animation at 0.01ms does not stop, it strobes ~100,000
       times a second at the reader this query protects. The duration is kept for
       parity with the reference and the marquee is stopped in the component layer
       instead — `animation-play-state: paused` — because no custom property can
       express it. See the kit's .pg-marquee rule. */
    --dur-marquee: 0.01ms; /* MEASURED — and insufficient on its own; see above */
    --blur-enter: 0px; /* SELECTED — the entrance blur has no reduced-motion value to read */
    --stagger-word: 0s; /* SELECTED — same reason */
    --ease-overshoot: cubic-bezier(0.4, 0, 0.2, 1); /* SELECTED — an overshoot is motion, so it degrades to the standard curve; the reference states no reduced-motion easing */
  }
}

/* ── components ── */
/* Authored CSS for the states the pack's Components section specifies and the
   reference paints none of. Everything below consumes var(--…) only: the gate
   rejects a raw colour literal past this line. */

/* ---- Button ------------------------------------------------------------- */
/* The primary ramp runs light-to-dark on purpose. The reference runs it the other
   way and its white label clears 5.04:1 at the top of the button and only 3.29:1
   at the bottom; reversing the stops puts the label's worst case on the passing
   colour. */
.pg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: var(--size-body-lg);
  font-weight: var(--weight-label);
  line-height: var(--lh-body-lg);
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  padding: 11.7px 22px;
  cursor: pointer;
  transition: box-shadow var(--dur-quick) var(--ease),
    transform var(--dur-quick) var(--ease),
    background-color var(--dur-quick) var(--ease),
    color var(--dur-quick) var(--ease);
}

.pg-btn--sm { padding: 8px 16px; font-size: var(--size-body); }
.pg-btn--md { padding: 11.7px 22px; }
.pg-btn--lg { padding: 14px 26px; }

.pg-btn--primary {
  background-image: linear-gradient(var(--accent-2), var(--accent));
  color: var(--on-accent);
  box-shadow: var(--shadow-cta);
}

.pg-btn--primary:hover {
  /* Deepen its OWN tint. Swapping to --shadow-card would hand the button a shadow
     that is greyer and fainter than its resting one, so it would read as sinking —
     which is what the pack's Components section now forbids in those words. */
  box-shadow: 0 4px 14px var(--cta-shadow-tint);
  transform: translateY(-1px);
}

.pg-btn--secondary {
  background-color: var(--surface);
  border-color: var(--rule);
  color: var(--ink-body);
}

.pg-btn--secondary:hover { background-color: var(--surface-2); }

.pg-btn--ghost {
  background-color: transparent;
  color: var(--ink-body);
}

.pg-btn--ghost:hover { background-color: var(--surface-2); }

/* The reference computes outline-style: none on its focused primary CTA and adds
   no compensating shadow, which is the one defect in it a keyboard user meets
   immediately. This kit ships the ring. */
.pg-btn:focus-visible,
.pg-cat:focus-visible,
.pg-row:focus-visible {
  outline: 2px solid var(--accent-strong);
  outline-offset: 2px;
}

.pg-btn:disabled {
  background-image: none;
  background-color: var(--surface-2);
  color: var(--ink-faint);
  border-color: var(--rule);
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}

/* ---- Card --------------------------------------------------------------- */
.pg-card {
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-card);
  padding: 28px;
}

.pg-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 12px;
}

.pg-card__title {
  font-family: var(--font-body);
  font-size: var(--size-body-lg);
  font-weight: var(--weight-emphasis);
  line-height: var(--lh-body-lg);
  color: var(--ink);
  margin: 0;
}

.pg-card__meta {
  font-size: var(--size-chip);
  font-weight: var(--weight-label);
  color: var(--ink-soft);
}

.pg-card__body {
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--ink-soft);
}

/* ---- Chip (the generic tag) --------------------------------------------- */
/* For a category, use CategoryChip: it is the two-layer construction and its
   label word is required. This one is a plain tag. */
.pg-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--size-chip);
  font-weight: var(--weight-label);
  line-height: var(--lh-chip);
  border: 1px solid transparent;
  border-radius: var(--radius-chip);
  padding: 3px 8px;
}

.pg-chip--neutral {
  background-color: var(--surface-2);
  color: var(--ink-soft);
}

.pg-chip--accent {
  background-color: var(--accent-wash);
  color: var(--accent-strong);
}

.pg-chip--selected { border-color: var(--accent-edge); }

/* ---- CategoryChip — the signature -------------------------------------- */
/* Two nested chips: the outer in the deeper tint pair at 8px, the inner in the
   paler pair at 7px with 1px of padding, which is exactly the step the reference
   uses. The label word is required by the component's type, because the hue
   cannot carry the category on its own: darkened to clear AA, the worst
   deuteranopic pair sits 1.24 ΔE apart. */
.pg-cat {
  display: inline-flex;
  padding: 1px;
  border-radius: var(--radius-chip);
  transition: filter var(--dur-quick) var(--ease);
}

.pg-cat__inner {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border-radius: var(--radius-chip-inner);
  padding: 2px 7px;
  font-family: var(--font-body);
  font-size: var(--size-chip);
  font-weight: var(--weight-label);
  line-height: var(--lh-chip);
  white-space: nowrap;
}

.pg-cat:hover { filter: saturate(1.08); }

/* Selected — for a product whose categories are filters. The inner layer takes the
   -150 step instead of -50, and the ink marks the edge. This is the one place a
   chip may carry a border. */
.pg-cat[aria-pressed='true'],
.pg-cat--selected { box-shadow: inset 0 0 0 2px currentColor; }

.pg-cat--reply {
  background-image: linear-gradient(var(--cat-reply-150), var(--cat-reply-200));
}

.pg-cat--reply .pg-cat__inner {
  background-image: linear-gradient(var(--cat-reply-50), var(--cat-reply-100));
  color: var(--cat-reply-ink);
}

.pg-cat--newsletter {
  background-image: linear-gradient(var(--cat-newsletter-150), var(--cat-newsletter-200));
}

.pg-cat--newsletter .pg-cat__inner {
  background-image: linear-gradient(var(--cat-newsletter-50), var(--cat-newsletter-100));
  color: var(--cat-newsletter-ink);
}

.pg-cat--marketing {
  background-image: linear-gradient(var(--cat-marketing-150), var(--cat-marketing-200));
}

.pg-cat--marketing .pg-cat__inner {
  background-image: linear-gradient(var(--cat-marketing-50), var(--cat-marketing-100));
  color: var(--cat-marketing-ink);
}

.pg-cat--calendar {
  background-image: linear-gradient(var(--cat-calendar-150), var(--cat-calendar-200));
}

.pg-cat--calendar .pg-cat__inner {
  background-image: linear-gradient(var(--cat-calendar-50), var(--cat-calendar-100));
  color: var(--cat-calendar-ink);
}

.pg-cat--notification {
  background-image: linear-gradient(var(--cat-notification-150), var(--cat-notification-200));
}

.pg-cat--notification .pg-cat__inner {
  background-image: linear-gradient(var(--cat-notification-50), var(--cat-notification-100));
  color: var(--cat-notification-ink);
}

.pg-cat--cold {
  background-image: linear-gradient(var(--cat-cold-150), var(--cat-cold-200));
}

.pg-cat--cold .pg-cat__inner {
  background-image: linear-gradient(var(--cat-cold-50), var(--cat-cold-100));
  color: var(--cat-cold-ink);
}

.pg-cat--team {
  background-image: linear-gradient(var(--cat-team-150), var(--cat-team-200));
}

.pg-cat--team .pg-cat__inner {
  background-image: linear-gradient(var(--cat-team-50), var(--cat-team-100));
  color: var(--cat-team-ink);
}

.pg-cat--urgent {
  background-image: linear-gradient(var(--cat-urgent-150), var(--cat-urgent-200));
}

.pg-cat--urgent .pg-cat__inner {
  background-image: linear-gradient(var(--cat-urgent-50), var(--cat-urgent-100));
  color: var(--cat-urgent-ink);
}

.pg-cat--step {
  background-image: linear-gradient(var(--cat-step-150), var(--cat-step-200));
}

.pg-cat--step .pg-cat__inner {
  background-image: linear-gradient(var(--cat-step-50), var(--cat-step-100));
  color: var(--cat-step-ink);
}

.pg-cat--reply[aria-pressed='true'] .pg-cat__inner,
.pg-cat--reply.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-reply-150), var(--cat-reply-200));
  color: var(--cat-reply-ink);
}

.pg-cat--newsletter[aria-pressed='true'] .pg-cat__inner,
.pg-cat--newsletter.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-newsletter-150), var(--cat-newsletter-200));
  color: var(--cat-newsletter-ink);
}

.pg-cat--marketing[aria-pressed='true'] .pg-cat__inner,
.pg-cat--marketing.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-marketing-150), var(--cat-marketing-200));
  color: var(--cat-marketing-ink);
}

.pg-cat--calendar[aria-pressed='true'] .pg-cat__inner,
.pg-cat--calendar.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-calendar-150), var(--cat-calendar-200));
  color: var(--cat-calendar-ink);
}

.pg-cat--notification[aria-pressed='true'] .pg-cat__inner,
.pg-cat--notification.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-notification-150), var(--cat-notification-200));
  color: var(--cat-notification-ink);
}

.pg-cat--cold[aria-pressed='true'] .pg-cat__inner,
.pg-cat--cold.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-cold-150), var(--cat-cold-200));
  color: var(--cat-cold-ink);
}

.pg-cat--team[aria-pressed='true'] .pg-cat__inner,
.pg-cat--team.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-team-150), var(--cat-team-200));
  color: var(--cat-team-ink);
}

.pg-cat--urgent[aria-pressed='true'] .pg-cat__inner,
.pg-cat--urgent.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-urgent-150), var(--cat-urgent-200));
  color: var(--cat-urgent-ink);
}

.pg-cat--step[aria-pressed='true'] .pg-cat__inner,
.pg-cat--step.pg-cat--selected .pg-cat__inner {
  background-image: linear-gradient(var(--cat-step-150), var(--cat-step-200));
  color: var(--cat-step-ink);
}

/* ---- LabelledRow — one row of the product, labelled -------------------- */
.pg-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-card);
  padding: 16px 20px;
  transition: box-shadow var(--dur-quick) var(--ease),
    transform var(--dur-quick) var(--ease);
}

.pg-row:hover { box-shadow: var(--shadow-soft); transform: translateY(-1px); }

.pg-row--unread .pg-row__subject { font-weight: var(--weight-emphasis); }

.pg-row__body { width: 100%; }

.pg-row__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.pg-row__from {
  font-size: var(--size-body);
  font-weight: var(--weight-label);
  color: var(--ink);
}

.pg-row__date {
  font-size: var(--size-chip);
  color: var(--ink-soft);
  white-space: nowrap;
}

.pg-row__subject {
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--ink-body);
}

.pg-row__preview {
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- WashCard ---------------------------------------------------------- */
/* The shadow is mixed toward the card's own hue rather than toward black. That
   is why the page reads coloured while the field stays white, and it is the
   detail most often dropped when this look is copied. */
.pg-wash {
  border-radius: var(--radius-panel);
  padding: 28px;
  transition: transform var(--dur-quick) var(--ease);
}

.pg-wash:hover { transform: translateY(-1px); }

.pg-wash__title {
  font-family: var(--font-display);
  font-size: var(--size-sub);
  font-weight: var(--weight-display);
  line-height: var(--lh-sub);
  color: var(--ink);
  margin: 0 0 8px;
}

.pg-wash__body {
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--ink-body);
}

.pg-wash--reply {
  background-image: linear-gradient(var(--cat-reply-50), var(--cat-reply-100));
  box-shadow: 0 2px 3.4px var(--cat-reply-150), 0 1px 1px var(--cat-reply-200);
}

.pg-wash--newsletter {
  background-image: linear-gradient(var(--cat-newsletter-50), var(--cat-newsletter-100));
  box-shadow: 0 2px 3.4px var(--cat-newsletter-150), 0 1px 1px var(--cat-newsletter-200);
}

.pg-wash--marketing {
  background-image: linear-gradient(var(--cat-marketing-50), var(--cat-marketing-100));
  box-shadow: 0 2px 3.4px var(--cat-marketing-150), 0 1px 1px var(--cat-marketing-200);
}

.pg-wash--calendar {
  background-image: linear-gradient(var(--cat-calendar-50), var(--cat-calendar-100));
  box-shadow: 0 2px 3.4px var(--cat-calendar-150), 0 1px 1px var(--cat-calendar-200);
}

.pg-wash--notification {
  background-image: linear-gradient(var(--cat-notification-50), var(--cat-notification-100));
  box-shadow: 0 2px 3.4px var(--cat-notification-150), 0 1px 1px var(--cat-notification-200);
}

.pg-wash--cold {
  background-image: linear-gradient(var(--cat-cold-50), var(--cat-cold-100));
  box-shadow: 0 2px 3.4px var(--cat-cold-150), 0 1px 1px var(--cat-cold-200);
}

.pg-wash--team {
  background-image: linear-gradient(var(--cat-team-50), var(--cat-team-100));
  box-shadow: 0 2px 3.4px var(--cat-team-150), 0 1px 1px var(--cat-team-200);
}

.pg-wash--urgent {
  background-image: linear-gradient(var(--cat-urgent-50), var(--cat-urgent-100));
  box-shadow: 0 2px 3.4px var(--cat-urgent-150), 0 1px 1px var(--cat-urgent-200);
}

.pg-wash--step {
  background-image: linear-gradient(var(--cat-step-50), var(--cat-step-100));
  box-shadow: 0 2px 3.4px var(--cat-step-150), 0 1px 1px var(--cat-step-200);
}

/* ---- Stat -------------------------------------------------------------- */
.pg-stat { display: flex; flex-direction: column; gap: 4px; }

.pg-stat__label {
  font-size: var(--size-chip);
  font-weight: var(--weight-label);
  color: var(--ink-soft);
}

.pg-stat__value {
  font-family: var(--font-display);
  font-size: var(--size-head);
  font-weight: var(--weight-display);
  line-height: var(--lh-head);
  color: var(--ink);
}

.pg-stat__source { font-size: var(--size-micro); color: var(--ink-faint); }

/* ---- Heading ----------------------------------------------------------- */
/* Weight 400 at every level. A 600 display is a different pack. */
.pg-heading {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  color: var(--ink);
  margin: 0;
}

.pg-heading--1 { font-size: var(--size-display); line-height: var(--lh-display); }
.pg-heading--2 { font-size: var(--size-head); line-height: var(--lh-head); }
.pg-heading--3 { font-size: var(--size-sub); line-height: 1.2; }

/* ---- Rule -------------------------------------------------------------- */
.pg-rule {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 0;
}

.pg-rule--strong { border-top-width: 2px; border-top-color: var(--rule-strong); }

/* ---- FaqList ----------------------------------------------------------- */
.pg-faq { margin: 0; }

.pg-faq__row {
  border-top: 1px solid var(--rule);
  padding: 20px 0;
}

.pg-faq__q {
  font-size: var(--size-body-lg);
  font-weight: var(--weight-emphasis);
  line-height: 1.5;
  color: var(--ink);
}

.pg-faq__a {
  margin: 6px 0 0;
  font-size: var(--size-body);
  line-height: var(--lh-body);
  color: var(--ink-soft);
  max-width: var(--measure-body);
}

/* ---- The logo marquee -------------------------------------------------- */
/* 100s, linear, and the one continuous animation in the pack. */
.pg-marquee {
  display: flex;
  gap: var(--gutter); /* the measured gutter, reused: the marquee's own gap was not measured */
  animation: pg-marquee var(--dur-marquee) linear infinite;
}

@keyframes pg-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ---- Reduced motion ---------------------------------------------------- */
/* The durations already collapse in the token layer. Two things a duration cannot
   do: stop a transform, and stop an INFINITE animation — at 0.01ms the marquee
   would strobe roughly a hundred thousand times a second at the reader this query
   protects, which is worse than the motion it replaced. */
@media (prefers-reduced-motion: reduce) {
  .pg-btn--primary:hover,
  .pg-row:hover,
  .pg-wash:hover { transform: none; }
  .pg-cat:hover { filter: none; }
  .pg-marquee { animation-play-state: paused; }
}
