/* ===========================================================================
   professions-skins.css — one SIGNATURE SKIN per profession.

   Loaded after skins.css. Same shape as every block in that file and nothing
   else: a copy of the :root token set, answering to two selectors —

     html[data-skin="x"]                 the viewer's own page
     .brand-card[data-skin-card="x"]     one card wearing somebody else's skin

   so a post arrives in its author's colours and cannot reach the reader's page.
   The boundary from skins.css holds: chrome tokens only. No .c-*, no .la-*,
   no .lr-*. A Botanicals chip is the same green inside a Quenchfire card as it
   is on your own page.

   THREE PROFESSIONS NEED NOTHING HERE — they claim a skin that already exists,
   which is the Professions v3 rule (claim a good fit before authoring one):
     Herbalist    -> wildwood   (already shipped)
     Bone-hunter  -> boneink    (warm paper on near-black; it IS bone and ink)
     Mycologist   -> foxfire    (darkest ground, most chromatic; emitted light)

   The twelve below are the ones with no fit. Each is distinct on an AXIS, not
   on a hue — temperature, contrast, chroma, or ground lightness — because two
   skins that differ only in hue read as one skin with a tint, and the second
   then feels like nothing was earned. The axis is named in each comment.
   =========================================================================== */

/* Lanternstone — Prospector. ONE POOL OF LIGHT. Distinct from Emberlight by
   ground: the shadows here are cold blue-grey stone, not warm leather, so the
   amber reads as a single lamp in a tunnel rather than a lit room. The lowest
   chroma surfaces of any warm skin. */
html[data-skin="lanternstone"],
.brand-card[data-skin-card="lanternstone"] {
  --surface-0: #0d0e11;
  --surface-1: #14151a;
  --surface-2: #1d1c1f;
  --surface-3: #2b2621;
  --border: rgba(232,206,160,0.10);
  --border-strong: rgba(232,206,160,0.22);
  --border-accent: #e8a13c;
  --text-primary: #ece4d6;
  --text-secondary: #a89e8e;
  --text-muted: #79736a;
  --text-accent: #f0b45c;
  --text-success: #a8c98a;
  --bg-success: rgba(168,201,138,0.12);
  --accent-fg: #14100a;
  --accent-hover: #f2bd6e;
  --danger: #ef938c;
  --xp: #f0b45c;
  --coin: #ffd27a;
  --warn-text: #edce90;
  --warn-bg: rgba(255,210,122,0.10);
  --warn-border: rgba(255,210,122,0.34);
  --chrome-bg: rgba(20,21,26,0.93);
  --glow: 0 0 0 1px rgba(232,161,60,0.40), 0 0 18px rgba(232,161,60,0.20);

  --fx-1: rgba(232,161,60,0.085);
  --fx-2: rgba(170,190,220,0.045);
  --fx-3: rgba(255,210,122,0.05);
}

/* Heartwood — Woodwright. GROUND LIGHTNESS. The lightest dark skin in the app
   by some way: the surfaces themselves carry the chroma (bark, not void), where
   Emberlight keeps dark surfaces and puts its warmth in the accent. Reads as
   timber in daylight. */
html[data-skin="heartwood"],
.brand-card[data-skin-card="heartwood"] {
  --surface-0: #171310;
  --surface-1: #221b16;
  --surface-2: #2d241d;
  --surface-3: #3b2f25;
  --border: rgba(236,214,180,0.12);
  --border-strong: rgba(236,214,180,0.24);
  --border-accent: #c98a45;
  --text-primary: #f0e3d2;
  --text-secondary: #bda88c;
  --text-muted: #8c7a64;
  --text-accent: #dda869;
  --text-success: #a9c383;
  --bg-success: rgba(169,195,131,0.13);
  --accent-fg: #1b1209;
  --accent-hover: #d99b5c;
  --danger: #ea9086;
  --xp: #dda869;
  --coin: #e8c47c;
  --warn-text: #dac08e;
  --warn-bg: rgba(232,196,124,0.10);
  --warn-border: rgba(232,196,124,0.34);
  --chrome-bg: rgba(34,27,22,0.93);
  --glow: 0 0 0 1px rgba(201,138,69,0.40), 0 0 16px rgba(201,138,69,0.20);

  --fx-1: rgba(201,138,69,0.075);
  --fx-2: rgba(236,214,180,0.04);
  --fx-3: rgba(140,120,80,0.055);
}

