/* Additions on top of the design system for the live site. */
.topbar a{color:inherit}
.topbar .name{font-family:var(--font-brand);font-size:22px;line-height:1}
.form-card{max-width:520px}
label.lbl{display:block;margin-bottom:6px;font-family:var(--font-emphasis);
  font-size:11px;letter-spacing:.14em;text-transform:uppercase}
input.f,select.f,textarea.f{
  width:100%;border:2px solid var(--color-black);border-radius:var(--radius-base);
  background:var(--color-bg-light);padding:12px var(--space-base);
  font-family:var(--font-body);font-size:var(--font-size-base);color:var(--color-ink)}
input.f:focus,select.f:focus,textarea.f:focus{outline:3px solid var(--color-pink);outline-offset:1px}
button.btn{font-family:var(--font-body);cursor:pointer}
.flash{border:2px solid var(--color-black);border-radius:var(--radius-lg);
  padding:var(--space-base) var(--space-lg);background:var(--color-chartreuse);margin-bottom:var(--space-lg)}
.flash.warn{background:var(--color-pink)}
a.plainlink{color:inherit}

/* Tables */
.ptable{width:100%;border-collapse:collapse;border:2px solid var(--color-black);
  background:var(--color-bg-light);font-size:var(--font-size-sm)}
.ptable th{background:var(--color-black);color:var(--color-white);
  font-family:var(--font-emphasis);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;padding:10px;text-align:left}
.ptable td{border-top:1px solid rgba(0,0,0,.22);padding:10px}
.ptable td.nm{font-weight:600}
.ptable tr.hl td{background:var(--color-chartreuse);font-weight:600}

/* Studio stat boxes reuse .stat/.box from the design system */
.stat .box{border:3px solid var(--color-black);border-radius:var(--radius-lg);
  padding:12px 20px;background:var(--color-bg-light);min-width:150px}
.stat .box .n{font-family:var(--font-brand);font-size:30px;line-height:1;display:block}

/* Built by credit. Its own light strip so the navy mark reads correctly. */
.gl-credit{
  background:var(--color-bg-warm);
  border-top:2px solid var(--color-black);
  padding:var(--space-base) var(--space-lg);
}
.gl-credit .inner{
  max-width:1180px;margin:0 auto;
  display:flex;align-items:center;justify-content:center;gap:10px;
  font-family:var(--font-body);font-size:13px;color:var(--color-ink);
}
.gl-credit img{width:22px;height:22px;display:block;flex:none}
.gl-credit a{
  color:var(--color-ink);font-weight:600;text-decoration:none;
  border-bottom:2px solid var(--color-pink);
  transition:border-color var(--transition-fast);
}
.gl-credit a:hover{border-color:var(--color-black)}
@media(max-width:520px){.gl-credit .inner{flex-direction:column;text-align:center;gap:6px}}

/* ============================================================
   Fun, per the brand guide: layer, overlap, let forms run off
   the edge. Nothing here is a straight line if it can help it.
   ============================================================ */

/* Ribbon squiggle instead of a border.
   The wave is the boundary, not a strip sitting under one. The tile fills
   everything below the wave in the colour of the next section, and the whole
   thing is pulled up over the section above by exactly its own height, so the
   two backgrounds meet along the wave. No straight seam anywhere. */
.squiggle-wrap{
  position:relative;z-index:3;line-height:0;
  margin-top:-44px;pointer-events:none;
}
.squiggle-wrap svg{display:block;width:100%;height:44px}

/* The hero no longer needs a hard edge; the ribbon is the edge. */
.slab.cover{border-bottom:none}

/* Taylor. The badge is built into the art, so no frame and no shadow. */
.taylor{width:100%;max-width:340px;height:auto;display:block}
.taylor.bleed{max-width:400px;margin-right:-40px}

/* Everything tilts a little. */
.tilt-l{transform:rotate(-1.6deg)}
.tilt-r{transform:rotate(1.4deg)}
.tilt-l:hover,.tilt-r:hover{transform:rotate(0)}
.tilt-l,.tilt-r{transition:transform var(--transition-base)}

/* Price cards. The layered block behind is the "colour layering" rule. */
.tiers{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-xl);
  margin-top:var(--space-2xl);margin-right:15px}
/* The layered block is an offset shadow rather than a pseudo element. A tilted
   card forms its own stacking context, which would flip a negative z-index layer
   in front of the card. A shadow cannot break that way. */
.tier{
  position:relative;border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-lg);
  box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black);
}
.tier .count{
  font-family:var(--font-emphasis);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;
}
.tier .amount{font-family:var(--font-brand);font-size:56px;line-height:.95;margin:6px 0 2px}
.tier .per{font-size:12px;opacity:.75}
.tier .byop{
  margin-top:var(--space-base);border-top:2px dashed rgba(0,0,0,.3);padding-top:10px;font-size:13px;
}

/* Luxe. Bigger, deeper, sparkles, and it sits above the others. */
.tier.luxe{
  background:var(--color-lavender);padding:var(--space-xl) var(--space-lg);
  box-shadow:15px 15px 0 0 var(--color-pink), 15px 15px 0 3px var(--color-black);
}
.tier.luxe .amount{font-size:66px}
.tier.luxe .flag{
  position:absolute;top:-16px;left:50%;transform:translateX(-50%) rotate(-2deg);
  background:var(--color-chartreuse);border:3px solid var(--color-black);
  border-radius:var(--radius-full);padding:4px 16px;white-space:nowrap;
  font-family:var(--font-emphasis);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
}
.tier.luxe .spark{position:absolute;width:44px;height:44px}
.tier.luxe .spark.a{top:-18px;right:-14px;transform:rotate(12deg)}
.tier.luxe .spark.b{bottom:-16px;left:-16px;transform:rotate(-18deg)}
.tier.luxe .spark.c{top:-18px;left:-16px;transform:rotate(-14deg)}

/* Feature cards with the icon breaking the top edge.
   The card stays neutral and the colour lives in the offset layer. The party
   icons carry their own blob, and a blob on a bright card reads as a clashing
   sticker; the ink only variant is no good either, because its chartreuse line
   work disappears on a chartreuse field. Neutral ground solves both. */
/* The offset shadow hangs 11px off the right of the last card only, so a grid
   with equal margins reads as sitting left of centre. Giving the grid that
   width back on the right balances the block optically. */
.pops{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-2xl);
  margin-top:var(--space-3xl);margin-right:11px}
/* The icon sits centred over the top edge, so the text is centred under it.
   Left aligned copy under a centred icon is what read as off balance. */
.pop{
  position:relative;border:3px solid var(--color-black);border-radius:var(--radius-xl);
  padding:56px var(--space-lg) var(--space-xl);
  background:var(--color-bg-light);text-align:center;
}
.pop img{
  position:absolute;top:-40px;left:50%;transform:translateX(-50%);
  width:86px;height:86px;
}
.pop .emph{margin-top:4px}
.pop.a{box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.pop.b{box-shadow:11px 11px 0 0 var(--color-pink),       11px 11px 0 3px var(--color-black)}
.pop.c{box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black)}
/* d for use on a periwinkle section, where a periwinkle layer would vanish. */
.pop.d{box-shadow:11px 11px 0 0 var(--color-lavender),   11px 11px 0 3px var(--color-black)}
.pop.warm{background:var(--color-bg-warm)}

/* Steps, numbered and overlapping. */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-2xl);
  margin-top:var(--space-2xl);margin-right:11px;align-items:stretch}
/* Modifier names are prefixed. "two" collided with the .two grid utility in the
   design system sheet and silently turned card two into a two column grid. */
.step-card{
  position:relative;display:block;
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-xl) var(--space-lg) var(--space-lg);
  box-shadow:11px 11px 0 0 var(--color-lavender), 11px 11px 0 3px var(--color-black);
}
.step-card{text-align:center}
.step-card .emph{display:block;margin:0 0 10px}
.step-card .caption{display:block;margin:0}
.step-card.step-2{box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.step-card.step-3{box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black)}
.step-card .num{
  position:absolute;top:-22px;left:-14px;width:52px;height:52px;border-radius:var(--radius-full);
  border:3px solid var(--color-black);background:var(--color-pink);
  display:grid;place-items:center;font-family:var(--font-brand);font-size:28px;
}
.step-card.step-2 .num{background:var(--color-chartreuse)}
.step-card.step-3 .num{background:var(--color-lavender)}

/* The closing call, centred. */
.finale{text-align:center;padding:var(--space-3xl) 0}
.finale .btn{font-size:var(--font-size-lg);padding:20px 44px}
.finale .row{display:flex;justify-content:center;gap:var(--space-base);flex-wrap:wrap;margin-top:var(--space-lg)}
.finale .conf{display:flex;justify-content:center;gap:var(--space-md);margin-bottom:var(--space-lg)}
.finale .conf img{width:42px;height:42px}
.finale .conf img:nth-child(1){transform:rotate(-14deg)}
.finale .conf img:nth-child(3){transform:rotate(16deg)}

@media(max-width:900px){
  .tiers,.pops,.steps{grid-template-columns:1fr;gap:var(--space-2xl)}
  .taylor.bleed{margin-right:0}
}

/* The Book link is a real button, same as everywhere else. */
.topbar a.navbtn{
  background:var(--color-pink);color:var(--color-black);
  border:2px solid var(--color-black);border-radius:12px;
  padding:10px 22px;font-family:var(--font-body);font-weight:600;
  font-size:var(--font-size-base);letter-spacing:0;text-transform:none;
  /* It used to inherit this from .topbar nav a. It lives outside nav now so it
     can stay on the bar when the links collapse. */
  text-decoration:none;
  box-shadow:var(--shadow-sm);
  transition:box-shadow var(--transition-base),transform var(--transition-base);
}
.topbar a.navbtn:hover{box-shadow:var(--shadow-md);transform:translateY(-1px);border-color:var(--color-black)}
.topbar nav{align-items:center}

/* The ribbon mark under the closing line. Whole, centred, nothing clipped. */
/* The brand mark itself, which is long and thin, rather than the party icon
   with its round colour blob. */
/* Length kept, height cut to a quarter. object-fit only sizes the box; the SVG
   preserves its own aspect ratio inside it, which drew the mark small and
   centred. This uses a copy of the mark with preserveAspectRatio none, so it
   genuinely stretches to the box. */
/* True 85:46 proportions, both dimensions given so the width can never
   collapse to the intrinsic value and squash the mark. */
.finale-ribbon{
  display:block;width:159px;height:86px;
  margin:14px auto 8px;transform:rotate(-2deg);
  max-width:60vw;
}

/* ============================================================
   About page
   ============================================================ */

/* Confetti behind a single word. Sits behind the text, never over it. */
.confetti-word{position:relative;display:inline-block;isolation:isolate}
.confetti-word > span{position:relative;z-index:1}
.confetti-word i{
  position:absolute;z-index:0;display:block;
  width:12px;height:16px;border:2px solid var(--color-black);border-radius:3px;
  opacity:0;animation:fall 3.4s linear infinite;
}
.confetti-word i:nth-child(1){left:2%;  background:var(--color-pink);       animation-delay:0s}
.confetti-word i:nth-child(2){left:18%; background:var(--color-chartreuse); animation-delay:.45s;width:10px;height:10px;border-radius:99px}
.confetti-word i:nth-child(3){left:34%; background:var(--color-periwinkle); animation-delay:.9s}
.confetti-word i:nth-child(4){left:50%; background:var(--color-lavender);   animation-delay:1.3s;width:14px;height:9px}
.confetti-word i:nth-child(5){left:66%; background:var(--color-pink);       animation-delay:1.75s;width:9px;height:9px;border-radius:99px}
.confetti-word i:nth-child(6){left:82%; background:var(--color-chartreuse); animation-delay:2.2s}
.confetti-word i:nth-child(7){left:94%; background:var(--color-lavender);   animation-delay:2.7s;width:11px;height:14px}
@keyframes fall{
  0%   {opacity:0;transform:translateY(-130%) rotate(0deg)}
  12%  {opacity:1}
  80%  {opacity:1}
  100% {opacity:0;transform:translateY(190%) rotate(320deg)}
}

