/**
 * Site styles.
 *
 * Every colour and font is a custom property written by engine/theme.js from
 * the site config. There is not one hard-coded brand colour in this file, which
 * is what makes sites two to six a config swap. The values in :root are
 * fallbacks only, for the frame before the module runs.
 *
 * Structure, per Christa's second pass: LIGHT throughout. The Halloween is
 * carried by illustration, warm tints and small decorations rather than by a
 * dark band, so the page stays easy to shop. The footer is the only dark
 * surface left.
 *
 * This is an ideas site, not a shop. There is no styling here for a cart, a
 * price, a rating or a wishlist, and there should never be.
 *
 * Mobile first: base rules are the 375px layout and every media query adds.
 */

:root {
  --hero-bg: #fffaf3;
  --hero-bg-2: #fff3e0;
  --hero-bg-3: #f3ecfb;
  --hero-glow: #ff8a00;
  --hero-glow-2: #6a1b9a;
  --hero-ink: #212121;
  --hero-ink-dim: #5c5566;

  --night: #3b1163;
  --night-2: #26073f;
  --night-ink: #fff;
  --night-ink-dim: #d9c9ec;

  --bg: #fff;
  --bg-tint: #f5f5f7;
  --surface: #fff;
  --surface-2: #fff3e0;
  --ink: #212121;
  --ink-dim: #5c5566;
  --line: #ece7f2;

  --brand: #6a1b9a;
  --brand-2: #8e24aa;
  --brand-ink: #fff;
  --accent: #ff8a00;
  --accent-2: #e07400;
  /* --accent-ink sits ON orange; --accent-text is orange ON light. See the
     contrast note in config/halloween.js - #ff8a00 is 2.36:1 on white and
     cannot carry text either way round. */
  --accent-ink: #212121;
  --accent-text: #ad5300;
  --accent-soft: #fff3e0;
  --focus: #6a1b9a;

  --font-display: Poppins, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --radius: 16px;
  --radius-lg: 22px;
  --wrap: 1180px;
  --shadow-sm: 0 1px 2px rgb(33 33 33 / 5%), 0 4px 12px rgb(33 33 33 / 5%);
  --shadow-md: 0 4px 14px rgb(33 33 33 / 7%), 0 12px 32px rgb(33 33 33 / 7%);
  --shadow-lg: 0 8px 24px rgb(33 33 33 / 9%), 0 24px 60px rgb(33 33 33 / 10%);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 4.5rem; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
button, input, textarea { font: inherit; color: inherit; }
ul { list-style: none; margin: 0; padding: 0; }

:where(a, button, textarea, summary):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 6px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 60;
  background: var(--accent); color: var(--accent-ink);
  padding: .75rem 1rem; border-radius: 0 0 var(--radius) 0; font-weight: 600;
}
.skip:focus { left: 0; }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: 1.125rem; }
.wrap--narrow { max-width: 46rem; }

h1, h2, h3, .brand__text { font-family: var(--font-display); font-weight: 700; letter-spacing: -.02em; }

/* -----------------------------------------------------------  decoration */

/* Small Halloween marks used across the page. Drawn as masks rather than
   coloured images so they take their colour from the palette like everything
   else, and so a palette swap on site two carries them along. */
:root {
  --web: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.4'%3E%3Cpath d='M0 0 L100 100 M0 0 L100 45 M0 0 L45 100 M0 0 L100 74 M0 0 L74 100'/%3E%3Cpath d='M22 0 A22 22 0 0 1 0 22 M40 0 A40 40 0 0 1 0 40 M60 0 A60 60 0 0 1 0 60 M82 0 A82 82 0 0 1 0 82'/%3E%3C/g%3E%3C/svg%3E");
  --bats: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 40'%3E%3Cg fill='%23000'%3E%3Cpath d='M30 20c-4-3.4-7-2.6-8.6-.3-.7-2.6-2.4-4.5-4.8-5.6 1.4 2.6 1.4 4.8.3 6.9l-4.5-2.4 4.5 4.8L21.4 21 26 23.4 30 20Z'/%3E%3Cpath d='M78 12c-3-2.6-5.3-2-6.5-.2-.5-2-1.8-3.4-3.6-4.2 1 2 1 3.6.2 5.2l-3.4-1.8 3.4 3.6L71 12.7l3.4 1.8L78 12Z'/%3E%3Cpath d='M110 28c-2.4-2-4.2-1.6-5.2-.2-.4-1.6-1.4-2.7-2.9-3.4.8 1.6.8 2.9.2 4.2l-2.7-1.4 2.7 2.9 2.7-1.5 2.7 1.5 2.5-2.1Z'/%3E%3C/g%3E%3C/svg%3E");
}

/* A cobweb in the corner of two sections, and a small flight of bats above
   the theme tiles. Pseudo-elements, so they add no markup and no request, and
   they take their colour from the palette like everything else. */
.section--showcase::before,
.section--faq::before {
  content: ""; position: absolute; top: 0; pointer-events: none;
  width: 9rem; height: 9rem;
  background-color: var(--brand);
  opacity: .08;
  -webkit-mask: var(--web) no-repeat top left / contain;
  mask: var(--web) no-repeat top left / contain;
}
.section--showcase::before { left: 0; }
.section--faq::before { right: 0; transform: scaleX(-1); }