/* Saltglass — Tidecaller. COLD AND LIT. Distinct from Arcane by hue family and
   from Verdigris by being lit rather than weathered: high-chroma accent, and a
   ground that is genuinely blue rather than neutral-with-a-tint. */
html[data-skin="saltglass"],
.brand-card[data-skin-card="saltglass"] {
  --surface-0: #070f18;
  --surface-1: #0d1b28;
  --surface-2: #142637;
  --surface-3: #1d3448;
  --border: rgba(200,232,244,0.12);
  --border-strong: rgba(200,232,244,0.25);
  --border-accent: #3fa9d8;
  --text-primary: #dcedf6;
  --text-secondary: #95b8ca;
  --text-muted: #64879b;
  --text-accent: #6fd6e4;
  --text-success: #7fe0bd;
  --bg-success: rgba(127,224,189,0.13);
  --accent-fg: #05121c;
  --accent-hover: #59bce6;
  --danger: #ff9b9b;
  --xp: #6fd6e4;
  --coin: #e6cf8a;
  --warn-text: #dbca9a;
  --warn-bg: rgba(230,207,138,0.10);
  --warn-border: rgba(230,207,138,0.34);
  --chrome-bg: rgba(13,27,40,0.93);
  --glow: 0 0 0 1px rgba(63,169,216,0.44), 0 0 20px rgba(63,169,216,0.22);

  --fx-1: rgba(63,169,216,0.09);
  --fx-2: rgba(127,227,224,0.06);
  --fx-3: rgba(210,240,250,0.035);
}

/* Feralnight — Beastmaster. SPLIT TEMPERATURE, which is the axis no other skin
   uses: a cold violet ground with a HOT accent. Arcane is violet with cool
   light; this one has the fire inside it. */
html[data-skin="feralnight"],
.brand-card[data-skin-card="feralnight"] {
  --surface-0: #0a0710;
  --surface-1: #150e1e;
  --surface-2: #1f152b;
  --surface-3: #2c1e3b;
  --border: rgba(226,208,240,0.12);
  --border-strong: rgba(226,208,240,0.24);
  --border-accent: #b07af0;
  --text-primary: #ebdff4;
  --text-secondary: #ab98c2;
  --text-muted: #7b6a92;
  --text-accent: #ffa464;
  --text-success: #8fdba0;
  --bg-success: rgba(143,219,160,0.12);
  --accent-fg: #120a1c;
  --accent-hover: #c294f5;
  --danger: #ff8f8a;
  --xp: #ffa464;
  --coin: #ffc978;
  --warn-text: #ecc68e;
  --warn-bg: rgba(255,201,120,0.10);
  --warn-border: rgba(255,201,120,0.34);
  --chrome-bg: rgba(21,14,30,0.93);
  --glow: 0 0 0 1px rgba(176,122,240,0.42), 0 0 18px rgba(255,164,100,0.20);

  --fx-1: rgba(176,122,240,0.09);
  --fx-2: rgba(255,164,100,0.055);
  --fx-3: rgba(226,208,240,0.035);
}

/* Hearthfield — Homesteader. LOWEST CHROMA IN THE APP, deliberately. Matte,
   flat, unlit — the settled life rather than the lit one. Distinct from
   Verdigris (which is a metal) and Wildwood (which is alive). */
