/* ============================================================
   Build your set -- PROTOTYPE styles.

   Sits on top of the real site.css, so the colours, type and buttons
   are the site's own. Same rules as there: ivory and slate only, no
   shadows, no dark mode. The only colour on the page is on the nails.
   ============================================================ */

.proto-flag {
  margin: 0;
  max-width: none;
  width: 100%;
  padding: 7px 16px;
  text-align: center;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--blue);
}

.byo-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 26px 20px 0;
}
.byo-wordmark { width: 150px; }

.bow-egg {
  border: 0;
  background: none;
  padding: 4px;
  cursor: pointer;
  border-radius: 50%;
}
.bow-egg { border-radius: var(--radius); }
.bow-egg:active img { transform: scale(0.97); }

/* ---------- layout ---------- */

/* The site's heading and fine print sit above and below the builder, so
   they line up with its first column rather than being centred on the
   site's narrower 640px content width -- otherwise the h2 floats off to
   the right of the service cards. Same max-width and padding as .byo. */
.byo-rail {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 28px;
}
@media (max-width: 560px) { .byo-rail { padding: 0 20px; } }

.byo {
  max-width: 1240px;
  margin: 0 auto;
  padding: 18px 28px 120px;
  display: grid;
  gap: 0 48px;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "intro" "stage" "steps" "ticket";
}

.byo-intro { grid-area: intro; text-align: center; padding: 18px 0 8px; }
.byo-intro h1 { font-size: clamp(40px, 6vw, 58px); }
.byo-intro .eyebrow { margin: 0 auto 8px; max-width: none; text-align: center; }
.lede-small {
  max-width: 470px;
  margin: 12px auto 0;
  color: var(--ink-soft);
  font-size: 15.5px;
}

.side { display: contents; }
.stage { grid-area: stage; }
.steps-wrap { grid-area: steps; min-width: 0; }
.steps { container-type: inline-size; }
.ticket-col { grid-area: ticket; }

/* On a phone the hands stay pinned at the top while you scroll through
   the choices -- seeing a colour land on the nails is the whole point. */
.stage {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--paper);
  margin: 0 -20px;
  padding: 6px 20px 4px;
  border-bottom: 1px solid var(--line);
}
#hands {
  display: block;
  width: 100%;
  max-height: 36vh;
  overflow: visible;
}
.hand-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 4px;
}
.hand-switch {
  display: inline-flex;
  border: 1px solid var(--blue);
  border-radius: 999px;
  overflow: hidden;
}
.hand-switch button {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue);
  background: none;
  border: 0;
  padding: 8px 16px;
  min-height: 36px;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.hand-switch button[aria-pressed="true"] { background: var(--blue); color: var(--paper); }
.mirror-btn {
  font: inherit;
  font-size: 13px;
  color: var(--blue-link);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 14px;
  min-height: 36px;
  cursor: pointer;
  transition: opacity 0.2s, border-color 0.2s;
}
.mirror-btn:hover { border-color: var(--blue-soft); }
.mirror-btn:disabled { opacity: 0.4; cursor: default; }
@media (min-width: 600px) { .hand-switch { display: none; } }
/* On a phone the Left/Right switch already says which hand it is. */
@media (max-width: 599px) { #hands .caption { display: none; } }

.stage-hint {
  margin: 2px 0 4px;
  text-align: center;
  font-family: var(--display);
  font-style: italic;
  font-size: 18px;
  color: var(--ink-soft);
  min-height: 1.6em;
}

@media (min-width: 900px) {
  .byo {
    grid-template-columns: minmax(0, 1fr) 420px;
    grid-template-areas: "intro intro" "steps side";
  }
  .side {
    display: block;
    grid-area: side;
    position: sticky;
    top: 16px;
    align-self: start;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    scrollbar-width: none;
  }
  .stage {
    position: static;
    margin: 0;
    padding: 0;
    border: 0;
  }
  #hands { max-height: none; }
}

@media (min-width: 1260px) {
  .byo {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr) 330px;
    grid-template-areas: "intro intro intro" "steps stage ticket";
    gap: 0 40px;
  }
  .side { display: contents; }
  .stage, .ticket-col {
    position: sticky;
    top: 24px;
    align-self: start;
  }
  .stage { padding-top: 40px; }
}

/* ---------- the hands ---------- */

