/* ==========================================================================
   Nectaring, purple.css
   Loaded AFTER aero.css. The purple-led, clay-textured pass built around
   the six commissioned 3D renders.

   What changes and why:

     The lead colour moves from pink to the violet of the renders. Pink is
     still here, as the secondary, on the badge and the wordmark halo. Lime
     green, the dot in the glyphs and the eyes on the swirl, is the third
     colour and is used only as a dot.

     The panes stop being wet glass and become matte clay. Same shape, same
     windows, but the hard specular streak is gone, the radius is rounder,
     there is a grain across every surface, and the inner light is soft.
     The renders are matte and grainy and the page has to be the same
     material or they sit on it like stickers.

     The renders themselves are placed as furniture rather than as
     decoration: columns flank the wordmark, the portrait stands in the
     doorway of the arch on its steps, the new single's cover sits on the
     checkerboard plinth, the swirl peeks over the corner of the Listen
     window, the clouds drift behind everything, and the glyph strip is the
     divider under the hero.

   Everything decorative is aria-hidden and takes no pointer events.
   Reduced motion stops the clouds. Everything scales to a phone, and the
   columns and the swirl simply leave on narrow screens rather than
   squeezing in.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* The violet of the arch and the column, sampled from the renders. */
  --purple:       #a24dff;
  --purple-deep:  #6b1fd3;
  --purple-ink:   #4a0f9c;   /* text-safe on lavender glass, 7.9:1 */
  --lilac:        #d9b8ff;
  --lavender:     #efe3ff;
  --lime:         #b8ff1e;   /* the dot. never text */

  /* aero.css reads these for every glow on the page. Cyan becomes violet,
     so every tube light on the site changes colour at once. */
  --neon-pink:  255, 90, 200;
  --neon-cyan:  162, 77, 255;
  --neon-gold:  184, 255, 30;

  --sky-1: #3b1466;
  --sky-2: #7a3fd1;
  --sky-3: #b07cf0;
  --sky-4: #d6b6ff;
  --sky-5: #ead9ff;

  --aurora-a: rgba(255, 120, 220, 0.30);
  --aurora-b: rgba(170, 110, 255, 0.42);
  --aurora-c: rgba(200, 170, 255, 0.36);

  /* Lavender clay, not rose glass. Slightly more opaque than before because
     matte surfaces do not let the world through the way glass does. */
  --glass:        rgba(246, 236, 255, 0.84);
  --glass-strong: rgba(250, 243, 255, 0.94);
  --glass-quiet:  rgba(246, 236, 255, 0.62);
  --glass-edge:   rgba(255, 255, 255, 0.95);
  --glass-line:   rgba(74, 15, 156, 0.16);

  --ink:      #2a1040;
  --ink-soft: #5a3a7a;

  --pink:      #ff5ac8;
  --pink-ink:  #b0007a;
  --pink-deep: #7d0056;
  --pink-bright: #ff5ac8;
  --pink-wash: rgba(255, 90, 200, 0.18);

  --shadow:      0 18px 46px rgba(58, 14, 110, 0.28);
  --shadow-soft: 0 8px 22px rgba(58, 14, 110, 0.18);

  --radius: 22px;
  --radius-sm: 14px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --purple:      #b877ff;
    --purple-deep: #8a48e8;
    --purple-ink:  #d9b8ff;
    --lilac:       #7a48c8;
    --lavender:    #2a1444;

    --sky-1: #12061f; --sky-2: #2a0e4c; --sky-3: #43197a; --sky-4: #5a2a9a; --sky-5: #6b3ab0;

    --aurora-a: rgba(255, 90, 200, 0.34);
    --aurora-b: rgba(150, 90, 255, 0.34);
    --aurora-c: rgba(120, 80, 220, 0.26);

    --glass:        rgba(34, 14, 54, 0.80);
    --glass-strong: rgba(34, 14, 54, 0.92);
    --glass-quiet:  rgba(34, 14, 54, 0.62);
    --glass-edge:   rgba(200, 160, 255, 0.34);
    --glass-line:   rgba(200, 160, 255, 0.18);

    --ink:      #f6ecff;
    --ink-soft: #cdb0e8;

    --pink:      #ff6fd0;
    --pink-ink:  #ff9fe0;
    --pink-deep: #ffc4ec;
    --pink-bright: #ff6fd0;
    --pink-wash: rgba(255, 111, 208, 0.18);

    --shadow:      0 18px 46px rgba(0, 0, 0, 0.55);
    --shadow-soft: 0 8px 22px rgba(0, 0, 0, 0.40);
  }
}

/* --------------------------------------------------------------------------
   2. THE SKY, re-keyed
   The same four layers, with the textures moved into violet by
   tools/textures-purple.py, plus the four clouds.
   -------------------------------------------------------------------------- */

.sky {
  background:
    image-set(url("../img/sky-light-purple.webp") type("image/webp")) center / cover no-repeat,
    linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 34%, var(--sky-3) 62%, var(--sky-4) 84%, var(--sky-5) 100%);
  background-attachment: fixed;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sky {
    background:
      image-set(url("../img/sky-dark-purple.webp") type("image/webp")) center / cover no-repeat,
      linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 34%, var(--sky-3) 62%, var(--sky-4) 84%, var(--sky-5) 100%);
    background-attachment: fixed;
  }
}

.caustics { background-image: url("../img/caustics-purple.webp"); opacity: 0.42; }
.bokeh    { background-image: url("../img/bokeh-purple.webp"); opacity: 0.6; }

/* The clouds. Four renders, four depths. Farther ones are smaller, paler
   and slower. They live between the bokeh and the content, so a pane can
   pass in front of a cloud, which is the whole reason to have them. */
.clouds {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}
.clouds span {
  position: absolute;
  display: block;
  background-repeat: no-repeat;
  background-size: contain;
  filter: drop-shadow(0 18px 30px rgba(90, 30, 150, 0.22));
  will-change: transform;
  animation: cloud-drift linear infinite alternate;
}
.clouds .c1 { background-image: url("../img/3d/cloud-1.webp"); width: min(34vw, 420px); aspect-ratio: 457/306; left: -6%;  top: 8%;  opacity: 0.95; animation-duration: 70s; }
.clouds .c2 { background-image: url("../img/3d/cloud-2.webp"); width: min(26vw, 300px); aspect-ratio: 440/368; right: -4%; top: 22%; opacity: 0.85; animation-duration: 95s; animation-direction: alternate-reverse; }
.clouds .c3 { background-image: url("../img/3d/cloud-3.webp"); width: min(20vw, 230px); aspect-ratio: 450/328; left: 18%;  top: 58%; opacity: 0.7;  animation-duration: 120s; }
.clouds .c4 { background-image: url("../img/3d/cloud-4.webp"); width: min(30vw, 360px); aspect-ratio: 550/397; right: 6%;  top: 66%; opacity: 0.9;  animation-duration: 84s; animation-direction: alternate-reverse; }

@keyframes cloud-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(6vw, -2vh, 0); }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .clouds span { filter: drop-shadow(0 18px 30px rgba(0, 0, 0, 0.45)) brightness(0.82) saturate(1.1); }
}

/* Bubbles go lilac and there are fewer of them visually: the clouds now do
   the depth work, so the bubbles can be small and quiet. */
.bubble {
  background:
    radial-gradient(circle at 30% 26%,
      rgba(255, 255, 255, 0.98) 0%,
      rgba(255, 255, 255, 0.45) 15%,
      rgba(255, 255, 255, 0.06) 40%,
      rgba(217, 184, 255, 0.10) 62%,
      rgba(255, 255, 255, 0.28) 86%,
      rgba(255, 255, 255, 0.66) 100%);
  box-shadow:
    inset 0 0 18px rgba(255, 255, 255, 0.6),
    inset -4px -6px 12px rgba(162, 77, 255, 0.30),
    0 0 16px rgba(255, 255, 255, 0.28);
}

/* --------------------------------------------------------------------------
   3. CLAY, not glass
   -------------------------------------------------------------------------- */

.win {
  border: 1px solid var(--glass-edge);
  outline: 1px solid rgba(74, 15, 156, 0.10);
  background:
    radial-gradient(140% 60% at 50% -14%, rgba(255, 255, 255, 0.70) 0%, rgba(255, 255, 255, 0.18) 46%, rgba(255, 255, 255, 0) 70%),
    linear-gradient(180deg, var(--glass-strong) 0%, var(--glass) 60%, var(--glass-strong) 100%);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  box-shadow:
    var(--shadow),
    0 2px 0 rgba(255, 255, 255, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -18px 30px rgba(162, 77, 255, 0.10),
    inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}

/* Grain over everything, the butterflies underneath it, and the caustics
   re-keyed. The droplets are gone: clay is not wet. */
.win::before {
  background:
    url("../img/grain.webp") 0 0 / 160px 160px repeat,
    url("../img/butterflies.webp") 0 0 / 150px 150px repeat,
    url("../img/caustics-purple.webp") 0 0 / 520px 520px repeat;
  background-blend-mode: normal, normal, screen;
  opacity: 0.16;
  mix-blend-mode: multiply;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .win::before { mix-blend-mode: soft-light; opacity: 0.28; }
}

/* The long specular streak is what said "wet". It goes to almost nothing. */
.win::after { opacity: 0.16; }

.win-bar {
  border-bottom: 1px solid var(--glass-line);
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.96) 0%,
    rgba(236, 222, 255, 0.86) 46%,
    rgba(206, 178, 255, 0.60) 50%,
    rgba(226, 206, 255, 0.72) 82%,
    rgba(246, 238, 255, 0.90) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -1px 0 rgba(255, 255, 255, 0.7),
    0 1px 0 rgba(74, 15, 156, 0.10);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .win-bar {
    background: linear-gradient(180deg, rgba(58, 26, 96, 0.94) 0%, rgba(58, 26, 96, 0.66) 48%, rgba(58, 26, 96, 0.42) 50%, rgba(58, 26, 96, 0.66) 100%);
  }
}

