/* Астрокот — the site. The app's own night and gold (ui/theme/Color.kt) and its own faces (ui/theme/Type.kt):
   Cormorant for headings, Montserrat for reading. Nothing is loaded from other sites, and the pages carry no
   styles of their own: the server lets a page use only this file (Content-Security-Policy). */

@font-face { font-family: "Cormorant"; font-weight: 600; font-display: swap; src: url("/fonts/cormorant-semibold.woff2") format("woff2"); }
@font-face { font-family: "Cormorant"; font-weight: 700; font-display: swap; src: url("/fonts/cormorant-bold.woff2") format("woff2"); }
@font-face { font-family: "Montserrat"; font-weight: 400; font-display: swap; src: url("/fonts/montserrat-regular.woff2") format("woff2"); }
@font-face { font-family: "Montserrat"; font-weight: 500; font-display: swap; src: url("/fonts/montserrat-medium.woff2") format("woff2"); }
@font-face { font-family: "Montserrat"; font-weight: 600; font-display: swap; src: url("/fonts/montserrat-semibold.woff2") format("woff2"); }

:root {
  --night: #0B1630;
  --night-deep: #070F24;
  --surface: #101D3C;
  --border: #26355C;
  --hairline: rgba(255, 255, 255, .07);
  --gold: #F2B45A;
  --gold-light: #FFE3A3;
  --gold-line: rgba(242, 180, 90, .4);
  --ink: #1E1A2E;
  --text: #F6EEDD;
  --text-2: #D0D5E6;
  --muted: #A3ACC8;
  --serif: "Cormorant", Georgia, "Times New Roman", serif;
  --sans: "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  /* A four-pointed star, for every place one is drawn. */
  --star: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  /* Two squares of quiet stars, laid over the sky and twinkling out of step. */
  --stars-near:
    radial-gradient(1.4px 1.4px at 24px 36px, rgba(255, 227, 163, .95), transparent 70%),
    radial-gradient(1px 1px at 150px 84px, rgba(255, 255, 255, .75), transparent 70%),
    radial-gradient(1.6px 1.6px at 268px 190px, rgba(255, 227, 163, .8), transparent 70%),
    radial-gradient(1px 1px at 92px 232px, rgba(255, 255, 255, .6), transparent 70%),
    radial-gradient(1.2px 1.2px at 206px 318px, rgba(255, 227, 163, .7), transparent 70%);
  --stars-far:
    radial-gradient(1px 1px at 60px 120px, rgba(255, 255, 255, .6), transparent 70%),
    radial-gradient(1.2px 1.2px at 330px 48px, rgba(255, 255, 255, .55), transparent 70%),
    radial-gradient(1px 1px at 410px 300px, rgba(255, 227, 163, .6), transparent 70%),
    radial-gradient(1.3px 1.3px at 190px 420px, rgba(255, 255, 255, .5), transparent 70%),
    radial-gradient(1px 1px at 480px 180px, rgba(255, 255, 255, .45), transparent 70%),
    radial-gradient(1px 1px at 260px 20px, rgba(255, 227, 163, .5), transparent 70%);
  color-scheme: dark;
}

* { box-sizing: border-box; }
body { margin: 0; background: var(--night-deep); color: var(--text-2); font: 400 16px/1.6 var(--sans); overflow-x: hidden; }
img, video, svg { display: block; max-width: 100%; }
img, video { height: auto; }
a { color: var(--gold-light); text-underline-offset: 3px; }
a:hover { color: var(--gold); }
a:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 6px; }
.wrap { width: min(1120px, 100% - 32px); margin-inline: auto; }