.nail-fill { transition: fill 0.45s ease; }
/* The nails are born with no fill (so black), and the first draw sets the
   real colour. Without this that read as a fade from black on every load.
   book.js drops the class once the first draw is on screen. */
#hands.first .nail-fill { transition: none; }
.hand { transition: opacity 0.3s ease; }
.hand.off { opacity: 0; pointer-events: none; }
.nail-btn { cursor: default; outline: none; }
#hands.tappable .nail-btn { cursor: pointer; }
.nail-btn:focus-visible .nail-line { stroke-width: 3; }
#hands.tappable .nail-btn:hover .nail-line { stroke-width: 2; }
.fixmark { transition: opacity 0.25s ease; }

.art.pop {
  transform-box: fill-box;
  transform-origin: center;
  animation: pop 0.34s cubic-bezier(0.2, 1.5, 0.4, 1);
}
@keyframes pop {
  from { transform: scale(0.4); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.sparks { opacity: 0; }
.sparks.go { animation: sparks 0.5s ease-out; }
@keyframes sparks {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}
.sparks.go path { animation: spark-out 0.5s ease-out; }
@keyframes spark-out {
  from { stroke-dasharray: 0 20; }
  to   { stroke-dasharray: 7 20; stroke-dashoffset: -6; }
}

#hands.nudge { animation: nudge 0.42s ease; }
@keyframes nudge {
  20% { transform: translateX(-6px); }
  45% { transform: translateX(5px); }
  70% { transform: translateX(-3px); }
}

/* The massage: two slow rings, then a few quiet glints. */
.ripple { opacity: 0; transform-box: fill-box; transform-origin: center; }
#hands.breathing .ripple { animation: ripple 1.5s ease-out both; }
#hands.breathing .ripple.r1 { animation-delay: 0.3s; }
#hands.breathing .ripple.r2 { animation-delay: 0.6s; }
@keyframes ripple {
  0%   { opacity: 0; transform: scale(0.12); }
  15%  { opacity: 0.95; }
  100% { opacity: 0; transform: scale(1.1); }
}
.glint { opacity: 0; transform-box: fill-box; transform-origin: center; transition: opacity 0.6s; }
#hands.pampered .glint { animation: glint 3.2s ease-in-out infinite; }
#hands.pampered .glint:nth-of-type(2) { animation-delay: 1.1s; }
#hands.pampered .glint:nth-of-type(3) { animation-delay: 2.1s; }
@keyframes glint {
  0%, 100% { opacity: 0; transform: scale(0.4) rotate(0deg); }
  45%      { opacity: 0.9; transform: scale(1) rotate(45deg); }
}

/* ---------- steps ---------- */

.step {
  padding: 34px 0 30px;
  border-bottom: 1px solid var(--line-blue);
  transition: opacity 0.4s ease, filter 0.4s ease;
}
.step h2 {
  font-size: 30px;
  margin: 0 0 18px;
  display: flex;
  align-items: baseline;
  gap: 12px;
}
.step .num {
  font-family: var(--body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--blue-link);
}
.step-sub, .step-note {
  color: var(--ink-soft);
  font-size: 15px;
  margin: -6px 0 16px;
}
.step-note { margin: 12px 0 0; }

.step.locked { opacity: 0.38; filter: grayscale(1); pointer-events: none; }
.step.unlocking {
  animation: unlock 0.6s ease both;
  animation-delay: calc(var(--i) * 90ms);
}
@keyframes unlock {
  from { opacity: 0.38; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

body.is-sent .steps { opacity: 0.45; pointer-events: none; transition: opacity 0.6s; }

/* base cards */

.bases {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}


.base {
  position: relative;
  display: flex;
  flex-direction: column;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  transition: border-color 0.2s, transform 0.2s;
}
.base:hover { border-color: var(--blue-soft); }
.base:focus-visible { outline: 2px solid var(--blue-link); outline-offset: 2px; }
.base.is-on { border-color: var(--blue); }
.base.is-on::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid var(--blue);
  pointer-events: none;
}
.base-photo { display: block; aspect-ratio: 4 / 3; overflow: hidden; background: var(--paper-tint); }
.base-photo img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s ease; }
.base:hover .base-photo img { transform: scale(1.04); }
.base-body { display: grid; gap: 4px; padding: 14px 14px 16px; }
.base-name { font-family: var(--display); font-size: 21px; line-height: 1.15; font-weight: 500; }
.base-price { font-family: var(--display); font-size: 24px; color: var(--blue); }
.base-blurb { font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); }
.base-incl { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 4px; }
.base-incl span {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--blue-link);
}
.base-chosen {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 5px 9px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--blue);
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.2s, transform 0.2s;
}
.base.is-on .base-chosen { opacity: 1; transform: none; }

