/* quvyta.com
 *
 * The family's rules hold here too: shape comes from tone and spacing, never from drawn lines;
 * one accent colour; the half-cell pillar marks what is selected or raised; motion whispers.
 * Every colour is a token below. Dark is the framework's Iris theme; light is its daytime twin.
 */

:root {
  color-scheme: light dark;

  --canvas: #f7f7fc;
  --surface: #edeef8;
  --raised: #e3e5f4;
  --active: #d6d9ef;
  --accent: #4f46e5;
  --accent-strong: #4338ca;
  --on-accent: #ffffff;
  --text: #16172b;
  --dim: #383c80;
  --muted: #595d8e;
  --shade: rgb(22 23 43 / 0.10);

  /* How much of the canvas the three drifting fields are allowed to take. Light keeps less: the
     accent is dark there, so every point it takes is contrast the text loses. The grain is the
     dither that keeps a gradient this shallow from stepping into visible rings. */
  --aura-one: 0.080;
  --aura-two: 0.066;
  --aura-three: 0.055;
  --aura-grain: 0.04;
  --aura-stops:
    var(--accent) 0%,
    color-mix(in oklab, var(--accent) 70%, transparent) 30%,
    color-mix(in oklab, var(--accent) 40%, transparent) 54%,
    color-mix(in oklab, var(--accent) 16%, transparent) 76%,
    color-mix(in oklab, var(--accent) 4%, transparent) 90%,
    transparent 100%;

  --mono: "JetBrains Mono", "Iosevka", "Cascadia Code", "SF Mono", ui-monospace, Menlo, Consolas,
    "DejaVu Sans Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", "Noto Sans", Roboto, "Helvetica Neue", Arial,
    sans-serif;

  --page: 72rem;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --radius: 0.5rem;
  --pillar: 0.3rem;

  --quick: 140ms;
  --calm: 260ms;
}

/* Japanese and Chinese: the same design, with faces that have the glyphs for it. */

html[lang="ja"] {
  --sans: system-ui, -apple-system, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic UI",
    "Yu Gothic", "Noto Sans JP", "Noto Sans CJK JP", Meiryo, sans-serif;
  --mono: "JetBrains Mono", "Cascadia Code", ui-monospace, Menlo, Consolas, "Noto Sans Mono CJK JP",
    "Yu Gothic", Meiryo, monospace;
}

html[lang="zh-Hans"] {
  --sans: system-ui, -apple-system, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
    "Noto Sans SC", "Noto Sans CJK SC", "Source Han Sans SC", sans-serif;
  --mono: "JetBrains Mono", "Cascadia Code", ui-monospace, Menlo, Consolas, "Noto Sans Mono CJK SC",
    "Microsoft YaHei", monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --canvas: #0e0f18;
    --surface: #161826;
    --raised: #202336;
    --active: #2c304a;
    --accent: #818cf8;
    --accent-strong: #a5b4fc;
    --on-accent: #0e0f18;
    --text: #eef2ff;
    --dim: #a5b4fc;
    --muted: #8c91cc;
    --shade: rgb(0 0 0 / 0.35);

    --aura-one: 0.132;
    --aura-two: 0.107;
    --aura-three: 0.086;
    --aura-grain: 0.045;
  }
}

/* Base ------------------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--text);
  font: 400 1.0625rem/1.65 var(--sans);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: var(--accent-strong);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--text);
}

code,
pre,
kbd {
  font-family: var(--mono);
  font-size: 0.92em;
}

:not(pre) > code {
  padding: 0.1em 0.35em;
  border-radius: 0.25rem;
  background: var(--raised);
  color: var(--text);
}

h1,
h2,
h3 {
  font-family: var(--mono);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 0.2rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: var(--gutter);
  top: -4rem;
  z-index: 10;
  padding: 0.5rem 0.9rem;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--mono);
  text-decoration: none;
  border-radius: var(--radius);
}

.skip:focus {
  top: 0.75rem;
}

.wrap {
  width: min(100% - 2 * var(--gutter), var(--page));
  margin-inline: auto;
}

/* The pillar: the family's ▌, half a cell of accent at the left of what is raised. ------------- */

.pillar {
  position: relative;
  padding-left: calc(var(--pillar) + 0.9rem);
}