/* The orb on every title bar becomes the lime dot from the glyphs. */
.win-title .orb,
.taskbar .brand::before {
  background: radial-gradient(circle at 34% 30%, #fff 0%, rgba(255,255,255,.7) 20%, var(--lime) 55%, #4e8a00 100%);
  box-shadow: 0 0 8px rgba(184, 255, 30, 0.55);
}

.taskbar {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.78) 0%, rgba(246, 236, 255, 0.56) 49%, rgba(226, 206, 255, 0.34) 51%, rgba(246, 236, 255, 0.58) 100%);
  border-bottom-color: var(--glass-edge);
  box-shadow: 0 4px 18px rgba(58, 14, 110, 0.20), 0 0 24px rgba(var(--neon-cyan), 0.22);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .taskbar {
    background: linear-gradient(180deg, rgba(40, 16, 66, 0.86) 0%, rgba(40, 16, 66, 0.62) 49%, rgba(40, 16, 66, 0.44) 51%, rgba(40, 16, 66, 0.66) 100%);
  }
  :root:not([data-theme="light"]) .taskbar nav a {
    background: linear-gradient(180deg, rgba(74, 34, 120, 0.92), rgba(48, 20, 84, 0.62));
    border-color: rgba(200, 160, 255, 0.32);
  }
}

