/* Extensions (extensions.html): the orbit, the list by kind, and the panel one
   opens into. extensions.js builds the orbit and the panel from the page's own
   <article class="ext"> blocks, so the text is all in the document and a new
   extension is one more article (site/README.md, "Extensions"). The previews
   in the cards and the panels are v-extensions.*. */

/* The hero spans the window, so the range under it melts into the night at
   the sides instead of stopping at the column's edge. */
.hero.plain { color: var(--ink); padding: calc(var(--bar-h) + 22px) var(--gut) 0; min-height: 0; }
.hero.plain .hero-h { text-shadow: none; font-size: clamp(34px, 3.4vw, 46px); line-height: 1.02; max-width: 12ch; margin: 0 auto 12px; }
.hero.plain .hero-lede { color: var(--ink-2); text-shadow: none; font-size: 16px; line-height: 1.5; max-width: 30ch; margin: 0 auto; }
/* The range sinks only a little as the page moves: the list starts right
   under it, and its first heading must never land on the peaks. */
.hero.plain .range { --range-w: min(1300px, 120vw); --range-top: clamp(0px, 1vw, 12px); margin-bottom: calc(min(1300px, 120vw) * -.07); opacity: .85; transform: translate3d(-50%, calc(var(--sy, 0) * .06px), 0); }
@media (max-width: 640px) { .hero.plain .range { --range-w: 190vw; } }
/* On a phone the circle may use the gutters too: every pixel is a larger card. */
@media (max-width: 759px) { .hero.plain .orbit { width: auto; margin-inline: calc(var(--gut) * -1); } .hero.plain .orbit-mid { padding-inline: var(--gut); } }

/* ---------------------------------------------------------------- The orbit
   Every extension's card going round the app on a flat circle, upright, the
   headline in the middle; on a phone the headline stands above the circle
   and the icon alone is in the middle. Sizes and places are written by
   extensions.js; without scripting this is just the headline, and the list
   below says everything. */
.orbit { position: relative; width: 100%; max-width: 1180px; margin: 0 auto; }
.js .orbit { height: var(--oh, 760px); }
.orbit-mid { position: relative; z-index: 3; text-align: center; padding-top: 50px; }
.js .orbit:not(.small) .orbit-mid { position: absolute; left: 50%; top: 50%; width: 340px; padding: 0; transform: translate(-50%, -50%); }
.orbit-icon {
  width: 58px; height: 58px; margin: 0 auto 18px; border-radius: 14px;
  box-shadow: 0 0 0 1px rgba(190, 225, 255, .2), 0 22px 60px -14px rgba(47, 123, 255, .9);
}
.js .orbit.small .orbit-icon { display: none; }
.orbit-core { display: none; }
.js .orbit.small .orbit-core {
  display: block; position: absolute; z-index: 1; width: 60px; height: 60px; transform: translate(-50%, -50%); border-radius: 14px;
  box-shadow: 0 0 0 1px rgba(190, 225, 255, .2), 0 18px 50px -12px rgba(47, 123, 255, .9);
}
.orbit-core img { width: 100%; height: 100%; border-radius: inherit; }
/* The light the middle gives off, filling the circle. */
.js .orbit::before {
  content: ""; position: absolute; left: var(--cx, 50%); top: var(--cy, 50%); z-index: 0; width: var(--glow, 900px); height: var(--glow, 900px);
  transform: translate(-50%, -50%); pointer-events: none;
  background: radial-gradient(closest-side, rgba(47, 123, 255, .2), rgba(47, 123, 255, .06) 50%, transparent);
}
.orbit-ring {
  position: absolute; left: var(--cx, 50%); top: var(--cy, 50%); z-index: 1; transform: translate(-50%, -50%);
  border-radius: 50%; border: 1px solid rgba(190, 225, 255, .12); pointer-events: none;
}

/* A card: the extension at work, its name over the foot of the picture. */
.oc {
  position: absolute; left: 0; top: 0; z-index: 2; display: block; width: var(--cw, 188px); height: var(--ch, 139px);
  border-radius: calc(var(--cw, 188px) * .075); overflow: hidden; text-decoration: none; color: var(--ink);
  background: #090d15; border: 1px solid rgba(190, 225, 255, .16);
  box-shadow: 0 26px 50px -24px rgba(0, 0, 0, .95), 0 0 50px -22px rgba(47, 123, 255, .6);
  transition: border-color .3s ease, box-shadow .3s ease, opacity .4s ease;
  will-change: transform; -webkit-tap-highlight-color: transparent;
}
.oc-thumb, .ext-thumb {
  background: radial-gradient(80% 90% at 50% 40%, rgba(47, 123, 255, .2), transparent 75%), #0a0e16;
}
.oc-thumb { position: absolute; inset: 0; overflow: hidden; }
.oc-title {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 26px 11px 9px;
  font: 600 max(11px, calc(var(--cw, 188px) * .074))/1.2 var(--display); letter-spacing: -.005em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  background: linear-gradient(180deg, rgba(5, 8, 14, 0), rgba(5, 8, 14, .86) 52%, rgba(5, 8, 14, .96));
}
.oc-soon {
  position: absolute; top: 7px; right: 7px; z-index: 2; padding: 1px 8px; border-radius: 999px;
  font: 600 10.5px/1.5 var(--display); color: var(--ink); background: rgba(5, 8, 14, .78); border: 1px solid var(--rim);
}
.oc.up { z-index: 4; }
.oc:hover, .oc:focus-visible, .oc.up, .oc.lit {
  border-color: rgba(143, 200, 255, .55);
  box-shadow: 0 30px 60px -24px rgba(0, 0, 0, .95), 0 0 60px -14px rgba(90, 166, 255, .9);
}
.oc.dim { opacity: .3; }
.oc:focus-visible { outline: 2px solid var(--ice); outline-offset: 3px; }
/* Small cards let a long name take two lines. */
.orbit.small .oc-title { padding: 16px 6px 5px; font-size: 10.5px; line-height: 1.15; white-space: normal; }
.orbit.small .oc-soon { display: none; }