.pillar::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.12em;
  bottom: 0.12em;
  width: var(--pillar);
  background: var(--accent);
}

/* On a narrow screen the fields cover far more of the text than they do on a wide one: vmax is
 * the tall side there, so each mass is wider than the column it sits behind. They are dimmed to
 * match, which is what keeps the dimmest line above its contrast floor on a phone.
 */
@media (max-width: 48rem) {
  :root {
    --aura-one: 0.055;
    --aura-two: 0.045;
    --aura-three: 0.038;
  }
}

@media (max-width: 48rem) and (prefers-color-scheme: dark) {
  :root {
    --aura-one: 0.09;
    --aura-two: 0.073;
    --aura-three: 0.058;
  }
}

/* The aura: slow, shapeless fields of the accent, the way a lamp moves. ----------------------- *
 *
 * Nothing here is a circle and nothing here has an edge. Each field is three soft gradients
 * lying over each other inside one box, so the mass it makes is lopsided; the three masses
 * drift at speeds that do not divide into each other, so they meet, thicken into one body and
 * part again, never twice in the same place. Only transform is animated: the picture inside a
 * field is painted once and the browser only moves it, which is why there is no blur filter
 * anywhere here. A filter would be recomputed every frame -- measured at four to thirteen
 * frames a second on a machine with no graphics card, against the sixty this keeps.
 *
 * The grain on top is not decoration. A gradient this wide and this shallow cannot cross eight
 * bits of colour smoothly: it steps, and the steps read as rings. A little noise scatters each
 * step across its neighbours and the rings go.
 */

.aura {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
}

.aura span {
  position: absolute;
  display: block;
}

/* Every gradient in every field fades out before the edge of its own box, so no field is ever
 * cut off in a straight line. Each one ends inside the box it lives in.
 */
.aura .one {
  width: 74vmax;
  height: 62vmax;
  left: -20vmax;
  top: -22vmax;
  opacity: var(--aura-one);
  background:
    radial-gradient(33% 32% at 35% 34%, var(--aura-stops)),
    radial-gradient(34% 36% at 64% 52%, var(--aura-stops)),
    radial-gradient(44% 26% at 46% 74%, var(--aura-stops));
}

.aura .two {
  width: 60vmax;
  height: 70vmax;
  right: -18vmax;
  top: 6vmax;
  opacity: var(--aura-two);
  background:
    radial-gradient(40% 28% at 58% 30%, var(--aura-stops)),
    radial-gradient(36% 38% at 38% 58%, var(--aura-stops)),
    radial-gradient(32% 24% at 66% 76%, var(--aura-stops));
}

.aura .three {
  width: 56vmax;
  height: 52vmax;
  left: 18vmax;
  bottom: -20vmax;
  opacity: var(--aura-three);
  background:
    radial-gradient(42% 40% at 44% 58%, var(--aura-stops)),
    radial-gradient(30% 32% at 68% 34%, var(--aura-stops)),
    radial-gradient(26% 28% at 28% 30%, var(--aura-stops));
}

.aura::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: var(--aura-grain);
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n' x='0' y='0' width='100%25' height='100%25'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='180' height='180' filter='url(%23n)'/></svg>");
  background-size: 180px 180px;
}

/* How fast is calm? A mass has to cross its own width in something like half a minute, or the
 * eye reads the page as a still picture -- which is what happened with the first try, where the
 * quickest field moved about three pixels a second and spent most of its time stopped at one end
 * of its travel. Measured on the page: these three are 16 to 19 pixels a second on a 1280 by 800
 * screen, and each crosses its own width -- the span where it is at least half as strong as at
 * its brightest -- in twenty-three to thirty seconds.
 *
 * Each path is a closed loop of eight points around an ellipse, walked at an even pace: there is
 * no end to stop at, no turning round, and because the two axes are different lengths the mass
 * never travels in a straight line. The three periods do not divide into each other, so the
 * fields meet somewhere different every time.
 */
@media (prefers-reduced-motion: no-preference) {
  .aura span {
    will-change: transform;
  }

  .aura .one {
    animation: aura-one 34s linear infinite;
  }

  .aura .two {
    animation: aura-two 47s linear infinite;
  }

  .aura .three {
    animation: aura-three 53s linear infinite;
  }
}

