/* ══════════════════════════════════════════════════════════════════════════
   ECLIPSE — the crossing between the two worlds.

   tg.tours (day, turquoise, tourists)  ⇄  the Academy shop (eclipse, plum, students)

   Deliberately SELF-CONTAINED: this file and js/eclipse.js know nothing about
   the rest of the site. The other half of the pair has to be installed into
   WordPress on tg.tours, and it has to be portable to get there. Do not merge
   it into styles.css.

   🔴 THE MEASUREMENT THAT SHAPES ALL OF IT
   tg.tours paints `rgb(255,255,255)` on first paint — measured in the browser,
   its hero video arrives later. So the crossing must END ON WHITE. End it on
   plum or gold and the visitor gets a hard white flash at the exact moment of
   handover, which is the thing that makes transitions like this look broken.
   The last 300ms of this animation exist only to match the destination.

   Going the other way (tg.tours → shop) the end colour must be #230F1B, the
   shop's own first paint. Same rule, other colour.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the control ─────────────────────────────────────────────────────────
   On the dark Academy it is a SUN: press it to go out into the day.
   On tg.tours it becomes an eclipsed disc: press it to come into the dark.
   The control always shows the world you are NOT in. */
/* 🔴 D · THE SUN IS PINNED TO THE VIEWPORT, NOT TO EITHER HEADER.
   The goal was «make the two top bars match so the sun does not jump across
   the crossing». Matching two headers is the fragile way to get there: one
   is our CSS, the other is Elementor, and any future theme update moves it.

   Measured on the live tg.tours at a 1024 viewport:
       band vertical centre  y = 32px   ← matched exactly, ours is 32 too
       right gutter              25px
       logo                  118 × 30, top 17
       bar position          relative (scrolls away)

   ⚠️ The VERTICAL number is matched to tg.tours; the HORIZONTAL one is not,
   and deliberately. 25px is where their social icons happen to sit today,
   and contorting our control to a third party's current layout means it
   breaks the day they move it. `right: 24px` is a number WE choose, and the
   WordPress install must use the same 24 — then the two match by
   construction rather than by coincidence.

   So the sun is fixed at that exact position instead. It lands on the same
   pixel on both sites at every screen width, it survives anything Elementor
   does to its own header, and on WordPress it installs as ONE element
   appended to <body> rather than as surgery inside the theme.

   Side effect worth having: tg.tours' bar is `position: relative` and
   scrolls away. A fixed sun stays reachable down the whole page, which is
   what a mode switch should do.

   ⚠️ top:10 + 44px tall = centre at y=32. Change one, change the other. */
/* 🔴 IT IS LABELLED, AND THAT IS NOT A COMPROMISE.
   «How does someone know to press the sun?» — they don't. An unexplained
   glowing circle is a designer's delight and a visitor's blind spot.

   lessons/a-control-explains-itself-or-it-is-the-wrong-control:
     «If a control needs a sentence under it explaining what it does, the
      control is mislabelled. Fix the label. Then delete the explanation.»

   So there is no tooltip and no coach mark — those are the explanation the
   lesson says to delete. Two words sit next to the sun instead. The magic
   is in what happens AFTER the press; it never needed to be a mystery
   before it. */
.sunbtn{
  position:fixed;
  top:10px;right:24px;
  z-index:200;
  display:flex;align-items:center;gap:10px;
  height:44px;flex:none;
  text-decoration:none;
  border:0;padding:0;margin:0;
  /* ⚠️ PILL, NOT 50%. This was `border-radius:50%` from when the control was
     a bare 44px circle. It is now a ~114×44 row (label + orb), and 50% on a
     wide box draws an ELLIPSE — which is exactly what the focus ring turned
     into: a gold oval round the whole thing. Spotted on screen. */
  border-radius:999px;
  background:transparent;
  cursor:pointer;
  -webkit-appearance:none;appearance:none;
  transition:transform .5s cubic-bezier(.32,.72,0,1);
}
/* Keep the nav's own content clear of it.
   76px was sized for a bare 44px sun. With the label the control is ~114px
   wide and it overlapped the CTA by 62px — measured, not eyeballed. */
