/* Swan Jewellry — banner, marquees and the Etsy-style product blocks.
   Loaded after main.css so it can lean on the same custom properties. */

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

.banner {
  position: relative;
  overflow: hidden;
  background: var(--navy-deep);
  min-height: clamp(430px, 62vh, 640px);
  display: grid;
}
.banner-slide {
  grid-area: 1 / 1;
  position: relative;
  display: grid;
  place-items: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity .9s ease;
}
.banner-slide.on { opacity: 1; visibility: visible; }

/* blurred still sits behind the 16:9 clip so ultrawide never shows bars */
.banner-bg, .banner-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; pointer-events: none;
}
.banner-bg { filter: blur(26px) saturate(.85); transform: scale(1.12); }
.banner-video { opacity: .92; }

.banner-slide::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, rgba(6,23,53,.92) 0%, rgba(6,23,53,.72) 42%, rgba(6,23,53,.35) 100%);
}
@media (max-width: 720px) {
  .banner-slide::after { background: linear-gradient(180deg, rgba(6,23,53,.6) 0%, rgba(6,23,53,.9) 62%); }
}

.banner-inner {
  position: relative; z-index: 2;
  width: min(100% - 32px, var(--wrap));
  margin-inline: auto;
  padding: 40px 0;
  color: #fff;
  display: grid; gap: 26px; align-items: center;
}
@media (min-width: 900px) {
  .banner-inner { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 44px; padding: 52px 0; }
}
.banner-copy { max-width: 620px; min-width: 0; }

/* the ring itself, over the video */
.banner-shot { position: relative; display: block; justify-self: center; width: min(78vw, 380px); }
@media (min-width: 900px) { .banner-shot { width: min(100%, 420px); justify-self: end; } }
.banner-shot img {
  width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: var(--r-lg);
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
  border: 3px solid rgba(255,255,255,.16);
}
.banner-badge {
  position: absolute; top: 12px; left: 12px;
  background: #fff; color: var(--navy-deep);
  font-size: .7rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  padding: 6px 12px; border-radius: 999px; box-shadow: var(--shadow);
}
@media (max-width: 899px) {
  .banner-shot { order: -1; width: min(58vw, 260px); }
  .banner-inner { padding: 30px 0 40px; }
}
.banner-eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: .72rem; letter-spacing: .18em; text-transform: uppercase; font-weight: 700;
  color: #C7D4EC; margin-bottom: 14px;
}
/* The personalisation promise is the reason people are here — it gets a lit
   pill rather than the quiet grey line the other slides use. */
.banner-eyebrow.hl {
  position: relative; overflow: hidden;
  color: #fff; background: rgba(255,255,255,.13);
  border: 1px solid rgba(255,255,255,.34);
  border-radius: 999px; padding: 7px 15px 7px 12px;
  box-shadow: 0 6px 22px rgba(6,23,53,.45);
}
.banner-eyebrow.hl svg { width: 14px; height: 14px; flex: none; fill: var(--star); }
.banner-eyebrow.hl::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 38%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.5), transparent);
  transform: translateX(-160%); animation: shine 4.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .banner-eyebrow.hl::after { animation: none; opacity: 0; } }