@keyframes aura-one {
  0% { transform: translate3d(0vmax, 0vmax, 0); }
  12.5% { transform: translate3d(2.93vmax, 4.60vmax, 0); }
  25% { transform: translate3d(10vmax, 6.50vmax, 0); }
  37.5% { transform: translate3d(17.07vmax, 4.60vmax, 0); }
  50% { transform: translate3d(20vmax, 0vmax, 0); }
  62.5% { transform: translate3d(17.07vmax, -4.60vmax, 0); }
  75% { transform: translate3d(10vmax, -6.50vmax, 0); }
  87.5% { transform: translate3d(2.93vmax, -4.60vmax, 0); }
  100% { transform: translate3d(0vmax, 0vmax, 0); }
}

@keyframes aura-two {
  0% { transform: translate3d(-0vmax, -0vmax, 0); }
  12.5% { transform: translate3d(-3.22vmax, -6.36vmax, 0); }
  25% { transform: translate3d(-11vmax, -9vmax, 0); }
  37.5% { transform: translate3d(-18.78vmax, -6.36vmax, 0); }
  50% { transform: translate3d(-22vmax, -0vmax, 0); }
  62.5% { transform: translate3d(-18.78vmax, 6.36vmax, 0); }
  75% { transform: translate3d(-11vmax, 9vmax, 0); }
  87.5% { transform: translate3d(-3.22vmax, 6.36vmax, 0); }
  100% { transform: translate3d(-0vmax, 0vmax, 0); }
}

@keyframes aura-three {
  0% { transform: translate3d(0vmax, 0vmax, 0); }
  12.5% { transform: translate3d(3.81vmax, 7.42vmax, 0); }
  25% { transform: translate3d(13vmax, 10.50vmax, 0); }
  37.5% { transform: translate3d(22.19vmax, 7.42vmax, 0); }
  50% { transform: translate3d(26vmax, 0vmax, 0); }
  62.5% { transform: translate3d(22.19vmax, -7.42vmax, 0); }
  75% { transform: translate3d(13vmax, -10.50vmax, 0); }
  87.5% { transform: translate3d(3.81vmax, -7.42vmax, 0); }
  100% { transform: translate3d(0vmax, 0vmax, 0); }
}

/* Header ------------------------------------------------------------------------------------ */

.site-head {
  position: relative;
  padding-block: 1.1rem;
}

.site-head .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font: 700 1.15rem/1 var(--mono);
  color: var(--text);
  text-decoration: none;
  letter-spacing: -0.01em;
}

.brand .mark {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  fill: var(--accent);
  transition: fill var(--quick) ease-out;
}

.brand:hover .mark {
  fill: var(--accent-strong);
}

.brand:hover {
  color: var(--accent-strong);
}

.nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  list-style: none;
}

.nav a {
  position: relative;
  display: block;
  padding: 0.4rem 0.8rem;
  font: 500 0.9rem/1.4 var(--mono);
  color: var(--dim);
  text-decoration: none;
  border-radius: 0.3rem;
  transition: background-color var(--quick) ease-out, color var(--quick) ease-out;
}

.nav a:hover {
  background: var(--raised);
  color: var(--text);
}

.nav a[aria-current] {
  color: var(--text);
}

.nav a[aria-current]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--pillar);
  background: var(--accent);
}

/* The language picker: a disclosure, so it works with no script at all. ----------------------- */

.lang {
  font: 500 0.9rem/1.4 var(--mono);
}

.lang > summary {
  position: relative;
  display: inline-block;
  padding: 0.4rem 0.8rem 0.4rem calc(0.8rem + var(--pillar));
  color: var(--dim);
  border-radius: 0 0.3rem 0.3rem 0;
  cursor: pointer;
  list-style: none;
  transition: background-color var(--quick) ease-out, color var(--quick) ease-out;
}

.lang > summary::-webkit-details-marker {
  display: none;
}

/* The pillar says this is the language, the way it says which tab is open. */
.lang > summary::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.35rem;
  bottom: 0.35rem;
  width: var(--pillar);
  background: var(--accent);
  transition: top var(--quick) ease-out, bottom var(--quick) ease-out;
}