/* After the .base rules on purpose, so it wins. When the choices column is narrow (a phone, or the three-column
   desktop layout) the cards lie on their side: photo left, words right. */
@container (max-width: 600px) {
  .bases { grid-template-columns: minmax(0, 1fr); }
  .base { display: grid; grid-template-columns: 110px minmax(0, 1fr); }
  .base-photo { aspect-ratio: auto; height: 100%; min-height: 120px; }
}
.quick { margin-top: 22px; }
.quick-label {
  margin: 0 0 10px;
  font-family: var(--display);
  font-style: italic;
  font-size: 19px;
  color: var(--ink-soft);
}

/* chips */

.chips, .quick-row { display: flex; flex-wrap: wrap; gap: 8px; }
.chips + .chips { margin-top: 12px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 9px 16px;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s, color 0.2s;
}
.chip:hover { border-color: var(--blue-soft); }
.chip:focus-visible { outline: 2px solid var(--blue-link); outline-offset: 2px; }
.chip.is-on { background: var(--blue); border-color: var(--blue); color: var(--paper); }
.chip-price { color: var(--ink-faint); }
.chip.is-on .chip-price { color: var(--line-blue); }

.icon-chip {
  flex-direction: column;
  /* Labels line up along the bottom however tall the nail above them is. */
  justify-content: flex-end;
  gap: 6px;
  border-radius: var(--radius);
  padding: 10px 12px 9px;
  min-width: 70px;
  font-size: 12.5px;
}
.icon-chip svg { display: block; }
.icon-chip.is-on { background: var(--paper-raised); color: var(--ink); border-color: var(--blue); box-shadow: inset 0 0 0 1px var(--blue); }

/* polish bottles */

.bottles { display: flex; flex-wrap: wrap; gap: 6px 4px; }
.bottle {
  border: 0;
  background: none;
  padding: 6px 6px 10px;
  cursor: pointer;
  position: relative;
  transition: transform 0.25s cubic-bezier(0.2, 1.4, 0.4, 1);
}
.bottle svg { display: block; }
.bottle:hover { transform: translateY(-3px); }
.bottle.is-on { transform: translateY(-6px) rotate(-6deg); }
.bottle::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 18px;
  height: 2px;
  margin-left: -9px;
  background: var(--blue);
  transform: scaleX(0);
  transition: transform 0.25s;
}
.bottle.is-on::after { transform: scaleX(1) rotate(6deg); }
.bottle:focus-visible { outline: 2px solid var(--blue-link); outline-offset: 2px; border-radius: 4px; }

/* art */

.art-tally {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin: 18px 0 0;
  font-family: var(--display);
  font-size: 22px;
}
.art-deal { font-style: italic; font-size: 17px; color: var(--blue-link); }
.art-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 20px; margin-top: 14px; }
.link-btn {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 13.5px;
  color: var(--blue-link);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  cursor: pointer;
}
.link-btn:hover { color: var(--ink); }
.tier-key { margin: 14px 0 0; font-size: 12.5px; color: var(--ink-faint); letter-spacing: 0.02em; }

/* the massage */

.extra {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: start;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--paper-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  cursor: pointer;
  transition: border-color 0.2s;
}
.extra:hover { border-color: var(--blue-soft); }
.extra:focus-visible { outline: 2px solid var(--blue-link); outline-offset: 2px; }
.extra.is-on { border-color: var(--blue); box-shadow: inset 0 0 0 1px var(--blue); }
.extra-box {
  width: 20px;
  height: 20px;
  margin-top: 3px;
  border: 1.5px solid var(--blue);
  border-radius: 50%;
  position: relative;
  transition: background 0.2s;
}
.extra.is-on .extra-box { background: var(--blue); }
.extra.is-on .extra-box::after {
  content: "";
  position: absolute;
  /* Centre the box, then lift it: a rotated check's ink sits below its
     box's middle, so the box's middle is not where it looks centred. */
  left: 50%;
  top: 50%;
  width: 5px;
  height: 10px;
  border: solid var(--paper);
  border-width: 0 2px 2px 0;
  transform: translate(-50%, calc(-50% - 1.8px)) rotate(45deg);
}
.extra-text { display: grid; gap: 2px; }
.extra-text strong { font-family: var(--display); font-size: 21px; font-weight: 500; line-height: 1.2; }
.extra-text span { line-height: 1.5; }
.extra-text span { font-size: 14px; color: var(--ink-soft); }
.extra-price { font-family: var(--display); font-size: 22px; color: var(--blue); }