.nav__in{padding-right:156px}
/* 🔴 WHY THIS IS FLAT AND NOT A SPHERE
   The first version was `radial-gradient(circle at 38% 34%, …)` — an
   off-centre highlight on a round object, which the eye reads as a shiny
   plastic ball. That one decision is the whole "AI-generated icon" look, and
   the founder called it immediately.

   A star is not a ball. It has no specular highlight, because nothing is
   lighting it. In the game the sun is a FLAT bright disc with a hard rim and
   an enormous soft halo, and that is what makes it read as a light source
   rather than an object. So: centred ramp, no highlight, crisp rim, big
   bloom, rays.

   If anyone reintroduces an off-centre highlight here, the plastic comes
   back with it. */
/* The label. Reads on the dark ground, gets out of the way on a phone where
   the header is already tight. */
.sunbtn__label{
  font-family:var(--sans, inherit);
  font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(244,234,230,.82);
  white-space:nowrap;
  transition:color .4s cubic-bezier(.32,.72,0,1);
}
.sunbtn:hover .sunbtn__label{color:#F1D087}

/* The sun itself is now its own box inside the row. */
.sunbtn__orb{position:relative;width:44px;height:44px;flex:none}

.sunbtn__disc{
  position:absolute;inset:6px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:radial-gradient(circle, #FFFBF0 0%, #FFF0CC 52%, #F6C879 82%, #EDB25C 100%);
  /* the rim is a hard bright line, not a soft glow — that crispness against
     a huge soft bloom is what makes the bloom read as light */
  box-shadow:
    0 0 0 1.5px rgba(255,251,240,.95),
    0 0 14px rgba(255,214,140,.9),
    0 0 34px rgba(240,183,96,.55);
  transition:box-shadow .5s cubic-bezier(.32,.72,0,1), transform .5s cubic-bezier(.32,.72,0,1);
  overflow:hidden;
}

/* Rays. A repeating conic gradient masked into a ring so the spokes exist
   only outside the disc and fade out before they reach the bloom's edge —
   same masking rule as every other gradient on the site. They turn very
   slowly: at 34s a visitor never catches them moving, they only notice the
   thing is alive. */
.sunbtn__rays{
  position:absolute;inset:-9px;border-radius:50%;pointer-events:none;
  background:repeating-conic-gradient(
    from 0deg,
    rgba(255,226,166,.55) 0deg 1.6deg,
    rgba(255,226,166,0) 1.6deg 15deg);
  -webkit-mask-image:radial-gradient(circle, transparent 46%, #000 58%, #000 76%, transparent 96%);
          mask-image:radial-gradient(circle, transparent 46%, #000 58%, #000 76%, transparent 96%);
  opacity:.75;
  transition:opacity .5s cubic-bezier(.32,.72,0,1);
}
/* 🔴 THE MARK INSIDE THE SUN IS THE DESTINATION'S, NOT OURS.
   The control shows the world you are going TO. From the Academy the sun
   carries the **Grupo TG Tours** monogram, because that is where it lands.
   On tg.tours the same control will carry the Academy's wave mark. Put our
   own logo in our own button and it stops being a door and becomes a badge.

   Drawn as a MASK over a solid colour rather than an <img> with a filter.
   `brightness(0)` can only ever give pure black; a mask gives the exact
   near-black plum, which sits on gold like a shadow instead of like a hole. */
.sunbtn__mark{
  width:60%;aspect-ratio:1;display:block;
  /* Black-brown, not plum. On a gold disc a purple-black turns muddy and the
     shape stops reading; a warm near-black is the same family as the gold, so
     it sits in the light rather than fighting it. ~14:1 against the disc. */
  background:#1C0F06;
  -webkit-mask:url("../assets/img/logo-grupo-mark.webp") center / contain no-repeat;
          mask:url("../assets/img/logo-grupo-mark.webp") center / contain no-repeat;
  opacity:1;
  transition:opacity .5s cubic-bezier(.32,.72,0,1), transform .6s cubic-bezier(.32,.72,0,1);
}
.sunbtn:hover .sunbtn__mark{opacity:1;transform:scale(1.05)}
/* The bloom. Large, soft, and well outside the disc — a glow drawn INSIDE a
   shape reads as a gradient; a glow drawn on what surrounds it reads as
   light. It fades to nothing at 72% of its own box, so it never shows the
   clipped edge that cost this project an afternoon elsewhere. */
.sunbtn__corona{
  position:absolute;inset:-14px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,
    rgba(255,226,166,.45) 0%,
    rgba(240,183,96,.3) 34%,
    rgba(240,183,96,.12) 52%,
    rgba(240,183,96,0) 72%);
  opacity:.9;
  transition:opacity .5s cubic-bezier(.32,.72,0,1), transform .6s cubic-bezier(.32,.72,0,1);
}

.sunbtn:hover .sunbtn__disc{
  box-shadow:
    0 0 0 1.5px #FFFDF6,
    0 0 20px rgba(255,226,166,1),
    0 0 52px rgba(240,183,96,.8);
}
.sunbtn:hover .sunbtn__corona{opacity:1;transform:scale(1.18)}
.sunbtn:hover .sunbtn__rays{opacity:1}
.sunbtn:active{transform:scale(.93)}
/* 🔴 THE FOCUS STATE IS A GLOW, NOT AN OUTLINE — AND IT IS NOT OPTIONAL.
   The gold oval that used to be here was a plain `outline` drawn round the
   whole label+orb row. He disliked it on sight, and he was right: it is a
   rectangle-shaped idea sitting on a control made of light.

   ⚠️ It cannot simply be deleted. `:focus-visible` is how a keyboard user
   knows where they are, and it shows up here at a very real moment — press
   the sun, land on tg.tours, press Back, and the browser restores focus to
   it. Remove the indicator and that person is lost on the page.

   So it is replaced, not removed, and by something MORE visible than the
   outline was: a hard white rim, a gold ring outside it, and the disc's own
   bloom turned up. Same language as the rest of the control — respond with
   light, not with a box. The label underlines too, so the state does not
   depend on colour alone. */
.sunbtn:focus-visible{outline:none}
.sunbtn:focus-visible .sunbtn__disc{
  box-shadow:
    0 0 0 2px #FFFDF6,
    0 0 0 5px rgba(240,183,96,.6),
    0 0 26px rgba(255,226,166,1),
    0 0 70px rgba(240,183,96,.75);
}
.sunbtn:focus-visible .sunbtn__corona{opacity:1;transform:scale(1.2)}
.sunbtn:focus-visible .sunbtn__label{
  color:#FFF6E2;
  text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:4px;
}

/* Two motions, both far too slow to watch on purpose. A sun that pulses
   visibly is a loading spinner; one that drifts is a star. */
@media (prefers-reduced-motion:no-preference){
  .sunbtn__corona{animation:sunbreathe 6s ease-in-out infinite}
  .sunbtn__rays{animation:sunturn 34s linear infinite}
}
@keyframes sunbreathe{
  0%,100%{opacity:.72;transform:scale(1)}
  50%    {opacity:1;transform:scale(1.07)}
}
@keyframes sunturn{ to{transform:rotate(360deg)} }

/* ── the crossing ────────────────────────────────────────────────────────
   Three stacked layers, all fixed, all above everything including the film
   grain (z 40) and the nav (z 60). */
.xing{
  position:fixed;inset:0;z-index:300;
  pointer-events:none;visibility:hidden;
  contain:strict;
}
.xing.is-on{pointer-events:auto;visibility:visible}

/* 1 · the light. Expands from the exact pixel that was pressed, so the
      crossing starts where the visitor's attention already is. The size is
      set in JS from the click position, because the radius needed to cover
      the viewport depends on which corner is furthest away. */
.xing__light{
  position:absolute;
  left:var(--x,50%);top:var(--y,50%);
  width:var(--d,150vmax);height:var(--d,150vmax);
  margin-left:calc(var(--d,150vmax) / -2);
  margin-top:calc(var(--d,150vmax) / -2);
  border-radius:50%;
  background:radial-gradient(circle,
    #FFFFFF 0%, #FFF6E2 16%, #F1D087 34%, #F0B760 52%,
    rgba(221,90,95,.7) 70%, rgba(89,50,131,.45) 84%, rgba(35,15,27,0) 96%);
  transform:scale(0);
  will-change:transform;
}

/* 2 · the body of the eclipse crossing the light. This is the Shadow Fight
      beat: not a fade, an occlusion. It sweeps across and off. */
.xing__body{
  position:absolute;
  left:var(--x,50%);top:var(--y,50%);
  width:var(--d,150vmax);height:var(--d,150vmax);
  margin-left:calc(var(--d,150vmax) / -2);
  margin-top:calc(var(--d,150vmax) / -2);
  border-radius:50%;
  background:#230F1B;
  transform:scale(0) translate3d(-60%,-30%,0);
  opacity:0;
  will-change:transform,opacity;
}

/* 3 · the handover. Pure white, matching tg.tours' measured first paint.
      Nothing beautiful happens here — its whole job is that the seam between
      the two sites is invisible. */
.xing__handover{
  position:absolute;inset:0;
  background:#fff;
  opacity:0;
  will-change:opacity;
}
/* Going the other way, the handover colour is the shop's own first paint. */
.xing--todark .xing__handover{background:#230F1B}

/* ── the choreography ────────────────────────────────────────────────────
   1400ms total. That is not an aesthetic number: it is roughly how long
   tg.tours needs to start painting on a normal connection, and the crossing
   has to outlast the load or the visitor watches a blank screen. If the
   destination gets faster, shorten it. */
.xing.is-on .xing__light{
  animation:xLight 1400ms cubic-bezier(.22,.61,.36,1) forwards;
}
.xing.is-on .xing__body{
  animation:xBody 1400ms cubic-bezier(.4,0,.2,1) forwards;
}
.xing.is-on .xing__handover{
  animation:xHand 1400ms linear forwards;
}

@keyframes xLight{
  0%   {transform:scale(0)}
  55%  {transform:scale(1)}
  100% {transform:scale(1.15)}
}
@keyframes xBody{
  0%   {transform:scale(0) translate3d(-60%,-34%,0);opacity:0}
  22%  {opacity:0}
  34%  {opacity:.92}
  62%  {transform:scale(.72) translate3d(-6%,-4%,0);opacity:.92}
  100% {transform:scale(1.25) translate3d(52%,30%,0);opacity:0}
}
@keyframes xHand{
  0%,62% {opacity:0}
  100%   {opacity:1}
}

/* ── reduced motion ──────────────────────────────────────────────────────
   Not "the same but quicker". An expanding disc and a sweeping occlusion are
   exactly the kinds of large-area motion that trigger vestibular symptoms, so
   the whole device is replaced by a plain cross-fade. The navigation still
   happens and the seam is still covered. */
@media (prefers-reduced-motion:reduce){
  .xing.is-on .xing__light,
  .xing.is-on .xing__body{animation:none;opacity:0;transform:none}
  .xing.is-on .xing__handover{animation:xHandReduced 420ms linear forwards}
  .sunbtn,.sunbtn__disc,.sunbtn__corona{transition:none}
}
@keyframes xHandReduced{ from{opacity:0} to{opacity:1} }

/* ── arriving ────────────────────────────────────────────────────────────
   The other half. A page entered through a crossing starts under the same
   white sheet and lifts it, so the two halves read as one movement rather
   than as an animation followed by a page load.

   `.is-arriving` is set by the inline bootstrap in the <head> — it has to be
   applied before first paint, so it cannot wait for js/eclipse.js. */
html.is-arriving body{visibility:visible}
/* 🔴 THE ARRIVAL SHEET IS THE COLOUR OF **THIS** PAGE, NOT THE ONE YOU LEFT.
   It was #fff here, copied from the departure animation, and that is exactly
   backwards. A visitor crossing FROM tg.tours arrives through a transition
   that ends on #230F1B — and then this page lifted a WHITE sheet over its own
   plum background. A white flash at the precise moment the whole device
   exists to hide.

   The rule, both ways: the departing page ends on the DESTINATION colour,
   the arriving page lifts its OWN colour. Here both are #230F1B.
   On tg.tours both are #fff. */
.xarrive{
  position:fixed;inset:0;z-index:300;pointer-events:none;
  background:#230F1B;opacity:1;
  animation:xArrive 700ms 60ms cubic-bezier(.22,.61,.36,1) forwards;
}
@keyframes xArrive{ from{opacity:1} to{opacity:0} }
@media (prefers-reduced-motion:reduce){
  .xarrive{animation-duration:300ms}
}

/* ── the first-visit flare ────────────────────────────────────────
   Runs ONCE, ever, on a visitor's first arrival, two seconds in — late
   enough that they have looked at the page, early enough to still be near
   the top. The label does the explaining; this only says "look here".

   Once, not every visit: a control that flares at you repeatedly stops
   being a discovery and becomes a nag. The flag lives in localStorage. */
.sunbtn.is-flaring .sunbtn__corona{animation:sunflare 1900ms cubic-bezier(.22,.61,.36,1) 2 both}
.sunbtn.is-flaring .sunbtn__disc{animation:sunflaredisc 1900ms cubic-bezier(.22,.61,.36,1) 2 both}
@keyframes sunflare{
  0%,100%{opacity:.72;transform:scale(1)}
  22%    {opacity:1;transform:scale(1.55)}
  55%    {opacity:.8;transform:scale(1.12)}
}
@keyframes sunflaredisc{
  0%,100%{box-shadow:0 0 0 1.5px rgba(255,251,240,.95), 0 0 14px rgba(255,214,140,.9), 0 0 34px rgba(240,183,96,.55)}
  22%    {box-shadow:0 0 0 2px #FFFDF6, 0 0 34px rgba(255,235,190,1), 0 0 90px rgba(240,183,96,.95)}
}
@media (prefers-reduced-motion:reduce){
  .sunbtn.is-flaring .sunbtn__corona,
  .sunbtn.is-flaring .sunbtn__disc{animation:none}
}

/* ══ MOBILE ════════════════════════════════════════════════════════════════
   🔴 THESE LIVE AT THE END OF THE FILE, AND THAT IS LOAD-BEARING.
   They were written above the rules they override. Same specificity, earlier
   in the file, so the base rule won every time and `.sunbtn__orb` stayed
   44px on a phone however many times the media query said 38. Measured, not
   guessed: the orb reported 44px at a 375px viewport.

   This is the SECOND time this exact mistake shipped today — the heading
   colour was the first, at 1.06:1. An override placed above its base is not
   an override, it is a default. Keep this block last.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width:620px){
  .sunbtn__label{font-size:9.5px;letter-spacing:.08em}
  /* The bar does not need to repeat the price: the hero button two
     centimetres below already reads «Начать с интенсива за €15». */
  .nav__cta .nav__cta__price{display:none}
  .nav__cta{padding:10px 13px;font-size:12.5px}
  .nav__in{padding-right:120px}
}
@media (max-width:430px){
  /* right:18, not 12 — the corona is a 14px halo OUTSIDE the orb, so at
     right:12 it hung 2px past the viewport and gave the whole page a
     horizontal scrollbar. The glow has to be inside the gutter too. */
  .sunbtn{top:13px;right:18px;height:38px;gap:7px}
  .sunbtn__orb{width:38px;height:38px}
  .sunbtn__disc{inset:5px}
  .sunbtn__corona{inset:-11px}
  .nav__in{padding-right:116px}
}