/* The real Taylor, then surprise, the drawn one. */
/* One fixed box for both, since the photo and the drawing are different shapes.
   The box takes the drawing's ratio (1440 by 1520). At the photo's 4:5 the
   drawing letterboxed top and bottom, which floated it above the label and
   opened a gap under it. Now both meet the bottom edge. */
.swap{position:relative;display:inline-block;width:100%;max-width:380px;aspect-ratio:1440/1520}
.swap img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;display:block;
}
/* The drawing is 1440 by 1520 and fills the box exactly. The photograph is 4:5,
   so contain left it narrower and floating inside the same slot. Cover makes it
   occupy the identical box; the crop comes off the bottom so her face stays put
   and the two land in the same place at the same size. */
.swap .real{
  animation:showReal 7s ease-in-out infinite;
  object-fit:cover;object-position:center top;border-radius:var(--radius-xl);
}
.swap .toon{animation:showToon 7s ease-in-out infinite}
@keyframes showReal{
  0%,42%   {opacity:1;transform:scale(1) rotate(0deg)}
  48%,92%  {opacity:0;transform:scale(.9) rotate(-3deg)}
  98%,100% {opacity:1;transform:scale(1) rotate(0deg)}
}
@keyframes showToon{
  0%,42%   {opacity:0;transform:scale(.86) rotate(4deg)}
  48%      {opacity:1;transform:scale(1.06) rotate(-2deg)}
  54%,92%  {opacity:1;transform:scale(1) rotate(0deg)}
  98%,100% {opacity:0;transform:scale(.86) rotate(4deg)}
}
/* Centred with margins, not a transform. The keyframes below set transform, which
   would otherwise wipe out a translateX(-50%) and let the label drift right. */
.swap .label{
  position:absolute;left:0;right:0;bottom:-14px;
  margin:0 auto;width:fit-content;
  border:3px solid var(--color-black);border-radius:var(--radius-full);
  padding:6px 18px;white-space:nowrap;
  font-family:var(--font-emphasis);font-size:12px;letter-spacing:.12em;text-transform:uppercase;
}
.swap .label.a{background:var(--color-pink);animation:showReal 7s ease-in-out infinite}
.swap .label.b{background:var(--color-chartreuse);animation:showToon 7s ease-in-out infinite}

/* Anyone who has asked for less movement gets none of it. */
@media (prefers-reduced-motion: reduce){
  .confetti-word i{animation:none;opacity:1}
  .swap .real,.swap .label.a{animation:none;opacity:0}
  .swap .toon,.swap .label.b{animation:none;opacity:1;transform:none}
}

.centered{text-align:center}

/* Every squiggle is pulled up 44px over the section above it, which eats that
   much of the section's visible bottom. Content ended up sitting high in its
   colour band with a large gap above and almost none below. Give it back. */
.slab:has(+ .squiggle-wrap){padding-bottom:calc(var(--space-3xl) + 44px)}
/* A grid that is the only thing in its section does not need a top margin on
   top of the section padding. */
.wrap > .pops:first-child,
.wrap > .ideas:first-child{margin-top:0}

/* The hero columns were drifting apart on wide screens. */
.cover .inner{gap:var(--space-xl)}
@media(min-width:901px){
  .cover .inner{grid-template-columns:1.15fr .85fr}
}
.centered .btnrow{justify-content:center}

/* The price cards are the way into the flow, so they behave like it. */
a.tier{
  display:block;text-decoration:none;color:var(--color-ink);cursor:pointer;
  transition:transform var(--transition-base),box-shadow var(--transition-base);
}
a.tier:hover{transform:translate(-3px,-3px)}
a.tier.tilt-l:hover{transform:translate(-3px,-3px) rotate(-1.6deg)}
a.tier.tilt-r:hover{transform:translate(-3px,-3px) rotate(1.4deg)}
a.tier:hover{box-shadow:15px 15px 0 0 var(--color-periwinkle), 15px 15px 0 3px var(--color-black)}
a.tier.luxe:hover{box-shadow:19px 19px 0 0 var(--color-pink), 19px 19px 0 3px var(--color-black)}
a.tier:focus-visible{outline:4px solid var(--color-black);outline-offset:4px}
.pick-cta{
  margin-top:var(--space-base);font-family:var(--font-body);font-weight:600;
  font-size:15px;border-top:2px solid var(--color-black);padding-top:10px;
}
.pick-cta::after{content:" \2192"}

/* ============================================================
   Questions. Turn cards, no JavaScript: a hidden checkbox drives
   the flip, so it works with the strict content policy and stays
   operable from the keyboard.
   ============================================================ */
.flips{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:var(--space-2xl);margin-top:var(--space-lg);margin-right:11px;
}
.flip{position:relative;perspective:1200px}
.flip-in{position:absolute;width:1px;height:1px;opacity:0;margin:0}
.flip-inner{
  display:block;position:relative;min-height:250px;cursor:pointer;
  transform-style:preserve-3d;transition:transform .6s cubic-bezier(.4,0,.2,1);
}
.flip-in:checked + .flip-inner{transform:rotateY(180deg)}
.flip-in:focus-visible + .flip-inner{outline:4px solid var(--color-black);outline-offset:6px;border-radius:var(--radius-xl)}
.face{
  position:absolute;inset:0;backface-visibility:hidden;
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  padding:var(--space-xl) var(--space-lg);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;gap:12px;
}
/* Every other box here casts a brand colour with a black outline behind it.
   These were casting flat black, which is the one shadow the kit does not use.
   Each front takes a colour that is not its own, so the pair reads as two
   layers rather than one thing with a bruise. */
.face.front.pink{background:var(--color-pink);
  box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.face.front.chart{background:var(--color-chartreuse);
  box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black)}
.face.front.periw{background:var(--color-periwinkle);
  box-shadow:11px 11px 0 0 var(--color-pink), 11px 11px 0 3px var(--color-black)}
.face.front.lav{background:var(--color-lavender);
  box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.face.back{
  background:var(--color-bg-light);transform:rotateY(180deg);
  box-shadow:11px 11px 0 0 var(--color-lavender), 11px 11px 0 3px var(--color-black);
}
.face .q{font-family:var(--font-brand);font-size:30px;line-height:1.15}
.face .a{font-size:var(--font-size-md);line-height:1.5}
.face .hint{
  font-family:var(--font-emphasis);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;opacity:.75;
}

/* Confetti when a card is turned. */
.burst{position:absolute;inset:0;pointer-events:none;overflow:visible}
.burst i{
  position:absolute;top:50%;left:50%;display:block;
  width:11px;height:14px;border:2px solid var(--color-black);border-radius:3px;
  opacity:0;
}
.flip-in:checked ~ .burst i{animation:pop .75s ease-out forwards}
.burst i:nth-child(1){background:var(--color-pink);      --dx:-150px;--dy:-110px;animation-delay:0s}
.burst i:nth-child(2){background:var(--color-chartreuse);--dx: 150px;--dy:-120px;animation-delay:.03s;border-radius:99px;width:10px;height:10px}
.burst i:nth-child(3){background:var(--color-periwinkle);--dx:-180px;--dy:  40px;animation-delay:.06s}
.burst i:nth-child(4){background:var(--color-lavender);  --dx: 180px;--dy:  60px;animation-delay:.09s;width:13px;height:9px}
.burst i:nth-child(5){background:var(--color-pink);      --dx: -70px;--dy:-160px;animation-delay:.12s;border-radius:99px;width:9px;height:9px}
.burst i:nth-child(6){background:var(--color-chartreuse);--dx:  80px;--dy: 150px;animation-delay:.15s}
.burst i:nth-child(7){background:var(--color-lavender);  --dx:-110px;--dy: 140px;animation-delay:.18s}
.burst i:nth-child(8){background:var(--color-periwinkle);--dx: 120px;--dy: -40px;animation-delay:.21s;width:12px;height:12px;border-radius:99px}
@keyframes pop{
  0%  {opacity:1;transform:translate(-50%,-50%) scale(.4) rotate(0deg)}
  70% {opacity:1}
  100%{opacity:0;transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(1) rotate(300deg)}
}

@media (prefers-reduced-motion: reduce){
  .flip-inner{transition:none}
  .flip-in:checked ~ .burst i{animation:none;opacity:0}
}
@media(max-width:820px){
  .flips{grid-template-columns:1fr}
  .flip-inner{min-height:230px}
  .face .q{font-size:26px}
}

/* The wordmark is the brand. It was sitting at nav-link size. */
.topbar{padding:var(--space-base) var(--space-lg);gap:var(--space-lg)}
/* The mark is 1.85:1. Set the height and let the width follow, rather than
   forcing it into a square where it letterboxed and looked tiny. */
.topbar img.mark{width:81px;height:44px}
.topbar .name{font-size:54px;line-height:1}
@media(max-width:900px){
  .topbar img.mark{width:63px;height:34px}
  .topbar .name{font-size:36px}
}

/* ============================================================
   Surprise ideas. The photo slots are sized and waiting; drop a
   picture into .shot and it replaces the icon with no other change.
   ============================================================ */
.ideas{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:var(--space-2xl);margin-top:var(--space-lg);margin-right:11px;
}
.idea{
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-lg);
  box-shadow:11px 11px 0 0 var(--color-black);text-align:center;
}
.idea.a{box-shadow:11px 11px 0 0 var(--color-pink),       11px 11px 0 3px var(--color-black)}
.idea.b{box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.idea.c{box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black)}
.idea.d{box-shadow:11px 11px 0 0 var(--color-lavender),   11px 11px 0 3px var(--color-black)}
.idea .shot{
  display:grid;place-items:center;
  aspect-ratio:4/3;width:100%;margin-bottom:var(--space-base);
  border:2px dashed var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-bg-warm);overflow:hidden;
}
.idea .shot img{width:84px;height:84px;object-fit:contain}
/* v7 category artwork is square and carries its own colour field. The slot goes
   square with it so nothing letterboxes or clips, and the placeholder frame
   comes off entirely. */
.idea .shot img.art{width:100%;height:100%;object-fit:contain;padding:0}
.idea .shot:has(img.art){
  aspect-ratio:1/1;border:0;background:none;overflow:visible;
  margin-bottom:var(--space-sm);
}
/* When a real photograph lands, it fills the slot edge to edge. */
.idea .shot img.photo{width:100%;height:100%;object-fit:cover}
.idea .shot:has(img.photo){border-style:solid;background:none}

.craft-row{display:flex;flex-wrap:wrap;gap:var(--space-md);justify-content:center;margin-top:var(--space-lg)}
.craft{
  border:3px solid var(--color-black);border-radius:var(--radius-full);
  padding:10px 22px;background:var(--color-bg-light);
  font-family:var(--font-brand);font-size:26px;line-height:1;
}
.craft:nth-child(2){background:var(--color-chartreuse)}
.craft:nth-child(4){background:var(--color-pink)}

@media(max-width:900px){.ideas{grid-template-columns:1fr 1fr}}
@media(max-width:620px){.ideas{grid-template-columns:1fr}}

/* One elevation for every content card on the site, so nothing reads as flatter
   than what sits around it. Same offset layer as the price and feature cards. */
.card.lift{
  border-width:3px;
  box-shadow:11px 11px 0 0 var(--color-black);
}
.card.lift.a{box-shadow:11px 11px 0 0 var(--color-pink),       11px 11px 0 3px var(--color-black)}
.card.lift.b{box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.card.lift.c{box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black)}
.card.lift.d{box-shadow:11px 11px 0 0 var(--color-lavender),   11px 11px 0 3px var(--color-black)}

/* The note callouts sat flat against lifted cards too. */
.notecap{box-shadow:9px 9px 0 0 var(--color-black);border-width:3px}

/* ============================================================
   HARD RULE: every box header on every page capitalises the first
   letter of every word. Enforced here rather than in each string,
   so a header added next month cannot drift out of the rule.
   Overrides the brand guide's sentence case for headers only;
   body copy and the eyebrow labels are untouched.
   ============================================================ */
.emph,
.face .q,
.tier-head,
.craft,
.step-card .emph,
.idea .emph,
.pop .emph,
.card .emph,
.col h4{
  text-transform:capitalize;
}

/* Ideas are grouped, one set per row, so the page reads as ordered rather than
   as a pile. Each group takes one colour for its layer. */
