/* Self-hosted so the browser doesn't have to resolve DNS and negotiate TLS
   with two more origins before any text can render. Latin subset only. */
@font-face{
  font-family:'Fredoka';
  font-style:normal;
  font-weight:600;
  font-display:swap;
  src:url('../assets/fonts/fredoka-600.woff2') format('woff2');
}
@font-face{
  font-family:'Fredoka';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('../assets/fonts/fredoka-700.woff2') format('woff2');
}
@font-face{
  font-family:'Outfit';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('../assets/fonts/outfit-400.woff2') format('woff2');
}
@font-face{
  font-family:'Outfit';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('../assets/fonts/outfit-500.woff2') format('woff2');
}
@font-face{
  font-family:'Outfit';
  font-style:normal;
  font-weight:600;
  font-display:swap;
  src:url('../assets/fonts/outfit-600.woff2') format('woff2');
}
@font-face{
  font-family:'Outfit';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('../assets/fonts/outfit-700.woff2') format('woff2');
}

/* ═══════════════════════════════════════════════════════════════
   Cuts n Loops — app.css
   Everything visual lives here. Palette is set once, at the top.
   ═══════════════════════════════════════════════════════════════ */

:root{
  /* ── The candy palette ────────────────────────────────────── */
  --pink:#FF2E88;
  --pink-lo:#FF6FAE;
  --blue:#00B4FF;
  --blue-lo:#5FD5FF;
  --purple:#8B3DFF;
  --purple-lo:#B57BFF;
  --orange:#FF7A1A;
  --yellow:#FFD400;

  /* ── Neutrals ─────────────────────────────────────────────── */
  --ink:#160F26;          /* deep purple-black, never pure black */
  --ink-soft:#3E3355;
  --cream:#FFF7EE;
  --white:#FFFFFF;
  --line:rgba(22,15,38,.14);

  /* ── Signature gradients ──────────────────────────────────── */
  --rainbow:linear-gradient(90deg,var(--pink),var(--orange),var(--yellow),var(--blue),var(--purple));
  --ring:linear-gradient(135deg,var(--pink),var(--orange) 55%,var(--yellow));
  --candy:linear-gradient(135deg,var(--purple),var(--pink) 50%,var(--orange));

  /* ── Motion ───────────────────────────────────────────────── */
  --jab:cubic-bezier(.2,1.5,.3,1);      /* the needle-punch overshoot */
  --ease:cubic-bezier(.22,.61,.36,1);

  --r:18px;               /* standard corner */
  --r-lg:28px;
  --shadow:0 10px 30px -12px rgba(22,15,38,.35);
  --shadow-lg:0 24px 60px -20px rgba(22,15,38,.45);
}

/* ── Reset ──────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;
  font-family:'Outfit',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:clamp(16px,1rem + .2vw,18px);
  line-height:1.65;
  color:var(--ink);
  background:var(--cream);
  overflow-x:hidden;
}
img,video,canvas,svg{display:block;max-width:100%}
img,video{height:auto}
button,input,textarea,select{font:inherit;color:inherit}
a{color:inherit}
h1,h2,h3,h4{
  font-family:'Fredoka','Outfit',system-ui,sans-serif;
  font-weight:700;
  line-height:1.05;
  letter-spacing:-.02em;
  margin:0 0 .5em;
  text-wrap:balance;
}
p{margin:0 0 1em;text-wrap:pretty}
ul,ol{margin:0 0 1em;padding-left:1.15em}

/* ── Type scale ─────────────────────────────────────────────── */
.d1{font-size:clamp(2.6rem,7vw,4.6rem);overflow-wrap:break-word}
.d2{font-size:clamp(2rem,5vw,3.4rem)}
.d3{font-size:clamp(1.5rem,3.6vw,2.1rem)}
.lede{font-size:clamp(1.05rem,2.4vw,1.3rem);color:var(--ink-soft);max-width:56ch}
.small{font-size:.875rem}

/* Rainbow-filled text */
.rainbow-text{
  background:var(--rainbow);
  -webkit-background-clip:text;background-clip:text;
  color:transparent;
  /* fallback for any engine that ignores background-clip */
  -webkit-text-fill-color:transparent;

  /* These words sit in <em>, which renders as a SYNTHESISED OBLIQUE — Fredoka
     ships no true italic, so the browser shears the glyphs. The shear pushes
     the last letter's ink past its inline box, and background-clip:text only
     paints inside that box, so the final character was being sliced off
     ("tuft it" lost the last t). Widen the painting area and pull the space
     back with equal negative margins, so the layout is byte-for-byte the same. */
  padding-inline:.3em;
  margin-inline:-.3em;
}

