/* Atlas / season — dressing for the public site on its seasonal dates.

   Every rule below waits for atlas-season.js to mark <html data-season="…">,
   which it does only while a season is running. This sheet can therefore stay
   linked all year and does nothing outside those dates: on November 1 the site
   is itself again without a file changing, and next October it dresses up
   again on its own.

   One rule for every season: change the mood, never the layout. Light and
   texture go around the work; artwork is never tinted or covered, nothing here
   moves content, and the page's own accent (atlas-palette.js) is left alone.

   Layering, against atlas-core.css: the ambient sits at -3, the page floor at
   -2 and the grain at -1. The season's light (html::before) and fog
   (html::after) both join the floor at -2 — the light painting before it and
   the fog after it in tree order — so the grain still textures all of them. */

/* Repeated from core on purpose; see the note there. Guarded per file by
   tests/smoke/design-system-hidden-guard.test.mjs. */
[hidden],
.hidden { display: none !important; }

/* ================================================================ shared */
/* Structure for the pieces a season can put on a page. Each season supplies
   only its colours and its mark. */

/* Home: the season's shelf, a sibling of the game shelves. Its header is the
   season's name instead of a game banner, and its panel takes the season's
   colour where a game shelf takes its banner's. */
:root[data-season] .am-season-title {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex: 0 0 auto;
  margin: 0;
  font-family: var(--am-display);
  font-size: clamp(1.3rem, 2.2vw, 1.75rem);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.1;
  color: var(--am-ink);
}

:root[data-season] .am-season-title__mark {
  flex: 0 0 auto;
  width: 1.55em;
  height: 1.55em;
  background: var(--season-mark) center / contain no-repeat;
}

/* Game hub: the season's strip on the search panel's top edge. Its pill sits
   on the left, and Spooktober's pumpkin patch (index-season-pumpkins.js) on
   the right; the two share one grid cell. The room is reserved here, before
   first paint and partly inside the empty padding above, so nothing on the
   page moves when either arrives. Clicks pass through to the row above
   except on the pill. */
:root[data-season] #hubSeasonScene {
  display: grid;
  /* One row exactly the strip's height. Anything taller (the pumpkins'
     canvas carries headroom for flying litter) overflows upward into the
     empty padding, never down behind the panel. */
  grid-template-rows: minmax(0, 1fr);
  align-items: end;
  align-items: unsafe end;
  height: 3.3rem;
  margin-top: -1.1rem;
  /* A little air between the strip's ground and the panel, so nothing on it
     reads as clipped by the panel's edge. */
  padding-bottom: .3rem;
  pointer-events: none;
}
:root[data-season] #hubSeasonScene > * { grid-area: 1 / 1; justify-self: start; }
@media (max-width: 40rem) {
  :root[data-season] #hubSeasonScene { height: 2.9rem; }
  /* The name alone on a phone, leaving room beside it for the scene. */
  :root[data-season] #hubSeasonScene .am-season-pill__count { display: none; }
}

/* One quiet way into the season's mods. */
:root[data-season] .am-season-pill {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem .8rem .3rem .4rem;
  pointer-events: auto;
  border: 1px solid rgba(var(--season-rgb), .34);
  border-radius: 999px;
  background: rgba(var(--season-rgb), .08);
  color: var(--am-ink);
  font-family: var(--am-mono);
  font-size: .6875rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  transition: border-color .18s var(--am-ease), background .18s var(--am-ease);
}
:root[data-season] .am-season-pill:hover {
  border-color: rgba(var(--season-rgb), .62);
  background: rgba(var(--season-rgb), .15);
}
:root[data-season] .am-season-pill[aria-current="page"] {
  border-color: rgba(var(--season-rgb), .7);
  background: rgba(var(--season-rgb), .2);
}
:root[data-season] .am-season-pill__mark {
  flex: 0 0 auto;
  width: 1.3rem;
  height: 1.3rem;
  background: var(--season-mark) center / contain no-repeat;
}
:root[data-season] .am-season-pill__count { color: var(--am-ink-3); }
:root[data-season] .am-season-pill[aria-current="page"] .am-season-pill__count { color: var(--am-ink-2); }

/* ============================================================ spooktober */
:root[data-season="spooktober"] {
  --season-rgb: 255, 122, 26;      /* pumpkin */
  --season-flame: 255, 186, 92;    /* candle */
  --season-dusk: 128, 84, 226;     /* witching-hour violet */

  /* A carved pumpkin, lit from inside. */
  --season-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3CradialGradient id='g' cx='.5' cy='.42' r='.62'%3E%3Cstop offset='0' stop-color='%23ffb15c'/%3E%3Cstop offset='.62' stop-color='%23f26d1b'/%3E%3Cstop offset='1' stop-color='%23b8430c'/%3E%3C/radialGradient%3E%3C/defs%3E%3Cpath d='M15.2 7.6c.1-2.2 1-3.9 2.9-4.9l1.1 1.4c-1.4.8-2 2-2 3.6z' fill='%235f7a35'/%3E%3Cellipse cx='10.4' cy='18.6' rx='7.4' ry='9.6' fill='url(%23g)'/%3E%3Cellipse cx='21.6' cy='18.6' rx='7.4' ry='9.6' fill='url(%23g)'/%3E%3Cellipse cx='16' cy='18.4' rx='7.6' ry='10.6' fill='url(%23g)'/%3E%3Cpath d='M12.4 9.2c-1.6 2.6-2.2 6-2 9.6m9.2-9.6c1.6 2.6 2.2 6 2 9.6' stroke='%23a63b09' stroke-opacity='.55' stroke-width='.8' fill='none'/%3E%3Cpath d='M9.6 15.6l3.6-2.4.6 4.1zm12.8 0-3.6-2.4-.6 4.1zM16 17.6l1.5 2.4h-3zM9.4 21.4c2.3 2.6 4.4 3.4 6.6 3.4s4.3-.8 6.6-3.4c-.9.3-1.6.4-2.4.4l-.7 1.3-1-1.1c-.8.2-1.6.2-2.5.2s-1.7 0-2.5-.2l-1 1.1-.7-1.3c-.8 0-1.5-.1-2.4-.4z' fill='%23ffe08a'/%3E%3C/svg%3E");
}