h1, h2, h3, p { margin: 0; }
h2 {
  font: 700 clamp(30px, 3.8vw, 46px)/1.08 var(--serif);
  text-align: center; text-wrap: balance;
  color: var(--gold-light);
  background: linear-gradient(180deg, var(--gold-light), var(--gold));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.sub { max-width: 40em; margin: 14px auto 38px; text-align: center; color: var(--muted); }
.band { position: relative; padding: 84px 0; }

/* A thin gold line with a star in its middle: under a heading, over the foot. */
.orn { width: 230px; max-width: 62%; height: 16px; margin: 16px auto 0; }
.orn__line { fill: none; stroke: var(--gold-line); stroke-width: 1; }
.orn__dot { fill: var(--gold); opacity: .7; }
.orn__star { fill: var(--gold); }

/* ───────── the top line: what this is, and the language ───────── */

.top { position: absolute; z-index: 3; top: 0; left: 0; right: 0; padding-top: 20px; }
.top__row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.chip {
  display: inline-block; padding: 6px 14px;
  border: 1px solid rgba(242, 180, 90, .45); border-radius: 999px; background: rgba(7, 15, 36, .35);
  color: var(--gold-light); font: 500 13px/1.3 var(--sans); letter-spacing: .04em;
}
.lang { display: inline-flex; padding: 3px; border: 1px solid var(--gold-line); border-radius: 999px; background: rgba(7, 15, 36, .45); }
.lang a {
  padding: 5px 12px; border-radius: 999px;
  color: var(--muted); font: 600 12px/1.2 var(--sans); letter-spacing: .1em; text-decoration: none;
}
.lang a:hover { color: var(--gold-light); }
.lang a[aria-current="true"] { background: linear-gradient(180deg, var(--gold-light), var(--gold)); color: var(--ink); }

/* ───────── the first screen: the sky, the wheel, the cat, the way to the store ───────── */

.hero {
  position: relative; overflow: hidden; padding-top: 92px;
  background:
    radial-gradient(48% 62% at 78% 46%, rgba(242, 180, 90, .14), transparent 70%),
    radial-gradient(50% 60% at 8% 0%, rgba(62, 52, 133, .55), transparent 70%),
    radial-gradient(40% 50% at 100% 100%, rgba(31, 43, 99, .5), transparent 70%),
    linear-gradient(180deg, var(--night) 0%, var(--night-deep) 100%);
}
.sky, .sky i { position: absolute; inset: 0; pointer-events: none; }
.sky__near { background-image: var(--stars-near); background-size: 380px 380px; animation: twinkle 5.5s ease-in-out infinite; }
.sky__far { background-image: var(--stars-far); background-size: 540px 540px; animation: twinkle 8s ease-in-out -3s infinite; }
/* A star falls across the sky now and then. */
.sky i.sky__fall {
  inset: 14% auto auto 62%; width: 150px; height: 2px; border-radius: 2px; opacity: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 227, 163, .95));
  animation: fall 12s linear 3s infinite;
}
@keyframes twinkle { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes fall {
  0% { opacity: 0; transform: translate3d(0, 0, 0) rotate(155deg); }
  1.5% { opacity: 1; }
  7% { opacity: 0; transform: translate3d(-380px, 178px, 0) rotate(155deg); }
  100% { opacity: 0; transform: translate3d(-380px, 178px, 0) rotate(155deg); }
}

.hero__grid { position: relative; display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: end; }
.hero__text { padding-bottom: 70px; }
.logo { width: min(500px, 100%); filter: drop-shadow(0 6px 22px rgba(242, 180, 90, .22)); }
.hero__line { margin: 22px 0 14px; font: 600 clamp(26px, 3.3vw, 40px)/1.15 var(--serif); color: var(--gold-light); text-wrap: balance; }
.hero__lead { max-width: 33em; margin-bottom: 26px; font-size: 17px; }
/* Google's badge is shown as Google drew it, with room around it. */
.play { display: inline-block; border-radius: 12px; transition: transform .25s ease, filter .25s ease; }
.play img { height: 66px; width: auto; }
.play:hover { transform: translateY(-2px); filter: drop-shadow(0 10px 22px rgba(242, 180, 90, .28)); }
.hero__note { margin-top: 12px; color: var(--muted); font-size: 13px; }

.hero__art { position: relative; width: 100%; max-width: 540px; margin-left: auto; }
.hero__halo {
  position: absolute; left: -22%; top: -24%; width: 144%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(242, 180, 90, .3), rgba(242, 180, 90, .09) 56%, transparent 74%);
  animation: breathe 6s ease-in-out infinite;
}
/* The zodiac's wheel turns slowly behind the cat. Its lower part is cut off where the cat's robe hides the cut,
   and the cat's own lower edge fades out in the picture itself (site_build.py). (Not a mask: a mask over
   something that turns is redrawn at every step, which a phone cannot keep up with.) */
.hero__wheel { position: absolute; left: -7%; top: -12%; width: 114%; height: 92%; overflow: hidden; opacity: .62; }
.hero__wheel img { width: 100%; animation: turn 200s linear infinite; }
@keyframes turn { to { transform: rotate(360deg); } }
@keyframes breathe { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.05); opacity: .8; } }

/* The cat: its picture, and over it the app's own lids — both for a blink, one for a wink. Seven seconds round:
   a quick blink at the second second, a slow wink at the fifth, with a glint by the eye. */
.cat { position: relative; }
.cat__body { width: 100%; }
.cat__lid { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; }
.cat__lid--blink-half { animation: blink-half 7s infinite; }
.cat__lid--blink { animation: blink-shut 7s infinite; }
.cat__lid--wink-half { animation: wink-half 7s infinite; }
.cat__lid--wink { animation: wink-shut 7s infinite; }
@keyframes blink-half { 0%, 29.99% { opacity: 0; } 30%, 30.89% { opacity: 1; } 30.9%, 32.59% { opacity: 0; } 32.6%, 33.49% { opacity: 1; } 33.5%, 100% { opacity: 0; } }
@keyframes blink-shut { 0%, 30.89% { opacity: 0; } 30.9%, 32.59% { opacity: 1; } 32.6%, 100% { opacity: 0; } }
@keyframes wink-half { 0%, 69.99% { opacity: 0; } 70%, 71.19% { opacity: 1; } 71.2%, 77.99% { opacity: 0; } 78%, 79.19% { opacity: 1; } 79.2%, 100% { opacity: 0; } }
@keyframes wink-shut { 0%, 71.19% { opacity: 0; } 71.2%, 77.99% { opacity: 1; } 78%, 100% { opacity: 0; } }
.cat__spark {
  position: absolute; left: 68.5%; top: 27.5%; width: 7.5%; aspect-ratio: 1; opacity: 0;
  background: #FFF4D6; clip-path: var(--star); animation: wink-spark 7s infinite;
}
@keyframes wink-spark {
  0%, 71% { opacity: 0; transform: scale(.2) rotate(0); }
  74% { opacity: 1; transform: scale(1) rotate(40deg); }
  80%, 100% { opacity: 0; transform: scale(.3) rotate(90deg); }
}

/* The Moon's eight faces close the first screen. */
.moons { position: relative; display: flex; align-items: center; justify-content: center; gap: clamp(8px, 2vw, 22px); padding: 6px 16px 34px; }
.moons img { width: clamp(30px, 5vw, 52px); border-radius: 50%; box-shadow: 0 0 14px rgba(242, 180, 90, .3); }
.moons::before, .moons::after { content: ""; flex: 1; max-width: 230px; height: 1px; background: linear-gradient(90deg, transparent, var(--gold-line)); }
.moons::after { transform: scaleX(-1); }

/* ───────── a line of the sections' names, running slowly ───────── */