.section--themes::after {
  content: ""; position: absolute; right: 6%; top: .9rem;
  width: 7rem; height: 2.4rem; pointer-events: none;
  background-color: var(--brand);
  opacity: .16;
  -webkit-mask: var(--bats) no-repeat center / contain;
  mask: var(--bats) no-repeat center / contain;
}
.section--themes { position: relative; overflow: hidden; }
@media (max-width: 46em) { .section--themes::after { display: none; } }

/* --------------------------------------------------------------- top bars */

/* Warm, quiet, and out of the way. It used to be a purple gradient, which was
   the first thing anyone saw and the darkest thing on the page. */
.announce {
  margin: 0;
  background: var(--accent-soft);
  color: var(--ink);
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  text-align: center;
  font-size: .8rem;
  font-weight: 600;
  padding: .5rem 1rem;
  line-height: 1.4;
}

.siteheader {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.siteheader__inner {
  display: flex; align-items: center; gap: 1rem;
  min-height: 3.75rem;
}

.brand {
  display: inline-flex; align-items: center; gap: .55rem;
  text-decoration: none; color: var(--ink);
  padding-block: .6rem;         /* lifts the tap target to 44px */
  min-width: 0;                 /* the wordmark shrinks before the CTA wraps */
}
.brand__mark {
  display: grid; place-items: center; color: var(--brand-ink);
  width: 2.1rem; height: 2.1rem; border-radius: 11px;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  flex: 0 0 auto;
}
.brand__text { font-size: clamp(.92rem, 3.6vw, 1.05rem); line-height: 1.05; }
.brand__a { color: var(--ink); }
.brand__b { color: var(--accent-text); }

.nav { display: none; margin-left: auto; }
.nav__list { display: flex; gap: 1.35rem; }
.nav__link {
  text-decoration: none; color: var(--ink-dim); font-size: .92rem; font-weight: 600;
  padding-block: .7rem;         /* keeps the target comfortable on a tablet */
}
.nav__link:hover { color: var(--brand); }
.nav__cta { margin-left: auto; flex: 0 0 auto; }

@media (min-width: 52em) {
  .nav { display: block; }
  .nav__cta { margin-left: 0; }
}

/* ------------------------------------------------------------------ hero */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 88% 8%, var(--hero-bg-3) 0%, transparent 58%),
    linear-gradient(165deg, var(--hero-bg) 0%, var(--hero-bg-2) 62%, var(--hero-bg-3) 100%);
  color: var(--hero-ink);
  padding-top: 1.75rem;
  padding-bottom: 2rem;
  border-bottom: 1px solid color-mix(in srgb, var(--brand) 10%, transparent);
}

/* Christa's illustration: moon, bats, haunted house, bare trees, pumpkins.
   Its own left third is transparent, so it needs no mask and no gradient of
   ours - it simply stops before it reaches the headline. Decoration only. */
.hero__scene {
  position: absolute; inset: 0; z-index: -1;
  pointer-events: none;
  overflow: hidden;
}
/* On a phone the hero is tall enough that art anchored to its foot never gets
   seen - it sits below the fold, behind the feature cards, and the page opens
   with no Halloween in it at all. So on small screens it is pinned to the TOP
   corner instead, faded back far enough that the headline still carries. */
.hero__art {
  position: absolute; top: -1rem; right: -18%; bottom: auto;
  width: 128%; height: auto;
  opacity: .34;
}

.hero__inner { position: relative; }
.hero__copy { position: relative; min-width: 0; }

.hero__eyebrow {
  display: inline-flex; align-items: center; gap: .4rem;
  margin: 0 0 .8rem;
  padding: .35rem .85rem;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--brand) 18%, transparent);
  box-shadow: var(--shadow-sm);
  font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; font-weight: 800;
  color: var(--brand);
}

.hero__headline {
  font-size: clamp(2.05rem, 7.6vw, 3.35rem);
  line-height: 1.06;
  margin: 0 0 .8rem;
  max-width: 15ch;
  text-wrap: balance;
}
.hero__headline .hl { color: var(--accent-text); }

.hero__sub {
  margin: 0 0 1.1rem;
  max-width: 36rem;
  color: var(--hero-ink-dim);
  font-size: 1rem;
}
.hero__sub strong { color: var(--ink); font-weight: 700; }

/* ------------------------------------------------- hero composition

   TWO ZONES. The copy and the generator own the left; one large costume
   photograph owns the upper right. The illustration is the ground both stand
   on - it keeps the whole hero width but drops back in weight and sits
   BEHIND the photo card, so the moon and bats read as sky around a
   foreground object rather than as artwork the photo was dropped onto.

   Mobile inverts this into a deliberate order rather than a shrink: the
   generator stays first because it is the primary action, and the photograph
   follows it. See the 375px block near the foot of this file. */

.herophoto {
  position: relative;
  display: grid;
  justify-items: center;
  gap: .75rem;
  margin: 1.5rem 0 0;
}
.herophoto[hidden] { display: none; }

/* The warm halo that makes the card a foreground object rather than a
   rectangle floating on the illustration. */
