/* =========================================================
   ALICE'S PATH — the chart that took the portrait's place in COUNT 2
   Markup: figure.journey in index.html · behaviour: journey.js

   Neon sign: glass tubes that flicker on one by one.
   ========================================================= */
@import url("https://fonts.googleapis.com/css2?family=Tilt+Neon&display=swap");

.journey{
  --e-draw:cubic-bezier(.77,0,.175,1);    /* the can travelling on screen */
  --e-pop:cubic-bezier(.34,1.56,.64,1);   /* a node landing on its count */
  --neon:#F48FAA;                         /* the tube's colour: powder pushed hot */
  position:sticky;top:max(24px,calc(50svh - 420px));
  align-self:start;
  margin:0;
  display:flex;flex-direction:column;align-items:center;gap:var(--s2);
}

.journey__box{
  position:relative;
  /* tall like the portrait it replaces, and never taller than the screen */
  width:min(100%,max(300px,calc((100svh - 150px) * 600 / 760)),600px);
  aspect-ratio:600/760;
  container-type:inline-size;
}
/* the wine light the portrait used to stand in; the neon brings its own */
.journey__box::before{
  content:"";position:absolute;inset:-6% -12%;
  background:radial-gradient(48% 42% at 58% 52%,rgba(127,31,50,.55),transparent 72%);
  pointer-events:none;
  transition:opacity .6s var(--e-soft);
  opacity:.3;
}
.journey__art{position:absolute;inset:0;width:100%;height:100%;overflow:visible}

/* ---------- the three stages: dot + label, one button each ---------- */
/* The button is a 44px circle centred on the anchor, not a 0×0 point with
   its dot and label hanging off it — an empty box leaves the hit test to
   whatever overflows it, which is not something to rely on across browsers. */
.journey__node{
  position:absolute;left:var(--ax);top:var(--ay);z-index:2;
  width:44px;height:44px;margin:-22px 0 0 -22px;padding:0;
  border-radius:50%;
  text-align:left;
  -webkit-tap-highlight-color:transparent;
}
.journey__node:focus-visible{outline:0}
.journey__node:focus-visible .journey__dot{outline:2px solid var(--powder);outline-offset:9px}

.journey__dot{
  position:absolute;left:13px;top:13px;      /* centred in the 44px button */
  width:18px;height:18px;border-radius:50%;
  transition:transform .2s var(--e-out);
}
.journey__dot::before{                    /* 44px target around an 18px dot */
  content:"";position:absolute;inset:-13px;border-radius:50%;
}
.journey__dot::after{                     /* the beat ring */
  content:"";position:absolute;inset:-5px;border-radius:50%;
  border:2px solid var(--powder);opacity:0;
}
/* Alive on an 8-count: the rings fire on beats 1, 2, 3 of each bar
   (4s = eight beats at 120 bpm), so the pulse climbs the path and rests. */
.journey.is-live .journey__dot::after{
  animation:journey-beat 4s var(--e-out) infinite;
  animation-delay:calc(var(--i) * .5s);
}
@keyframes journey-beat{
  0%{transform:scale(1);opacity:.8}
  22%,100%{transform:scale(2.6);opacity:0}
}

.journey__label{
  position:absolute;left:22px;top:22px;      /* the anchor point */
  display:flex;flex-direction:column;align-items:flex-end;gap:3px;
  white-space:nowrap;text-align:right;
  translate:calc(-100% - 24px) calc(-100% - 10px);     /* above-left of the dot */
}
.journey__label em{
  font:600 10.5px/1.2 var(--ui);font-style:normal;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
  transition:color var(--t-fast) var(--e-soft);
}
.journey__label em:first-child{color:var(--powder)}     /* the years, powder like the sheet's */
.journey__label b{margin-top:4px;font-weight:400;color:var(--white)}
@media (hover:hover) and (pointer:fine){
  .journey__node:hover .journey__dot{transform:scale(1.2)}
  .journey__node:hover .journey__label em{color:var(--powder)}
}

