/*
 * BeastPing — brand tokens.
 *
 * This file contains **values only**. It declares no selector the core
 * stylesheet does not already style, adds no component, and changes no layout.
 * That is the whole white-label contract: to add a brand, copy this directory,
 * change the numbers, and register a `Brand` in `gaming_platform.branding`.
 *
 * Identity: a high-performance gaming network. Dark-first, near-black graphite
 * ground, neon green as the action colour, violet as the counter-accent, and
 * controlled glow - lit, not luminous. The two hues meet on hairlines and card
 * edges rather than being splashed across surfaces, which is the difference
 * between a technical brand and an RGB peripheral.
 *
 * ## Three blocks, not four
 *
 *   :root                                          dark   (the brand default)
 *   @media (prefers-color-scheme: light)           light  (the OS asked, and
 *     :root:not([data-theme="dark"])                      the viewer did not
 *                                                         say otherwise)
 *   :root[data-theme="light"]                      light  (the viewer chose)
 *
 * There is deliberately no `[data-theme="dark"]` block. The `:not()` on the
 * media query already excludes an explicit dark choice, so `:root` wins on its
 * own - and a fourth block would be fifty duplicated lines whose only job is to
 * restate the first. Every combination is covered:
 *
 *   OS dark,  no choice     -> media does not apply           -> :root (dark)
 *   OS light, no choice     -> media applies                  -> light
 *   OS light, chose dark    -> media excluded by :not()       -> :root (dark)
 *   OS dark,  chose light   -> [data-theme] outranks :root    -> light
 *
 * With JavaScript disabled the media block still applies, so the brand is
 * correct in both schemes before the toggle exists.
 */