.idea-group{margin-bottom:var(--space-3xl)}
.idea-group:last-child{margin-bottom:0}
.group-head{
  font-family:var(--font-brand);font-size:34px;line-height:1.1;
  margin:0 0 var(--space-base);
}
.idea-group .ideas{margin-top:0}

/* Standard and Luxe are section headings above their own prices. These were
   lost to an earlier bulk edit and the labels dropped back to body size. */
.tier-head{
  font-family:var(--font-brand);font-size:44px;line-height:1.05;margin:0;
}
.tier-sub{
  font-size:var(--font-size-md);line-height:1.5;margin:8px 0 0;max-width:52ch;
}
@media(max-width:600px){.tier-head{font-size:36px}}

/* The about hero holds a short headline, so its columns were sized for content
   that isn't there and the photo drifted off to the right. Let both columns hug
   their content and centre the pair instead. */
@media(min-width:901px){
  .cover.tight .inner{
    grid-template-columns:auto auto;
    justify-content:center;
    gap:var(--space-2xl);
    align-items:center;
  }
  /* An auto sized grid column gives width:100% nothing to resolve against, so
     the column collapses and the picture disappears. Explicit width instead. */
  .cover.tight .swap{width:340px;max-width:38vw}
}

/* Confetti fired from a Start booking button. Pieces are positioned in the
   viewport and never take clicks. */
.confetti-layer{
  position:fixed;inset:0;pointer-events:none;z-index:9999;overflow:hidden;
}
.confetti-layer i{
  position:fixed;display:block;width:12px;height:15px;
  border:2px solid var(--color-black);border-radius:3px;
  will-change:transform,opacity;
}

/* The footer reads as a signature, so it is centred on every page. */
.footer-inner{
  display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;
}
.footer-inner img.mark{width:74px;height:40px;display:block;margin-bottom:4px}
.footer-inner .page-title{font-size:30px;margin:0}
.footer-inner .caption{opacity:.85;margin:0}
.footer-inner a{color:inherit}

/* The first choice: wrapping, which is bookable, or a surprise, which is a
   conversation. Two doors, equal weight. */
.forks{
  display:grid;grid-template-columns:1fr 1fr;gap:var(--space-2xl);
  max-width:900px;margin:0 auto;margin-right:auto;
}
.fork{
  display:block;text-decoration:none;color:var(--color-ink);
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-lg);text-align:center;
  transition:transform var(--transition-base),box-shadow var(--transition-base);
}
.fork.a{box-shadow:13px 13px 0 0 var(--color-pink),       13px 13px 0 3px var(--color-black)}
.fork.b{box-shadow:13px 13px 0 0 var(--color-chartreuse), 13px 13px 0 3px var(--color-black)}
.fork:hover{transform:translate(-3px,-3px)}
.fork.a.tilt-l:hover{transform:translate(-3px,-3px) rotate(-1.6deg)}
.fork.b.tilt-r:hover{transform:translate(-3px,-3px) rotate(1.4deg)}
.fork:focus-visible{outline:4px solid var(--color-black);outline-offset:5px}
.fork .shot{display:block;aspect-ratio:1/1;max-width:230px;margin:0 auto var(--space-sm)}
.fork .shot img{width:100%;height:100%;object-fit:contain;display:block}
.fork .emph{font-size:var(--font-size-lg)}
.fork .caption{margin-top:8px}
.fork .pick-cta{margin-top:var(--space-base)}
@media(max-width:820px){.forks{grid-template-columns:1fr}}

/* Idea cards start a surprise request, so they behave like the price cards. */
a.idea{display:block;text-decoration:none;color:var(--color-ink);cursor:pointer;
  transition:transform var(--transition-base)}
a.idea:hover{transform:translate(-3px,-3px)}
a.idea.tilt-l:hover{transform:translate(-3px,-3px) rotate(-1.6deg)}
a.idea.tilt-r:hover{transform:translate(-3px,-3px) rotate(1.4deg)}
a.idea:focus-visible{outline:4px solid var(--color-black);outline-offset:5px}

/* ============================================================
   The booking flow. Same language as the rest of the site: a
   coloured header, the ribbon boundary, then lifted cards.
   ============================================================ */
.stepper{
  display:flex;justify-content:center;flex-wrap:wrap;gap:var(--space-md);
}
.stepdot{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:64px}
.stepdot b{
  width:38px;height:38px;border-radius:var(--radius-full);
  border:3px solid var(--color-black);background:var(--color-bg-light);
  display:grid;place-items:center;font-family:var(--font-emphasis);font-size:14px;
}
.stepdot i{
  font-style:normal;font-family:var(--font-emphasis);font-size:9px;
  letter-spacing:.12em;text-transform:uppercase;opacity:.65;
}
.stepdot.now b{background:var(--color-pink);box-shadow:0 0 0 5px rgba(0,0,0,.08)}
.stepdot.now i{opacity:1;font-weight:600}
.stepdot.done b{background:var(--color-chartreuse)}

/* People already on the tree. */
.people-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
  gap:var(--space-xl);margin-right:11px;
}
.person-card{
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-base) var(--space-lg);
  text-align:center;
  box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black);
}
.person-card.b{box-shadow:11px 11px 0 0 var(--color-pink),       11px 11px 0 3px var(--color-black)}
.person-card.c{box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.person-card.d{box-shadow:11px 11px 0 0 var(--color-lavender),   11px 11px 0 3px var(--color-black)}
.person-card .who{font-family:var(--font-brand);font-size:30px;line-height:1;margin:0}
.person-card .rel{
  font-family:var(--font-emphasis);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;opacity:.7;margin:6px 0 0;
}
.person-card .likes{font-size:13px;margin-top:10px}
.person-card .sw{display:flex;gap:5px;justify-content:center;margin-top:10px}
.person-card .sw i{width:16px;height:16px;border:2px solid var(--color-black);border-radius:5px;display:block}

/* The add form sits as a card of the same family. */
.add-card{
  border:3px dashed var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-warm);padding:var(--space-lg);text-align:left;
}
.chip-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.chip-pick{
  border:2px solid var(--color-black);border-radius:var(--radius-full);
  padding:6px 14px;font-size:13px;background:var(--color-bg-light);cursor:pointer;
}
.chip-pick input{position:absolute;opacity:0;width:0;height:0}
.chip-pick:has(input:checked){background:var(--color-pink);font-weight:600}
.step-actions{
  display:flex;justify-content:center;gap:var(--space-base);
  flex-wrap:wrap;margin-top:var(--space-2xl);
}

/* First run orientation. Nobody arrives knowing what a gifting tree is, so the
   empty state explains the idea before asking for anything. */
.orient{
  display:grid;grid-template-columns:230px 1fr;gap:var(--space-2xl);
  align-items:center;
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-xl);
  box-shadow:13px 13px 0 0 var(--color-chartreuse), 13px 13px 0 3px var(--color-black);
  margin-bottom:var(--space-2xl);
}
.orient-art img{width:100%;height:auto;display:block}
.orient-steps{list-style:none;margin:var(--space-base) 0 0;padding:0}
.orient-steps li{
  display:grid;grid-template-columns:40px 1fr;gap:14px;
  align-items:start;margin-bottom:var(--space-base);
}
.orient-steps li:last-child{margin-bottom:0}
.orient-steps b{
  width:34px;height:34px;border-radius:var(--radius-full);
  border:3px solid var(--color-black);display:grid;place-items:center;
  font-family:var(--font-emphasis);font-size:14px;background:var(--color-pink);
}
.orient-steps li:nth-child(2) b{background:var(--color-periwinkle)}
.orient-steps li:nth-child(3) b{background:var(--color-lavender)}
.orient-steps span{font-size:var(--font-size-base);line-height:1.5}
.orient-steps strong{font-weight:600}
@media(max-width:820px){
  .orient{grid-template-columns:1fr;text-align:center;gap:var(--space-lg)}
  .orient-art img{max-width:180px;margin:0 auto}
  .orient-steps li{text-align:left}
}

/* ============================================================
   Hand drawn bubble cards. The library is explicit that these
   squares are drawn by hand, that the sides wobble and the
   corners are soft, and that a CSS rounded rectangle must not be
   substituted. Content sits inside the shape's own safe area.
   ============================================================ */
.bubble-card{position:relative;display:block}
.bubble-card .bub{
  position:absolute;inset:0;width:100%;height:100%;display:block;z-index:0;
}
.bubble-card .bub-content{
  position:relative;z-index:1;text-align:center;
  padding:14.71% 14.56% 19.85% 11.17%;
}
.bubble-card .who{font-family:var(--font-brand);font-size:30px;line-height:1;margin:0}
.bubble-card .rel{
  font-family:var(--font-emphasis);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;opacity:.75;margin:6px 0 0;
}
.bubble-card .likes{font-size:13px;margin-top:8px}
.bubble-card .sw{display:flex;gap:5px;justify-content:center;margin-top:8px}
.bubble-card .sw i{width:16px;height:16px;border:2px solid var(--color-black);border-radius:5px;display:block}

/* The bubbles carry their own colour, so the grid needs no offset layers. */
.people-grid{
  grid-template-columns:repeat(auto-fill,minmax(260px,1fr));
  gap:var(--space-lg);margin-right:0;
}

/* ============================================================
   Bubble cards, rolled out. The shape carries the colour and the
   layering, so these need no border, radius or offset shadow.
   ============================================================ */
.bubble-card .pop-icon{
  display:block;width:78px;height:78px;margin:0 auto var(--space-sm);
}
.bubble-card .emph{margin:0}
.bubble-card .caption{margin-top:8px}
.bubble-card .pick-cta{
  margin-top:12px;border-top:2px solid var(--color-black);padding-top:8px;
  font-weight:600;font-size:14px;
}
.bubble-card .shot{display:block;max-width:160px;margin:0 auto var(--space-sm)}
.bubble-card .shot img{width:100%;height:auto;display:block}
.bubble-card .num{
  position:absolute;top:4%;left:4%;width:44px;height:44px;
  border-radius:var(--radius-full);border:3px solid var(--color-black);
  background:var(--color-bg-light);display:grid;place-items:center;
  font-family:var(--font-brand);font-size:24px;z-index:2;
}

/* The grids no longer need shadow compensation. */
.pops,.ideas,.steps{margin-right:0}
.pops{gap:var(--space-lg)}
.ideas{gap:var(--space-lg)}
.steps{gap:var(--space-lg)}

/* Cards that are links keep their own hover, the bubble inside does the rest. */
.idea-link,.fork-link{
  display:block;text-decoration:none;color:var(--color-ink);
  transition:transform var(--transition-base);
}
.idea-link:hover,.fork-link:hover{transform:translateY(-4px)}
.idea-link:focus-visible,.fork-link:focus-visible{
  outline:4px solid var(--color-black);outline-offset:6px;border-radius:var(--radius-lg);
}
.fork-link .shot{max-width:190px}

/* Privacy and Questions sit on their own line beneath the location. */
.footer-inner .footer-links{margin-top:2px}
.footer-inner .footer-links a{text-decoration:underline;text-underline-offset:3px}

/* Step two: the list on the left, the form on the right. */
.gift-layout{display:block}
/* Capped columns and a centred track, so one list does not stretch to fill the
   row and three still sit side by side. */
.gift-groups{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,260px));
  justify-content:center;gap:var(--space-base);align-items:stretch;
  margin-top:var(--space-base);
}
.giftlist{list-style:none;margin:var(--space-md) 0 0;padding:0;text-align:left}
.giftlist li{
  display:flex;justify-content:space-between;gap:10px;align-items:baseline;
  padding:7px 0;border-bottom:2px dashed rgba(0,0,0,.22);font-size:14px;
}
.giftlist li:last-child{border-bottom:0}
.tagline{
  font-family:var(--font-emphasis);font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap;
  border:2px solid var(--color-black);border-radius:var(--radius-full);
  padding:2px 9px;background:var(--color-bg-light);
}
.tagline.soft{background:transparent;border-style:dashed;opacity:.75}
/* The form sits on the coloured band, so it needs its own ground. */
.gift-layout .add-card{background:var(--color-bg-light);border-style:solid}


/* ---------------------------------------------------------------- step three
   The style step. Standard and Luxe ask for completely different things, so the
   card shows one set or the other. No script anywhere on this site, so the
   reveal is :has() on the form, keyed off the radio the customer just pressed. */
