/*
    One world, committed: a tape running in a dark room. The stencil wordmark is
    spray-rough and the orc is neon — that tension is the identity, so nothing
    here smooths either of them out.
  */
  :root {
    --void:   #050a14;   /* lifted straight from the artwork's ground */
    --panel:  #0a1220;
    --raise:  #0e1828;
    --rule:   #17293f;
    --ink:    #e2f0f7;
    --ash:    #7d99ae;
    --dim:    #4a6377;
    --cyan:   #35b8d8;
    --magenta:#e82a8e;
    --measure: 66ch;
  }

  * { box-sizing: border-box; }
  html { scroll-behavior: smooth; }
  @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

  body {
    margin: 0;
    background: var(--void);
    color: var(--ash);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 14.5px;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
  }

  a { color: var(--cyan); text-underline-offset: 3px; }
  a:hover { color: var(--ink); }
  a:focus-visible, button:focus-visible {
    outline: 2px solid var(--magenta); outline-offset: 3px;
  }

  /* The logos carry real alpha: white glyphs, transparent ground. An earlier
     version faked it with invert + screen, which any stacking context can
     isolate — and one did, so the mark rendered inside a black box. Doing it in
     the asset costs nothing at runtime and cannot be broken from CSS. */
  .stencil { display: block; }

  /* ── chrome ──────────────────────────────────────────────────── */

  .nav {
    position: sticky; top: 0; z-index: 30;
    display: flex; align-items: center; gap: 24px;
    padding: 12px 24px;
    background: rgba(5,10,20,.82);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--rule);
  }
  .nav .mark { flex: none; display: flex; align-items: center; }
  a.mark { display: flex; align-items: center; }
  a.mark:hover { opacity: .8; }
  a.mark:focus-visible { outline: 2px solid var(--magenta); outline-offset: 4px; }
  /* Bigger still on the variant that leans on the mark. */
  .nav .mark img { height: 48px; width: auto; }
  @media (max-width: 640px) { .nav .mark img { height: 30px; } }

  .nav nav { display: flex; gap: 4px; flex-wrap: wrap; margin-left: auto; }
  .nav nav a {
    padding: 7px 12px;
    font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
    color: var(--ash); text-decoration: none;
    border: 1px solid transparent;
  }
  .nav nav a:hover { color: var(--ink); border-color: var(--rule); }
  .nav nav a[aria-current="page"] { color: var(--void); background: var(--cyan); }

  /* ── hero ────────────────────────────────────────────────────── */

  .hero {
    position: relative;
    min-height: min(78vh, 720px);
    display: flex; align-items: center;
    padding: 76px 24px 84px;
    max-width: 1180px; margin: 0 auto;
    overflow: hidden;
  }
  .hero-copy { position: relative; z-index: 2; max-width: 620px; }
  @media (max-width: 900px) { .hero { min-height: 0; padding-top: 32px; } }

  .hero-copy { display: flex; flex-direction: column; gap: 22px; }

  .wordmark { width: min(100%, 460px); }
  .wordmark img { width: 100%; height: auto; }

  .tagline {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: clamp(21px, 3.2vw, 30px);
    font-weight: 800; letter-spacing: -.028em; line-height: 1.14;
    color: var(--ink); text-wrap: balance;
    max-width: 22ch;
  }
  .hero p { margin: 0; max-width: 46ch; }

  /* Background rather than a framed picture, sized from HEIGHT: setting width
     and deriving height from the square aspect clipped the orc's head on any
     viewport shorter than the frame was wide. */
  .frame {
    position: absolute;
    top: 50%; right: -4%;
    transform: translateY(-50%);
    height: min(104%, 680px);
    width: auto; aspect-ratio: 1 / 1;
    background: transparent; border: 0;
    z-index: 1; pointer-events: none;

    /* All four edges are faded by the masks themselves.
       An earlier version faded only the left and relied on the right bleeding
       off-screen — but `right` is a percentage of the hero, which is capped at
       1180px and centred, so on a wide display the right edge lands well inside
       the viewport and cuts the picture with a hard vertical rule. Depending on
       the window being narrow enough is not a fade. */
    -webkit-mask-image:
      linear-gradient(to right, transparent 0%, #000 42%, #000 78%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 14%, #000 78%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to right, transparent 0%, #000 42%, #000 78%, transparent 100%),
      linear-gradient(to bottom, transparent 0%, #000 14%, #000 78%, transparent 100%);
    mask-composite: intersect;
  }
  @media (max-width: 900px) {
    .frame {
      right: -14%; height: auto; width: 118%; opacity: .3;
      -webkit-mask-image: radial-gradient(closest-side, #000 38%, transparent 100%);
      mask-image: radial-gradient(closest-side, #000 38%, transparent 100%);
    }
  }
  .frame canvas { display: block; width: 100%; height: 100%; }
  #tape { image-rendering: pixelated; }
  #bloom {
    position: absolute; inset: 0;
    mix-blend-mode: screen; pointer-events: none;
    filter: blur(12px);
  }

  .cta { display: flex; flex-wrap: wrap; gap: 12px; }
  .btn {
    display: inline-block;
    white-space: nowrap;
    padding: 12px 22px;
    font: inherit; font-size: 12.5px;
    letter-spacing: .1em; text-transform: uppercase;
    text-decoration: none;
    background: var(--cyan); color: #04121a;
    border: 1px solid var(--cyan);
  }
  .btn:hover { background: #5ad0ec; border-color: #5ad0ec; color: #04121a; }
  .btn.ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
  .btn.ghost:hover { border-color: var(--cyan); color: var(--cyan); background: transparent; }

  /* ── sections ────────────────────────────────────────────────── */

  main { max-width: 1180px; margin: 0 auto; padding: 0 24px 110px; }

  .view { display: none; flex-direction: column; gap: 56px; }
  .view.on { display: flex; }

  section { display: flex; flex-direction: column; gap: 20px; }

  .kicker {
    font-size: 11px; letter-spacing: .26em; text-transform: uppercase;
    color: var(--dim);
    display: flex; align-items: center; gap: 12px;
  }
  .kicker::after { content: ""; flex: 1; height: 1px; background: var(--rule); }

  h1.page {
    margin: 0;
    font-family: system-ui, -apple-system, sans-serif;
    font-size: clamp(30px, 5vw, 50px);
    font-weight: 800; letter-spacing: -.035em; line-height: 1.03;
    color: var(--ink); text-wrap: balance;
  }
  h2 {
    margin: 0;
    font-family: system-ui, -apple-system, sans-serif;
    font-size: clamp(19px, 2.4vw, 25px);
    font-weight: 700; letter-spacing: -.02em;
    color: var(--ink); text-wrap: balance;
  }
  h3 {
    margin: 0;
    font-family: system-ui, -apple-system, sans-serif;
    font-size: 15px; font-weight: 700; letter-spacing: -.01em;
    color: var(--ink);
  }
  p { margin: 0; max-width: var(--measure); }

  .grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1px;
    background: var(--rule);
    border: 1px solid var(--rule);
  }
  .grid > * {
    background: var(--panel);
    padding: 26px 24px;
    display: flex; flex-direction: column; gap: 10px;
  }
  .grid p { max-width: none; }

  .card-link {
    text-decoration: none; color: inherit;
    transition: background .15s;
  }
  .card-link:hover { background: var(--raise); }
  .card-link .more { color: var(--cyan); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }

  /* Product links carry their own state: a thing you can use today reads
     differently from a thing that is coming, and the label says which. */
  .links { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
  .link-row {
    background: var(--panel);
    display: grid; grid-template-columns: 148px 1fr auto;
    gap: 6px 22px; padding: 20px 24px; align-items: baseline;
    text-decoration: none; color: inherit;
  }
  .link-row:hover { background: var(--raise); }
  .link-row .name {
    font-family: system-ui, sans-serif; font-weight: 700; font-size: 14px;
    color: var(--ink);
  }
  .link-row .what { color: var(--ash); }
  .link-row .state {
    font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
    padding: 3px 9px; white-space: nowrap;
  }
  .state.live { color: var(--void); background: var(--cyan); }
  .state.soon { color: var(--magenta); border: 1px solid var(--magenta); }
  @media (max-width: 640px) {
    .link-row { grid-template-columns: 1fr; }
  }

  dl.spec { display: grid; grid-template-columns: 190px 1fr; gap: 4px 24px; margin: 0; }
  dl.spec dt {
    font-family: system-ui, sans-serif; font-weight: 700; font-size: 13px;
    color: var(--ink);
    padding: 14px 0 0;
    border-top: 1px solid var(--rule);
  }
  dl.spec dd {
    margin: 0; padding: 14px 0 14px;
    border-top: 1px solid var(--rule);
    max-width: var(--measure);
  }
  @media (max-width: 640px) {
    dl.spec { grid-template-columns: 1fr; gap: 0; }
    dl.spec dd { border-top: 0; padding-top: 4px; }
  }

  .note {
    padding: 20px 22px; max-width: var(--measure);
    border-left: 2px solid var(--magenta);
    background: #14081020;
  }
  .note strong { color: var(--magenta); font-weight: 400; }

  .entry {
    display: grid; grid-template-columns: 132px 1fr; gap: 6px 26px;
    padding: 22px 0; border-top: 1px solid var(--rule);
  }
  .entry:last-child { border-bottom: 1px solid var(--rule); }
  .entry time { color: var(--dim); font-variant-numeric: tabular-nums; font-size: 13px; }
  .entry .body { display: flex; flex-direction: column; gap: 8px; }
  @media (max-width: 640px) { .entry { grid-template-columns: 1fr; } }

  ul.plain { margin: 0; padding-left: 1.1em; max-width: var(--measure); }
  ul.plain li { margin-bottom: 8px; }
  ul.plain li::marker { color: var(--cyan); }

  code {
    color: var(--magenta); background: rgba(232,42,142,.1);
    padding: 1px 6px; font-size: 13.5px;
  }

  footer {
    border-top: 1px solid var(--rule);
    padding: 40px 24px 60px;
  }
  .foot-in {
    max-width: 1180px; margin: 0 auto;
    display: flex; flex-wrap: wrap; gap: 28px 48px; align-items: flex-start;
    justify-content: space-between;
  }
  .foot-in .brand { width: 200px; opacity: .55; }
  .foot-in .brand img { width: 100%; height: auto; }
  .foot-cols { display: flex; flex-wrap: wrap; gap: 44px; }
  .foot-col { display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
  .foot-col b {
    font-family: system-ui, sans-serif; font-size: 11px;
    letter-spacing: .18em; text-transform: uppercase; color: var(--dim);
    font-weight: 700;
  }
  .foot-col a { text-decoration: none; }
  .legal { color: var(--dim); font-size: 12px; max-width: 52ch; }

/* ── company navigation ────────────────────────────────────────
   Grouped menus rather than a flat row. A flat row of page names works for a
   site about one thing; this site is about a company that will have four
   products, and the menu has to hold that without being redrawn. */

.nav { gap: 6px; }
.nav .menus { display: flex; align-items: center; gap: 2px; margin-left: 26px; }
.nav .tail { margin-left: auto; display: flex; align-items: center; gap: 8px; }

.menu { position: relative; }
.menu > button, .nav .flat {
  font: inherit; font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ash); background: transparent;
  border: 1px solid transparent; padding: 8px 12px;
  cursor: pointer; text-decoration: none; display: inline-block;
}
.menu > button:hover, .nav .flat:hover { color: var(--ink); border-color: var(--rule); }
.menu > button[aria-expanded="true"] { color: var(--ink); border-color: var(--rule); background: var(--panel); }
.nav .flat[aria-current="page"], .menu.here > button { color: var(--void); background: var(--cyan); }

.drop {
  position: absolute; top: calc(100% + 9px); left: 0;
  min-width: 330px; background: var(--panel);
  border: 1px solid var(--rule); padding: 8px; display: none; z-index: 40;
}
.menu.open .drop { display: block; }
.drop a {
  display: block; padding: 10px 12px; text-decoration: none; color: var(--ink);
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 13.5px; font-weight: 700; letter-spacing: -.01em;
}
.drop a em {
  display: block; font-style: normal;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 12px; font-weight: 400; color: var(--ash); margin-top: 2px;
}
.drop a:hover { background: var(--raise); }
.drop .label {
  font-size: 10px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--dim); padding: 10px 12px 4px;
}
.drop hr { border: 0; border-top: 1px solid var(--rule); margin: 8px 0; }

/* What does not exist yet is a slot, not a link. An empty slot reserves the
   shape honestly; a dead link does neither. */
.drop .slot {
  padding: 10px 12px; color: var(--dim);
  font-family: system-ui, sans-serif; font-size: 13.5px; font-weight: 700;
}
.drop .slot em {
  display: block; font-style: normal;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 12px; font-weight: 400; margin-top: 2px;
}

.btn.sm { padding: 8px 14px; font-size: 11.5px; }

@media (max-width: 1080px) {
  .nav { flex-wrap: wrap; }
  .nav .menus { margin-left: 0; order: 3; width: 100%; flex-wrap: wrap; }
  .nav .tail { order: 2; }
  .drop { position: static; min-width: 0; width: 100%; margin-top: 6px; }
}

/* ── product line ──────────────────────────────────────────────── */

.line { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.line-item {
  background: var(--panel); padding: 30px 28px;
  display: grid; grid-template-columns: 1fr auto; gap: 14px 24px;
  text-decoration: none; color: inherit; align-items: start;
}
a.line-item:hover { background: var(--raise); }
.line-item .head { display: flex; flex-direction: column; gap: 8px; }
.line-item h3 { font-size: 19px; }
.line-item p { max-width: 62ch; }
.line-item .more { color: var(--cyan); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }
.line-item.future { color: var(--dim); }
.line-item.future h3 { color: var(--ash); }

.state {
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  padding: 4px 10px; white-space: nowrap; align-self: start;
}
.state.live { color: var(--void); background: var(--cyan); }
.state.soon { color: var(--magenta); border: 1px solid var(--magenta); }
.state.later { color: var(--dim); border: 1px dashed var(--dim); }

@media (max-width: 640px) { .line-item { grid-template-columns: 1fr; } }

/* ── pricing ───────────────────────────────────────────────────── */
.tiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1px;
         background: var(--rule); border: 1px solid var(--rule); }
.tier { background: var(--panel); padding: 28px 24px; display: flex; flex-direction: column; gap: 14px; }
.tier .price {
  font-family: system-ui, sans-serif; font-size: 28px; font-weight: 800;
  letter-spacing: -.03em; color: var(--ink);
}
.tier .price small { font-size: 13px; font-weight: 400; color: var(--ash); letter-spacing: 0; }
.tier ul { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: 7px; }
.tier li::marker { color: var(--cyan); }
.tier .foot { margin-top: auto; padding-top: 8px; }

/* Openness is a property of a product, not a section of the site — so it is a
   tag on the row rather than an item in the menu. A product can carry more than
   one state at once: available and open are independent facts. */
.states { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.state.open { color: var(--cyan); border: 1px solid var(--cyan); }

.drop .tag {
  display: inline-block; margin-left: 8px;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--cyan); border: 1px solid var(--rule);
  padding: 1px 6px; vertical-align: 2px; font-weight: 400;
}
@media (max-width: 640px) { .states { flex-direction: row; align-items: flex-start; } }

/* ── per-product theme ─────────────────────────────────────────
   The company chrome stays constant; a product brings its own colour with it.
   Both accents below are sampled from the product's own artwork rather than
   picked to look nice beside it, so the page and the picture cannot drift.

   Tokens only — no component is restyled here, so a new product needs a block
   like this and nothing else. */

body[data-page="contextverse"], body[data-page="dither-ork"] {
  --void:    #04040a;
  --panel:   #0b0a18;
  --raise:   #11102260;
  --rule:    #221f3d;
  --ink:     #e8f6e2;
  --ash:     #8ea390;   /* neutral pulled toward the green, not a flat grey */
  --dim:     #5b6b58;
  --cyan:    #3fd914;   /* the acid green, lifted for legibility on black */
  --magenta: #7a68d8;   /* the violet from the cables */
}
/* Sampled from assets/img/dither-ork.png by counting pixels, not chosen beside
   it: the hero renderer derives its own palette from the image at load, so an
   eyeballed value fights the canvas. The picture is 56.7% pure black with two
   inks — #f749f6 at 0.7% and #59fdfd at 0.6% — which is what a two-colour
   dither on an unlit ground looks like when you count it. */
body[data-page="dither-ork"] {
  --void:    #050409;
  --panel:   #0c0a14;
  --raise:   #16102260;
  --rule:    #291f3d;
  --ink:     #e6f7f7;
  --ash:     #8ea5ab;   /* neutral pulled toward the cyan, not a flat grey */
  --dim:     #5a6b70;
  --cyan:    #59fdfd;   /* the cyan ink, straight off the image */
  --magenta: #f749f6;   /* the magenta ink, straight off the image */
}
body[data-page="dither-ork"] .btn:not(.ghost) { color: #04120f; }
body[data-page="dither-ork"] .btn:hover { background: #7dfdfd; border-color: #7dfdfd; color: #04120f; }
body[data-page="dither-ork"] .state.live { color: #04120f; }
body[data-page="dither-ork"] .nav .flat[aria-current="page"],
body[data-page="dither-ork"] .menu.here > button { color: #04120f; }

body[data-page="contextverse"] .btn:not(.ghost) { color: #04120a; }
body[data-page="contextverse"] .btn:hover { background: #58ef2e; border-color: #58ef2e; color: #04120a; }
body[data-page="contextverse"] .state.live { color: #04120a; }
body[data-page="contextverse"] .nav .flat[aria-current="page"],
body[data-page="contextverse"] .menu.here > button { color: #04120a; }

/* ── product hero: a banner, not a welcome ─────────────────────
   The company's hero introduces the company. Repeating it above a product page
   makes the visitor read the pitch again to reach the thing they clicked. */

body[data-page="contextverse"] .hero, body[data-page="dither-ork"] .hero { min-height: 0; padding: 0 24px; max-width: none; }
body[data-page="contextverse"] .hero-copy, body[data-page="dither-ork"] .hero-copy { display: none; }

/* dither-ork's artwork is 1318x1187 — very nearly square, where ContextVerse's
   is a wide picture and these banner rules were written for one. Left at
   width:100% a square fills ~1600x1440 and pushes up under the sticky header.
   Cropping it to a strip is also the right call for the picture: the orc sits
   in the upper middle, so the interesting part survives the crop. */
body[data-page="dither-ork"] .frame { max-height: 46vh; }
body[data-page="dither-ork"] .frame canvas { object-fit: cover; object-position: 50% 42%; }

body[data-page="contextverse"] .frame, body[data-page="dither-ork"] .frame {
  position: relative; inset: auto; transform: none;
  width: 100%; max-width: 1600px; margin: 0 auto;
  height: auto; aspect-ratio: var(--art-aspect, 16 / 9);
  max-height: 62vh;
  -webkit-mask-image: linear-gradient(to bottom, #000 46%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 46%, transparent 100%);
  -webkit-mask-composite: source-over;
  mask-composite: add;
}
body[data-page="contextverse"] .frame canvas, body[data-page="dither-ork"] .frame canvas { object-fit: cover; }

/* ══ small screens ═══════════════════════════════════════════════
   Not a set of shrink-to-fit overrides. Two things are laid out
   differently because side-by-side stops being the right answer, and
   touch targets are sized for a finger rather than a cursor. */

@media (max-width: 720px) {

  /* The bar was 107px and sticky — an eighth of a phone screen, permanently,
     with the actions stacked above the navigation they belong beside. One row,
     scrollable if it has to be, and Docs steps out: it is on every product
     page and in the footer, and the bar is not the only way to reach it. */
  .nav {
    flex-wrap: nowrap;
    gap: 4px;
    padding: 8px 12px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav .menus { order: 0; width: auto; margin-left: 8px; flex-wrap: nowrap; }
  .nav .tail { order: 0; }
  .nav .tail .ghost { display: none; }
  .nav .mark img { height: 32px; }

  /* A finger is not a cursor. 44px is the smallest target that does not need
     a second attempt. */
  .menu > button, .nav .flat { padding: 12px 10px; font-size: 11.5px; white-space: nowrap; }
  /* Wrapping "Get started" onto two lines pushed the sticky bar to 81px. A
     button label that wraps is a label that is too long for the space, not a
     bar that needs to be taller. */
  .btn.sm { padding: 12px 14px; white-space: nowrap; }
  .nav .mark { padding: 6px 0; }   /* a tap target, not just a picture */
  .drop a, .drop .slot { padding: 14px 12px; }

  /* The menu drops out of the bar entirely rather than trying to sit inside a
     scrolling strip. */
  .menu { position: static; }
  .drop {
    position: fixed; left: 0; right: 0;
    top: var(--nav-h, 56px);
    min-width: 0; margin: 0;
    border-left: 0; border-right: 0;
    max-height: calc(100vh - var(--nav-h, 56px));
    overflow-y: auto;
  }

  /* The artwork was wallpaper behind the paragraph at 30% — readable enough to
     pass a contrast check and tiring to actually read. Stacked instead: the
     copy gets a clean ground, the picture gets its own band. */
  .hero {
    flex-direction: column;
    align-items: stretch;
    gap: 28px;
    padding: 28px 20px 40px;
    min-height: 0;
    overflow: visible;
  }
  .hero-copy { max-width: none; }
  .frame {
    position: relative; inset: auto; transform: none;
    width: 100%; height: auto;
    aspect-ratio: var(--art-aspect, 1 / 1);
    opacity: 1;
    -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  }

  .wordmark { width: min(100%, 320px); }
  .tagline { font-size: clamp(20px, 6.4vw, 26px); max-width: none; }
  .hero p { max-width: none; }
  .cta .btn { flex: 1; text-align: center; padding: 14px 16px; }

  main { padding: 0 20px 72px; }
  .view { gap: 40px; }
  section { gap: 16px; }

  /* Reading measure, not the desktop one squeezed. */
  body { font-size: 15px; line-height: 1.65; }
  h1.page { font-size: clamp(26px, 8vw, 34px); }

  .grid > * { padding: 22px 20px; }
  .line-item { padding: 24px 20px; }
  .tier { padding: 24px 20px; }
  .link-row { padding: 18px 20px; }
  dl.spec dd { padding-bottom: 18px; }

  .foot-in { flex-direction: column; gap: 28px; }
  .foot-cols { gap: 28px; }
  .foot-col a { padding: 4px 0; }   /* tappable without hitting its neighbour */
}

/* The product banner is a wide picture; on a narrow screen a 16:9 strip is a
   sliver, so it is allowed to be taller than it is on a desktop. */
@media (max-width: 720px) {
body[data-page="contextverse"] .hero, body[data-page="dither-ork"] .hero { padding: 0 0 24px; gap: 0; }
body[data-page="contextverse"] .frame, body[data-page="dither-ork"] .frame { max-height: 42vh; }
body[data-page="contextverse"] .frame canvas, body[data-page="dither-ork"] .frame canvas { object-fit: cover; }
}

/* Two labels, one button: the bar has room for the long one on a desktop and
   not on a phone, and a truncated word is worse than a shorter one. */
.narrow-only { display: none; }
@media (max-width: 460px) {
  .wide-only { display: none; }
  .narrow-only { display: inline; }
}
