/* ═══════════════════════════════════════════
   Bubbly Balloons — Misa & Line
   ═══════════════════════════════════════════ */

:root{
  --grape:#3E0F4E;
  --purple:#8B2FA8;
  --purple-d:#6B1E86;
  --orchid:#C06BDD; --orchid-ink:#A63FC4;
  --lilac:#EBD3F5;
  --pink:#FF5FA2;
  --sun:#FFC53D;
  --sky:#45C4F0;
  --mint:#3FD3A8;

  --ink:#2B1233;
  --ink-2:#61506B;
  --cream:#FFF8FC;
  --paper:#fff;
  --line:#F0E1F6;

  --r-sm:12px; --r:20px; --r-lg:30px; --r-xl:44px;
  --shadow:0 18px 44px -18px rgba(62,15,78,.28);
  --shadow-lg:0 34px 70px -24px rgba(62,15,78,.36);

  --font-d:'Fredoka',system-ui,sans-serif;
  --font-b:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;
  --nav-h:74px;
}

*,*::before,*::after{box-sizing:border-box}
html{
  scroll-behavior:smooth;scroll-padding-top:calc(var(--nav-h) + 14px);
  /* Android browsers "font boost" text on zoom, which reflows paragraphs and
     makes the layout appear to rebuild mid-pinch. Pin it, unprefixed too —
     Opera/Chrome on Android honour the standard property now. */
  -webkit-text-size-adjust:100%;
  text-size-adjust:100%;
}
body{
  margin:0;background:var(--cream);color:var(--ink);
  font:400 17px/1.65 var(--font-b);
  overflow-x:hidden;-webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block;height:auto}