@layer brand {

:root {
  color-scheme: dark;
  --display-light-theme: none;
  --display-dark-theme: inline-block;

  /* UX10-A 06. Optical sizing for the supplied PlayStation mark: its artwork is
     wide and short on its canvas, so at the shared box size it read visibly
     lighter than the round Xbox and square Nintendo marks beside it. Uniform
     scale only - its proportions are the supplied ones. */
  --platform-mark-scale-playstation: 1.18;

  /* -- ground ----------------------------------------------------------- */
  --paper: #06080c;
  --chrome: #0a0e14;
  --surface: #0e131b;
  --surface-raised: #121926;
  --surface-sunken: #080b11;
  --band: #080c12;

  /* -- text ------------------------------------------------------------- */
  --ink: #eaf2ec;
  --ink-soft: #9fb2a8;
  --ink-faint: #718478;

  /* -- edges ------------------------------------------------------------ */
  --line: #1c2633;
  --line-strong: #2b3a4a;

  /* -- accents ---------------------------------------------------------- */
  /* Neon green carries every primary action. The contrast colour is the near
     black ground rather than white, because green this bright needs dark text
     on it to stay readable. */
  --accent: #00ee76;
  --accent-strong: #3dff96;
  --accent-soft: #0d2418;
  --accent-contrast: #04120a;
  --accent-edge: rgba(0, 238, 118, 0.3);

  /* Violet is the counter-accent: a second signature colour for one action per
     view, never a third button style. */
  --accent-2: #8b5cf6;
  --accent-2-soft: #1c1533;
  --accent-2-contrast: #0b0616;

  /* Primary fills are gradients rather than flat colour: two stops of the same
     hue give a button a lit edge without adding an element to draw it. */
  --accent-fill: linear-gradient(135deg, #00ee76 0%, #00b957 100%);
  --accent-2-fill: linear-gradient(135deg, #9d75ff 0%, #7c46f0 100%);

  /* -- status ----------------------------------------------------------- */
  /* Deliberately distinct from --accent. If "OK" were the same green as the
     primary button, a status would read as an action. */
  --ok: #5fd7a0;
  --ok-tint: #0c2419;
  --warn: #e8b45c;
  --warn-tint: #251d0f;
  --danger: #f2848a;
  --danger-tint: #2a1216;
  --info: #7cc4f0;
  --info-tint: #0d1f2b;

  /* -- depth and glow ---------------------------------------------------- */
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.55), 0 6px 20px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 2px 10px rgba(0, 0, 0, 0.6), 0 26px 64px rgba(0, 0, 0, 0.55);
  --glow: 0 0 0 1px rgba(0, 238, 118, 0.22), 0 6px 20px rgba(0, 238, 118, 0.2);
  --glow-strong: 0 0 0 1px rgba(0, 238, 118, 0.34), 0 10px 32px rgba(0, 238, 118, 0.32);
  --glow-soft: 0 0 18px rgba(0, 238, 118, 0.16);
  --glow-2: 0 0 0 1px rgba(139, 92, 246, 0.26), 0 6px 20px rgba(139, 92, 246, 0.24);
  --ring: #00ee76;

  /* -- atmosphere -------------------------------------------------------- */
  /*
   * One fixed light layer behind the whole document. Green rises from the start
   * edge, violet answers from the far corner, and a third stop pulls the bottom
   * of the page back toward black so content lower down sits on a calm surface
   * instead of a permanent wash.
   *
   * Gradients cannot use logical directions, so the composition is built to read
   * the same either way round: the two lights are near-symmetric about the
   * centre, and neither carries meaning that depends on which edge it is on.
   */
  --page-glow:
    radial-gradient(58% 44% at 8% -6%, rgba(0, 238, 118, 0.16), transparent 70%),
    radial-gradient(52% 40% at 94% -2%, rgba(139, 92, 246, 0.18), transparent 68%),
    radial-gradient(90% 60% at 50% 108%, rgba(139, 92, 246, 0.07), transparent 72%);

  /* A brighter key light behind the hero artwork, so the hero is the lit part of
     the page rather than the page being uniformly bright. */
  --hero-key:
    radial-gradient(38% 46% at 72% 42%, rgba(0, 238, 118, 0.2), transparent 72%),
    radial-gradient(30% 34% at 86% 18%, rgba(139, 92, 246, 0.16), transparent 70%);

  --hero-wash: linear-gradient(180deg, rgba(10, 14, 20, 0.92) 0%, rgba(6, 8, 12, 0) 100%);

  /* UX-2 homepage artwork. Three sources, because a landscape crop and a
     portrait composition are two different pictures rather than one picture at
     two sizes: the wide pair is the desktop field, and the portrait carries the
     same two worlds up the screen instead of across it.

     Addressed from the static root rather than relatively, and that is not a
     preference. A relative URL inside a custom property is resolved where the
     property is *used* and not where it is declared, so a path written
     relative to this file sends the browser to the core stylesheet's
     directory instead. The paths below therefore assume STATIC_URL is
     "/static/", which the test suite asserts rather than trusts. */
  /* A3 section accents. Values, like every other brand decision here: the core
     sizes and masks a band it never names. */
  --divider-art: url("/static/brands/beastping/art/ux2/a3/accents/divider-wave-dark.d4cc35c11af2.svg");

  /* A3.2 section artwork. The same mechanism as the hero: the core sizes a
     picture it never names, and only the active theme's file is ever fetched. */
  /* UX10-A correction 02. The route band takes the wide, map-led scene and the
     featured shelf takes the globe over a city, so each landing section stands on
     a picture chosen for the thing it is about rather than on a gradient. */
  --network-art: url("/static/brands/beastping/services/ux6-overview-scene-dark.4a6bb6578d6b.webp");
  --network-art-narrow: url("/static/brands/beastping/services/ux6-overview-scene-mobile-dark.ac7ba6bcde64.webp");
  --network-veil:
    linear-gradient(180deg,
      rgba(3, 5, 9, 0.62) 0%,
      rgba(3, 5, 9, 0.52) 40%,
      rgba(3, 5, 9, 0.86) 100%);
  --featured-art: url("/static/brands/beastping/art/ux2/a3/sections/network-route-dark.1e0f47750d70.webp");
  --featured-veil:
    linear-gradient(180deg,
      rgba(3, 5, 9, 0.72) 0%,
      rgba(3, 5, 9, 0.5) 45%,
      rgba(3, 5, 9, 0.88) 100%);
  --closing-art: url("/static/brands/beastping/art/ux2/a3/sections/final-cta-dark.267529a298dd.webp");
  /* Lighter at the top than a hero veil, because the top is where the artwork
     is looking back at the reader; the copy sits in the dark middle of the
     picture and needs less help than it looks like it does. */
  --closing-veil:
    linear-gradient(180deg,
      rgba(3, 5, 9, 0.3) 0%,
      rgba(3, 5, 9, 0.62) 44%,
      rgba(3, 5, 9, 0.82) 100%);
  --section-watermark: url("/static/brands/beastping/art/ux2/a3/accents/section-watermark-dark.0e5f56ef97ab.svg");

  --hero-art: url("/static/brands/beastping/art/ux2/hero-dark-wide.eb6b6b287534.webp");
  --hero-art-sm: url("/static/brands/beastping/art/ux2/hero-dark-wide-sm.b1b38236f67a.webp");
  --hero-art-narrow: url("/static/brands/beastping/art/ux2/hero-mobile-dual.8e0cc47e131d.webp");

  /* Hold the globe high in the frame and keep the reflective floor, which is
     the part of the picture the copy is meant to sit on. */
  --hero-art-focus: 50% 44%;
  --hero-art-focus-narrow: 50% 36%;
  --hero-art-ground: #05070a;

  /* Dimming, not a panel. Almost nothing at the top so the globe keeps its
     light, then deep enough by the last third that white type on it clears
     contrast with room to spare. */
  --hero-veil:
    linear-gradient(180deg,
      rgba(3, 5, 9, 0.14) 0%,
      rgba(3, 5, 9, 0.3) 38%,
      rgba(3, 5, 9, 0.72) 68%,
      rgba(5, 7, 10, 0.95) 100%);
  --hero-ink-shadow: 0 2px 22px rgba(0, 0, 0, 0.55);

  /* UX-3A. The front door has its own picture. It is a portrait composition and
     the narrative column is a portrait shape, so it is carried almost uncropped
     - the focus only lifts it enough to keep the Beast's head and the globe
     above the words rather than behind them.

     The veil is a floor, not a fog: nothing at all across the top two thirds so
     the artwork keeps its depth, then deepening to near-solid at the bottom
     where the lockup and the sentence sit. Anchoring the words to the foot is
     what makes one picture work in Persian and in English - a band has no side
     to be on, so neither writing direction collides with the composition. */
  --auth-art: url("/static/brands/beastping/art/ux3/auth/auth-visual-dark.5d18f1424a98.webp");
  --auth-art-position: 50% 26%;
  --auth-art-ground: #05070a;
  --auth-art-veil:
    linear-gradient(180deg,
      rgba(3, 5, 9, 0) 0%,
      rgba(3, 5, 9, 0.12) 42%,
      rgba(3, 5, 9, 0.62) 66%,
      rgba(4, 6, 10, 0.9) 82%,
      rgba(4, 6, 10, 0.96) 100%);

  /* Glass. Dark enough to read against, translucent enough that the artwork
     still moves behind the cards that overlap it. */
  --surface-glass: rgba(19, 24, 32, 0.66);
  --glass-blur: blur(16px) saturate(1.1);

  /* Showcase tiles. The ground is a lit floor rather than a flat panel, so a
     cut-out figure standing on it has something to stand on; the veil lands
     under the caption and nowhere near the figure's head. */
  --tile-ground:
    radial-gradient(120% 72% at 50% 108%, rgba(0, 238, 118, 0.22), transparent 68%),
    linear-gradient(180deg, rgba(24, 30, 40, 0.9) 0%, rgba(10, 13, 18, 0.96) 100%);
  --tile-veil: linear-gradient(180deg, transparent 46%, rgba(5, 7, 10, 0.82) 88%);

  /* UX-4. The dashboard's three pictures.

     The hero is a wide night composition - a figure at the left, the globe
     through the middle, a lit city at the right - and the words go over the
     city. So the veil is a *side* wash rather than a floor: near-solid at the
     right edge where the copy sits, gone by the middle so the globe keeps its
     light, and a thin darkening along the bottom to seat the band on the cards
     below it. A gradient angle is physical, which is what this needs to be: the
     figure does not move to the other side when the language does.

     The mobile crop is square and the subject sits high in it, so its veil is a
     floor instead - the copy drops below the picture and reads off a solid
     base. */
  --dashboard-hero-art: url("/static/brands/beastping/dashboard/dashboard-hero-dark.8b96e9c4518c.webp");
  --dashboard-hero-art-mobile: url("/static/brands/beastping/dashboard/dashboard-hero-dark-mobile.e0d31ca8fc65.webp");
  --dashboard-hero-position: 50% 46%;
  --dashboard-hero-ground: #04060a;
  --dashboard-hero-veil:
    linear-gradient(270deg,
      rgba(4, 6, 10, 0.94) 0%,
      rgba(4, 6, 10, 0.9) 22%,
      rgba(4, 6, 10, 0.66) 42%,
      rgba(4, 6, 10, 0.24) 62%,
      rgba(4, 6, 10, 0.06) 100%),
    linear-gradient(180deg,
      rgba(4, 6, 10, 0.34) 0%,
      rgba(4, 6, 10, 0) 34%,
      rgba(4, 6, 10, 0.3) 82%,
      rgba(4, 6, 10, 0.72) 100%);
  --dashboard-hero-veil-mobile:
    linear-gradient(180deg,
      rgba(4, 6, 10, 0.12) 0%,
      rgba(4, 6, 10, 0.08) 20%,
      rgba(4, 6, 10, 0.66) 34%,
      rgba(4, 6, 10, 0.93) 44%,
      rgba(4, 6, 10, 0.98) 100%);
  --dashboard-hero-edge: rgba(0, 238, 118, 0.22);

  /* UX7A-A11Y-01. The dashboard's wash is darkest at one side, because its
     copy sits at one side; the wallet centres its copy over the globe, where
     that wash is thinnest, and its lede fell to about 3:1 on the painted art.
     The wallet's own wash is an ellipse sized in rem around the centred copy,
     so it follows the copy rather than the band's width, over a light top and
     bottom fade. The picture stays open at both sides. */
  --wallet-hero-veil:
    radial-gradient(ellipse 30rem 10.5rem at 50% 52%,
      rgba(4, 6, 10, 0.82) 0%,
      rgba(4, 6, 10, 0.76) 55%,
      rgba(4, 6, 10, 0.4) 80%,
      rgba(4, 6, 10, 0) 100%),
    linear-gradient(180deg,
      rgba(4, 6, 10, 0.3) 0%,
      rgba(4, 6, 10, 0) 34%,
      rgba(4, 6, 10, 0.3) 82%,
      rgba(4, 6, 10, 0.66) 100%);

  /* The support photograph is a quiet one, so it is dimmed to a texture and the
     words sit on an almost-solid card. It decorates the message; it is not the
     message. */
  --dashboard-support-art: url("/static/brands/beastping/dashboard/dashboard-support-dark.aaeddd5edfc8.webp");
  --dashboard-support-art-mobile: url("/static/brands/beastping/dashboard/dashboard-support-dark-mobile.e5e3970f9ed4.webp");
  --dashboard-support-veil:
    linear-gradient(200deg,
      rgba(11, 15, 21, 0.7) 0%,
      rgba(11, 15, 21, 0.88) 46%,
      rgba(11, 15, 21, 0.96) 100%);

  --dashboard-controller-art: url("/static/brands/beastping/dashboard/dashboard-controller-dark.8a74c089f60b.webp");
  --dashboard-controller-art-small: url("/static/brands/beastping/dashboard/dashboard-controller-dark-small.b129ab15e3a9.webp");

  /* A summary card is lit from its own corner rather than outlined in neon.
     One low-opacity wash is the difference between a premium panel and an RGB
     box, and the row has three of them side by side. */
  --dashboard-card-glow:
    radial-gradient(120% 140% at 100% 0%, rgba(0, 238, 118, 0.07), transparent 62%);
  --dashboard-icon-ring: rgba(0, 238, 118, 0.09);
  --dashboard-accent-text: var(--accent);

  /* -- UX-5 commerce ----------------------------------------------------
   *
   * The catalog, offer, checkout and payment-result artwork, and the veils that
   * make text over it legible. Values only: the layout, the veil shape and the
   * opacities are the core stylesheet's, and nothing here adds a selector.
   *
   * Each token is redefined per theme block rather than paired with a second
   * "-light" token, so exactly one file is ever resolved - a dark viewer never
   * fetches the daylight artwork and vice versa. */
  --commerce-hero-art: url("/static/brands/beastping/commerce/catalog-hero-dark.69ac123826be.webp");
  --commerce-hero-position: 50% 42%;
  --commerce-hero-ground: #05080c;
  /* Physical, and deliberately so: the picture has a figure at one edge and a
     city at the other, and neither swaps when the language does. The veil
     darkens the whole band towards the reading side just enough to carry AA
     text over either end. */
  --commerce-hero-veil:
    linear-gradient(180deg,
      rgba(5, 8, 12, 0.42) 0%,
      rgba(5, 8, 12, 0.62) 55%,
      rgba(5, 8, 12, 0.86) 100%);
  --commerce-hero-edge: rgba(0, 238, 118, 0.22);

  --commerce-tiers-art: url("/static/brands/beastping/commerce/service-tiers-dark.517a7daface6.webp");
  --commerce-tiers-veil:
    linear-gradient(180deg, rgba(11, 15, 21, 0.55), rgba(11, 15, 21, 0.92));

  --commerce-secure-art: url("/static/brands/beastping/commerce/checkout-security-dark.43a2716aa574.webp");
  --commerce-secure-veil:
    linear-gradient(180deg, rgba(11, 15, 21, 0.62), rgba(11, 15, 21, 0.93));

  --commerce-success-art: url("/static/brands/beastping/commerce/payment-success-dark.6d8914f6d691.webp");
  --commerce-success-veil:
    linear-gradient(180deg, rgba(11, 15, 21, 0.58), rgba(11, 15, 21, 0.9));

  /* The same one low-opacity wash the dashboard cards use, for the same reason:
     lit, not luminous. */
  --commerce-card-glow:
    radial-gradient(120% 140% at 100% 0%, rgba(0, 238, 118, 0.07), transparent 62%);
  --commerce-accent-text: var(--accent);

  /* -- UX-6 active services ---------------------------------------------
   *
   * My Services and one owned service. Values only: the layout, the veil shape
   * and the opacities are the core stylesheet's, and nothing here adds a
   * selector.
   *
   * Each token is redefined per theme block rather than paired with a second
   * "-light" token, so exactly one file is ever resolved - a dark viewer never
   * fetches the daylight artwork and vice versa - and the narrow variants are
   * separate files rather than a crop, so a phone downloads a phone-sized
   * picture. */
  --services-hero-art: url("/static/brands/beastping/services/ux6-hero-dark.c80f5a51423f.webp");
  --services-hero-art-mobile: url("/static/brands/beastping/services/ux6-hero-mobile-dark.567db704225c.webp");
  /* Physical, and deliberately so: the wide composition has a figure at one end
     and a luminous globe at the other, and neither swaps when the language
     does. The tall crop puts its subject high in the frame, so the narrow
     anchor sits near the top and leaves a floor for the words. */
  --services-hero-position: 50% 38%;
  --services-hero-position-mobile: 50% 10%;
  --services-hero-ground: #05080c;
  --services-hero-veil:
    linear-gradient(180deg,
      rgba(5, 8, 12, 0.44) 0%,
      rgba(5, 8, 12, 0.64) 55%,
      rgba(5, 8, 12, 0.88) 100%);
  /* A floor rather than a side wash. With the copy full-width under the picture,
     a gradient that darkened one edge would dim the artwork and still leave the
     words on the bright half. */
  --services-hero-veil-mobile:
    linear-gradient(180deg,
      rgba(5, 8, 12, 0.28) 0%,
      rgba(5, 8, 12, 0.52) 46%,
      rgba(5, 8, 12, 0.93) 100%);
  --services-hero-edge: rgba(0, 238, 118, 0.22);

  --services-scene-art: url("/static/brands/beastping/services/ux6-overview-scene-dark.4a6bb6578d6b.webp");
  --services-scene-art-mobile: url("/static/brands/beastping/services/ux6-overview-scene-mobile-dark.ac7ba6bcde64.webp");
  --services-scene-veil:
    linear-gradient(180deg, rgba(11, 15, 21, 0.58), rgba(11, 15, 21, 0.9));

  --services-frame-art: url("/static/brands/beastping/services/ux6-detail-frame-dark.7ec0dc28e55a.webp");
  --services-frame-art-mobile: url("/static/brands/beastping/services/ux6-detail-frame-mobile-dark.81019ae8555d.webp");
  /* SERVICE-DETAIL-COMPACT-01: the detail band's creature - the brand's existing neon beast. */
  --services-beast-art: url("/static/brands/beastping/art/ux3/auth/auth-visual-dark.5d18f1424a98.webp");
  --services-beast-position: 50% 6%;
  --services-frame-veil:
    linear-gradient(180deg, rgba(11, 15, 21, 0.6), rgba(11, 15, 21, 0.92));

  /* The same one low-opacity wash the dashboard and the shop cards use, for the
     same reason: lit, not luminous. */
  --services-card-glow:
    radial-gradient(120% 140% at 100% 0%, rgba(0, 238, 118, 0.07), transparent 62%);
  --services-accent-text: var(--accent);

  /* PO-SVC-REFRESH-ORANGE: warm neon orange on the refresh action only - an outlined, faintly
   * tinted control with a restrained glow, secondary to the green actions. Orange text on this
   * ground measures about 8:1. */
  --service-refresh-text: #ff8a00;
  --service-refresh-text-hover: #ffa31a;
  --service-refresh-accent: #ff8a00;
  --service-refresh-accent-hover: #ffa31a;
  --service-refresh-edge: rgba(255, 138, 0, 0.55);
  --service-refresh-edge-hover: #ffa31a;
  --service-refresh-tint: rgba(255, 138, 0, 0.06);
  --service-refresh-tint-hover: rgba(255, 163, 26, 0.12);
  --service-refresh-glow: 0 0 8px rgba(255, 138, 0, 0.35);
  --service-refresh-glow-hover: 0 0 14px rgba(255, 138, 0, 0.35);
  /* EMAIL-VERIFY-COOLDOWN-01: the verification card's short helper lines in the same neon orange
   * as the refresh action - about 8:1 on this ground. */
  --verification-hint-text: var(--service-refresh-text);

  --grid-line: rgba(0, 238, 118, 0.055);

  /* The signature thread under the chrome: green into violet, faded at both
     ends so it never terminates against the viewport edge. */
  --hairline: linear-gradient(90deg, transparent 5%, rgba(0, 238, 118, 0.6) 30%, rgba(139, 92, 246, 0.5) 70%, transparent 95%);
  --hairline-soft: linear-gradient(90deg, transparent, rgba(0, 238, 118, 0.16), rgba(139, 92, 246, 0.14), transparent);
  --edge: linear-gradient(90deg, transparent, rgba(0, 238, 118, 0.55), rgba(139, 92, 246, 0.4), transparent);
}

/*
 * Daylight. The same identity at a tenth of the strength - the two hues darken
 * enough to hold contrast on a light ground, the grid stays, and the glow is
 * dropped entirely, because a neon bloom on white reads as a rendering fault
 * rather than a style. It is BeastPing with the lights on, not a generic white
 * SaaS page.
 */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --display-light-theme: inline-block;
    --display-dark-theme: none;

    --paper: #f4f7f5;
    --chrome: #ffffff;
    --surface: #ffffff;
    --surface-raised: #ffffff;
    --surface-sunken: #eef2ef;
    --band: #eaefec;

    --ink: #0d1512;
    --ink-soft: #48584f;
    --ink-faint: #6b7a71;

    --line: #dde5e0;
    --line-strong: #c2cec7;

    --accent: #0d8f42;
    --accent-strong: #0a7135;
    --accent-soft: #e2f6ea;
    --accent-contrast: #ffffff;
    --accent-edge: rgba(13, 143, 66, 0.24);

    --accent-2: #6d3fd4;
    --accent-2-soft: #efe9fd;
    --accent-2-contrast: #ffffff;

    --accent-fill: linear-gradient(135deg, #12a44d 0%, #0b7a39 100%);
    --accent-2-fill: linear-gradient(135deg, #7d51e0 0%, #6134c4 100%);

    --ok: #1f6b45;
    --ok-tint: #e4f3ea;
    --warn: #8a5a06;
    --warn-tint: #fbf0dc;
    --danger: #9a2c2c;
    --danger-tint: #fbe9e9;
    --info: #285a86;
    --info-tint: #e6f1f8;

    --shadow: 0 1px 2px rgba(13, 21, 18, 0.06), 0 4px 16px rgba(13, 21, 18, 0.05);
    --shadow-lg: 0 2px 6px rgba(13, 21, 18, 0.08), 0 18px 48px rgba(13, 21, 18, 0.09);
    --glow: 0 1px 2px rgba(13, 21, 18, 0.08), 0 6px 18px rgba(13, 143, 66, 0.16);
    --glow-strong: 0 2px 4px rgba(13, 21, 18, 0.1), 0 10px 26px rgba(13, 143, 66, 0.22);
    --glow-soft: none;
    --glow-2: 0 1px 2px rgba(13, 21, 18, 0.08), 0 6px 18px rgba(109, 63, 212, 0.18);
    --ring: #0d8f42;

    --page-glow:
      radial-gradient(56% 42% at 8% -6%, rgba(13, 143, 66, 0.09), transparent 70%),
      radial-gradient(50% 38% at 94% -2%, rgba(109, 63, 212, 0.09), transparent 68%);
    --hero-key: radial-gradient(38% 46% at 72% 42%, rgba(13, 143, 66, 0.1), transparent 72%);
    --hero-wash: linear-gradient(180deg, #ffffff 0%, rgba(244, 247, 245, 0) 100%);

    --divider-art: url("/static/brands/beastping/art/ux2/a3/accents/divider-wave-light.e76b0f6e851f.svg");

    /* UX10-A correction 02. The Product Owner's light section pack: the same art
       direction as dark - a world of routes, a stage under a globe, and the
       Beast's eyes at the end - lit for a bright page instead of re-lighting the
       dark files. The pack's panel pictures stay in the repository; the section
       that showed them was removed in UX10-A 07. */
    --network-art: url("/static/brands/beastping/art/ux10/sections/landing-section-light-routes-map-desktop.491a1ad67557.webp");
    --network-art-narrow: url("/static/brands/beastping/art/ux10/sections/landing-section-light-routes-map-mobile.1f67a7250339.webp");
    --network-veil:
      linear-gradient(180deg,
        rgba(255, 255, 255, 0.64) 0%,
        rgba(252, 253, 253, 0.54) 40%,
        rgba(248, 251, 249, 0.86) 100%);
    --featured-art: url("/static/brands/beastping/art/ux10/sections/landing-section-light-featured-globe-desktop.97b19764ff77.webp");
    --featured-art-narrow: url("/static/brands/beastping/art/ux10/sections/landing-section-light-featured-globe-mobile.64ab3e451fda.webp");
    --featured-veil:
      linear-gradient(180deg,
        rgba(255, 255, 255, 0.7) 0%,
        rgba(252, 253, 253, 0.5) 45%,
        rgba(248, 251, 249, 0.88) 100%);
    --closing-art: url("/static/brands/beastping/art/ux10/sections/landing-section-light-cta-eyes-desktop.7f49e09e9ff2.webp");
    --closing-art-narrow: url("/static/brands/beastping/art/ux10/sections/landing-section-light-cta-eyes-mobile.77f1048e3973.webp");
    --closing-veil:
      linear-gradient(180deg,
        rgba(255, 255, 255, 0.4) 0%,
        rgba(252, 253, 253, 0.7) 44%,
        rgba(248, 251, 249, 0.86) 100%);
    --section-watermark: url("/static/brands/beastping/art/ux2/a3/accents/section-watermark-light.932c57ac3e13.svg");

    /* Separate artwork, not the dark artwork filtered. UX10-RESP-01: the phone
       portrait is now composed from the approved light wide hero itself - the
       same stadium, globe, city and two figures, arranged like the dark
       portrait - rather than cut-out figures on an empty pale sky, so Light and
       Dark read as one art direction. The narrow scrim is lighter to match: the
       figures stay visible through it and the headline still clears contrast. */
    --hero-art: url("/static/brands/beastping/art/ux2/hero-light-wide.75d77a493c34.webp");
    --hero-art-sm: url("/static/brands/beastping/art/ux2/hero-light-wide-sm.a313a3e3c20d.webp");
    --hero-art-narrow: url("/static/brands/beastping/art/ux10/hero-light-mobile.e578b5f25ed1.webp");

    /* A panel behind the words, not a wash over the picture.
     *
     * Measured rather than guessed: at 390px the eyebrow sits at 29-35% of the
     * hero, the headline at 37-55%, the body at 57-68% and the two actions at
     * 71-94%. The actions are opaque buttons and the eyebrow is a filled pill,
     * so they carry their own contrast - which means the old wash was heaviest
     * (0.93 to 1.0) exactly where nothing needed it, and that is what turned the
     * lower half into fog and erased both characters.
     *
     * So the scrim concentrates on 34-70%, where black type meets artwork, and
     * lets go below 76% where the buttons take over. The floor, the ball and
     * both figures keep their contrast. */
    --hero-veil-narrow:
      linear-gradient(180deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.04) 24%,
        rgba(250, 252, 253, 0.5) 33%,
        rgba(250, 252, 253, 0.74) 45%,
        rgba(250, 252, 253, 0.72) 60%,
        rgba(250, 252, 253, 0.46) 70%,
        rgba(250, 252, 253, 0.16) 76%,
        rgba(250, 252, 253, 0.06) 88%,
        rgba(244, 247, 245, 0.2) 100%);

    --hero-art-focus: 50% 44%;
    --hero-art-focus-narrow: 50% 38%;
    --hero-art-ground: #ffffff;

    --hero-veil:
      linear-gradient(180deg,
        rgba(255, 255, 255, 0.03) 0%,
        rgba(255, 255, 255, 0.28) 34%,
        rgba(253, 254, 253, 0.72) 56%,
        rgba(250, 252, 251, 0.93) 74%,
        rgba(244, 247, 245, 1) 100%);
    --hero-ink-shadow: 0 0 12px rgba(255, 255, 255, 0.92), 0 0 2px rgba(255, 255, 255, 0.9);

    /* UX-3A, daylight. Its own picture rather than the dark one lightened: the
       approved light composition is a separate frame, and the mirror image of
       the dark one - the Beast and the city sit to the trailing side and the
       pale sky to the leading side. That is invisible to this layout precisely
       because the words sit at the foot of the frame, so the same veil shape
       serves both files.

       The veil rises further here than in the dark. Dark type on a pale ground
       is unforgiving of a mid-tone, and the bottom of this frame is where the
       rock and the seated figure are - the darkest part of the picture is
       exactly where the sentence goes, so the floor has to be nearly opaque by
       the last fifth. Above two thirds it is untouched, which is the whole
       reason the artwork still reads as artwork. */
    /* Daylight is where the signature green stops being enough on its own. The
       ordinary accent is #0d8f42, which measures 3.87:1 against this paper -
       fine for a filled button that carries the colour behind white type, short
       of AA for a link that *is* the colour. The darker accent this palette
       already declares measures 5.68:1, so the fix is a value this brand had
       rather than a colour invented for one page.

       Only the auth token moves. The site-wide link colour is untouched, and so
       is every surface UX-2 signed off on. */
    --auth-link: var(--accent-strong);

    --auth-art: url("/static/brands/beastping/art/ux3/auth/auth-visual-light.a513a1ac8be7.webp");
    --auth-art-position: 50% 26%;
    --auth-art-ground: #ffffff;
    --auth-art-veil:
      linear-gradient(180deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.16) 42%,
        rgba(252, 253, 253, 0.74) 66%,
        rgba(250, 252, 251, 0.94) 82%,
        rgba(248, 251, 249, 0.98) 100%);

    --surface-glass: rgba(255, 255, 255, 0.76);
    --glass-blur: blur(16px) saturate(1.05);

    /* The same floor with the lights on. The characters are dark cut-outs, so
       on a pale tile they read as silhouettes rather than as glow. */
    --tile-ground:
      radial-gradient(120% 72% at 50% 108%, rgba(13, 143, 66, 0.18), transparent 68%),
      linear-gradient(180deg, #ffffff 0%, rgba(236, 242, 238, 0.96) 100%);
    --tile-veil: linear-gradient(180deg, transparent 46%, rgba(244, 247, 245, 0.92) 88%);


    /* UX-4, with the lights on. The daylight hero is a bright sky, so the wash
       that carries the copy is white rather than black and has to be heavier: a
       pale surface behind dark text needs more coverage than a dark one behind
       light text before it clears AA. Same physical direction, same reason. */
    --dashboard-hero-art: url("/static/brands/beastping/dashboard/dashboard-hero-light.f7fa38192c1b.webp");
    --dashboard-hero-art-mobile: url("/static/brands/beastping/dashboard/dashboard-hero-light-mobile.a0af660b4b84.webp");
    --dashboard-hero-position: 50% 46%;
    --dashboard-hero-ground: #f4f7f5;
    --dashboard-hero-veil:
      linear-gradient(270deg,
        rgba(248, 251, 249, 0.97) 0%,
        rgba(248, 251, 249, 0.94) 24%,
        rgba(248, 251, 249, 0.74) 44%,
        rgba(248, 251, 249, 0.3) 64%,
        rgba(248, 251, 249, 0.05) 100%),
      linear-gradient(180deg,
        rgba(255, 255, 255, 0.2) 0%,
        rgba(255, 255, 255, 0) 36%,
        rgba(244, 247, 245, 0.28) 84%,
        rgba(244, 247, 245, 0.66) 100%);
    --dashboard-hero-veil-mobile:
      linear-gradient(180deg,
        rgba(248, 251, 249, 0.1) 0%,
        rgba(248, 251, 249, 0.06) 20%,
        rgba(248, 251, 249, 0.72) 34%,
        rgba(248, 251, 249, 0.96) 44%,
        rgba(250, 252, 251, 1) 100%);
    --dashboard-hero-edge: rgba(13, 143, 66, 0.24);

    /* UX-7A, with the lights on, on a phone. The dashboard's wash ends in solid
       white, which on the wallet's taller band left the lower half a blank slab.
       The wallet's own wash is measured up from the bottom edge - where its copy
       is anchored - so it closes just above the first line at every width and in
       both languages (the tallest case, a three-line Persian lede at 320px,
       starts about 12rem up), and it stops at 92% so the picture still reads
       through under the text. Dark is unchanged: a black wash over a night sky
       does not read as fog. */
    --wallet-hero-veil-mobile:
      linear-gradient(0deg,
        rgba(250, 252, 251, 0.92) 0%,
        rgba(248, 251, 249, 0.92) 11rem,
        rgba(248, 251, 249, 0.9) 12.5rem,
        rgba(248, 251, 249, 0.42) 14.75rem,
        rgba(248, 251, 249, 0.1) 16.75rem,
        rgba(248, 251, 249, 0) 19rem);

    /* UX7A-A11Y-01, with the lights on: the same centred ellipse as the dark
       block, in daylight white and a little heavier, because a pale wash
       behind dark text needs more coverage than a dark one behind light text. */
    --wallet-hero-veil:
      radial-gradient(ellipse 32rem 11.5rem at 50% 52%,
        rgba(248, 251, 249, 0.93) 0%,
        rgba(248, 251, 249, 0.9) 58%,
        rgba(248, 251, 249, 0.55) 82%,
        rgba(248, 251, 249, 0) 100%),
      linear-gradient(180deg,
        rgba(255, 255, 255, 0.14) 0%,
        rgba(244, 247, 245, 0) 40%,
        rgba(244, 247, 245, 0.3) 100%);

    --dashboard-support-art: url("/static/brands/beastping/dashboard/dashboard-support-light.5d3a9a250b97.webp");
    --dashboard-support-art-mobile: url("/static/brands/beastping/dashboard/dashboard-support-light-mobile.4e639a2aea33.webp");
    --dashboard-support-veil:
      linear-gradient(200deg,
        rgba(255, 255, 255, 0.82) 0%,
        rgba(253, 254, 253, 0.93) 46%,
        rgba(252, 254, 253, 0.97) 100%);

    --dashboard-controller-art: url("/static/brands/beastping/dashboard/dashboard-controller-light.69ce4de4a40f.webp");
    --dashboard-controller-art-small: url("/static/brands/beastping/dashboard/dashboard-controller-light-small.255a1b8467a1.webp");

    /* A tenth of the strength, like every other glow in daylight: on white a
       neon bloom reads as a rendering fault rather than as a style. */
    --dashboard-card-glow:
      radial-gradient(120% 140% at 100% 0%, rgba(13, 143, 66, 0.05), transparent 62%);
    --dashboard-icon-ring: rgba(13, 143, 66, 0.07);
    /* Measured, not assumed: the neon green reads 3.87:1 as 13px text on the
       daylight panel, and the darker green clears AA. Only this token moves -
       the buttons, the rules and the glow keep the accent they were signed off
       with. */
    --dashboard-accent-text: var(--accent-strong);

    /* -- UX-5 commerce ----------------------------------------------------
     *
     * The daylight half. Same tokens, the light artwork, and veils that lift the
     * picture away from the text rather than darkening it - on a pale panel a
     * dark scrim reads as a rendering fault. */
    --commerce-hero-art: url("/static/brands/beastping/commerce/catalog-hero-light.6f03e24a83f5.webp");
    --commerce-hero-position: 50% 42%;
    --commerce-hero-ground: #f2f6f4;
    --commerce-hero-veil:
      linear-gradient(180deg,
        rgba(247, 250, 248, 0.46) 0%,
        rgba(247, 250, 248, 0.72) 55%,
        rgba(247, 250, 248, 0.94) 100%);
    --commerce-hero-edge: rgba(13, 143, 66, 0.24);

    --commerce-tiers-art: url("/static/brands/beastping/commerce/service-tiers-light.a2f141c137c9.webp");
    --commerce-tiers-veil:
      linear-gradient(180deg, rgba(252, 254, 253, 0.72), rgba(252, 254, 253, 0.96));

    --commerce-secure-art: url("/static/brands/beastping/commerce/checkout-security-light.e19ab8941622.webp");
    --commerce-secure-veil:
      linear-gradient(180deg, rgba(252, 254, 253, 0.76), rgba(252, 254, 253, 0.96));

    --commerce-success-art: url("/static/brands/beastping/commerce/payment-success-light.c566eea21e35.webp");
    --commerce-success-veil:
      linear-gradient(180deg, rgba(252, 254, 253, 0.72), rgba(252, 254, 253, 0.95));

    --commerce-card-glow:
      radial-gradient(120% 140% at 100% 0%, rgba(13, 143, 66, 0.05), transparent 62%);
    /* The same measured substitution the dashboard makes: the neon green does not
       clear AA as small text on the daylight panel, and the darker green does. */
    --commerce-accent-text: var(--accent-strong);

    /* -- UX-6 active services ---------------------------------------------
     *
     * The daylight half. Same tokens, the light artwork, and veils that lift the
     * picture away from the text rather than darkening it - on a pale panel a
     * dark scrim reads as a rendering fault. */
    --services-hero-art: url("/static/brands/beastping/services/ux6-hero-light.ba8368f0da0c.webp");
    --services-hero-art-mobile: url("/static/brands/beastping/services/ux6-hero-mobile-light.e58fb37eb881.webp");
    --services-hero-position: 50% 38%;
    --services-hero-position-mobile: 50% 10%;
    --services-hero-ground: #f2f6f4;
    --services-hero-veil:
      linear-gradient(180deg,
        rgba(247, 250, 248, 0.48) 0%,
        rgba(247, 250, 248, 0.74) 55%,
        rgba(247, 250, 248, 0.95) 100%);
    --services-hero-veil-mobile:
      linear-gradient(180deg,
        rgba(247, 250, 248, 0.3) 0%,
        rgba(247, 250, 248, 0.6) 46%,
        rgba(247, 250, 248, 0.96) 100%);
    --services-hero-edge: rgba(13, 143, 66, 0.24);

    --services-scene-art: url("/static/brands/beastping/services/ux6-overview-scene-light.6aa936fa4671.webp");
    --services-scene-art-mobile: url("/static/brands/beastping/services/ux6-overview-scene-mobile-light.67b323a45838.webp");
    --services-scene-veil:
      linear-gradient(180deg, rgba(252, 254, 253, 0.74), rgba(252, 254, 253, 0.96));

    --services-frame-art: url("/static/brands/beastping/services/ux6-detail-frame-light.6f3fffd9f8c2.webp");
    --services-frame-art-mobile: url("/static/brands/beastping/services/ux6-detail-frame-mobile-light.46e517d7a44e.webp");
    --services-beast-art: url("/static/brands/beastping/art/ux3/auth/auth-visual-light.a513a1ac8be7.webp");
    --services-beast-position: 50% 6%;
    --services-frame-veil:
      linear-gradient(180deg, rgba(252, 254, 253, 0.76), rgba(252, 254, 253, 0.96));

    --services-card-glow:
      radial-gradient(120% 140% at 100% 0%, rgba(13, 143, 66, 0.05), transparent 62%);
    --services-accent-text: var(--accent-strong);
    /* PO-SVC-REFRESH-ORANGE, light: neon orange on a light ground is about 2.4:1 - too faint for
     * text. The label keeps the readable ink; the orange stays on the hairline, the icon (a
     * deeper orange, about 3:1 as a graphic) and the glow. */
    --service-refresh-text: var(--ink);
    --service-refresh-text-hover: var(--ink);
    --service-refresh-accent: #e07800;
    --service-refresh-accent-hover: #c96a00;
    --service-refresh-edge: #ff8a00;
    --service-refresh-edge-hover: #e07800;
    --service-refresh-tint: rgba(255, 138, 0, 0.06);
    --service-refresh-tint-hover: rgba(255, 138, 0, 0.12);
    /* EMAIL-VERIFY-COOLDOWN-01, light: neon orange is too faint for text here, so the helper
     * lines take a deep strong orange - about 5:1 on white, 4.7:1 on the light surface. */
    --verification-hint-text: #b45309;
    --service-refresh-glow: 0 0 8px rgba(255, 138, 0, 0.28);
    --service-refresh-glow-hover: 0 0 14px rgba(255, 138, 0, 0.35);

    --grid-line: rgba(13, 143, 66, 0.05);
    --hairline: linear-gradient(90deg, transparent 5%, rgba(13, 143, 66, 0.55) 30%, rgba(109, 63, 212, 0.45) 70%, transparent 95%);
    --hairline-soft: linear-gradient(90deg, transparent, rgba(13, 143, 66, 0.16), rgba(109, 63, 212, 0.14), transparent);
    --edge: linear-gradient(90deg, transparent, rgba(13, 143, 66, 0.45), rgba(109, 63, 212, 0.32), transparent);
  }
}

/* The viewer chose light. Same values as the media block above; this is the one
   block that has to be repeated, because it must also win when the operating
   system is asking for dark. */
:root[data-theme="light"] {
  color-scheme: light;
  --display-light-theme: inline-block;
  --display-dark-theme: none;

  --paper: #f4f7f5;
  --chrome: #ffffff;
  --surface: #ffffff;
  --surface-raised: #ffffff;
  --surface-sunken: #eef2ef;
  --band: #eaefec;

  --ink: #0d1512;
  --ink-soft: #48584f;
  --ink-faint: #6b7a71;

  --line: #dde5e0;
  --line-strong: #c2cec7;

  --accent: #0d8f42;
  --accent-strong: #0a7135;
  --accent-soft: #e2f6ea;
  --accent-contrast: #ffffff;
  --accent-edge: rgba(13, 143, 66, 0.24);

  --accent-2: #6d3fd4;
  --accent-2-soft: #efe9fd;
  --accent-2-contrast: #ffffff;

  --accent-fill: linear-gradient(135deg, #12a44d 0%, #0b7a39 100%);
  --accent-2-fill: linear-gradient(135deg, #7d51e0 0%, #6134c4 100%);

  --ok: #1f6b45;
  --ok-tint: #e4f3ea;
  --warn: #8a5a06;
  --warn-tint: #fbf0dc;
  --danger: #9a2c2c;
  --danger-tint: #fbe9e9;
  --info: #285a86;
  --info-tint: #e6f1f8;

  --shadow: 0 1px 2px rgba(13, 21, 18, 0.06), 0 4px 16px rgba(13, 21, 18, 0.05);
  --shadow-lg: 0 2px 6px rgba(13, 21, 18, 0.08), 0 18px 48px rgba(13, 21, 18, 0.09);
  --glow: 0 1px 2px rgba(13, 21, 18, 0.08), 0 6px 18px rgba(13, 143, 66, 0.16);
  --glow-strong: 0 2px 4px rgba(13, 21, 18, 0.1), 0 10px 26px rgba(13, 143, 66, 0.22);
  --glow-soft: none;
  --glow-2: 0 1px 2px rgba(13, 21, 18, 0.08), 0 6px 18px rgba(109, 63, 212, 0.18);
  --ring: #0d8f42;

  --page-glow:
    radial-gradient(56% 42% at 8% -6%, rgba(13, 143, 66, 0.09), transparent 70%),
    radial-gradient(50% 38% at 94% -2%, rgba(109, 63, 212, 0.09), transparent 68%);
  --hero-key: radial-gradient(38% 46% at 72% 42%, rgba(13, 143, 66, 0.1), transparent 72%);
  --hero-wash: linear-gradient(180deg, #ffffff 0%, rgba(244, 247, 245, 0) 100%);

  --divider-art: url("/static/brands/beastping/art/ux2/a3/accents/divider-wave-light.e76b0f6e851f.svg");

  /* UX10-A correction 02. The Product Owner's light section pack: the same art
     direction as dark - a world of routes, a stage under a globe, and the
     Beast's eyes at the end - lit for a bright page instead of re-lighting the
     dark files. The pack's panel pictures stay in the repository; the section
     that showed them was removed in UX10-A 07. */
  --network-art: url("/static/brands/beastping/art/ux10/sections/landing-section-light-routes-map-desktop.491a1ad67557.webp");
  --network-art-narrow: url("/static/brands/beastping/art/ux10/sections/landing-section-light-routes-map-mobile.1f67a7250339.webp");
  --network-veil:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.64) 0%,
      rgba(252, 253, 253, 0.54) 40%,
      rgba(248, 251, 249, 0.86) 100%);
  --featured-art: url("/static/brands/beastping/art/ux10/sections/landing-section-light-featured-globe-desktop.97b19764ff77.webp");
  --featured-art-narrow: url("/static/brands/beastping/art/ux10/sections/landing-section-light-featured-globe-mobile.64ab3e451fda.webp");
  --featured-veil:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.7) 0%,
      rgba(252, 253, 253, 0.5) 45%,
      rgba(248, 251, 249, 0.88) 100%);
  --closing-art: url("/static/brands/beastping/art/ux10/sections/landing-section-light-cta-eyes-desktop.7f49e09e9ff2.webp");
  --closing-art-narrow: url("/static/brands/beastping/art/ux10/sections/landing-section-light-cta-eyes-mobile.77f1048e3973.webp");
  --closing-veil:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.4) 0%,
      rgba(252, 253, 253, 0.7) 44%,
      rgba(248, 251, 249, 0.86) 100%);
  --section-watermark: url("/static/brands/beastping/art/ux2/a3/accents/section-watermark-light.932c57ac3e13.svg");

  --hero-art: url("/static/brands/beastping/art/ux2/hero-light-wide.75d77a493c34.webp");
  --hero-art-sm: url("/static/brands/beastping/art/ux2/hero-light-wide-sm.a313a3e3c20d.webp");
  --hero-art-narrow: url("/static/brands/beastping/art/ux10/hero-light-mobile.e578b5f25ed1.webp");

  /* The same panel the block above declares, and it has to be repeated here for
     the same reason every other light value is: this block exists to win when a
     viewer chose light on a dark operating system, so anything it leaves out
     falls back to the *core* default - which for this token is the wide veil,
     and the wide veil on a phone is the broad white fog this scrim replaced.
     Missing it did not break light mode; it broke light mode only for the people
     who asked for it. */
  --hero-veil-narrow:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, 0.04) 24%,
      rgba(250, 252, 253, 0.5) 33%,
      rgba(250, 252, 253, 0.74) 45%,
      rgba(250, 252, 253, 0.72) 60%,
      rgba(250, 252, 253, 0.46) 70%,
      rgba(250, 252, 253, 0.16) 76%,
      rgba(250, 252, 253, 0.06) 88%,
      rgba(244, 247, 245, 0.2) 100%);

  --hero-art-focus: 50% 44%;
  --hero-art-focus-narrow: 50% 38%;
  --hero-art-ground: #ffffff;

  --hero-veil:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.03) 0%,
      rgba(255, 255, 255, 0.28) 34%,
      rgba(253, 254, 253, 0.72) 56%,
      rgba(250, 252, 251, 0.93) 74%,
      rgba(244, 247, 245, 1) 100%);
  --hero-ink-shadow: 0 0 12px rgba(255, 255, 255, 0.92), 0 0 2px rgba(255, 255, 255, 0.9);

  /* UX-3A, daylight - the same declarations the system-light block above makes.
     Both blocks carry the whole set on purpose: a token declared in only one of
     them is a theme that looks different depending on how the reader reached it,
     which is a defect the last slice already had to repair once. */
  /* The same darker accent the system-light block takes, for the same measured
     reason. Declared here too because a token in one light block and not the
     other is a theme that changes with how the reader arrived at it. */
  --auth-link: var(--accent-strong);

  --auth-art: url("/static/brands/beastping/art/ux3/auth/auth-visual-light.a513a1ac8be7.webp");
  --auth-art-position: 50% 26%;
  --auth-art-ground: #ffffff;
  --auth-art-veil:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, 0.16) 42%,
      rgba(252, 253, 253, 0.74) 66%,
      rgba(250, 252, 251, 0.94) 82%,
      rgba(248, 251, 249, 0.98) 100%);

  --surface-glass: rgba(255, 255, 255, 0.76);
  --glass-blur: blur(16px) saturate(1.05);

  --tile-ground:
    radial-gradient(120% 72% at 50% 108%, rgba(13, 143, 66, 0.18), transparent 68%),
    linear-gradient(180deg, #ffffff 0%, rgba(236, 242, 238, 0.96) 100%);
  --tile-veil: linear-gradient(180deg, transparent 46%, rgba(244, 247, 245, 0.92) 88%);


  /* UX-4, with the lights on. The daylight hero is a bright sky, so the wash
     that carries the copy is white rather than black and has to be heavier: a
     pale surface behind dark text needs more coverage than a dark one behind
     light text before it clears AA. Same physical direction, same reason. */
  --dashboard-hero-art: url("/static/brands/beastping/dashboard/dashboard-hero-light.f7fa38192c1b.webp");
  --dashboard-hero-art-mobile: url("/static/brands/beastping/dashboard/dashboard-hero-light-mobile.a0af660b4b84.webp");
  --dashboard-hero-position: 50% 46%;
  --dashboard-hero-ground: #f4f7f5;
  --dashboard-hero-veil:
    linear-gradient(270deg,
      rgba(248, 251, 249, 0.97) 0%,
      rgba(248, 251, 249, 0.94) 24%,
      rgba(248, 251, 249, 0.74) 44%,
      rgba(248, 251, 249, 0.3) 64%,
      rgba(248, 251, 249, 0.05) 100%),
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.2) 0%,
      rgba(255, 255, 255, 0) 36%,
      rgba(244, 247, 245, 0.28) 84%,
      rgba(244, 247, 245, 0.66) 100%);
  --dashboard-hero-veil-mobile:
    linear-gradient(180deg,
      rgba(248, 251, 249, 0.1) 0%,
      rgba(248, 251, 249, 0.06) 20%,
      rgba(248, 251, 249, 0.72) 34%,
      rgba(248, 251, 249, 0.96) 44%,
      rgba(250, 252, 251, 1) 100%);
  --dashboard-hero-edge: rgba(13, 143, 66, 0.24);

  /* UX7A-A11Y-01, with the lights on - the same centred daylight ellipse as
     the system-light block above, for a visitor who chose light explicitly. */
  --wallet-hero-veil:
    radial-gradient(ellipse 32rem 11.5rem at 50% 52%,
      rgba(248, 251, 249, 0.93) 0%,
      rgba(248, 251, 249, 0.9) 58%,
      rgba(248, 251, 249, 0.55) 82%,
      rgba(248, 251, 249, 0) 100%),
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.14) 0%,
      rgba(244, 247, 245, 0) 40%,
      rgba(244, 247, 245, 0.3) 100%);

  /* UX-7A, with the lights on, on a phone - the same wallet ramp as the
     system-light block above, for a visitor who chose light explicitly. */
  --wallet-hero-veil-mobile:
    linear-gradient(0deg,
      rgba(250, 252, 251, 0.92) 0%,
      rgba(248, 251, 249, 0.92) 11rem,
      rgba(248, 251, 249, 0.9) 12.5rem,
      rgba(248, 251, 249, 0.42) 14.75rem,
      rgba(248, 251, 249, 0.1) 16.75rem,
      rgba(248, 251, 249, 0) 19rem);

  --dashboard-support-art: url("/static/brands/beastping/dashboard/dashboard-support-light.5d3a9a250b97.webp");
  --dashboard-support-art-mobile: url("/static/brands/beastping/dashboard/dashboard-support-light-mobile.4e639a2aea33.webp");
  --dashboard-support-veil:
    linear-gradient(200deg,
      rgba(255, 255, 255, 0.82) 0%,
      rgba(253, 254, 253, 0.93) 46%,
      rgba(252, 254, 253, 0.97) 100%);

  --dashboard-controller-art: url("/static/brands/beastping/dashboard/dashboard-controller-light.69ce4de4a40f.webp");
  --dashboard-controller-art-small: url("/static/brands/beastping/dashboard/dashboard-controller-light-small.255a1b8467a1.webp");

  /* A tenth of the strength, like every other glow in daylight: on white a
     neon bloom reads as a rendering fault rather than as a style. */
  --dashboard-card-glow:
    radial-gradient(120% 140% at 100% 0%, rgba(13, 143, 66, 0.05), transparent 62%);
  --dashboard-icon-ring: rgba(13, 143, 66, 0.07);
  /* Measured, not assumed: the neon green reads 3.87:1 as 13px text on the
     daylight panel, and the darker green clears AA. Only this token moves -
     the buttons, the rules and the glow keep the accent they were signed off
     with. */
  --dashboard-accent-text: var(--accent-strong);

  /* -- UX-5 commerce ----------------------------------------------------
   *
   * The daylight half. Same tokens, the light artwork, and veils that lift the
   * picture away from the text rather than darkening it - on a pale panel a
   * dark scrim reads as a rendering fault. */
  --commerce-hero-art: url("/static/brands/beastping/commerce/catalog-hero-light.6f03e24a83f5.webp");
  --commerce-hero-position: 50% 42%;
  --commerce-hero-ground: #f2f6f4;
  --commerce-hero-veil:
    linear-gradient(180deg,
      rgba(247, 250, 248, 0.46) 0%,
      rgba(247, 250, 248, 0.72) 55%,
      rgba(247, 250, 248, 0.94) 100%);
  --commerce-hero-edge: rgba(13, 143, 66, 0.24);

  --commerce-tiers-art: url("/static/brands/beastping/commerce/service-tiers-light.a2f141c137c9.webp");
  --commerce-tiers-veil:
    linear-gradient(180deg, rgba(252, 254, 253, 0.72), rgba(252, 254, 253, 0.96));

  --commerce-secure-art: url("/static/brands/beastping/commerce/checkout-security-light.e19ab8941622.webp");
  --commerce-secure-veil:
    linear-gradient(180deg, rgba(252, 254, 253, 0.76), rgba(252, 254, 253, 0.96));

  --commerce-success-art: url("/static/brands/beastping/commerce/payment-success-light.c566eea21e35.webp");
  --commerce-success-veil:
    linear-gradient(180deg, rgba(252, 254, 253, 0.72), rgba(252, 254, 253, 0.95));

  --commerce-card-glow:
    radial-gradient(120% 140% at 100% 0%, rgba(13, 143, 66, 0.05), transparent 62%);
  /* The same measured substitution the dashboard makes: the neon green does not
     clear AA as small text on the daylight panel, and the darker green does. */
  --commerce-accent-text: var(--accent-strong);

  /* -- UX-6 active services ---------------------------------------------
   *
   * The daylight half. Same tokens, the light artwork, and veils that lift the
   * picture away from the text rather than darkening it - on a pale panel a
   * dark scrim reads as a rendering fault. */
  --services-hero-art: url("/static/brands/beastping/services/ux6-hero-light.ba8368f0da0c.webp");
  --services-hero-art-mobile: url("/static/brands/beastping/services/ux6-hero-mobile-light.e58fb37eb881.webp");
  --services-hero-position: 50% 38%;
  --services-hero-position-mobile: 50% 10%;
  --services-hero-ground: #f2f6f4;
  --services-hero-veil:
    linear-gradient(180deg,
      rgba(247, 250, 248, 0.48) 0%,
      rgba(247, 250, 248, 0.74) 55%,
      rgba(247, 250, 248, 0.95) 100%);
  --services-hero-veil-mobile:
    linear-gradient(180deg,
      rgba(247, 250, 248, 0.3) 0%,
      rgba(247, 250, 248, 0.6) 46%,
      rgba(247, 250, 248, 0.96) 100%);
  --services-hero-edge: rgba(13, 143, 66, 0.24);

  --services-scene-art: url("/static/brands/beastping/services/ux6-overview-scene-light.6aa936fa4671.webp");
  --services-scene-art-mobile: url("/static/brands/beastping/services/ux6-overview-scene-mobile-light.67b323a45838.webp");
  --services-scene-veil:
    linear-gradient(180deg, rgba(252, 254, 253, 0.74), rgba(252, 254, 253, 0.96));

  --services-frame-art: url("/static/brands/beastping/services/ux6-detail-frame-light.6f3fffd9f8c2.webp");
  --services-frame-art-mobile: url("/static/brands/beastping/services/ux6-detail-frame-mobile-light.46e517d7a44e.webp");
  --services-beast-art: url("/static/brands/beastping/art/ux3/auth/auth-visual-light.a513a1ac8be7.webp");
  --services-beast-position: 50% 6%;
  --services-frame-veil:
    linear-gradient(180deg, rgba(252, 254, 253, 0.76), rgba(252, 254, 253, 0.96));

  --services-card-glow:
    radial-gradient(120% 140% at 100% 0%, rgba(13, 143, 66, 0.05), transparent 62%);
  --services-accent-text: var(--accent-strong);
  /* PO-SVC-REFRESH-ORANGE, light: neon orange on a light ground is about 2.4:1 - too faint for
   * text. The label keeps the readable ink; the orange stays on the hairline, the icon (a
   * deeper orange, about 3:1 as a graphic) and the glow. */
  --service-refresh-text: var(--ink);
  --service-refresh-text-hover: var(--ink);
  --service-refresh-accent: #e07800;
  --service-refresh-accent-hover: #c96a00;
  --service-refresh-edge: #ff8a00;
  --service-refresh-edge-hover: #e07800;
  --service-refresh-tint: rgba(255, 138, 0, 0.06);
  --service-refresh-tint-hover: rgba(255, 138, 0, 0.12);
  /* EMAIL-VERIFY-COOLDOWN-01, light: neon orange is too faint for text here, so the helper
   * lines take a deep strong orange - about 5:1 on white, 4.7:1 on the light surface. */
  --verification-hint-text: #b45309;
  --service-refresh-glow: 0 0 8px rgba(255, 138, 0, 0.28);
  --service-refresh-glow-hover: 0 0 14px rgba(255, 138, 0, 0.35);

  --grid-line: rgba(13, 143, 66, 0.05);
  --hairline: linear-gradient(90deg, transparent 5%, rgba(13, 143, 66, 0.55) 30%, rgba(109, 63, 212, 0.45) 70%, transparent 95%);
  --hairline-soft: linear-gradient(90deg, transparent, rgba(13, 143, 66, 0.16), rgba(109, 63, 212, 0.14), transparent);
  --edge: linear-gradient(90deg, transparent, rgba(13, 143, 66, 0.45), rgba(109, 63, 212, 0.32), transparent);
}

}
