/* =============================================================================
   LILY LIBRARY - SEASONAL THEMES
   =============================================================================

   Every rule in this file is scoped to a class on <body>, so the file is inert
   until a theme is switched on. style.css is never edited, which means the
   normal look is always intact underneath.

   TO TURN A THEME ON   ->  <body class="halloween">
   TO TURN IT OFF       ->  <body>

   That single word is the whole switch. Leave the <link> to this file in
   index.html permanently; with no body class it changes nothing.

   Future seasons follow the same pattern in this same file:
       body.winter  { ... }    body.spring { ... }
   ============================================================================= */


/* =============================================================================
   HALLOWEEN - "HAUNTED LIBRARY"
   Deep plum to ink, bone-white title with a faint green rim glow, cobwebs in
   the corners, slow fog along the bottom, and the star bubbles become bats.
   ============================================================================= */

/* ---------- 1. Title container: swap the pastel drift for plum and ember ---- */

body.halloween #animated-title-bg {
    background: linear-gradient(
        45deg,
        #1b0f2b,   /* deep plum shadow  */
        #3d1a4d,   /* witch purple      */
        #7a2d1a,   /* banked ember      */
        #c05a1e,   /* pumpkin           */
        #24122f    /* back to plum      */
    );
    background-size: 200% 200%;
    animation: color 16s ease-in-out infinite;  /* slower than the usual 12s */
    position: relative;
    overflow: hidden;                            /* keeps fog and webs inside */
}

/* ---------- 2. Cobwebs in the top corners -------------------------------- */
/* Drawn with repeating gradients rather than images, so there is nothing new
   to download and nothing to break if a file goes missing.                   */

body.halloween #animated-title-bg::before,
body.halloween #animated-title-bg::after {
    content: "";
    position: absolute;
    top: 0;
    width: 130px;
    height: 130px;
    pointer-events: none;
    opacity: 0.5;
    background:
        /* radial strands */
        repeating-radial-gradient(circle at 0 0,
            transparent 0 16px,
            rgba(226, 232, 240, 0.55) 16px 17px),
        /* the two spokes */
        linear-gradient(35deg,  transparent 49.4%, rgba(226,232,240,.5) 49.4% 50.6%, transparent 50.6%),
        linear-gradient(-10deg, transparent 49.4%, rgba(226,232,240,.5) 49.4% 50.6%, transparent 50.6%);
}

body.halloween #animated-title-bg::before { left: 0; }
body.halloween #animated-title-bg::after  { right: 0; transform: scaleX(-1); }

/* ---------- 3. The title: bone white with a cold green rim ---------------- */

body.halloween .title span {
    color: #f2efe4 !important;          /* overrides the 5-colour candy cycle */
    text-shadow:
        0 0 6px  rgba(140, 255, 170, 0.35),
        0 0 18px rgba(90, 210, 130, 0.22),
        2px 2px 0 rgba(0, 0, 0, 0.55);
    animation: letterWave 3s ease-in-out infinite,
               candleFlicker 5s ease-in-out infinite;
}

/* a shallow, uneven flicker - like light off a candle, not a strobe */
@keyframes candleFlicker {
    0%, 100% { opacity: 1;    }
    18%      { opacity: 0.88; }
    22%      { opacity: 1;    }
    56%      { opacity: 0.92; }
    60%      { opacity: 1;    }
    83%      { opacity: 0.86; }
}

/* stagger the flicker so the letters do not pulse in unison */
body.halloween .title span:nth-child(3n)   { animation-delay: 0s,    0.7s; }
body.halloween .title span:nth-child(3n+1) { animation-delay: 0.15s, 2.1s; }
body.halloween .title span:nth-child(3n+2) { animation-delay: 0.3s,  3.4s; }

body.halloween .title span:hover {
    color: #ffd79a !important;          /* warms up like a lit match */
    text-shadow:
        0 0 10px rgba(255, 170, 60, 0.6),
        0 0 26px rgba(255, 120, 30, 0.35);
}

/* ---------- 4. Subtitle ---------------------------------------------------- */

