/* =====================================================
   Tech2Software – festival layer, shared rules
   Loaded async, only while a campaign is active (includes/header.php).
   The theme file (css/festivals/<theme>.css) sets the tokens and the garland
   pattern; js/festival-motifs.js supplies the painted SVG; this file is where
   everything sits, how it moves, and how it stops.

   Every element here is position:fixed and pointer-events:none, below the
   navbar (1000), the mobile drawer (999) and the announcement bar (1100), so
   nothing can ever land on a control and nothing enters the page flow (CLS 0).
   The pill and the greeting card are the only interactive pieces.
   ===================================================== */
.t2fest{
  --fest-a:#d4801c; --fest-b:#f2b352; --fest-ink:#141a26; --fest-card:#ffffff; --fest-top:84px; --fest-right:28px; --fest-left:20px;
  position:fixed; inset:0; z-index:900; pointer-events:none; overflow:hidden;
  opacity:0; transition:opacity .6s ease;
}
.t2fest.is-on{opacity:1}

/* ── atmosphere ── */
.t2fest-canvas{position:absolute; inset:0; width:100%; height:100%}
/* The tint is its own body-level element, not a child of .t2fest: mix-blend-mode
   blends with the backdrop of the element's own stacking context, and .t2fest is
   one — inside it the glow could only blend with the transparent layer and drew
   as a solid colour band over white sections. --fest-tint is the scroll fade. */
.t2fest-tint{
  --fest-tint:1;
  position:fixed; inset:0; z-index:900; pointer-events:none; mix-blend-mode:screen;
  opacity:0; transition:opacity 1.2s ease;
}
.fest--main .t2fest-tint.is-on{opacity:var(--fest-tint)}
/* corner motif: painted inline SVG (js/festival-motifs.js); themes without one fall back to a CSS background */
/* 88px in from the right edge: the WhatsApp float (right 28, 56 wide) and the
   back-to-top button sit in that strip, and the motif's focal piece must not. */
.t2fest-corner{
  position:absolute; right:88px; bottom:0; width:340px; height:210px;
  background-repeat:no-repeat; background-position:right bottom; background-size:contain; opacity:.26;
}
.t2fest-corner.is-svg{opacity:.94; background:none}
.t2fest-corner svg{display:block; width:100%; height:100%}

/* ── the hairline along the top edge. Above the navbar's top few px on purpose:
      it is what stays visible once the navbar turns white on scroll. ── */
.t2fest-garland{
  /* above the scroll-progress bar (10000, 3px, same edge), which would otherwise draw across it */
  position:fixed; left:0; right:0; top:0; height:4px; z-index:10001; pointer-events:none;
  background:repeating-linear-gradient(90deg,var(--fest-a) 0 14px,var(--fest-b) 14px 22px,transparent 22px 28px);
  opacity:0; transition:opacity .6s ease;
}
.t2fest-garland.is-on{opacity:1}
.t2fest-garland.is-svg{background:none !important; animation:none !important; height:12px}
.t2fest-garland svg{display:block; width:100%; height:100%}

/* ── the pill: two real buttons. [icon name · countdown ●] [⏸]
      Background at 80% so white text holds 4.5:1 over a white page (55% was
      4.0:1). 32 px tall; 44 under a finger (WCAG 2.5.8 / Apple / Material). ── */