.ticker { overflow: hidden; padding: 13px 0; border-block: 1px solid rgba(242, 180, 90, .2); background: rgba(16, 29, 60, .55); }
.ticker__run { display: flex; width: max-content; animation: ticker 70s linear infinite; }
.ticker__run span {
  display: inline-flex; align-items: center; gap: 26px; padding-right: 26px; white-space: nowrap;
  color: var(--gold-light); font: 600 17px/1 var(--serif); letter-spacing: .14em; text-transform: uppercase;
}
.ticker__run span::after { content: ""; width: 9px; height: 9px; background: var(--gold); clip-path: var(--star); }
@keyframes ticker { to { transform: translateX(-50%); } }

/* ───────── the film ───────── */

.film { background: radial-gradient(46% 40% at 50% 58%, rgba(62, 52, 133, .32), transparent 72%); }
.film__frame {
  margin-inline: auto; overflow: hidden; border: 1px solid transparent; border-radius: 22px;
  background: linear-gradient(#000, #000) padding-box,
    linear-gradient(135deg, var(--gold-light), rgba(242, 180, 90, .18) 34%, rgba(242, 180, 90, .18) 66%, var(--gold)) border-box;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .5), 0 0 60px rgba(242, 180, 90, .1);
}
.film__frame--wide { max-width: 960px; aspect-ratio: 16 / 9; }
.film__frame--tall { display: none; max-width: 330px; aspect-ratio: 9 / 16; }
.film__frame video { width: 100%; height: 100%; object-fit: cover; }
/* The deck and the crystal ball stand by the heading, swaying a little. */
.deco { position: absolute; z-index: 1; top: 34px; width: 168px; pointer-events: none; animation: sway 9s ease-in-out infinite; }
.deco--cards { left: max(18px, 50% - 640px); }
.deco--ball { right: max(18px, 50% - 640px); width: 184px; animation-delay: -4.5s; }
@keyframes sway { 0%, 100% { transform: translateY(0) rotate(-3deg); } 50% { transform: translateY(-10px) rotate(2deg); } }

/* ───────── the fifteen sections ───────── */

.sections { background: linear-gradient(180deg, transparent, rgba(11, 22, 48, .9) 30%, rgba(11, 22, 48, .9) 70%, transparent); }
.cards { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; }
.card {
  position: relative; overflow: hidden; aspect-ratio: 4 / 5;
  background: var(--surface); border: 1px solid var(--hairline); border-radius: 18px;
  transition: transform .5s cubic-bezier(.2, .7, .2, 1), border-color .3s ease, box-shadow .3s ease;
}
.card img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s cubic-bezier(.2, .7, .2, 1); }
.card__text {
  position: absolute; inset: auto 0 0 0; padding: 52px 14px 14px;
  background: linear-gradient(180deg, transparent, rgba(7, 15, 36, .9) 58%);
}
.card h3 { margin-bottom: 3px; font: 700 21px/1.1 var(--serif); color: var(--text); }
.card p { font-size: 12.5px; line-height: 1.35; }
@media (hover: hover) {
  .card:hover { transform: translateY(-5px); border-color: rgba(242, 180, 90, .55); box-shadow: 0 18px 40px rgba(0, 0, 0, .45), 0 0 26px rgba(242, 180, 90, .14); }
  .card:hover img { transform: scale(1.06); }
  .card:hover h3 { color: var(--gold-light); }
}

/* ───────── three plain things about the app ───────── */

.points__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.point {
  position: relative; padding: 28px 24px 26px; border: 1px solid var(--hairline); border-radius: 20px;
  background: radial-gradient(120% 90% at 0% 0%, rgba(62, 52, 133, .3), transparent 62%), rgba(16, 29, 60, .6);
}
.point__sign {
  display: grid; place-items: center; width: 46px; height: 46px; margin-bottom: 16px;
  border: 1px solid rgba(242, 180, 90, .55); border-radius: 50%; color: var(--gold-light);
  box-shadow: 0 0 22px rgba(242, 180, 90, .14);
}
.point__sign svg { width: 24px; height: 24px; }
.point h3 { margin-bottom: 10px; font: 700 25px/1.12 var(--serif); color: var(--gold-light); }
.point p { font-size: 15px; }

/* ───────── the beta test ───────── */

.beta { padding-top: 12px; }
.beta__box {
  position: relative; display: grid; grid-template-columns: 280px 1fr; gap: 44px; align-items: center; padding: 42px 46px;
  border: 1px solid rgba(242, 180, 90, .34); border-radius: 26px;
  background: radial-gradient(70% 120% at 0% 50%, rgba(62, 52, 133, .42), transparent 70%), var(--surface);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .35);
}
/* Two glints on the box's corners. */
.beta__box::before, .beta__box::after { content: ""; position: absolute; background: var(--gold-light); clip-path: var(--star); animation: glint 4s ease-in-out infinite; }
.beta__box::before { top: -13px; right: 54px; width: 26px; height: 26px; }
.beta__box::after { bottom: -9px; left: 46px; width: 18px; height: 18px; animation-delay: -2s; }
@keyframes glint { 0%, 100% { opacity: .9; transform: scale(1) rotate(0); } 50% { opacity: .35; transform: scale(.7) rotate(45deg); } }
.beta__cat { filter: drop-shadow(0 16px 26px rgba(0, 0, 0, .45)); }
.beta h2 { text-align: left; }
.beta__text > p { margin: 14px 0 18px; max-width: 36em; }
.steps { list-style: none; counter-reset: step; margin: 0 0 24px; padding: 0; }
.steps li { position: relative; counter-increment: step; margin: 12px 0; padding-left: 46px; min-height: 32px; display: flex; align-items: center; }
.steps li::before {
  content: counter(step); position: absolute; left: 0; top: 50%; width: 32px; height: 32px; margin-top: -16px;
  border: 1px solid rgba(242, 180, 90, .6); border-radius: 50%;
  color: var(--gold-light); font: 700 18px/30px var(--serif); text-align: center;
}

/* ───────── the foot ───────── */