.style-card{
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-xl);
  box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black);
  margin-bottom:var(--space-2xl);
}
.style-card:nth-of-type(2n){box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.style-card:nth-of-type(3n){box-shadow:11px 11px 0 0 var(--color-lavender), 11px 11px 0 3px var(--color-black)}
.style-head{
  display:flex;justify-content:space-between;align-items:baseline;
  gap:12px;flex-wrap:wrap;
}
.style-foot{
  display:flex;flex-direction:column;align-items:center;
  margin-top:var(--space-lg);gap:10px;
  border-top:2px dashed var(--color-black);padding-top:var(--space-lg);
}

/* Two things you press, rather than a menu you open. Used by the style step
   for Standard against Luxe, and by the when step for where it happens. */
.pick-2{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:var(--space-base)}
.pick-box{
  display:block;cursor:pointer;padding:14px 16px;text-align:center;
  border:3px solid var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-bg-warm);transition:background .12s ease, transform .12s ease;
}
.pick-box input{position:absolute;opacity:0;width:0;height:0}
.pick-name{display:block;font-family:var(--font-brand);font-size:20px;line-height:1.1}
.pick-note{display:block;font-size:12px;margin-top:4px;opacity:.75}
.pick-box:has(input:checked){background:var(--color-pink);transform:translateY(-2px)}
.pick-box:has(input:focus-visible){outline:3px solid var(--color-black);outline-offset:3px}

/* One panel at a time. */
.style-card:has(.tier-in[value="standard"]:checked) .luxe-only{display:none}
.style-card:has(.tier-in[value="luxe"]:checked) .std-only{display:none}

/* The palette. Deep shade behind, bright shade in front, the same two layer
   build as every bubble on the site. */
.swatch-group{
  font-family:var(--font-mono, var(--font-body));font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;margin-top:var(--space-base);margin-bottom:8px;opacity:.7;
}
.swatches{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-base)}
.swatch{display:flex;flex-direction:column;align-items:center;gap:6px;cursor:pointer;width:74px}
.swatch input{position:absolute;opacity:0;width:0;height:0}
.swatch-dot{
  position:relative;display:block;width:54px;height:54px;
  transition:transform .12s ease;
}
.swatch-deep,.swatch-bright{
  position:absolute;border-radius:50%;border:2.5px solid var(--color-black);
}
.swatch-deep{left:6px;top:6px;width:48px;height:48px}
.swatch-bright{left:0;top:0;width:46px;height:46px}
.swatch-name{font-size:12px;text-align:center;line-height:1.2}
.swatch:has(input:checked) .swatch-dot{transform:scale(1.12) rotate(-6deg)}
.swatch:has(input:checked) .swatch-name{font-weight:700}
/* The tick is the confirmation. Scale alone is too quiet to answer "did that
   register", especially on the two lightest swatches. */
.swatch:has(input:checked) .swatch-dot::after{
  content:"";position:absolute;right:-4px;bottom:-2px;width:20px;height:20px;
  border-radius:50%;background:var(--color-black);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 10.5l3.2 3.2L15 7' fill='none' stroke='%23fffbf5' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.swatch:has(input:focus-visible) .swatch-dot{outline:3px solid var(--color-black);outline-offset:4px}

/* The look, and the schemes, share one chip. */
.looks{display:flex;flex-wrap:wrap;justify-content:center;gap:10px}
.look{
  display:block;cursor:pointer;padding:11px 14px;text-align:center;
  flex:1 1 190px;max-width:260px;
  border:2.5px solid var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-bg-warm);transition:background .12s ease, transform .12s ease;
}
.look input{position:absolute;opacity:0;width:0;height:0}
.look-name{display:block;font-weight:700;font-size:14px}
.look-note{display:block;font-size:12px;margin-top:3px;opacity:.75}
.look:has(input:checked){background:var(--color-chartreuse);transform:translateY(-2px)}
.look:has(input:focus-visible){outline:3px solid var(--color-black);outline-offset:3px}
.look-custom{border-style:dashed}

/* The box only exists once there is something to describe. */
.custom-box{display:none}
.style-card:has(input[name="luxe_style"][value="custom"]:checked) .custom-box{display:block}

@media (prefers-reduced-motion: reduce){
  .pick-box,.look,.swatch-dot{transition:none}
  .pick-box:has(input:checked),.look:has(input:checked){transform:none}
  .swatch:has(input:checked) .swatch-dot{transform:none}
}
@media (max-width: 640px){
  .pick-2{grid-template-columns:1fr}
}

/* The style choices read back under each name on the review line. */
.line-sub{display:block;font-size:12px;opacity:.7;margin-top:2px}
.wants{font-size:12px;max-width:32ch}

/* The address and the mileage only exist when Taylor is driving. Asking for a
   street address under "drop off at the studio" reads as a data grab. */
.travel-only{display:none}
.when-form:has(.svc-in[value="driveway"]:checked) .travel-only{display:block}

/* The tones follow the look. Every set is rendered and only the chosen one is
   shown, because there is no script on this site to swap them. */
.tones{display:none}
.style-card:has(input[name="luxe_style"][value="elegant"]:checked) .tones-elegant,
.style-card:has(input[name="luxe_style"][value="playful"]:checked) .tones-playful,
.style-card:has(input[name="luxe_style"][value="storybook"]:checked) .tones-storybook,
.style-card:has(input[name="luxe_style"][value="glam"]:checked) .tones-glam,
.style-card:has(input[name="luxe_style"][value="themed"]:checked) .tones-themed,
.style-card:has(input[name="luxe_style"][value="custom"]:checked) .tones-custom{display:block}

/* The style card reads as one centred column: every label, every hint and every
   row of choices lines up on the same axis. */
.style-card .lbl,
.style-card .micro,
.when-form .lbl,
.when-form .micro{text-align:center;display:block}
.style-card .f,
.when-form .f{margin-left:auto;margin-right:auto}
.style-card .chip-pick{display:block;width:fit-content;margin-left:auto;margin-right:auto}

/* The paper chip is a pill, so it has to be told how wide it is before auto
   margins can find its centre. */
.style-card .byop{display:block;width:fit-content;margin:var(--space-lg) auto 0}

/* The price answers the two questions on the card. Standard and Luxe carry
   different numbers, and supplying your own paper takes two dollars a gift off
   the Luxe one, so the old figure is struck rather than quietly replaced. */
.p-standard,.p-luxe,.p-luxe-byop{display:none}
.style-card:has(.tier-in[value="standard"]:checked) .p-standard{display:block}
.style-card:has(.tier-in[value="luxe"]:checked):not(:has(.byop input:checked)) .p-luxe{display:block}
.style-card:has(.tier-in[value="luxe"]:checked):has(.byop input:checked) .p-luxe-byop{display:block}
.p-luxe-byop s{opacity:.45;margin-right:10px;text-decoration-thickness:2px}

/* Text sits centred in every box on these forms, placeholders included. */
.style-card .f,
.when-form .f{text-align:center}
.style-card .f::placeholder,
.when-form .f::placeholder{text-align:center}

/* What the next gift costs, phrased for the tier that is selected. */
.headroom{margin-top:6px}
.n-standard,.n-luxe,.n-luxe-byop{display:none}
.style-card:has(.tier-in[value="standard"]:checked) .n-standard{display:inline}
.style-card:has(.tier-in[value="luxe"]:checked):not(:has(.byop input:checked)) .n-luxe{display:inline}
.style-card:has(.tier-in[value="luxe"]:checked):has(.byop input:checked) .n-luxe-byop{display:inline}

/* ----------------------------------------------------------- the calendar
   A month you can read, not a dropdown of dates. The grid is seven columns
   because a calendar that does not line up under its own weekday letters is
   not a calendar. */
.when-form{max-width:720px;margin-left:auto;margin-right:auto}
.cal{
  border:2.5px solid var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-bg-warm);padding:var(--space-base);
  margin:var(--space-base) auto 0;max-width:420px;
}
.cal-month{
  font-family:var(--font-brand);font-size:22px;text-align:center;
  margin-bottom:10px;line-height:1.1;
}
.cal-head,.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.cal-head{margin-bottom:6px}
.cal-head span{
  text-align:center;font-size:11px;letter-spacing:.08em;opacity:.6;font-weight:700;
}
.cal-day{
  display:flex;align-items:center;justify-content:center;
  aspect-ratio:1;border-radius:50%;font-size:14px;font-weight:600;
  border:2px solid transparent;
}
.cal-day.shut{opacity:.28}
.cal-day.open{cursor:pointer;border-color:var(--color-black);background:var(--color-bg-light)}
.cal-day.open input{position:absolute;opacity:0;width:0;height:0}
.cal-day.open:hover{background:var(--color-chartreuse)}
.cal-day.open:has(input:checked){background:var(--color-pink);transform:scale(1.08)}
.cal-day.open:has(input:focus-visible){outline:3px solid var(--color-black);outline-offset:2px}
.cal-pad{aspect-ratio:1}

/* The windows for the chosen day. Every set is rendered, one is revealed. */
.wins{display:block}
.win-set{display:none;flex-wrap:wrap;justify-content:center;gap:10px;margin-top:10px}
.win{
  display:block;cursor:pointer;padding:11px 18px;text-align:center;
  border:2.5px solid var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-bg-warm);flex:0 1 auto;
}
.win input{position:absolute;opacity:0;width:0;height:0}
.win-time{display:block;font-weight:700;font-size:14px}
.win-note{display:block;font-size:12px;opacity:.7;margin-top:2px}
.win:has(input:checked){background:var(--color-periwinkle)}
.win:has(input:focus-visible){outline:3px solid var(--color-black);outline-offset:3px}
/* The prompt disappears the moment a day is chosen. */
.when-form:has(input[name="slot_date"]:checked) .win-empty{display:none}

/* Address autocomplete. The list is same origin markup; the lookup and the
   distance both happen on the server so Taylor's address is never in the page. */
.addr-list{
  display:none;max-width:420px;margin:6px auto 0;text-align:left;
  border:2.5px solid var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-bg-light);overflow:hidden;
}
.addr-list.on{display:block}
.addr-list button{
  display:block;width:100%;text-align:left;padding:10px 14px;font-size:14px;
  background:none;border:0;border-bottom:1.5px solid rgba(0,0,0,.12);cursor:pointer;
}
.addr-list button:last-child{border-bottom:0}
.addr-list button:hover,.addr-list button:focus-visible{background:var(--color-chartreuse)}

/* A sentence should not drop one word onto a line by itself. */
.pick-note,.look-note,.win-note,.micro,.caption,.cal-month,.headroom,
.body-lg,.lbl,.next-line,.tree-likes,.tree-none,.book-when,.list-name,.emph{text-wrap:balance}

/* One month at a time. */
.cal{display:none}
.cal-months{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:12px}
.cal-mo{
  cursor:pointer;padding:7px 16px;font-size:13px;font-weight:700;
  border:2.5px solid var(--color-black);border-radius:var(--radius-full);
  background:var(--color-bg-light);
}
.cal-mo input{position:absolute;opacity:0;width:0;height:0}
.cal-mo:has(input:checked){background:var(--color-lavender)}
.cal-mo:has(input:focus-visible){outline:3px solid var(--color-black);outline-offset:3px}

/* City, state and zip read as one line, the way an address is written. */
.csz{display:grid;grid-template-columns:2fr 1fr 1fr;gap:10px;margin-top:14px;max-width:420px;
  margin-left:auto;margin-right:auto}
.when-form .lbl.vis{margin-top:14px;font-size:11px}
.csz .lbl.vis{margin-top:0}
@media (max-width: 520px){ .csz{grid-template-columns:1fr} }

/* The per project window sits with the address it belongs to. */
.win-form{display:flex;align-items:flex-end;gap:10px;margin-top:14px;flex-wrap:wrap}
.win-form .f{max-width:110px;margin:0}
.win-form .lbl{margin:0 0 4px}

/* Step four sat cream on cream with a hairline round it. Everything else on
   this site is a shape with weight behind it, so this is too. */