.t2fest-pill{
  position:fixed; top:var(--fest-top); right:var(--fest-right); z-index:2; pointer-events:auto;
  display:inline-flex; align-items:stretch; border-radius:999px; overflow:hidden; min-height:32px;
  font:700 .74rem/1.2 Inter,system-ui,sans-serif; letter-spacing:.01em; white-space:nowrap;
  color:#fff; background:rgba(20,26,38,.8); border:1px solid var(--fest-b);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
}
.t2fest-open,.t2fest-pause{font:inherit; color:inherit; background:none; border:0; cursor:pointer; padding:0; margin:0}
.t2fest-open{display:inline-flex; align-items:center; gap:7px; padding:0 12px}
.t2fest-open[disabled]{cursor:default}
.t2fest-open .ic{font-size:.92rem; line-height:1}
.t2fest-open .n{font-family:ui-monospace,Menlo,Consolas,monospace; font-weight:600; color:var(--fest-b)}
.t2fest-dot{width:7px; height:7px; border-radius:50%; background:var(--fest-b); display:none; margin-left:2px}
.t2fest-pill.has-dot .t2fest-dot{display:inline-block; animation:t2fest-ping 2.4s ease-out infinite}
.t2fest-pill.has-dot .t2fest-open:hover{background:rgba(255,255,255,.08)}
.t2fest-pause{width:34px; display:grid; place-items:center; border-left:1px solid rgba(255,255,255,.22); color:var(--fest-b); font-size:.72rem}
.t2fest-pause:hover{background:rgba(255,255,255,.1)}
.t2fest-pause[aria-pressed="true"]{background:rgba(255,255,255,.16); color:#fff}
.t2fest-open:focus-visible,.t2fest-pause:focus-visible{outline:2px solid #fff; outline-offset:-3px}
@keyframes t2fest-ping{0%{box-shadow:0 0 0 0 rgba(255,255,255,.55)}70%{box-shadow:0 0 0 7px rgba(255,255,255,0)}100%{box-shadow:0 0 0 0 rgba(255,255,255,0)}}

/* ── greeting card: bottom-left, clear of the WhatsApp float and back-to-top on the right.
      Rises in 300 ms, folds into the pill after 9 s (the bar along its foot is the
      countdown; hover or focus holds it), reopens from the pill. ── */
.t2fest-greet{
  content-visibility:visible; /* critical.css gives every off-hero <section> a 600px placeholder; a fixed card must measure at its real size */
  position:fixed; left:var(--fest-left); bottom:24px; z-index:3; pointer-events:auto; max-width:min(340px,calc(100vw - 32px));
  background:var(--fest-card); color:var(--fest-ink); border-radius:14px; padding:14px 46px 14px 16px;
  box-shadow:0 14px 40px rgba(0,0,0,.28); border-top:3px solid var(--fest-a);
  font:400 .88rem/1.45 Inter,system-ui,sans-serif; outline:none;
  transform:translateY(10px); opacity:0; transition:transform .3s cubic-bezier(.2,.8,.2,1),opacity .3s ease;
  --fold-x:0px; --fold-y:0px;
}
.t2fest-greet.is-in{transform:none; opacity:1}
.t2fest-greet.is-folding{transform:translate(var(--fold-x),var(--fold-y)) scale(.08); opacity:0; transition:transform .35s cubic-bezier(.5,0,.8,.4),opacity .25s ease .1s}
.t2fest-greet:focus-visible{box-shadow:0 14px 40px rgba(0,0,0,.28),0 0 0 3px var(--fest-b)}
.t2fest-greet h2{font:700 1.02rem/1.25 'Plus Jakarta Sans',Inter,system-ui,sans-serif; margin:0 0 4px; color:var(--fest-ink)}
.t2fest-greet p{margin:0}
.t2fest-cta{display:inline-block; margin-top:6px; font-weight:700; color:var(--fest-link,var(--fest-a)); text-decoration:none; font-size:.82rem; min-height:24px; line-height:24px}
.t2fest-cta:hover{text-decoration:underline}
.t2fest-x{
  position:absolute; top:6px; right:6px; width:32px; height:32px; border:0; border-radius:50%;
  background:rgba(20,26,38,.07); color:#5b6472; font-size:1.1rem; line-height:1; cursor:pointer; padding:0;
}
.t2fest-x:hover{background:rgba(20,26,38,.14); color:#141a26}
.t2fest-x:focus-visible,.t2fest-cta:focus-visible{outline:2px solid var(--fest-a); outline-offset:2px}
.t2fest-bar{position:absolute; left:0; right:0; bottom:0; height:2px; background:var(--fest-a); opacity:.45; transform-origin:left; transform:scaleX(0)}
.t2fest-greet.is-timed .t2fest-bar{transform:scaleX(1); animation:t2fest-count 9s linear forwards}
.t2fest-greet.is-held .t2fest-bar{animation-play-state:paused}
@keyframes t2fest-count{from{transform:scaleX(1)}to{transform:scaleX(0)}}
.t2fest-tag{
  position:absolute; top:-13px; left:12px; padding:4px 8px; border-radius:4px;
  font:700 .64rem/1 ui-monospace,Menlo,Consolas,monospace; letter-spacing:.12em; text-transform:uppercase;
  background:#141a26; color:#fff; box-shadow:0 2px 6px rgba(0,0,0,.25);
}
.t2fest-confetti{position:fixed; inset:0; z-index:4; pointer-events:none}

/* ── painted SVG parts (js/festival-motifs.js). Draw-ons play once and hold;
      loops move only transform or opacity. ── */
.fx-draw{stroke-dasharray:1; stroke-dashoffset:1; animation:fx-draw 2.2s cubic-bezier(.4,0,.2,1) forwards}
.fx-draw.d2{animation-delay:.35s} .fx-draw.d3{animation-delay:.7s} .fx-draw.d4{animation-delay:1.05s} .fx-draw.d8{animation-delay:.8s}
.fx-node{opacity:0; animation:fx-in .6s ease-out forwards; animation-delay:1.9s}
.fx-fade{opacity:0; animation:fx-in .8s ease-out forwards}
.fx-fade.d3{animation-delay:.3s} .fx-fade.d5{animation-delay:.5s} .fx-fade.d6{animation-delay:.6s} .fx-fade.d9{animation-delay:.9s} .fx-fade.d11{animation-delay:1.1s} .fx-fade.d12{animation-delay:1.2s} .fx-fade.d13{animation-delay:1.3s}
.fx-gear{transform-box:fill-box; transform-origin:center; animation:fx-spin 26s linear infinite}
.fx-gear.rev{animation-direction:reverse; animation-duration:18s}
.fx-petal{transform-box:fill-box; transform-origin:50% 100%; transform:scale(.06); opacity:0; animation:fx-open 1.2s cubic-bezier(.2,.8,.2,1) forwards}
.fx-petal.p1{animation-delay:.1s} .fx-petal.p2{animation-delay:.25s} .fx-petal.p3{animation-delay:.4s} .fx-petal.p4{animation-delay:.55s} .fx-petal.p5{animation-delay:.7s} .fx-petal.p6{animation-delay:.85s} .fx-petal.p7{animation-delay:1s}
.fx-flame{transform-box:fill-box; transform-origin:50% 100%; animation:fx-flick 1.4s ease-in-out infinite alternate}
.fx-flame.f2{animation-delay:-.5s} .fx-flame.f3{animation-delay:-.9s} .fx-flame.f4{animation-delay:-.3s}
.fx-halo{transform-box:fill-box; transform-origin:center; animation:fx-halo 1.4s ease-in-out infinite alternate}
.fx-halo.f2{animation-delay:-.5s} .fx-halo.f3{animation-delay:-.9s} .fx-halo.f4{animation-delay:-.3s}
.fx-sway{transform-box:fill-box; transform-origin:50% 0; animation:fx-sway 4s ease-in-out infinite alternate}
.fx-sway.s2{animation-delay:-1.3s} .fx-sway.s3{animation-delay:-2.6s} .fx-sway.s4{animation-delay:-.7s} .fx-sway.s5{animation-delay:-2s}
.fx-swing{transform-box:fill-box; transform-origin:50% 0; animation:fx-swing 4.2s ease-in-out infinite alternate}
.fx-swing.s2{animation-delay:-1.4s} .fx-swing.s3{animation-delay:-2.8s}
.fx-sun.down{transform:translateY(-50px); animation:fx-settle 3.2s cubic-bezier(.2,.7,.2,1) forwards}
.fx-sun.up{transform:translateY(80px); animation:fx-settle 3.2s cubic-bezier(.2,.7,.2,1) forwards}
.fx-refl{transform-box:fill-box; transform-origin:center; transform:scaleX(0); opacity:0; animation:fx-stretch 1.4s ease-out forwards; animation-delay:1.2s}
.fx-shim{animation:fx-shim 3s ease-in-out infinite alternate}
.fx-shim.k2{animation-delay:-1s} .fx-shim.k3{animation-delay:-2s}
.fx-bob{animation:fx-bob 4s ease-in-out infinite alternate}
.fx-bob.b2{animation-delay:-1.3s} .fx-bob.b3{animation-delay:-2.6s}
.fx-ripple{transform-box:fill-box; transform-origin:center; animation:fx-ripple 4s ease-in-out infinite}
.fx-ripple.b2{animation-delay:-1.3s} .fx-ripple.b3{animation-delay:-2.6s}
.fx-ring{transform-box:fill-box; transform-origin:center; transform:scale(0); animation:fx-pop .9s cubic-bezier(.2,.8,.2,1) forwards}
.fx-ring.r2{animation-delay:.25s} .fx-ring.r3{animation-delay:.5s} .fx-ring.r4{animation-delay:.75s} .fx-ring.r5{animation-delay:1s}
.fx-chakra{transform-box:fill-box; transform-origin:center; animation:fx-spin 60s linear infinite}
.fx-glow{animation:fx-glowo 1.6s ease-in-out infinite alternate}
.fx-glow.g2{animation-delay:-.55s} .fx-glow.g3{animation-delay:-1.1s}
@keyframes fx-glowo{from{opacity:.65}to{opacity:1}}
@keyframes fx-draw{to{stroke-dashoffset:0}}
@keyframes fx-in{to{opacity:1}}
@keyframes fx-spin{to{transform:rotate(360deg)}}
@keyframes fx-open{to{transform:scale(1); opacity:1}}
@keyframes fx-flick{from{transform:scaleY(1) skewX(0)}to{transform:scaleY(1.1) skewX(-4deg)}}
@keyframes fx-halo{from{opacity:.55; transform:scale(.92)}to{opacity:.95; transform:scale(1.1)}}
@keyframes fx-sway{from{transform:rotate(-1.6deg)}to{transform:rotate(1.6deg)}}
@keyframes fx-swing{from{transform:rotate(-2.5deg)}to{transform:rotate(2.5deg)}}
@keyframes fx-settle{to{transform:translateY(0)}}
@keyframes fx-stretch{to{transform:scaleX(1); opacity:1}}
@keyframes fx-shim{from{opacity:.25}to{opacity:.7}}
@keyframes fx-bob{from{transform:translateY(0)}to{transform:translateY(-5px)}}
@keyframes fx-ripple{0%,100%{transform:scaleX(1); opacity:.35}50%{transform:scaleX(1.15); opacity:.7}}
@keyframes fx-pop{to{transform:scale(1)}}

/* ── the opening moment's scene (the curtain itself is styled inline in the header,
      so it is in the first frame; this arrives with the rest of the layer) ── */
.t2fest-moment-scene svg{position:absolute; inset:0; width:100%; height:100%; display:block}
.t2fest-moment-scene .mo-lyr{will-change:transform; transition:transform .14s linear}
.fx-bokeh{animation:fx-bok 6s ease-in-out infinite alternate}
.fx-bokeh.b2{animation-delay:-2s} .fx-bokeh.b3{animation-delay:-4s}
.fx-fade.d10{animation-delay:1s} .fx-fade.d13{animation-delay:1.3s} .fx-fade.d16{animation-delay:1.6s} .fx-fade.d19{animation-delay:1.9s} .fx-fade.d22{animation-delay:2.2s}
@keyframes fx-bok{from{transform:translateY(0) scale(1)}to{transform:translateY(-18px) scale(1.12)}}
@media (max-width:640px){ .t2fest-moment-txt{top:18%} .t2fest-moment-txt h2{font-size:2rem} }

/* ── ⏸ pressed: every keyframe frozen where it is; the canvas stops in festival.js ── */
.fest-still .t2fest *,.fest-still .t2fest-garland,.fest-still .t2fest-garland *,.fest-still .t2fest-tint{animation-play-state:paused !important}

/* ── phones ── */
@media (max-width:640px){
  .t2fest-corner,.t2fest-tint{display:none}
  .t2fest-pill{right:24px}   /* the hamburger's inset */
  .t2fest-open{padding:0 10px}
  .t2fest-open .t{display:none}
  .t2fest-greet{
    left:12px; right:96px; bottom:calc(16px + env(safe-area-inset-bottom)); max-width:none; max-height:20vh; overflow:auto;
    padding:12px 44px 12px 14px; font-size:.84rem;
  }
}
@media (pointer:coarse){
  .t2fest-pill{min-height:44px}
  .t2fest-pause{width:44px}
  .t2fest-x{width:44px; height:44px; top:2px; right:2px}
}

/* ── reduced motion: the still parts stay; anything that moves shows its finished frame ── */
@media (prefers-reduced-motion:reduce){
  .t2fest-canvas,.t2fest-confetti{display:none}
  .t2fest,.t2fest-garland,.t2fest-greet,.t2fest-tint{transition:none}
  .t2fest *,.t2fest-garland,.t2fest-garland *{animation:none !important}
  .fx-draw{stroke-dashoffset:0} .fx-node,.fx-fade{opacity:1} .fx-petal,.fx-ring{transform:none; opacity:1}
  .fx-sun.down,.fx-sun.up{transform:none} .fx-refl{transform:scaleX(1); opacity:1}
  .t2fest-bar{display:none}
}
/* the Save-Data header is what browsers send today; this query is specified for the same intent */
@media (prefers-reduced-data:reduce){ .t2fest-canvas,.t2fest-confetti{display:none} }
/* Windows High Contrast keeps SVG strokes and drops backgrounds; the canvas would draw regardless */
@media (forced-colors:active){
  .t2fest-canvas,.t2fest-confetti,.t2fest-tint{display:none}
  .t2fest-pill,.t2fest-greet{border:1px solid CanvasText}
}

/* ── paper: a quotation printed from the site in Diwali week should not carry diyas ── */
@media print{
  .t2fest,.t2fest-garland,.t2fest-tint{display:none !important}
}