.foot { padding: 28px 0 52px; color: var(--muted); font-size: 13px; }
.foot .orn { margin: 0 auto 34px; }
.foot p { max-width: 64em; }
.foot__warn { margin-bottom: 18px; color: var(--text-2); font-size: 14px; }
.foot__row { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
.foot__links { display: flex; flex-wrap: wrap; gap: 8px 24px; }
.foot__links a { font-weight: 500; font-size: 14px; }

/* ───────── parts of the page come up as they are scrolled to; the first screen — when the opening leaves ───────── */

/* (An animation that ends and lets go, not a transition: a card's own lift under the pointer stays its own.) */
@keyframes come-up { from { opacity: 0; transform: translateY(22px); } }
.js .reveal { opacity: 0; }
.js .reveal.is-in { opacity: 1; animation: come-up .7s cubic-bezier(.2, .7, .2, 1) backwards; }
.no-app .reveal { opacity: 1; }
.js .cards .reveal.is-in:nth-child(5n + 2) { animation-delay: .07s; }
.js .cards .reveal.is-in:nth-child(5n + 3) { animation-delay: .14s; }
.js .cards .reveal.is-in:nth-child(5n + 4) { animation-delay: .21s; }
.js .cards .reveal.is-in:nth-child(5n + 5) { animation-delay: .28s; }
.js .points .reveal.is-in:nth-child(2) { animation-delay: .1s; }
.js .points .reveal.is-in:nth-child(3) { animation-delay: .2s; }

/* The first screen comes in when the opening leaves, piece by piece: the wheel spins into place and the light
   behind it swells, the name grows out of the dark, the cat rises, the lines come up one after another, the
   moons pop out in a row, the running line fades in.
   For the passage to run without a stumble: (1) until then the first screen is not hidden — it lies whole and
   already drawn under the opening, with its own motions held, so that at the moment of passage nothing has to
   be drawn or unpacked for the first time; (2) each piece that will move has a sheet of its own beforehand;
   (3) the pieces move by shifting, turning and fading only — no blur, no shadow that is redrawn on the way;
   (4) they start when the opening is all but gone, not under it. */
.js:not(.loaded) .hero *, .js:not(.loaded) .ticker__run { animation-play-state: paused; }
.js .top:not(.doc-top) .top__row > *, .js .hero__text > *, .js .hero__halo, .js .hero__wheel img, .js .cat,
.js .moons img { will-change: transform, opacity; }
@keyframes in-up { from { opacity: 0; transform: translateY(32px); } }
@keyframes in-down { from { opacity: 0; transform: translateY(-20px); } }
@keyframes in-name { from { opacity: 0; transform: translateY(20px) scale(.86); } }
@keyframes in-wheel { from { transform: scale(.45) rotate(-90deg); } to { transform: none; } }
@keyframes turn-wheel { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes in-swell { from { opacity: 0; transform: scale(.25); } }
@keyframes in-cat { from { opacity: 0; transform: translateY(90px) scale(.9); } }
@keyframes in-moon { from { opacity: 0; transform: scale(0) rotate(-140deg); } }
@keyframes in-fade { from { opacity: 0; } }
.js.loaded .top:not(.doc-top) .top__row > * { animation: in-down .7s cubic-bezier(.2, .7, .2, 1) .5s backwards; }
.js.loaded .top:not(.doc-top) .top__row > :nth-child(2) { animation-delay: .6s; }
/* (The wheel itself spins into place inside its cut-off frame; the frame only fades in — a frame that turned
   would show its straight cut.) */
.js.loaded .hero__wheel { animation: in-fade 1s ease .4s backwards; }
.js.loaded .hero__wheel img { animation: in-wheel 1.5s cubic-bezier(.16, .84, .3, 1) .4s backwards, turn-wheel 200s linear 1.9s infinite; }
.js.loaded .hero__halo { animation: in-swell 1.4s cubic-bezier(.16, .84, .3, 1) .4s backwards, breathe 6s ease-in-out 1.8s infinite; }
.js.loaded .cat { animation: in-cat 1.1s cubic-bezier(.2, .9, .3, 1.12) .65s backwards; }
.js.loaded .hero__text > * { animation: in-up .8s cubic-bezier(.2, .7, .2, 1) backwards; }
.js.loaded .hero__text > :nth-child(1) { animation: in-name 1s cubic-bezier(.2, .8, .2, 1.1) .5s backwards; }
.js.loaded .hero__text > :nth-child(2) { animation-delay: .77s; }
.js.loaded .hero__text > :nth-child(3) { animation-delay: .89s; }
.js.loaded .hero__text > :nth-child(4) { animation-delay: 1.01s; }
.js.loaded .hero__text > :nth-child(5) { animation-delay: 1.13s; }
.js.loaded .moons img { animation: in-moon .6s cubic-bezier(.2, .9, .3, 1.3) backwards; }
.js.loaded .moons img:nth-child(1) { animation-delay: 1.2s; }
.js.loaded .moons img:nth-child(2) { animation-delay: 1.27s; }
.js.loaded .moons img:nth-child(3) { animation-delay: 1.34s; }
.js.loaded .moons img:nth-child(4) { animation-delay: 1.41s; }
.js.loaded .moons img:nth-child(5) { animation-delay: 1.48s; }
.js.loaded .moons img:nth-child(6) { animation-delay: 1.55s; }
.js.loaded .moons img:nth-child(7) { animation-delay: 1.62s; }
.js.loaded .moons img:nth-child(8) { animation-delay: 1.69s; }
.js.loaded .ticker { animation: in-fade 1s ease 1.55s backwards; }

/* ───────── the living sky behind the page: stars, numbers and tarot cards drift up its free sides ─────────
   It lies over the sections' own grounds and under everything that is read; app.js makes and scatters the
   pieces, and each carries its place and pace as properties of its own. */

.cosmos { position: fixed; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; }
.hero__grid, .moons, .ticker, .band > .wrap, .foot, .doc-top, .doc-page > main { position: relative; z-index: 2; }
.deco { z-index: 2; }
/* Two slow clouds of light. */
.cosmos::before, .cosmos::after { content: ""; position: absolute; width: 70vmax; height: 70vmax; border-radius: 50%; }
.cosmos::before { left: -30vmax; top: 8%; background: radial-gradient(closest-side, rgba(62, 52, 133, .24), transparent 70%); animation: cloud 46s ease-in-out infinite; }
.cosmos::after { right: -32vmax; top: 44%; background: radial-gradient(closest-side, rgba(242, 180, 90, .09), transparent 70%); animation: cloud 58s ease-in-out -20s infinite reverse; }
@keyframes cloud { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(6vmax, -8vmax, 0) scale(1.15); } }
/* The sky leans a little after the pointer: the near pieces more, the far ones less. */
.cosmos__far, .cosmos__near { position: absolute; inset: 0; transition: transform .9s cubic-bezier(.2, .7, .2, 1); animation: appear 1.8s ease both; }
.cosmos__far { transform: translate3d(calc(var(--mx, 0) * -16px), calc(var(--my, 0) * -10px), 0); }
.cosmos__near { transform: translate3d(calc(var(--mx, 0) * -42px), calc(var(--my, 0) * -26px), 0); }
/* A piece rises from under the screen to over it, swaying aside and turning a little, again and again. */
.cz { position: absolute; top: 0; display: block; opacity: var(--o, 1); animation: drift var(--t, 60s) linear var(--d, 0s) infinite; }
@keyframes drift {
  from { transform: translate3d(0, 106vh, 0) rotate(var(--r0, 0deg)); }
  to { transform: translate3d(var(--sway, 0px), -28vh, 0) rotate(var(--r1, 0deg)); }
}
.cz__star { display: block; width: var(--s); height: var(--s); background: var(--gold-light); clip-path: var(--star); animation: spark var(--tw, 3s) ease-in-out infinite; }
@keyframes spark { 0%, 100% { transform: scale(1) rotate(0); opacity: 1; } 50% { transform: scale(.4) rotate(45deg); opacity: .3; } }
.cz__num {
  display: block; font: 700 var(--s)/1 var(--serif); color: var(--gold-light);
  background: linear-gradient(180deg, var(--gold-light), var(--gold));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
/* A card turns as it rises: its face on one side, its back on the other. The turn is flat — the card narrows
   to an edge and widens again, and at the edge the back is swapped for the face — because a turn in depth makes
   Firefox stumble for a moment when the first such card appears. */
.cz__card { position: relative; display: block; width: var(--s); aspect-ratio: 3 / 5; animation: turn-card var(--f, 14s) infinite; }
.cz__card img { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 7%; }
.cz__back { opacity: 0; animation: show-back var(--f, 14s) step-end infinite; }
@keyframes turn-card {
  0%, 50%, 100% { transform: scaleX(1); animation-timing-function: ease-in; }
  25%, 75% { transform: scaleX(0); animation-timing-function: ease-out; }
}
@keyframes show-back { 0% { opacity: 0; } 25% { opacity: 1; } 75% { opacity: 0; } }
/* A star falls across the whole page now and then, as one does in the first screen. */
.cosmos__fall {
  position: absolute; top: 22%; left: 30%; width: 170px; height: 2px; border-radius: 2px; opacity: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 227, 163, .95));
  animation: fall 17s linear 8s infinite;
}
.cosmos__fall + .cosmos__fall { top: 58%; left: 88%; animation-delay: 15s; animation-duration: 23s; }