/* ── Layout ─────────────────────────────────────────────────── */
.wrap{width:min(1180px,100% - 2.5rem);margin-inline:auto}
.section{padding:clamp(3.5rem,9vw,7rem) 0}
.section--tight{padding:clamp(2.5rem,6vw,4.5rem) 0}
.skip{
  position:absolute;left:-999px;top:0;z-index:200;
  background:var(--ink);color:var(--white);padding:.75rem 1.25rem;border-radius:0 0 var(--r) 0;
}
.skip:focus{left:0}
:focus-visible{outline:3px solid var(--purple);outline-offset:3px;border-radius:6px}

/* ── The running-stitch rule ────────────────────────────────── */
.stitch{
  border:0;height:5px;margin:0;
  background:
    repeating-linear-gradient(90deg,
      var(--ink) 0 14px, transparent 14px 26px);
  opacity:.18;
  border-radius:99px;
}
.stitch--rainbow{
  opacity:1;
  background:var(--rainbow);
  -webkit-mask:repeating-linear-gradient(90deg,#000 0 14px,transparent 14px 26px);
          mask:repeating-linear-gradient(90deg,#000 0 14px,transparent 14px 26px);
}

/* ═══════════════ Nav ═══════════════════════════════════════ */
.nav{
  position:sticky;top:0;z-index:100;
  background:rgba(255,247,238,.82);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid transparent;
  transition:border-color .3s var(--ease),background .3s var(--ease);
}
.nav.is-stuck{border-bottom-color:var(--line)}
.nav__in{display:flex;align-items:center;gap:1rem;min-height:68px}

.brand{display:flex;align-items:center;gap:.6rem;text-decoration:none;font-weight:700;margin-right:auto}
.brand{flex-direction:column;align-items:flex-start;gap:.15rem}
/* The lockup carries the name now, so the header shows the actual logo
   rather than a small mark that reads the same as any other circle. */
/* An inline SVG has no intrinsic width, and .brand is a column flex box that
   sizes to its content — so the lockup was collapsing to the width of the
   'TUFTING STUDIO' line beneath it. State the width outright. */
/* max-width:none matters: the global `svg{max-width:100%}` reset was clamping
   this to its parent, and the parent sizes to its content — so the lockup
   collapsed to the width of the 'TUFTING STUDIO' line beneath it. */
.brand__lockup{width:185px;height:26px;max-width:none;display:block;flex:none;color:var(--ink)}
.foot .brand__lockup{color:var(--cream)}
@media (min-width:900px){.brand__lockup{width:213px;height:30px}}
.brand b{display:none}
.brand b--unused{
  font-family:'Fredoka',sans-serif;font-size:1.2rem;letter-spacing:-.02em;line-height:1;
}
.brand i{display:block;font-size:.68rem;font-weight:500;font-style:normal;color:var(--ink-soft);letter-spacing:.14em;text-transform:uppercase}

.menu{display:none;align-items:center;gap:.35rem}
.menu a{
  text-decoration:none;font-weight:500;font-size:.95rem;
  padding:.5rem .7rem;border-radius:99px;
  transition:background .2s var(--ease),color .2s var(--ease);
}
.menu a:hover{background:rgba(139,61,255,.1);color:var(--purple)}
.menu a[aria-current="page"]:not(.btn){color:var(--pink);font-weight:600}

.burger{
  margin-left:auto;width:44px;height:44px;display:grid;place-content:center;gap:5px;
  background:none;border:0;cursor:pointer;padding:0;
}
.burger i{display:block;width:22px;height:2.5px;background:var(--ink);border-radius:2px;transition:transform .3s var(--ease),opacity .2s}
.burger[aria-expanded="true"] i:nth-child(1){transform:translateY(7.5px) rotate(45deg)}
.burger[aria-expanded="true"] i:nth-child(2){opacity:0}
.burger[aria-expanded="true"] i:nth-child(3){transform:translateY(-7.5px) rotate(-45deg)}

/* Mobile drawer */
.menu.is-open{
  display:flex;flex-direction:column;align-items:stretch;
  position:absolute;inset:100% .75rem auto;
  background:var(--white);border-radius:var(--r-lg);
  padding:.75rem;box-shadow:var(--shadow-lg);
  border:1px solid var(--line);
}
.menu.is-open a{padding:.8rem 1rem;font-size:1.05rem}
.menu.is-open .btn{margin-top:.35rem;justify-content:center}

@media (min-width:900px){
  .burger{display:none}
  .menu{display:flex}
}

/* ═══════════════ Buttons ═══════════════════════════════════ */
.btn{
  --btn-bg:var(--ink);--btn-fg:var(--white);
  display:inline-flex;align-items:center;gap:.55rem;
  padding:.85rem 1.5rem;border-radius:99px;border:0;
  background:var(--btn-bg);color:var(--btn-fg);
  font-weight:600;font-size:1rem;text-decoration:none;cursor:pointer;
  position:relative;isolation:isolate;
  transition:transform .35s var(--jab),box-shadow .3s var(--ease),filter .2s;
  box-shadow:0 6px 0 -1px rgba(22,15,38,.22);
}
.btn:hover{transform:translateY(-3px);box-shadow:0 12px 0 -3px rgba(22,15,38,.18),var(--shadow)}
.btn:active{transform:translateY(0);box-shadow:0 3px 0 -1px rgba(22,15,38,.25)}
.btn svg{width:18px;height:18px;flex:none;transition:transform .35s var(--jab)}
.btn:hover svg{transform:translateX(3px)}

.btn--pink{--btn-bg:var(--pink)}
.btn--blue{--btn-bg:var(--blue);--btn-fg:var(--ink)}
.btn--purple{--btn-bg:var(--purple)}
.btn--candy{background:var(--candy);color:var(--white)}
.btn--ghost{
  --btn-bg:transparent;--btn-fg:var(--ink);
  box-shadow:inset 0 0 0 2.5px var(--ink);
}
.btn--ghost:hover{box-shadow:inset 0 0 0 2.5px var(--purple),var(--shadow);color:var(--purple)}
.btn--sm{padding:.6rem 1.1rem;font-size:.9rem;box-shadow:0 4px 0 -1px rgba(22,15,38,.2)}
.btn--wide{width:100%;justify-content:center}

/* The yarn-loop flourish that draws itself on hover */
.btn .loop{width:0;overflow:visible;transition:width .35s var(--jab)}
.btn:hover .loop{width:18px}
.btn .loop path{
  stroke-dasharray:44;stroke-dashoffset:44;
  transition:stroke-dashoffset .5s var(--ease) .05s;
}
.btn:hover .loop path{stroke-dashoffset:0}

/* ═══════════════ Hero ══════════════════════════════════════ */
.hero{
  position:relative;
  padding:clamp(2rem,6vw,4rem) 0 clamp(3rem,8vw,6rem);
  background:
    radial-gradient(90% 70% at 12% 0%,rgba(0,180,255,.16),transparent 60%),
    radial-gradient(80% 70% at 92% 12%,rgba(255,46,136,.16),transparent 60%),
    radial-gradient(70% 60% at 60% 100%,rgba(139,61,255,.13),transparent 65%);
}
/* Mobile order: copy, then the rug, then the stats — so the signature
   animation lands just under the CTA instead of way below the fold.
   On desktop the rug moves into its own column and the stats tuck back
   under the copy. */
.hero__grid{display:grid;gap:clamp(2rem,5vw,3.5rem);align-items:center}
@media (min-width:920px){
  /* In the two-column hero the headline only gets ~46% of the width, so it
     needs its own scale — the page-level clamp is tuned for full width. */
  .hero__copy .d1{font-size:clamp(2.8rem,4.4vw,4.2rem)}
  .hero__grid{grid-template-columns:1.05fr .95fr;grid-template-rows:auto auto;align-items:center}
  .hero__copy {grid-column:1;grid-row:1}
  .hero__stage{grid-column:2;grid-row:1 / span 2;align-self:center}
  .hero__grid > .stats{grid-column:1;grid-row:2;margin-top:0}
}

.eyebrow{
  display:inline-flex;align-items:center;gap:.5rem;
  font-size:.78rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--purple);
  background:rgba(139,61,255,.1);
  padding:.45rem .9rem;border-radius:99px;margin:0 0 1.1rem;
}
.eyebrow .dot{width:8px;height:8px;border-radius:50%;background:var(--pink);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.75)}}