html[data-skin="hearthfield"],
.brand-card[data-skin-card="hearthfield"] {
  --surface-0: #0c1211;
  --surface-1: #141b19;
  --surface-2: #1c2422;
  --surface-3: #26302d;
  --border: rgba(214,228,222,0.10);
  --border-strong: rgba(214,228,222,0.21);
  --border-accent: #6aa79c;
  --text-primary: #e0e8e4;
  --text-secondary: #9cada7;
  --text-muted: #71807b;
  --text-accent: #86bfb2;
  --text-success: #93cfa4;
  --bg-success: rgba(147,207,164,0.12);
  --accent-fg: #08110f;
  --accent-hover: #7db8ac;
  --danger: #e0928d;
  --xp: #86bfb2;
  --coin: #d9bf85;
  --warn-text: #cebc93;
  --warn-bg: rgba(217,191,133,0.10);
  --warn-border: rgba(217,191,133,0.34);
  --chrome-bg: rgba(20,27,25,0.93);
  --glow: 0 0 0 1px rgba(106,167,156,0.34);

  --fx-1: rgba(106,167,156,0.06);
  --fx-2: rgba(217,191,133,0.04);
  --fx-3: rgba(214,228,222,0.03);
}

/* Honeyveil — Apiarist. GROUND WARMTH AT MID-TONE. The only skin whose
   surface-3 leans light, so the chrome reads as wax and comb rather than as
   void. Warm like Emberlight but a whole step brighter at every surface. */
html[data-skin="honeyveil"],
.brand-card[data-skin-card="honeyveil"] {
  --surface-0: #14100c;
  --surface-1: #1f1814;
  --surface-2: #2c221b;
  --surface-3: #40311f;
  --border: rgba(255,222,190,0.13);
  --border-strong: rgba(255,222,190,0.26);
  --border-accent: #f2a05e;
  --text-primary: #f7e6d8;
  --text-secondary: #c5a891;
  --text-muted: #8f7a68;
  --text-accent: #ffbe7c;
  --text-success: #b6cf8c;
  --bg-success: rgba(182,207,140,0.13);
  --accent-fg: #1c1108;
  --accent-hover: #f7b273;
  --danger: #f0948e;
  --xp: #ffbe7c;
  --coin: #ffd88a;
  --warn-text: #efd49e;
  --warn-bg: rgba(255,216,138,0.10);
  --warn-border: rgba(255,216,138,0.34);
  --chrome-bg: rgba(31,24,20,0.93);
  --glow: 0 0 0 1px rgba(242,160,94,0.42), 0 0 18px rgba(255,190,124,0.22);

  --fx-1: rgba(255,190,124,0.085);
  --fx-2: rgba(242,160,94,0.055);
  --fx-3: rgba(255,222,190,0.04);
}

/* Retort — Alchemist. HUE DISAGREEMENT, on purpose. The only skin whose accent
   and success colours come from different families and are meant to clash
   slightly — indigo chrome, glass-green light. Matter being changed into
   something it wasn't. */
html[data-skin="retort"],
.brand-card[data-skin-card="retort"] {
  --surface-0: #08090f;
  --surface-1: #0f111c;
  --surface-2: #161829;
  --surface-3: #20233a;
  --border: rgba(212,216,244,0.12);
  --border-strong: rgba(212,216,244,0.24);
  --border-accent: #7b8bf5;
  --text-primary: #e4e6f7;
  --text-secondary: #a1a6c8;
  --text-muted: #737898;
  --text-accent: #9fa9ff;
  --text-success: #67e0a8;
  --bg-success: rgba(103,224,168,0.14);
  --accent-fg: #0a0b14;
  --accent-hover: #93a1f8;
  --danger: #ff96a2;
  --xp: #9fa9ff;
  --coin: #e2c98a;
  --warn-text: #d7c599;
  --warn-bg: rgba(226,201,138,0.10);
  --warn-border: rgba(226,201,138,0.34);
  --chrome-bg: rgba(15,17,28,0.93);
  --glow: 0 0 0 1px rgba(123,139,245,0.42), 0 0 18px rgba(103,224,168,0.16);

  --fx-1: rgba(123,139,245,0.085);
  --fx-2: rgba(103,224,168,0.05);
  --fx-3: rgba(212,216,244,0.03);
}