/* The ticker becomes the lead colour. */
.ticker {
  background: linear-gradient(180deg, #b46bff 0%, #6b1fd3 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 0 22px rgba(var(--neon-cyan), 0.6),
    0 0 54px rgba(var(--neon-cyan), 0.28);
}

/* Buttons: primary is violet, secondary is lavender clay. */
.btn {
  border-color: rgba(255, 255, 255, 0.85);
  background:
    radial-gradient(120% 96% at 50% -34%, rgba(255,255,255,0.98) 0%, rgba(255,255,255,0) 60%),
    linear-gradient(180deg, rgba(252, 248, 255, 0.98) 0%, rgba(236, 222, 255, 0.78) 48%, rgba(217, 184, 255, 0.50) 50%, rgba(240, 230, 255, 0.86) 100%);
}
.btn:not(.btn-go) {
  box-shadow: var(--shadow-soft), 0 0 16px rgba(var(--neon-cyan), 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.98);
}
.btn-go {
  background:
    radial-gradient(120% 96% at 50% -34%, rgba(255,255,255,0.90) 0%, rgba(255,255,255,0) 58%),
    linear-gradient(180deg, #c48cff 0%, #9b4dff 47%, #5a12b0 50%, #8a3af0 100%);
  box-shadow:
    0 10px 26px rgba(var(--neon-cyan), 0.5),
    0 0 26px rgba(var(--neon-cyan), 0.55),
    0 0 60px rgba(var(--neon-cyan), 0.24),
    inset 0 1px 0 rgba(255, 255, 255, 0.85);
}
.btn-go:hover {
  box-shadow:
    0 14px 34px rgba(var(--neon-cyan), 0.6),
    0 0 38px rgba(var(--neon-cyan), 0.8),
    0 0 90px rgba(var(--neon-cyan), 0.36),
    inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

/* The badge keeps pink: it is the one place the secondary colour shouts. */
.badge {
  /* the first cut of this was lighter and put white text at 3.3:1 */
  background: linear-gradient(180deg, #ea36ae 0%, #c90d86 45%, #86005c 100%);
  box-shadow: 0 4px 14px rgba(255, 90, 200, 0.45), inset 0 1px 0 rgba(255,255,255,0.6);
}
.badge::before { background: var(--lime); box-shadow: 0 0 8px rgba(184, 255, 30, 0.8); }

.site-footer {
  background: linear-gradient(180deg, rgba(246, 236, 255, 0.46) 0%, rgba(246, 236, 255, 0.72) 100%);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .site-footer {
    background: linear-gradient(180deg, rgba(30, 12, 50, 0.6) 0%, rgba(30, 12, 50, 0.88) 100%);
  }
}

/* Links inside panes were pink ink; they follow the lead colour now. */
.win-body a:not(.btn):not(.catalogue a) { color: var(--purple-ink); }

/* Gold leaf survives on hairlines only, and it cools a touch toward the
   lilac around it, so it reads as brass rather than as trumpet. */
:root {
  --gold-1: #fff0d0; --gold-2: #e2b04a; --gold-3: #8a5a22;
}

/* --------------------------------------------------------------------------
   4. THE HERO: rose window re-keyed, columns either side, glyphs beneath
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  padding-top: clamp(3rem, 9vw, 5.4rem);
  padding-bottom: clamp(2.4rem, 7vw, 4.2rem);
}

.rose {
  background-image: url("../img/rose-window-purple.webp");
  opacity: 0.58;
  filter:
    saturate(1.1)
    drop-shadow(0 0 40px rgba(var(--neon-cyan), 0.55))
    drop-shadow(0 0 100px rgba(var(--neon-pink), 0.30));
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .rose { opacity: 0.7; }
}

/* The wordmark halo goes violet under pink. */
.wordmark::before {
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.95),
    0 2px 2px rgba(var(--neon-cyan), 0.7),
    0 0 16px rgba(255, 255, 255, 0.5),
    0 0 34px rgba(var(--neon-cyan), 0.75),
    0 0 74px rgba(var(--neon-pink), 0.42),
    0 0 120px rgba(var(--neon-cyan), 0.28),
    0 14px 34px rgba(40, 8, 80, 0.55);
}
.wm-fill {
  background: linear-gradient(180deg, #ffffff 0%, #f8f0ff 32%, #e2ccff 48%, #ffffff 51%, #f2e6ff 72%, #d4b4ff 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

/* Two columns, one each side of the wordmark, standing on the hero floor.
   Real renders, so they get a real drop shadow and a slight lean toward
   the centre. Under 900px they leave: on a phone they would be sandwiched
   against the letters. */
.pillar {
  position: absolute;
  /* Sized from the hero's height, not from the viewport width: the first
     cut gave them a width and let the aspect ratio set the height, and at
     1280px they stood taller than the hero and ran up under the ticker. */
  top: clamp(0.4rem, 2vw, 1.2rem);
  bottom: clamp(0.4rem, 2vw, 1.2rem);
  width: auto;
  aspect-ratio: 389/782;
  background: url("../img/3d/column.webp") center / contain no-repeat;
  filter: drop-shadow(0 22px 28px rgba(58, 14, 110, 0.35));
  pointer-events: none;
  z-index: 0;
}
.pillar.left  { left: max(0.5rem, calc(50% - 30rem)); transform: rotate(-2deg); }
.pillar.right { right: max(0.5rem, calc(50% - 30rem)); transform: rotate(2deg) scaleX(-1); }
.wordmark { z-index: 1; }
@media (max-width: 900px) { .pillar { display: none; } }

/* The glyph strip. The eleven signs, repeated across the whole width as a
   frieze, just under the hero and again above the footer. */
.frieze {
  height: clamp(26px, 3.4vw, 40px);
  margin: 0 0 clamp(1.4rem, 4vw, 2.4rem);
  background: url("../img/3d/glyphs.webp") center / auto 100% repeat-x;
  opacity: 0.82;
  filter: drop-shadow(0 4px 8px rgba(58, 14, 110, 0.25));
  pointer-events: none;
}
.frieze.foot { margin: clamp(1.4rem, 4vw, 2.4rem) 0 0; }

/* --------------------------------------------------------------------------
   5. THE NEW SINGLE: the cover sits on the checkerboard plinth
   -------------------------------------------------------------------------- */

.single-grid { position: relative; }

/* The wet-floor reflection under the cover said glass. It goes. */
.single-art { -webkit-box-reflect: none; margin-bottom: 0; }

.single-stage {
  position: relative;
  display: block;
  padding-bottom: clamp(2.2rem, 9vw, 4.2rem);   /* room for the plinth below the cover */
}
.plinth {
  position: absolute;
  /* pushed a little right of centre: the pane clips whatever crosses its
     left edge, and the grid gap on the right has room to spare */
  left: 55%;
  bottom: -2%;
  width: 108%;
  aspect-ratio: 1100/517;
  transform: translateX(-50%);
  background: url("../img/3d/checker.webp") center / contain no-repeat;
  filter: drop-shadow(0 26px 30px rgba(58, 14, 110, 0.35));
  pointer-events: none;
  z-index: 0;
}
.single-stage .single-art {
  position: relative;
  z-index: 1;
  width: 78%;
  margin-inline: auto;
  filter: drop-shadow(0 22px 24px rgba(40, 8, 80, 0.45));
}

/* --------------------------------------------------------------------------
   6. LISTEN: the swirl peeks over the corner
   -------------------------------------------------------------------------- */

.win-wrap { position: relative; }
.mascot {
  position: absolute;
  right: -3rem;
  top: -5.6rem;
  width: clamp(200px, 24vw, 340px);
  aspect-ratio: 900/536;
  background: url("../img/3d/swirl.webp") center / contain no-repeat;
  filter: drop-shadow(0 18px 24px rgba(58, 14, 110, 0.32));
  pointer-events: none;
  z-index: 2;
  animation: mascot-bob 7s ease-in-out infinite;
}
@keyframes mascot-bob {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-8px) rotate(-1.5deg); }
}
@media (max-width: 900px) { .mascot { display: none; } }

/* --------------------------------------------------------------------------
   7. ABOUT: the portrait stands in the doorway of the arch
   -------------------------------------------------------------------------- */

/* Everything here is sized from one number, the portrait's height, so
   the figure always stands on the top step and always fits inside the
   opening. Measured off the render: the top platform sits about 39% of the way
   up the arch, and the opening clears the head at 2.05 portrait heights. */
.about-portrait {
  --ph: clamp(190px, 26vw, 290px);
  /* headroom for the arch: it stands 2.05 portraits tall and the portrait
     plus its step is 1.79, so the figure has to reserve the difference */
  padding: calc(var(--ph) * 0.3) 0 0;
}
.doorway {
  position: absolute;
  left: 50%;
  bottom: 0;
  height: calc(var(--ph) * 2.05);
  width: auto;
  aspect-ratio: 659/1000;
  transform: translateX(-50%);
  background: url("../img/3d/arch.webp") center bottom / contain no-repeat;
  filter: drop-shadow(0 26px 34px rgba(58, 14, 110, 0.35));
  pointer-events: none;
  z-index: 0;
}
.reliquary {
  position: relative;
  z-index: 1;
  padding: 0;
  background: none;
  clip-path: none;
  border-radius: 999px 999px 14px 14px;
  overflow: hidden;
  box-shadow: 0 18px 24px rgba(40, 8, 80, 0.45), inset 0 0 0 4px rgba(255, 255, 255, 0.85);
  margin-bottom: calc(var(--ph) * 0.79);
  /* the arch is drawn in perspective, so its opening sits left of the
     image's centre line */
  transform: translateX(-4%);
}
.reliquary img {
  height: var(--ph);
  clip-path: none;
  border-radius: 999px 999px 14px 14px;
  animation-name: reliquary-hue-purple;
}
/* The portrait used to swing from pink through cyan. Cyan is the one colour
   this pass removed, so it now swings from pink to violet and back. */
@keyframes reliquary-hue-purple {
  0%   { filter: saturate(1.25) hue-rotate(0deg); }
  50%  { filter: saturate(1.4) hue-rotate(-38deg); }
  100% { filter: saturate(1.25) hue-rotate(0deg); }
}
/* The four sparks around the frame were part of the gold reliquary. */
.about-portrait .spark { display: none; }

/* --------------------------------------------------------------------------
   8. HEADING GLOWS, re-keyed to violet under pink
   -------------------------------------------------------------------------- */

.single-title, .catalogue h3, .win-title {
  text-shadow:
    0 0 9px rgba(var(--neon-cyan), 0.40),
    0 0 22px rgba(var(--neon-cyan), 0.20),
    0 0 34px rgba(var(--neon-pink), 0.14);
}

/* --------------------------------------------------------------------------
   9. MOTION AND SMALL SCREENS
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .clouds span, .mascot { animation: none; }
}

@media (max-width: 780px) {
  .clouds .c3 { display: none; }
  .clouds .c1 { width: 46vw; top: 6%; }
  .clouds .c4 { width: 40vw; }
  .frieze { height: 24px; }
  .single-stage .single-art { width: 84%; }
}

@media print {
  .clouds, .frieze, .pillar, .mascot, .plinth, .doorway { display: none; }
}

/* --------------------------------------------------------------------------
   10. PICTURE FRAMES
   Gold leaf on the covers read as brass on lavender. The pictures get the
   same white clay rim as the panes instead, so the renders, the panes and
   the covers are all one material.
   -------------------------------------------------------------------------- */
.single-art img,
.catalogue img {
  border: 4px solid rgba(255, 255, 255, 0.92);
  border-image: none;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 1px rgba(162, 77, 255, 0.28), 0 14px 26px rgba(58, 14, 110, 0.30);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .single-art img,
  :root:not([data-theme="light"]) .catalogue img {
    border-color: rgba(230, 210, 255, 0.5);
    box-shadow: 0 0 0 1px rgba(184, 119, 255, 0.4), 0 14px 26px rgba(0, 0, 0, 0.5);
  }
}

/* --------------------------------------------------------------------------
   11. PILLS AGAIN
   The medieval pass squared the buttons and the badge off and gave them
   gold leaf. Clay wants them round and rimmed in white, which is also what
   the renders' edges look like.
   -------------------------------------------------------------------------- */
.btn, .badge {
  border-radius: 999px;
  border: 2px solid rgba(255, 255, 255, 0.9);
  border-image: none;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn, :root:not([data-theme="light"]) .badge {
    border-color: rgba(230, 210, 255, 0.45);
  }
}

/* Dark-mode buttons: aero.css restates these under a dark selector with
   higher specificity than the light rules above, so they have to be
   restated here too or the old teal and pink come back at night. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn {
    color: var(--ink);
    border-color: rgba(230, 210, 255, 0.45);
    background: linear-gradient(180deg, rgba(88, 44, 140, 0.95) 0%, rgba(66, 30, 110, 0.72) 48%, rgba(52, 22, 90, 0.6) 52%, rgba(80, 40, 130, 0.9) 100%);
  }
  :root:not([data-theme="light"]) .btn-go {
    color: #fff;
    background:
      radial-gradient(120% 96% at 50% -34%, rgba(255,255,255,0.55) 0%, rgba(255,255,255,0) 58%),
      linear-gradient(180deg, #c48cff 0%, #9b4dff 47%, #6a1fd0 50%, #9a52ff 100%);
  }
  :root:not([data-theme="light"]) .taskbar nav a:hover {
    background: linear-gradient(180deg, var(--purple) 0%, var(--purple-deep) 100%);
    color: #fff;
  }
}

/* Footer links measured 4.38:1 in light, pink ink on lavender. Violet ink. */
.footer-links a { color: var(--purple-ink); }

/* ==========================================================================
   12. LUNA
   Purple Windows XP. Everything in aero.css that said "wet" is switched
   off here and replaced with the plastic-clay of the Luna theme: a thick
   coloured frame around every window, a saturated title bar with one soft
   light along its top edge, matte buttons with a one-pixel highlight, a
   lime Start button. No glass, no blur, no specular streak, no sweep, no
   reflection, no glow. Light comes from above and stops there.

   The rose window goes too: it was the stained-glass idea, and the renders
   are not stained glass.
   ========================================================================== */

:root {
  --xp-frame:  #8b56e8;
  --xp-frame-dark: #5e2ab0;
  --xp-body:   rgba(247, 240, 255, 0.97);
  --xp-bar-hi: #b993ff;
  --xp-bar-1:  #9463f2;
  --xp-bar-2:  #7c44dc;
  --xp-bar-3:  #7036ca;
  --xp-btn-1:  #ffffff;
  --xp-btn-2:  #f0e4ff;
  --xp-btn-3:  #dfc9ff;
  --xp-go-1:   #a878ff;
  --xp-go-2:   #7a3fd1;
  --xp-go-3:   #6427b8;
  --xp-start-1: #dcff7a;
  --xp-start-2: #b8ff1e;
  --xp-start-3: #8fd400;
  --xp-start-ink: #1e3a00;
  --xp-start-edge: #6ea300;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --xp-frame:  #6b3ab0;
    --xp-frame-dark: #3f1a78;
    --xp-body:   rgba(40, 18, 66, 0.97);
    --xp-bar-hi: #a279ff;
    --xp-bar-1:  #7a48d8;
    --xp-bar-2:  #5e2fb8;
    --xp-bar-3:  #4d229c;
    --xp-btn-1:  #6a3cc0;
    --xp-btn-2:  #56309e;
    --xp-btn-3:  #47268a;
  }
}

/* ---- gone --------------------------------------------------------------- */
.rose, .caustics, .win::after, .win-bar::before, .win-bar::after,
.btn::after, .single-art::after, .wordmark::after, .glimmer { display: none; }
.bokeh { opacity: 0.32; }
/* Chromium does not accept `none` for -webkit-box-reflect at all, and
   CSS.supports() confirms it: the declaration is dropped and the
   reflection stays. (The phone rule in aero.css that tries the same thing
   has therefore never worked.) A reflection through a fully transparent
   mask paints nothing, which is the same result by a door that opens. */
.wordmark, .single-art img, .catalogue img {
  -webkit-box-reflect: below 0px linear-gradient(transparent, transparent);
}
.hero { padding-top: clamp(2.2rem, 7vw, 4rem); }

/* ---- windows ------------------------------------------------------------ */
.win {
  border: 4px solid var(--xp-frame);
  outline: none;
  border-radius: 14px;
  background: var(--xp-body);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow:
    0 16px 34px rgba(58, 14, 110, 0.30),
    inset 0 0 0 1px rgba(255, 255, 255, 0.7);
}
.win::before {
  background:
    url("../img/grain.webp") 0 0 / 160px 160px repeat,
    url("../img/butterflies.webp") 0 0 / 150px 150px repeat;
  background-blend-mode: normal;
  opacity: 0.16;
  mix-blend-mode: multiply;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .win { box-shadow: 0 16px 34px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.12); }
  :root:not([data-theme="light"]) .win::before { mix-blend-mode: soft-light; opacity: 0.22; }
}

.win-bar {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--xp-frame-dark);
  background: linear-gradient(180deg, var(--xp-bar-hi) 0%, var(--xp-bar-1) 10%, var(--xp-bar-2) 58%, var(--xp-bar-3) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
.win-title { color: #fff; text-shadow: 0 1px 1px rgba(40, 8, 80, 0.6); }
.win-title .orb,
.taskbar .brand::before {
  background: radial-gradient(circle at 35% 30%, #f4ffd0 0%, var(--lime) 45%, #74b000 100%);
  box-shadow: 0 1px 2px rgba(40, 8, 80, 0.5), inset 0 -1px 1px rgba(0, 0, 0, 0.15);
}
.win-chrome i {
  width: 24px; height: 20px;
  border-radius: 5px;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: linear-gradient(180deg, #b48cff 0%, #8a55ea 50%, #7a44d8 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 1px 2px rgba(40, 8, 80, 0.4);
}
.win-chrome i:last-child {
  background: linear-gradient(180deg, #ff8ad8 0%, #e6299f 50%, #c20f84 100%);
  border-color: rgba(255, 255, 255, 0.6);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 1px 2px rgba(40, 8, 80, 0.4);
}

/* ---- taskbar: the blue bar, in violet, with a lime Start ---------------- */
.taskbar {
  background: linear-gradient(180deg, #a57cf7 0%, #7d47dd 14%, #6a32ca 86%, #5a25ae 100%);
  border-bottom: 1px solid #4a1a9a;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: 0 3px 10px rgba(40, 8, 80, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.taskbar .brand { color: #fff; text-shadow: 0 1px 1px rgba(40, 8, 80, 0.6); }
.taskbar nav a {
  color: var(--xp-start-ink);
  font-weight: 800;
  background: linear-gradient(180deg, var(--xp-start-1) 0%, var(--xp-start-2) 48%, var(--xp-start-3) 100%);
  border: 1px solid var(--xp-start-edge);
  border-radius: 999px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 2px 5px rgba(20, 0, 50, 0.35);
  text-shadow: none;
}
.taskbar nav a:hover {
  background: linear-gradient(180deg, #eaffa0 0%, #ccff4a 48%, #a2e800 100%);
  color: var(--xp-start-ink);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .taskbar {
    background: linear-gradient(180deg, #7a48d8 0%, #5a2bb8 14%, #48209a 86%, #3a1680 100%);
  }
  :root:not([data-theme="light"]) .taskbar nav a,
  :root:not([data-theme="light"]) .taskbar nav a:hover {
    background: linear-gradient(180deg, var(--xp-start-1) 0%, var(--xp-start-2) 48%, var(--xp-start-3) 100%);
    color: var(--xp-start-ink);
    border-color: var(--xp-start-edge);
  }
}

.ticker {
  background: linear-gradient(180deg, #8452e6 0%, #6b2fc0 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 2px 6px rgba(40, 8, 80, 0.3);
}
.ticker span { text-shadow: 0 1px 1px rgba(40, 8, 80, 0.5); }

/* ---- buttons ------------------------------------------------------------ */
.btn, .badge {
  border-radius: 10px;
  border: 1px solid var(--xp-frame);
  background: linear-gradient(180deg, var(--xp-btn-1) 0%, var(--xp-btn-2) 50%, var(--xp-btn-3) 100%);
  color: var(--ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 2px 4px rgba(58, 14, 110, 0.20);
  transition: transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
}
.btn:not(.btn-go) { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 2px 4px rgba(58, 14, 110, 0.20); }
/* XP lit a hovered button with an orange ring. Ours is lime. */
.btn:hover, .btn:focus-visible {
  border-color: var(--xp-start-edge);
  box-shadow: 0 0 0 2px rgba(184, 255, 30, 0.6), 0 3px 6px rgba(58, 14, 110, 0.22);
  transform: translateY(-1px);
}
.btn-go {
  color: #fff;
  border-color: var(--xp-frame-dark);
  background: linear-gradient(180deg, var(--xp-go-1) 0%, var(--xp-go-2) 52%, var(--xp-go-3) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), 0 3px 6px rgba(58, 14, 110, 0.32);
  text-shadow: 0 1px 1px rgba(40, 8, 80, 0.5);
}
.btn-go:hover {
  color: #fff;
  box-shadow: 0 0 0 2px rgba(184, 255, 30, 0.6), 0 4px 8px rgba(58, 14, 110, 0.32);
}
.badge {
  color: #fff;
  border-color: #8e005f;
  background: linear-gradient(180deg, #f34fb9 0%, #c90d86 55%, #96006a 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), 0 2px 4px rgba(90, 0, 60, 0.3);
  text-shadow: 0 1px 1px rgba(60, 0, 40, 0.4);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn {
    color: var(--ink);
    border-color: var(--xp-frame);
    background: linear-gradient(180deg, var(--xp-btn-1) 0%, var(--xp-btn-2) 50%, var(--xp-btn-3) 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 2px 4px rgba(0, 0, 0, 0.4);
  }
  :root:not([data-theme="light"]) .btn-go {
    color: #fff;
    background: linear-gradient(180deg, var(--xp-go-1) 0%, var(--xp-go-2) 52%, var(--xp-go-3) 100%);
  }
}

/* ---- the wordmark: clay letters, extruded, no gloss --------------------- */
.wordmark::before {
  color: #d3b3ff;
  text-shadow:
    0 2px 0 #c49dff,
    0 4px 0 #b085f7,
    0 6px 0 #9c6eea,
    0 8px 0 #8859d6,
    0 10px 0 #7647c2,
    0 18px 26px rgba(58, 14, 110, 0.42);
}
.wm-fill {
  background: linear-gradient(180deg, #ffffff 0%, #f6eeff 55%, #e9d9ff 100%);
  -webkit-background-clip: text;
  background-clip: text;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wordmark::before {
    text-shadow:
      0 2px 0 #a37cf5, 0 4px 0 #8b61e0, 0 6px 0 #744bc8, 0 8px 0 #5f38ad, 0 10px 0 #4b2890,
      0 18px 26px rgba(0, 0, 0, 0.6);
  }
}

/* ---- headings: a shadow, not a glow ------------------------------------ */
.single-title, .catalogue h3 {
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.55), 0 2px 5px rgba(58, 14, 110, 0.18);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .single-title,
  :root:not([data-theme="light"]) .catalogue h3 { text-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); }
}

/* ---- pictures: a frame the colour of the window frame ------------------- */
.single-art img, .catalogue img {
  border: 3px solid rgba(255, 255, 255, 0.95);
  box-shadow: 0 0 0 2px var(--xp-frame), 0 10px 20px rgba(58, 14, 110, 0.28);
  border-radius: 10px;
}
.reliquary { box-shadow: 0 18px 24px rgba(40, 8, 80, 0.45), inset 0 0 0 4px rgba(255, 255, 255, 0.9); }

/* ---- bubbles become marbles, and half of them leave --------------------- */
.bubble, .bubble.pinkish {
  background: radial-gradient(circle at 36% 30%, #ffffff 0%, #f7e4ff 22%, #dcb4ff 58%, #a97be6 100%);
  box-shadow: 0 6px 12px rgba(58, 14, 110, 0.22);
}
.bubble:nth-child(2n) { display: none; }

/* ---- footer ------------------------------------------------------------- */
.site-footer {
  background: var(--xp-body);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-top: 4px solid var(--xp-frame);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .site-footer { background: var(--xp-body); }
}

/* Gold leaf lived in border-image on the taskbar, the title bar and the
   title itself. The border shorthand above resets it on .win; these three
   were set with longhands and kept their leaf. */
.taskbar, .ticker, .win-bar, .win-title, .tagline { border-image: none; }
.taskbar { border-bottom: 1px solid #4a1a9a; }
.win-title { border-top: 0; border-bottom: 0; }

/* ==========================================================================
   13. ROUND THREE
   The door floats instead of framing the portrait. Clouds come forward.
   Two more pairs of columns. Glow comes off the words. The buttons get
   the Luna bevel, chunky enough to want to press.
   ========================================================================== */

/* ---- the portrait, back in a plain clay frame -------------------------- */
.about-portrait { padding: 0; --ph: clamp(210px, 28vw, 320px); }
.reliquary {
  transform: none;
  margin-bottom: 0;
  border-radius: 999px 999px 14px 14px;
  border: 4px solid var(--xp-frame);
  box-shadow: 0 14px 26px rgba(40, 8, 80, 0.4), inset 0 0 0 3px rgba(255, 255, 255, 0.95);
  padding: 3px;
  background: #fff;
}
.reliquary img { height: var(--ph); border-radius: 999px 999px 10px 10px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .reliquary { background: #2a1444; box-shadow: 0 14px 26px rgba(0,0,0,.5), inset 0 0 0 3px rgba(255,255,255,.25); }
}

/* ---- the door floats by the Contact window, like the swirl ------------ */
.win-wrap-contact { --side: clamp(0px, 4vw, 3rem); }
.portal {
  /* floats over the empty right half of the Contact pane, clear of the
     links on the left and the chrome buttons at the top right */
  position: absolute;
  right: 7rem;
  bottom: -2.6rem;
  height: clamp(200px, 22vw, 320px);
  aspect-ratio: 659/1000;
  background: url("../img/3d/arch.webp") center / contain no-repeat;
  filter: drop-shadow(0 22px 30px rgba(58, 14, 110, 0.35));
  pointer-events: none;
  z-index: 2;
  animation: portal-float 9s ease-in-out infinite;
}
@keyframes portal-float {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50%      { transform: translateY(-14px) rotate(2deg); }
}

/* ---- columns by the Contact window, standing on its bottom edge ------- */
.pillar-c {
  position: absolute;
  bottom: -0.6rem;
  height: clamp(150px, 16vw, 230px);
  aspect-ratio: 389/782;
  background: url("../img/3d/column.webp") center / contain no-repeat;
  filter: drop-shadow(0 18px 24px rgba(58, 14, 110, 0.35));
  pointer-events: none;
  z-index: 2;
}
.pillar-c.left  { left: -3.2rem; transform: rotate(-3deg); }
.pillar-c.right { right: -3.2rem; transform: rotate(3deg) scaleX(-1); }

/* ---- the hero's second, farther pair --------------------------------- */
.pillar.far {
  /* shorter and paler: a second rank of columns further back */
  top: clamp(2.6rem, 8vw, 5rem);
  bottom: clamp(0.8rem, 3vw, 1.8rem);
  opacity: 0.8;
  filter: drop-shadow(0 16px 20px rgba(58, 14, 110, 0.3)) brightness(0.96);
}
.pillar.left.far  { left: max(0.5rem, calc(50% - 39rem)); transform: rotate(-4deg); }
.pillar.right.far { right: max(0.5rem, calc(50% - 39rem)); transform: rotate(4deg) scaleX(-1); }
@media (max-width: 1180px) { .pillar.far { display: none; } }

/* ---- clouds in front: one per window, over a corner with no text ------- */
.fcloud {
  position: absolute;
  aspect-ratio: 457/306;
  background-size: contain;
  background-repeat: no-repeat;
  filter: drop-shadow(0 16px 26px rgba(58, 14, 110, 0.32));
  pointer-events: none;
  z-index: 3;
  animation: fcloud-float 11s ease-in-out infinite;
}
.fcloud.fc1 { background-image: url("../img/3d/cloud-3.webp"); aspect-ratio: 450/328; width: clamp(140px, 17vw, 250px); right: -4.5rem; bottom: -2.6rem; }
.fcloud.fc2 { background-image: url("../img/3d/cloud-1.webp"); width: clamp(150px, 19vw, 280px); left: -5rem; bottom: -3rem; animation-delay: -4s; }
.fcloud.fc3 { background-image: url("../img/3d/cloud-4.webp"); aspect-ratio: 550/397; width: clamp(150px, 18vw, 260px); left: -4.5rem; bottom: -2.4rem; animation-delay: -7s; }
.fcloud.fc4 { background-image: url("../img/3d/cloud-2.webp"); aspect-ratio: 440/368; width: clamp(110px, 13vw, 180px); left: 46%; bottom: -3.2rem; animation-delay: -2s; }
@keyframes fcloud-float {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(10px, -10px); }
}
/* Where a front cloud would land on the buttons on a phone, it goes. */
@media (max-width: 780px) {
  .fcloud.fc2, .fcloud.fc4, .pillar-c, .portal { display: none; }
  .fcloud.fc1 { width: 34vw; right: -3rem; bottom: -2rem; }
  .fcloud.fc3 { width: 36vw; left: -3rem; bottom: -1.6rem; }
}

/* ---- glow off the words ------------------------------------------------- */
.single-title, .catalogue h3, .single-meta, .year, .illuminated, .badge,
.btn, .btn-go, .ticker span, .footer-links a, .win-body p, .win-body h2, .win-body h3, .win-body a,
.taskbar .brand { text-shadow: none; }
/* Luna keeps one: white title text with a one-pixel shadow on the bar. */
.win-title, .taskbar .brand { text-shadow: 0 1px 1px rgba(40, 8, 80, 0.55); }
.wordmark::before {
  text-shadow:
    0 2px 0 #c49dff, 0 4px 0 #b085f7, 0 6px 0 #9c6eea, 0 8px 0 #8859d6, 0 10px 0 #7647c2,
    0 12px 14px rgba(58, 14, 110, 0.32);
}

/* ---- the Luna bevel ----------------------------------------------------- */
.win-chrome { gap: 4px; }
.win-chrome i {
  width: 22px; height: 22px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  border: 1px solid #4f1f9e;
  background: linear-gradient(180deg, #d0b4ff 0%, #a77cff 18%, #8a55ea 56%, #6f37cc 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    inset 0 -1px 0 rgba(40, 8, 80, 0.35),
    inset 1px 0 0 rgba(255, 255, 255, 0.3),
    0 1px 2px rgba(40, 8, 80, 0.45);
  text-shadow: 0 1px 1px rgba(40, 8, 80, 0.5);
}
.win-chrome i:last-child {
  border-color: #8e0060;
  background: linear-gradient(180deg, #ffb0e4 0%, #ff6fd0 18%, #e6299f 56%, #b8067f 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    inset 0 -1px 0 rgba(90, 0, 60, 0.35),
    0 1px 2px rgba(40, 8, 80, 0.45);
}
.win-chrome i:nth-child(1)::before { content: "\2013"; }
.win-chrome i:nth-child(2)::before { content: "\25A1"; }
.win-chrome i:nth-child(3)::before { content: "\2715"; }

.btn, .badge {
  border-radius: 8px;
  border: 1px solid #6f3fc4;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -2px 0 rgba(111, 63, 196, 0.22),
    inset 1px 0 0 rgba(255, 255, 255, 0.5),
    0 2px 0 #b899ee,
    0 3px 5px rgba(58, 14, 110, 0.25);
  background: linear-gradient(180deg, #ffffff 0%, #f4ebff 45%, #e9dbff 55%, #dcc8ff 100%);
}
.btn:not(.btn-go) { box-shadow: inset 0 1px 0 rgba(255,255,255,.95), inset 0 -2px 0 rgba(111,63,196,.22), 0 2px 0 #b899ee, 0 3px 5px rgba(58,14,110,.25); }
.btn:hover, .btn:focus-visible {
  transform: translateY(-1px);
  border-color: var(--xp-start-edge);
  box-shadow: 0 0 0 2px rgba(184, 255, 30, 0.65), 0 3px 0 #b899ee, 0 4px 6px rgba(58, 14, 110, 0.25);
}
.btn:active { transform: translateY(1px); box-shadow: inset 0 2px 3px rgba(58, 14, 110, 0.25), 0 0 0 2px rgba(184, 255, 30, 0.5); }
.btn-go {
  border-color: #4f1f9e;
  background: linear-gradient(180deg, #c7a4ff 0%, #a070ff 16%, #7a3fd1 56%, #6224b4 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -2px 0 rgba(40, 8, 80, 0.3),
    0 2px 0 #4a1a90,
    0 3px 6px rgba(58, 14, 110, 0.35);
  text-shadow: 0 1px 1px rgba(40, 8, 80, 0.5);
}
.btn-go:hover { box-shadow: 0 0 0 2px rgba(184, 255, 30, 0.65), 0 3px 0 #4a1a90, 0 4px 8px rgba(58, 14, 110, 0.35); }
.badge {
  border-color: #8e005f;
  background: linear-gradient(180deg, #ff8ad8 0%, #f34fb9 16%, #c90d86 56%, #96006a 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), inset 0 -2px 0 rgba(90, 0, 60, 0.3), 0 2px 0 #7a004f, 0 3px 5px rgba(90, 0, 60, 0.3);
  text-shadow: 0 1px 1px rgba(60, 0, 40, 0.4);
}
.taskbar nav a {
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.75), inset 0 -2px 0 rgba(60, 100, 0, 0.35), 0 2px 0 #5a8a00, 0 3px 5px rgba(20, 0, 50, 0.4);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn {
    border-color: #3f1a78;
    background: linear-gradient(180deg, #8a5ce0 0%, #6a3cc0 45%, #5a30a8 55%, #47268a 100%);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.3), inset 0 -2px 0 rgba(0,0,0,.3), 0 2px 0 #2c1160, 0 3px 5px rgba(0,0,0,.45);
  }
  :root:not([data-theme="light"]) .btn-go {
    background: linear-gradient(180deg, #c7a4ff 0%, #a070ff 16%, #7a3fd1 56%, #6224b4 100%);
  }
}

/* Furniture that overhangs the panes must not widen the page. clip, not
   hidden: clip does not create a scroll container, so nothing about
   scrolling or sticky positioning changes. */
main { overflow-x: clip; }

/* ==========================================================================
   14. MORNING LIST, 2026-09-02
   ========================================================================== */

/* The static bubbles: the out-of-focus bokeh field. It barely moved, and
   against clouds that actually drift it read as a stain on the sky. The
   small rising marbles stay; they move. */
.bokeh { display: none; }

/* The cloud over the corner of the Listen window, beside the swirl. */
.fcloud.fc2 { display: none; }

/* The rightmost column beside Contact & Follow. The left one stays. */
.pillar-c.right { display: none; }

/* The artist credit, under the copyright line. Quiet, but not hidden. */
.credit {
  margin: 0.35rem 0 0;
  font-size: 0.86rem;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}

/* ==========================================================================
   15. HIS FONTS
   Lemon Popsicle for the wordmark, his pick. Pirata One in the slot the
   gothic held (titles, headings, buttons, nav, the drop cap), his pick from
   the open-licence options after two FontSpace downloads failed the
   licence check: Libra (fsType 2, conversion forbidden, commercial fee)
   and Black Castle MF (fsType 2, all rights reserved, no author licence).
   Pirata One is SIL OFL and the nearest open match to Black Castle.

   Lemon Popsicle: designer Warung Grafis 62, fsType 0 (installable), the
   designer's own listing says unrestricted commercial use. Converted from
   the supplied OTF to WOFF2, 19 KB.
   ========================================================================== */

@font-face {
  font-family: "Lemon Popsicle";
  font-style: normal; font-weight: 400; font-display: swap;
  src: url("../fonts/lemon-popsicle-400-normal.woff2") format("woff2");
}

:root {
  --display:      "Lemon Popsicle", "Grenze Gotisch", serif;
  --gothic:       "Pirata One", "Grenze Gotisch", Palatino, serif;
  --black-letter: "Pirata One", "Grenze Gotisch", serif;
}

/* Lemon Popsicle is wide and heavy, so the wordmark comes down a size and
   the clay extrusion gets a touch deeper to match the letter weight. */
.wordmark {
  font-size: clamp(2.6rem, 9.6vw, 5.5rem);
  letter-spacing: 0.02em;
  line-height: 1.05;
}
.wordmark::before {
  text-shadow:
    0 2px 0 #c49dff, 0 4px 0 #b085f7, 0 6px 0 #9c6eea, 0 8px 0 #8859d6, 0 10px 0 #7647c2, 0 12px 0 #66399f,
    0 14px 16px rgba(58, 14, 110, 0.32);
}

/* Pirata One is condensed, so it can run a touch larger than the gothic
   did and still fit the same title bars and buttons. */
.win-title { font-size: 1.1rem; letter-spacing: 0.03em; }
.btn { font-size: 1.06rem; letter-spacing: 0.02em; }
.single-title { letter-spacing: 0.01em; }
.taskbar nav a { font-family: var(--gothic); }
.illuminated::first-letter { font-size: 3.6em; }

/* ==========================================================================
   16. NO TASKBAR
   The header (brand and Press Kit) is gone; the Press Kit button moves to
   the footer. The ticker is now the top of the page, so it takes the
   sticky role and the top edge treatment the taskbar had.
   ========================================================================== */
.ticker {
  position: sticky;
  top: 0;
  z-index: 40;
  border-bottom: 1px solid #4a1a9a;
}
.footer-press { justify-content: center; margin: 0 0 0.9rem; }
.footer-press .btn { min-width: 11rem; justify-content: center; }
.site-footer .footer-links { margin-bottom: 1rem; }

/* The plinth's right lobe was reaching toward the Spotify button. Centred
   under the cover, no wider than the cover's column. */
.plinth { left: 50%; width: 100%; }

/* ==========================================================================
   17. CLOUDS, AGAIN
   ========================================================================== */

/* The front cloud that sat on Now Playing's bottom-right corner was, one
   window down, sitting on the swirl. It is now centred under the Listen
   window, floating over the gap between Listen and About. `translate`
   does the centring so the float animation can keep `transform`. */
.fcloud.fc5 {
  background-image: url("../img/3d/cloud-3.webp");
  aspect-ratio: 450/328;
  width: clamp(150px, 18vw, 260px);
  left: 50%;
  translate: -50% 0;
  bottom: -4.2rem;
  animation-delay: -3s;
}
@media (max-width: 780px) { .fcloud.fc5 { width: 36vw; bottom: -2.6rem; } }

/* The background clouds drift so slowly they read as parked. A second
   animation on the `translate` property gives each one a slow bob on top
   of its drift, out of phase with its neighbours. */
.clouds span {
  animation-name: cloud-drift, cloud-bob;
  animation-timing-function: linear, ease-in-out;
  animation-iteration-count: infinite, infinite;
  animation-direction: alternate, alternate;
}
.clouds .c1 { animation-duration: 70s, 7s; }
.clouds .c2 { animation-duration: 95s, 9s; animation-direction: alternate-reverse, alternate; animation-delay: 0s, -3s; }
.clouds .c3 { animation-duration: 120s, 8s; animation-delay: 0s, -5s; }
.clouds .c4 { animation-duration: 84s, 10s; animation-direction: alternate-reverse, alternate; animation-delay: 0s, -1.5s; }
@keyframes cloud-bob {
  from { translate: 0 0; }
  to   { translate: 0 -14px; }
}
@media (prefers-reduced-motion: reduce) {
  .clouds span, .fcloud, .portal, .mascot { animation: none; }
}

/* ==========================================================================
   18. HIS PALETTE, HIS ROMAN
   Five colours from Jackson, 2026-09-02:

     #f8b4fe  pale pink-lilac   the pane tint, the wordmark fill, cloud light
     #8825b7  deep purple       the lead: frames, title bars, ticker, primary
     #1923f9  electric blue     links, the badge, focus rings
     #44fa09  lime              the dot, the Press Kit button, hover rings
     #d27cfd  orchid            the top light on every bar and button

   And Cinzel for everything the gothic and then Pirata held: Trajan's
   column capitals, which is the reference he named. Lemon Popsicle stays
   on the wordmark. Nunito stays for reading.
   ========================================================================== */

@font-face { font-family: "Cinzel"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/cinzel-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Cinzel"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/cinzel-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Cinzel"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/cinzel-latin-700-normal.woff2") format("woff2"); }

:root {
  --j-lilac:  #f8b4fe;
  --j-purple: #8825b7;
  --j-blue:   #1923f9;
  --j-lime:   #44fa09;
  --j-orchid: #d27cfd;

  --gothic:       "Cinzel", "Grenze Gotisch", Palatino, serif;
  --black-letter: "Cinzel", "Grenze Gotisch", serif;

  --purple:      var(--j-purple);
  --purple-deep: #6a1a91;
  --purple-ink:  var(--j-blue);         /* links: 7.4:1 on the pane */
  --lilac:       var(--j-orchid);
  --lavender:    #fdeeff;
  --lime:        var(--j-lime);

  --neon-cyan: 136, 37, 183;
  --neon-pink: 248, 180, 254;
  --neon-gold: 68, 250, 9;

  --ink:      #2c0f3d;
  --ink-soft: #5c2e78;
  --pink:      var(--j-orchid);
  --pink-ink:  #8a1fbd;
  --pink-bright: var(--j-lilac);        /* the cursor sparkles read this */

  --xp-frame:      var(--j-purple);
  --xp-frame-dark: #5e1580;
  --xp-body:       rgba(253, 238, 255, 0.97);
  --xp-bar-hi:     var(--j-orchid);
  --xp-bar-1:      #a445d6;
  --xp-bar-2:      var(--j-purple);
  --xp-bar-3:      #6f1d96;
  --xp-btn-1:      #ffffff;
  --xp-btn-2:      #fbe4ff;
  --xp-btn-3:      var(--j-lilac);
  --xp-go-1:       var(--j-orchid);
  --xp-go-2:       var(--j-purple);
  --xp-go-3:       #5e1580;
  --xp-start-1:    #b9ff9a;
  --xp-start-2:    var(--j-lime);
  --xp-start-3:    #2fc400;
  --xp-start-ink:  #113600;
  --xp-start-edge: #2a9e00;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --purple-ink:  #9ea3ff;            /* the blue, lifted for dark ground */
    --ink:      #fbeaff;
    --ink-soft: #d9b4e6;
    --xp-frame:      var(--j-purple);
    --xp-frame-dark: #3f0d5c;
    --xp-body:       rgba(44, 15, 61, 0.97);
    --xp-bar-hi:     var(--j-orchid);
    --xp-bar-1:      #8a2fbd;
    --xp-bar-2:      #6a1a91;
    --xp-bar-3:      #55146f;
    --xp-btn-1:      #7d2fae;
    --xp-btn-2:      #63208c;
    --xp-btn-3:      #501672;
  }
}

/* ---- sky ---------------------------------------------------------------- */
.sky {
  background:
    image-set(url("../img/sky-light-jackson.webp") type("image/webp")) center / cover no-repeat,
    linear-gradient(180deg, #5e1580 0%, var(--j-purple) 34%, var(--j-orchid) 62%, var(--j-lilac) 84%, #fdeeff 100%);
  background-attachment: fixed;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sky {
    background:
      image-set(url("../img/sky-dark-jackson.webp") type("image/webp")) center / cover no-repeat,
      linear-gradient(180deg, #14061e 0%, #3f0d5c 40%, #5e1580 70%, var(--j-purple) 100%);
    background-attachment: fixed;
  }
}
.aurora .a1 { background: radial-gradient(closest-side, rgba(248, 180, 254, 0.5), transparent); }
.aurora .a2 { background: radial-gradient(closest-side, rgba(210, 124, 253, 0.45), transparent); }
.aurora .a3 { background: radial-gradient(closest-side, rgba(25, 35, 249, 0.18), transparent); }

/* ---- chrome, re-keyed --------------------------------------------------- */
.win { border-color: var(--j-purple); }
.win-bar { border-bottom-color: var(--xp-frame-dark); }
.ticker {
  background: linear-gradient(180deg, #a445d6 0%, var(--j-purple) 55%, #6f1d96 100%);
  border-bottom-color: #5e1580;
}
.win-chrome i {
  border-color: #5e1580;
  background: linear-gradient(180deg, #e9b9ff 0%, var(--j-orchid) 18%, #a445d6 56%, var(--j-purple) 100%);
}
.win-chrome i:last-child {
  border-color: #0d14b0;
  background: linear-gradient(180deg, #9ea3ff 0%, #5a63ff 18%, var(--j-blue) 56%, #0d14b0 100%);
}
.site-footer { border-top-color: var(--j-purple); }

/* buttons: secondary is white to lilac, primary is orchid to purple */
.btn, .badge {
  border-color: var(--j-purple);
  background: linear-gradient(180deg, #ffffff 0%, #fbe4ff 45%, #f9d2ff 55%, var(--j-lilac) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.95), inset 0 -2px 0 rgba(136,37,183,.22), 0 2px 0 #c98be0, 0 3px 5px rgba(94,21,128,.25);
}
.btn:not(.btn-go) { box-shadow: inset 0 1px 0 rgba(255,255,255,.95), inset 0 -2px 0 rgba(136,37,183,.22), 0 2px 0 #c98be0, 0 3px 5px rgba(94,21,128,.25); }
.btn:hover, .btn:focus-visible {
  border-color: var(--xp-start-edge);
  box-shadow: 0 0 0 2px rgba(68, 250, 9, 0.7), 0 3px 0 #c98be0, 0 4px 6px rgba(94,21,128,.25);
}
.btn-go {
  border-color: #5e1580;
  background: linear-gradient(180deg, #e9b9ff 0%, var(--j-orchid) 14%, var(--j-purple) 56%, #6a1a91 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.55), inset 0 -2px 0 rgba(40,8,80,.3), 0 2px 0 #4a0f68, 0 3px 6px rgba(94,21,128,.35);
}
.btn-go:hover { box-shadow: 0 0 0 2px rgba(68, 250, 9, 0.7), 0 3px 0 #4a0f68, 0 4px 8px rgba(94,21,128,.35); }

/* the badge goes electric blue: the one place the blue shouts */
.badge {
  color: #fff;
  border-color: #0d14b0;
  background: linear-gradient(180deg, #8f95ff 0%, #4a53ff 16%, var(--j-blue) 56%, #0d14b0 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), inset 0 -2px 0 rgba(0,0,80,.3), 0 2px 0 #0a0f8a, 0 3px 5px rgba(0,0,80,.3);
}
.badge::before { background: var(--j-lime); box-shadow: 0 0 6px rgba(68, 250, 9, 0.8); }

/* the Press Kit button in the footer is the lime Start button */
.footer-press .btn {
  color: var(--xp-start-ink);
  border-color: var(--xp-start-edge);
  background: linear-gradient(180deg, var(--xp-start-1) 0%, var(--xp-start-2) 48%, var(--xp-start-3) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), inset 0 -2px 0 rgba(20,80,0,.35), 0 2px 0 #1f8a00, 0 3px 5px rgba(20,0,50,.35);
  text-shadow: none;
}
.footer-press .btn:hover { box-shadow: 0 0 0 2px rgba(136,37,183,.55), 0 3px 0 #1f8a00, 0 4px 6px rgba(20,0,50,.35); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn {
    background: linear-gradient(180deg, #9a45cc 0%, #7d2fae 45%, #6a1a91 55%, #55146f 100%);
    border-color: #3f0d5c;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.3), inset 0 -2px 0 rgba(0,0,0,.3), 0 2px 0 #2a0840, 0 3px 5px rgba(0,0,0,.45);
  }
  :root:not([data-theme="light"]) .btn-go { background: linear-gradient(180deg, #e9b9ff 0%, var(--j-orchid) 14%, var(--j-purple) 56%, #6a1a91 100%); }
  :root:not([data-theme="light"]) .footer-press .btn,
  :root:not([data-theme="light"]) .footer-press .btn:hover {
    color: var(--xp-start-ink);
    background: linear-gradient(180deg, var(--xp-start-1) 0%, var(--xp-start-2) 48%, var(--xp-start-3) 100%);
    border-color: var(--xp-start-edge);
  }
}

/* ---- the wordmark: lilac fill, purple extrusion ------------------------- */
.wm-fill {
  background: linear-gradient(180deg, #ffffff 0%, #fde6ff 45%, var(--j-lilac) 100%);
  -webkit-background-clip: text;
  background-clip: text;
}
.wordmark::before {
  color: var(--j-orchid);
  text-shadow:
    0 2px 0 #c96cf3, 0 4px 0 #b552e0, 0 6px 0 #a23fcc, 0 8px 0 #9430bf, 0 10px 0 var(--j-purple), 0 12px 0 #6f1d96,
    0 14px 16px rgba(94, 21, 128, 0.35);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wordmark::before {
    text-shadow: 0 2px 0 #b552e0, 0 4px 0 #a23fcc, 0 6px 0 var(--j-purple), 0 8px 0 #6f1d96, 0 10px 0 #5e1580, 0 12px 0 #4a0f68, 0 14px 16px rgba(0,0,0,.55);
  }
}

/* ---- Cinzel sizing ------------------------------------------------------ */
/* Cinzel's lowercase is small capitals, so everything set in it reads as
   caps. It is wide; sizes come down so the long title still lands on two
   lines at desktop and the buttons keep one. */
.win-title { font-size: 0.98rem; font-weight: 700; letter-spacing: 0.06em; }
.btn { font-size: 0.92rem; font-weight: 700; letter-spacing: 0.05em; }
.badge { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.12em; }
.single-title { font-size: clamp(1.25rem, 1rem + 1.6vw, 2rem); font-weight: 700; letter-spacing: 0.03em; line-height: 1.22; }
.catalogue h3 { font-size: 1.02rem; font-weight: 700; letter-spacing: 0.04em; }
.illuminated::first-letter { font-size: 3.4em; font-weight: 700; }
.taskbar nav a, .footer-links a { font-family: var(--gothic); font-weight: 700; letter-spacing: 0.05em; }

/* the marbles and the front clouds take the lilac */
.bubble, .bubble.pinkish {
  background: radial-gradient(circle at 36% 30%, #ffffff 0%, #fde6ff 22%, var(--j-lilac) 58%, var(--j-orchid) 100%);
  box-shadow: 0 6px 12px rgba(94, 21, 128, 0.22);
}
.clouds span, .fcloud, .pillar, .pillar-c, .portal, .mascot, .plinth {
  filter: drop-shadow(0 18px 28px rgba(94, 21, 128, 0.32));
}

/* ==========================================================================
   19. SKY BLUE, MATTE WORDMARK, THE OTHER COLOURS ON THE BUTTONS
   ========================================================================== */

/* ---- the sky, blue, to see ---------------------------------------------- */
.sky {
  background:
    image-set(url("../img/sky-light-blue.webp") type("image/webp")) center / cover no-repeat,
    linear-gradient(180deg, #2f5fd8 0%, #4f8bff 34%, #8dc0ff 62%, #c9e2ff 84%, #f2f6ff 100%);
  background-attachment: fixed;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sky {
    background:
      image-set(url("../img/sky-dark-blue.webp") type("image/webp")) center / cover no-repeat,
      linear-gradient(180deg, #050b2a 0%, #0d1a5c 40%, #163084 70%, #1f4ab0 100%);
    background-attachment: fixed;
  }
}
.aurora .a3 { background: radial-gradient(closest-side, rgba(25, 35, 249, 0.22), transparent); }

/* ---- the wordmark: matte lilac clay, extruded in the deep purple --------- */
/* The fill was a white-to-lilac gradient, which reads as gloss. It is now
   a flat lilac with the same grain the panes carry, clipped to the
   letters, so the wordmark is the same material as everything else. */
.wm-fill {
  background:
    url("../img/grain.webp") 0 0 / 160px 160px repeat,
    linear-gradient(var(--j-lilac), var(--j-lilac));
  background-blend-mode: multiply, normal;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
.wordmark::before {
  color: #e9a6f5;                          /* a hair darker than the face: the turn of the edge */
  text-shadow:
    0 2px 0 #c96cf3, 0 4px 0 #b552e0, 0 6px 0 #a23fcc, 0 8px 0 var(--j-purple), 0 10px 0 #7a1fa5,
    0 12px 0 #6a1a91, 0 14px 0 #5e1580,
    0 18px 14px rgba(40, 8, 80, 0.32);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wm-fill {
    background:
      url("../img/grain.webp") 0 0 / 160px 160px repeat,
      linear-gradient(#f2c9ff, #f2c9ff);
    background-blend-mode: multiply, normal;
    -webkit-background-clip: text;
    background-clip: text;
  }
}

/* ---- buttons: blue primary, lilac secondary, orchid badge ---------------- */
.btn-go {
  color: #fff;
  border-color: #0d14b0;
  background: linear-gradient(180deg, #a9adff 0%, #5a63ff 14%, var(--j-blue) 56%, #0f17c4 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), inset 0 -2px 0 rgba(0,0,80,.3), 0 2px 0 #0a0f8a, 0 3px 6px rgba(0,0,80,.3);
  text-shadow: 0 1px 1px rgba(0, 0, 80, 0.45);
}
.btn-go:hover { box-shadow: 0 0 0 2px rgba(68, 250, 9, 0.7), 0 3px 0 #0a0f8a, 0 4px 8px rgba(0,0,80,.3); }

.btn:not(.btn-go) {
  color: var(--ink);
  border-color: #c96cf3;
  background: linear-gradient(180deg, #ffffff 0%, #fde6ff 40%, #fbd0ff 55%, var(--j-lilac) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.95), inset 0 -2px 0 rgba(136,37,183,.2), 0 2px 0 #d98cf0, 0 3px 5px rgba(94,21,128,.22);
}

.badge {
  color: var(--ink);
  border-color: #a23fcc;
  background: linear-gradient(180deg, #f2c9ff 0%, #e2a2ff 16%, var(--j-orchid) 56%, #b552e0 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6), inset 0 -2px 0 rgba(94,21,128,.28), 0 2px 0 #9430bf, 0 3px 5px rgba(94,21,128,.28);
  text-shadow: none;
}
.badge::before { background: var(--j-lime); box-shadow: 0 0 6px rgba(68, 250, 9, 0.8), 0 0 0 1px rgba(17,54,0,.35); }

/* window buttons: lilac for minimise and maximise, blue for close */
.win-chrome i {
  color: var(--ink);
  border-color: #a23fcc;
  background: linear-gradient(180deg, #ffffff 0%, #fde6ff 18%, var(--j-lilac) 56%, #e2a2ff 100%);
  text-shadow: none;
}
.win-chrome i:last-child {
  color: #fff;
  border-color: #0d14b0;
  background: linear-gradient(180deg, #a9adff 0%, #5a63ff 18%, var(--j-blue) 56%, #0d14b0 100%);
  text-shadow: 0 1px 1px rgba(0,0,80,.45);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn-go { background: linear-gradient(180deg, #a9adff 0%, #5a63ff 14%, var(--j-blue) 56%, #0f17c4 100%); }
  :root:not([data-theme="light"]) .btn:not(.btn-go) {
    color: #2c0f3d;
    background: linear-gradient(180deg, #fbe4ff 0%, #f2c9ff 45%, #e6adff 55%, var(--j-orchid) 100%);
    border-color: #9430bf;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.6), inset 0 -2px 0 rgba(94,21,128,.3), 0 2px 0 #7a1fa5, 0 3px 5px rgba(0,0,0,.45);
  }
  :root:not([data-theme="light"]) .badge { color: #2c0f3d; }
}

/* ==========================================================================
   20. BLUE SKY, GREEN NAME
   ========================================================================== */

/* The sky tile is now built from real sky blues with white clouds on top
   (tools/sky-blue.py). The aurora blobs and the ground gradient under the
   tile were tinting it grey-violet; both go blue. */
.sky {
  background:
    image-set(url("../img/sky-light-blue.webp") type("image/webp")) center / cover no-repeat,
    linear-gradient(180deg, #3aacff 0%, #8cd4ff 55%, #e8f8ff 100%);
  background-attachment: fixed;
}
.aurora { display: none; }

/* The wordmark pops in the lime, extruded in the deep purple. Same grain,
   same clay, louder colour. */
.wm-fill {
  background:
    url("../img/grain.webp") 0 0 / 160px 160px repeat,
    linear-gradient(var(--j-lime), var(--j-lime));
  background-blend-mode: multiply, normal;
  -webkit-background-clip: text;
  background-clip: text;
}
.wordmark::before {
  color: #35d400;                          /* the turn of the edge, a shade darker than the face */
  text-shadow:
    0 2px 0 #2a9e00, 0 4px 0 #9430bf, 0 6px 0 var(--j-purple), 0 8px 0 #7a1fa5, 0 10px 0 #6a1a91,
    0 12px 0 #5e1580, 0 14px 0 #4a0f68,
    0 18px 14px rgba(40, 8, 80, 0.4);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wm-fill {
    background:
      url("../img/grain.webp") 0 0 / 160px 160px repeat,
      linear-gradient(var(--j-lime), var(--j-lime));
    background-blend-mode: multiply, normal;
    -webkit-background-clip: text;
    background-clip: text;
  }
  :root:not([data-theme="light"]) .wordmark::before {
    color: #35d400;
    text-shadow: 0 2px 0 #2a9e00, 0 4px 0 #9430bf, 0 6px 0 var(--j-purple), 0 8px 0 #6a1a91, 0 10px 0 #5e1580, 0 12px 0 #4a0f68, 0 14px 0 #3a0a52, 0 18px 14px rgba(0,0,0,.6);
  }
}

/* ==========================================================================
   21. THE WORDMARK, OPTION E
   Checkerboard fill in the plinth's blue and white, a thick purple outline,
   a flat purple drop underneath. Three layers: ::before carries the stroke
   and sits behind, .wm-fill carries the checks clipped to the letters, and
   the drop is a filter on the whole mark so it hugs the outline, not the
   fill. Stroke and check size are in em so they scale with the type.
   ========================================================================== */
.wordmark {
  filter: drop-shadow(0 0.09em 0 #4a0f68) drop-shadow(0 0.14em 0.16em rgba(74, 15, 104, 0.35));
}
.wordmark::before {
  color: transparent;
  -webkit-text-stroke: 0.08em var(--j-purple);
  text-shadow: none;
  z-index: 0;
}
.wm-fill {
  position: relative;
  z-index: 1;
  color: transparent;
  -webkit-text-fill-color: transparent;
  background: repeating-conic-gradient(#5a63ff 0% 25%, #eef0ff 0% 50%) 0 0 / 0.24em 0.24em;
  background-blend-mode: normal;
  -webkit-background-clip: text;
  background-clip: text;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wm-fill {
    background: repeating-conic-gradient(#4a53ff 0% 25%, #e6e9ff 0% 50%) 0 0 / 0.24em 0.24em;
    -webkit-background-clip: text;
    background-clip: text;
  }
  :root:not([data-theme="light"]) .wordmark::before { color: transparent; text-shadow: none; }
  :root:not([data-theme="light"]) .wordmark { filter: drop-shadow(0 0.09em 0 #2a0840) drop-shadow(0 0.14em 0.16em rgba(0, 0, 0, 0.5)); }
}

/* ==========================================================================
   22. DAYTIME ONLY
   The page is pinned to light with data-theme="light" on <html>. The sky
   is the design; it does not have a night mode. The browser is told the
   same so form controls and scrollbars do not go dark on their own.
   ========================================================================== */
:root { color-scheme: light; }
.pillar.far { display: none; }


/* ==========================================================================
   23. THE GLYPHS MOVE
   The strip is split into its thirteen signs (tools: the split script in
   the session record). Each sign is its own element with its own bob and
   tilt, out of phase with its neighbours, and the whole row conveys slowly
   to the left. The row is three copies of the set, translated by one
   third, so the loop is seamless.
   ========================================================================== */
.frieze {
  height: auto;
  background: none;
  filter: none;
  overflow: hidden;
  padding: 0.8em 0;
  font-size: clamp(26px, 3.4vw, 44px);      /* one em = one glyph height */
  -webkit-mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.frieze-track {
  display: flex;
  align-items: center;
  gap: 0.9em;
  width: max-content;
  animation: frieze-convey 60s linear infinite;
}
.frieze.foot .frieze-track { animation-direction: reverse; }
.glyph {
  display: block;
  height: 1em;
  flex: none;
  background: center / contain no-repeat;
  filter: drop-shadow(0 0.12em 0.14em rgba(74, 15, 104, 0.35));
  animation: glyph-bob 4.2s ease-in-out infinite, glyph-tilt 36s ease-in-out infinite;
  transform-origin: 50% 60%;
}
.glyph.g1 { background-image: url("../img/3d/glyphs/g1.webp"); width: 0.858em; animation-delay: 3.83s, 34.9s; }
.glyph.g2 { background-image: url("../img/3d/glyphs/g2.webp"); width: 1.025em; animation-delay: 3.46s, 33.8s; }
.glyph.g3 { background-image: url("../img/3d/glyphs/g3.webp"); width: 0.908em; animation-delay: 3.09s, 32.7s; }
.glyph.g4 { background-image: url("../img/3d/glyphs/g4.webp"); width: 0.642em; animation-delay: 2.72s, 31.6s; }
.glyph.g5 { background-image: url("../img/3d/glyphs/g5.webp"); width: 0.858em; animation-delay: 2.35s, 30.5s; }
.glyph.g6 { background-image: url("../img/3d/glyphs/g6.webp"); width: 0.850em; animation-delay: 1.98s, 29.4s; }
.glyph.g7 { background-image: url("../img/3d/glyphs/g7.webp"); width: 0.908em; animation-delay: 1.61s, 28.3s; }
.glyph.g8 { background-image: url("../img/3d/glyphs/g8.webp"); width: 0.425em; animation-delay: 1.24s, 27.2s; }
.glyph.g9 { background-image: url("../img/3d/glyphs/g9.webp"); width: 0.867em; animation-delay: 0.87s, 26.1s; }
.glyph.g10 { background-image: url("../img/3d/glyphs/g10.webp"); width: 0.558em; animation-delay: 0.50s, 25.0s; }
.glyph.g11 { background-image: url("../img/3d/glyphs/g11.webp"); width: 0.208em; animation-delay: 0.13s, 23.9s; }
@keyframes frieze-convey {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% / 3)); }
}
@keyframes glyph-bob {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -0.22em; }
}
@keyframes glyph-tilt {
  0%, 100% { rotate: -6deg; }
  50%      { rotate: 6deg; }
}
@media (prefers-reduced-motion: reduce) {
  .frieze-track, .glyph { animation: none; }
}

/* ==========================================================================
   24. PANES, 15% MORE TRANSPARENT
   The sky shows through the clay a little.
   ========================================================================== */
:root { --xp-body: rgba(253, 238, 255, 0.82); }
.site-footer { background: rgba(253, 238, 255, 0.86); }

/* ==========================================================================
   25. THE WORDMARK, OPTION F
   Puffy emboss. Lilac face, a white edge catching light from the top left,
   an orchid then purple edge turning away at the bottom right, and a soft
   purple shadow under the whole thing. No outline, no fill pattern: the
   letters are the same plush clay as the clouds. The stroke layer from E
   goes quiet and the drop-shadow filter comes off, so the emboss reads
   clean.
   ========================================================================== */
.wordmark { filter: none; }
.wordmark::before { -webkit-text-stroke: 0; color: transparent; text-shadow: none; }
.wm-fill {
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--j-lilac);
  -webkit-text-fill-color: var(--j-lilac);
  text-shadow:
    -0.022em -0.022em 0 #ffffff,
     0.022em  0.022em 0 #b552e0,
     0.044em  0.044em 0 var(--j-purple),
     0 0.13em 0.22em rgba(74, 15, 104, 0.42);
}

/* ==========================================================================
   26. THE WORDMARK, OPTION M
   The pillow, in the column's own four colours: #f6b2ff face, a thin
   #e89afd rim all the way round, a #943abd lip beneath, #6c03af as the
   darkest step and as the soft shadow under everything. The same shading
   the render uses, so the name and the columns are one material.
   ========================================================================== */
.wm-fill {
  color: #f6b2ff;
  -webkit-text-fill-color: #f6b2ff;
  text-shadow:
    -0.022em -0.022em 0 #e89afd,  0.022em -0.022em 0 #e89afd,
    -0.022em  0.022em 0 #e89afd,  0.022em  0.022em 0 #e89afd,
     0 -0.022em 0 #e89afd,        0  0.022em 0 #e89afd,
    -0.022em 0 0 #e89afd,         0.022em 0 0 #e89afd,
     0 0.055em 0 #943abd,         0 0.076em 0 #943abd,
     0 0.098em 0 #6c03af,
     0 0.15em 0.2em rgba(108, 3, 175, 0.4);
}


/* ==========================================================================
   27. THE WORDMARK, FINAL: T3
   Lilac at the top shading into the column purple at the bottom, the way
   the shaft of the column rounds off. A white edge along the top, a
   two-step drop in the darkest purple, a soft shadow under it all. The
   face is on the span and the drop is a filter on the h1, because a
   background clipped to text and a filter on the same element paint
   nothing in Chromium.
   ========================================================================== */
.wordmark {
  filter:
    drop-shadow(0 -1px 0 rgba(255, 255, 255, 0.7))
    drop-shadow(0 0.03em 0 #6c03af)
    drop-shadow(0 0.03em 0 #6c03af)
    drop-shadow(0 0.13em 0.13em rgba(40, 0, 80, 0.4));
}
.wordmark::before { display: none; }
.wm-fill {
  color: transparent;
  -webkit-text-fill-color: transparent;
  text-shadow: none;
  background: linear-gradient(180deg, #f6b2ff 0%, #d27cfd 40%, #943abd 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

/* ==========================================================================
   28. A BIGGER NAME, AND THE COLUMNS GO FLOATING
   The hero pair is gone. Four columns now drift among the background
   clouds, tilted, at four depths: the near ones large and sharp, the far
   ones small, paler and slower. Same fixed layer as the clouds, so panes
   pass in front of them.
   ========================================================================== */
.wordmark { font-size: clamp(3rem, 12.5vw, 7.4rem); }
.hero { padding-top: clamp(1.6rem, 5vw, 3rem); padding-bottom: clamp(1.4rem, 4vw, 2.4rem); }
.pillar { display: none; }

.clouds .p1, .clouds .p2, .clouds .p3, .clouds .p4 {
  background-image: url("../img/3d/column.webp");
  aspect-ratio: 389/782;
  filter: drop-shadow(0 18px 28px rgba(94, 21, 128, 0.3));
}
.clouds .p1 { width: min(11vw, 150px); left: 9%;  top: 6%;  rotate: -14deg; opacity: 1;    animation-duration: 80s, 8s;  animation-delay: 0s, -2s; }
.clouds .p2 { width: min(7vw, 96px);   right: 14%; top: 12%; rotate: 18deg;  opacity: 0.8;  animation-duration: 110s, 11s; animation-direction: alternate-reverse, alternate; animation-delay: 0s, -5s; }
.clouds .p3 { width: min(5vw, 64px);   left: 34%;  top: 40%; rotate: -26deg; opacity: 0.55; animation-duration: 140s, 13s; animation-delay: 0s, -8s; filter: drop-shadow(0 10px 16px rgba(94,21,128,.2)) blur(0.6px); }
.clouds .p4 { width: min(9vw, 120px);  right: 4%;  top: 52%; rotate: 22deg;  opacity: 0.9;  animation-duration: 95s, 9s;   animation-direction: alternate-reverse, alternate; animation-delay: 0s, -3.5s; }
@media (max-width: 780px) {
  .clouds .p3 { display: none; }
  .clouds .p1 { width: 16vw; left: 4%; top: 4%; }
  .clouds .p4 { width: 13vw; }
}

/* The near column at the top left sat on a cloud. Down into the empty
   stretch of sky on the left side of the page, under the frieze. */
.clouds .p1 { top: 38%; left: 4%; }
@media (max-width: 780px) { .clouds .p1 { top: 30%; left: 2%; } }
/* further down and further left still */
.clouds .p1 { top: 54%; left: 1%; }
@media (max-width: 780px) { .clouds .p1 { top: 44%; left: 0; } }

/* The far columns read as far by size alone: full opacity, no blur. */
.clouds .p2, .clouds .p3, .clouds .p4 { opacity: 1; }
.clouds .p3 { filter: drop-shadow(0 10px 16px rgba(94, 21, 128, 0.25)); }

/* The cursor sparkles take the palette: lilac, with every third one
   electric blue and every seventh lime. */
.sparkle {
  background: var(--j-lilac);
  box-shadow: 0 0 8px rgba(248, 180, 254, 0.9), 0 0 2px #d27cfd;
}
.sparkle:nth-child(3n) { background: var(--j-blue); box-shadow: 0 0 8px rgba(25, 35, 249, 0.8); }
.sparkle:nth-child(7n) { background: var(--j-lime); box-shadow: 0 0 9px rgba(68, 250, 9, 0.85); }

/* The About copy, larger. One paragraph now, so it can carry more size. */
.illuminated { font-size: clamp(1.12rem, 1rem + 0.7vw, 1.42rem); line-height: 1.6; }
.illuminated::first-letter { font-size: 3.2em; }
/* The drop cap was still in the gold ink of the medieval pass. */
.illuminated::first-letter { color: #6c03af; background: none; -webkit-text-fill-color: #6c03af; text-shadow: none; }

/* On a phone the Listen buttons run full width, so the cloud under that
   window was sitting on Apple Music. Smaller, and dropped into the gap
   between Listen and About, over the empty middle of About's title bar
   (the title is on the left, the buttons are on the right). */
@media (max-width: 780px) {
  .fcloud.fc5 { width: 26vw; left: 42%; bottom: -4.9rem; }
}
/* On a phone the column to the right of the name crowds it. Gone there. */
@media (max-width: 780px) { .clouds .p2 { display: none; } }

/* Two fixes to the name, 2026-09-05.

   The g's swash was cut off on the right. Lemon Popsicle's g overhangs its
   own advance width, and a fill clipped to text only paints inside the
   element's box, so the overhang had no fill. Padding widens the paintable
   box; the negative margin keeps the mark centred where it was.

   And the name sat closer to the ticker than to the glyph strip (59px
   above, 75px below, measured on the painted pixels). The hero's padding
   shifts to split the difference. */
.wm-fill { padding: 0 0.16em 0.06em; margin: 0 -0.16em -0.06em; }
.hero { padding-top: clamp(2.1rem, 5vw + 0.5rem, 3.5rem); padding-bottom: clamp(0.9rem, 4vw - 0.5rem, 1.9rem); }