.herophoto::before {
  content: "";
  position: absolute; inset: -8% -6% 12%;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--accent) 26%, transparent),
    transparent 72%);
  filter: blur(18px);
  z-index: -1;
  pointer-events: none;
}

/* MOBILE SHAPE. A 3/4 portrait at 375px is a 500px block of scroll between
   the generator and the rest of the page. 5/4 keeps the costume large and
   unmistakably a photograph while costing ~300px, and `contain` means the
   full-length figure is never cropped at the knees to make it fit. */
.herophoto__frame {
  position: relative;
  width: 100%;
  max-width: 21rem;
  aspect-ratio: 5 / 4;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--brand) 16%, transparent);
  box-shadow: var(--shadow-lg);
}
/* `contain`: retailer shots are full-length figures on white, and cropping
   them to fill decapitates the costume. The card background matches the
   shot's own, so it reads as one object. */
.herophoto__img { width: 100%; height: 100%; object-fit: contain; }

.herophoto__cta { width: 100%; max-width: 21rem; }

/* Inside the frame, on the card's own white. Outside it, this sat over the
   haunted house and was unreadable. */
.herophoto__caption {
  position: absolute; inset: auto 0 0 0;
  margin: 0;
  display: grid;
  gap: .1rem;
  padding: 1.6rem .9rem .7rem;
  background: linear-gradient(180deg, transparent, var(--surface) 42%);
  font-family: var(--font-display); font-weight: 700;
  font-size: .8rem; line-height: 1.25; color: var(--ink);
}
.herophoto__retailer {
  font-family: var(--font-body); font-weight: 400;
  font-size: .72rem; color: var(--ink-dim);
}

/* ------------------------------------------------------------- generator */

/* Front and centre, and the widest thing on the hero: one field, one button. */
.generator { position: relative; max-width: 46rem; }

/* The old h1. Smaller than the headline now, and the only orange in the
   hero - which is what keeps the generator obviously the main action while
   the H1 carries the site. */
.generator__hook {
  margin: 0 0 .6rem;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.05rem, 3.4vw, 1.35rem);
  line-height: 1.25;
  letter-spacing: -.01em;
  text-wrap: balance;
}
.generator__hook .hl { color: var(--accent-text); }

.generator__form {
  display: grid;
  gap: .6rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: .6rem;
}

.generator__field {
  position: relative;
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .6rem .5rem .6rem .75rem;
  min-width: 0;
}
.generator__field-icon {
  /* The wand sits on white at 20px. The raw orange is 2.36:1 there — faint
     even for decoration, and it reads as washed out beside the placeholder. */
  flex: 0 0 auto; color: var(--accent-text); display: grid; place-items: center;
  padding-top: .1rem;
}

.generator__input {
  flex: 1 1 auto; min-width: 0;
  border: 0; background: none; resize: none;
  line-height: 1.5;
  padding: 0 0 1.1rem;
  max-height: 8rem; overflow-y: auto;
}
.generator__input::placeholder { color: color-mix(in srgb, var(--ink-dim) 70%, transparent); }
.generator__input:focus { outline: none; }
.generator__form:focus-within { border-color: var(--brand); box-shadow: var(--shadow-lg); }

.generator__counter {
  position: absolute; right: .6rem; bottom: .15rem;
  font-size: .72rem; font-variant-numeric: tabular-nums; color: var(--ink-dim);
}
.generator__counter.is-full { color: var(--accent-text); font-weight: 700; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  border: 1.5px solid transparent;
  border-radius: 999px;
  padding: .75rem 1.25rem;
  font-weight: 700;
  font-family: var(--font-display);
  cursor: pointer;
  min-height: 2.75rem;              /* 44px touch target */
  text-decoration: none;
  white-space: nowrap;              /* "Get ideas" must never break in two */
  transition: transform .12s ease, background .12s ease, opacity .12s ease, box-shadow .12s ease;
}
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .6; cursor: progress; }

.btn--brand {
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  color: var(--brand-ink);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--brand) 30%, transparent);
}
.btn--brand:hover:not([disabled]) { filter: brightness(1.08); }

.btn--accent {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--accent-ink);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 34%, transparent);
}
.btn--accent:hover:not([disabled]) { filter: brightness(1.06); }

.btn--ghost { background: var(--surface); color: var(--ink); border-color: var(--line); }
.btn--ghost:hover { background: var(--surface-2); border-color: var(--brand); }

.btn--sm { padding: .5rem .9rem; min-height: 2.25rem; font-size: .85rem; }
.btn--lg { padding: .85rem 1.4rem; font-size: 1rem; }

.generator__button { width: 100%; }
.generator__button-icon { display: grid; place-items: center; }

.generator__status { margin: .9rem 0 0; font-size: .88rem; color: var(--ink-dim); }
.generator__status--warn { color: var(--accent-text); font-weight: 600; }
.generator__status--ok { color: var(--brand); font-weight: 600; }

/* One line of guidance under the field. The placeholder says what to write;
   this shows what a good answer looks like. */
.generator__hint {
  margin: .65rem .25rem 0;
  font-size: .82rem; color: var(--hero-ink-dim);
}

/* Microcopy, not cards: four short promises under the field. Two up on a
   phone, because four stacked lines is a wall. */