/* The kinds, under the orbit: resting on one lights its cards. */
.kinds { display: none; flex-wrap: wrap; justify-content: center; gap: 8px; margin: clamp(10px, 2vw, 20px) auto 0; padding: 0; list-style: none; }
.js .kinds { display: flex; }
.kinds a {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 15px; border-radius: 999px; text-decoration: none;
  font: 600 14.5px/1.2 var(--display); color: var(--ink-2); border: 1px solid var(--rim); background: var(--frost);
  transition: color .2s ease, border-color .2s ease, background-color .2s ease;
}
.kinds a span { color: var(--ink-3); font-weight: 500; }
.kinds a:hover, .kinds a:focus-visible, .kinds a.lit { color: var(--ink); border-color: rgba(143, 200, 255, .45); background: var(--frost-2); }

/* ---------------------------------------------------------------- The list, kind by kind */
.shelf { padding-top: clamp(80px, 10vw, 130px); }
.kind { max-width: 1000px; margin: 0 auto; padding-top: clamp(44px, 6vw, 72px); scroll-margin-top: calc(var(--bar-h) + 10px); }
.kind:first-child { padding-top: 0; }
.kind > h2 { font-size: clamp(28px, 3.4vw, 40px); letter-spacing: -.02em; line-height: 1.08; }
.kind > p { margin-top: 10px; color: var(--ink-2); font-size: 18px; max-width: 56ch; }
.exts { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 380px), 1fr)); gap: 16px; margin-top: 26px; }

.ext { position: relative; scroll-margin-top: calc(var(--bar-h) + 20px); }
/* The same card as in the orbit, larger, with what it does under its name. */
.ext-card {
  position: relative; display: flex; flex-direction: column; height: 100%; border-radius: 20px; overflow: hidden;
  text-decoration: none; color: var(--ink);
  background: linear-gradient(180deg, rgba(170, 210, 255, .06), rgba(170, 210, 255, .02));
  border: 1px solid var(--rim);
  transition: border-color .25s ease, transform .35s var(--ease), box-shadow .35s var(--ease);
}
.ext-card:hover { border-color: rgba(143, 200, 255, .45); transform: translateY(-3px); box-shadow: 0 30px 60px -30px rgba(0, 0, 0, .9), 0 0 60px -26px rgba(90, 166, 255, .8); }
.ext-thumb { display: none; }
.js .ext-thumb { display: block; position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-bottom: 1px solid var(--line); }
.ext-t { padding: 16px 20px 19px; }
.ext-t h3 { font-size: 20px; line-height: 1.25; letter-spacing: -.01em; }
.ext-t p { margin-top: 4px; color: var(--ink-2); font-size: 15.5px; line-height: 1.45; }
.ext-soon { display: inline-block; margin-left: 8px; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--rim); font: 600 12.5px/1.4 var(--display); color: var(--ink-2); vertical-align: 3px; }

/* Without scripting the whole of every article shows under its card. */
.ext-full { padding: 22px 4px 8px; }
.js .ext-full { display: none; }
.js .xd .ext-full { display: block; padding: 0; }

.ext-more { max-width: 1000px; margin: clamp(60px, 8vw, 100px) auto 0; padding: 28px 0 clamp(80px, 10vw, 130px); border-top: 1px solid var(--line); }
.ext-more h2 { font-size: 24px; }
.ext-more p { margin-top: 8px; color: var(--ink-2); max-width: 62ch; }
.ext-more p + p { margin-top: 10px; }
.ext-more a { color: var(--ink); text-underline-offset: 4px; text-decoration-thickness: 1px; }

/* ---------------------------------------------------------------- The panel
   One <dialog>. Opening an extension moves its article's text and picture in
   and grows the panel out of the planet or card that was pressed. */
