/* ky-plates — the per-wallpaper identity, drawn.
   ky/ky-plates.js is the only writer of the --kyp-* properties and the
   data-kyp attributes these rules read.

   THE DIVISION OF LABOUR
   ----------------------
   ky-wave.css   the palette crossfade (the 13 --color-* tokens, per element,
                 as the wavefront arrives). Colour of TYPE.
   ky-mode.css   whether chrome is glass at all (wallmode) or pure ink.
   THIS FILE     what "glass" MEANS on this particular plate — how much
                 ground it holds back, how it blurs, what shape it is, how
                 fast it moves, how its hairlines read. Material, not colour.

   It loads AFTER ky-mode.css so it can specialise inside wallmode, and every
   rule is gated on html.ky-wallmode[data-kyp] so the ink site is untouched.

   THE SCRIM — the fix for the measured failure
   --------------------------------------------
   MEASURED before this file, worst-case background luminance under the type:
     forest-snow   cal month 3.30:1   cal weekday 3.67:1
     singularity   cal weekday 4.04:1
   Both fail AA. Both fail for the same reason: the panel sits over the
   brightest region of that specific plate (the mist band; the accretion
   disk) and a translucent pane cannot hold a contrast against a moving
   highlight. --kyp-scrim is a per-plate ground plane painted UNDER the tint,
   sized from that measurement — 0.46 on singularity, 0.16 on starfield,
   which needs almost none. It rides on ::before so the pane's own
   background, border and lens are all left alone. */

/* ---- the material --------------------------------------------------------

   POSITION IS DELIBERATELY NOT SET HERE. This rule used to open with
   `position: relative`, to give the ::before scrim below something to anchor
   to. On the three in-flow surfaces that was free. On #ky-cal-panel it was a
   catastrophe:

     #ky-cal-panel      in ky-cal2.css declares position:fixed   (1,0,0)
     html.ky-wallmode[data-kyp] #ky-cal-panel   declared relative (1,2,1)

   The plate won on specificity, so the booking panel stopped being fixed and
   fell back into normal flow with left/top:50% resolving against the BODY —
   MEASURED at y=11274px on the portfolio and y=3156px on a world page. The
   panel was opening correctly every time; it was just three viewports below
   the fold. All the visitor ever saw was #ky-cal-scrim's blur(2px) landing on
   the page, which is exactly the reported "the calendar does not open, it
   just blurs the page".

   The scrim only needs a positioned ancestor, and #ky-cal-panel already IS
   one (fixed is positioned). So the three in-flow surfaces are named
   explicitly below and the panel is left to its own declaration. Never add
   #ky-cal-panel to a rule that sets `position` — it must stay fixed. */
html.ky-wallmode[data-kyp] #ky-cal,
html.ky-wallmode[data-kyp] #ky-music,
html.ky-wallmode[data-kyp] .ky-c3-card {
  position: relative;
}
html.ky-wallmode[data-kyp] #ky-cal,
html.ky-wallmode[data-kyp] #ky-cal-panel,
html.ky-wallmode[data-kyp] #ky-music,
html.ky-wallmode[data-kyp] .ky-c3-card {
  border-radius: var(--kyp-radius, 14px);
  border-color: var(--kyp-line, rgba(20, 17, 10, .22));
}

/* THE CALENDAR WEARS THE PLATE'S ACCENT, NOT THE HONEY'S.
   ky-cal2.css derives its working colours from the --color-* theme tokens,
   which only ky-wave rewrites — and a wave only runs when a wave is RUN. A
   pinned world page never runs one, so the booking instrument opened wearing
   honey-ink's amber month tabs, meter and strike marks inside a violet (or
   aqua, or lamplight) world — MEASURED on singularity: the panel read as
   another world's prop. --kyp-accent is stamped unconditionally by
   ky-plates.js on every plate, so it is the value that is always true here.
   The custom properties are re-pointed rather than any rule re-painted:
   ky-cal2.css keeps sole ownership of what the tokens mean. */