.hero__cta{display:flex;flex-wrap:wrap;gap:.75rem;margin:1.75rem 0 0}

.hero__stage{
  position:relative;border-radius:var(--r-lg);overflow:hidden;
  background:#241645;
  box-shadow:var(--shadow-lg);
  aspect-ratio:4/5;
  border:3px solid var(--ink);
}
@media (min-width:920px){.hero__stage{aspect-ratio:1/1}}
.hero__stage canvas,.hero__stage video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
}
.hero__stage video{z-index:2;opacity:0;transition:opacity .9s var(--ease)}
.stage__tag{
  position:absolute;left:.85rem;bottom:.85rem;z-index:3;
  display:flex;align-items:center;gap:.45rem;
  background:rgba(22,15,38,.72);backdrop-filter:blur(8px);
  color:var(--white);font-size:.78rem;font-weight:500;
  padding:.45rem .8rem;border-radius:99px;
}
.stage__tag .dot{width:7px;height:7px;border-radius:50%;background:var(--yellow);animation:pulse 1.6s infinite}

/* Hero stat strip */
.stats{
  display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;
  list-style:none;padding:1.5rem 0 0;margin:1.5rem 0 0;
  border-top:5px solid transparent;
  border-image:var(--rainbow) 1;
}
.stats b{display:block;font-family:'Fredoka',sans-serif;font-size:clamp(1.4rem,4vw,2rem);line-height:1}
.stats span{font-size:.8rem;color:var(--ink-soft)}