.xd {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0;
  background: transparent; color: var(--ink); overflow: hidden;
}
/* The dim behind the panel is a layer of its own, not ::backdrop, so it fades with the panel. */
.xd::backdrop { background: transparent; }
.xd-veil { position: absolute; inset: 0; background: rgba(1, 3, 8, .66); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.xd[open] { display: grid; place-items: center; }
.xd-panel {
  position: relative; width: min(1060px, calc(100vw - 32px)); max-height: min(900px, calc(100dvh - 40px));
  display: flex; flex-direction: column; border-radius: 28px; overflow: hidden;
  background: linear-gradient(180deg, rgba(22, 30, 44, .94), rgba(8, 12, 20, .97));
  border: 1px solid rgba(190, 225, 255, .16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 60px 140px -40px rgba(0, 0, 0, .95), 0 0 120px -40px rgba(47, 123, 255, .5);
  transform-origin: 50% 50%;
}
.xd-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: clamp(22px, 3.4vw, 40px) clamp(20px, 4vw, 48px) clamp(24px, 3vw, 34px); }
.xd-head { padding-right: 48px; }
.xd-head h2 { font-size: clamp(26px, 3.2vw, 36px); letter-spacing: -.02em; line-height: 1.1; }
.xd-head p { margin-top: 4px; color: var(--ink-2); font-size: clamp(16px, 1.5vw, 18px); }
.xd-x {
  position: absolute; top: 18px; right: 18px; z-index: 3; width: 38px; height: 38px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--rim); background: rgba(10, 16, 26, .6); color: var(--ink-2); display: grid; place-items: center;
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.xd-x:hover { color: var(--ink); border-color: rgba(190, 225, 255, .4); }
.xd-x svg { width: 14px; height: 14px; }

/* The picture: its own little night inside the panel. */
.xv-stage {
  position: relative; margin: clamp(20px, 3vw, 30px) calc(clamp(20px, 4vw, 48px) * -1) 0; padding: clamp(26px, 4vw, 44px) clamp(16px, 4vw, 48px);
  background: radial-gradient(60% 70% at 50% 55%, rgba(47, 123, 255, .16), transparent 75%), rgba(0, 0, 0, .22);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}

.ext-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(26px, 4vw, 56px); margin-top: clamp(24px, 3vw, 34px); }
@media (max-width: 760px) { .ext-cols { grid-template-columns: minmax(0, 1fr); } }
.ext-cols h3 { font-size: 19px; letter-spacing: -.005em; }
.ext-what ul { list-style: none; margin: 12px 0 0; padding: 0; }
.ext-what li { position: relative; padding-left: 18px; color: var(--ink-2); font-size: 16px; line-height: 1.55; }
.ext-what li + li { margin-top: 9px; }
.ext-what li::before { content: ""; position: absolute; left: 2px; top: .68em; width: 5px; height: 5px; border-radius: 50%; background: var(--ice); opacity: .7; }
.ext-what li b, .ext-how b { color: var(--ink); font-weight: 600; }
.ext-how ol { list-style: none; margin: 12px 0 0; padding: 0; counter-reset: s; }
.ext-how li { counter-increment: s; position: relative; padding: 0 0 16px 40px; color: var(--ink-2); font-size: 16px; line-height: 1.55; }
.ext-how li::before {
  content: counter(s); position: absolute; left: 0; top: 0; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--frost-2); color: var(--ink); border: 1px solid var(--rim); font: 600 13.5px/1 var(--display);
}
.ext-how li:not(:last-child)::after { content: ""; position: absolute; left: 12.5px; top: 32px; bottom: 6px; width: 1px; background: var(--line); }
.ext-how kbd {
  display: inline-block; min-width: 1.6em; padding: 0 .4em; border-radius: 6px; text-align: center;
  font: 600 .86em/1.6 var(--ui); color: var(--ink); background: var(--frost-2); border: 1px solid var(--rim); border-bottom-width: 2px;
}
.ext-note { margin-top: 2px; color: var(--ink-3); font-size: 14.5px; line-height: 1.5; }
.ext-full .tech { max-width: none; margin-top: 18px; }

.xd-foot {
  flex: none; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px clamp(20px, 4vw, 48px) 16px; border-top: 1px solid var(--line); background: rgba(6, 10, 18, .5);
}
.xd-foot .xd-get { flex: 1; min-width: 0; color: var(--ink-3); font-size: 14.5px; }
.xd-foot .xd-get b { color: var(--ink-2); font-weight: 600; }
.xd-step {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--rim); background: var(--frost); color: var(--ink-2); font: 600 14px/1.2 var(--display);
}
.xd-step:hover { color: var(--ink); border-color: rgba(190, 225, 255, .4); }
.xd-step i { font-style: normal; color: var(--ink-3); font-weight: 500; }
@media (max-width: 560px) {
  .xd-panel { width: 100vw; max-height: 100dvh; height: 100dvh; border-radius: 0; border: 0; }
  .xd-foot .xd-get { flex-basis: 100%; }
  .xd-step { flex: 1; justify-content: center; }
  .xd-step i { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .oc, .ext-card { transition: none; }
}