body.halloween .subtitle {
    color: #e6dcc8;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}

/* ---------- 5. Star bubbles become bats ---------------------------------- */
/* index.js keeps spawning the same .bubble elements - only their appearance
   changes here, so there is no JavaScript to edit and nothing to undo.       */

body.halloween .bubble {
    clip-path: polygon(
        50% 38%,      /* head            */
        58% 28%, 64% 40%,
        78% 24%, 88% 42%, 100% 36%,
        90% 54%, 96% 70%,
        78% 62%, 66% 74%,
        50% 60%,      /* body bottom     */
        34% 74%, 22% 62%,
        4%  70%, 10% 54%,
        0%  36%, 12% 42%,
        22% 24%, 36% 40%,
        42% 28%
    );
    background-color: #15121d;
    background-image: none;             /* drop the glossy highlight */
    border: none;
    filter: drop-shadow(0 0 5px rgba(0, 0, 0, 0.6));
    animation: floatUp 5s forwards, batFlap 0.45s ease-in-out infinite;
}

@keyframes batFlap {
    0%, 100% { transform: scaleY(1)    scaleX(1);    }
    50%      { transform: scaleY(0.72) scaleX(1.06); }
}

/* ---------- 6. Fog drifting along the bottom of the header --------------- */

body.halloween .header::after {
    content: "";
    position: absolute;
    left: -50%;
    right: -50%;
    bottom: 0;
    height: 90px;
    pointer-events: none;
    z-index: 2;
    background: radial-gradient(ellipse 60% 100% at 20% 100%, rgba(214, 222, 235, 0.20), transparent 70%),
                radial-gradient(ellipse 50% 100% at 55% 100%, rgba(214, 222, 235, 0.16), transparent 70%),
                radial-gradient(ellipse 65% 100% at 85% 100%, rgba(214, 222, 235, 0.20), transparent 70%);
    animation: fogDrift 28s linear infinite alternate;
}

@keyframes fogDrift {
    from { transform: translateX(-4%); }
    to   { transform: translateX(4%);  }
}

/* ---------- 7. Darken the shelf photo and warm the lamp light ------------ */

body.halloween .header {
    position: relative;
    background-color: #120c18;
    background-blend-mode: multiply, normal;
    box-shadow: inset 0 -40px 70px -30px rgba(0, 0, 0, 0.85);
}

body.halloween .header::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
    /* one warm lamp, top-centre, over a cool shadow wash */
    background: radial-gradient(ellipse 45% 40% at 50% 12%, rgba(255, 168, 66, 0.20), transparent 68%),
                linear-gradient(180deg, rgba(14, 9, 20, 0.55), rgba(14, 9, 20, 0.22) 45%, rgba(14, 9, 20, 0.6));
}

/* Keep the real content above the overlay layers.
   Deliberately targeted rather than a blanket `.header > *` rule: the nav and
   the search button are absolutely positioned in style.css, and forcing
   position:relative on them would drop them back into normal flow and move
   them. These rules set stacking only, and never touch `position`. */

body.halloween #animated-title-bg,
body.halloween .text-scroller-container {
    position: relative;          /* these two are static, so they need this */
    z-index: 3;
}

/* Already absolutely positioned in style.css - stacking only, no position. */
body.halloween .books-games { z-index: 6; }   /* above the cobwebs and spider */
body.halloween #banner1     { z-index: 3; }
/* .search already carries z-index:99 in style.css, so it stays on top
   untouched - its position is left exactly as it was. */

/* ---------- 8. Top text scroller ---------------------------------------- */

body.halloween .text-scroller-container {
    background: linear-gradient(
        225deg,
        #3d1a4d 0%,
        #2a1138 35%,
        #1b0f2b 70%,
        #120a1c 100%
    );
    outline-color: rgba(226, 232, 240, 0.55);
}

