/* ==========================================================================
   Wrap It Up — dimlight.click/wrap-it-up/
   A table with five wrapped presents on it. Warm paper, pillar-box red, kraft.

   This is the bright window on the street — every sibling project is dark, so
   the light background is doing real work in the skyline. Don't darken it.

   Contrast floor: every text colour here is measured against --paper.
   4.5:1 minimum for anything under 18.66px, which is everything except h1.
   (Learned on Feed It, which shipped functional text at 2.58:1 before anyone
   thought to check.)

   Bump ?v= on every edit — cPanel caches hard.
   ========================================================================== */

:root {
  --paper:    #FBF6EE;   /* page */
  --paper-2:  #F3EADA;   /* cards, recessed areas */
  --ink:      #2A211C;   /* 13.9:1 — body text */
  --ink-soft: #5C4C42;   /*  7.6:1 on plain paper, 5.8:1 over the pattern at its
                          darkest — measured, not guessed */
  --red:      #BE2F2B;   /*  5.9:1 — accents, ribbon, headings */
  --red-deep: #8E211E;
  --gold:     #79591C;   /*  6.0:1 on page, 5.4:1 on the card — the "do this" mode */
  --kraft:    #C08F5E;
  --kraft-2:  #A9784A;
  --line:     rgba(42, 33, 28, 0.16);

  --display: "Bricolage Grotesque", "Trebuchet MS", system-ui, sans-serif;
  --body: "Newsreader", Georgia, "Times New Roman", serif;

  --gap: clamp(2.25rem, 6vw, 3.5rem);

  /* set per wrapping paper on .pile — the boxes read these and nothing else */
  --wrap-bg: var(--kraft);
  --wrap-img: none;
  --ribbon: #BE2F2B;
  --bow: #A32724;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  position: relative;          /* containing block for .decor */
  margin: 0;
  padding: 0 1.25rem 4rem;
  overflow-x: hidden;
  font-family: var(--body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background-color: var(--paper);
  /* patterned paper rather than a blank sheet: a polka grid, a warm wash top
     and bottom, and a faint tooth. All cheap gradients — no filters, no
     images, nothing that costs a repaint. */
  background-image:
    radial-gradient(circle at 50% 50%, rgba(190, 47, 43, 0.11) 0 2.6px, transparent 3.2px),
    radial-gradient(circle at 50% 50%, rgba(138, 106, 34, 0.10) 0 1.7px, transparent 2.3px),
    repeating-linear-gradient(45deg, rgba(42, 33, 28, 0.022) 0 1px, transparent 1px 1.2rem),
    radial-gradient(46rem 26rem at 50% -8rem, rgba(190, 47, 43, 0.15), transparent 72%),
    radial-gradient(52rem 32rem at 50% 104%, rgba(192, 143, 94, 0.22), transparent 72%),
    repeating-linear-gradient(102deg, rgba(42, 33, 28, 0.016) 0 1px, transparent 1px 5px);
  background-size: 2.4rem 2.4rem, 2.4rem 2.4rem, auto, 100% 100%, 100% 100%, auto;
  background-position: 0 0, 1.2rem 1.2rem, 0 0, 0 0, 0 0, 0 0;
  background-attachment: scroll, scroll, scroll, fixed, fixed, scroll;
}

/* a strip of ribbon across the top of the page, because the whole thing is
   meant to look wrapped */
body::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 0.45rem;
  z-index: 6;
  background: repeating-linear-gradient(
    -45deg,
    var(--red) 0 0.7rem,
    #FBF6EE 0.7rem 1.4rem,
    var(--kraft) 1.4rem 2.1rem,
    #FBF6EE 2.1rem 2.8rem);
  box-shadow: 0 1px 3px rgba(42, 33, 28, 0.18);
}

/* ==========================================================================
   DECORATIONS
   Confetti, curls and sparkles scattered by script.js. Everything sits in the
   gutters either side of the 46rem column at readable opacity; anything that
   would land behind text is dropped rather than faded, because I'd rather have
   fewer decorations than a page where the contrast fix quietly stops holding.
   ========================================================================== */
.decor {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.decor svg { position: absolute; top: 0; left: 0; }
.room { position: relative; z-index: 1; }

::selection { background: rgba(190, 47, 43, 0.2); }

a { color: var(--red); text-underline-offset: 3px; }
a:hover { color: var(--red-deep); }

:focus-visible { outline: 3px solid var(--red); outline-offset: 4px; border-radius: 2px; }

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

.room { max-width: 46rem; margin: 0 auto; }

/* --- head --------------------------------------------------------------- */
.head { padding: clamp(2.5rem, 8vw, 4rem) 0 clamp(1.5rem, 4vw, 2.25rem); text-align: center; }

h1 {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(3rem, 12vw, 5.25rem);
  line-height: 0.92;
  letter-spacing: -0.03em;
  margin: 0;
  color: var(--red);
}

.lede {
  margin: 1.1rem auto 0;
  max-width: 40ch;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
}

/* ==========================================================================
   THE PILE
   Five buttons, bottom-aligned so they read as objects standing on a table
   rather than a grid of tiles. Sizes vary because a wide flat box and a tall
   thin one obviously hold different things — that difference is the whole
   reason there are five instead of a dropdown.
   ========================================================================== */
.pile-wrap { margin-top: 0.5rem; }

.pile {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(0.6rem, 2.5vw, 1.5rem);
  min-height: 12rem;          /* reserved: boxes are injected by JS */
}

.table {
  height: 1px;
  margin: 0 auto;
  max-width: 34rem;
  background: linear-gradient(90deg, transparent, var(--line) 12%, var(--line) 88%, transparent);
  box-shadow: 0 10px 16px -14px rgba(42, 33, 28, 0.6);
}

.box {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  padding: 0 0 0.4rem;
  background: none;
  border: 0;
  font-family: var(--display);
  color: var(--ink);
  cursor: pointer;
}

.box__stack {
  position: relative;
  display: block;
  width: var(--w);
  height: var(--h);
  margin: 0 auto;
  transition: transform 220ms cubic-bezier(0.2, 0.9, 0.3, 1.3);
}
.box--wide  { --w: 9.5rem;  --h: 6rem;    }
.box--tall  { --w: 5.5rem;  --h: 9.5rem;  }
.box--cube  { --w: 7rem;    --h: 7rem;    }
.box--small { --w: 5rem;    --h: 5rem;    }
.box--flat  { --w: 10.5rem; --h: 4.25rem; }

.box__body,
.box__lid {
  position: absolute;
  background-color: var(--wrap-bg);
  background-image: var(--wrap-img);
  box-shadow: inset 0 -0.6rem 1rem -0.6rem rgba(42, 33, 28, 0.45);
}
.box__body {
  left: 0; right: 0; bottom: 0; top: 1.1rem;
  border-radius: 2px;
}
.box__lid {
  left: -0.35rem; right: -0.35rem; top: 0;
  height: 1.55rem;
  border-radius: 2px;
  box-shadow: 0 3px 6px -3px rgba(42, 33, 28, 0.5);
  transform-origin: 50% 100%;
  transition: transform 320ms cubic-bezier(0.2, 0.9, 0.3, 1.25);
  z-index: 3;
}

/* Ribbon: an overlay the size of the box, with the two bands drawn as
   pseudo-elements. The first version sized the cross-band in vw and pulled it
   back with a negative margin — which laid out a 100vw element inside every
   box and made the document wider than the viewport at every breakpoint.
   Never use vw for something nested inside a centred column. */
.box__ribbon {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.box__ribbon::before,
.box__ribbon::after {
  content: "";
  position: absolute;
  background: var(--ribbon);
}
.box__ribbon::before {          /* down the front */
  top: 0; bottom: 0; left: 50%;
  width: 0.7rem;
  margin-left: -0.35rem;
}
.box__ribbon::after {           /* across the body */
  left: 0; right: 0; top: 58%;
  height: 0.7rem;
  margin-top: -0.35rem;
}

.box__bow {
  position: absolute;
  top: -0.5rem; left: 50%;
  width: 2.1rem; height: 1.1rem;
  margin-left: -1.05rem;
  z-index: 4;
}
.box__bow::before,
.box__bow::after {
  content: "";
  position: absolute;
  top: 0;
  width: 0.95rem; height: 1.1rem;
  background: var(--bow);
  border-radius: 60% 40% 55% 45%;
}
.box__bow::before { left: 0;  transform: rotate(-16deg); }
.box__bow::after  { right: 0; transform: rotate(16deg); }

.box__label {
  display: block;
  margin-top: 0.7rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  transition: color 160ms ease;
}

/* hover / focus: it lifts. cheap, and it makes five static shapes feel alive */
.box:hover .box__stack,
.box:focus-visible .box__stack { transform: translateY(-0.5rem) rotate(-1deg); }
.box:hover .box__label,
.box:focus-visible .box__label { color: var(--red); }
.box:active .box__stack { transform: translateY(-0.15rem) scale(0.985); }

/* open: the lid comes off and stays off */
.box.is-open .box__lid { transform: translateY(-1.5rem) rotate(-14deg); }
.box.is-open .box__stack { transform: translateY(-0.35rem); }
.box.is-open .box__label { color: var(--red); }
/* tissue paper puffing out of the top */
.box.is-open .box__body::before {
  content: "";
  position: absolute;
  top: -0.55rem; left: 12%; right: 12%;
  height: 1.1rem;
  background: var(--paper);
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  box-shadow: 0 -2px 3px -2px rgba(42, 33, 28, 0.4);
  animation: puff 300ms ease-out both;
}
@keyframes puff {
  from { transform: translateY(0.6rem) scaleY(0.2); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

/* ==========================================================================
   WRAPPING PAPER
   One per box, fixed. A real pile of presents is never wrapped in matching
   paper, and five different papers do the decorative work the old switcher
   was doing without asking the visitor to decide anything.
   ========================================================================== */
.box[data-paper="kraft"] {
  --wrap-bg: #C08F5E;
  --wrap-img: repeating-linear-gradient(48deg, rgba(255,255,255,0.08) 0 2px, transparent 2px 7px);
  --ribbon: #BE2F2B; --bow: #9C2421;
}
.box[data-paper="pinstripe"] {
  --wrap-bg: #FBF6EE;
  --wrap-img: repeating-linear-gradient(90deg, #BE2F2B 0 1px, transparent 1px 0.55rem);
  --ribbon: #BE2F2B; --bow: #9C2421;
}
.box[data-paper="dots"] {
  --wrap-bg: #BE2F2B;
  --wrap-img:
    radial-gradient(circle at 25% 25%, rgba(255,255,255,0.9) 0 2.5px, transparent 3px),
    radial-gradient(circle at 75% 75%, rgba(255,255,255,0.9) 0 2.5px, transparent 3px);
  --ribbon: #FBF6EE; --bow: #E6D9C2;
}
.box[data-paper="dots"] .box__body,
.box[data-paper="dots"] .box__lid { background-size: 1.6rem 1.6rem; }

.box[data-paper="stripes"] {
  --wrap-bg: #FBF6EE;
  --wrap-img: repeating-linear-gradient(48deg, #BE2F2B 0 0.45rem, #FBF6EE 0.45rem 0.95rem);
  --ribbon: #8A6A22; --bow: #6F551A;
}
.box[data-paper="ink"] {
  --wrap-bg: #2A211C;
  --wrap-img:
    radial-gradient(circle at 30% 30%, rgba(199,154,62,0.95) 0 2px, transparent 2.5px),
    radial-gradient(circle at 80% 65%, rgba(199,154,62,0.6) 0 1.4px, transparent 2px);
  --ribbon: #C79A3E; --bow: #A87F2C;
}
.box[data-paper="ink"] .box__body,
.box[data-paper="ink"] .box__lid { background-size: 1.9rem 1.9rem; }

/* light papers need an outline or they vanish into the page */
.box[data-paper="pinstripe"] .box__body,
.box[data-paper="pinstripe"] .box__lid,
.box[data-paper="stripes"] .box__body,
.box[data-paper="stripes"] .box__lid { box-shadow: inset 0 0 0 1px rgba(42, 33, 28, 0.24); }

/* ==========================================================================
   THE CARD
   ========================================================================== */
.out {
  min-height: 15rem;         /* reserved so the card can't shove the page */
  margin-top: var(--gap);
}

.out__empty {
  margin: 0;
  text-align: center;
  color: var(--ink-soft);
  font-style: italic;
}

.card {
  position: relative;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 2.4rem 1.75rem 1.9rem;
  box-shadow: 0 14px 24px -22px rgba(42, 33, 28, 0.8);
  animation: lift 380ms cubic-bezier(0.16, 0.9, 0.3, 1) both;
}
@keyframes lift {
  from { opacity: 0; transform: translateY(1.1rem) rotate(-0.4deg); }
  to   { opacity: 1; transform: none; }
}

/* the gift tag. says who it's for and what day, so the paper choice is
   legible in words and not only in the pattern. */
/* The gift tag: pointed end on the left with the hole punched through the
   point, which is what an actual luggage-style gift tag looks like. The first
   version was a plain rounded rectangle and read as a browser tab.

   clip-path discards the border, so the fill has to carry its own edge —
   hence #D6B47F rather than the paler kraft (1.65:1 against the card, which
   is enough to see without an outline). box-shadow also follows the unclipped
   box, so the shadow is done with filter: drop-shadow instead. */
.card__tag {
  position: absolute;
  top: -0.9rem; left: 1.4rem;
  display: inline-flex;
  align-items: center;
  padding: 0.32rem 0.9rem 0.32rem 2rem;
  font-size: 0.875rem;
  color: #4A3624;               /* 5.8:1 on the tag */
  background: #D6B47F;
  background-image: repeating-linear-gradient(96deg, rgba(255,255,255,0.16) 0 1px, transparent 1px 4px);
  border: 0;
  clip-path: polygon(0.95rem 0, 100% 0, 100% 100%, 0.95rem 100%, 0 50%);
  transform: rotate(-1.6deg);
  filter: drop-shadow(0 2px 2px rgba(42, 33, 28, 0.28));
}
.card__tag::before {          /* the punched hole, in the point */
  content: "";
  position: absolute;
  left: 1.02rem; top: 50%;
  width: 0.44rem; height: 0.44rem;
  margin-top: -0.22rem;
  border-radius: 50%;
  background: var(--paper-2);
  box-shadow: inset 0 0 0 1px rgba(74, 54, 36, 0.45);
}

.card__mode {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red);
}
.card__mode[data-m="do"]  { color: var(--gold); }
.card__mode[data-m="buy"] { color: var(--ink-soft); }

.card__title {
  margin: 0 0 0.7rem;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.65rem, 1.35rem + 1.6vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.card__reason {
  margin: 0;
  max-width: 52ch;
  font-size: 1.125rem;
  line-height: 1.6;
}

.acts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 1.4rem;
}

.btn {
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.7rem 1.35rem;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease;
}
.btn:hover { border-color: var(--red); color: var(--red); }
.btn--main {
  color: var(--paper);
  background: var(--red);
  border-color: var(--red);
}
.btn--main:hover { background: var(--red-deep); border-color: var(--red-deep); color: var(--paper); }

/* --- ad, notes, footer -------------------------------------------------- */
.ad { margin: var(--gap) 0 0; min-height: 100px; }

.notes { margin-top: var(--gap); }
.notes h2 {
  margin-top: 1.9rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.35rem;
  margin: 0 0 0.7rem;
}
.notes p, .notes ul { margin: 0 0 1rem; max-width: 60ch; }
.notes ul { padding-left: 1.2rem; }
.notes li { margin-bottom: 0.4rem; }
.notes a, .notes code { overflow-wrap: anywhere; word-break: break-word; }
.notes code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  padding: 0.1em 0.35em;
  background: rgba(42, 33, 28, 0.07);
  border-radius: 3px;
}
.notes h2 + p { margin-top: 0; }
.notes p:last-child { margin-bottom: 0; }
.notes b { font-weight: 500; color: var(--red); }
.notes__soft { color: var(--ink-soft); font-size: 1rem; }

.foot {
  margin-top: var(--gap);
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}
.foot p { margin: 0; }

/* --- narrow ------------------------------------------------------------- */
@media (max-width: 34rem) {
  body { padding-left: 1rem; padding-right: 1rem; }
  .box--wide  { --w: 7.5rem;  --h: 5rem;   }
  .box--tall  { --w: 4.5rem;  --h: 7.5rem; }
  .box--cube  { --w: 5.5rem;  --h: 5.5rem; }
  .box--small { --w: 4.1rem;  --h: 4.1rem; }
  .box--flat  { --w: 8rem;    --h: 3.5rem; }
  .box__label { font-size: 0.75rem; }
  .card { padding: 2.2rem 1.2rem 1.6rem; }
  .out { min-height: 17rem; }
}

/* --- reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .box__stack, .box__lid, .btn { transition: none; }
  .card { animation: none; }
  .box.is-open .box__body::before { animation: none; }
  .box:hover .box__stack, .box:focus-visible .box__stack { transform: none; }
}
