:root {
  --bg: #f7f4ef;
  --card: #ffffff;
  --text: #1f2328;
  --muted: #6b7280;
  --accent: #b42318;
  --accent-text: #ffffff;
  --border: #e5e1d8;
  --ok: #157f3c;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #15171a;
    --card: #1f2227;
    --text: #e8e6e3;
    --muted: #9aa1ab;
    --accent: #e5484d;
    --border: #33373e;
    --ok: #3fb950;
  }
}
* { box-sizing: border-box; }
body {
  margin: 0;
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--text);
}
.topbar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--card);
}
.brand { font-weight: 700; color: var(--text); text-decoration: none; }
main { max-width: 760px; margin: 0 auto; padding: 16px; }
.card {
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 16px; margin-bottom: 16px;
}
h1, h2, h3 { margin: 0 0 12px; line-height: 1.25; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.15rem; } h3 { font-size: 1rem; }
form { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
label { display: flex; flex-direction: column; gap: 4px; font-size: .85rem; color: var(--muted); flex: 1 1 160px; }
input, select, textarea, button { font: inherit; }
input, select, textarea {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg); color: var(--text); width: 100%;
}
textarea { min-height: 80px; resize: vertical; }
input[type="checkbox"] { width: auto; margin: 0; }
button {
  padding: 8px 14px; border-radius: 8px; border: 1px solid var(--accent);
  background: var(--accent); color: var(--accent-text); cursor: pointer;
}
button.secondary { background: transparent; color: var(--accent); }
button.link { background: none; border: none; color: var(--muted); padding: 4px 6px; text-decoration: underline; }
button:disabled { opacity: .5; cursor: not-allowed; }
.tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.tabs button[aria-pressed="false"] { background: transparent; color: var(--accent); }
ul.list { list-style: none; margin: 0; padding: 0; }
ul.list li {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 8px 0; border-bottom: 1px solid var(--border);
}
ul.list li:last-child { border-bottom: none; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.badge { font-size: .75rem; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.badge.ok { color: var(--ok); border-color: var(--ok); }
.reveal { font-size: 1.4rem; font-weight: 700; color: var(--accent); }
.row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
a { color: var(--accent); }
.preview-bar {
  position: sticky; top: 0; z-index: 5; display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 8px; margin-bottom: 16px; padding: 10px 14px; border-radius: 10px;
  background: var(--text); color: var(--bg);
}
.preview-bar button { background: var(--bg); color: var(--text); border-color: var(--bg); }
.pick-group {
  border: 1px solid var(--border); border-radius: 10px; padding: 12px;
  margin-top: 12px; background: var(--bg);
}
.pick-group h3 {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
  margin: 0 0 10px; padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.pick-names { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
.pick-name {
  background: var(--card); color: var(--text); border: 1px solid var(--border);
  text-align: left; padding: 10px 12px; overflow-wrap: anywhere;
}
.pick-name:hover:not(:disabled), .pick-name:focus-visible { border-color: var(--accent); color: var(--accent); }
.pick-name:disabled { background: transparent; color: var(--muted); opacity: .6; }
.pick-name[hidden], .pick-group[hidden] { display: none; }
#toast {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%);
  background: var(--text); color: var(--bg); padding: 10px 16px; border-radius: 8px;
  max-width: calc(100% - 32px); opacity: 0; pointer-events: none; transition: opacity .2s;
}
#toast.show { opacity: 1; }
dialog.ask {
  border: 1px solid var(--border); border-radius: 12px; padding: 16px;
  background: var(--card); color: var(--text); max-width: min(420px, calc(100% - 32px));
}
dialog.ask::backdrop { background: rgb(0 0 0 / .45); }
dialog.ask p { margin: 0 0 16px; }
.reveal-box { position: relative; }
/* Same height before and after the reveal, so the card doesn't jump when the gift opens. */
.gift-card .reveal-box { min-height: 150px; display: flex; flex-direction: column; justify-content: center; }
.reveal-box li > div { position: relative; }
.reveal-box.hidden .reveal { visibility: hidden; user-select: none; } /* the gift stands in for it */
/* The gift card is centred around the gift and the revealed name. */
.gift-card { text-align: center; }
.gift-card .tabs { justify-content: center; }
.gift-card .reveal-box li { justify-content: center; }
.gift-rules {
  margin-top: 16px; padding: 12px 16px; border-radius: 10px; text-align: left;
  background: var(--bg); border: 1px dashed var(--border);
}
.gift-rules h3 { font-size: .95rem; margin: 0 0 6px; text-align: center; }
.gift-rules ul { margin: 0; padding-left: 20px; }
.gift-rules li + li { margin-top: 4px; }
.reveal-cover {
  position: absolute; inset: 0; display: flex; flex-direction: column; gap: 8px;
  align-items: center; justify-content: center;
}
.gift { font-size: 3.4rem; line-height: 1; filter: drop-shadow(0 6px 10px rgb(0 0 0 / .25)); animation: gift-bob 2.4s ease-in-out infinite; }
.gift.shaking { animation: gift-shake .9s ease-in-out; }
.gift.popping { animation: gift-pop .35s ease-in forwards; }
@keyframes gift-bob { 0%, 100% { transform: translateY(0) rotate(-3deg); } 50% { transform: translateY(-6px) rotate(3deg); } }
@keyframes gift-shake {
  0% { transform: rotate(0) scale(1); }
  15% { transform: rotate(-14deg) scale(1.05); }
  30% { transform: rotate(12deg) scale(1.08); }
  45% { transform: rotate(-10deg) scale(1.12); }
  60% { transform: rotate(8deg) scale(1.16); }
  75% { transform: rotate(-5deg) scale(1.2); }
  100% { transform: rotate(0) scale(1.25); }
}
@keyframes gift-pop { to { transform: scale(2.2); opacity: 0; } }
.reveal { display: inline-block; }
.reveal.spinning { opacity: .8; }
.reveal.landed { animation: reveal-land .7s cubic-bezier(.2, 1.6, .4, 1); }
@keyframes reveal-land {
  0% { transform: scale(.4) rotate(-6deg); opacity: .3; }
  60% { transform: scale(1.25) rotate(2deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); }
}
.reveal-box li > div.glow { animation: name-glow 2.4s ease-out; border-radius: 10px; }
@keyframes name-glow {
  0% { box-shadow: 0 0 0 0 rgb(242 183 5 / 0); background: transparent; }
  20% { box-shadow: 0 0 0 10px rgb(242 183 5 / .35); background: rgb(242 183 5 / .12); }
  100% { box-shadow: 0 0 0 24px rgb(242 183 5 / 0); background: transparent; }
}
.sparkle {
  position: absolute; font-size: 1.1rem; pointer-events: none; opacity: 0;
  animation: sparkle 1.6s ease-in-out forwards;
}
@keyframes sparkle {
  0% { transform: scale(0) rotate(0); opacity: 0; }
  40% { transform: scale(1.3) rotate(90deg); opacity: 1; }
  100% { transform: scale(0) rotate(180deg) translateY(-10px); opacity: 0; }
}
.confetti {
  position: fixed; z-index: 50; pointer-events: none; border-radius: 2px;
  will-change: transform, opacity;
}
.confetti.star { font-size: 1.2rem; }
@media (prefers-reduced-motion: reduce) {
  .gift { animation: none; }
}

/* ---------- festive draw page ---------- */
/* Colour lives in the background and on card edges; card faces stay solid so text keeps
   the same contrast as everywhere else. */
body.festive {
  --festive-red: #c8102e; --festive-green: #0f7b45; --festive-gold: #f2b705; --festive-blue: #1f6fd1;
  background-color: #0e4d33;
  background-image:
    radial-gradient(circle at 12% 18%, rgb(242 183 5 / .55), transparent 28%),
    radial-gradient(circle at 88% 12%, rgb(200 16 46 / .75), transparent 32%),
    radial-gradient(circle at 80% 85%, rgb(31 111 209 / .55), transparent 30%),
    radial-gradient(circle at 15% 90%, rgb(200 16 46 / .6), transparent 30%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cg fill='%23ffffff' fill-opacity='.14'%3E%3Cpath d='M20 10l2.4 5 5.6.8-4 3.9.9 5.5-4.9-2.6-4.9 2.6.9-5.5-4-3.9 5.6-.8z'/%3E%3Ccircle cx='85' cy='30' r='3'/%3E%3Ccircle cx='60' cy='80' r='2'/%3E%3Cpath d='M95 85l1.8 3.7 4.1.6-3 2.9.7 4.1-3.6-1.9-3.6 1.9.7-4.1-3-2.9 4.1-.6z'/%3E%3Ccircle cx='25' cy='100' r='2.5'/%3E%3C/g%3E%3C/svg%3E"),
    linear-gradient(160deg, #0f7b45 0%, #0b5c3b 45%, #7a0f24 100%);
  background-attachment: fixed;
}
@media (prefers-color-scheme: dark) {
  body.festive { background-color: #08281b; }
  body.festive::before {
    content: ''; position: fixed; inset: 0; background: rgb(0 0 0 / .12); pointer-events: none; z-index: -1;
  }
}
body.festive main, body.festive .topbar { position: relative; z-index: 1; }
body.festive .card {
  border: none; border-top: 5px solid var(--festive-red);
  box-shadow: 0 10px 30px rgb(0 0 0 / .25);
}
body.festive main .card:nth-of-type(3n + 2) { border-top-color: var(--festive-green); }
body.festive main .card:nth-of-type(3n) { border-top-color: var(--festive-gold); }
body.festive .card.hero {
  text-align: center; padding-top: 28px; position: relative; overflow: hidden;
  border-top: none;
  background:
    radial-gradient(circle at 10% 0%, rgb(242 183 5 / .18), transparent 40%),
    radial-gradient(circle at 90% 0%, rgb(200 16 46 / .16), transparent 40%),
    var(--card);
}
/* A string of coloured lights along the top of the title card. */
body.festive .card.hero::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 14px;
  background:
    radial-gradient(circle at 10px 9px, var(--festive-red) 4px, transparent 5px) 0 0 / 80px 14px repeat-x,
    radial-gradient(circle at 30px 9px, var(--festive-gold) 4px, transparent 5px) 0 0 / 80px 14px repeat-x,
    radial-gradient(circle at 50px 9px, var(--festive-green) 4px, transparent 5px) 0 0 / 80px 14px repeat-x,
    radial-gradient(circle at 70px 9px, var(--festive-blue) 4px, transparent 5px) 0 0 / 80px 14px repeat-x,
    linear-gradient(var(--border), var(--border)) 0 4px / 100% 1px no-repeat;
  animation: twinkle 2.4s ease-in-out infinite alternate;
}
@keyframes twinkle { from { filter: brightness(1); } to { filter: brightness(1.35) saturate(1.2); } }
body.festive .card.hero h1 { font-size: 1.9rem; margin-bottom: 10px; }
.garland { font-size: 1.4rem; letter-spacing: .25em; margin-bottom: 6px; }
body:not(.festive) .garland { display: none; }
.back-link { color: var(--accent); }
body.festive .back-link {
  display: inline-block; padding: 6px 12px; border-radius: 999px;
  background: var(--card); color: var(--text); text-decoration: none; font-weight: 600;
  box-shadow: 0 4px 14px rgb(0 0 0 / .2);
}
body.festive .pick-group { background: var(--bg); }
body.festive .tabs button[aria-pressed="true"] { box-shadow: 0 0 0 3px rgb(242 183 5 / .45); }

/* Gentle falling snow behind the cards. */
.snow { display: none; }
body.festive .snow {
  display: block; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    radial-gradient(circle, rgb(255 255 255 / .9) 1.5px, transparent 2.5px),
    radial-gradient(circle, rgb(255 255 255 / .7) 1px, transparent 2px),
    radial-gradient(circle, rgb(255 255 255 / .5) 2px, transparent 3px);
  background-size: 140px 140px, 90px 90px, 220px 220px;
  background-position: 0 0, 40px 60px, 100px 30px;
  animation: snowfall 22s linear infinite;
}
@keyframes snowfall {
  to { background-position: 140px 560px, 130px 420px, 100px 910px; }
}
@media (prefers-reduced-motion: reduce) {
  body.festive .snow, body.festive .card.hero::before { animation: none; }
}

/* ---------- sign-in pages: snowy night with northern lights ---------- */
/* A different scene from the draw page (which is red/green daytime festive). The sky is
   decoration only; text is white with a shadow on the dark sky, or on a solid card. */
body.wintry {
  background: linear-gradient(180deg, #0a0f2e 0%, #161a4a 45%, #2b1856 75%, #3d1d4f 100%) fixed;
  min-height: 100vh;
}
body.wintry .topbar {
  position: relative; z-index: 2;
  background: rgb(10 15 46 / .55); border-bottom-color: rgb(255 255 255 / .12);
  backdrop-filter: blur(6px);
}
body.wintry .brand { color: #fff; }
body.wintry main { position: relative; z-index: 1; }
.login-sky { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.aurora {
  position: absolute; width: 70vmax; height: 40vmax; border-radius: 50%;
  filter: blur(60px); opacity: .55; mix-blend-mode: screen;
  animation: aurora 18s ease-in-out infinite alternate;
}
.aurora.a1 { background: radial-gradient(closest-side, #19e3a1, transparent); left: -15vmax; top: -10vmax; }
.aurora.a2 { background: radial-gradient(closest-side, #2fb8ff, transparent); right: -20vmax; top: 0; animation-duration: 22s; animation-delay: -6s; }
.aurora.a3 { background: radial-gradient(closest-side, #ff5fa8, transparent); left: 20vmax; top: 10vmax; opacity: .35; animation-duration: 26s; animation-delay: -12s; }
@keyframes aurora {
  0% { transform: translate(0, 0) rotate(-8deg) scale(1); }
  50% { transform: translate(6vmax, 3vmax) rotate(6deg) scale(1.15); }
  100% { transform: translate(-4vmax, 6vmax) rotate(-2deg) scale(.95); }
}
.moon { position: absolute; right: 8%; top: 9%; font-size: 3.2rem; filter: drop-shadow(0 0 24px rgb(255 240 180 / .8)); }
.star-dot {
  position: absolute; width: 3px; height: 3px; border-radius: 50%; background: #fff;
  box-shadow: 0 0 6px 1px rgb(255 255 255 / .8); animation: twinkle-dot 3s ease-in-out infinite;
}
@keyframes twinkle-dot { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
.floater {
  position: absolute; opacity: .9; filter: drop-shadow(0 6px 10px rgb(0 0 0 / .35));
  animation: floater 7s ease-in-out infinite;
}
@keyframes floater {
  0%, 100% { transform: translateY(0) rotate(-8deg); }
  50% { transform: translateY(-18px) rotate(8deg); }
}
.flake {
  position: absolute; top: -5vh; color: #fff; text-shadow: 0 0 6px rgb(255 255 255 / .7);
  animation-name: flake-fall, flake-sway; animation-timing-function: linear, ease-in-out;
  animation-iteration-count: infinite, infinite; animation-direction: normal, alternate;
}
@keyframes flake-fall { to { transform: translateY(112vh) rotate(360deg); } }
@keyframes flake-sway { from { margin-left: -24px; } to { margin-left: 24px; } }

.login-wrap { position: relative; max-width: 480px; margin: 0 auto; padding-top: 12px; }
.login-wrap > :not(.login-floaters) { position: relative; z-index: 1; }
.login-floaters { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
body.wintry { overflow-x: hidden; }
.login-hero { text-align: center; color: #fff; margin: 8px 0 22px; text-shadow: 0 2px 12px rgb(0 0 0 / .55); }
.login-hero h1 {
  font-size: clamp(1.8rem, 6vw, 2.5rem); margin-bottom: 6px; letter-spacing: .01em;
  background: linear-gradient(90deg, #fff 0%, #ffe9a8 30%, #fff 55%, #ffd1e3 80%, #fff 100%);
  background-size: 200% auto; -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: title-shimmer 6s linear infinite;
  filter: drop-shadow(0 2px 10px rgb(0 0 0 / .5)); text-shadow: none;
}
@keyframes title-shimmer { to { background-position: 200% center; } }
.login-hero p { margin: 0; font-size: 1.05rem; font-weight: 500; }
.login-santa { font-size: 4.5rem; line-height: 1; margin-bottom: 8px; display: inline-block; animation: santa-bounce 2.2s ease-in-out infinite; }
@keyframes santa-bounce {
  0%, 100% { transform: translateY(0) rotate(-6deg); }
  30% { transform: translateY(-16px) rotate(6deg) scale(1.05); }
  60% { transform: translateY(0) rotate(-3deg) scale(.98, 1.02); }
}
.login-card {
  position: relative; border: none; padding: 30px 22px 22px; border-radius: 16px;
  box-shadow: 0 20px 50px rgb(0 0 0 / .45), 0 0 0 6px rgb(255 255 255 / .08);
  overflow: visible;
}
/* Candy-cane stripe along the top of the card. */
.login-card::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 10px; border-radius: 16px 16px 0 0;
  background: repeating-linear-gradient(-45deg, #d42a3c 0 12px, #fff 12px 24px);
  background-size: 34px 10px; animation: candy 1.6s linear infinite;
}
@keyframes candy { to { background-position: 34px 0; } }
.login-bow {
  position: absolute; left: 50%; top: -24px; transform: translateX(-50%); font-size: 2.6rem;
  filter: drop-shadow(0 4px 6px rgb(0 0 0 / .3)); animation: bow-wiggle 3s ease-in-out infinite;
}
@keyframes bow-wiggle { 0%, 100% { transform: translateX(-50%) rotate(-6deg); } 50% { transform: translateX(-50%) rotate(6deg); } }
.login-card h2 { text-align: center; font-size: 1.3rem; }
.login-card > p.muted { text-align: center; }
.login-card form { flex-direction: column; align-items: stretch; }
.login-card label { flex: none; }
.login-card input { padding: 12px 14px; font-size: 1.05rem; }
button.shiny {
  position: relative; overflow: hidden; padding: 12px 16px; font-size: 1.05rem; font-weight: 600;
  background: linear-gradient(135deg, #e0313f, #b42318); border: none; border-radius: 10px;
  box-shadow: 0 6px 16px rgb(180 35 24 / .45); transition: transform .15s, box-shadow .15s;
}
button.shiny:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 10px 22px rgb(180 35 24 / .5); }
button.shiny::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 40%; left: -60%;
  background: linear-gradient(100deg, transparent, rgb(255 255 255 / .45), transparent);
  animation: shine 3.2s ease-in-out infinite;
}
@keyframes shine { 0%, 55% { left: -60%; } 100% { left: 130%; } }
.login-sent { text-align: center; }
.login-sent h3 { font-size: 1.2rem; margin: 6px 0 8px; }
.login-sent p { margin: 0 0 8px; }
.login-sent-icon { font-size: 3.6rem; display: inline-block; animation: mail-in .9s cubic-bezier(.2, 1.4, .4, 1); }
@keyframes mail-in {
  0% { transform: translate(-60px, 40px) rotate(-30deg) scale(.3); opacity: 0; }
  100% { transform: none; opacity: 1; }
}
.login-footer { text-align: center; color: #fff; opacity: .85; margin-top: 18px; text-shadow: 0 2px 8px rgb(0 0 0 / .5); }
@media (prefers-reduced-motion: reduce) {
  .aurora, .star-dot, .floater, .login-santa, .login-card::before, .login-bow, button.shiny::after,
  .login-hero h1, .login-sent-icon { animation: none; }
}