/* ═══════════════ Section headers ═══════════════════════════ */
.head{max-width:62ch;margin:0 0 clamp(2rem,5vw,3rem)}
.head--center{margin-inline:auto;text-align:center}
.label{
  display:block;font-size:.78rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--pink);margin:0 0 .6rem;
}

/* ═══════════════ The three pillars ═════════════════════════ */
.pillars{display:grid;gap:1.25rem}
@media (min-width:760px){.pillars{grid-template-columns:repeat(3,1fr)}}

.pillar{
  position:relative;display:flex;flex-direction:column;
  color:var(--ink);
  padding:1.75rem;border-radius:var(--r-lg);
  background:var(--white);border:3px solid var(--ink);
  box-shadow:0 8px 0 -1px var(--ink);
  text-decoration:none;overflow:hidden;
  transition:transform .35s var(--jab),box-shadow .35s var(--ease);
}
.pillar:hover{transform:translate(-3px,-6px);box-shadow:0 16px 0 -2px var(--ink)}
.pillar::before{
  content:"";position:absolute;inset:0 0 auto;height:8px;background:var(--bar,var(--pink));
}
.pillar--1{--bar:var(--pink)}
.pillar--2{--bar:var(--blue)}
.pillar--3{--bar:var(--yellow)}
.pillar__ico{
  width:56px;height:56px;border-radius:16px;display:grid;place-content:center;
  background:var(--bar);color:var(--white);margin:.5rem 0 1rem;flex:none;
}
.pillar--3 .pillar__ico{color:var(--ink)}
.pillar h3{margin-bottom:.35rem;font-size:1.4rem}
.pillar p{color:var(--ink-soft);font-size:.95rem;flex:1}
.pillar__go{display:inline-flex;align-items:center;gap:.4rem;font-weight:600;color:var(--purple);margin-top:.5rem}
.pillar:hover .pillar__go svg{transform:translateX(4px)}
.pillar__go svg{width:16px;height:16px;transition:transform .3s var(--jab)}

/* ═══════════════ Cards / galleries ═════════════════════════ */
.grid{display:grid;gap:1.25rem}
.grid--2{grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
.grid--3{grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr))}

.card{
  position:relative;display:flex;flex-direction:column;
  color:var(--ink);
  background:var(--white);border-radius:var(--r-lg);overflow:hidden;
  border:3px solid var(--ink);box-shadow:0 8px 0 -1px var(--ink);
  transition:transform .35s var(--jab),box-shadow .35s var(--ease);
}
.card:hover{transform:translate(-3px,-6px);box-shadow:0 16px 0 -2px var(--ink)}
.card__media{
  position:relative;aspect-ratio:4/3;overflow:hidden;background:var(--ink);
}
.card__media img,.card__media canvas{width:100%;height:100%;object-fit:cover}
.card__media img{transition:transform .6s var(--ease)}
.card:hover .card__media img{transform:scale(1.06)}
.card__body{padding:1.25rem;display:flex;flex-direction:column;flex:1;gap:.15rem}
.card__body h3{font-size:1.15rem;margin-bottom:.2rem}
.card__body p{font-size:.9rem;color:var(--ink-soft);flex:1;margin-bottom:.9rem}
.price{font-family:'Fredoka',sans-serif;font-weight:600;font-size:1.25rem;color:var(--pink)}
.price small{font-size:.75rem;color:var(--ink-soft);font-family:'Outfit',sans-serif;font-weight:400}

.tag{
  position:absolute;top:.75rem;left:.75rem;z-index:2;
  background:var(--yellow);color:var(--ink);
  font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  padding:.3rem .7rem;border-radius:99px;border:2px solid var(--ink);
}
.tag--pink{background:var(--pink);color:var(--white)}
.tag--blue{background:var(--blue)}

/* Play badge on video thumbs */
.play{
  position:absolute;inset:0;z-index:2;display:grid;place-content:center;
  background:rgba(22,15,38,.28);border:0;cursor:pointer;width:100%;
  transition:background .3s var(--ease);
}
.card:hover .play{background:rgba(22,15,38,.12)}
.play i{
  width:60px;height:60px;border-radius:50%;background:var(--white);
  display:grid;place-content:center;border:3px solid var(--ink);
  transition:transform .35s var(--jab);
}
.play:hover i{transform:scale(1.12)}
.play svg{width:22px;height:22px;margin-left:3px;fill:var(--ink)}


/* ═══════════════ Photo placeholder ═════════════════════════
   Stands in for a rug photo that has not been added yet. Deliberately
   plain rather than animated: the gallery is meant to be photographs of
   real finished rugs, so a decorative animation in that slot would
   misrepresent the work. */