/* Prismlight — Glassworker. ACCENT BRIGHTNESS. Its accent is nearly white at
   the core, so the light reads as light rather than as colour — the one skin
   where the chrome looks lit from behind. Ground is the coldest near-black. */
html[data-skin="prismlight"],
.brand-card[data-skin-card="prismlight"] {
  --surface-0: #050b0e;
  --surface-1: #0b1519;
  --surface-2: #112026;
  --surface-3: #1a2f38;
  --border: rgba(214,244,252,0.13);
  --border-strong: rgba(214,244,252,0.27);
  --border-accent: #63dced;
  --text-primary: #e6f7fb;
  --text-secondary: #9cc2cd;
  --text-muted: #6b8e9a;
  --text-accent: #a6f0fb;
  --text-success: #8ce8c8;
  --bg-success: rgba(140,232,200,0.13);
  --accent-fg: #040f13;
  --accent-hover: #86e8f5;
  --danger: #ff9d9d;
  --xp: #a6f0fb;
  --coin: #ecd691;
  --warn-text: #e1d1a1;
  --warn-bg: rgba(236,214,145,0.10);
  --warn-border: rgba(236,214,145,0.34);
  --chrome-bg: rgba(11,21,25,0.93);
  --glow: 0 0 0 1px rgba(99,220,237,0.48), 0 0 22px rgba(166,240,251,0.26);

  --fx-1: rgba(99,220,237,0.08);
  --fx-2: rgba(214,244,252,0.05);
  --fx-3: rgba(140,232,200,0.04);
}

/* Quenchfire — Forgewright. HIGHEST-CONTRAST WARM SKIN. Soot ground, near-white
   hot accent. Emberlight is the calmest warm skin by design; this is
   deliberately its opposite on the same hue axis. */
html[data-skin="quenchfire"],
.brand-card[data-skin-card="quenchfire"] {
  --surface-0: #0c0806;
  --surface-1: #16100c;
  --surface-2: #211711;
  --surface-3: #33231a;
  --border: rgba(255,224,196,0.12);
  --border-strong: rgba(255,224,196,0.26);
  --border-accent: #ff6a2b;
  --text-primary: #f7e6d8;
  --text-secondary: #c0a189;
  --text-muted: #8b7159;
  --text-accent: #ff9d55;
  --text-success: #b3cd83;
  --bg-success: rgba(179,205,131,0.12);
  --accent-fg: #150802;
  --accent-hover: #ff8548;
  --danger: #ff8d84;
  --xp: #ff9d55;
  --coin: #ffce7a;
  --warn-text: #edcb90;
  --warn-bg: rgba(255,206,122,0.10);
  --warn-border: rgba(255,206,122,0.34);
  --chrome-bg: rgba(22,16,12,0.94);
  --glow: 0 0 0 1px rgba(255,106,43,0.46), 0 0 22px rgba(255,157,85,0.24);

  --fx-1: rgba(255,106,43,0.09);
  --fx-2: rgba(255,214,150,0.055);
  --fx-3: rgba(90,50,30,0.07);
}

/* Loomlight — Weaver. SURFACE SPACING. Its four surfaces sit closer together in
   value than any other skin's, so the chrome reads as one cloth with a nap
   rather than as stacked panels. Magenta, but the spacing is the point. */