.journey__cap{
  display:flex;flex-wrap:wrap;justify-content:center;gap:4px 14px;
  font-size:12px;color:var(--muted);text-align:center;
}
.journey__hint::before{content:"● ";color:var(--powder)}

/* =========================================================
   NEON
   A sign on a dark wall: five glass tubes — the three stretches, the last
   climb and the arrowhead — each bent at the corners, held by clips. Unlit,
   the glass is still there; they flicker on one after another.
   ========================================================= */
.nb-off use{fill:none;stroke:rgba(248,247,248,.13);stroke-width:7;stroke-linecap:round;stroke-linejoin:round}
.nb-off .nb-gloss{stroke:rgba(255,255,255,.2);stroke-width:1.3}
.nb-tube{fill:none;stroke:var(--neon);stroke-width:6.5;stroke-linecap:round;stroke-linejoin:round}
.nb-core{fill:none;stroke:#FFF5F8;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.nb-clip{stroke:#141316;stroke-width:5}
.nb-cap{fill:#2A272D;stroke:rgba(248,247,248,.18);stroke-width:1}
/* lit, it hums: the brightness breathes a little, never flashes */
.journey.is-live .nb-lit{animation:nb-hum 4.4s ease-in-out infinite}
@keyframes nb-hum{0%,100%{opacity:1}50%{opacity:.86}}

.journey .journey__dot{
  background:#1B1A1E;
  box-shadow:0 0 0 2.5px #FFE9EF,0 0 8px 3px var(--neon),0 0 26px 7px rgba(244,143,170,.5),
             inset 0 0 6px 1px var(--neon);
}
.journey .journey__dot::after{border-color:var(--neon);box-shadow:0 0 10px var(--neon)}
.journey .journey__label b{
  font-family:"Tilt Neon",var(--display);
  font-size:clamp(19px,5cqi,31px);line-height:1;letter-spacing:.02em;
  color:#FFEFF3;
  text-shadow:0 0 2px #FFFFFF,0 0 8px var(--neon),0 0 18px var(--neon),0 0 38px rgba(244,143,170,.55);
}

/* ---------- before the draw-in (journey.js arms, then plays) ---------- */
.journey.is-armed .nb-lit g,
.journey.is-armed .journey__dot,
.journey.is-armed .journey__label{opacity:0}

/* =========================================================
   THE SHEET — a stage's achievements
   A modal dialog on desktop, a bottom sheet on phones.
   ========================================================= */
.journey-sheet{
  width:min(560px,calc(100vw - 32px));
  max-height:min(86svh,780px);
  padding:0;
  border:1px solid rgba(248,247,248,.12);border-radius:var(--r3);
  background:linear-gradient(160deg,#3A363F,#26242A 60%);
  color:var(--text);
  box-shadow:0 40px 120px -30px rgba(0,0,0,.85),inset 0 1px 0 rgba(248,247,248,.08);
  overflow:hidden;
}
/* No CSS entrance (@starting-style + transitioned display/overlay): Safari —
   so every iPhone browser, Telegram's included — left the sheet at its
   starting state, off-screen, with only the blurred backdrop showing. The
   entrance is a Web Animation in journey.js instead; if it never runs, the
   sheet is simply there. */
.journey-sheet[open]{display:flex;flex-direction:column}
.journey-sheet::backdrop{background:rgba(15,14,17,.72);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}

/* no <dialog> support (journey.js): the same card, fixed and centred, with
   the page dimmed by hand since there's no ::backdrop */
.has-sheet-fallback body::after{
  content:"";position:fixed;inset:0;z-index:199;
  background:rgba(15,14,17,.72);
}
.has-sheet-fallback .journey-sheet[open]{
  position:fixed;z-index:200;
  top:50%;left:50%;margin:0;
  max-height:86vh;
  transform:translate(-50%,-50%);
}

/* flex:1 1 AUTO, not flex:1 — the sheet only has a max-height, and Safari
   resolved the 0% basis of `flex:1` against it as zero: the whole card
   collapsed to its border. An auto basis sizes from the content and shrinks
   (min-height:0) once the max-height bites, so the list scrolls. */
.journey-sheet__in{position:relative;display:flex;flex-direction:column;width:100%;min-height:0;flex:1 1 auto}
.journey-sheet__in .modal__x{z-index:2}

.journey-stage{display:flex;flex-direction:column;min-height:0;flex:1 1 auto}
.journey-stage[hidden]{display:none}
.journey-stage__head{padding:clamp(24px,4vw,36px) clamp(22px,4vw,36px) var(--s3)}
.journey-stage__t{
  margin:12px 0 0;
  font:400 clamp(34px,7vw,52px)/.9 var(--display);
  letter-spacing:-.045em;color:var(--white);
}

.journey-list{
  flex:1 1 auto;min-height:0;
  margin:0;padding:0 clamp(22px,4vw,36px) var(--s4);
  overflow-y:auto;overscroll-behavior:contain;
  /* the fade says "more below"; the bottom padding lets the last row clear it */
  -webkit-mask-image:linear-gradient(#000 calc(100% - 32px),transparent);
  mask-image:linear-gradient(#000 calc(100% - 32px),transparent);
}
.journey-list li{
  display:grid;grid-template-columns:62px minmax(0,1fr);gap:14px;
  padding:14px 0;border-top:1px solid var(--line);
}
.journey-list__y{
  white-space:nowrap;
  font:400 13px/1.55 var(--display);letter-spacing:-.01em;
  color:var(--powder);font-variant-numeric:tabular-nums;
}
.journey-list__y--none{color:var(--muted)}
.journey-list p{margin:0;font-size:14px;line-height:1.55;color:var(--text)}
.journey-list b{
  display:block;margin-bottom:2px;
  font:800 16px/1.3 var(--head);letter-spacing:-.015em;color:var(--white);
}
.journey-list .is-top b{color:var(--powder)}

.journey-sheet__nav{
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:var(--s2);
  padding:14px clamp(14px,3vw,26px);
  border-top:1px solid var(--line);
  background:rgba(27,26,30,.5);
}
.journey-sheet__go{
  display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 12px;
  border-radius:var(--pill);
  font:400 13px/1 var(--display);letter-spacing:-.01em;color:var(--white);
  transition:background var(--t-fast),color var(--t-fast);
}
.journey-sheet__go[data-go="1"]{justify-self:end}
.journey-sheet__go[hidden]{display:inline-flex;visibility:hidden}
.journey-sheet__go i{font-style:normal;color:var(--powder)}
.journey-sheet__pos{font-size:11px;letter-spacing:.14em;color:var(--muted);font-variant-numeric:tabular-nums}
@media (hover:hover) and (pointer:fine){
  .journey-sheet__go:hover{background:rgba(248,247,248,.06);color:var(--powder)}
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width:1080px){
  .journey{position:static;order:2}     /* one column: the chart follows the text */
}
/* narrow charts: the names stay, the captions live in the sheet */
@container (max-width:440px){
  .journey__label em{display:none}
  .journey__label{translate:calc(-100% - 16px) calc(-100% - 6px)}
}
@media (max-width:760px){
  /* bottom sheet: rises from the edge the thumb is on (journey.js slides it
     up). A set height, not just a cap: a definite box is one less thing for
     a mobile engine to size from nothing. vh first for engines without svh. */
  .journey-sheet{
    width:100%;max-width:100%;
    height:84vh;max-height:84vh;
    height:84svh;max-height:84svh;
    margin:auto 0 0;
    border-radius:26px 26px 0 0;border-bottom:0;
  }
  .has-sheet-fallback .journey-sheet[open]{top:auto;bottom:0;left:0;transform:none}
  .journey-list li{grid-template-columns:60px minmax(0,1fr);gap:10px}
}

@media (prefers-reduced-motion:reduce){
  .journey.is-live .journey__dot::after,
  .journey.is-live .nb-lit{animation:none}
}