.ph{
  width:100%;height:100%;
  display:grid;place-content:center;justify-items:center;gap:.55rem;
  padding:1rem;text-align:center;
  color:rgba(255,247,238,.5);
  background:
    repeating-linear-gradient(135deg,rgba(255,255,255,.05) 0 10px,transparent 10px 20px),
    linear-gradient(150deg,#2C1B4E,#3B2A62);
}
.ph svg{width:32px;height:32px}
.ph span{font-size:.8rem;font-weight:600}

/* Once a real photo has loaded, the card opens it full size. */
.card__media.is-photo{cursor:zoom-in}
.card__media.is-photo::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:rgba(22,15,38,0);transition:background .3s var(--ease);
}
.card:hover .card__media.is-photo::after{background:rgba(22,15,38,.14)}

/* ═══════════════ Video cards ═══════════════════════════════ */
.vid{cursor:pointer;text-align:left;font:inherit;padding:0;appearance:none;-webkit-appearance:none}
.vid .card__media{background:var(--ink)}
.vid--tall .card__media{aspect-ratio:3/4}
.vid .card__media img{width:100%;height:100%;object-fit:cover}
.vid__panel{
  position:absolute;inset:0;
  background:linear-gradient(140deg,var(--purple),var(--pink) 55%,var(--orange));
}
.vid__panel::after{
  content:"";position:absolute;inset:0;
  background:repeating-linear-gradient(135deg,rgba(0,0,0,.10) 0 12px,transparent 12px 24px);
}
.vid .play{pointer-events:none}


/* ═══════════════ Shop product cards ════════════════════════ */
/* The description used to carry flex:1, which stretched it and left a gap
   between the text and the bullet list — very visible on short descriptions.
   The buy row pushes itself down instead, so the bullets now sit tight under
   the description. */
.card__body .card__desc{flex:0 0 auto;margin-bottom:.55rem}
.card__specs{
  color:var(--ink-soft);
  margin:0 0 1rem;
  padding-left:1.1em;
}
.card__specs li{margin:.12rem 0}

/* The video slot sits where the decorative swatch used to, and inherits
   .card__media's 4:3 box — so an empty slot and a filled one take exactly the
   same space and the card never changes shape. */