.lang > summary:hover {
  background: var(--raised);
  color: var(--text);
}

.lang[open] > summary {
  color: var(--text);
}

.lang[open] > summary::before {
  top: 0;
  bottom: 0;
}

/* The nine names, in a band the width of the page. Nothing floats and nothing is boxed in. */
.lang > ul {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.35rem;
  margin: 0;
  padding: 0.9rem max(var(--gutter), calc((100% - var(--page)) / 2)) 1.1rem;
  list-style: none;
  background: var(--surface);
}

.lang > ul a {
  position: relative;
  display: block;
  padding: 0.45rem 0.9rem;
  color: var(--dim);
  text-decoration: none;
  border-radius: 0.3rem;
  transition: background-color var(--quick) ease-out, color var(--quick) ease-out;
}

.lang > ul a:hover {
  background: var(--raised);
  color: var(--text);
}

.lang > ul a[aria-current] {
  padding-left: calc(0.9rem + var(--pillar));
  color: var(--text);
}

.lang > ul a[aria-current]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--pillar);
  background: var(--accent);
}

@media (max-width: 40rem) {
  .lang > ul {
    justify-content: flex-start;
  }
}

/* The nine languages on the home page: the same list, laid out to be read. ------------------- */

.langs ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
  padding: 0;
}

.langs a {
  position: relative;
  display: block;
  padding: 0.45rem 0.9rem;
  background: var(--canvas);
  color: var(--dim);
  font: 500 0.95rem/1.4 var(--mono);
  text-decoration: none;
  border-radius: 0.3rem;
  transition: background-color var(--quick) ease-out, color var(--quick) ease-out;
}

.langs a:hover {
  background: var(--raised);
  color: var(--text);
}

.langs a[aria-current] {
  padding-left: calc(0.9rem + var(--pillar));
  color: var(--text);
}

.langs a[aria-current]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--pillar);
  background: var(--accent);
}

/* Type scale ---------------------------------------------------------------------------------- */