html[data-skin="loomlight"],
.brand-card[data-skin-card="loomlight"] {
  --surface-0: #100a10;
  --surface-1: #181018;
  --surface-2: #1f151f;
  --surface-3: #281c28;
  --border: rgba(244,214,238,0.12);
  --border-strong: rgba(244,214,238,0.25);
  --border-accent: #e263bd;
  --text-primary: #f4e2ef;
  --text-secondary: #bf9bb4;
  --text-muted: #8d7286;
  --text-accent: #f58fd4;
  --text-success: #93d9a8;
  --bg-success: rgba(147,217,168,0.12);
  --accent-fg: #150a13;
  --accent-hover: #ea7fca;
  --danger: #ff939b;
  --xp: #f58fd4;
  --coin: #e8c98a;
  --warn-text: #dbc69a;
  --warn-bg: rgba(232,201,138,0.10);
  --warn-border: rgba(232,201,138,0.34);
  --chrome-bg: rgba(24,16,24,0.93);
  --glow: 0 0 0 1px rgba(226,99,189,0.42), 0 0 18px rgba(226,99,189,0.20);

  --fx-1: rgba(226,99,189,0.085);
  --fx-2: rgba(244,214,238,0.045);
  --fx-3: rgba(147,217,168,0.035);
}

/* Greenhearth — Cook. TEXT BRIGHTNESS. The brightest body text of the dark
   skins, because a kitchen is a lit room — it is the readable one, where
   Boneink is the high-contrast one. Warm-green rather than Wildwood's forest. */
html[data-skin="greenhearth"],
.brand-card[data-skin-card="greenhearth"] {
  --surface-0: #0b0f08;
  --surface-1: #12180d;
  --surface-2: #1a2113;
  --surface-3: #262f1a;
  --border: rgba(232,244,206,0.12);
  --border-strong: rgba(232,244,206,0.25);
  --border-accent: #9ecf42;
  --text-primary: #f3f7e6;
  --text-secondary: #b6c496;
  --text-muted: #83906a;
  --text-accent: #c3e072;
  --text-success: #9ee08a;
  --bg-success: rgba(158,224,138,0.13);
  --accent-fg: #0d1305;
  --accent-hover: #b0dc5e;
  --danger: #f2958c;
  --xp: #c3e072;
  --coin: #f0d488;
  --warn-text: #e3cf9a;
  --warn-bg: rgba(240,212,136,0.10);
  --warn-border: rgba(240,212,136,0.34);
  --chrome-bg: rgba(18,24,13,0.93);
  --glow: 0 0 0 1px rgba(158,207,66,0.40), 0 0 16px rgba(195,224,114,0.20);

  --fx-1: rgba(158,207,66,0.075);
  --fx-2: rgba(240,212,136,0.05);
  --fx-3: rgba(232,244,206,0.03);
}

/* Lampblack — Scribe. MOST NEUTRAL COOL SKIN. The lowest-chroma accents in the
   app on a genuinely cold ground, with paper-warm text over it. Arcane is the
   lit wizard's tower; this is the reading room at 2am. */
html[data-skin="lampblack"],
.brand-card[data-skin-card="lampblack"] {
  --surface-0: #0a0b0d;
  --surface-1: #111318;
  --surface-2: #191c22;
  --surface-3: #242832;
  --border: rgba(228,232,240,0.11);
  --border-strong: rgba(228,232,240,0.23);
  --border-accent: #8ba4c9;
  --text-primary: #ece9e2;
  --text-secondary: #a6aab4;
  --text-muted: #767c88;
  --text-accent: #b0c4de;
  --text-success: #8fcaa4;
  --bg-success: rgba(143,202,164,0.12);
  --accent-fg: #0a0c10;
  --accent-hover: #9db4d6;
  --danger: #e79a95;
  --xp: #b0c4de;
  --coin: #ddc48c;
  --warn-text: #d2c19a;
  --warn-bg: rgba(221,196,140,0.10);
  --warn-border: rgba(221,196,140,0.34);
  --chrome-bg: rgba(17,19,24,0.93);
  --glow: 0 0 0 1px rgba(139,164,201,0.36);

  --fx-1: rgba(139,164,201,0.06);
  --fx-2: rgba(228,232,240,0.04);
  --fx-3: rgba(221,196,140,0.03);
}