.card__media--video.is-empty{
  display:grid;place-items:center;
  background:
    repeating-linear-gradient(135deg,rgba(255,255,255,.04) 0 12px,transparent 12px 24px),
    linear-gradient(150deg,#2C1B4E,#3B2A62);
}
.card__media--video .vidslot{
  display:grid;place-items:center;gap:.5rem;
  color:rgba(255,247,238,.55);text-align:center;padding:1rem;
}
.card__media--video .vidslot svg{
  width:46px;height:46px;fill:currentColor;opacity:.5;
  border:2.5px solid currentColor;border-radius:50%;padding:9px;
}
.card__media--video .vidslot span{font-size:.78rem;font-weight:600}

.card__buy{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-top:auto}

/* Delivery caveat — fine print tied to the price directly above it. */
.card__body .card__fineprint{
  margin:.55rem 0 0;
  font-size:.72rem;
  font-style:italic;
  line-height:1.4;
  color:var(--ink-soft);
  opacity:.85;
}

/* ═══════════════ Colour-block bands ════════════════════════ */
.band{position:relative;color:var(--white)}
.band--purple{background:var(--purple)}
.band--ink{background:var(--ink)}
.band--candy{background:var(--candy)}
.band--blue{background:var(--blue);color:var(--ink)}
.band .label{color:rgba(255,255,255,.75)}
.band--blue .label{color:var(--ink)}
.band .lede{color:rgba(255,255,255,.85)}
.band--blue .lede{color:var(--ink-soft)}
.band .btn--ghost{--btn-fg:var(--white);box-shadow:inset 0 0 0 2.5px currentColor}
.band--blue .btn--ghost{--btn-fg:var(--ink)}

/* Zig-zag stitched edge on colour bands */
.band::before,.band::after{
  content:"";position:absolute;left:0;right:0;height:10px;
  background:var(--rainbow);
}
.band::before{top:0}
.band::after{bottom:0}

/* ═══════════════ Numbered process ══════════════════════════ */
.steps{list-style:none;padding:0;margin:0;display:grid;gap:1.5rem;counter-reset:s}
@media (min-width:760px){.steps{grid-template-columns:repeat(2,1fr);gap:2rem}}
@media (min-width:1040px){.steps{grid-template-columns:repeat(4,1fr)}}
.steps li{counter-increment:s;position:relative;padding-top:3.75rem}
.steps li::before{
  content:counter(s);
  position:absolute;top:0;left:0;
  width:54px;height:54px;border-radius:50%;
  display:grid;place-content:center;
  font-family:'Fredoka',sans-serif;font-size:1.4rem;
  background:var(--white);color:var(--ink);border:3px solid var(--ink);
  box-shadow:0 5px 0 -1px var(--ink);
}
.steps li:nth-child(1)::before{background:var(--pink);color:var(--white)}
.steps li:nth-child(2)::before{background:var(--orange);color:var(--white)}
.steps li:nth-child(3)::before{background:var(--yellow)}
.steps li:nth-child(4)::before{background:var(--blue)}
.steps h3{font-size:1.1rem;margin-bottom:.3rem}
.steps p{font-size:.92rem;color:var(--ink-soft);margin:0}
.band .steps p{color:rgba(255,255,255,.82)}


/* ═══════════════ Scroll-scrubbed rug ═══════════════════════ */
/* A tall section with a pinned stage. How far you have scrolled
   through it decides how much of the rug exists. Scroll back up
   and the loops come out again. */
.scrub{position:relative;height:420vh}
@media (max-width:640px){.scrub{height:330vh}}
.scrub__pin{position:sticky;top:0;height:100vh;display:grid;align-content:center;overflow:hidden}
.scrub__grid{display:grid;gap:clamp(1.5rem,4vw,3rem);align-items:center;width:min(1180px,100% - 2.5rem);margin-inline:auto}
@media (min-width:920px){.scrub__grid{grid-template-columns:1fr 1fr}}
.scrub__stage{
  position:relative;width:100%;aspect-ratio:1/1;max-height:52vh;margin-inline:auto;
  border-radius:var(--r-lg);overflow:hidden;border:3px solid var(--ink);box-shadow:var(--shadow-lg);
}
@media (min-width:920px){.scrub__stage{max-height:70vh}}
.scrub__stage canvas{position:absolute;inset:0;width:100%;height:100%}

.caps{position:relative;min-height:13rem}
.caps > div{
  position:absolute;inset:0;opacity:0;pointer-events:none;
  transform:translateY(18px) scale(.97);
  transition:opacity .4s var(--ease),transform .55s var(--jab);
}
.caps > div.is-on{opacity:1;transform:none;pointer-events:auto}
.caps h3{font-size:clamp(1.4rem,3.4vw,2rem);margin-bottom:.4rem}
.caps p{color:var(--ink-soft);margin:0}
.band .caps p{color:rgba(255,255,255,.82)}
.caps .label{color:var(--yellow)}

/* ═══════════════ Misc helpers ══════════════════════════════ */
.center{text-align:center}
.mt{margin-top:clamp(2rem,5vw,3rem)}
.tight{max-width:70ch}
.pricebox{
  color:var(--ink);
  display:grid;gap:1rem;padding:clamp(1.25rem,4vw,2rem);
  background:var(--white);border:3px solid var(--ink);border-radius:var(--r-lg);
  box-shadow:0 8px 0 -1px var(--ink);
}
.pricebox__row{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:space-between;align-items:baseline;padding-bottom:.85rem;border-bottom:2px dashed var(--line)}
.pricebox__row:last-child{border-bottom:0;padding-bottom:0}
.pricebox__row b{font-family:'Fredoka',sans-serif;font-weight:600;font-size:1.05rem}
.pricebox__row span{color:var(--pink);font-family:'Fredoka',sans-serif;font-weight:600;font-size:1.15rem}
.pricebox__row small{display:block;color:var(--ink-soft);font-size:.85rem;font-family:'Outfit',sans-serif;font-weight:400}

/* ═══════════════ Forms ═════════════════════════════════════ */
.form{
  color:var(--ink);
  background:var(--white);border:3px solid var(--ink);border-radius:var(--r-lg);
  padding:clamp(1.25rem,4vw,2rem);box-shadow:0 10px 0 -2px var(--ink);
}
.field{margin:0 0 1rem}
.field label{display:block;font-weight:600;font-size:.9rem;margin:0 0 .35rem}
.field label .req{color:var(--pink)}
.field input,.field select,.field textarea{
  width:100%;padding:.8rem 1rem;
  border:2.5px solid var(--line);border-radius:14px;
  background:var(--cream);
  transition:border-color .2s var(--ease),background .2s;
}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:0;border-color:var(--purple);background:var(--white);
}
.field textarea{min-height:120px;resize:vertical}

/* File input — the default control ignores the field styling, so give it a
   dashed drop-zone look that matches the rest of the form. */
.field input[type="file"]{
  padding:.7rem;
  border-style:dashed;
  cursor:pointer;
  font-size:.9rem;
}
.field input[type="file"]::file-selector-button{
  margin-right:.75rem;
  padding:.45rem .9rem;
  border:0;border-radius:99px;
  background:var(--purple);color:var(--white);
  font-weight:600;font-size:.85rem;cursor:pointer;
  transition:transform .25s var(--jab),filter .2s;
}
.field input[type="file"]:hover::file-selector-button{transform:translateY(-1px);filter:brightness(1.08)}
.row{display:grid;gap:1rem}
/* Grid children default to min-width:auto, so a form control will not shrink
   below its intrinsic width (~255px, from the browser's default input size).
   In the two-column rows above 620px that pushed the right-hand field past the
   card's padding — the fields looked misaligned and their text was clipped.
   min-width:0 lets them size to the column they are given instead. */