.eyebrow {
  font: 600 0.78rem/1.4 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.display {
  font-size: clamp(2.3rem, 1.2rem + 4.6vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: -0.035em;
}

.title {
  font-size: clamp(1.9rem, 1.2rem + 2.8vw, 3.2rem);
  letter-spacing: -0.03em;
}

.subtitle {
  font-size: clamp(1.3rem, 1.05rem + 1vw, 1.7rem);
}

.lead {
  font-size: clamp(1.1rem, 1rem + 0.45vw, 1.3rem);
  line-height: 1.55;
  color: var(--dim);
  max-width: 44rem;
}

.prose {
  max-width: 44rem;
}

.prose > * + * {
  margin-top: 1rem;
}

.muted {
  color: var(--muted);
}

/* Sections ------------------------------------------------------------------------------------ */

main {
  display: block;
}

.section {
  padding-block: clamp(3.5rem, 8vw, 7rem);
}

.section + .section {
  padding-top: 0;
}

.band {
  background: var(--surface);
}

.band + .section,
.section + .band {
  padding-top: clamp(3.5rem, 8vw, 7rem);
}

.stack > * + * {
  margin-top: var(--gap, 1.25rem);
}

.split {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

@media (min-width: 60rem) {
  .split {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  }

  .split.flip {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }

  .split.flip > :first-child {
    order: 2;
  }
}

/* Hero ---------------------------------------------------------------------------------------- */

.hero {
  padding-top: clamp(2.5rem, 7vw, 6rem);
  padding-bottom: clamp(2.5rem, 6vw, 4.5rem);
}

.hero .display {
  max-width: 17ch;
}

.screen.hero-screen {
  margin-top: clamp(2.25rem, 5vw, 4rem);
}

/* A screen: the screenshots carry their own window, so they only need room and a soft lift. */

.screen {
  margin: 0;
}

.screen img {
  width: 100%;
  border-radius: 0.7rem;
  box-shadow: 0 1.5rem 3.5rem -1.5rem var(--shade), 0 0.3rem 1rem -0.4rem var(--shade);
}

.screen figcaption {
  margin-top: 0.8rem;
  font-size: 0.92rem;
  color: var(--muted);
}

/* A recorded video: the same window as a screenshot, and a Pause button beside its caption. */

.screen video {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0.7rem;
  background: var(--surface);
  box-shadow: 0 1.5rem 3.5rem -1.5rem var(--shade), 0 0.3rem 1rem -0.4rem var(--shade);
}

.reel figcaption {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.reel figcaption > span {
  max-width: 68ch;
}

.reel-toggle {
  flex: none;
  min-width: 5.8rem;
  padding: 0.45rem 0.9rem;
  border: 0;
  border-radius: 0.3rem;
  background: var(--raised);
  color: var(--dim);
  font: 600 0.82rem/1.4 var(--mono);
  cursor: pointer;
  transition: background-color var(--quick) ease-out, color var(--quick) ease-out;
}

.reel-toggle:hover {
  background: var(--active);
  color: var(--text);
}

.reel-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Commands ------------------------------------------------------------------------------------ */

.cmd {
  display: flex;
  align-items: stretch;
  max-width: 100%;
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

.band .cmd {
  background: var(--canvas);
}

.cmd pre {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 0.85rem 1rem;
  font-size: 0.88rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--text);
}

.cmd pre[data-prompt]::before {
  content: attr(data-prompt) " ";
  color: var(--muted);
}

.cmd pre code {
  font-size: inherit;
}

.copy {
  flex: none;
  min-width: 5.8rem;
  padding: 0 1rem;
  border: 0;
  background: var(--raised);
  color: var(--dim);
  font: 600 0.82rem/1 var(--mono);
  cursor: pointer;
  transition: background-color var(--quick) ease-out, color var(--quick) ease-out;
}

.copy:hover {
  background: var(--active);
  color: var(--text);
}

.copy:active {
  background: var(--accent);
  color: var(--on-accent);
}

.copy:focus-visible {
  outline-offset: -3px;
}

.copy[data-state="done"] {
  background: var(--accent);
  color: var(--on-accent);
}

.copy[data-state="failed"] {
  background: var(--active);
  color: var(--text);
}

.cmds > * + * {
  margin-top: 0.6rem;
}

.cmd-label {
  margin-bottom: 0.45rem;
  font: 600 0.8rem/1.4 var(--mono);
  color: var(--muted);
}

/* Buttons and links that act like them -------------------------------------------------------- */

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.button {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.65rem 1.1rem;
  border-radius: 0.35rem;
  background: var(--raised);
  color: var(--text);
  font: 600 0.9rem/1.2 var(--mono);
  text-decoration: none;
  transition: background-color var(--quick) ease-out;
}

.button:hover {
  background: var(--active);
  color: var(--text);
}

.button.primary {
  background: var(--accent);
  color: var(--on-accent);
}

.button.primary:hover {
  background: var(--accent-strong);
  color: var(--on-accent);
}

.button .arrow {
  font-family: var(--mono);
}

/* Short facts, as tone blocks rather than boxes ------------------------------------------------ */

.facts {
  display: grid;
  gap: 0.35rem;
  list-style: none;
}

.facts li {
  padding: 0.95rem 1.1rem;
  border-radius: 0.35rem;
  background: var(--surface);
}

.band .facts li {
  background: var(--canvas);
}

.facts strong {
  display: block;
  margin-bottom: 0.2rem;
  font: 700 0.95rem/1.4 var(--mono);
}

.facts p {
  color: var(--dim);
  font-size: 0.98rem;
}

@media (min-width: 44rem) {
  .facts.two {
    grid-template-columns: 1fr 1fr;
  }
}

/* A list of names, each on a tone chip */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
}

.chips li {
  padding: 0.35rem 0.75rem;
  border-radius: 0.3rem;
  background: var(--raised);
  font: 600 0.85rem/1.4 var(--mono);
}

/* A two-column table drawn with tone, not rules */

.rows {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 0.3rem;
  font-size: 0.98rem;
}

.rows th,
.rows td {
  padding: 0.7rem 1rem;
  text-align: left;
  vertical-align: top;
  background: var(--surface);
}

.band .rows th,
.band .rows td {
  background: var(--canvas);
}

.rows thead th {
  background: none;
  padding-block: 0 0.2rem;
  font: 600 0.78rem/1.4 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.rows tbody th {
  font: 700 0.95rem/1.5 var(--mono);
  white-space: nowrap;
}

.rows tbody tr > :first-child {
  border-radius: 0.35rem 0 0 0.35rem;
}

.rows tbody tr > :last-child {
  border-radius: 0 0.35rem 0.35rem 0;
}

.table-scroll {
  overflow-x: auto;
}

/* Notes: a surface with the pillar down its whole left edge */

.note {
  position: relative;
  padding: 1rem 1.2rem 1rem calc(1.2rem + var(--pillar));
  border-radius: 0 0.35rem 0.35rem 0;
  background: var(--surface);
  color: var(--dim);
  max-width: 44rem;
}

.band .note {
  background: var(--canvas);
}

.note::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--pillar);
  background: var(--accent);
}

.note strong {
  color: var(--text);
  font-family: var(--mono);
}

/* Flagships on the home page ------------------------------------------------------------------ */

.flagship .name {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  flex-wrap: wrap;
}

.flagship .name .muted {
  font: 500 0.95rem/1 var(--mono);
  letter-spacing: 0;
}

.flagship-shot {
  margin-top: clamp(2rem, 4vw, 3rem);
}

/* The theme switcher (qframe): radio tabs, no script. ----------------------------------------- */

.themes {
  display: grid;
  gap: 1rem;
}

.themes fieldset {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.themes legend {
  float: left;
  margin-right: 0.8rem;
  padding: 0.45rem 0;
  font: 600 0.78rem/1.4 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.themes input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.themes label {
  position: relative;
  padding: 0.45rem 0.9rem;
  border-radius: 0.3rem;
  background: var(--raised);
  color: var(--dim);
  font: 600 0.88rem/1.4 var(--mono);
  cursor: pointer;
  transition: background-color var(--quick) ease-out, color var(--quick) ease-out;
}

.themes label:hover {
  background: var(--active);
  color: var(--text);
}

.themes input:checked + label {
  color: var(--text);
}

.themes input:checked + label::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--pillar);
  background: var(--accent);
}

.themes input:focus-visible + label {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.theme-shots {
  display: grid;
  gap: 1.5rem;
}

/* Where :has() is known, the four pictures share one place and the radios pick one. Elsewhere
   they simply stand one under the other, each with its caption. */
@supports selector(:has(a)) {
  .theme-shots {
    grid-template-areas: "shot";
    align-items: start;
  }

  .theme-shots .screen {
    grid-area: shot;
    opacity: 0;
    visibility: hidden;
  }

  .themes:has(input[value="iris"]:checked) .screen[data-theme="iris"],
  .themes:has(input[value="nordic"]:checked) .screen[data-theme="nordic"],
  .themes:has(input[value="amber"]:checked) .screen[data-theme="amber"],
  .themes:has(input[value="monochrome"]:checked) .screen[data-theme="monochrome"] {
    opacity: 1;
    visibility: visible;
  }

  @media (prefers-reduced-motion: no-preference) {
    .theme-shots .screen {
      transition: opacity var(--calm) ease-out, visibility 0s linear var(--calm);
    }

    .themes:has(input[value="iris"]:checked) .screen[data-theme="iris"],
    .themes:has(input[value="nordic"]:checked) .screen[data-theme="nordic"],
    .themes:has(input[value="amber"]:checked) .screen[data-theme="amber"],
    .themes:has(input[value="monochrome"]:checked) .screen[data-theme="monochrome"] {
      transition: opacity var(--calm) ease-out, visibility 0s;
    }
  }
}

@supports not selector(:has(a)) {
  .themes fieldset {
    display: none;
  }
}

/* The qcode tour ------------------------------------------------------------------------------
   Plain layout first: each step's sentence, then its screen, one after another. Where the
   browser can tie animation to scrolling, and motion is welcome, and the window is wide, the
   screen stays in place beside the steps and each step brings its own screen in as it reaches
   the middle of the window. Scrolling itself is never taken over. */

.tour {
  display: grid;
  gap: 1.25rem;
}

.tour-stage,
.tour-steps {
  display: contents;
}

.tour-steps {
  list-style: none;
}

.tour-text {
  position: relative;
  padding-left: calc(var(--pillar) + 1rem);
}

.tour-text::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.2em;
  bottom: 0.2em;
  width: var(--pillar);
  background: var(--accent);
}

.tour-step h3 {
  font-size: 1.15rem;
  margin-bottom: 0.35rem;
}

.tour-step p {
  color: var(--dim);
}

.tour-step:nth-child(1) { order: 1; }
.tour-shot:nth-child(1) { order: 2; }
.tour-step:nth-child(2) { order: 3; }
.tour-shot:nth-child(2) { order: 4; }
.tour-step:nth-child(3) { order: 5; }
.tour-shot:nth-child(3) { order: 6; }
.tour-step:nth-child(4) { order: 7; }
.tour-shot:nth-child(4) { order: 8; }
.tour-step:nth-child(5) { order: 9; }
.tour-shot:nth-child(5) { order: 10; }

.tour-shot {
  margin-bottom: 2rem;
}

@supports (animation-timeline: view()) and (timeline-scope: --t) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 60rem) {
    .tour {
      grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
      gap: 0 clamp(2rem, 4vw, 3.5rem);
      timeline-scope: --t1, --t2, --t3, --t4, --t5;
    }

    .tour-steps {
      display: block;
      grid-column: 1;
      grid-row: 1;
    }

    .tour-stage {
      display: grid;
      grid-template-areas: "shot";
      grid-column: 2;
      grid-row: 1;
      position: sticky;
      top: max(1rem, calc(50vh - 20rem));
      align-self: start;
    }

    .tour-shot {
      grid-area: shot;
      margin: 0;
    }

    /* One lift for the whole stack, so the screens' shadows do not pile up. */
    .tour-stage {
      border-radius: 0.7rem;
      box-shadow: 0 1.5rem 3.5rem -1.5rem var(--shade), 0 0.3rem 1rem -0.4rem var(--shade);
    }

    .tour-shot img {
      box-shadow: none;
    }

    .tour-step {
      display: flex;
      flex-direction: column;
      justify-content: center;
      min-height: 72vh;
      padding-block: 2rem;
    }

    .tour-step:first-child {
      min-height: 50vh;
      justify-content: flex-start;
      padding-top: 6vh;
    }

    .tour-step:nth-child(1) { view-timeline-name: --t1; }
    .tour-step:nth-child(2) { view-timeline-name: --t2; }
    .tour-step:nth-child(3) { view-timeline-name: --t3; }
    .tour-step:nth-child(4) { view-timeline-name: --t4; }
    .tour-step:nth-child(5) { view-timeline-name: --t5; }

    /* The step at the middle of the window is lit; the others rest in a quieter tone. */
    .tour-step h3,
    .tour-step p {
      animation: step-lit linear both;
      animation-range: cover 25% cover 75%;
    }

    .tour-text::before {
      animation: step-pillar linear both;
      animation-range: cover 25% cover 75%;
    }

    .tour-step:nth-child(1) h3, .tour-step:nth-child(1) p, .tour-step:nth-child(1) .tour-text::before { animation-timeline: --t1; }
    .tour-step:nth-child(2) h3, .tour-step:nth-child(2) p, .tour-step:nth-child(2) .tour-text::before { animation-timeline: --t2; }
    .tour-step:nth-child(3) h3, .tour-step:nth-child(3) p, .tour-step:nth-child(3) .tour-text::before { animation-timeline: --t3; }
    .tour-step:nth-child(4) h3, .tour-step:nth-child(4) p, .tour-step:nth-child(4) .tour-text::before { animation-timeline: --t4; }
    .tour-step:nth-child(5) h3, .tour-step:nth-child(5) p, .tour-step:nth-child(5) .tour-text::before { animation-timeline: --t5; }

    .tour-step:first-child h3,
    .tour-step:first-child p {
      animation-name: step-lit-first;
    }

    .tour-step:first-child .tour-text::before {
      animation-name: step-pillar-first;
    }

    /* Each later screen settles over the one before it as its step comes in, and lifts away
       again when scrolling back up. The first is always underneath. */
    .tour-shot + .tour-shot {
      animation: shot-in linear both;
      animation-range: entry 70% cover 45%;
    }

    .tour-shot:nth-child(2) { animation-timeline: --t2; }
    .tour-shot:nth-child(3) { animation-timeline: --t3; }
    .tour-shot:nth-child(4) { animation-timeline: --t4; }
    .tour-shot:nth-child(5) { animation-timeline: --t5; }
  }
}