.benefits {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: .45rem .9rem;
  margin-top: .9rem;
}
@media (min-width: 46em) { .benefits { display: flex; flex-wrap: wrap; gap: .5rem 1.1rem; } }
.benefit { display: flex; align-items: center; gap: .4rem; font-size: .8rem; }
.benefit__icon { flex: 0 0 auto; display: grid; place-items: center; color: var(--brand); }
.benefit__label { color: var(--hero-ink-dim); }

/* -------------------------------------------------------------- features */

.features__list { display: grid; gap: .75rem; margin-top: 1.75rem; }

.feature {
  display: flex; align-items: flex-start; gap: .75rem;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand) 12%, transparent);
  border-radius: var(--radius);
  padding: .85rem 1rem;
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(4px);
}
.feature__icon {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 2.4rem; height: 2.4rem; border-radius: 12px;
  background: var(--accent-soft);
  color: var(--brand);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
}
.feature__body { display: grid; gap: .1rem; }
.feature__title { font-family: var(--font-display); font-size: .95rem; }
.feature__text { font-size: .84rem; color: var(--ink-dim); line-height: 1.45; }

/* ---------------------------------------------------- generated ideas */

.generator__output:empty { display: none; }
.generator__output { margin-top: 1.25rem; }
.ideas__lead { margin: 0 0 .6rem; font-size: .85rem; color: var(--ink-dim); }

.ideas { display: grid; gap: .85rem; }

.idea {
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 4px solid var(--accent);
  border-radius: var(--radius);
  padding: 1rem;
  box-shadow: var(--shadow-sm);
  animation: rise .32s ease both;
  animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.idea__name {
  display: flex; align-items: center; gap: .5rem;
  font-size: 1.05rem; margin: 0 0 .5rem; line-height: 1.25;
}
.idea__name-icon { color: var(--brand); flex: 0 0 auto; display: grid; place-items: center; }

.idea__label { color: var(--brand); font-weight: 700; }
.idea__reason { margin: 0 0 .55rem; font-size: .92rem; }
.idea__accessory { margin: 0 0 .35rem; font-size: .86rem; color: var(--ink-dim); }
.idea__accessory-label { color: var(--accent-text); font-weight: 700; }
.idea__funny { margin: .55rem 0 0; font-size: .85rem; font-style: italic; color: var(--ink-dim); }

/* "Make it happen": the real products behind the idea. */
.makeit { margin: .7rem 0 0; }
.makeit__label { display: block; font-size: .82rem; font-weight: 700; margin-bottom: .45rem; }
.makeit__list { display: flex; flex-wrap: wrap; gap: .45rem; }

.piece {
  display: flex; align-items: center; gap: .55rem;
  background: var(--bg-tint);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .3rem .85rem .3rem .3rem;
  text-decoration: none; color: var(--ink);
  max-width: 100%;
  transition: border-color .12s ease, background .12s ease;
}
.piece:hover { border-color: var(--brand); background: var(--surface); }
.piece__media {
  flex: 0 0 auto; width: 2.1rem; height: 2.1rem; border-radius: 50%;
  overflow: hidden; background: var(--surface); display: grid; place-items: center;
}
.piece__media img { width: 100%; height: 100%; object-fit: cover; }
.piece__body { display: grid; min-width: 0; }
.piece__name {
  font-size: .78rem; font-weight: 700; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 11rem;
}
.piece__retailer { font-size: .68rem; color: var(--ink-dim); line-height: 1.2; }

.piece--diy {
  background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--accent-text); font-weight: 700; font-size: .78rem;
  padding: .5rem .9rem; cursor: default;
}
.piece--diy .piece__body { max-width: 16rem; }
.piece--diy .piece__name { white-space: normal; max-width: none; color: var(--accent-text); }