.row > *{min-width:0}
.field input,.field select,.field textarea{min-width:0}
@media (min-width:620px){.row--2{grid-template-columns:1fr 1fr}}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form__note{font-size:.82rem;color:var(--ink-soft);margin:.85rem 0 0}
.status{margin:.85rem 0 0;font-weight:600;font-size:.92rem;min-height:1.4em}
.status[data-ok]{color:var(--purple)}
.status[data-err]{color:var(--pink)}

/* Inline validation messages. These sit directly under the offending input
   as well as in the summary line, because on a long form the summary by the
   Send button can be scrolled well out of sight of the field it refers to. */
.field__err{
  margin:.4rem 0 0;
  font-size:.82rem;font-weight:600;line-height:1.4;
  color:var(--pink);
}
.field input[aria-invalid],
.field textarea[aria-invalid]{
  border-color:var(--pink);
  background:var(--white);
}
.field input[aria-invalid]:focus,
.field textarea[aria-invalid]:focus{
  border-color:var(--pink);
  box-shadow:0 0 0 3px rgba(255,46,136,.18);
}

/* Chip radios (workshop dates, budget) */
.chips{display:flex;flex-wrap:wrap;gap:.5rem;margin:0}
.chips input{position:absolute;opacity:0;width:0;height:0}
.chips label{
  display:inline-block;padding:.55rem 1rem;border-radius:99px;
  border:2.5px solid var(--line);cursor:pointer;font-size:.9rem;font-weight:500;
  transition:all .25s var(--jab);margin:0;
}
.chips input:checked + label{
  background:var(--purple);color:var(--white);border-color:var(--purple);
  transform:scale(1.04);
}
.chips input:focus-visible + label{outline:3px solid var(--purple);outline-offset:3px}

/* ═══════════════ FAQ ═══════════════════════════════════════ */
.faq{border-top:2px solid var(--line)}
.faq details{border-bottom:2px solid var(--line)}
.faq summary{
  cursor:pointer;list-style:none;padding:1.15rem 2.5rem 1.15rem 0;
  font-weight:600;position:relative;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";position:absolute;right:.35rem;top:50%;
  width:12px;height:12px;margin-top:-8px;
  border-right:3px solid var(--pink);border-bottom:3px solid var(--pink);
  transform:rotate(45deg);transition:transform .3s var(--jab);
}
.faq details[open] summary::after{transform:rotate(-135deg);margin-top:-3px}
.faq p{color:var(--ink-soft);font-size:.95rem;padding:0 0 1.15rem}

/* On a dark band the FAQ inverts — it has no surface of its own. */
.band--ink .faq,.band--purple .faq,.band--candy .faq,
.band--ink .faq details,.band--purple .faq details,.band--candy .faq details{
  border-color:rgba(255,255,255,.22);
}
.band--ink .faq p,.band--purple .faq p,.band--candy .faq p{color:rgba(255,255,255,.82)}
.band--ink .faq summary::after,.band--purple .faq summary::after,.band--candy .faq summary::after{
  border-color:var(--yellow);
}

/* ═══════════════ Footer ════════════════════════════════════ */
.foot{background:var(--ink);color:var(--cream);padding:clamp(3rem,7vw,5rem) 0 2rem;position:relative}
.foot::before{content:"";position:absolute;inset:0 0 auto;height:10px;background:var(--rainbow)}
.foot__grid{display:grid;gap:2rem}
@media (min-width:760px){.foot__grid{grid-template-columns:1.4fr 1fr 1fr}}
.foot h4{font-size:.8rem;letter-spacing:.16em;text-transform:uppercase;color:var(--blue-lo);margin-bottom:.9rem}
.foot a{color:rgba(255,247,238,.78);text-decoration:none;transition:color .2s}
.foot a:hover{color:var(--yellow)}
.foot ul{list-style:none;padding:0;display:grid;gap:.5rem}
.foot .brand b,.foot .brand i{color:var(--cream)}
.socials{display:flex;gap:.6rem;margin-top:1rem}
.socials a{
  width:44px;height:44px;border-radius:14px;display:grid;place-content:center;
  background:rgba(255,255,255,.09);transition:transform .3s var(--jab),background .3s;
}
.socials a:hover{transform:translateY(-4px) rotate(-6deg);background:var(--pink);color:var(--white)}
.socials svg{width:20px;height:20px}
.foot__base{
  margin-top:2.5rem;padding-top:1.5rem;border-top:1px solid rgba(255,255,255,.14);
  display:flex;flex-wrap:wrap;gap:.75rem;justify-content:space-between;
  font-size:.83rem;color:rgba(255,247,238,.55);
}