html.ky-wallmode[data-kyp] #ky-cal,
html.ky-wallmode[data-kyp] #ky-cal-panel {
  --kyc-glow: var(--kyp-accent, var(--color-accent-200, #E3AC33));
  --kyc-mark: color-mix(in srgb, var(--kyp-accent, #C4901D) 78%, var(--kyp-halo, #07040E));
}

/* The scrim. isolation:isolate is NOT used — that would create a stacking
   context and cut the lens off from what is behind it. z-index 0 on the
   layer with the content lifted above it is enough, and keeps the
   backdrop-filter reading the real page. */
html.ky-wallmode[data-kyp] #ky-cal::before,
html.ky-wallmode[data-kyp] #ky-cal-panel::before,
html.ky-wallmode[data-kyp] .ky-c3-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  border-radius: inherit;
  background: color-mix(in srgb, var(--kyp-pane, #101822) 92%, transparent);
  opacity: var(--kyp-scrim, .3);
}
html.ky-wallmode[data-kyp] #ky-cal > *,
html.ky-wallmode[data-kyp] #ky-cal-panel > *,
html.ky-wallmode[data-kyp] .ky-c3-card > * {
  position: relative;
  z-index: 1;
}

/* Glass CHARACTER. The engine's own inline backdrop-filter is an SVG lens
   url() plus blur/saturate; we re-declare the whole shorthand so the plate's
   blur and saturation win, and accept losing the lens url on the in-flow
   surfaces — which the PERF LAW forbids a lens on anyway. The fixed panel
   keeps its lens because ky-mode.css re-asserts it after this file. */
html.ky-wallmode[data-kyp] #ky-cal,
html.ky-wallmode[data-kyp] .ky-c3-card {
  -webkit-backdrop-filter: blur(var(--kyp-blur, 20px)) saturate(var(--kyp-sat, 1.2));
  backdrop-filter: blur(var(--kyp-blur, 20px)) saturate(var(--kyp-sat, 1.2));
}

/* ---- type treatment ------------------------------------------------------ */
html.ky-wallmode[data-kyp] #ky-cal .kyc2-w,
html.ky-wallmode[data-kyp] #ky-cal-panel .kyc-lab,
html.ky-wallmode[data-kyp] .ky-c3-lab {
  letter-spacing: var(--kyp-track, .18em);
  font-weight: var(--kyp-weight, 500);
}

/* The weekday row was the worst reading on two plates: it is small, mono,
   and sat directly on the highlight. It now takes the heading pole rather
   than a faded mix, and earns a hairline shelf so it reads as a header band
   rather than as faint text floating on footage. */
html.ky-wallmode[data-kyp] #ky-cal .kyc2-w {
  color: var(--kyp-ink, #F2EADF);
  opacity: .92;
}
html.ky-wallmode[data-kyp] #ky-cal .kyc2-mo {
  color: var(--kyp-ink, #F2EADF);
}

/* TYPE FOLLOWS THE PANE, NOT THE WALLPAPER.
   CAUGHT by measurement the moment the scrim landed: forest-snow's pane is
   cold cream (that IS its identity), and the day numerals were still taking
   the cream text pole the dark plates need — 1.03:1, invisible. The luma
   rule that decides the ink pole is about the FOOTAGE; inside a pane the
   local ground is the pane. So on a light-ground plate every glyph sitting
   on chrome flips to the ink pole, and the accent-filled cells (today, the
   busy marks) keep their own colours because they carry their own fill. */
html.ky-wallmode[data-kyp-ground="light"] :is(#ky-cal, #ky-cal-panel, .ky-c3-card)
  :not(.is-today):not([class*="accent"]) {
  color: var(--kyp-ink, #14110A);
}
html.ky-wallmode[data-kyp-ground="light"] #ky-cal .kyc2-d.is-busy {
  color: var(--kyp-ink-2, var(--kyp-ink, #14110A));
}

/* ...and the SAME exemption, for the controls that carry a --kyc-btn fill.
   The rule above states the principle correctly — anything with its own fill
   keeps its own ink — but only spells it out for .is-today and [class*=accent].
   Six controls in ky-cal2.css set `background:var(--kyc-btn)` together with
   `color:var(--kyc-btnt)`, and the blanket above outranks them
   (1,2,1 against #ky-cal-panel .kyc3-go's 1,1,0), so on a LIGHT-ground plate
   their ink was being flipped to --kyp-ink while their fill stayed --kyc-btn.

   MEASURED on tuesday before this fix: the "Use this day" button painted
   #0B2A33 text on a #0B2A33 fill — 1:1, the label completely invisible.
   forest-snow was the same failure wearing #14110A. Both are light-ground
   plates; the dark-ground worlds never showed it, which is why it survived.

   Re-asserting the token (rather than a literal) keeps ky-cal2.css the sole
   owner of what the pairing means — this only restores the half the blanket
   took away.

   THE DESCENDANT HALF IS NOT OPTIONAL. The blanket is a descendant selector,
   so it does not merely beat the control's own `color` — it also matches the
   control's CHILDREN and sets the property directly on them, which
   inheritance from the parent can never win back. .kyc3-go's label lives in a
   <span> (and its arrow in an <i>), so fixing only the button left the button
   correct and the words still invisible — measured: the control reported
   14.74:1 while the label rendered blank. Both halves, or neither. */
html.ky-wallmode[data-kyp-ground="light"] :is(#ky-cal, #ky-cal-panel)
  :is(.kyc3-go, .kyc3-chip.is-free, .kyc3-slot.is-on,
      .kyc3-arrow:hover, .kyc3-today:hover, .kyc3-edit button:hover),
html.ky-wallmode[data-kyp-ground="light"] :is(#ky-cal, #ky-cal-panel)
  :is(.kyc3-go, .kyc3-chip.is-free, .kyc3-slot.is-on,
      .kyc3-arrow:hover, .kyc3-today:hover, .kyc3-edit button:hover) * {
  color: var(--kyc-btnt);
}

/* ---- motion feel --------------------------------------------------------- */
html.ky-wallmode[data-kyp] #ky-cal,
html.ky-wallmode[data-kyp] #ky-music,
html.ky-wallmode[data-kyp] .ky-c3-card,
html.ky-wallmode[data-kyp] .ky-c3-chip {
  transition-timing-function: var(--kyp-ease, cubic-bezier(.22, 1, .36, 1));
}

/* ---- focus, from the plate's own light ----------------------------------- */
html.ky-wallmode[data-kyp] :is(button, a, input, textarea, select):focus-visible {
  outline: 2px solid var(--kyp-glow, #FFFFFF);
  outline-offset: 2px;
}

/* ---- per-plate chrome character ------------------------------------------
   Small, deliberate divergences — enough that each world is recognisably
   itself, never so much that the layout moves. */

/* SNOW — frost sits on the top edge of every pane, the way it actually
   collects; hairlines are ink because the ground is light. */
html.ky-wallmode[data-kyp="forest-snow"] :is(#ky-cal, .ky-c3-card)::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .85), transparent);
}

/* EMBER — the pane's lit edge glows along the bottom, where the heat is. */
html.ky-wallmode[data-kyp="ember-ring"] :is(#ky-cal, .ky-c3-card) {
  box-shadow: 0 10px 34px -18px var(--kyp-glow, #FF9457),
              inset 0 -1px 0 color-mix(in srgb, var(--kyp-pane2) 55%, transparent);
}

/* RAIN — chrome is squarer and wetter: a vertical sheen down the pane. */
html.ky-wallmode[data-kyp="courtyard-rain"] :is(#ky-cal, .ky-c3-card)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(100deg,
    transparent 0 42%,
    color-mix(in srgb, var(--kyp-pane2) 16%, transparent) 47%,
    transparent 52% 100%);
}

/* SINGULARITY — the pane is lensed: a bright rim that falls off, so chrome
   reads as something light is bending around. The heaviest scrim in the set
   lives here, and it is why the calendar now holds over the disk. */
html.ky-wallmode[data-kyp="singularity"] :is(#ky-cal, .ky-c3-card, #ky-cal-panel) {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--kyp-pane2) 42%, transparent),
              0 18px 60px -24px color-mix(in srgb, var(--kyp-glow) 55%, transparent);
}

/* STARFIELD — hairline chrome: almost no fill, a drawn 1px frame, wide
   tracking. The quietest plate gets the quietest material. */
html.ky-wallmode[data-kyp="starfield-drift"] :is(#ky-cal, .ky-c3-card) {
  box-shadow: inset 0 0 0 1px var(--kyp-line, rgba(169, 191, 232, .26));
}

/* ---- the backdrop's legibility plane wears the plate ----------------------
   ky-wall.js lays a flat ground plane over the footage and binary-searches its
   opacity for the smallest value that keeps the worst pixel behind the type at
   4.8:1. ky-wall.css paints that plane in honey amber, which is right for the
   ink page and wrong for every plate: it washed snow, rain and a black hole
   all toward the same mud, and the wallpaper stopped reading as itself.

   Here it becomes the plate's own pane, so the coverage the solver asks for is
   spent in a colour that belongs to the world — cold white over snow, void
   black under the singularity.

   THIS MUST STAY IN LOCKSTEP WITH ground() IN ky-wall.js. That function reads
   --kyp-pane under the identical html.ky-wallmode condition and models THIS
   colour when it solves. If the two ever name different tokens the solver is
   measuring a plane the page does not paint, and the contrast number it
   reports becomes fiction. Change one, change the other. */
html.ky-wallmode[data-kyp] .ky-wall-boost {
  background: var(--kyp-pane, var(--color-accent-200, #E3AC33));
}

/* EVERY TREATMENT PASS COMES OFF IN WALLMODE.
   .ky-wall-tint is a `color` blend that duotones the footage to the theme hue;
   .ky-wall-soft is a soft-light pass on top of it; the wash and the two scrim
   gradients bury what survives (the hero gradient alone reaches 94%). Together
   they turn five distinct wallpapers into five shades of one wash — a black
   hole arrives as tinted grey.

   They are correct on the ink page, where the wallpaper is a texture behind
   honey chrome. In wallmode the wallpaper is the subject, so it is shown as
   shot. ky-wall.js's solve() returns early under the same condition (con 1, no
   plane) and scrimAlpha() returns 0, so the solver is never modelling passes
   that are not painted. All four facts are one change — see solve(). */
html.ky-wallmode[data-kyp] :is(.ky-wall-tint, .ky-wall-soft, .ky-wall-wash,
                               .ky-wall-scrim-hero, .ky-wall-scrim-foot) {
  display: none;
}

/* and no contrast crush: --kyw-con collapses the picture's luminance range
   toward mid-tone, which is the difference between an event horizon and a grey
   disc. ky-wall.js already stops solving it here; this is the belt to that
   brace, so a stale inline value from ink mode cannot survive the switch. */
html.ky-wallmode[data-kyp] :is(.ky-wall-still, .ky-wall-vid) {
  filter: none;
}

/* The hero's type POLE is set in ky-site.css, which owns .kys-* and loads
   after this file — a colour rule here loses the cascade to it. This file
   supplies the token (--kyp-heroInk) and the halo below; ky-site.css spends
   it. Only the halo lives here, because it is a plate concern rather than a
   layout one, and nothing else sets text-shadow on those elements. */

/* ---- the landing page's hero takes the footage pole too -------------------
   Same rule as the world pages, same reason, different markup. The wordmark,
   the nav and the pitch line on index.html sit directly on the wallpaper, so
   they must follow the FOOTAGE — but they inherit --color-foreground, which
   ky-wave derives from the plate's PANE. On the two light-ground plates that
   points the wrong way: Tuesday put dark ink on a mid-aqua room and Snowfall
   put dark ink on a dark forest.

   Setting `color` here rather than redefining --color-foreground is deliberate.
   ky-wave stamps the palette INLINE on each registered element as the
   wavefront crosses it, so a token redeclared in a stylesheet would lose — but
   it stamps CUSTOM PROPERTIES, never `color` itself, so a direct colour
   declaration still wins. The per-letter spans are included because the hero
   cascade splits the wordmark into .kycl children that would otherwise keep
   their own inherited colour.

   The hero zone is identified by the same container ky-wall.js mounts its
   backdrop into — if that selector ever changes, the backdrop and this rule
   break together rather than drifting apart silently. */
html.ky-wallmode[data-kyp] :is(
  h1 .ky-heroname, h1 .ky-heroname *,
  .section-padding-equal.sticky.top-0.h-svh p,
  header a.group.relative.block
) {
  color: var(--kyp-heroInk, #F2EADF);
}

/* ---- the halo: legibility that costs the picture nothing ------------------
   With the veil gone, type sits on unmodified footage, and footage has bright
   regions — an accretion disc, a snowbank, a lantern. The old answer damaged
   the whole frame so the worst pixel would behave. This is the local answer: a
   soft halo carried by the glyph itself, so it exists within a few pixels of
   type and nowhere else. Away from the words the wallpaper is untouched, which
   is the entire point of the change.

   --kyp-halo is deliberately the OPPOSITE pole to --kyp-heroInk, not the pane:
   cream type gets a near-black halo, and Sunset's dark type gets a warm pale
   one. Tinted to the world rather than pure black, so it reads as depth in the
   picture instead of a drop shadow on a sticker.

   Three radii, not one: 2px holds the edge against fine detail like falling
   snow, 8px and 22px lift the glyph off a large bright shape like the
   accretion disc. */
html.ky-wallmode[data-kyp] :is(#ky-site .kys-hero h1,
                               #ky-site .kys-hero .kys-name,
                               #ky-site .kys-hero .kys-lede,
                               #ky-site .kys-hero .kys-eyebrow,
                               #ky-site .kys-hero p,
                               #ky-slide-hero h1, #ky-slide-hero p,
                               h1 .ky-heroname,
                               .section-padding-equal.sticky.top-0.h-svh p) {
  text-shadow:
    0 0 2px    color-mix(in srgb, var(--kyp-halo, #07040E) 92%, transparent),
    0 0 8px    color-mix(in srgb, var(--kyp-halo, #07040E) 78%, transparent),
    0 1px 22px color-mix(in srgb, var(--kyp-halo, #07040E) 62%, transparent);
}

/* THE DUST WORDMARK TAKES NO TEXT-SHADOW. KYText.dust leaves the real text in
   place as a `color: transparent` span and paints particles on a canvas above
   it — but text-shadow is generated from the GLYPH SHAPE, not from the colour,
   so an invisible span still casts a fully visible halo. The result was a
   solid block of shadow behind the particles: the wordmark read as a pixel
   grid rather than as dust. */
html.ky-wallmode[data-kyp] :is(.kyt-dust, .kyt-dust *, .kyt-dust-ink) {
  text-shadow: none !important;
}

/* ...it gets a drop-shadow on the CANVAS instead. drop-shadow follows the
   painted alpha, so each particle carries its own halo and the space between
   particles stays empty — which is the difference between dust over a black
   hole and a grey slab over one. Same protection, correct shape.

   ...and it did not work, in both directions. Sized against the glyph (9px) a
   mote's shadow covered ~20 neighbours at ~2px spacing, they summed, and the
   field filled in solid — the grey slab this comment set out to avoid, reached
   from the other side. Sized down near the spacing it still pooled.

   RETIRED, and deliberately left as `none`. ky-textfx now bakes the halo into
   the particle sprite itself, where it is bounded by a footprint clamped below
   the particle spacing and cannot pool between motes. This must stay off
   rather than stack a second, redundant halo on top. */
html.ky-wallmode[data-kyp] .kyt-dust-cv { filter: none; }

/* ---- hot plates carry a heavier halo -------------------------------------
   Ember and Singularity are the two plates with a genuinely blown-out feature
   in frame — a white-hot fire ring and an accretion disc — and the wordmark
   crosses both. Measured with the standard halo, cream type over those regions
   still bottomed out at 1.0:1. The rest of the set never needs this, so it is
   spent only where the footage actually demands it rather than thickening
   every plate's type to suit the worst one. */
html.ky-wallmode[data-kyp="ember-ring"] :is(#ky-site .kys-hero h1,
                                            #ky-site .kys-hero .kys-name,
                                            #ky-site .kys-hero .kys-lede,
                                            #ky-site .kys-hero .kys-eyebrow),
html.ky-wallmode[data-kyp="singularity"] :is(#ky-site .kys-hero .kys-lede,
                                             #ky-site .kys-hero .kys-eyebrow) {
  text-shadow:
    0 0 3px    color-mix(in srgb, var(--kyp-halo, #170B06) 96%, transparent),
    0 0 10px   color-mix(in srgb, var(--kyp-halo, #170B06) 90%, transparent),
    0 0 26px   color-mix(in srgb, var(--kyp-halo, #170B06) 78%, transparent),
    0 2px 44px color-mix(in srgb, var(--kyp-halo, #170B06) 62%, transparent);
}

/* ---- reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html.ky-wallmode[data-kyp] :is(#ky-cal, #ky-music, .ky-c3-card, .ky-c3-chip) {
    transition-duration: .01ms !important;
  }
}

/* ---- gradient wordmarks and the letter split ------------------------------
   Three plate skins fill the wordmark with a gradient the standard way:
   background-image + background-clip:text + a transparent text fill. On a
   plain <h1> that works. On THIS site it silently painted nothing.

   ky-cursor splits .ky-heroname into per-letter .kycl spans, each an
   inline-block with its own box. -webkit-text-fill-color is an INHERITED
   property, so the transparent fill reaches every letter — but the background
   does not, and background-clip has nothing to clip inside a child box. The
   result is a wordmark with no fill at all, visible only through its halo:
   near-black letters on a dark forest, and near-black letters on a bright
   lavender field. Both were effectively unreadable.

   The skins each guarded the @supports case (browser cannot clip to text) but
   not this one, which is the failure that actually happens. Handled here, once,
   rather than in each skin: background-image:inherit hands every letter the
   same gradient its parent was given, so the fill survives the split.

   Safe on plates with no gradient: inherit resolves to `none` and clipping a
   background that does not exist changes nothing. And because the letters share
   a height and a baseline, a per-letter vertical gradient is indistinguishable
   from one run across the whole word — which is why all three of these
   gradients are near-vertical.

   EVERY descendant, not just the leaf letters. inherit takes its value from the
   IMMEDIATE parent, and the split nests three deep
   (.ky-heroname > .kyc-row > .kycw > .kycl) — naming only the leaf makes it
   inherit `none` from an intermediate span that was never handed the gradient.
   The universal selector is scoped to one element's subtree, which is a dozen
   spans. */
html.ky-wallmode[data-kyp] .ky-heroname * {
  background-image: inherit;
  -webkit-background-clip: text;
          background-clip: text;
}

/* ---- the wordmark halo must be a FILTER, not a text-shadow ----------------
   PAINT ORDER, and it bit three plates at once.

   Three skins fill the wordmark with background-clip:text + a transparent text
   fill. The element's background paints BELOW the text layer, and text-shadow
   paints as part of the text layer — so the halo lands ON TOP of the gradient,
   not behind it. With a halo at 92% opacity that means the fill is completely
   covered and the word renders as its own shadow: a near-black wordmark on a
   dark forest, and a near-black wordmark on a bright lavender field. Measured
   on Snowfall: killing the shadow took the wordmark from mean luminance 38 to
   122 out of 255 — the gradient had been painting correctly the whole time.

   (ky-p-house-of-dreams.css asserts the opposite order in a comment — that the
   halo "paints BEHIND the clipped background". It does not.)

   drop-shadow() is the fix: as a filter it runs on the element's RENDERED
   result, so it sees the gradient-filled glyphs and always composites behind
   them. Applied to the wordmark's own box, and the text-shadow that ky-plates
   otherwise gives the hero is switched off here so the two cannot stack.

   SCOPED TO THE TWO GRADIENT PLATES, not applied across the board, for two
   reasons — both of which are regressions if ignored:

   · Singularity's wordmark is the DUST canvas, and that canvas is a child of
     .ky-heroname. A filter on the parent filters the whole subtree, so a
     drop-shadow here would blur the particle field and pool it back into the
     grey slab that ky-textfx's per-mote sprite halo was written to prevent.
   · Tuesday and Bongo Cat use their text-shadow deliberately — Tuesday's is a
     hard two-step offset print, which is its signature. Neither fills with a
     gradient, so neither has the paint-order problem, and blanking their
     shadow would delete a design rather than fix a bug.

   On House of Dreams the drop-shadow below does NOT land: its own skin animates
   `filter` for the oil-lamp flicker, and an animation beats a static
   declaration. Left in place anyway so the rule stays true for that plate if
   the lamp is ever removed — and the plate does not need it: cream on the
   lavender field clears AA without help. Killing the text-shadow is what
   actually matters there, and that part does apply. */
/* !important, and it is load-bearing — MEASURED, not defensive. The halo rule
   above reaches (1,4,2) because its :is() carries #ky-site arms, and this
   override without the flag reaches only (0,4,2), so on the ELEMENT ITSELF the
   halo wins. That was invisible in ordinary testing because ky-cursor splits
   the wordmark into .kycl letter spans and the `*` arm below matches those
   children directly, beating mere inheritance. But ky-cursor gates on
   finePtr() && !reduced(): under prefers-reduced-motion AND on every
   coarse-pointer device the wordmark stays ONE unsplit span, the halo lands on
   it, and a 92%-opaque shadow paints over the background-clipped gradient —
   KRYPTO PICO rendered as a near-black silhouette (measured 1.5:1 on
   forest-snow, 2.4:1 on house-of-dreams, i.e. every phone visitor). Scoped to
   the two gradient-fill plates only, so no deliberate shadow elsewhere
   (Tuesday's offset print, Bongo's tube glow) is touched. */
html.ky-wallmode[data-kyp="forest-snow"] :is(h1 .ky-heroname, .kys-name .ky-heroname),
html.ky-wallmode[data-kyp="forest-snow"] :is(h1 .ky-heroname, .kys-name .ky-heroname) *,
html.ky-wallmode[data-kyp="house-of-dreams"] :is(h1 .ky-heroname, .kys-name .ky-heroname),
html.ky-wallmode[data-kyp="house-of-dreams"] :is(h1 .ky-heroname, .kys-name .ky-heroname) * {
  text-shadow: none !important;
}
html.ky-wallmode[data-kyp="forest-snow"] :is(h1 .ky-heroname, .kys-name .ky-heroname),
html.ky-wallmode[data-kyp="house-of-dreams"] :is(h1 .ky-heroname, .kys-name .ky-heroname) {
  filter:
    drop-shadow(0 0 2px  color-mix(in srgb, var(--kyp-halo, #07040E) 88%, transparent))
    drop-shadow(0 1px 9px color-mix(in srgb, var(--kyp-halo, #07040E) 66%, transparent));
}