/* Skeleton loader, not a spinner: the shape of what is coming. */
.idea--skeleton { animation: none; border-top-color: var(--line); }
.sk {
  display: block; border-radius: 6px;
  background: linear-gradient(90deg, var(--bg-tint) 25%, var(--line) 37%, var(--bg-tint) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
.sk--title { height: 1.15rem; width: 60%; margin-bottom: .6rem; }
.sk--line { height: .78rem; width: 100%; margin-bottom: .4rem; }
.sk--short { width: 70%; }
.sk--chip { height: 1.9rem; width: 11rem; margin-top: .7rem; border-radius: 999px; }

/* ---------------------------------------------------------------- chips */

.chips { display: flex; flex-wrap: wrap; gap: .4rem; }

.chip {
  background: var(--surface);
  border: 1.5px solid var(--line);
  color: var(--ink);
  border-radius: 999px;
  padding: .45rem .85rem;
  font-size: .85rem; font-weight: 600;
  cursor: pointer;
  min-height: 2.75rem;          /* 44px: these are the main controls on a phone */
  display: inline-flex; align-items: center; gap: .4rem;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.chip:hover { border-color: var(--brand); color: var(--brand); }
.chip.is-active {
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  border-color: transparent; color: var(--brand-ink);
}
.chip__count { font-size: .72rem; opacity: .7; font-variant-numeric: tabular-nums; }

.chip--theme {
  background: var(--surface); border-color: var(--brand);
  color: var(--brand); font-size: .8rem; margin-top: .7rem;
}
.chip--theme:hover { background: var(--brand); color: var(--brand-ink); }

.chip--ghost {
  background: var(--accent-soft); border-color: transparent;
  color: var(--accent-text); font-size: .7rem; padding: .22rem .55rem; min-height: 0;
}

/* -------------------------------------------------------------- sections */

.section { padding-block: 2.5rem; }
.section--trending { background: var(--bg); padding-top: 2.25rem; }
.section--categories { background: var(--bg); }
.section--themes { background: var(--bg-tint); }
.section--grid { background: var(--bg); }
.section--showcase { background: var(--bg-tint); position: relative; overflow: hidden; }
.section--prose { background: var(--bg); }
.section--faq { background: var(--bg-tint); position: relative; overflow: hidden; }

.section__heading { font-size: clamp(1.4rem, 5.2vw, 2rem); line-height: 1.15; margin: 0 0 .4rem; text-wrap: balance; }
.section__sub { margin: 0 0 1.4rem; color: var(--ink-dim); max-width: 46rem; }

.sectionhead {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  margin-bottom: 1.1rem;
}
.sectionhead .section__heading { margin-bottom: 0; }
.seeall {
  flex: 0 0 auto;
  color: var(--accent-text); font-weight: 700; font-size: .88rem; text-decoration: none;
  white-space: nowrap;
}
.seeall:hover { text-decoration: underline; }

/* ----------------------------------------------------- trending strip */

.trending {
  display: grid; gap: .85rem;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 56em) { .trending { grid-template-columns: repeat(4, 1fr); gap: 1.25rem; } }

.tcard {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-sm);
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.tcard:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--brand); }
.tcard__media {
  aspect-ratio: 4 / 3; background: var(--bg-tint);
  display: grid; place-items: center; overflow: hidden;
}
.tcard__media img { width: 100%; height: 100%; object-fit: contain; }
.tcard__body { padding: .75rem .8rem .85rem; display: flex; flex-direction: column; gap: .2rem; flex: 1; }
.tcard__title {
  margin: 0; font-size: .9rem; line-height: 1.3;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.tcard__title a { color: var(--ink); text-decoration: none; }
.tcard__title a:hover { color: var(--brand); }
.tcard__retailer { font-size: .75rem; color: var(--ink-dim); margin: 0 0 .55rem; }
.tcard__out {
  margin-top: auto;
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  color: var(--accent-text);
  border-radius: 999px; padding: .5rem .9rem;
  font-weight: 700; font-size: .8rem; font-family: var(--font-display);
  text-decoration: none; white-space: nowrap;
  min-height: 2.4rem;
}
.tcard__out:hover { background: var(--accent); color: var(--accent-ink); border-color: transparent; }

/* ------------------------------------------------- category browser row */

.catrow {
  display: flex; gap: 1rem;
  overflow-x: auto;
  padding: .25rem .25rem 1rem;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.catrow__item { flex: 0 0 auto; scroll-snap-align: start; }

.cat {
  display: grid; justify-items: center; gap: .55rem;
  background: none; border: 0; cursor: pointer; padding: 0;
  width: 6rem;
}
.cat__media {
  width: 6rem; height: 6rem; border-radius: 50%;
  overflow: hidden; display: grid; place-items: center;
  background: var(--surface-2);
  border: 3px solid color-mix(in srgb, var(--brand) 14%, transparent);
  box-shadow: var(--shadow-sm);
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.cat:hover .cat__media { border-color: var(--accent); transform: translateY(-3px); box-shadow: var(--shadow-md); }
.cat__media img { width: 100%; height: 100%; object-fit: cover; }
.cat__fallback { color: var(--brand); }
.cat__label { font-size: .85rem; font-weight: 700; font-family: var(--font-display); line-height: 1.2; text-align: center; }

/* ------------------------------------------------------- theme tiles */

.tiles {
  display: grid; gap: .75rem;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 40em) { .tiles { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 68em) { .tiles { grid-template-columns: repeat(6, 1fr); } }

.tile {
  position: relative; display: block; width: 100%;
  border: 0; padding: 0; cursor: pointer;
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 3 / 4;
  background: var(--night);
  box-shadow: var(--shadow-sm);
  transition: transform .15s ease, box-shadow .15s ease;
}
.tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.tile img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: .85;
  transition: transform .3s ease;
}
.tile:hover img { transform: scale(1.05); }
.tile__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 35%, rgb(0 0 0 / 72%) 100%);
}
.tile__label {
  position: absolute; inset: auto 0 0 0;
  padding: .6rem .6rem .7rem;
  color: #fff; font-family: var(--font-display); font-weight: 700;
  font-size: .8rem; line-height: 1.2; text-align: center;
  text-shadow: 0 1px 6px rgb(0 0 0 / 60%);
}

/* --------------------------------------------------------------- filters */

.filters { display: grid; gap: .85rem; margin-bottom: 1.5rem; }
.filters__group { display: grid; gap: .5rem; }
.filters__label { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-dim); font-weight: 800; }
.filters__summary { margin: 0; font-size: .85rem; color: var(--ink-dim); }

.search {
  position: relative; display: flex; align-items: center; gap: .5rem;
  background: var(--surface); border: 1.5px solid var(--line);
  border-radius: 999px; padding: .1rem .6rem .1rem .9rem;
  max-width: 26rem;
}
.search:focus-within { border-color: var(--brand); }
.search__icon { flex: 0 0 auto; color: var(--ink-dim); display: grid; place-items: center; }
.search__input {
  flex: 1 1 auto; min-width: 0; border: 0; background: none;
  padding: .65rem 0; font-size: .9rem;
}
.search__input:focus { outline: none; }
.search__clear {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  color: var(--ink-dim); font-size: 1.2rem; line-height: 1;
  width: 2rem; height: 2rem; border-radius: 50%;
}
.search__clear:hover { background: var(--bg-tint); color: var(--ink); }
.search__clear[hidden] { display: none; }

/* Theme row scrolls sideways on a phone rather than eating half the screen.
   Every theme stays reachable - none are hidden or folded together, however
   few products a theme currently holds. */
.filters__row--themes .chips {
  flex-wrap: nowrap; overflow-x: auto; padding-bottom: .35rem;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch;
}
.filters__row--themes .chip { flex: 0 0 auto; }

@media (min-width: 40em) {
  .filters__row--themes .chips { flex-wrap: wrap; overflow: visible; }
}

/* ------------------------------------------------------------------ grid */

.grid { display: grid; gap: .85rem; grid-template-columns: repeat(2, 1fr); }

@media (min-width: 48em) { .grid { grid-template-columns: repeat(3, 1fr); gap: 1.25rem; } }
@media (min-width: 68em) { .grid { grid-template-columns: repeat(4, 1fr); } }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-sm);
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--brand); }