/* Sticky mobile CTA */
.sticky-cta{
  position:fixed;left:.75rem;right:.75rem;bottom:.75rem;z-index:90;
  display:flex;gap:.5rem;
  transform:translateY(150%);transition:transform .45s var(--jab);
}
.sticky-cta.is-on{transform:none}
.sticky-cta .btn{flex:1;justify-content:center;box-shadow:var(--shadow-lg)}
@media (min-width:900px){.sticky-cta{display:none}}

/* ═══════════════ Lightbox ══════════════════════════════════ */
.lb{
  position:fixed;inset:0;z-index:150;display:none;
  place-content:center;padding:1rem;
  background:rgba(22,15,38,.9);backdrop-filter:blur(6px);
}
.lb[open]{display:grid}
/* The player is sized to the video's real shape and made as large as the
   viewport allows, so YouTube serves a matching resolution. Nothing is ever
   scaled up after the fact — that is what made it look soft before, and a
   portrait Short letterboxed inside a fixed 16:9 box was tiny as well.
   The min() chain means it can never overflow either axis. */
.lb__in{
  position:relative;
  aspect-ratio:16/9;
  width:min(1180px, 94vw, calc(88vh * 16 / 9));
  height:auto;
  border-radius:var(--r);
  overflow:hidden;
  border:3px solid var(--white);
  background:#000;
}
/* Instagram's embed is a post CARD — video plus a header and footer — so it
   needs its own shape and a white ground, not the bare 9:16 a Short uses.
   Driving off height keeps the video itself as large as the screen allows. */
.lb__in--ig{
  aspect-ratio:9/16;
  height:min(92vh, 960px);
  width:auto;
  max-width:94vw;
  background:#fff;
}

/* Shorts are vertical: drive off height instead. */
.lb__in--portrait{
  aspect-ratio:9/16;
  height:min(88vh, calc(94vw * 16 / 9));
  width:auto;
  max-width:94vw;
}
.lb__in iframe,.lb__in video{display:block;width:100%;height:100%;border:0;background:#000}

/* Spinner while an embed loads, so a slow frame doesn't read as broken. */
.lb__in.is-loading::after{
  content:"";position:absolute;top:50%;left:50%;
  width:38px;height:38px;margin:-19px 0 0 -19px;
  border:3px solid rgba(22,15,38,.18);
  border-top-color:var(--pink);
  border-radius:50%;
  animation:lbspin .7s linear infinite;
}
@keyframes lbspin{to{transform:rotate(360deg)}}

.lb__in--img{aspect-ratio:auto;width:auto;height:auto;max-width:94vw;max-height:88vh;background:var(--ink)}
.lb__in--img img{display:block;max-width:94vw;max-height:88vh;width:auto;height:auto}
.lb iframe{width:100%;height:100%;border:0}
.lb__x{
  position:absolute;top:1rem;right:1rem;width:48px;height:48px;border-radius:50%;
  background:var(--white);border:0;cursor:pointer;font-size:1.5rem;line-height:1;
}

/* ═══════════════ The punch-in reveal ═══════════════════════ */
/* Elements start slightly low + small, then get "jabbed" into place
   like a tufting gun driving yarn through the cloth. */
.rev{
  opacity:0;
  transform:translateY(26px) scale(.94);
  transition:
    opacity .5s var(--ease) calc(var(--i,0) * 80ms),
    transform .65s var(--jab) calc(var(--i,0) * 80ms);
}
.rev.is-in{opacity:1;transform:none}

/* Headline that punches in line by line */
.lines span{
  display:block;
  overflow:hidden;              /* this is what makes the line-by-line reveal work */
  /* …but the clip box only ever needed to clip VERTICALLY, and it was cutting
     into the type on every side:
       · below — line-height:1.05 sliced the tails off g, y and p
       · right — a trailing glyph's overhang got shaved
     Pad it out on all sides and pull the space straight back. Equal padding and
     negative margin leaves the content width and the left edge exactly where
     they were, so nothing reflows. */
  padding:0 .3em .22em;
  margin:0 -.3em -.22em;
}
.lines span i{
  display:block;font-style:normal;
  /* 130% rather than 105% — it now has the padding to clear as well. */
  transform:translateY(130%) rotate(2deg);
  transition:transform .8s var(--jab) calc(var(--i,0) * 90ms);
}
.lines.is-in span i{transform:none}

/* ── Reduced motion: keep everything, just stop moving it ──── */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  .rev{opacity:1;transform:none}
  .lines span i{transform:none}
  .sticky-cta{transform:none}
  .scrub{height:auto}
  .scrub__pin{position:static;height:auto;padding:clamp(2rem,6vw,4rem) 0}
  .caps{min-height:0;display:grid;gap:1.5rem}
  .caps > div{position:static;opacity:1;transform:none;pointer-events:auto}
}

/* ═══════════════ Print ═════════════════════════════════════ */
@media print{
  .nav,.sticky-cta,.foot,.hero__stage,.play{display:none}
  body{background:#fff;color:#000}
  .card,.pillar,.form{box-shadow:none;border:1px solid #999}
}