/* ===========================================================================
   AMBIENCE — one bespoke idle motion per skin.

   The SKINS rows in cosmetics.js carry an `ambience` keyword and skins.css binds
   it, so a skin without one is a skin that does not breathe. `drift` and
   `flicker` are taken and, per the bespoke directive, not reused: twelve skins
   sharing two motions is the sameness the directive exists to stop.

   Same guards as skins.css's own ambience block:
     · inset stays 0 on the overlay. A fixed element with a negative inset still
       extends the scrollable area — that is what put 254px of horizontal
       overflow on every page once. Everything below pans a gradient INSIDE the
       stationary box, or animates opacity.
     · nothing faster than a 20-second cycle unless the subject demands it
       (Quenchfire's roar and Honeyveil's hum are the two that do, and both keep
       their amplitude tiny to compensate).

   ONE DIFFERENCE FROM skins.css, deliberate: these bind to `body::before`, which
   is the element that actually paints `--ambience`. The existing blocks put
   `animation` on `html[data-skin=...]`, where background-position has nothing to
   move — worth a look, but not changed here.
   =========================================================================== */

/* Lanternstone — the lamp SWINGS. An arc, not a pan: the light returns through
   the same path, which is what a hanging lantern does. */
html[data-skin="lanternstone"] {
  --ambience:
    radial-gradient(circle at 30% 14%, rgba(232, 161, 60, 0.12), transparent 54%),
    radial-gradient(circle at 74% 82%, rgba(170, 190, 220, 0.05), transparent 50%);
  --ambience-size: 200% 200%;
}
html[data-skin="lanternstone"] body::before { animation: cm-sway 26s ease-in-out infinite; }
@keyframes cm-sway {
  0%, 100% { background-position: 34% 46%; }
  50%      { background-position: 66% 52%; }
}

/* Heartwood — timber MOVING WITH THE ROOM. The slowest cycle in the app: two
   minutes, and only the size changes. Wood does not glow, it expands. */
html[data-skin="heartwood"] {
  --ambience:
    radial-gradient(circle at 22% 30%, rgba(201, 138, 69, 0.10), transparent 58%),
    radial-gradient(circle at 80% 70%, rgba(140, 120, 80, 0.07), transparent 54%);
  --ambience-size: 170% 170%;
}
html[data-skin="heartwood"] body::before { animation: cm-settle 122s ease-in-out infinite alternate; }
@keyframes cm-settle {
  from { background-size: 168% 168%; }
  to   { background-size: 184% 176%; }
}

/* Saltglass — a SWELL. Vertical only, and it never pauses at either end, which
   is what separates a swell from a breath. */
html[data-skin="saltglass"] {
  --ambience:
    radial-gradient(ellipse 70% 40% at 50% 8%, rgba(127, 227, 224, 0.10), transparent 62%),
    radial-gradient(ellipse 60% 50% at 30% 94%, rgba(63, 169, 216, 0.08), transparent 58%);
  --ambience-size: 180% 200%;
}
html[data-skin="saltglass"] body::before { animation: cm-swell 31s linear infinite; }
@keyframes cm-swell {
  0%   { background-position: 50% 8%; }
  50%  { background-position: 50% 92%; }
  100% { background-position: 50% 8%; }
}

/* Feralnight — something CROSSING. One direction, then a hard restart: the only
   skin ambience that does not run `alternate`, because a thing that paces back
   and forth is caged and this one is not. */
html[data-skin="feralnight"] {
  --ambience:
    radial-gradient(ellipse 40% 60% at 18% 50%, rgba(176, 122, 240, 0.11), transparent 56%),
    radial-gradient(circle at 82% 24%, rgba(255, 164, 100, 0.06), transparent 48%);
  --ambience-size: 260% 180%;
}
html[data-skin="feralnight"] body::before { animation: cm-stalk 44s linear infinite; }
@keyframes cm-stalk {
  0%       { background-position: 0% 50%; opacity: 0; }
  8%, 88%  { opacity: 1; }
  100%     { background-position: 100% 50%; opacity: 0; }
}