/* ---------- the ticket ---------- */

.ticket-col { padding-top: 34px; }
@media (min-width: 900px) and (max-width: 1259px) { .ticket-col { padding-top: 6px; } }

.ticket {
  position: relative;
  background: #fbf8f2;
  border: 1px solid var(--line);
  padding: 22px 22px 0 50px;
}
.vine {
  position: absolute;
  left: 8px;
  top: 16px;
  width: 30px;
  height: 380px;
  overflow: visible;
  pointer-events: none;
}
.vine .stem {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 0.9s ease;
}
.vine .leaf {
  opacity: 0;
  transform: scale(0);
  transition: opacity 0.4s ease 0.35s, transform 0.5s cubic-bezier(0.2, 1.5, 0.4, 1) 0.35s;
}
.vine .leaf.on { opacity: 1; transform: scale(1); }

.ticket-head {
  display: flex;
  justify-content: space-between;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue);
}
.ticket-no { color: var(--ink-faint); letter-spacing: 0.12em; }
.ticket-title {
  font-family: var(--display);
  font-size: 34px;
  font-style: italic;
  margin: 6px 0 12px;
  line-height: 1.1;
}

.lines { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.line { padding: 10px 0; border-bottom: 1px dotted var(--line); }
.line .row { display: flex; align-items: baseline; gap: 6px; }
.line .what { font-size: 14.5px; }
.line .dots { flex: 1; }
.line .price { font-family: var(--display); font-size: 19px; font-weight: 500; white-space: nowrap; }
.line .detail { font-size: 12.5px; color: var(--ink-faint); margin-top: 1px; }
.line.faint { padding: 5px 0; }
.line.faint .what, .line.faint .price {
  font-size: 12.5px;
  font-family: var(--body);
  font-weight: 400;
  color: var(--ink-faint);
}
.line.faint .what::before { content: "✓ "; color: var(--blue-link); }
.line.empty .what { font-family: var(--display); font-style: italic; color: var(--ink-faint); font-size: 17px; }

/* A new line writes itself in, left to right, like ink. */
.line.ink { animation: ink 0.55s ease-out both; }
@keyframes ink {
  from { clip-path: inset(0 100% 0 0); opacity: 0.3; }
  to   { clip-path: inset(0 0 0 0); opacity: 1; }
}
.line.flash .price, .line.flash .what { animation: flash 0.5s ease; }
@keyframes flash {
  0%   { color: var(--blue-soft); }
  100% { color: inherit; }
}

.total-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 14px 0 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue);
}
.total {
  display: inline-flex;
  font-family: var(--display);
  font-size: 46px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink);
  line-height: 1;
}
.total .cur { font-size: 0.6em; margin-top: 0.3em; margin-right: 2px; }
.odo { display: inline-flex; }
/* Lining figures, not Cormorant's default old-style ones: old-style 3s
   and 5s dip below the line and got sliced off by the digit window.
   The window is also a little taller than the type for the same reason. */
.total, .tb-total { font-variant-numeric: lining-nums tabular-nums; }
.digit { display: inline-block; height: 1.2em; overflow: hidden; }
.strip { display: flex; flex-direction: column; transition: transform 0.6s cubic-bezier(0.25, 1.3, 0.4, 1); }
.strip span { height: 1.2em; line-height: 1.2; text-align: center; }

.ticket-fine { font-size: 12.5px; color: var(--ink-soft); margin: 4px 0 14px; line-height: 1.55; }
.ticket-when {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 12.5px;
  padding: 10px 0 18px;
  border-top: 1px dotted var(--line);
}
.ticket-when .faint { color: var(--ink-faint); font-style: italic; }

/* The tear-off stub with the button on it. */
.stub { position: relative; margin: 0 -22px 0 -50px; padding: 22px 22px 22px; }
.perf {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  border-top: 1.5px dashed var(--line-blue);
}
.perf::before, .perf::after {
  content: "";
  position: absolute;
  top: -9px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--line);
}
/* The notches are bites out of the ticket's edge, so only the half of each
   circle that is inside the ticket is drawn; the outer half used to poke out
   past the edge with its outline. */