.when-form{
  border:3px solid var(--color-black);border-radius:var(--radius-xl);
  background:var(--color-bg-light);padding:var(--space-xl);
  box-shadow:13px 13px 0 0 var(--color-pink), 13px 13px 0 3px var(--color-black);
}
.cal{
  background:var(--color-bg-light);
  box-shadow:8px 8px 0 0 var(--color-periwinkle), 8px 8px 0 3px var(--color-black);
}
.cal-day.open{background:var(--color-bg-warm);font-weight:700}
.win{box-shadow:5px 5px 0 0 var(--color-lavender), 5px 5px 0 3px var(--color-black)}
.win:has(input:checked){
  background:var(--color-periwinkle);
  box-shadow:5px 5px 0 0 var(--color-chartreuse), 5px 5px 0 3px var(--color-black);
}
.pick-box{box-shadow:6px 6px 0 0 var(--color-lavender), 6px 6px 0 3px var(--color-black)}
.pick-box:has(input:checked){box-shadow:6px 6px 0 0 var(--color-chartreuse), 6px 6px 0 3px var(--color-black)}

/* ------------------------------------------------------------ page edges
   The bar at the top and the footer at the bottom are shapes now, not blocks
   with a ruled edge. Same wave language as every section boundary. */
.topbar{background:var(--color-lavender);color:var(--color-black)}
.topbar .name{color:var(--color-black)}
.topbar nav a{color:var(--color-black)}
.footer{background:var(--color-periwinkle);color:var(--color-black);margin-top:0}
.footer .page-title,.footer .caption,.footer a{color:var(--color-black)}
.footer-inner .caption{opacity:.8}

.edge{line-height:0;height:44px;pointer-events:none;position:relative}
.edge svg{display:block;width:100%;height:44px}
.edge .edge-accent{position:absolute;inset:0}
/* Hangs off the bottom of the sticky bar, so the black line stays with the bar
   instead of scrolling away from it. */
.edge-down{position:absolute;left:0;right:0;top:100%}
/* Pulled up over the section above so that section, whatever colour it is,
   shows through the transparent half of the wave. */
.edge-up{position:relative;margin-top:-44px;z-index:2}

/* Boxes in a row are the same height as each other. A ragged row of three
   reads as three unrelated things rather than three choices. */
.grid3 > .card,.grid2 > .card,.gift-layout > *{height:100%}
.extras{align-items:stretch}
.extras .card{display:flex;flex-direction:column}
.extras .card .micro:last-child{margin-top:auto;padding-top:10px}

/* Cards on a coloured band need their own weight, or they sink into it. Pink,
   because no band is pink and the shadow has to read against all of them. */
.slab .card.warm,.slab .add-card{
  border:3px solid var(--color-black);
  box-shadow:11px 11px 0 0 var(--color-pink), 11px 11px 0 3px var(--color-black);
}

/* The green under the header line holds while you start scrolling, then pulls
   away and leaves the black line on its own. Scrolling back up brings it in
   again, because a scroll timeline runs both directions. Browsers without one
   simply keep the green, which is the resting state anyway. */
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: scroll()){
    .edge-down .edge-accent{
      animation:accent-pull linear both;
      animation-timeline:scroll(root block);
      animation-range:0 340px;
    }
    @keyframes accent-pull{
      0%,55%{transform:translateY(0);opacity:1}
      100%{transform:translateY(14px);opacity:0}
    }
  }
}

/* A finished step is a way back. It should feel like one. */
a.stepdot{text-decoration:none;color:inherit;cursor:pointer}
a.stepdot b{transition:transform .12s ease, background .12s ease}
a.stepdot:hover b{background:var(--color-chartreuse);transform:translateY(-2px)}
a.stepdot:focus-visible b{outline:3px solid var(--color-black);outline-offset:3px}
a.stepdot:hover i{text-decoration:underline;text-underline-offset:3px}

/* ------------------------------------------------------------- the receipt
   Step six is the page somebody agrees to money on, so it reads like a
   receipt: what it is at the top, what it costs in the middle, and what
   leaves the account today separated from what does not. */
/* The card was lavender on a lavender band, so it had no edge of its own and
   the page showed straight through the middle of it. Periwinkle gives it a
   ground, and the same offset shadow the form beside it carries gives it
   weight. */
.card.receipt{
  padding:0;overflow:hidden;background:var(--color-periwinkle);
  border:3px solid var(--color-black);
  box-shadow:13px 13px 0 0 var(--color-pink), 13px 13px 0 3px var(--color-black);
}
.receipt-head{
  background:var(--color-black);color:var(--color-bg-light);
  padding:var(--space-lg) var(--space-lg) var(--space-base);text-align:center;
}
.receipt-head .eyebrow{color:var(--color-chartreuse);margin:0}
/* A reference gets read down a phone and typed into a box. The script face is
   the wrong tool for six characters that have to survive both. */
.receipt .ref{
  font-family:var(--font-emphasis);font-size:26px;line-height:1.1;margin:4px 0 12px;
  color:var(--color-pink);letter-spacing:.18em;font-weight:600;
}
.receipt-when{font-family:var(--font-brand);font-size:22px;line-height:1.15;margin:0}
.receipt-slot{font-size:14px;margin:2px 0 0;opacity:.85}
.receipt-how{
  display:inline-block;margin-top:10px;padding:4px 12px;font-size:11px;
  letter-spacing:.12em;text-transform:uppercase;font-weight:700;
  border-radius:var(--radius-full);background:var(--color-periwinkle);color:var(--color-black);
}
.receipt-lines{padding:var(--space-lg) var(--space-lg) 0}
/* The base .total draws a straight border-top. This one draws a wave instead,
   so the straight one has to be turned off rather than merely covered. */
.receipt .total{
  position:relative;border-top:0;
  margin:var(--space-base) var(--space-lg) 0;padding-top:var(--space-lg);
}
.receipt-split{
  position:relative;display:grid;grid-template-columns:1fr 1fr;gap:0;
  margin:var(--space-lg) 0 0;padding-top:2px;
}
.receipt-split > div{padding:var(--space-base) var(--space-md);text-align:center}
.split-now{position:relative;background:var(--color-chartreuse)}
.split-later{background:var(--color-bg-warm)}
.split-label{
  display:block;font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  font-weight:700;opacity:.75;
}
.split-amt{display:block;font-family:var(--font-brand);font-size:28px;line-height:1.1;margin-top:2px}
.split-note{display:block;font-size:11px;margin-top:4px;opacity:.75}
.receipt-foot{margin:0;padding:var(--space-md) var(--space-lg) var(--space-lg);text-align:center;opacity:.8}
@media(max-width:420px){
  .receipt-split{grid-template-columns:1fr}
  /* the divider lies down with the columns */
  .split-now::after{top:auto;bottom:-5px;left:0;right:0;width:auto;height:10px;
    background-image:var(--rule-h);background-repeat:repeat-x}
}

/* ------------------------------------------------------------- ruled lines
   Nothing else on this site is drawn with a straight edge, so the receipt's
   dividers are not either. One tile repeated, same wave as every boundary. */
:root{
  --rule-h:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='10' viewBox='0 0 40 10'%3E%3Cpath d='M0 6 q5 -4.7 10 0 t10 0 t10 0 t10 0' fill='none' stroke='%23111111' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E");
  --rule-v:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='40' viewBox='0 0 10 40'%3E%3Cpath d='M6 0 q-4.7 5 0 10 t0 10 t0 10 t0 10' fill='none' stroke='%23111111' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E");
}
/* Above the split cells, not behind them. split-now is positioned so it can
   carry the vertical divider, which put it in front of this and swallowed the
   left half of the wave. */
.receipt .total::before,
.receipt-split::before{
  content:"";position:absolute;left:0;right:0;top:0;height:10px;z-index:3;
  background-image:var(--rule-h);background-repeat:repeat-x;
}
.receipt .total::before{left:0;right:0}
/* The wall between what you pay now and what you pay later. */
.split-now::after{
  content:"";position:absolute;top:0;bottom:0;right:-5px;width:10px;z-index:2;
  background-image:var(--rule-v);background-repeat:repeat-y;
}

/* A swatch you cannot pick because three are already picked. It stays legible,
   it just stops inviting the click. */
.swatch.is-capped{cursor:default}
.swatch.is-capped .swatch-dot{opacity:.32;transform:none}
.swatch.is-capped .swatch-name{opacity:.45}

/* ------------------------------------------------- actions on a person card
   Three pills inside a bubble, in the same ink and weight as every other
   control on the site. Each is its own form, so display:contents keeps them
   on one line instead of stacking three block elements. */
.who-acts{
  display:flex;justify-content:center;flex-wrap:wrap;
  gap:6px;margin-top:12px;
}
.who-acts form{display:contents}
.who-act{
  font-family:var(--font-emphasis);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;font-weight:600;line-height:1;
  padding:6px 11px;cursor:pointer;
  border:2px solid var(--color-black);border-radius:var(--radius-full);
  background:var(--color-bg-light);color:var(--color-black);
  transition:background .12s ease, transform .12s ease;
}
.who-act:hover:not(:disabled){background:var(--color-chartreuse);transform:translateY(-1px)}
.who-act:focus-visible{outline:3px solid var(--color-black);outline-offset:2px}
.who-act.on{background:var(--color-pink)}
.who-act.off{background:var(--color-periwinkle)}
.who-act.danger:hover:not(:disabled){background:var(--color-pink)}
.who-act:disabled{opacity:.35;cursor:default}

.me-tag{
  display:inline-block;vertical-align:middle;margin-left:6px;
  font-family:var(--font-emphasis);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;font-weight:700;padding:3px 8px;
  border:2px solid var(--color-black);border-radius:var(--radius-full);
  background:var(--color-pink);
}

/* Someone sitting this booking out. Still on the tree, visibly not in the order. */
.bubble-card.is-skipped .bub{opacity:.4}
.bubble-card.is-skipped .who,
.bubble-card.is-skipped .rel,
.bubble-card.is-skipped .likes{opacity:.5}

/* The partner invite, which only exists once somebody says which one is them. */
.partner-invite{max-width:620px;margin:var(--space-2xl) auto 0}

/* Says plainly what removing did, so nobody thinks they deleted a relative. */
.skip-tag{
  font-family:var(--font-emphasis);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;font-weight:700;margin-top:6px;opacity:.75;
}

/* The add form lives under the lists it feeds, at reading width. */
.gift-layout .add-card{
  max-width:620px;margin:var(--space-2xl) auto 0;
  background:var(--color-bg-light);border-style:solid;
}
/* Who it is for, as boxes. The names are on screen a few inches above; a
   dropdown asked people to remember what they had just read. */
.who-picks{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:8px}
.who-pick{
  font-family:var(--font-emphasis);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;font-weight:600;padding:8px 14px;cursor:pointer;
  border:2.5px solid var(--color-black);border-radius:var(--radius-full);
  background:var(--color-bg-warm);transition:background .12s ease, transform .12s ease;
}
.who-pick input{position:absolute;opacity:0;width:0;height:0}
.who-pick:has(input:checked){background:var(--color-pink);transform:translateY(-1px)}
.who-pick:has(input:focus-visible){outline:3px solid var(--color-black);outline-offset:3px}

/* -------------------------------------------------------- shopping lists
   One box per person, so the step reads as a list you are filling rather
   than a shape you are decorating. */
.lists-head{margin-top:var(--space-2xl);text-align:center}
.list-card{
  background:var(--color-bg-light);border:3px solid var(--color-black);
  border-radius:var(--radius-lg);padding:var(--space-base) var(--space-md);
  display:flex;flex-direction:column;
}
.list-card.tint-pink{box-shadow:8px 8px 0 0 var(--color-pink), 8px 8px 0 3px var(--color-black)}
.list-card.tint-chartreuse{box-shadow:8px 8px 0 0 var(--color-chartreuse), 8px 8px 0 3px var(--color-black)}
.list-card.tint-periwinkle{box-shadow:8px 8px 0 0 var(--color-periwinkle), 8px 8px 0 3px var(--color-black)}
.list-name{
  font-family:var(--font-brand);font-size:24px;line-height:1.1;
  margin:0;text-align:center;
}
.list-count{
  font-family:var(--font-emphasis);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;text-align:center;margin:4px 0 10px;opacity:.7;
}
.list-card .giftlist{margin-top:0}
.list-card .giftlist li{padding:6px 0}

/* Section headings inside a step. They were written as <p class="lbl">, which
   matched nothing, because the field label rule is label.lbl. They are their
   own thing: a heading over a group of choices, not a label on one input. */