body.halloween .text-scroller-content       { color: #ffd79a; }
body.halloween .text-scroller-content p     { background-color: rgba(60, 26, 76, 0.45); }

/* ---------- 9. Navigation ------------------------------------------------ */

body.halloween .books-games li  { color: #ffb347; }
body.halloween .books-games a   { color: #ffb347; }

/* the About link is inline-styled black in the HTML, so it needs the override */
body.halloween .books-games a[href*="iblog"] { color: #ffb347 !important; }

body.halloween .books-games a:hover {
    color: #fff0d0;
    text-shadow: 0 0 8px rgba(255, 140, 40, 0.7);
}

/* ---------- 10. Search button ------------------------------------------- */

body.halloween .search button:hover {
    border-radius: 10px;
    border: 1px inset #ffb347;
}

/* ---------- 11. A spider lowering itself from the right-hand web ---------
   Hosted on the two free pseudo-elements of the empty .header-content div, so
   nothing is added to index.html. .header-content itself is left in normal
   flow and unstyled - only its pseudo-elements are positioned, and they anchor
   to .header (which is position:relative). Both are pointer-events:none, so
   the spider can never intercept a click meant for the search button.        */

body.halloween .header-content::before,
body.halloween .header-content::after {
    content: "";
    position: absolute;
    right: 3.5%;                 /* outboard of the search button at right:10% */
    pointer-events: none;
    z-index: 4;                  /* over the webs, under the nav */
}

/* the silk thread */
body.halloween .header-content::before {
    top: 58px;                   /* just under the scroller, at the web's edge */
    width: 1px;
    height: 132px;
    background: linear-gradient(180deg,
        rgba(226, 232, 240, 0.65),
        rgba(226, 232, 240, 0.35));
    transform-origin: top center;
    animation: spiderThread 16s ease-in-out infinite;
}

/* the spider: an original silhouette drawn as an inline SVG, so there is no
   extra file to load and it stays crisp at any size */
body.halloween .header-content::after {
    top: 178px;
    width: 26px;
    height: 26px;
    margin-right: -12.5px;       /* centre the body on the thread */
    background: no-repeat center/contain
        url('data:image/svg+xml;utf8,\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">\
<g stroke="%23141019" stroke-width="2.6" stroke-linecap="round" fill="none">\
<path d="M20 22 L8 14 L3 19"/><path d="M20 26 L6 25 L2 31"/>\
<path d="M20 30 L7 35 L4 42"/><path d="M21 33 L14 42 L16 46"/>\
<path d="M28 22 L40 14 L45 19"/><path d="M28 26 L42 25 L46 31"/>\
<path d="M28 30 L41 35 L44 42"/><path d="M27 33 L34 42 L32 46"/>\
</g>\
<ellipse cx="24" cy="20" rx="6" ry="5.5" fill="%23141019"/>\
<ellipse cx="24" cy="29" rx="8.5" ry="9.5" fill="%231d1726"/>\
<circle cx="21.6" cy="18.4" r="1.15" fill="%23ffb347"/>\
<circle cx="26.4" cy="18.4" r="1.15" fill="%23ffb347"/>\
</svg>');
    animation: spiderDrop 16s ease-in-out infinite;
}

/* drops in, hangs and sways, then climbs back up - one slow 16s cycle */
@keyframes spiderDrop {
    0%           { transform: translateY(-130px) rotate(0deg);   opacity: 0; }
    6%           { opacity: 1; }
    22%          { transform: translateY(0) rotate(0deg);        opacity: 1; }
    34%          { transform: translateY(6px) rotate(5deg);      opacity: 1; }
    48%          { transform: translateY(2px) rotate(-4deg);     opacity: 1; }
    62%          { transform: translateY(7px) rotate(3deg);      opacity: 1; }
    78%          { transform: translateY(0) rotate(0deg);        opacity: 1; }
    96%          { transform: translateY(-130px) rotate(0deg);   opacity: 0; }
    100%         { transform: translateY(-130px) rotate(0deg);   opacity: 0; }
}

/* the thread pays out and reels back in with the spider */
@keyframes spiderThread {
    0%           { transform: scaleY(0);    }
    22%          { transform: scaleY(1);    }
    34%          { transform: scaleY(1.05); }
    48%          { transform: scaleY(1.02); }
    62%          { transform: scaleY(1.06); }
    78%          { transform: scaleY(1);    }
    96%, 100%    { transform: scaleY(0);    }
}

/* ---------- 12. Jack-o'-lantern beside the title -------------------------
   Hosted on the two free pseudo-elements of the .title h1, which puts it in
   the gap between the nav at top-left and the centred title text. Nothing is
   added to index.html, and .title only gains position:relative - which does
   not move it, since it has no offsets of its own.
   The pumpkin is an original drawing, inlined as SVG so there is no extra
   file to fetch. Both layers are pointer-events:none.                        */

body.halloween .title { position: relative; }

/* warm light thrown onto the shelf behind the lantern */
body.halloween .title::after {
    content: "";
    position: absolute;
    left: 15%;
    top: 50%;
    width: 130px;
    height: 130px;
    margin: -65px 0 0 -31px;
    border-radius: 50%;
    pointer-events: none;
    z-index: 0;
    background: radial-gradient(circle,
        rgba(255, 173, 61, 0.40) 0%,
        rgba(255, 138, 28, 0.16) 45%,
        transparent 72%);
    animation: lanternGlow 4.6s ease-in-out infinite;
}

/* the lantern itself */
body.halloween .title::before {
    content: "";
    position: absolute;
    left: 15%;
    top: 50%;
    width: 68px;
    height: 68px;
    margin-top: -34px;
    pointer-events: none;
    z-index: 1;
    background: no-repeat center/contain url('data:image/svg+xml;utf8,\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">\
<defs><radialGradient id="p" cx="38%25" cy="30%25" r="72%25">\
<stop offset="0" stop-color="%23f59029"/>\
<stop offset="62%25" stop-color="%23d9641b"/>\
<stop offset="100%25" stop-color="%23a3440e"/>\
</radialGradient></defs>\
<path d="M32 16 q-3-8 5-11 q-2 7 2 10" fill="none" stroke="%234d6b2a" stroke-width="4.2" stroke-linecap="round"/>\
<ellipse cx="32" cy="38" rx="26" ry="21" fill="url(%23p)"/>\
<path d="M18 21 q-5 17 0 34" fill="none" stroke="%23a3440e" stroke-width="1.8" opacity="0.5"/>\
<path d="M46 21 q5 17 0 34" fill="none" stroke="%23a3440e" stroke-width="1.8" opacity="0.5"/>\
<path d="M32 18 q-3 20 0 40" fill="none" stroke="%23a3440e" stroke-width="1.4" opacity="0.3"/>\
<path d="M20 31 l9.5 2.5 -8.5 5 z" fill="%23ffd23f"/>\
<path d="M44 31 l-9.5 2.5 8.5 5 z" fill="%23ffd23f"/>\
<path d="M32 37 l3 5.5 -6 0 z" fill="%23ffd23f"/>\
<path d="M19 45 l5.5 4 4-3 3.5 3 4-3 4 4 -3.5 4.5 -4-2 -4 2 -4-2 -5.5 1 z" fill="%23ffd23f"/>\
</svg>');
    animation: lanternFlicker 4.6s ease-in-out infinite;
}

/* candle-in-a-pumpkin: shallow, uneven, never a strobe */
@keyframes lanternFlicker {
    0%, 100% { filter: brightness(1)    drop-shadow(0 0 7px rgba(255, 150, 40, 0.55)); }
    15%      { filter: brightness(1.1)  drop-shadow(0 0 11px rgba(255, 160, 50, 0.7)); }
    28%      { filter: brightness(0.93) drop-shadow(0 0 5px  rgba(255, 150, 40, 0.45)); }
    47%      { filter: brightness(1.07) drop-shadow(0 0 10px rgba(255, 160, 50, 0.65)); }
    64%      { filter: brightness(0.96) drop-shadow(0 0 6px  rgba(255, 150, 40, 0.5)); }
    81%      { filter: brightness(1.12) drop-shadow(0 0 12px rgba(255, 170, 60, 0.72)); }
}

@keyframes lanternGlow {
    0%, 100% { opacity: 0.85; transform: scale(1);    }
    15%      { opacity: 1;    transform: scale(1.07); }
    28%      { opacity: 0.72; transform: scale(0.97); }
    47%      { opacity: 0.97; transform: scale(1.05); }
    64%      { opacity: 0.8;  transform: scale(1);    }
    81%      { opacity: 1;    transform: scale(1.08); }
}

/* ---------- 13. Respect reduced-motion and small screens ---------------- */

@media (prefers-reduced-motion: reduce) {
    body.halloween .title span,
    body.halloween .bubble,
    body.halloween .header::after,
    body.halloween #animated-title-bg,
    body.halloween .header-content::before,
    body.halloween .header-content::after,
    body.halloween .title::before,
    body.halloween .title::after {
        animation: none !important;
    }
}

@media (max-width: 600px) {
    /* smaller webs so they do not crowd the title on a phone */
    body.halloween #animated-title-bg::before,
    body.halloween #animated-title-bg::after {
        width: 78px;
        height: 78px;
        opacity: 0.4;
    }
    body.halloween .header::after { height: 60px; }

    /* smaller spider, shorter drop, to suit the tighter header */
    body.halloween .header-content::before { top: 44px; height: 86px; }
    body.halloween .header-content::after  { top: 128px; width: 20px; height: 20px; margin-right: -9.5px; }

    /* smaller lantern, closer to the edge, so it never crowds the title text */
    body.halloween .title::before { left: 7%; width: 44px; height: 44px; margin-top: -22px; }
    body.halloween .title::after  { left: 7%; width: 86px; height: 86px; margin: -43px 0 0 -21px; }
}