.banner h1 {
  color: #fff; font-size: clamp(1.8rem, 4.6vw, 3.1rem); margin-bottom: 12px; text-wrap: balance;
}
.banner p.lede { color: #D5DEEE; font-size: clamp(.95rem, 1.6vw, 1.08rem); max-width: 52ch; }
.banner-price { display: flex; align-items: baseline; gap: 10px; margin: 16px 0 4px; }
.banner-price .now { font-family: var(--serif); font-size: 1.7rem; font-weight: 600; }
.banner-price del { color: #9FB0CC; font-size: 1rem; }
.banner-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.banner .btn-ghost { background: rgba(255,255,255,.1); color: #fff; border-color: rgba(255,255,255,.35); backdrop-filter: blur(6px); }
.banner .btn-ghost:hover { background: rgba(255,255,255,.2); border-color: #fff; }
.banner .btn-primary { background: #fff; color: var(--navy-deep); }
.banner .btn-primary:hover { background: #E9EEF7; }

.banner-rating { display: flex; align-items: center; gap: 9px; margin-top: 18px; font-size: .86rem; color: #D5DEEE; }

.banner-dots { position: absolute; left: 0; right: 0; bottom: 18px; z-index: 3;
  display: flex; gap: 8px; justify-content: center; }
.banner-dots button {
  width: 34px; height: 4px; border-radius: 99px; border: 0; padding: 0;
  background: rgba(255,255,255,.34); transition: background .3s;
}
.banner-dots button.on { background: #fff; }

/* ---------------------------------------------------------------- marquees */

.marquee { overflow: hidden; position: relative; }
.marquee::before, .marquee::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 70px; z-index: 2; pointer-events: none;
}
.marquee::before { left: 0;  background: linear-gradient(90deg, var(--paper), transparent); }
.marquee::after  { right: 0; background: linear-gradient(270deg, var(--paper), transparent); }
.section-alt .marquee::before { background: linear-gradient(90deg, var(--paper-2), transparent); }
.section-alt .marquee::after  { background: linear-gradient(270deg, var(--paper-2), transparent); }

.marquee-track { display: flex; gap: 12px; width: max-content; will-change: transform; }
.marquee-track.ltr { animation: mq-ltr var(--speed, 60s) linear infinite; }
.marquee-track.rtl { animation: mq-rtl var(--speed, 70s) linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }

/* the track holds the set twice, so -50% is a seamless wrap */
@keyframes mq-ltr { from { transform: translateX(-50%); } to { transform: translateX(0); } }
@keyframes mq-rtl { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.mq-photo {
  flex: none; width: 132px; height: 132px; border-radius: var(--r);
  object-fit: cover; background: var(--paper-2); cursor: zoom-in;
}
@media (min-width: 700px) { .mq-photo { width: 168px; height: 168px; } }

.mq-row + .mq-row { margin-top: 12px; }

/* video reel marquee */
.mq-reel {
  flex: none; width: 176px; border-radius: var(--r); overflow: hidden;
  background: #000; position: relative; display: block; aspect-ratio: 9 / 16;
  box-shadow: var(--shadow);
}
@media (min-width: 700px) { .mq-reel { width: 208px; } }
.mq-reel video, .mq-reel img { width: 100%; height: 100%; object-fit: cover; }
.mq-reel .cap {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 26px 11px 11px;
  background: linear-gradient(transparent, rgba(6,23,53,.9));
  color: #fff; font-size: .77rem; line-height: 1.35; font-weight: 600;
}
.mq-reel .cap span { display: block; font-weight: 400; opacity: .85; font-size: .72rem; margin-top: 2px; }
.mq-reel .play {
  position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none;
}
.mq-reel .play svg { width: 42px; height: 42px; fill: rgba(255,255,255,.9); filter: drop-shadow(0 2px 8px rgba(0,0,0,.5)); }
.mq-reel.playing .play { display: none; }

/* Manual swiping.
   The track is driven by a transform, and its parent is overflow:hidden, so the
   strip could only ever auto-scroll — on a phone there was no way to go back to a
   clip you had just passed. On touch devices the animation is dropped and the
   marquee becomes a real horizontal scroller you can flick left and right.
   (The old reduced-motion rule put overflow-x on .marquee-track, which is
   width:max-content and therefore never scrolls — the overflow has to sit on the
   .marquee parent that actually clips.) */
@media (hover: none) and (pointer: coarse) {
  .marquee {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    /* let the strip run to the screen edges but keep the first tile aligned */
    padding-inline: 16px;
    scroll-padding-inline: 16px;
  }
  .marquee::-webkit-scrollbar { display: none; }
  /* the edge fades sit over a scrolling strip and read as clipped content */
  .marquee::before, .marquee::after { display: none; }
  .marquee-track { animation: none !important; }
  .mq-reel, .mq-photo { scroll-snap-align: start; }
  /* The track holds the set twice so the animation can wrap seamlessly. Once you
     are scrolling by hand that just means swiping past every clip a second time,
     so the duplicate pass (already aria-hidden) is dropped. */
  .marquee-track > [aria-hidden="true"] { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .marquee {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .marquee::-webkit-scrollbar { display: none; }
  .marquee-track { animation: none !important; }
}

/* ---------------------------------------------------------------- order tracking */

.track-form { display: grid; gap: 14px; align-items: end; }
@media (min-width: 560px) { .track-form { grid-template-columns: 1fr auto; } }
.track-form input { font-size: 1.05rem; letter-spacing: .06em; text-transform: uppercase; }
.track-error {
  background: #FBEAE8; border: 1px solid #E9C4C0; color: var(--red);
  padding: 12px 16px; border-radius: var(--r); font-size: .9rem;
}
.lnk-btn { background: none; border: 0; padding: 0; color: var(--gold); font-weight: 600; text-decoration: underline; }

.track-head { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; margin-bottom: 26px; }
.track-head .eyebrow { font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; font-weight: 700; margin: 0 0 6px; }
.track-eta {
  margin-left: auto; background: var(--gold-soft); border: 1px solid #C9D5EA;
  border-radius: var(--r); padding: 12px 18px; text-align: right;
}
.track-eta span { display: block; font-size: .74rem; color: var(--ink-2); text-transform: uppercase; letter-spacing: .06em; }
.track-eta b { font-size: 1.05rem; font-family: var(--serif); }
@media (max-width: 559px) { .track-eta { margin-left: 0; width: 100%; text-align: left; } }

/* the stepper */
.track-steps { list-style: none; margin: 0 0 24px; padding: 0; position: relative; }
.track-step { position: relative; display: flex; gap: 16px; padding-bottom: 26px; }
.track-step:last-child { padding-bottom: 0; }

/* the connecting spine */
.track-step::before {
  content: ""; position: absolute; left: 17px; top: 34px; bottom: -2px;
  width: 2px; background: var(--line);
}
.track-step:last-child::before { display: none; }
.track-step.done::before { background: var(--green); }

.ts-dot {
  position: relative; flex: none; width: 36px; height: 36px; border-radius: 50%;
  background: var(--paper-2); border: 2px solid var(--line);
  display: grid; place-items: center; z-index: 1;
  transition: background .3s, border-color .3s;
}
.track-step.done .ts-dot { background: var(--green); border-color: var(--green); }
.track-step.done .ts-dot svg { width: 17px; height: 17px; stroke: #fff; fill: none; stroke-width: 3; }
.track-step.now .ts-dot { background: var(--gold); border-color: var(--gold); }

/* the live stage keeps a soft pulse so progress reads as ongoing */
.ts-pulse { width: 11px; height: 11px; border-radius: 50%; background: #fff; }
.track-step.now .ts-dot::after {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  border: 2px solid var(--gold); opacity: .55;
  animation: tsPing 1.9s cubic-bezier(0, 0, .2, 1) infinite;
}
@keyframes tsPing {
  0%   { transform: scale(.85); opacity: .6; }
  70%  { transform: scale(1.35); opacity: 0; }
  100% { transform: scale(1.35); opacity: 0; }
}

.ts-body { padding-top: 5px; min-width: 0; }
.ts-body b { display: block; font-size: .98rem; }
.ts-body span { font-size: .87rem; color: var(--muted); }
.track-step.now .ts-body b { color: var(--gold); }
.track-step:not(.done):not(.now) .ts-body b { color: var(--muted); font-weight: 600; }

/* steps fade in one after another on load */
.track-step { animation: tsIn .45s both; animation-delay: calc(var(--i) * .09s); }
@keyframes tsIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.track-courier { display: flex; gap: 13px; align-items: center; }
.track-courier svg { width: 26px; height: 26px; flex: none; stroke: var(--ink); fill: none; stroke-width: 1.6; }
.track-courier code {
  background: var(--paper-2); padding: 2px 8px; border-radius: 5px;
  font-size: .88rem; letter-spacing: .04em;
}
.track-personal { color: var(--gold) !important; display: flex; align-items: center; gap: 5px; }
.track-personal svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; flex: none; }

@media (prefers-reduced-motion: reduce) {
  .track-step { animation: none; }
  .track-step.now .ts-dot::after { animation: none; }
}

/* ---------------------------------------------------------------- in-chat forms */

.ship-form { display: grid; gap: 7px; margin-top: 10px; }
.ship-form b { font-size: .85rem; }
.ship-form input {
  width: 100%; padding: 9px 11px; border: 1px solid var(--line);
  border-radius: 8px; background: #fff; font-size: .85rem; color: var(--ink);
}
.sf-row { display: flex; gap: 7px; }
.sf-row > * { flex: 1; min-width: 0; }
.sf-send {
  margin-top: 4px; padding: 10px; border: 0; border-radius: 999px;
  background: var(--gold); color: #fff; font-weight: 600; font-size: .86rem;
}
.sf-msg { color: var(--red); font-size: .78rem; margin: 4px 0 0; }
.sf-done { font-size: .84rem; color: var(--green); font-weight: 600; margin: 8px 0 0; }
.bubble.k-ship_request { max-width: 100%; }
.bubble.k-order_card .msg-product { border-color: var(--gold); }
/* The instant reply says so in the text; this labels it at a glance too, so it
   never reads as Eray having answered and then gone quiet. */
.bubble.k-auto_greeting::before {
  content: 'Automatic reply';
  display: block; margin-bottom: 6px;
  font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
}

/* email -> code gate */
.verify-gate { padding: 15px; border-top: 1px solid var(--line); background: var(--card); }
.verify-gate input {
  width: 100%; padding: 11px 13px; border: 1px solid var(--line);
  border-radius: 8px; font-size: .9rem; background: var(--paper); margin-bottom: 8px;
}
.verify-gate .code { letter-spacing: .36em; text-align: center; font-size: 1.15rem; }
.verify-gate button {
  width: 100%; padding: 11px; border: 0; border-radius: 999px;
  background: var(--ink); color: #fff; font-weight: 600; font-size: .88rem;
}
.verify-gate p { font-size: .78rem; color: var(--muted); margin: 8px 0 0; }
.verify-gate .err { color: var(--red); }

/* reel lightbox */
.reel-modal {
  position: fixed; inset: 0; z-index: 160; background: rgba(6,23,53,.94);
  display: none; place-items: center; padding: 16px;
}
.reel-modal.on { display: grid; }
.rm-frame { position: relative; width: min(94vw, 420px); max-height: 92vh; display: flex; flex-direction: column; gap: 10px; }
.rm-frame video {
  width: 100%; max-height: 76vh; border-radius: var(--r); background: #000;
  object-fit: contain;
}
.rm-x {
  position: absolute; top: -6px; right: -6px; z-index: 2;
  width: 38px; height: 38px; border-radius: 50%; border: 0;
  background: #fff; color: var(--ink); font-size: 1.4rem; line-height: 1; box-shadow: var(--shadow-lg);
}
/* the full clip is only fetched on tap, so show that it is on its way */
.reel-modal.loading .rm-frame::after {
  content: ''; position: absolute; top: 50%; left: 50%; width: 34px; height: 34px;
  margin: -17px 0 0 -17px; border-radius: 50%; z-index: 3;
  border: 3px solid rgba(255,255,255,.28); border-top-color: #fff;
  animation: rmSpin .8s linear infinite;
}
@keyframes rmSpin { to { transform: rotate(360deg); } }

.rm-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; color: #fff; }
.rm-info b { display: block; font-size: .92rem; }
.rm-info span { font-size: .85rem; color: #C7D4EC; }
.rm-cta { margin-left: auto; background: #fff; color: var(--navy-deep); }
@media (max-width: 520px) { .rm-cta { margin-left: 0; width: 100%; } }

/* the reel tile is a button now */
button.mq-reel { border: 0; padding: 0; cursor: pointer; text-align: left; }

/* ---------------------------------------------------------------- Etsy-style product blocks */

.p-badge {
  display: inline-block; margin-bottom: 9px;
  background: var(--gold-soft); color: var(--gold);
  border: 1px solid #C9D5EA;
  font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 5px 12px; border-radius: 999px;
}

/* price with strike-through + savings */
.p-price .save-pct { color: var(--green); font-weight: 700; font-size: .84rem; }
.p-urgency { font-size: .84rem; color: var(--red); font-weight: 700; margin-bottom: 2px; }

/* rating summary */
.rating-block { border: 1px solid var(--line); border-radius: var(--r); padding: 18px; background: var(--card); }
.rating-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.rating-big { font-family: var(--serif); font-size: 2.6rem; line-height: 1; }
.rating-head .lbl { font-size: .84rem; color: var(--muted); }
.rating-dials { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-top: 18px; }
@media (min-width: 620px) { .rating-dials { grid-template-columns: repeat(4, 1fr); } }
.dial { display: flex; align-items: center; gap: 10px; font-size: .82rem; }
.dial svg { width: 46px; height: 46px; flex: none; }
.dial .ring-bg { fill: none; stroke: var(--paper-2); stroke-width: 3.4; }
.dial .ring-fg { fill: none; stroke: var(--star); stroke-width: 3.4; stroke-linecap: round; transform: rotate(-90deg); transform-origin: 50% 50%; }
.dial .num { font-size: .8rem; font-weight: 700; fill: var(--ink); }

.buyers-say { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 12px 0 4px; font-size: .85rem; }
.buyers-say b { width: 100%; font-size: .86rem; }
.buyers-say span { display: inline-flex; align-items: center; gap: 5px; color: var(--ink-2); }
.buyers-say svg { width: 14px; height: 14px; stroke: var(--green); fill: none; stroke-width: 2.4; }

/* Star Seller callout — the maker's face, with the Etsy star pinned beside him */
.star-seller-block {
  display: flex; gap: 14px; align-items: center;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 14px 17px;
}
.ss-avatar { position: relative; flex: none; }
.ss-avatar img { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; }
.ss-star {
  position: absolute; right: -5px; bottom: -3px;
  width: 21px; height: 21px; border-radius: 50%;
  background: #C64AC9; border: 2px solid var(--card);
  display: grid; place-items: center;
}
.ss-star svg { width: 11px; height: 11px; fill: #fff; }
.star-seller-block p { margin: 0; font-size: .87rem; color: var(--ink-2); line-height: 1.5; }
.star-seller-block b { color: var(--ink); }

/* Inbox — directly under the Star Seller line */
.inbox-btn {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 12px; width: 100%;
  margin: 10px 0 20px; padding: 11px 14px;
  border: 1px solid var(--gold); border-radius: var(--r);
  background: var(--gold-soft); color: var(--gold);
  text-align: left; transition: box-shadow .16s ease, background .16s ease;
}
.inbox-btn:hover { background: #DEE7F6; box-shadow: var(--shadow); }
.inbox-btn .ib-ico {
  position: relative; flex: none; width: 38px; height: 38px; border-radius: 50%;
  background: var(--gold); display: grid; place-items: center;
}
.inbox-btn .ib-ico svg { width: 19px; height: 19px; stroke: #fff; fill: none; stroke-width: 1.7; stroke-linejoin: round; }
.inbox-btn .ib-dot {
  position: absolute; top: -1px; right: -1px; width: 11px; height: 11px; border-radius: 50%;
  background: var(--red); border: 2px solid var(--gold-soft); display: none;
}
.inbox-btn.has-unread .ib-dot { display: block; }
.inbox-btn .ib-txt { min-width: 0; line-height: 1.3; }
.inbox-btn .ib-txt b { display: block; font-size: .92rem; font-weight: 700; }
.inbox-btn .ib-txt span { font-size: .77rem; color: var(--ink-2); }
.inbox-btn .ib-go { width: 17px; height: 17px; margin-left: auto; flex: none; stroke: var(--gold); fill: none; stroke-width: 2; }
.inbox-btn.shine::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 34%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.85), transparent);
  transform: translateX(-140%); animation: shine 3.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .inbox-btn.shine::after { animation: none; opacity: 0; } }

/* ---------------------------------------------------------------- option picker */

.picker { position: relative; }
.picker-btn {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--card); font-size: .95rem; text-align: left;
}
.picker-btn:hover { border-color: var(--gold-2); }
.picker.open .picker-btn { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.picker-btn .pk-text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.picker-btn .pk-dot {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  border: 1px solid rgba(0,0,0,.16); background-size: cover; background-position: center; background-color: #E4E9F2;
}
.pk-caret { width: 18px; height: 18px; flex: none; stroke: var(--muted); fill: none; stroke-width: 2; transition: transform .18s; }
.picker.open .pk-caret { transform: rotate(180deg); }

.picker-menu {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 40;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow-lg); padding: 6px; max-height: 300px; overflow-y: auto;
}
.picker-opt {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 10px 11px; border: 0; border-radius: var(--r-sm);
  background: none; font-size: .89rem; text-align: left;
}
.picker-opt:hover { background: var(--gold-soft); }
.picker-opt[aria-selected="true"] { background: var(--gold-soft); box-shadow: inset 0 0 0 1px var(--gold); }
.picker-opt .dot {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  border: 1px solid rgba(0,0,0,.16); background-size: cover; background-position: center;
}
.picker-opt .nm { flex: 1; min-width: 0; }
.picker-opt .price { color: var(--gold-2); font-weight: 700; font-size: .85rem; white-space: nowrap; }

/* invalid state — used when someone tries to buy without choosing */
.opt.invalid .picker-btn,
.opt.invalid select:not(.sr-only) { border-color: var(--red); box-shadow: inset 0 0 0 1px var(--red); }
.opt .err { display: none; color: var(--red); font-size: .8rem; margin-top: 6px; }
.opt.invalid .err { display: block; }
.opt.shake { animation: optShake .4s; }
@keyframes optShake {
  0%,100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

/* ---------------------------------------------------------------- personalisation (collapsed by default) */

.personalise-wrap { border: 0; padding: 0; }
.personalise-wrap > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 9px;
  font-weight: 600; font-size: .95rem; padding: 12px 2px;
}
.personalise-wrap > summary::-webkit-details-marker { display: none; }
.pw-opt { color: var(--muted); font-weight: 400; }
.pw-plus { position: relative; width: 15px; height: 15px; flex: none; }
.pw-plus::before, .pw-plus::after {
  content: ""; position: absolute; background: var(--ink); border-radius: 2px;
  transition: transform .2s;
}
.pw-plus::before { left: 0; right: 0; top: 6.5px; height: 2px; }
.pw-plus::after  { top: 0; bottom: 0; left: 6.5px; width: 2px; }
.personalise-wrap[open] .pw-plus::after { transform: scaleY(0); }
.personalise-wrap[open] > summary { color: var(--gold); }

/* ---------------------------------------------------------------- sticky buy bar (mobile) */

/* Pinned for good: opaque, GPU-promoted, and with no backdrop-filter. A blurred
   fixed bar has to re-sample the page on every scroll frame, which is exactly
   what made this bar lag behind the scroll and slide off the bottom on phones. */
.buy-sticky {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 72;
  background: var(--paper);
  border-top: 1px solid var(--line);
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  display: none; gap: 9px; align-items: center;
  transform: translate3d(0, 110%, 0); transition: transform .28s cubic-bezier(.2,.8,.3,1);
  box-shadow: 0 -6px 24px rgba(16,28,51,.12);
  will-change: transform; backface-visibility: hidden;
}
.buy-sticky.on { transform: translate3d(0, 0, 0); }
.buy-sticky .bs-price { flex: none; line-height: 1.15; }
.buy-sticky .bs-price b { display: block; font-size: .98rem; font-family: var(--serif); }
.buy-sticky .bs-price span { font-size: .66rem; color: var(--muted); }
.buy-sticky .btn { flex: 1; padding: 12px 8px; font-size: .86rem; white-space: nowrap; }
@media (max-width: 899px) { .buy-sticky { display: flex; } }
@media (max-width: 400px) {
  .buy-sticky { gap: 7px; padding-inline: 9px; }
  .buy-sticky .bs-price span { display: none; }
  .buy-sticky .btn { padding: 12px 6px; font-size: .82rem; }
}

/* Everything that floats bottom-right has to clear the buy bar, and the page
   itself needs the height back so the footer is not sitting under it. */
body.has-buy-bar .chat-fab { bottom: 84px; }
body.has-buy-bar { padding-bottom: calc(68px + env(safe-area-inset-bottom)); }
@media (max-width: 899px) {
  /* the launcher shrinks to just Eray's face so it stops covering the page */
  .chat-fab { padding: 6px; gap: 0; border-radius: 50%; }
  .chat-fab span:not(.dot) { display: none; }
  .chat-fab img { width: 42px; height: 42px; }
  .chat-fab .dot { top: 4px; right: 4px; }
}

/* delivery / policy facts */
.fact-list { display: grid; gap: 11px; margin: 18px 0; }
.fact { display: flex; gap: 11px; align-items: flex-start; font-size: .88rem; }
.fact svg { width: 19px; height: 19px; flex: none; stroke: var(--ink); fill: none; stroke-width: 1.7; margin-top: 1px; }
.fact b { border-bottom: 1px dashed var(--muted); }

/* seller card, matching Etsy's shop header */
.shop-card { border: 1px solid var(--line); border-radius: var(--r); padding: 20px; background: var(--card); }
.shop-head { display: flex; gap: 15px; align-items: center; flex-wrap: wrap; }
.shop-head .avatar { position: relative; flex: none; }
.shop-head .avatar img { width: 74px; height: 74px; border-radius: 50%; object-fit: cover; }
.shop-head .avatar .pip {
  position: absolute; right: -2px; bottom: -2px; width: 24px; height: 24px; border-radius: 50%;
  background: #C64AC9; display: grid; place-items: center; border: 2px solid var(--card);
}
.shop-head .avatar .pip svg { width: 13px; height: 13px; fill: #fff; }
.shop-name { font-family: var(--serif); font-size: 1.5rem; }
.shop-meta { font-size: .85rem; color: var(--ink-2); display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.shop-actions { margin-left: auto; display: flex; gap: 9px; flex-wrap: wrap; }
.shop-traits { display: grid; gap: 16px; margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line); }
@media (min-width: 700px) { .shop-traits { grid-template-columns: repeat(3, 1fr); } }
.shop-trait { display: flex; gap: 10px; font-size: .85rem; color: var(--ink-2); }
.shop-trait svg { width: 20px; height: 20px; flex: none; fill: var(--ink); }
.shop-trait b { color: var(--ink); }

/* material swatch picker — a grid, not a single tall column */
.swatches {
  display: grid; gap: 8px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 520px) and (max-width: 949px) { .swatches { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .swatches { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.swatch {
  display: flex; align-items: center; gap: 8px; text-align: left;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); font-size: .82rem; transition: .15s; min-width: 0;
}
.swatch:hover { border-color: var(--gold-2); }
.swatch.on { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); background: var(--gold-soft); }
.swatch .dot {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  border: 1px solid rgba(0,0,0,.16); background-size: cover; background-position: center;
}
.swatch .lbl { min-width: 0; line-height: 1.25; }
.swatch .nm { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.swatch .price { display: block; color: var(--gold-2); font-size: .78rem; font-weight: 700; }
.swatch.on .price { color: var(--gold); }

/* personalisation panel */
.personalise { border: 1px solid var(--line); border-radius: var(--r); padding: 16px; background: var(--card); }
.personalise .cnt { text-align: right; font-size: .76rem; color: var(--muted); margin-top: 4px; }
.dropzone {
  border: 2px dashed var(--line); border-radius: var(--r-sm); padding: 18px;
  display: flex; align-items: center; gap: 13px; cursor: pointer; transition: .15s;
}
.dropzone:hover, .dropzone.over { border-color: var(--gold); background: var(--gold-soft); }
.dropzone .plus { font-size: 1.7rem; line-height: 1; color: var(--ink-2); }
.dropzone b { display: block; font-size: .9rem; }
.dropzone span { font-size: .78rem; color: var(--muted); }
.dz-files { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 11px; }
.dz-files figure { position: relative; margin: 0; }
.dz-files img { width: 62px; height: 62px; object-fit: cover; border-radius: var(--r-sm); }
.dz-files button {
  position: absolute; top: -6px; right: -6px; width: 21px; height: 21px; border-radius: 50%;
  border: 0; background: var(--ink); color: #fff; font-size: .8rem; line-height: 1;
}

/* the "Message Eray" button, made to catch the eye */
.msg-seller.shine { position: relative; overflow: hidden; border-color: var(--gold); background: var(--gold-soft); }
.msg-seller.shine .t { color: var(--gold); }
.msg-seller.shine::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 44%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.85), transparent);
  transform: translateX(-140%); animation: shine 3.6s ease-in-out infinite;
}
@keyframes shine { 0%, 62% { transform: translateX(-140%); } 100% { transform: translateX(320%); } }
@media (prefers-reduced-motion: reduce) { .msg-seller.shine::after { animation: none; opacity: 0; } }

/* size / material chart */
.chart-btns { display: flex; gap: 9px; flex-wrap: wrap; margin: 16px 0 4px; }

.chart-modal {
  position: fixed; inset: 0; z-index: 150; background: rgba(6,23,53,.94);
  display: none; padding: 0;
}
.chart-modal.on { display: block; }

/* the controls float over the image, clear of the notch and the home bar */
.chart-modal .tools {
  position: fixed; top: max(12px, env(safe-area-inset-top)); right: 12px; z-index: 3;
  display: flex; gap: 8px;
}
.chart-modal .tools button {
  width: 42px; height: 42px; border-radius: 50%; border: 0;
  background: rgba(255,255,255,.94); color: var(--ink);
  font-size: 1.25rem; line-height: 1; box-shadow: 0 4px 14px rgba(0,0,0,.3);
  display: grid; place-items: center;
}
.chart-modal .frame {
  position: absolute; inset: 0;
  overflow: auto; -webkit-overflow-scrolling: touch;
  padding: 64px 12px calc(20px + env(safe-area-inset-bottom));
  display: grid; place-items: start center;
}
/* opens fitted to the screen; the + button zooms in from there */
.chart-modal img {
  max-width: 100%; width: auto; height: auto;
  border-radius: var(--r); background: #fff;
  transform-origin: top center; transition: transform .2s;
}

/* ---------------------------------------------------------------- gallery (Etsy layout)
   Thumbnail rail on the left, main image on the right, height capped so the
   page never grows taller than the viewport on a laptop. */

.gallery-col { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .gallery-col { grid-template-columns: 74px minmax(0, 1fr); } }
@media (min-width: 1200px) { .gallery-col { grid-template-columns: 84px minmax(0, 1fr); } }

.gallery-main {
  position: relative; order: 2;
  border-radius: var(--r); overflow: hidden; background: var(--paper-2);
  border: 1px solid var(--line);
  aspect-ratio: 1;
  max-height: min(68vh, 620px);
  display: grid; place-items: center;
}
.gallery-main img { width: 100%; height: 100%; object-fit: cover; }
.gallery-main img.contain { object-fit: contain; background: #fff; cursor: zoom-in; }
.gallery-main video { width: 100%; height: 100%; object-fit: cover; background: #000; }

.gallery-thumbs {
  order: 1;
  display: flex; flex-direction: row; gap: 8px;
  overflow-x: auto; overflow-y: hidden;
  padding-bottom: 4px; scrollbar-width: thin;
}
@media (min-width: 640px) {
  .gallery-thumbs {
    flex-direction: column; overflow-x: hidden; overflow-y: auto;
    max-height: min(68vh, 620px); padding-right: 4px; padding-bottom: 0;
  }
}
.gallery-thumbs button {
  flex: none; width: 62px; height: 62px; border-radius: var(--r-sm); overflow: hidden;
  border: 2px solid transparent; background: var(--paper-2); padding: 0; position: relative;
}
@media (min-width: 1200px) { .gallery-thumbs button { width: 72px; height: 72px; } }
.gallery-thumbs button.on { border-color: var(--gold); }
.gallery-thumbs img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumbs button.is-chart { border-color: var(--gold-2); }
.gallery-thumbs button.is-chart img { object-fit: contain; background: #fff; }

/* video thumb marker */
.gallery-thumbs button.is-video::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(6,23,53,.32) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E") center/22px no-repeat;
}

.gallery-zoom {
  position: absolute; bottom: 10px; right: 10px; z-index: 3;
  width: 34px; height: 34px; border-radius: 50%; border: 0;
  background: rgba(255,255,255,.92); display: grid; place-items: center; box-shadow: var(--shadow);
}
.gallery-zoom svg { width: 16px; height: 16px; stroke: var(--ink); fill: none; stroke-width: 2; }
.gallery-progress {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(0,0,0,.08); z-index: 2;
}
.gallery-progress span { display: block; height: 100%; width: 0; background: var(--gold); }
.gallery-pause {
  position: absolute; top: 10px; right: 10px; z-index: 3;
  width: 34px; height: 34px; border-radius: 50%; border: 0;
  background: rgba(255,255,255,.9); display: grid; place-items: center; box-shadow: var(--shadow);
}
.gallery-pause svg { width: 15px; height: 15px; fill: var(--ink); }

/* ---------------------------------------------------------------- fast-reply badge
   Instagram marks an active account with a lightning bolt; the same signal reads
   instantly here. Purple keeps it a status marker, separate from the navy/gold. */
.fast-reply {
  display: inline-flex; align-items: center; gap: 4px;
  color: #8B3FD9; font-weight: 600; white-space: nowrap;
}
.fast-reply .bolt {
  fill: #8B3FD9; stroke: none; flex: none;
  filter: drop-shadow(0 0 3px rgba(139, 63, 217, .35));
  animation: boltPulse 2.6s ease-in-out infinite;
}
@keyframes boltPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .72; transform: scale(1.12); }
}
@media (prefers-reduced-motion: reduce) {
  .fast-reply .bolt { animation: none; }
}
/* on the dark chat header the same purple needs lifting to stay legible */
.chat-head .fast-reply { color: #A45CF0; }
.chat-head .fast-reply .bolt { fill: #A45CF0; }

/* ---------------------------------------------------------------- reel browser
   The lightbox is a reel browser: neighbours peek in at both edges so it is
   obvious there is more to move to, and the frame slides as you go. */
.reel-modal { grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 4px; }
.reel-modal.on { display: grid; }

.rm-stage {
  position: relative; display: flex; align-items: center; justify-content: center;
  gap: 10px; min-width: 0; overflow: hidden;
}

.rm-peek {
  flex: none; width: clamp(34px, 7vw, 92px); height: min(62vh, 420px);
  border: 0; padding: 0; border-radius: var(--r);
  background-color: #0b1c3a; background-size: cover; background-position: center;
  opacity: .38; filter: blur(1px);
  transition: opacity .25s, transform .25s;
  cursor: pointer;
}
.rm-peek:hover { opacity: .72; transform: scale(1.03); filter: none; }
.reel-modal.solo .rm-peek, .reel-modal.solo .rm-nav, .reel-modal.solo .rm-dots { display: none; }

.rm-frame { transition: transform .28s cubic-bezier(.2,.8,.3,1), opacity .28s; touch-action: pan-y; }
.rm-frame.dragging { transition: none; cursor: grabbing; }
.rm-frame video { user-select: none; }

@keyframes rmInR { from { transform: translateX(46px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes rmInL { from { transform: translateX(-46px); opacity: 0; } to { transform: none; opacity: 1; } }
.rm-frame.slide-r { animation: rmInR .3s cubic-bezier(.2,.8,.3,1); }
.rm-frame.slide-l { animation: rmInL .3s cubic-bezier(.2,.8,.3,1); }

.rm-nav {
  flex: none; width: 46px; height: 46px; border-radius: 50%; border: 0;
  background: rgba(255,255,255,.14); backdrop-filter: blur(6px);
  display: grid; place-items: center; cursor: pointer;
  transition: background .2s, transform .2s;
}
.rm-nav:hover { background: rgba(255,255,255,.28); transform: scale(1.06); }
.rm-nav svg { width: 24px; height: 24px; fill: none; stroke: #fff; stroke-width: 2.2; stroke-linecap: round; }

.rm-dots {
  grid-column: 1 / -1; display: flex; gap: 7px; justify-content: center;
  padding-top: 4px; flex-wrap: wrap;
}
.rm-dots button {
  width: 26px; height: 4px; border: 0; padding: 0; border-radius: 99px;
  background: rgba(255,255,255,.3); cursor: pointer; transition: background .2s;
}
.rm-dots button.on { background: #fff; }

@media (max-width: 700px) {
  /* arrows would crowd a phone; the peeks and the swipe carry it there */
  .reel-modal { grid-template-columns: 1fr; }
  .rm-nav { display: none; }
  .rm-peek { width: 26px; height: min(52vh, 340px); }
  .rm-stage { gap: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .rm-frame.slide-r, .rm-frame.slide-l { animation: none; }
}

/* Load sentinel — see main.css. Keep last. */
:root { --swan-comp-ok: 1; }