.group-head{
  font-family:var(--font-emphasis);font-size:13px;letter-spacing:.1em;
  text-transform:uppercase;font-weight:600;text-align:center;
  margin:var(--space-lg) 0 4px;
}
.style-card .group-head,.when-form .group-head{text-align:center}

/* ------------------------------------------------------------ step five
   One box per row, each one landscape, stacked in the order she offers them:
   stockings, then assembly, then the partner surprise. */
.extras{display:flex;flex-direction:column;gap:var(--space-lg);max-width:720px;margin-left:auto;margin-right:auto}
.extras .card{width:100%;height:auto}

/* --------------------------------------------------- everything in a box
   Boxes on this site read centred. This is the whole set in one place so a
   new box cannot quietly come out left aligned. */
.card,.add-card,.list-card,.style-card,.when-form,.orient-copy,.bubble-card,.receipt{
  text-align:center;
}
.card .lbl,.card label.lbl,
.add-card label.lbl,.style-card label.lbl,.when-form label.lbl,
.extras .lbl{text-align:center}
.card p,.card h2,.card h3,
.add-card p,.list-card p,.extras p{text-align:center}
.orient-copy{text-align:center}
/* Rows that pair a name with a value stay as rows; centring those would put
   the price under the thing it prices. */
.giftlist li,.line,.receipt .total,.style-head{text-align:left}
.card .f,.add-card .f,.extras .f{margin-left:auto;margin-right:auto}

/* Icons sit over the middle of the box like everything else in it. */
.card .icon,.card .pop-icon,.list-card img,.add-card img{display:block;margin-left:auto;margin-right:auto}

/* Two short answers side by side. A number box the width of the card reads as
   though it wants a sentence. */
.field-pair{
  display:grid;grid-template-columns:1fr 1fr;gap:var(--space-base);
  margin-top:var(--space-base);max-width:520px;margin-left:auto;margin-right:auto;
}
/* A label that wraps to two lines must not drop its own input below the one
   beside it, so the labels share a row and the inputs sit on one line. */
.field-pair > div{display:flex;flex-direction:column}
.field-pair .lbl{margin-top:0;flex:1 0 auto;display:flex;align-items:flex-end;justify-content:center}
@media(max-width:520px){ .field-pair{grid-template-columns:1fr} }

/* A number sits in the middle of its box, like every other value here. */
.card input[type="number"],.add-card input[type="number"],
.when-form input[type="number"]{text-align:center}

/* Icons sit over the middle of the box like everything else in it. */
.card .icon,.card .pop-icon,.list-card img,.add-card img{display:block;margin-left:auto;margin-right:auto}

/* Two short answers side by side. A number box the width of the card reads as
   though it wants a sentence. */
.field-pair{
  display:grid;grid-template-columns:1fr 1fr;gap:var(--space-base);
  margin-top:var(--space-base);max-width:520px;margin-left:auto;margin-right:auto;
}
/* A label that wraps to two lines must not drop its own input below the one
   beside it, so the labels share a row and the inputs sit on one line. */
.field-pair > div{display:flex;flex-direction:column}
.field-pair .lbl{margin-top:0;flex:1 0 auto;display:flex;align-items:flex-end;justify-content:center}
@media(max-width:520px){ .field-pair{grid-template-columns:1fr} }

/* A number sits in the middle of its box, like every other value here. */
.card input[type="number"],.add-card input[type="number"],
.when-form input[type="number"]{text-align:center}

/* Icons sit over the middle of the box like everything else in it. */
.card .icon,.card .pop-icon,.list-card img,.add-card img{display:block;margin-left:auto;margin-right:auto}

/* Two short answers side by side. A number box the width of the card reads as
   though it wants a sentence. */
.field-pair{
  display:grid;grid-template-columns:1fr 1fr;gap:var(--space-base);
  margin-top:var(--space-base);max-width:520px;margin-left:auto;margin-right:auto;
}
/* A label that wraps to two lines must not drop its own input below the one
   beside it, so the labels share a row and the inputs sit on one line. */
.field-pair > div{display:flex;flex-direction:column}
.field-pair .lbl{margin-top:0;flex:1 0 auto;display:flex;align-items:flex-end;justify-content:center}
@media(max-width:520px){ .field-pair{grid-template-columns:1fr} }

/* A number sits in the middle of its box, like every other value here. */
.card input[type="number"],.add-card input[type="number"],
.when-form input[type="number"]{text-align:center}

/* Icons sit over the middle of the box like everything else in it. */
.card .icon,.card .pop-icon,.list-card img,.add-card img{display:block;margin-left:auto;margin-right:auto}

/* Two short answers side by side. A number box the width of the card reads as
   though it wants a sentence. */
.field-pair{
  display:grid;grid-template-columns:1fr 1fr;gap:var(--space-base);
  margin-top:var(--space-base);max-width:520px;margin-left:auto;margin-right:auto;
}
/* A label that wraps to two lines must not drop its own input below the one
   beside it, so the labels share a row and the inputs sit on one line. */
.field-pair > div{display:flex;flex-direction:column}
.field-pair .lbl{margin-top:0;flex:1 0 auto;display:flex;align-items:flex-end;justify-content:center}
@media(max-width:520px){ .field-pair{grid-template-columns:1fr} }

/* A number sits in the middle of its box, like every other value here. */
.card input[type="number"],.add-card input[type="number"],
.when-form input[type="number"]{text-align:center}

/* Icons sit over the middle of the box like everything else in it. */
.card .icon,.card .pop-icon,.list-card img,.add-card img{display:block;margin-left:auto;margin-right:auto}

/* Two short answers side by side. A number box the width of the card reads as
   though it wants a sentence. */
.field-pair{
  display:grid;grid-template-columns:1fr 1fr;gap:var(--space-base);
  margin-top:var(--space-base);max-width:520px;margin-left:auto;margin-right:auto;
}
/* A label that wraps to two lines must not drop its own input below the one
   beside it, so the labels share a row and the inputs sit on one line. */
.field-pair > div{display:flex;flex-direction:column}
.field-pair .lbl{margin-top:0;flex:1 0 auto;display:flex;align-items:flex-end;justify-content:center}
@media(max-width:520px){ .field-pair{grid-template-columns:1fr} }

/* A number sits in the middle of its box, like every other value here. */
.card input[type="number"],.add-card input[type="number"],
.when-form input[type="number"]{text-align:center}

/* Assembly has nothing to fill in, so it is a note rather than a box. It stands
   on its own beside the stack, tilted, not layered over anything. */
.assembly-note{
  width:min(340px,100%);margin:var(--space-lg) auto 0;transform:rotate(-2deg);
}
.assembly-note .bub-content{padding:15% 13% !important;text-align:left}
/* Kept in normal flow. Absolute positioning here resolved against an ancestor
   that was not the stack, and the note landed on top of a card. */
@media(min-width:820px){
  .assembly-note{margin-right:0;margin-left:auto;transform:rotate(-3deg)}
}

/* ------------------------------------------------------------ the tree home
   The dashboard. Everything here outlives one order, so it reads as a place
   rather than a step: what is coming, who is on the tree, what they were
   given before, and how this household likes to be served. */
.next-up{display:flex;flex-direction:column;gap:4px;margin-top:14px;align-items:center}
.next-line{font-size:15px}
.next-line b{font-weight:700}
.next-line a{color:inherit;text-decoration:underline;text-underline-offset:3px}

/* Twelve months at a glance, so the year has a shape. */
.yr{display:flex;justify-content:center;gap:6px;margin-top:var(--space-lg);flex-wrap:wrap}
.yr-m{
  position:relative;width:34px;height:34px;display:flex;align-items:center;justify-content:center;
  border:2px solid var(--color-black);border-radius:50%;background:var(--color-bg-light);
  font-family:var(--font-emphasis);font-size:11px;font-weight:700;
}
.yr-m.on{background:var(--color-chartreuse)}
.yr-m i{font-style:normal}
/* dot-ev rather than ev, because .ev is already an event row and a marker that
   answers to the same selector is a trap. */
.dot{
  display:inline-block;flex:0 0 8px;width:8px;height:8px;border-radius:50%;
  border:1.5px solid var(--color-black);
}
.dot-bk{background:var(--color-pink)}
.dot-ev{background:var(--color-periwinkle)}
.yr-m .dot{position:absolute;bottom:-3px}
.yr-m .dot-bk{left:5px}
.yr-m .dot-ev{right:5px}
.yr-key{margin-top:10px;display:flex;align-items:center;justify-content:center;gap:5px}

.tree-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,270px));
  justify-content:center;gap:var(--space-base);margin-top:var(--space-lg);
  align-items:stretch;
}
.tree-grid > *{height:100%}
.tree-card{
  background:var(--color-bg-light);border:3px solid var(--color-black);
  border-radius:var(--radius-lg);padding:var(--space-base) var(--space-md);text-align:center;
}
/* The class says what it paints. tint-chartreuse casting a periwinkle shadow
   is a lie the next person has to read the stylesheet to catch. */
.tree-card.tint-pink{box-shadow:8px 8px 0 0 var(--color-pink), 8px 8px 0 3px var(--color-black)}
.tree-card.tint-periwinkle{box-shadow:8px 8px 0 0 var(--color-periwinkle), 8px 8px 0 3px var(--color-black)}
.tree-card.tint-lavender{box-shadow:8px 8px 0 0 var(--color-lavender), 8px 8px 0 3px var(--color-black)}
.tree-card{display:flex;flex-direction:column}
.tree-card .giftlist{margin-top:auto}
.tree-likes{font-size:13px;margin:6px 0 0}
.tree-head{
  font-family:var(--font-emphasis);font-size:9px;letter-spacing:.12em;text-transform:uppercase;
  margin:var(--space-base) 0 4px;opacity:.65;
}
.tree-none{font-size:12px;opacity:.6;margin-top:var(--space-base)}

/* Dates, newest first, with how far off each one is. */
.ev-list{list-style:none;margin:var(--space-lg) auto 0;padding:0;max-width:620px}
/* Left aligned on purpose: a date, what it is and how far off pair up as a
   row, and centring them would stack the countdown under the thing it counts.
   Everything else about it follows the box rules, shadow included. */
.ev{
  display:flex;align-items:center;gap:var(--space-base);text-align:left;
  background:var(--color-bg-light);border:2.5px solid var(--color-black);
  border-radius:var(--radius-lg);padding:10px var(--space-base);margin-bottom:14px;
  box-shadow:6px 6px 0 0 var(--color-periwinkle), 6px 6px 0 3px var(--color-black);
}
.ev-when{
  display:flex;flex-direction:column;align-items:center;line-height:1;flex:0 0 44px;
}
.ev-when b{font-family:var(--font-brand);font-size:22px}
.ev-when i{font-style:normal;font-size:10px;text-transform:uppercase;letter-spacing:.1em;opacity:.7}
.ev-what{flex:1;display:flex;flex-direction:column}
.ev-what b{font-weight:700;font-size:14px}
.ev-what i{font-style:normal;font-size:12px;opacity:.7}
.ev-away{
  font-family:var(--font-emphasis);font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  opacity:.75;white-space:nowrap;
}
.ev-none{text-align:center;font-size:13px;opacity:.6;list-style:none}

/* Bookings, with the lock window written on them. */
.book-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,380px));
  justify-content:center;gap:var(--space-base);margin-top:var(--space-lg);
}
.book-card{
  background:var(--color-bg-light);border:3px solid var(--color-black);
  border-radius:var(--radius-lg);padding:var(--space-base) var(--space-md);text-align:center;
  box-shadow:8px 8px 0 0 var(--color-lavender), 8px 8px 0 3px var(--color-black);
}
.book-when{font-family:var(--font-brand);font-size:20px;line-height:1.1;margin:0}
.book-slot{font-size:13px;margin:2px 0 8px;opacity:.75}
.book-acts{justify-content:center;margin-top:var(--space-base)}
.book-card .ask{margin-top:var(--space-base)}
.book-card .locked{
  margin-top:var(--space-base);padding:8px;border-radius:var(--radius-lg);
  background:var(--color-chartreuse);border:2px solid var(--color-black);
}

/* Change requests sit above the day board, because a date she is already
   shopping for is the thing she most needs to know has moved. */