@keyframes step-lit {
  0%, 100% { color: var(--muted); }
  25%, 75% { color: var(--text); }
}

@keyframes step-lit-first {
  0%, 75% { color: var(--text); }
  100% { color: var(--muted); }
}

@keyframes step-pillar {
  0%, 100% { background-color: var(--active); }
  25%, 75% { background-color: var(--accent); }
}

@keyframes step-pillar-first {
  0%, 75% { background-color: var(--accent); }
  100% { background-color: var(--active); }
}

@keyframes shot-in {
  from { opacity: 0; transform: translateY(0.6rem); }
  to { opacity: 1; transform: none; }
}

/* The rest of the family ---------------------------------------------------------------------- */

.members {
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.5rem);
  list-style: none;
}

@media (min-width: 50rem) {
  .members {
    grid-template-columns: 1fr 1fr;
  }
}

.member {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: clamp(1rem, 2.5vw, 1.5rem);
  border-radius: 0.6rem;
  background: var(--surface);
  transition: background-color var(--quick) ease-out;
}

.band .member {
  background: var(--canvas);
}

.member::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--pillar);
  border-radius: 0.6rem 0 0 0.6rem;
  background: transparent;
  transition: background-color var(--quick) ease-out;
}

.member:hover,
.member:focus-within {
  background: var(--raised);
}