.perf::before { left: -9px; clip-path: inset(0 0 0 50%); }
.perf::after { right: -9px; clip-path: inset(0 50% 0 0); }
.send { width: 100%; }

/* The number is printed on the stub too, as on a real ticket. */
.stub-no {
  display: block;
  text-align: right;
  margin: 0 0 12px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* THE RIP. The moment the request is accepted the stub comes away from the
   ticket: it stops being part of the ticket's height (so the ticket shrinks
   to its torn size and the zigzag edge shows) and becomes a loose piece of
   paper, still sitting exactly where it was. It then peels off from the left
   while staying pinned at the right, as if pulled from the left-hand end, its
   top edge going ragged as it goes, and drops away. */
.ticket.tearing,
.ticket.torn { padding-bottom: 18px; }

.ticket.tearing .stub {
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  top: calc(100% - 18px);
  margin: 0;
  padding-left: 50px;
  background: #fbf8f2;
  box-shadow: inset 1px 0 0 var(--line), inset -1px 0 0 var(--line), inset 0 -1px 0 var(--line);
  transform-origin: 96% 0;
  animation: rip 0.98s cubic-bezier(0.45, 0, 0.8, 0.6) forwards;
}
@keyframes rip {
  0%   { transform: none; opacity: 1;
         clip-path: polygon(0 0, 8% 0, 16% 0, 24% 0, 32% 0, 40% 0, 48% 0, 56% 0, 64% 0, 72% 0, 80% 0, 88% 0, 100% 0, 100% 100%, 0 100%); }
  14%  { transform: rotate(-1.5deg) translateY(1px);
         clip-path: polygon(0 0, 8% 4px, 16% 1px, 24% 5px, 32% 2px, 40% 6px, 48% 1px, 56% 5px, 64% 2px, 72% 4px, 80% 0, 88% 3px, 100% 0, 100% 100%, 0 100%); }
  55%  { transform: rotate(-9deg) translateY(8px);
         clip-path: polygon(0 0, 8% 4px, 16% 1px, 24% 5px, 32% 2px, 40% 6px, 48% 1px, 56% 5px, 64% 2px, 72% 4px, 80% 0, 88% 3px, 100% 0, 100% 100%, 0 100%); }
  100% { transform: translate(20px, 200px) rotate(-24deg); opacity: 0;
         clip-path: polygon(0 0, 8% 4px, 16% 1px, 24% 5px, 32% 2px, 40% 6px, 48% 1px, 56% 5px, 64% 2px, 72% 4px, 80% 0, 88% 3px, 100% 0, 100% 100%, 0 100%); }
}
.ticket.torn .stub { display: none; }
/* The torn edge: a row of little paper-coloured teeth along the bottom. */
.ticket.tearing::after,
.ticket.torn::after {
  content: "";
  position: absolute;
  left: -1px;
  right: -1px;
  bottom: -7px;
  height: 8px;
  background:
    linear-gradient(-45deg, var(--paper) 4px, transparent 0) 0 0 / 8px 8px repeat-x,
    linear-gradient(45deg, var(--paper) 4px, transparent 0) 0 0 / 8px 8px repeat-x;
}

/* Lands low on the ticket, over the fine print, so every price on it
   stays readable through the ink. */
.stamp {
  position: absolute;
  right: 6px;
  bottom: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: multiply;
}
.ticket.stamped .stamp { animation: stamp 0.42s cubic-bezier(0.3, 1.6, 0.5, 1) forwards; }
@keyframes stamp {
  0%   { opacity: 0; transform: scale(1.9) rotate(-4deg); }
  60%  { opacity: 0.9; transform: scale(0.94) rotate(-13deg); }
  100% { opacity: 0.86; transform: scale(1) rotate(-12deg); }
}

/* after sending */

.after { padding: 26px 4px 0; }
.after.in { animation: unlock 0.7s ease both; }
.after .after-big { color: var(--ink); font-family: var(--display); font-size: 30px; line-height: 1.15; margin: 0 0 8px; }
.after p { color: var(--ink-soft); font-size: 15px; }
.signoff {
  font-family: var(--display);
  font-style: italic;
  font-size: 24px;
  color: var(--blue) !important;
  margin: 14px 0 22px;
}
.after-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---------- typing on a phone ---------- */