a{color:var(--purple);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{font-family:var(--font-d);font-weight:600;line-height:1.1;margin:0;letter-spacing:-.01em}
p{margin:0 0 1em}
:focus-visible{outline:3px solid var(--pink);outline-offset:3px;border-radius:6px}

/* ── touch behaviour ───────────────────────────────────────────────
   Every tappable thing defaults to touch-action:auto, which leaves
   double-tap-to-zoom armed — so two quick taps on a filter chip or a
   gallery tile zoom the page instead of registering as taps. That is
   the "weird zooming" on mobile.

   `manipulation` disables double-tap zoom and the 300ms tap delay while
   LEAVING pinch-zoom intact. We deliberately don't use
   user-scalable=no: iOS Safari ignores it, and it would block low-vision
   users from zooming at all. */
a, button, summary, label,
input, select, textarea,
.tile, .chip, .btn, .drop{
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* The one place deliberate zoom SHOULD work: an opened gallery photo.
   Restoring `auto` here re-arms pinch and double-tap on the lightbox so
   people can inspect a balloon setup close up. */
.lb, .lb img, .lb__cap{ touch-action: auto; }

.skip{position:absolute;left:-999px;top:0;background:var(--purple);color:#fff;padding:12px 18px;z-index:200;border-radius:0 0 10px 0}
.skip:focus{left:0}

.wrap{width:min(1200px,calc(100% - 44px));margin-inline:auto}
.wrap--narrow{width:min(820px,calc(100% - 44px))}

/* ── buttons ───────────────────────────── */
.btn{
  --bg:var(--purple);
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  background:var(--bg);color:#fff;font-family:var(--font-d);font-weight:600;font-size:1.05rem;
  padding:15px 30px;border:0;border-radius:999px;cursor:pointer;
  text-decoration:none;white-space:nowrap;
  box-shadow:0 10px 0 -4px rgba(62,15,78,.22), var(--shadow);
  transition:transform .18s cubic-bezier(.34,1.7,.5,1), box-shadow .18s, background .18s;
}
.btn:hover{transform:translateY(-3px);text-decoration:none;box-shadow:0 14px 0 -4px rgba(62,15,78,.22), var(--shadow-lg)}
.btn:active{transform:translateY(1px)}
.btn--sm{padding:11px 22px;font-size:.95rem;box-shadow:0 7px 0 -3px rgba(62,15,78,.2)}
.btn--pop{background:linear-gradient(135deg,var(--pink),var(--purple) 70%)}
.btn--ghost{background:transparent;color:var(--purple);box-shadow:inset 0 0 0 2px var(--orchid)}
.btn--ghost:hover{background:#fff;box-shadow:inset 0 0 0 2px var(--purple), var(--shadow)}
.btn--full{width:100%}

/* ── nav ───────────────────────────────── */
/* STICKY, not fixed. A fixed header is sized against the LAYOUT viewport, so
   pinch-zooming to 3x renders the bar 3x larger than the visible area — it
   swallows a third of the screen. Browsers also defer repositioning fixed
   elements until the gesture ends, which is why it snapped into place on
   release rather than tracking the pinch. Sticky sits in the normal flow and
   scales with the content, so zooming behaves like the rest of the page. */
.nav{
  position:sticky;top:0;z-index:100;height:var(--nav-h);
  /* Safari needs the prefix — without it desktop Safari shows a flat
     translucent panel instead of the blur */
  background:rgba(255,248,252,.82);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border-bottom:1px solid transparent;transition:border-color .3s, box-shadow .3s;
}
.nav.is-stuck{border-bottom-color:var(--line);box-shadow:0 6px 26px -18px rgba(62,15,78,.5)}
.nav__in{height:100%;display:flex;align-items:center;gap:26px}
.brand{display:flex;align-items:center;gap:11px;color:var(--grape);text-decoration:none;flex-shrink:0}
/* size by HEIGHT, width auto — the mark is a 1.51:1 wordmark, so a fixed
   square box would letterbox it and shrink the artwork by ~40% */
.brand img{height:40px;width:auto;object-fit:contain;display:block}
.brand__txt{display:flex;flex-direction:column;font-family:var(--font-d);font-weight:600;font-size:1.05rem;line-height:1.05}
.brand__txt em{font-style:normal;font-size:.68rem;font-weight:400;color:var(--orchid-ink);letter-spacing:.14em;text-transform:uppercase}
.nav__links{display:flex;gap:6px;margin-left:auto}
.nav__links a{
  color:var(--ink-2);font-weight:600;font-size:.95rem;padding:9px 14px;border-radius:999px;
  text-decoration:none;transition:color .2s,background .2s;
}
.nav__links a:hover{color:var(--purple);background:var(--lilac)}
.burger{display:none;background:none;border:0;padding:10px;cursor:pointer;flex-direction:column;gap:5px}
.burger span{display:block;width:24px;height:2.5px;background:var(--grape);border-radius:2px;transition:.25s}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7.5px) rotate(-45deg)}

/* ── hero ──────────────────────────────── */
/* the sticky header now occupies real space, so no --nav-h compensation here */
.hero{position:relative;padding:60px 0 90px;overflow:hidden}
.blobs{position:absolute;inset:0;pointer-events:none}
.blob{position:absolute;border-radius:50%;filter:blur(80px);opacity:.5}
.b1{width:520px;height:520px;background:var(--lilac);top:-120px;left:-140px}
.b2{width:460px;height:460px;background:#FFE3F0;top:180px;right:-120px}
.b3{width:380px;height:380px;background:#DFF6FF;bottom:-160px;left:38%}

.floaters{position:absolute;inset:0;pointer-events:none;overflow:hidden}
.fl{position:absolute;width:44px;opacity:.5;will-change:transform}
/* three drift paths so ten balloons never move as one block */
.f1{color:var(--pink);  left:6%;  top:22%;            animation:driftA 13s ease-in-out infinite;      animation-delay:0s}
.f2{color:var(--sun);   left:20%; top:66%; width:32px;animation:driftB 16s ease-in-out infinite;      animation-delay:-3s}
.f3{color:var(--sky);   right:9%; top:16%; width:38px;animation:driftC 11s ease-in-out infinite;      animation-delay:-6s}
.f4{color:var(--orchid);right:24%;bottom:8%;width:50px;animation:driftA 18s ease-in-out infinite;     animation-delay:-9s}
.f5{color:var(--mint);  left:47%; top:6%;  width:28px;animation:driftB 12s ease-in-out infinite;      animation-delay:-12s}
.f6{color:var(--sun);   left:34%; bottom:14%;width:36px;animation:driftC 15s ease-in-out infinite;    animation-delay:-2s}
.f7{color:var(--pink);  right:38%;top:4%;  width:26px;animation:driftA 14s ease-in-out infinite;      animation-delay:-7s}
.f8{color:var(--sky);   left:2%;  bottom:26%;width:34px;animation:driftB 17s ease-in-out infinite;    animation-delay:-4s}
.f9{color:var(--orchid);right:3%; bottom:38%;width:30px;animation:driftC 13s ease-in-out infinite;    animation-delay:-10s}
.f10{color:var(--mint); left:62%; bottom:4%;width:40px;animation:driftA 16s ease-in-out infinite;     animation-delay:-5s}
/* wider travel than before — vertical bob plus a real sideways sway */
@keyframes driftA{
  0%,100%{transform:translate(0,0) rotate(-5deg)}
  33%    {transform:translate(14px,-46px) rotate(6deg)}
  66%    {transform:translate(-10px,-24px) rotate(-3deg)}
}
@keyframes driftB{
  0%,100%{transform:translate(0,0) rotate(4deg)}
  40%    {transform:translate(-18px,-38px) rotate(-7deg)}
  75%    {transform:translate(9px,-58px) rotate(3deg)}
}
@keyframes driftC{
  0%,100%{transform:translate(0,0) rotate(-3deg)}
  50%    {transform:translate(20px,-52px) rotate(8deg)}
}

.hero__in{position:relative;display:grid;grid-template-columns:1.05fr .95fr;gap:60px;align-items:center}

.eyebrow{
  display:inline-flex;align-items:center;gap:9px;margin:0 0 20px;
  background:#fff;border:1px solid var(--line);border-radius:999px;
  padding:8px 17px;font-size:.83rem;font-weight:700;color:var(--purple-d);
  letter-spacing:.02em;box-shadow:var(--shadow);
}
.dot{width:8px;height:8px;border-radius:50%;background:var(--mint);box-shadow:0 0 0 4px rgba(63,211,168,.22)}

.hero h1{font-size:clamp(2.15rem,5.4vw,4.25rem);font-weight:600;letter-spacing:-.025em;margin-bottom:22px}
.wow{
  position:relative;color:var(--pink);white-space:nowrap;
  background:
    linear-gradient(var(--sun),var(--sun)) 0 .92em/100% .13em no-repeat,
    linear-gradient(100deg,var(--pink),var(--purple));
  -webkit-background-clip:padding-box,text;background-clip:padding-box,text;
  -webkit-text-fill-color:transparent;
  border-radius:4px;
}
.lede{font-size:1.14rem;color:var(--ink-2);max-width:52ch;margin-bottom:30px}
.hero__cta{display:flex;flex-wrap:wrap;gap:14px;margin-bottom:44px}

.trust{list-style:none;display:flex;gap:34px;padding:0;margin:0;flex-wrap:wrap}
.trust li{display:flex;flex-direction:column}
.trust strong{font-family:var(--font-d);font-size:1.75rem;color:var(--purple);line-height:1}
.trust span{font-size:.85rem;color:var(--ink-2);max-width:15ch;margin-top:5px}

/* hero collage */
.hero__art{position:relative;aspect-ratio:1/1.02}
.ph{margin:0;position:absolute;border-radius:var(--r-lg);overflow:hidden;border:6px solid #fff;box-shadow:var(--shadow-lg)}
.ph img{width:100%;height:100%;object-fit:cover}
.ph--a{width:66%;top:0;right:0;aspect-ratio:1;transform:rotate(2.5deg);z-index:2}
.ph--b{width:50%;bottom:0;left:0;aspect-ratio:1.15;transform:rotate(-4deg);z-index:3}
.ph--c{width:41%;bottom:9%;right:3%;aspect-ratio:1.2;transform:rotate(6deg);z-index:1}
.sticker{
  position:absolute;top:6%;left:-2%;z-index:4;
  background:var(--sun);color:var(--grape);font-family:var(--font-d);font-weight:600;
  padding:11px 19px;border-radius:999px;font-size:.95rem;
  box-shadow:var(--shadow);transform:rotate(-8deg);
  animation:wiggle 4s ease-in-out infinite;
}
@keyframes wiggle{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(-3deg) scale(1.04)}}

/* ── marquee ───────────────────────────── */
.marquee{background:var(--grape);color:#fff;padding:15px 0;overflow:hidden;position:relative}
.marquee__track{
  display:flex;width:max-content;will-change:transform;
  animation:slide var(--dur,40s) linear infinite;
}
/* each copy is identical width — items + inner gaps + one trailing gap —
   so translating by exactly --setw lands the next copy in the same place */
.marquee__set{display:flex;align-items:center;gap:26px;padding-right:26px;flex:none}
@media (hover:hover){.marquee:hover .marquee__track{animation-play-state:paused}}
.marquee span{font-family:var(--font-d);font-weight:500;font-size:1.05rem;white-space:nowrap;opacity:.94}
.marquee i{font-style:normal;opacity:.8}
@keyframes slide{
  from{transform:translateX(0)}
  to{transform:translateX(calc(-1 * var(--setw,50%)))}
}

/* ── sections ──────────────────────────── */
.sec{padding:100px 0}
.sec--tint{background:linear-gradient(180deg,#fff 0%,#FDF3FA 100%)}
.sec__head{max-width:660px;margin:0 auto 54px;text-align:center}
.kicker{
  font-family:var(--font-d);font-weight:600;text-transform:uppercase;
  letter-spacing:.18em;font-size:.78rem;color:var(--orchid-ink);margin:0 0 12px;
}
.sec h2{font-size:clamp(2rem,3.6vw,2.9rem);margin-bottom:16px}
.hl{color:var(--pink)}
.sub{color:var(--ink-2);font-size:1.06rem;margin:0}

/* ── service cards ─────────────────────── */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(295px,1fr));gap:24px}
.card{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:34px 30px 30px;transition:transform .25s cubic-bezier(.34,1.5,.5,1),box-shadow .25s,border-color .25s;
}
.card:hover{transform:translateY(-7px);box-shadow:var(--shadow-lg);border-color:transparent}
.card__ico{
  width:58px;height:58px;display:grid;place-items:center;font-size:1.65rem;
  border-radius:18px;margin-bottom:20px;
  background:color-mix(in srgb, var(--c) 18%, #fff);
  box-shadow:0 8px 20px -8px var(--c);
}
.card h3{font-size:1.28rem;margin-bottom:10px}
.card p{color:var(--ink-2);font-size:.97rem;margin:0}

/* ── gallery ───────────────────────────── */
.filters{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-bottom:34px}
.chip{
  font-family:var(--font-b);font-weight:600;font-size:.92rem;cursor:pointer;
  padding:10px 20px;border-radius:999px;border:1.5px solid var(--line);
  background:#fff;color:var(--ink-2);transition:.2s;
}
.chip:hover{border-color:var(--orchid);color:var(--purple)}
.chip.is-on{background:var(--purple);border-color:var(--purple);color:#fff}

.grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));
  grid-auto-rows:250px;gap:18px;
}
.tile{
  margin:0;position:relative;overflow:hidden;border-radius:var(--r);
  cursor:zoom-in;background:var(--lilac);box-shadow:var(--shadow);
  transition:transform .3s cubic-bezier(.34,1.5,.5,1), box-shadow .3s, opacity .3s;
}
.tile.tall{grid-row:span 2}
.tile img{width:100%;height:100%;object-fit:cover;transition:transform .55s ease}
.tile:hover{transform:translateY(-5px)}
.tile:hover img{transform:scale(1.07)}
.tile figcaption{
  position:absolute;inset:auto 0 0;padding:36px 18px 16px;color:#fff;
  background:linear-gradient(rgba(43,18,51,0) 0%,rgba(43,18,51,.62) 26%,rgba(43,18,51,.94) 100%);
  display:flex;flex-direction:column;gap:2px;
  transform:translateY(8px);opacity:0;transition:.3s;
}
.tile:hover figcaption,.tile:focus-within figcaption{transform:none;opacity:1}
.tile figcaption b{font-family:var(--font-d);font-size:1.02rem;font-weight:600}
.tile figcaption span{font-size:.8rem;opacity:.85}
.tile.is-hidden{display:none}

/* ── about ─────────────────────────────── */
.about{display:grid;grid-template-columns:.95fr 1.05fr;gap:64px;align-items:center}
.about__art{position:relative;padding-bottom:44px}
.about__photo{width:100%;border-radius:var(--r-xl);border:8px solid #fff;box-shadow:var(--shadow-lg);transform:rotate(-2deg)}
.about__badge{
  position:absolute;right:-14px;bottom:0;width:44%;
  border-radius:var(--r);border:6px solid #fff;box-shadow:var(--shadow-lg);transform:rotate(5deg);
}
.about h2{font-size:clamp(2rem,3.6vw,2.9rem);margin-bottom:18px}
.about p{color:var(--ink-2)}
.ticks{list-style:none;padding:0;margin:26px 0 30px;display:grid;gap:12px}
.ticks li{position:relative;padding-left:34px;color:var(--ink);font-size:.99rem}
.ticks li::before{
  content:'✓';position:absolute;left:0;top:1px;width:22px;height:22px;
  display:grid;place-items:center;border-radius:50%;
  background:var(--mint);color:#fff;font-size:.72rem;font-weight:800;
}

/* ── review strip ──────────────────────── */
.strip{background:var(--grape);color:#fff;padding:74px 0;text-align:center;position:relative;overflow:hidden}
.strip::before,.strip::after{
  content:'';position:absolute;border-radius:50%;filter:blur(70px);opacity:.34;
}
.strip::before{width:340px;height:340px;background:var(--pink);left:-90px;top:-110px}
.strip::after{width:340px;height:340px;background:var(--orchid);right:-90px;bottom:-130px}
.strip__in{position:relative}
.stars{color:var(--sun);font-size:1.5rem;letter-spacing:.18em;margin-bottom:14px}
.strip__quote{font-family:var(--font-d);font-size:clamp(1.9rem,4vw,3rem);font-weight:500;margin:0 0 12px}
.strip__meta{margin:0;opacity:.8;font-size:.95rem}
.strip__meta a{color:var(--sun)}

/* ── process ───────────────────────────── */
.steps{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:26px;counter-reset:s}
.step{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:36px 30px 30px;position:relative}
.step__n{
  position:absolute;top:-22px;left:30px;width:48px;height:48px;
  display:grid;place-items:center;border-radius:50%;
  background:linear-gradient(135deg,var(--pink),var(--purple));color:#fff;
  font-family:var(--font-d);font-size:1.35rem;font-weight:600;
  box-shadow:0 10px 22px -8px var(--purple);
}
.step h3{margin:16px 0 10px;font-size:1.25rem}
.step p{color:var(--ink-2);font-size:.97rem;margin:0}

/* ── quote / form ──────────────────────── */
.quote{display:grid;grid-template-columns:1fr 1.05fr;gap:60px;align-items:start}
.quote .kicker,.quote h2{text-align:left}
.quote h2{font-size:clamp(2rem,3.6vw,2.9rem);margin-bottom:16px}
.contacts{list-style:none;padding:0;margin:34px 0 0;display:grid;gap:20px}
.contacts li{display:flex;gap:15px;align-items:flex-start}
.ci{
  flex:0 0 44px;height:44px;display:grid;place-items:center;font-size:1.15rem;
  background:#fff;border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);
}
.contacts b{display:block;font-family:var(--font-d);font-size:.82rem;text-transform:uppercase;letter-spacing:.1em;color:var(--orchid-ink)}
.contacts div>span,.contacts div>a{color:var(--ink);font-size:1rem}

.form{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-xl);
  padding:36px;box-shadow:var(--shadow-lg);display:grid;gap:18px;
}
.form .row{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.form label{display:grid;gap:7px;font-weight:600;font-size:.87rem;color:var(--ink-2)}
.form input,.form select,.form textarea{
  font:400 1rem/1.5 var(--font-b);color:var(--ink);
  padding:13px 15px;border:1.5px solid var(--line);border-radius:14px;
  background:var(--cream);width:100%;transition:border-color .2s,background .2s;
}
.form input:focus,.form select:focus,.form textarea:focus{border-color:var(--orchid);background:#fff;outline:none}
.form textarea{resize:vertical;min-height:110px}
.addons{border:0;padding:0;margin:0;display:grid;gap:9px}
.addons legend{font-weight:600;font-size:.87rem;color:var(--ink-2);padding:0 0 8px}
.addons{grid-template-columns:1fr 1fr}
.addons legend{grid-column:1/-1}
.tickbox{display:flex!important;flex-direction:row;align-items:center;gap:9px;font-weight:500;color:var(--ink);cursor:pointer}
.tickbox input{width:19px;height:19px;accent-color:var(--purple);flex:0 0 19px;padding:0}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form__note{margin:0;font-size:.83rem;color:var(--ink-2);text-align:center}
/* stop long addresses and scaled-up text clipping at 200% zoom */
.contacts a,.contacts div>span,.foot a,.form__note{overflow-wrap:anywhere}
.btn{white-space:normal}
.form__note.is-ok{color:var(--mint);font-weight:700}
.form__note.is-err{color:var(--pink);font-weight:700}

/* ── faq ───────────────────────────────── */
.faq{display:grid;gap:12px}
.faq details{
  background:#fff;border:1px solid var(--line);border-radius:var(--r);
  padding:4px 26px;transition:box-shadow .25s,border-color .25s;
}
.faq details[open]{box-shadow:var(--shadow);border-color:var(--orchid)}
.faq summary{
  list-style:none;cursor:pointer;padding:20px 34px 20px 0;position:relative;
  font-family:var(--font-d);font-weight:500;font-size:1.1rem;color:var(--grape);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:'+';position:absolute;right:0;top:50%;transform:translateY(-50%);
  font-size:1.5rem;color:var(--orchid);transition:transform .25s;
}
.faq details[open] summary::after{transform:translateY(-50%) rotate(45deg)}
.faq p{color:var(--ink-2);font-size:.99rem;padding-bottom:20px;margin:0}

/* ── footer ────────────────────────────── */
.foot{background:var(--grape);color:#EFDFF6;padding:70px 0 26px}
.foot__in{display:grid;grid-template-columns:1.5fr 1fr 1fr;gap:44px;padding-bottom:44px}
.foot h4{font-size:.82rem;text-transform:uppercase;letter-spacing:.15em;color:var(--orchid);margin-bottom:16px;font-family:var(--font-b);font-weight:700}
.foot__brand img{background:#fff;border-radius:16px;padding:8px;margin-bottom:16px}
.foot__brand p{color:#C9AED6;font-size:.95rem;max-width:38ch;margin:0}
.foot__nav,.foot__contact{display:flex;flex-direction:column;gap:9px;align-items:flex-start}
.foot a{color:#EFDFF6;font-size:.95rem}
.foot a:hover{color:#fff}
.foot__contact span{color:#C9AED6;font-size:.95rem}
.social{display:flex;gap:16px;margin-top:8px}
.social a{
  font-size:.85rem;font-weight:700;padding:8px 16px;border-radius:999px;
  background:rgba(255,255,255,.09);transition:background .2s;
}
.social a:hover{background:rgba(255,255,255,.19);text-decoration:none}
.foot__bar{
  border-top:1px solid rgba(255,255,255,.12);padding-top:24px;
  display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  font-size:.85rem;color:#B69AC4;
}

/* ── lightbox ──────────────────────────── */
/* iOS Safari resolves `vh` against the LARGE viewport — the height the page
   would have if the toolbars were hidden. With the address bar and tab bar
   actually on screen, 82vh + padding pushes the photo and its caption under
   the bottom toolbar. `dvh` tracks the real visible height; the vh line stays
   first as the fallback for anything older than iOS 15.4. */
.lb{
  position:fixed;inset:0;z-index:300;background:rgba(30,8,38,.94);
  display:grid;place-items:center;
  padding:5vh 6vw;
  padding:5dvh 6vw;
  animation:fade .22s ease;
}
.lb[hidden]{display:none}
@keyframes fade{from{opacity:0}to{opacity:1}}
.lb img{
  max-width:100%;
  max-height:82vh;
  max-height:78dvh;
  border-radius:var(--r);box-shadow:0 40px 90px rgba(0,0,0,.6);
}
.lb__cap{
  position:absolute;left:0;right:0;text-align:center;color:#fff;
  font-size:.95rem;margin:0;opacity:.9;
  bottom:3.4vh;
  bottom:max(3.4dvh, env(safe-area-inset-bottom, 0px) + 12px);
}
.lb__x{position:absolute;top:18px;right:22px;background:none;border:0;color:#fff;font-size:2.6rem;line-height:1;cursor:pointer;opacity:.75}
.lb__x:hover{opacity:1}
.lb__nav{
  position:absolute;top:50%;transform:translateY(-50%);
  background:rgba(255,255,255,.13);border:0;color:#fff;font-size:2.2rem;line-height:1;
  width:52px;height:52px;border-radius:50%;cursor:pointer;transition:background .2s;
}
.lb__nav:hover{background:rgba(255,255,255,.28)}
.lb__prev{left:14px}.lb__next{right:14px}

/* ── confetti ──────────────────────────── */
.confetti{position:fixed;pointer-events:none;z-index:400;width:9px;height:14px;border-radius:2px;will-change:transform,opacity}

/* ── reveal ────────────────────────────── */
/* only hide when JS is running (script.js adds html.js) — otherwise a failed
   script would leave 27 blocks permanently invisible */
html.js .reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.3,1)}
html.js .reveal.in{opacity:1;transform:none}

/* ── responsive ────────────────────────── */
@media (max-width:1000px){
  .hero__in{grid-template-columns:1fr;gap:52px}
  .hero__art{max-width:520px;margin-inline:auto;width:100%}
  .about{grid-template-columns:1fr;gap:48px}
  /* the badge hangs 14px past its container for the collage look; on a
     narrow screen that pushes the document 5px wider than the viewport
     (confirmed in WebKit on iPhone), so tuck it back inside */
  .about__badge{right:0}
  .about__art{max-width:460px}
  .quote{grid-template-columns:1fr;gap:44px}
  .foot__in{grid-template-columns:1fr 1fr;gap:36px}
}
@media (max-width:820px){
  /* ── the header is IN-FLOW on mobile ──────────────────────────────
     Not fixed, not sticky. Both of those are positioned against the
     viewport, so a pinch-zoom re-anchors them and the bar changes size
     relative to the rest of the page. `relative` keeps it in the normal
     document flow, so it magnifies exactly like a paragraph does —
     nothing re-anchors, nothing reflows.

     (relative rather than static purely so the dropdown below still has
     a positioned ancestor to anchor to.)

     backdrop-filter is dropped here too: it recomputes its blur region
     during the pinch, which is a separate source of jank on iOS. */
  .nav{
    position:relative;
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
    background:var(--cream);
  }
  .nav.is-stuck{box-shadow:none}
  html{scroll-padding-top:14px}

  /* absolute against the header above */
  .nav__links{
    position:absolute;top:100%;left:0;right:0;flex-direction:column;gap:0;
    background:var(--cream);border-bottom:1px solid var(--line);
    padding:14px 22px 26px;box-shadow:var(--shadow);
    /* When this was position:fixed, translateY(-130%) parked it off-screen.
       Absolute inside the (unclipped) header it would paint OVER the bar,
       so the closed state uses display:none — unlike a transform or a
       visibility/opacity pair, it cannot paint and has no transition edge
       cases when opening from a hidden state. */
    display:none;
  }
  .nav__links.is-open{
    display:flex;
    animation:menuDrop .24s cubic-bezier(.2,.8,.3,1) both;
  }
  @keyframes menuDrop{
    from{opacity:0;transform:translateY(-10px)}
    to  {opacity:1;transform:none}
  }
  .nav__links a{padding:14px 10px;font-size:1.05rem;border-radius:12px}
  .nav .btn--sm{margin-left:auto}
  .burger{display:flex;margin-right:-10px}
}
@media (max-width:560px){
  :root{--nav-h:68px}
  .nav__in{gap:10px}
  .brand img{height:42px}
  .brand__txt{font-size:.95rem}
  .brand__txt em{font-size:.6rem;letter-spacing:.1em}
  .nav .btn--sm{padding:9px 15px;font-size:.85rem;box-shadow:0 5px 0 -3px rgba(62,15,78,.2)}
}
@media (max-width:400px){
  /* The mark already contains "Bubbly Balloons · Misa & Line", so the text
     beside it is redundant here. Drop it and let the logo grow into the
     space instead of shrinking — it now carries the brand on its own. */
  .brand__txt{display:none}
  .brand img{height:50px}
}
@media (max-width:640px){
  body{font-size:16px}
  .wrap,.wrap--narrow{width:calc(100% - 32px)}
  .sec{padding:74px 0}
  .hero{padding-top:34px;padding-bottom:64px}
  .trust{gap:22px}
  .trust strong{font-size:1.45rem}
  .form{padding:26px 22px;border-radius:var(--r-lg)}
  .form .row,.addons{grid-template-columns:1fr}
  .grid{grid-auto-rows:200px;gap:12px}
  .tile figcaption{opacity:1;transform:none;padding-top:28px}
  .foot__in{grid-template-columns:1fr}
  .brand__txt{font-size:.98rem}
  .lb__nav{width:44px;height:44px;font-size:1.8rem}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  html.js .reveal{opacity:1;transform:none}

  /* ── the marquee under reduce-motion ────────────────────────────────
     Previously this stopped the animation and turned the band into a
     horizontal scroll region — which left a dead strip the reader had to
     drag by hand to see anything past the first two phrases. Opera on
     Android reports reduce-motion for its data-saver/battery settings, so
     this is a real user-facing state, not an edge case.

     Instead: stop the animation AND let the phrases wrap into a normal
     centred block. Everything is readable at once, nothing to drag, and
     the duplicate cloned copies are hidden so nothing repeats. */
  .marquee{overflow:hidden}
  .marquee__track{
    animation:none;transform:none;
    width:auto;max-width:100%;flex-wrap:wrap;justify-content:center;
  }
  .marquee__set{
    /* the base rule sets flex:none, which would hold the set at its
       1574px max-content width and defeat the wrapping entirely */
    flex:1 1 100%;width:100%;
    flex-wrap:wrap;justify-content:center;
    padding-right:0;row-gap:6px;
  }
  /* script.js clones the set to fill the screen; only the original is needed
     once the phrases wrap. :first-child survives however many clones exist. */
  .marquee__set:not(:first-child){display:none}
}