/* Candlelight pooled along the bottom of the window, and the last of the dusk
   in its top corners. Fixed, so it stays with the visitor through a long page
   the way the floor does. */
:root[data-season="spooktober"]::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(75% 42% at 50% 112%, rgba(var(--season-rgb), .17), transparent 72%),
    radial-gradient(38% 30% at 6% 100%, rgba(var(--season-flame), .07), transparent 70%),
    radial-gradient(42% 34% at 0% 0%, rgba(var(--season-dusk), .11), transparent 72%),
    radial-gradient(42% 34% at 100% 0%, rgba(var(--season-dusk), .08), transparent 72%);
}

/* Low fog along the ground. A tiling noise texture, faded upward, drifting
   very slowly — in steps a pixel apart, so the layer repaints a few times a
   second rather than every frame. */
:root[data-season="spooktober"]::after {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 36vh;
  z-index: -2;
  pointer-events: none;
  opacity: .3;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1200' height='320'%3E%3Cfilter id='f' filterUnits='userSpaceOnUse' x='0' y='0' width='1200' height='320'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0024 .0095' numOctaves='3' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .78 0 0 0 0 .75 0 0 0 0 .92 1.7 0 0 0 -.68'/%3E%3C/filter%3E%3Crect width='1200' height='320' filter='url(%23f)'/%3E%3C/svg%3E") 0 100% / 100vw 100% repeat-x;
  -webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, .5) 40%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, .5) 40%, transparent 100%);
  animation: season-fog-drift 200s steps(1600) infinite;
}
@keyframes season-fog-drift { to { background-position: -100vw 100%; } }

/* A witch's hat on the A. Drawn here rather than shipped as a second logo, so
   the mark itself is never swapped. */
:root[data-season="spooktober"] a:has(> .am-logo) { position: relative; }
:root[data-season="spooktober"] a:has(> .am-logo)::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -.48rem;
  width: 1.2rem;
  height: .96rem;
  pointer-events: none;
  transform: translateX(-46%) rotate(-10deg);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 32'%3E%3Cdefs%3E%3ClinearGradient id='h' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23604090'/%3E%3Cstop offset='1' stop-color='%23281a40'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cellipse cx='20' cy='26.2' rx='18.4' ry='4.4' fill='%23281a40' stroke='%23ffffff' stroke-opacity='.22' stroke-width='.8'/%3E%3Cpath d='M9.4 25.4C12.6 18.8 14.4 11.6 18.6 7.4 21.4 4.6 25.4 3.2 30.4 1.8 27.8 5 26 8.6 26 13c0 4.6 2 8.6 4.8 12.4z' fill='url(%23h)' stroke='%23ffffff' stroke-opacity='.22' stroke-width='.8'/%3E%3Cpath d='M11 21.6c5.6 1.6 13.6 1.6 19.2 0l.9 3c-6.4 1.8-14.6 1.8-21.2 0z' fill='%23ff7a1a'/%3E%3C/svg%3E") center / contain no-repeat;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .6));
}

/* Cards: the hover hairline becomes a candle-coloured one, and a warm glow
   rises under the caption — the light of the season rather than the page's
   accent, and only while the card is being considered. Eased in once rather
   than flickering: a looping shadow repaints the whole card every frame,
   artwork included. */
:root[data-season="spooktober"] .mod-showcase-card {
  transition: border-color .2s var(--am-ease), background-color .2s var(--am-ease), box-shadow .3s var(--am-ease);
}
:root[data-season="spooktober"] .mod-showcase-card::after {
  background: linear-gradient(90deg, rgb(var(--season-rgb)), rgb(var(--season-flame)) 55%, rgba(var(--season-dusk), .9));
}
:root[data-season="spooktober"] .mod-showcase-card:hover {
  border-color: rgba(var(--season-rgb), .42);
  box-shadow: 0 18px 38px -24px rgba(var(--season-rgb), .5), inset 0 -34px 40px -36px rgba(var(--season-flame), .45);
}

/* The season's own shelf glows its colour, the way a game's shelf glows its
   banner's. */
:root[data-season="spooktober"] .am-shelf--season {
  --am-shelf-tint: var(--season-rgb);
}
:root[data-season="spooktober"] .am-season-title__mark {
  filter: drop-shadow(0 0 10px rgba(var(--season-rgb), .55));
}

@media (prefers-reduced-motion: reduce) {
  :root[data-season="spooktober"]::after { animation: none; }
}