.member:hover::before,
.member:focus-within::before {
  background: var(--accent);
}

.member .screen img {
  border-radius: 0.45rem;
  box-shadow: 0 0.8rem 1.8rem -1rem var(--shade);
}

.member h3 {
  font-size: 1.3rem;
}

.member h3 a {
  color: var(--text);
  text-decoration: none;
}

.member h3 a:hover {
  color: var(--accent-strong);
}

.member .what {
  color: var(--dim);
}

.member .more {
  margin-top: auto;
  font: 600 0.88rem/1.4 var(--mono);
}

/* Galleries ----------------------------------------------------------------------------------- */

.gallery {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2rem);
}

@media (min-width: 50rem) {
  .gallery {
    grid-template-columns: 1fr 1fr;
  }
}

/* Code sample -------------------------------------------------------------------------------- */

.code {
  margin: 0;
  padding: 1.1rem 1.25rem;
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 0.86rem;
  line-height: 1.6;
  overflow-x: auto;
  color: var(--text);
}

.band .code {
  background: var(--canvas);
}

.code .c {
  color: var(--muted);
}

.code .k {
  color: var(--accent-strong);
}

/* Footer -------------------------------------------------------------------------------------- */

.site-foot {
  padding-block: 3rem 3.5rem;
  background: var(--surface);
  font-size: 0.95rem;
  color: var(--dim);
}

.site-foot .wrap {
  display: grid;
  gap: 2rem;
}

@media (min-width: 50rem) {
  .site-foot .wrap {
    grid-template-columns: 2fr 1fr 1fr 1fr;
  }
}

.site-foot .translation {
  margin-top: 0.8rem;
  color: var(--muted);
  font-size: 0.9rem;
}

.site-foot h2 {
  margin-bottom: 0.7rem;
  font: 600 0.78rem/1.4 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.site-foot ul {
  list-style: none;
  display: grid;
  gap: 0.3rem;
}

.site-foot a {
  color: var(--dim);
  text-decoration: none;
}

.site-foot a:hover {
  color: var(--text);
  text-decoration: underline;
}

.site-foot .brand {
  margin-bottom: 0.8rem;
}

/* A command inside a card sits one tone away from the card. */
.member .cmd {
  background: var(--canvas);
}

.band .member .cmd {
  background: var(--surface);
}

@media (max-width: 30rem) {
  .copy {
    min-width: 4.6rem;
    padding: 0 0.7rem;
  }

  .cmd pre {
    padding: 0.75rem 0.8rem;
    font-size: 0.84rem;
  }
}

/* Motion off means off. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }
}