/* Hearthfield — the TURNING SEASON. Three and a half minutes, and it changes
   nothing but its own weight. The calmest ambience here by a wide margin, which
   is the whole identity of the element. */
html[data-skin="hearthfield"] {
  --ambience:
    radial-gradient(ellipse 90% 50% at 50% 104%, rgba(106, 167, 156, 0.09), transparent 66%),
    radial-gradient(ellipse 70% 40% at 50% -6%, rgba(217, 191, 133, 0.06), transparent 62%);
  --ambience-size: 160% 170%;
}
html[data-skin="hearthfield"] body::before { animation: cm-season 214s ease-in-out infinite alternate; }
@keyframes cm-season {
  from { opacity: 0.55; }
  to   { opacity: 1; }
}

/* Honeyveil — a HUM. Fast and tiny: 1.4 seconds, and the amplitude is a fifth of
   a percent, so it reads as a sound rather than as a movement. The one place a
   short cycle is correct. */
html[data-skin="honeyveil"] {
  --ambience:
    radial-gradient(circle at 26% 20%, rgba(255, 194, 122, 0.11), transparent 52%),
    radial-gradient(circle at 76% 76%, rgba(242, 115, 155, 0.07), transparent 50%);
  --ambience-size: 180% 180%;
}
html[data-skin="honeyveil"] body::before { animation: cm-hum 1.4s ease-in-out infinite alternate; }
@keyframes cm-hum {
  from { background-position: 49.8% 50.1%; }
  to   { background-position: 50.2% 49.9%; }
}

/* Retort — a REACTION PROCEEDING. Irregular steps rather than a curve: something
   is going on in there and it is not smooth. */
html[data-skin="retort"] {
  --ambience:
    radial-gradient(circle at 50% 96%, rgba(123, 139, 245, 0.11), transparent 54%),
    radial-gradient(circle at 22% 30%, rgba(103, 224, 168, 0.06), transparent 48%);
  --ambience-size: 190% 190%;
}
html[data-skin="retort"] body::before { animation: cm-react 34s steps(9, end) infinite; }
@keyframes cm-react {
  0%   { background-position: 42% 58%; opacity: 0.7; }
  22%  { background-position: 58% 46%; opacity: 1; }
  41%  { background-position: 47% 62%; opacity: 0.78; }
  63%  { background-position: 62% 40%; opacity: 0.95; }
  81%  { background-position: 38% 55%; opacity: 0.72; }
  100% { background-position: 42% 58%; opacity: 0.7; }
}

/* Prismlight — REFRACTION. The gradient's stops move relative to each other
   rather than the whole thing panning, so the colours separate and rejoin. */
html[data-skin="prismlight"] {
  --ambience:
    radial-gradient(ellipse 50% 70% at 34% 20%, rgba(99, 220, 237, 0.10), transparent 56%),
    radial-gradient(ellipse 60% 50% at 68% 40%, rgba(214, 244, 252, 0.07), transparent 54%),
    radial-gradient(ellipse 40% 60% at 52% 82%, rgba(140, 232, 200, 0.06), transparent 52%);
  --ambience-size: 170% 190%;
}
html[data-skin="prismlight"] body::before { animation: cm-refract 29s ease-in-out infinite alternate; }
@keyframes cm-refract {
  from { background-position: 40% 44%, 56% 50%, 48% 60%; }
  to   { background-position: 58% 52%, 42% 44%, 60% 48%; }
}

/* Quenchfire — a ROAR. Deeper and faster than Emberlight's flicker, and that
   comparison is the point: a candle gutters, a forge draws. Uneven stops keep it
   from reading as a pulse. */