/* ───────── the note about what the browser keeps ───────── */

.notice {
  position: fixed; z-index: 80; left: 20px; bottom: 20px; width: min(440px, 100% - 24px);
  display: grid; grid-template-columns: 58px 1fr; gap: 4px 16px; padding: 18px 20px 18px 18px;
  border: 1px solid rgba(242, 180, 90, .42); border-radius: 22px;
  background: radial-gradient(120% 120% at 0% 0%, rgba(62, 52, 133, .62), transparent 65%), rgba(16, 29, 60, .97);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55), 0 0 40px rgba(242, 180, 90, .08);
  animation: note-in .6s cubic-bezier(.2, .9, .3, 1.1) both;
}
.notice[hidden] { display: none; }
.notice.is-leaving { animation: note-out .4s ease forwards; }
@keyframes note-in { from { opacity: 0; transform: translateY(34px) scale(.96); } }
@keyframes note-out { to { opacity: 0; transform: translateY(24px); } }
.notice__moon { grid-row: span 3; width: 58px; animation: sway 7s ease-in-out infinite; }
.notice__title { color: var(--gold-light); font: 700 22px/1.15 var(--serif); }
.notice__text { font-size: 13.5px; line-height: 1.5; }
.notice__row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.btn {
  padding: 9px 18px; border: 1px solid rgba(242, 180, 90, .5); border-radius: 999px; background: transparent;
  color: var(--text); font: 600 13.5px/1.2 var(--sans); cursor: pointer; transition: transform .2s ease, border-color .2s ease, color .2s ease;
}
.btn:hover { transform: translateY(-2px); border-color: var(--gold); color: var(--gold-light); }
.btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.btn--gold { border-color: transparent; background: linear-gradient(180deg, var(--gold-light), var(--gold)); color: var(--ink); }
.btn--gold:hover { color: var(--ink); filter: brightness(1.06); }

/* ───────── the opening, as in the app ───────── */