.asks{
  border:3px solid var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-chartreuse);padding:var(--space-base) var(--space-md);
  margin-bottom:var(--space-lg);
}
.asks ul{list-style:none;margin:8px 0 0;padding:0}
.ask-row{
  display:flex;align-items:center;justify-content:space-between;gap:var(--space-base);
  padding:8px 0;border-top:2px dashed var(--color-black);
}
.ask-row p{margin:0;text-align:left}

/* My Tree and Sign out made the bar tight enough to break the brand across two
   lines. The name never wraps; the links give up their spacing first. */
.topbar .name{white-space:nowrap}
/* Six links and a button. The brand gives up size before the bar gives up a
   single line, and the button never drops below the links it sits with. */
@media(max-width:1240px){
  .topbar{gap:var(--space-md);padding-left:var(--space-md);padding-right:var(--space-md)}
  .topbar nav{gap:14px;flex-wrap:nowrap}
  .topbar nav a{font-size:10px;letter-spacing:.08em;white-space:nowrap}
  .topbar .navbtn{padding:8px 14px}
  .topbar .name{font-size:19px}
  .topbar img.mark{width:63px;height:34px}
}
@media(max-width:900px){
  /* Below this the bar genuinely cannot hold it, so it wraps on purpose. */
  .topbar{flex-wrap:wrap}
  .topbar nav{flex-wrap:wrap;margin-left:0;width:100%;justify-content:center}
}


/* ------------------------------------------------------------- four doors
   The tree's landing page is four things and nothing else. Each says what is
   behind it, because a row of unexplained buttons is a quiz. */
/* Four doors, so two by two rather than an auto fit that leaves one stranded
   on its own row. */
.doors{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:var(--space-lg);align-items:stretch;
  max-width:820px;margin:0 auto;
}
@media(max-width:640px){ .doors{grid-template-columns:1fr} }
.door{
  display:flex;flex-direction:column;text-align:center;text-decoration:none;
  color:var(--color-black);height:100%;
  background:var(--color-bg-light);border:3px solid var(--color-black);
  border-radius:var(--radius-xl);padding:var(--space-lg) var(--space-md);
  transition:transform .12s ease, box-shadow .12s ease;
}
.door.tint-pink{box-shadow:11px 11px 0 0 var(--color-pink), 11px 11px 0 3px var(--color-black)}
.door.tint-periwinkle{box-shadow:11px 11px 0 0 var(--color-periwinkle), 11px 11px 0 3px var(--color-black)}
.door.tint-lavender{box-shadow:11px 11px 0 0 var(--color-lavender), 11px 11px 0 3px var(--color-black)}
.door.tint-chartreuse{box-shadow:11px 11px 0 0 var(--color-chartreuse), 11px 11px 0 3px var(--color-black)}
.door:hover{transform:translate(-3px,-3px)}
.door.tint-pink:hover{box-shadow:15px 15px 0 0 var(--color-pink), 15px 15px 0 3px var(--color-black)}
.door.tint-periwinkle:hover{box-shadow:15px 15px 0 0 var(--color-periwinkle), 15px 15px 0 3px var(--color-black)}
.door.tint-lavender:hover{box-shadow:15px 15px 0 0 var(--color-lavender), 15px 15px 0 3px var(--color-black)}
.door.tint-chartreuse:hover{box-shadow:15px 15px 0 0 var(--color-chartreuse), 15px 15px 0 3px var(--color-black)}
.door:focus-visible{outline:3px solid var(--color-black);outline-offset:4px}
.door-title{
  font-family:var(--font-brand);font-size:30px;line-height:1.05;display:block;
  text-wrap:balance;
}
.door-blurb{display:block;font-size:13px;line-height:1.5;margin-top:10px;text-wrap:balance}
.door-meta{
  display:block;margin-top:auto;padding-top:var(--space-base);
  font-family:var(--font-emphasis);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;opacity:.7;
}
.door-go{
  display:inline-block;margin:var(--space-base) auto 0;padding:8px 20px;
  font-family:var(--font-emphasis);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;font-weight:700;
  border:2.5px solid var(--color-black);border-radius:var(--radius-full);
  background:var(--color-pink);
}
.back-to-tree{
  font-family:var(--font-emphasis);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;font-weight:600;text-decoration:none;color:var(--color-black);
  padding:7px 16px;border:2.5px solid var(--color-black);border-radius:var(--radius-full);
  background:var(--color-bg-light);
}
.back-to-tree:hover{background:var(--color-chartreuse)}
@media (prefers-reduced-motion: reduce){ .door{transition:none} .door:hover{transform:none} }

/* Editing a person happens in place: the card swaps its face for a form. */
.tree-card{position:relative}
.edit-in{position:absolute;opacity:0;width:0;height:0}
.tree-edit{display:none;text-align:center}
.tree-card:has(.edit-in:checked) .tree-view{display:none}
.tree-card:has(.edit-in:checked) .tree-edit{display:block}
.tree-edit .lbl{margin-top:10px}
.tree-edit .lbl:first-of-type{margin-top:0}
.edit-open{display:inline-block;margin-top:var(--space-base);cursor:pointer}
.edit-acts{display:flex;justify-content:center;gap:8px;margin-top:var(--space-base);align-items:center}
.edit-acts .who-act{cursor:pointer}

/* Nothing here yet, said properly. A bare sentence on a colour band reads as a
   page that failed rather than a page with room in it. */
.empty{
  max-width:520px;margin:0 auto;text-align:center;
  background:var(--color-bg-light);border:3px dashed var(--color-black);
  border-radius:var(--radius-xl);padding:var(--space-2xl) var(--space-lg);
}
.empty-title{font-family:var(--font-brand);font-size:28px;line-height:1.05;margin:0}
.empty-blurb{font-size:13px;line-height:1.5;margin:10px auto 0;max-width:38ch;text-wrap:balance}
.empty .btn{margin-top:var(--space-lg)}
.empty .btn{scroll-margin-top:96px}

/* A date edits in place too, same rule as a person. */
.ev{position:relative;flex-wrap:wrap}
.ev-view{display:flex;align-items:center;gap:var(--space-base);width:100%}
.ev-edit{display:none;width:100%;text-align:center}
.ev:has(.edit-in:checked) .ev-view{display:none}
.ev:has(.edit-in:checked) .ev-edit{display:block}
.ev-edit .lbl{margin-top:10px}
.ev-edit .lbl:first-of-type{margin-top:0}

/* A card with an offset shadow hangs 14px past its own box, so the section
   looks bottom heavy unless the shadow is given room of its own. */
.slab .wrap > .add-card:last-child,
.slab .wrap > .empty:last-child{margin-bottom:14px}

/* Before a style is chosen the card says so rather than quoting a price for a
   tier nobody picked. */
.p-none{display:none}
.style-card:not(:has(.tier-in:checked)) .p-none{display:block}
.style-card:not(:has(.tier-in:checked)) .headroom{display:none}

/* ---------------------------------------------------------------- on a phone
   The type here goes down to nine pixels for the small caps labels, which is
   fine on a laptop and unreadable in a hand. And a control you press with a
   thumb needs to be a thumb tall, not a cursor tall. */
@media(max-width:600px){
  .me-tag,.skip-tag,.tree-head,.door-meta,.list-count,.split-label,.ev-away,
  .win-note,.note-title,.eyebrow,.tagline,.hint,.micro,
  .yr-m i,.ev-when i,.ev-what i,.gl-credit,.gl-credit a{font-size:11px}
  /* These carry their own size from app.css, so they are named directly. */
  .topbar nav a{font-size:11px}
  .stepper .stepdot i{font-size:11px}
  .bub-content .rel,.bubble-card .rel{font-size:11px}
  .face .hint{font-size:11px}
  .who-act,.jump,.back-to-tree{font-size:11px;padding:10px 14px;min-height:38px;
    display:inline-flex;align-items:center;justify-content:center}
  .chip-pick,.who-pick{min-height:38px;display:inline-flex;align-items:center}
  .cal-day.open{min-height:38px}
  .cal-head span{font-size:12px}
  .look,.pick-box,.win{min-height:44px}
  .btn.sm{min-height:38px;display:inline-flex;align-items:center;justify-content:center}
  /* The calendar is the tightest thing here, so it gets the full width. */
  .cal{max-width:none;padding:var(--space-md) 10px}
  .cal-head,.cal-grid{gap:2px}
}

/* Two across, then one beneath spanning both, so the third reads as a wider
   invitation rather than a stray third option. */
.hero-btns{
  display:grid;grid-template-columns:1fr 1fr;
  gap:var(--space-base);max-width:520px;
}
.hero-btns .btn{
  width:100%;display:flex;align-items:center;justify-content:center;text-align:center;
}
.hero-btns .wide{
  grid-column:1 / -1;
  background:var(--color-lavender);border-color:var(--color-black);
}
.hero-btns .wide:hover{background:var(--color-lavender);filter:brightness(1.04)}
/* Three buttons, three brand colours: pink to book, chartreuse to read on,
   lavender to go and look. */
.hero-btns .secondary:not(.wide){background:var(--color-chartreuse);border-color:var(--color-black)}
.hero-btns .secondary:not(.wide):hover{background:var(--color-chartreuse);filter:brightness(1.04)}
@media(max-width:520px){ .hero-btns{grid-template-columns:1fr} }

/* ------------------------------------------------------------ the bar, small
   Six links, a button and a wordmark do not fit across a phone, and stacking
   them ate a third of the first screen. The links collapse behind a button;
   the booking call to action never does, because it is the reason for the bar. */
.nav-toggle{position:absolute;opacity:0;width:0;height:0}
.burger{display:none}

@media(max-width:820px){
  .topbar{flex-wrap:wrap;row-gap:0}
  .topbar .navbtn{margin-left:auto;order:2}
  .burger{
    display:flex;order:3;flex-direction:column;justify-content:center;gap:4px;
    width:42px;height:42px;padding:9px;cursor:pointer;
    border:2.5px solid var(--color-black);border-radius:var(--radius-lg);
    background:var(--color-bg-light);
  }
  .burger span{display:block;height:3px;background:var(--color-black);border-radius:2px}
  .topbar nav{
    order:4;width:100%;margin-left:0;
    display:none;flex-direction:column;align-items:center;gap:0;
  }
  .topbar:has(.nav-toggle:checked) nav{display:flex;padding:var(--space-base) 0 var(--space-md)}
  .topbar nav a{
    width:100%;text-align:center;padding:12px 0;font-size:12px;
    border-top:2px dashed rgba(0,0,0,.25);
  }
  .topbar:has(.nav-toggle:checked) .burger{background:var(--color-chartreuse)}
  .nav-toggle:focus-visible + nav + .navbtn + .burger{outline:3px solid var(--color-black);outline-offset:3px}
}

/* Sign in with a provider. These only render when their keys are configured,
   so the page never offers a door that does not open. */