html[data-skin="quenchfire"] {
  --ambience:
    radial-gradient(ellipse 80% 50% at 50% 106%, rgba(255, 106, 43, 0.13), transparent 62%),
    radial-gradient(circle at 84% 12%, rgba(255, 214, 150, 0.05), transparent 46%);
  --ambience-size: 190% 200%;
}
html[data-skin="quenchfire"] body::before { animation: cm-roar 7.4s ease-in-out infinite; }
@keyframes cm-roar {
  0%   { opacity: 0.82; background-size: 190% 200%; }
  14%  { opacity: 1;    background-size: 202% 208%; }
  27%  { opacity: 0.74; background-size: 186% 196%; }
  46%  { opacity: 0.97; background-size: 198% 206%; }
  61%  { opacity: 0.8;  background-size: 188% 198%; }
  83%  { opacity: 1;    background-size: 200% 204%; }
  100% { opacity: 0.82; background-size: 190% 200%; }
}

/* Loomlight — a SHUTTLE PATH. Two axes, and the horizontal reverses twice for
   each vertical pass, so the light traces cloth being made. */
html[data-skin="loomlight"] {
  --ambience:
    radial-gradient(ellipse 40% 60% at 30% 40%, rgba(226, 99, 189, 0.11), transparent 54%),
    radial-gradient(ellipse 60% 40% at 70% 66%, rgba(245, 143, 212, 0.06), transparent 52%);
  --ambience-size: 210% 190%;
}
html[data-skin="loomlight"] body::before { animation: cm-weave 37s ease-in-out infinite; }
@keyframes cm-weave {
  0%   { background-position: 12% 42%; }
  25%  { background-position: 88% 46%; }
  50%  { background-position: 12% 54%; }
  75%  { background-position: 88% 58%; }
  100% { background-position: 12% 42%; }
}

/* Greenhearth — a SIMMER. A small, steady bob with no colour change: something
   on a low heat, not something on fire. */
html[data-skin="greenhearth"] {
  --ambience:
    radial-gradient(ellipse 70% 40% at 50% 100%, rgba(240, 212, 136, 0.10), transparent 62%),
    radial-gradient(ellipse 80% 40% at 50% 4%, rgba(158, 207, 66, 0.06), transparent 60%);
  --ambience-size: 180% 180%;
}
html[data-skin="greenhearth"] body::before { animation: cm-simmer 12s ease-in-out infinite alternate; }
@keyframes cm-simmer {
  from { background-position: 50% 53%; }
  to   { background-position: 50% 47%; }
}

/* Lampblack — a GUTTER. Almost nothing for most of the cycle, then one deep dip
   and a recovery. Emberlight's flicker is continuous unevenness; this is long
   stillness punctuated once, which is what a lamp at 2am actually does. */
html[data-skin="lampblack"] {
  --ambience:
    radial-gradient(circle at 20% 12%, rgba(221, 196, 140, 0.09), transparent 50%),
    radial-gradient(circle at 78% 74%, rgba(139, 164, 201, 0.05), transparent 48%);
  --ambience-size: 175% 175%;
}
html[data-skin="lampblack"] body::before { animation: cm-gutter 41s ease-in-out infinite; }
@keyframes cm-gutter {
  0%, 62%   { opacity: 1; }
  68%       { opacity: 0.62; }
  71%       { opacity: 0.88; }
  75%       { opacity: 0.54; }
  82%, 100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  html[data-skin="lanternstone"] body::before, html[data-skin="heartwood"] body::before,
  html[data-skin="saltglass"] body::before, html[data-skin="feralnight"] body::before,
  html[data-skin="hearthfield"] body::before, html[data-skin="honeyveil"] body::before,
  html[data-skin="retort"] body::before, html[data-skin="prismlight"] body::before,
  html[data-skin="quenchfire"] body::before, html[data-skin="loomlight"] body::before,
  html[data-skin="greenhearth"] body::before, html[data-skin="lampblack"] body::before {
    animation: none !important;
  }
}