.intro {
  position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding-bottom: 6vh; cursor: pointer; overflow: hidden;
  background: linear-gradient(180deg, var(--night-deep), var(--night));
}
/* It leaves by an animation of its own, begun when the page says it is ready — a plain fade of a sheet kept ready
   for it — and once gone it is taken off the page altogether (app.js), so that nothing in it goes on moving
   unseen. (Not by a changed value with a transition: Firefox does not apply one to an element that has an
   animation of the same properties waiting.) Without scripts it leaves by itself. */
.intro { will-change: opacity; }
.intro[hidden] { display: none; }
.loaded .intro { pointer-events: none; animation: intro-out .4s ease forwards; }
.loaded .intro__gleam { display: none; }
@keyframes intro-out { to { opacity: 0; } }
html:not(.js) .intro { animation: intro-gone .4s ease 3s forwards; }
@keyframes intro-gone { to { opacity: 0; visibility: hidden; } }
/* It is played on every opening of the page. All of it is drawn in a little over two seconds (app.js lets it go
   at INTRO_MS) — and while the page is still loading after that, it never stands still: the comet keeps
   circling, the sparks twinkle, the gleam runs over the name again and again, the light breathes.
   Everything in it moves by shifting, turning and fading only — what a phone draws smoothly even while the page
   behind is still being put together. Stars spread from the middle outwards, then twinkle. */
.intro__stars {
  position: absolute; inset: 0; background-image: var(--stars-near), var(--stars-far); background-size: 300px 300px, 420px 420px;
  transform-origin: 50% 42%;
  animation: stars-out 1.2s ease-out both, twinkle 4s ease-in-out 1.2s infinite;
}
@keyframes stars-out { from { opacity: 0; transform: scale(.55); } to { opacity: 1; transform: scale(1); } }
.intro__stage { position: relative; width: min(260px, 62vw); aspect-ratio: 1; }
.intro__glow {
  position: absolute; inset: -42%; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(242, 180, 90, .34), rgba(242, 180, 90, .09) 58%, transparent 76%);
  animation: appear .8s ease-out both, breathe 3s ease-in-out .8s infinite;
}
.intro__icon {
  position: absolute; inset: 11.5%; width: 77%; height: 77%; object-fit: cover;
  border: 1.5px solid rgba(255, 227, 163, .9); border-radius: 50%;
  animation: icon-in .6s cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes icon-in { from { opacity: 0; transform: scale(.92); } to { opacity: 1; transform: none; } }
@keyframes appear { from { opacity: 0; } to { opacity: 1; } }
/* A golden orbit draws itself round the cat, a comet at its head; once closed, the comet keeps circling. */
.intro__ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.intro__orbit {
  fill: none; stroke-width: 1.6; stroke-linecap: round;   /* its gold is named on the circle itself, in the page */
  stroke-dasharray: 742; stroke-dashoffset: 742; animation: orbit-draw 1.5s cubic-bezier(.22, .61, .36, 1) .2s forwards;
}
.intro__orbit-far { fill: none; stroke: rgba(242, 180, 90, .35); stroke-width: .6; opacity: 0; animation: appear .6s ease 1s forwards; }
@keyframes orbit-draw { to { stroke-dashoffset: 0; } }
/* (The circling names its own beginning: left to itself it would begin where the leading ended — and stand.) */
.intro__comet { position: absolute; inset: 0; opacity: 0; animation: comet-lead 1.5s cubic-bezier(.22, .61, .36, 1) .2s forwards, comet-round 2.2s linear 1.7s infinite; }
@keyframes comet-round { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
/* Four sparks at the orbit's cardinal points light up as the ring passes them, and go on twinkling. */
.intro__spark {
  position: absolute; width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px; opacity: 0;
  background: var(--gold-light); clip-path: var(--star);
  animation: spark-on .4s ease forwards, spark 2.2s ease-in-out infinite;
}
@keyframes spark-on { from { opacity: 0; transform: scale(0); } to { opacity: 1; transform: scale(1); } }
.intro__spark--n { left: 50%; top: 2.3%; animation-delay: .3s, .7s; }
.intro__spark--e { left: 97.7%; top: 50%; animation-delay: .55s, .95s; }
.intro__spark--s { left: 50%; top: 97.7%; animation-delay: .85s, 1.25s; }
.intro__spark--w { left: 2.3%; top: 50%; animation-delay: 1.25s, 1.65s; }
.intro__comet i {
  position: absolute; left: 50%; top: 4.6%; width: 16px; height: 16px; margin: -8px 0 0 -8px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0 22%, rgba(255, 227, 163, .8) 42%, transparent 72%);
  box-shadow: 0 0 16px 5px rgba(255, 227, 163, .5);
}
@keyframes comet-lead { from { opacity: 1; transform: rotate(0); } to { opacity: 1; transform: rotate(360deg); } }
/* The name is revealed from left to right, and a gleam runs over its letters only. */
.intro__logo { position: relative; width: min(340px, 72vw); margin-top: 36px; }
/* (The reveal is two shifts that cancel out: the window slides in from the left while the name inside it slides
   back by as much — so the name stands still and is uncovered.) */
.intro__wipe { display: block; overflow: hidden; transform: translateX(-101%); animation: wipe-window .8s cubic-bezier(.22, .61, .36, 1) 1s forwards; }
.intro__wipe img { width: 100%; transform: translateX(101%); animation: wipe-name .8s cubic-bezier(.22, .61, .36, 1) 1s forwards; }
@keyframes wipe-window { to { transform: translateX(0); } }
@keyframes wipe-name { to { transform: translateX(0); } }
.intro__gleam {
  position: absolute; inset: 0; overflow: hidden;
  -webkit-mask: url("/img/logo.webp") center / 100% 100% no-repeat; mask: url("/img/logo.webp") center / 100% 100% no-repeat;
}
/* The English page has the English name, and the gleam runs over its letters. */
html[lang="en"] .intro__gleam { -webkit-mask-image: url("/img/logo-en.webp"); mask-image: url("/img/logo-en.webp"); }
.intro__gleam::before {
  content: ""; position: absolute; top: -10%; bottom: -10%; left: -30%; width: 22%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .7), transparent); transform: skewX(-18deg);
  animation: gleam 2.2s ease-in-out 1.7s infinite;
}
@keyframes gleam { 0% { left: -30%; } 36%, 100% { left: 112%; } }
.intro__tag {
  margin-top: 16px; color: var(--text-2); font: 500 12px/1.4 var(--sans); letter-spacing: .22em; text-align: center;
  opacity: 0; animation: rise .4s ease 1.9s forwards;
}
@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ───────── the language, asked once ───────── */