.or-line{
  display:flex;align-items:center;gap:12px;margin:var(--space-lg) 0;
  font-family:var(--font-emphasis);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;opacity:.6;
}
.or-line::before,.or-line::after{
  content:"";flex:1;height:10px;
  background-image:var(--rule-h);background-repeat:repeat-x;opacity:.5;
}
.providers{display:flex;flex-direction:column;gap:10px}
.provider{text-align:center}
.provider.google{background:var(--color-bg-light)}
.provider.apple{background:var(--color-black);color:var(--color-bg-light)}
.provider.apple:hover{background:#222}

/* The line the whole about page is built around, set as the statement it is
   rather than as body copy in the display face. */
.creed{
  font-size:clamp(30px, 4.4vw, 46px);line-height:1.2;
  max-width:22ch;margin-left:auto;margin-right:auto;text-wrap:balance;
}

/* The about page reads down the middle, same as every other page here. The
   cartoon section above keeps its own two column arrangement. */
.about-body{text-align:center}
.about-body .body-lg{margin-left:auto;margin-right:auto;max-width:58ch}
.about-body .notecap{justify-content:center;text-align:center}
.about-body .notecap .caption{text-align:center}

/* The stock room. A row at or under its reorder line has to be findable in a
   glance, so it says so rather than leaving her to compare two numbers. */
.ptable tr.is-low{background:var(--color-chartreuse)}
.ptable tr.is-low .nm::after{
  content:"low";margin-left:8px;padding:2px 8px;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;font-family:var(--font-emphasis);font-weight:700;
  border:2px solid var(--color-black);border-radius:var(--radius-full);
  background:var(--color-pink);
}
.move{display:flex;align-items:center;gap:6px}
.move .f{width:74px;margin:0;text-align:center}
.move b{min-width:34px;display:inline-block;text-align:right}
.src{font-size:11px;text-decoration:underline;text-underline-offset:2px}
.stock-search{display:flex;gap:8px;align-items:center;margin-top:16px;max-width:420px}
.stock-search .f{margin:0}
a.chip-pick{text-decoration:none;display:inline-block}
a.chip-pick.on{background:var(--color-pink);font-weight:600}

/* ---------------------------------------------------------- studio calendar
   Her month, with what is open and what is booked on the same grid. Answering
   "when am I free" and "what is on" from two pages meant holding one of them
   in your head while you read the other. */
.cal-bar{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px;align-items:center}
.cal-head.studio{
  display:grid;grid-template-columns:repeat(7,1fr);gap:6px;margin-top:20px;
}
.cal-head.studio span{
  text-align:center;font-family:var(--font-emphasis);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;opacity:.65;
}
.cal-month{display:grid;grid-template-columns:repeat(7,1fr);gap:6px;margin-top:6px}
.cal-cell{
  position:relative;min-height:104px;padding:6px 6px 22px;
  border:2.5px solid var(--color-black);border-radius:var(--radius-lg);
  background:var(--color-bg-light);
}
.cal-cell.pad{border:0;background:none;min-height:0}
.cal-cell.has{background:var(--color-bg-warm)}
.cal-num{
  font-family:var(--font-emphasis);font-size:11px;font-weight:700;opacity:.7;
}
.cal-items{display:flex;flex-direction:column;gap:3px;margin-top:5px}
.slot{
  display:block;font-size:10px;line-height:1.3;padding:3px 6px;text-align:center;
  border:1.5px solid var(--color-black);border-radius:var(--radius-full);
  font-family:var(--font-emphasis);letter-spacing:.04em;
}
.slot.free{background:var(--color-chartreuse)}
.slot.full{background:var(--color-pink)}
.slot.job{
  background:var(--color-periwinkle);text-decoration:none;color:var(--color-black);
  font-weight:700;
}
.slot.job:hover{background:var(--color-lavender)}
.cal-add{position:absolute;right:5px;bottom:4px}
.cal-plus{
  width:22px;height:22px;line-height:1;cursor:pointer;padding:0;
  border:2px solid var(--color-black);border-radius:50%;
  background:var(--color-bg-light);font-weight:700;
}
.cal-plus:hover{background:var(--color-chartreuse)}
@media(max-width:760px){
  .cal-cell{min-height:76px;padding:4px 4px 20px}
  .slot{font-size:9px;padding:2px 4px}
}

/* Surprise requests. These landed in the database for weeks with nowhere to
   read them, so the page leads with the ones she has not answered. */
.reqs{display:grid;gap:var(--space-base);margin-top:20px}
.req{
  background:var(--color-bg-light);border:3px solid var(--color-black);
  border-radius:var(--radius-lg);padding:var(--space-base) var(--space-md);
  box-shadow:8px 8px 0 0 var(--color-periwinkle), 8px 8px 0 3px var(--color-black);
}
.req.is-new{box-shadow:8px 8px 0 0 var(--color-pink), 8px 8px 0 3px var(--color-black)}
.req-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap}
.req-detail{margin-top:10px;white-space:pre-line}
.req-who{margin-top:8px}
.req-who a{color:inherit}
.req-acts{display:flex;gap:8px;align-items:center;margin-top:12px}
.req-acts .f{margin:0;max-width:160px}

/* Closing an account. Reachable, not shouted, and unmistakable once you are on it. */
.close-link{margin-top:var(--space-2xl);text-align:center}
.close-link a{color:inherit;text-decoration:underline;text-underline-offset:3px}
.btn.danger{background:var(--color-pink);border-color:var(--color-black)}
.btn.danger:hover{filter:brightness(1.05)}

/* --------------------------------------------------------------- studio gaps
   These classes were in the studio markup and in neither stylesheet, so the
   controls they name rendered as browser defaults on pages Taylor uses every
   day. They live here rather than in app.css because this sheet loads last and
   would otherwise win.
   -------------------------------------------------------------------------- */

/* Which studio tab you are on. Eleven identical links told her nothing. */
/* Marked with the underline alone. Bolding the active tab made the nav a few
   pixels wider on whichever page you were on, which was enough to wrap it onto
   a second line on some tabs and not others. */
.topbar nav a[aria-current="page"]{
  border-bottom:2px solid var(--color-pink);
}

/* A control that has to sit inside a row without shouting. */
.linkish{
  background:none;border:0;padding:0;cursor:pointer;
  font-family:var(--font-body);font-size:14px;
  text-decoration:underline;text-underline-offset:3px;color:var(--color-black);
}
.linkish:hover{opacity:.65}

/* One item and its control on a line, used by the dashboard panels and the
   partner portal's list. */
.row-line{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.14);
  text-align:left;
}
.row-line:last-child{border-bottom:0}
.row-line .micro{opacity:.7}
@media(max-width:520px){
  .row-line{flex-direction:column;align-items:flex-start;gap:4px}
}

/* Settings. Every price is its own tiny form, and without this the pound sign
   and the box drifted apart on to separate lines. */
.set-form{display:flex;align-items:center;gap:6px}
.set-cur{font-family:var(--font-emphasis);font-size:14px;opacity:.7}
.set-form .f{max-width:9ch;padding:6px 8px;margin:0}
.set-form .btn{padding:6px 12px;font-size:12px}

/* Dashboard counters that mean something needs doing, and the ones that are
   links through to the queue behind them. */
.stat .box.urgent{background:var(--color-pink)}
.stat .box a{color:inherit;text-decoration:none;display:block}
.stat .box a:hover .n{text-decoration:underline;text-underline-offset:3px}

/* A reference in a table that is really a link to the order. */
.plainlink{color:inherit;text-decoration:underline;text-underline-offset:3px}
.plainlink:hover{opacity:.65}

/* The header of a booking card. The status chip was stacking under the time
   instead of sitting beside it. */
.book-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:8px}
.book-head .book-when{flex:1 1 auto}
.book-head .chip{flex:0 0 auto}

/* ------------------------------------------------------------ studio, today
   The dashboard used to state each fact twice: a counter in a grid at the top
   and a panel listing the same rows further down. These are the one shape that
   replaced both, so a queue carries its own count and appears only when it has
   something in it.
   -------------------------------------------------------------------------- */

.queues{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:16px;margin-top:12px;align-items:start;
}
.queue{
  background:var(--color-bg-warm);
  border:3px solid var(--color-black);border-radius:var(--radius-lg);
  padding:16px 20px;box-shadow:var(--shadow-md);
}
.queue-head{
  display:flex;align-items:center;gap:10px;
  padding-bottom:10px;border-bottom:2px solid var(--color-black);
}
.queue-head .emph{margin:0;flex:1 1 auto}
/* The count that used to be a separate box on the other side of the page. */
.queue-n{
  flex:0 0 auto;min-width:26px;padding:2px 8px;text-align:center;
  background:var(--color-pink);border:2px solid var(--color-black);
  border-radius:var(--radius-full);
  font-family:var(--font-emphasis);font-size:12px;
}
.queue-head a{flex:0 0 auto}
.queue .row-line:first-of-type{padding-top:10px}

/* Nothing on today, or nothing waiting. Said once, calmly, instead of drawn as
   three empty kanban columns. */
.quiet-day{
  background:var(--color-chartreuse);
  border:3px solid var(--color-black);border-radius:var(--radius-lg);
  padding:20px 24px;margin-top:20px;text-align:center;
}
.quiet-day .emph{margin:0}

/* The passive numbers. Deliberately quieter than a queue: these are context,
   not things to do, and when they looked identical to the action items the
   page had no hierarchy at all. */
.figures{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,140px),1fr));
  gap:12px;margin-top:12px;
}
.figures > div{
  border:2px solid rgba(0,0,0,.25);border-radius:var(--radius-base);
  padding:12px 16px;background:transparent;
}
.figures .n{
  font-family:var(--font-brand);font-size:26px;line-height:1;display:block;
}
.figures .micro{margin-top:4px;opacity:.7}

@media(max-width:600px){
  .queues{grid-template-columns:1fr}
  .queue{padding:14px 16px}
}

/* A structural heading for the dashboard's zones. Deliberately not
   .section-header: that is the script face the customer pages use, and putting
   two sizes of handwriting on one screen gave the page no hierarchy at all. */
.zone-label{
  font-family:var(--font-emphasis);font-size:12px;letter-spacing:.16em;
  text-transform:uppercase;margin:40px 0 0;padding-bottom:8px;
  border-bottom:2px solid var(--color-black);
}
.zone-label + *{margin-top:14px}

/* .emph capitalises every word, which is right for a label and wrong for a
   sentence. These are sentences. */
.quiet-line{
  font-family:var(--font-emphasis);font-size:18px;margin:0;
}

/* auto-fit stretches a lone card across the whole row, so one queue with one
   row in it became a 1100px band of empty warm paper. auto-fill keeps the
   empty tracks, so a single queue stays the width of a queue. */
/* min() so the track can never be wider than the screen. A bare 420px minimum
   forces a 420px column inside a 375px phone and pushes the card off the
   right edge. */
.queues{grid-template-columns:repeat(auto-fill,minmax(min(100%,420px),1fr))}

/* The studio carries eleven nav items where the customer side carries five, and
   at the customer spacing they wrapped onto a second line on every page. The
   tag chip is what marks a studio page, so scope the tightening to that rather
   than to a class every handler would have to remember to pass. */
.topbar:has(.tag) nav{gap:10px}
.topbar:has(.tag) nav a{letter-spacing:.04em;font-size:10px}

/* Columns stretched to match the tallest one, so a day with two jobs in Booked
   drew two empty boxes the same height beside it. */
.board{align-items:start}

/* Studio pages carry tables and boards, so they use the full measure. Forms
   inside them do not: a two field form stretched to 1100px reads as a mistake.
   Scoped to the tag chip, which is what marks a studio page. */
body:has(.topbar .tag) .form-card{max-width:680px;margin-left:auto;margin-right:auto}
body:has(.topbar .tag) .zone-label{margin-top:40px}


/* The brand on a phone.
   Below 900 the nav drops to its own line, so the top row is just the mark, the
   name and the burger and there is room for all three. It was being squashed
   into a 24px square by the 1240 rule, which is both smaller and the wrong
   shape: the mark is 1.85:1. */
@media(max-width:900px){
  .topbar img.mark{width:96px;height:52px}
  .topbar .name{font-size:44px}
}
@media(max-width:420px){
  .topbar img.mark{width:78px;height:42px}
  .topbar .name{font-size:36px}
}

/* A caption introducing a centred form card, centred with it. Left aligned
   under a centred box read as two different pages. */
body:has(.topbar .tag) .zone-label + .caption{text-align:center;max-width:70ch;margin-inline:auto}


/* The eyebrow is short but not always short enough. Balanced, so it splits
   evenly instead of stranding a single word like "INC." on its own line. */
.eyebrow{text-wrap:balance}


/* The header on a phone, centred.
   The brand is wide enough to take the whole first row, which left the button
   and the burger shoved against the right edge by margin-left:auto and the
   whole bar looking like it had fallen over. Both rows centre instead: the
   brand on its own line, then the call to action and the menu together under
   it. */
@media(max-width:820px){
  .topbar{justify-content:center}
  /* The brand link. Its display:flex is inline, so only the centring is set here. */
  .topbar > a:first-child{width:100%;justify-content:center}
  .topbar .navbtn{margin-left:0}
  /* The studio chip rides with the brand rather than starting the second row. */
  .topbar .tag{order:1}
}


/* Money and counts line up down a column. Lexend's digits are proportional by
   default, so a column of prices staggered by a pixel or two per row. */
.ptable td, .split-amt, .tier .amount, .stat .box .n, .figures .n, .queue-n{
  font-variant-numeric:tabular-nums;
}

/* L7: these were 11px, one step off a scale that has no 11. */
.eyebrow, .micro{font-size:var(--font-size-xs)}