/* Real retailer photography, taken from the shop that sells the item - never
   generated art, and never a generated likeness of a licensed character.
   `contain` because product shots arrive on assorted backgrounds. */
.card__media {
  background: var(--bg-tint);
  aspect-ratio: 4 / 5;
  display: grid; place-items: center; overflow: hidden;
}
.card__media img { width: 100%; height: 100%; object-fit: contain; }
.card__media--lowres img { padding: 12%; }
.card__media--failed img { display: none; }
.card__noimage { font-size: 2.25rem; opacity: .3; }

.card__body { padding: .7rem .75rem .85rem; display: flex; flex-direction: column; gap: .4rem; flex: 1; }
.card__title { margin: 0; font-size: .92rem; line-height: 1.3; }
.card__link { color: var(--ink); text-decoration: none; }
.card__link:hover { color: var(--brand); }

/* Two lines, everywhere. Christa: shorter descriptions so more costumes fit
   on the browse page. The full text is still in the JSON-LD for crawlers. */
.card__desc {
  margin: 0; font-size: .8rem; color: var(--ink-dim); line-height: 1.4;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.card__desc--empty { font-style: italic; opacity: .8; }

.card__themes { display: flex; flex-wrap: wrap; gap: .3rem; }
.card__themes .chip--ghost:nth-child(n+2) { display: none; }
@media (min-width: 48em) { .card__themes .chip--ghost:nth-child(n+2) { display: inline-flex; } }

.card__meta {
  margin: auto 0 0; padding-top: .5rem; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: .35rem;
  flex-wrap: wrap;              /* two-up cards at 320px cannot fit one line */
  font-size: .74rem;
  min-width: 0;
}
.card__retailer {
  color: var(--ink-dim);
  min-width: 0; flex: 1 1 auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.card__out { color: var(--accent-text); font-weight: 700; text-decoration: none; white-space: nowrap; flex: 0 0 auto; }
.card__out:hover { text-decoration: underline; }

@media (min-width: 48em) {
  .card__body { padding: .9rem .95rem 1rem; gap: .45rem; }
  .card__title { font-size: 1rem; }
  .card__desc { font-size: .84rem; }
  .card__media { aspect-ratio: 1 / 1; }
}

.grid__empty, .grid__loading, .grid__error {
  grid-column: 1 / -1; margin: 0; padding: 2.5rem 1rem; text-align: center; color: var(--ink-dim);
}

.more { display: block; margin: 1.75rem auto 0; }
.more[hidden] { display: none; }

/* ----------------------------------------------------------- trust strip */

.trust { background: var(--accent-soft); padding-block: 1.5rem; }
.trust__list { display: grid; gap: 1rem; }
.trust__item { display: flex; align-items: flex-start; gap: .75rem; }
.trust__icon {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 2.4rem; height: 2.4rem; border-radius: 12px;
  background: var(--surface); color: var(--brand);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.trust__body { display: grid; gap: .05rem; }
.trust__title { font-family: var(--font-display); font-weight: 700; font-size: .9rem; }
.trust__text { font-size: .82rem; color: var(--ink-dim); line-height: 1.4; }

@media (min-width: 46em) { .trust__list { grid-template-columns: repeat(3, 1fr); gap: 1.5rem; } }

/* ----------------------------------------------------- worked example */

.showcase { display: grid; gap: 1rem; align-items: start; }

.showcase__prompt {
  position: relative;
  background: var(--surface-2);
  border: 1px solid color-mix(in srgb, var(--brand) 16%, transparent);
  border-radius: var(--radius) var(--radius) var(--radius) 4px;
  padding: 1rem 1.1rem;
  font-size: .92rem; font-style: italic; color: var(--ink);
  margin: 0;
}
.showcase__prompt::after {
  content: ""; position: absolute; left: 1.5rem; bottom: -9px;
  width: 0; height: 0;
  border: 9px solid transparent;
  border-top-color: var(--surface-2); border-bottom: 0;
}

.showcase__card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  padding: 1.1rem;
}
.showcase__foot { margin: .9rem 0 0; }

@media (min-width: 52em) {
  .showcase { grid-template-columns: 1fr 1.9fr; gap: 1.5rem; }
  .showcase__prompt { border-radius: var(--radius) var(--radius) 4px var(--radius); align-self: center; }
  .showcase__prompt::after {
    left: auto; right: -9px; bottom: auto; top: 50%; transform: translateY(-50%);
    border: 9px solid transparent; border-left-color: var(--surface-2); border-right: 0;
  }
}

/* ----------------------------------------------------------------- prose */

.prose__stack { display: grid; gap: 1.25rem; }
.prose {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
}
.prose__heading { font-size: 1.1rem; margin: 0 0 .5rem; line-height: 1.3; font-weight: 700; }
.prose p { margin: 0 0 .75rem; color: var(--ink-dim); font-size: .92rem; }
.prose p:last-child { margin-bottom: 0; }

@media (min-width: 52em) { .prose__stack { grid-template-columns: repeat(2, 1fr); gap: 1.25rem; } }

/* ------------------------------------------------------------------- FAQ */

.faq { display: grid; gap: .6rem; }
.faq__item {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
}
.faq__item[open] { border-color: var(--brand); }

.faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .95rem 1rem;
  font-weight: 700; font-family: var(--font-display); font-size: .95rem;
  cursor: pointer; list-style: none; min-height: 2.75rem;
}
.faq__q::-webkit-details-marker { display: none; }

.faq__marker { position: relative; flex: 0 0 auto; width: .8rem; height: .8rem; }
.faq__marker::before, .faq__marker::after {
  content: ""; position: absolute; inset: 50% 0 auto 0;
  height: 2px; background: var(--accent); border-radius: 2px; transition: transform .18s ease;
}
.faq__marker::after { transform: rotate(90deg); }
.faq__item[open] .faq__marker::after { transform: rotate(0deg); }

.faq__a { padding: 0 1rem 1rem; }
.faq__a p { margin: 0; color: var(--ink-dim); font-size: .92rem; }

/* ---------------------------------------------------------------- footer */

/* The only dark surface on the page. */
.footer {
  position: relative;
  overflow: hidden;
  background: linear-gradient(160deg, var(--night), var(--night-2));
  color: var(--night-ink-dim);
  padding-block: 2.5rem 2.75rem;
  font-size: .85rem;
}
/* On a phone the pumpkins sat over the copyright line and the disclosure -
   there is no free corner at 375px, so tucking it into one just buries text.
   It flows below the copy instead, centered, as a closing flourish. It only
   becomes a corner decoration once the footer is wide enough to have a corner
   that is genuinely empty. */
.footer__scene {
  width: min(58%, 13rem);
  margin: 1.75rem auto 0;
  pointer-events: none;
}
.footer__scene img { width: 100%; height: auto; }

@media (min-width: 46em) {
  .footer__scene {
    position: absolute; right: 0; bottom: 0;
    width: min(44%, 16rem);
    margin: 0;
  }
}

.footer__top { display: grid; gap: 1.5rem; margin-bottom: 1.75rem; }
.footer__brand { display: grid; gap: .6rem; max-width: 24rem; }
.footer__lockup { display: inline-flex; align-items: center; gap: .55rem; color: var(--night-ink); }
.footer__lockup .brand__mark { background: var(--surface); color: var(--brand); }
.footer__lockup .brand__text { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; }
.footer__lockup .brand__a { color: var(--night-ink); }
.footer__lockup .brand__b { color: var(--accent-text); }
.footer__strap { margin: 0; color: var(--night-ink-dim); }

.footer__cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; }
.footer__colheading {
  font-family: var(--font-display); font-weight: 700; font-size: .9rem;
  color: var(--night-ink); margin: 0 0 .5rem;
}
.footer__links { display: grid; gap: .35rem; }
.footer__links a { color: var(--night-ink-dim); text-decoration: none; }
.footer__links a:hover { color: var(--accent); }