.chooser {
  position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: 20px;
  background: rgba(4, 9, 24, .74); backdrop-filter: blur(6px);
  animation: appear .35s ease both;
}
.chooser[hidden] { display: none; }
.chooser__card {
  width: min(400px, 100%); padding: 0 26px 28px; text-align: center;
  border: 1px solid rgba(242, 180, 90, .42); border-radius: 26px;
  background: radial-gradient(120% 80% at 50% 0%, rgba(62, 52, 133, .6), transparent 70%), var(--surface);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
  animation: pop .45s cubic-bezier(.2, .9, .3, 1.15) both;
}
@keyframes pop { from { opacity: 0; transform: translateY(18px) scale(.96); } to { opacity: 1; transform: none; } }
.chooser__cat { width: 150px; margin: -62px auto 8px; filter: drop-shadow(0 12px 20px rgba(0, 0, 0, .5)); }
.chooser__title span { display: block; }
.chooser__title span:first-child { color: var(--gold-light); font: 700 31px/1.1 var(--serif); }
.chooser__title span:last-child { margin-top: 6px; color: var(--muted); font-size: 14px; }
.chooser__row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 22px; }
.chooser__btn {
  padding: 13px 10px; border: 1px solid rgba(242, 180, 90, .45); border-radius: 14px; background: rgba(7, 15, 36, .5);
  color: var(--text); font: 600 16px/1.2 var(--sans); text-decoration: none; transition: transform .2s ease, border-color .2s ease;
}
.chooser__btn:hover { transform: translateY(-2px); border-color: var(--gold); color: var(--gold-light); }
.chooser__btn.is-guess { border-color: transparent; background: linear-gradient(180deg, var(--gold-light), var(--gold)); color: var(--ink); }
.chooser__btn.is-guess:hover { color: var(--ink); }

/* ───────── a document's page ───────── */

.doc-wrap { width: min(760px, 100% - 32px); }
.doc-top { position: static; padding-top: 26px; }
.doc-home { display: inline-block; border-radius: 8px; }
.doc-home img { width: 190px; }
.doc { padding: 30px 0 64px; }
.doc h1 {
  margin-bottom: 10px; font: 700 clamp(32px, 5vw, 46px)/1.08 var(--serif); text-wrap: balance;
  color: var(--gold-light);
  background: linear-gradient(180deg, var(--gold-light), var(--gold));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.doc h2 {
  margin: 44px 0 12px; font-size: 27px; line-height: 1.15; text-align: left;
  background: none; -webkit-text-fill-color: currentColor;
}
.doc p { margin: 12px 0; }
.doc ul { margin: 12px 0; padding-left: 1.25em; }
.doc li { margin: 8px 0; padding-left: 2px; }
.doc li::marker { color: var(--gold); }
.doc strong { color: var(--text); font-weight: 600; }
.doc h1 + p { color: var(--muted); font-size: 14px; }
.doc-toc { margin: 28px 0 8px; padding: 18px 24px; background: rgba(16, 29, 60, .6); border: 1px solid var(--hairline); border-radius: 16px; }
.doc-toc ol { margin: 0; padding-left: 1.5em; columns: 2; column-gap: 36px; }
.doc-toc li { margin: 5px 0; break-inside: avoid; font-size: 14.5px; }
.doc-toc li::marker { color: var(--muted); }
.doc-toc a { text-decoration: none; }
.doc-toc a:hover { text-decoration: underline; }

/* ───────── where the till sends a person back after paying (/pay/ok/, /pay/fail/) ───────── */
.pay-result { text-align: center; padding: 56px 0 80px; }
.pay-result__moon { display: block; margin: 0 auto 18px; width: 112px; height: 112px; filter: drop-shadow(0 0 22px rgba(242, 180, 90, .35)); }
.doc.pay-result h1 + p { color: var(--text); font-size: 17px; max-width: 520px; margin: 14px auto; }
.pay-result__note { color: var(--muted); font-size: 14px; }

/* ───────── the landing's band of the arcana: seven cards leading to their pages, and to all 22 ───────── */
.arcana-row { list-style: none; margin: 30px 0 26px; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; }
.arcana-row li { width: calc((100% - 6 * 14px) / 7); max-width: 150px; }
.arcana-row a { display: block; text-align: center; text-decoration: none; color: var(--text); transition: transform .3s ease; }
.arcana-row a:hover { transform: translateY(-6px) rotate(-1.5deg); }
.arcana-row img { display: block; width: 100%; height: auto; margin-bottom: 8px; border-radius: 10px;
  box-shadow: 0 14px 30px rgba(0, 0, 0, .45), 0 0 0 1px rgba(242, 180, 90, .3); }
.arcana-row b { display: block; color: var(--gold-light); font-size: 14px; }
.arcana-row span { font-size: 13px; }
.arcana-band__more { text-align: center; }
.arcana-band__more .btn { display: inline-block; padding: 12px 26px; font-size: 15px; text-decoration: none; }

/* ───────── the arcana: a page for each of the 22 and their list (site_build.py, arcana) ───────── */
.arcana__kicker { margin-bottom: 6px; color: var(--muted); font: 600 12.5px/1.3 var(--sans); letter-spacing: .14em; text-transform: uppercase; }
.arcana__top { display: flex; gap: 28px; align-items: center; margin: 22px 0 6px; }
.arcana__card { width: 210px; height: auto; flex: none; border-radius: 14px; box-shadow: 0 18px 40px rgba(0, 0, 0, .45), 0 0 0 1px rgba(242, 180, 90, .35); }
.arcana__essence { margin: 0 0 12px; font: italic 600 clamp(21px, 3vw, 26px)/1.3 var(--serif); color: var(--text); }
.arcana__keys { color: var(--gold-light); font-size: 14px; letter-spacing: .02em; }
.arcana__intro { margin: 14px 0 26px; color: var(--text-2); }
.arcana__cta { margin: 44px 0 10px; padding: 24px 26px; text-align: center; background: rgba(16, 29, 60, .6); border: 1px solid var(--hairline); border-radius: 18px; }
.arcana__cta-title { margin: 0 0 6px; font: 700 26px/1.2 var(--serif); color: var(--gold-light); }
.arcana__cta p { margin: 6px 0 16px; }
.arcana__nav { display: flex; justify-content: space-between; gap: 12px; margin-top: 30px; font-weight: 500; font-size: 14.5px; }
.arcana__nav a { text-decoration: none; }
.arcana__nav a:hover { text-decoration: underline; }
.arcana__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 22px 18px; margin: 0; padding: 0; list-style: none; }
.arcana__grid li { margin: 0; padding: 0; }
.arcana__grid a { display: block; text-align: center; text-decoration: none; color: var(--text); transition: transform .2s ease; }
.arcana__grid a:hover { transform: translateY(-3px); }
.arcana__grid img { display: block; width: 100%; height: auto; margin-bottom: 8px; border-radius: 10px; box-shadow: 0 0 0 1px rgba(242, 180, 90, .3); }
.arcana__grid b { display: block; color: var(--gold-light); font-size: 15px; }
.arcana__grid span { display: block; font-size: 14px; hyphens: auto; }