/* While a field has focus the keyboard covers half the screen, and the
   pinned hands (up to 36vh -- which iOS measures WITHOUT the keyboard)
   take most of what's left, so you can't see what you're typing. The
   hands step aside until the keyboard goes away. See watchTyping(). */
@media (max-width: 899px) {
  body.typing .stage { display: none; }
  body.typing .totalbar { display: none !important; }
}

/* ---------- the phone's total bar ---------- */

.totalbar {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 18px;
  font: inherit;
  color: var(--paper);
  background: var(--blue);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  animation: rise 0.35s ease both;
}
.totalbar[hidden] { display: none; }
@keyframes rise { from { transform: translateY(30px); opacity: 0; } }
.tb-label { font-size: 11px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; }
.tb-total { font-family: var(--display); font-size: 26px; line-height: 1; }
.tb-go { margin-left: auto; font-size: 13px; }
@media (min-width: 900px) { .totalbar { display: none !important; } }

/* ---------- the bow's daisies ---------- */

.daisies { position: fixed; inset: 0; pointer-events: none; z-index: 50; }
.daisy {
  position: absolute;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  animation: daisy 1.5s cubic-bezier(0.2, 0.7, 0.4, 1) forwards;
}
@keyframes daisy {
  0%   { transform: translate(0, 0) scale(0) rotate(0); opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(var(--s)) rotate(var(--r)); opacity: 0; }
}

/* ---------- moving between steps ---------- */

.next-btn { display: none; }
.step-nav { display: none; }

/* Under 900px the hands are pinned at the top, so the steps turn into a
   row of cards you swipe through (or that slide along by themselves as
   you choose) -- the nails never leave the screen. */
@media (max-width: 899px) {
  .step-nav {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 14px 0 2px;
  }
  .step-nav::-webkit-scrollbar { display: none; }
  .step-nav button {
    flex: none;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--blue);
    background: none;
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 7px 13px;
    cursor: pointer;
    transition: background 0.2s, color 0.2s, border-color 0.2s;
  }
  .step-nav button.is-here { background: var(--blue); border-color: var(--blue); color: var(--paper); }
  .step-nav button.is-done::after { content: " ✓"; }
  .step-nav button:disabled { opacity: 0.35; cursor: default; }

  .steps {
    display: flex;
    align-items: flex-start;
    overflow-x: auto;
    /* Sideways only. Without this a tap that pulls something into view
       can nudge the row down, hiding the top of the card. */
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    position: relative;
    margin: 0 -28px;
    transition: height 0.35s ease;
  }
  .steps::-webkit-scrollbar { display: none; }
  .step {
    flex: 0 0 100%;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    padding: 22px 28px 26px;
    border-bottom: 0;
  }
  .step h2 { font-size: 26px; }
  .next-btn {
    display: flex;
    justify-content: flex-end;
    margin-top: 22px;
  }
  .ticket-col { padding-top: 10px; }
}

.later-btn { margin: 0 0 16px; }

/* "needs length" on the pointed shapes, for natural-nail services */
.icon-chip .needs {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue-link);
  margin-top: -3px;
}
.shape-note { font-size: 14px; }
.shape-note .link-btn { font-size: 14px; }
.later-btn.is-on { background: var(--blue); color: var(--paper); }

/* the nail art counter */
.stepper { display: flex; align-items: center; gap: 22px; margin: 6px 0 4px; }
.step-btn {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid var(--blue);
  background: var(--paper-raised);
  color: var(--blue);
  font: inherit;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, opacity 0.2s;
}
.step-btn:hover:not(:disabled) { background: var(--blue); color: var(--paper); }
.step-btn:active:not(:disabled) { transform: scale(0.94); }
.step-btn:disabled { opacity: 0.3; cursor: default; }
.step-btn:focus-visible { outline: 2px solid var(--blue-link); outline-offset: 2px; }
.step-read { display: grid; justify-items: center; min-width: 74px; }
.step-read output {
  font-family: var(--display);
  font-size: 54px;
  line-height: 1;
  font-variant-numeric: lining-nums;
}
.step-read span {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.mirror-btn[hidden] { display: none; }
.hand-bar[hidden] { display: none; }

/* `.chips` sets display: flex, which beats the [hidden] attribute -- so
   the Length row showed on natural-nail services when it shouldn't. */
.chips[hidden] { display: none; }