.footer__disclosure { margin: 0 0 .75rem; max-width: 46rem; }
.footer__note { margin: 0 0 .75rem; max-width: 46rem; }
.footer__legal { margin: 0; opacity: .65; }

@media (min-width: 46em) {
  .footer__top { grid-template-columns: 1.4fr 1fr; gap: 2.5rem; }
  .footer__cols { grid-template-columns: repeat(2, 1fr); }
}

.noscript { padding-block: 1rem; color: var(--ink-dim); }

/* ------------------------------------------------- very small phones */

/* At 320x720 the headline wraps to four lines and pushed the button under the
   fold. Tighten the vertical rhythm rather than shrink the headline, which is
   the thing the client most wants people to read. */
@media (max-width: 23.5em) {
  .announce { font-size: .72rem; padding: .45rem .75rem; }
  .hero { padding-top: 1.25rem; }
  .hero__eyebrow { margin-bottom: .55rem; padding: .28rem .7rem; font-size: .66rem; }
  .hero__headline { margin-bottom: .55rem; }
  .hero__sub { font-size: .92rem; margin-bottom: 1.1rem; }
  .benefits { gap: .4rem .8rem; }
  .benefit { font-size: .76rem; }
  .cat, .cat__media { width: 5rem; }
  .cat__media { height: 5rem; }
}