/* ───────── narrower screens ───────── */

@media (max-width: 1180px) {
  .deco { top: 26px; width: 120px; }
  .deco--ball { width: 132px; }
}

@media (max-width: 980px) {
  .cards { grid-template-columns: repeat(3, 1fr); }
  .js .cards .reveal.is-in:nth-child(n) { animation-delay: 0s; }
  .points__grid { grid-template-columns: 1fr; }
  .beta__box { grid-template-columns: 200px 1fr; gap: 28px; padding: 32px 28px; }
}

@media (max-width: 760px) {
  .band { padding: 60px 0; }
  .top { padding-top: 14px; }
  .chip { padding: 5px 11px; font-size: 11.5px; }
  .hero { padding-top: 72px; }
  .hero__grid { grid-template-columns: 1fr; gap: 26px; text-align: center; }
  .hero__text { padding-bottom: 0; }
  .logo { margin-inline: auto; width: min(380px, 92%); }
  .hero__lead { margin-inline: auto; font-size: 16px; }
  .hero__art { max-width: 330px; margin-inline: auto; }
  .moons { padding: 4px 12px 28px; }
  .ticker__run span { font-size: 15px; gap: 20px; padding-right: 20px; }
  /* The deck and the ball move up over the heading, smaller. */
  .film { padding-top: 104px; }
  .deco { top: 20px; width: 76px; }
  .deco--cards { left: 18px; }
  .deco--ball { right: 18px; width: 82px; }
  .film__frame--wide { display: none; }
  .film__frame--tall { display: block; }
  .beta__box { grid-template-columns: 1fr; gap: 18px; padding: 30px 22px 32px; text-align: center; }
  .beta__cat { width: 170px; margin-inline: auto; }
  .beta h2 { text-align: center; }
  .beta__text > p { margin-inline: auto; }
  .steps li { text-align: left; }
  .foot__row { flex-direction: column-reverse; align-items: flex-start; }
  .doc-toc ol { columns: 1; }
  /* A phone draws shifting, turning and fading smoothly, and little else. So here nothing that moves is blurred
     or shadowed, the orbit fades in instead of being drawn stroke by stroke, the gleam does not run, the far
     stars and the clouds of light stand still. */
  .intro__gleam { display: none; }
  .intro__orbit { stroke-dashoffset: 0; opacity: 0; animation: appear .9s ease .3s forwards; }
  .js.loaded .hero__text > :nth-child(1) { animation-name: in-up; }
  .logo, .beta__cat, .chooser__cat { filter: none; }
  .cosmos::before, .cosmos::after { animation: none; }
  .sky__far, .sky i.sky__fall, .cosmos__fall { display: none; }
  .chooser { backdrop-filter: none; background: rgba(4, 9, 24, .88); }
}

@media (max-width: 560px) {
  .arcana-row { gap: 12px 10px; }
  .arcana-row li { width: calc((100% - 3 * 10px) / 4); }
  .arcana__top { flex-direction: column; text-align: center; }
  .arcana__card { width: 180px; }
  .arcana__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 10px; }
  .arcana__grid span { font-size: 13px; }
  .cards { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .card h3 { font-size: 19px; }
  /* Fifteen cards in two columns leave one alone: it takes the whole row. */
  .card:last-child { grid-column: span 2; aspect-ratio: 8 / 5; }
  .card:last-child img { object-position: 50% 12%; }
  .notice { left: 12px; right: 12px; bottom: 12px; width: auto; grid-template-columns: 46px 1fr; gap: 4px 12px; padding: 16px; }
  .notice__moon { width: 46px; }
  .notice__title { font-size: 20px; }
}

/* ───────── for those who asked their device for less movement: everything is in place and still ───────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .intro { display: none; }
  .js .reveal { opacity: 1; }
  .sky i.sky__fall, .cosmos__fall { display: none; }
}