/* Short viewports (a landscape phone, or a small window) get the same
   treatment, since the constraint is height rather than width. */
@media (max-height: 46em) and (max-width: 46em) {
  .hero { padding-top: 1.25rem; }
  .hero__sub { display: none; }   /* the headline and the box carry the message */
  .benefits { display: none; }
}

/* --------------------------------------------------------- larger screens */

@media (min-width: 46em) {
  .hero { padding-top: 3rem; padding-bottom: 3rem; }
  /* Room for the full scene: back to the foot of the hero, full strength. */
  .hero__art { top: auto; bottom: 0; right: 0; width: min(72%, 40rem); opacity: .85; }
  .generator__form {
    grid-template-columns: 1fr auto;
    align-items: center;
    border-radius: 999px;
    padding: .45rem .45rem .45rem .5rem;
    gap: .5rem;
  }
  .generator__button { width: auto; }
  .features__list { grid-template-columns: repeat(3, 1fr); margin-top: 2rem; }
  .section { padding-block: 3.25rem; }
  .ideas { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 62em) {
  /* THE TWO ZONES. Copy and generator left, one costume photograph right.
     The photo column is the narrower of the two so the generator stays the
     widest element on the page - it is still the primary action. */
  .hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(17rem, .78fr);
    align-items: center;
    gap: 3rem;
  }
  .herophoto { margin: 0; }
  .herophoto__frame,
  .herophoto__cta { max-width: 22rem; }
  /* Portrait again once there is a column to stand in. */
  .herophoto__frame { aspect-ratio: 3 / 4; }

  /* The illustration keeps the full hero width but drops back in weight, so
     it reads as the ground the photo stands on rather than as a second
     subject competing with it. Anchored to the foot: the house and pumpkins
     sit below the card, the moon and bats stay in the sky beside it. */
  .hero__art {
    top: auto; bottom: 0; right: 0;
    width: min(80%, 46rem);
    opacity: .45;
  }
  .hero__headline { font-size: clamp(2.5rem, 4vw, 3.25rem); }
  .features__list { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 80em) {
  .hero__inner { grid-template-columns: minmax(0, 1.2fr) minmax(19rem, .8fr); gap: 4rem; }
  .hero__art { width: min(72%, 48rem); opacity: .5; }
}

/* ------------------------------------------------- the legal and trust pages
 *
 * One column, generous measure, nothing decorative. These pages exist to be
 * read carefully - by a visitor deciding whether to trust the site, and by an
 * affiliate reviewer deciding whether to approve it - so the only job here is
 * legibility. They use the same tokens as the rest of the site, so a palette
 * change follows them automatically.
 */
.page main { padding: clamp(2rem, 6vw, 4.5rem) 0 clamp(3rem, 8vw, 6rem); }

.legal__body {
  width: min(100% - 2.5rem, 44rem);   /* ~70 characters, the readable measure */
  margin-inline: auto;
}

.legal__eyebrow {
  font-family: var(--font-display); font-weight: 700; font-size: .8rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent-text);
  margin: 0 0 .5rem;
}

.legal__body h1 {
  font-family: var(--font-display); font-weight: 800; color: var(--brand);
  font-size: clamp(1.9rem, 5vw, 2.75rem); line-height: 1.1; margin: 0 0 1rem;
}

.legal__intro { font-size: 1.08rem; line-height: 1.7; margin: 0 0 .75rem; }

.legal__updated {
  font-size: .85rem; color: var(--ink-dim); margin: 0 0 2.5rem;
  padding-bottom: 1.5rem; border-bottom: 1px solid var(--line);
}

.legal__section { margin-bottom: 2.25rem; }

.legal__section h2 {
  font-family: var(--font-display); font-weight: 700; color: var(--ink);
  font-size: 1.15rem; margin: 0 0 .6rem;
}

.legal__section p { line-height: 1.75; margin: 0 0 .9rem; }
.legal__section p:last-child { margin-bottom: 0; }

/* The one line on the page that has to be impossible to miss: the Amazon
   sentence, and the contact address. */
.legal__lead {
  background: var(--accent-soft); border: 1px solid var(--accent);
  border-radius: 12px; padding: .9rem 1.1rem;
  font-weight: 600; font-size: 1.05rem;
}

.legal__body a { color: var(--accent-text); }
.legal__body a:hover { color: var(--brand); }

.legal__back {
  margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--line);
  font-weight: 600;
}

/* The FTC's guidance is that a disclosure belongs near the links, not only in
   the footer. Quiet by design: it has to be readable, not shouted. */
.grid__disclosure {
  font-size: .85rem; color: var(--ink-dim);
  margin: -.25rem 0 1.25rem;
}
