/* Ohmage — site styles.
   One file, no build step. Colours are declared once per scheme with
   light-dark(); a data-theme attribute on <html> overrides the system choice. */

:root {
  color-scheme: light dark;

  /* Every text/background pair below clears WCAG 2.2 AAA (7:1) —
     see Website/check-contrast.py, which fails if one drops under. */
  --bg:        light-dark(#ffffff, #121417);
  --bg-raised: light-dark(#f3f4f6, #1b1e23);
  --bg-inset:  light-dark(#e8eaee, #24282f);
  --text:      light-dark(#1a1a1a, #ececec);
  --text-2:    light-dark(#4a4a4a, #b8bcc2);
  --link:      light-dark(#07468a, #8ec2ff);
  --accent:    light-dark(#007aff, #0a84ff);   /* Apple's system blue, non-text only */
  --rule:      light-dark(#d0d4da, #363b44);
  --focus:     light-dark(#1a1a1a, #ececec);   /* the text colour: one ring, no third hue */

  --measure: 68ch;
  --radius: 12px;
  --gap: clamp(1rem, 2.5vw, 2rem);

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

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

html {
  font-family: var(--font);
  font-size: 100%;
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-block-start: 5rem;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  min-block-size: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

/* The symbol holder. `hidden` does nothing on an SVG element, so it is taken out
   of the layout this way instead. */
.sprite {
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: hidden;
}

/* ---- Focus, always visible, never colour-only ---------------------------- */

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 4px;
  /* A gap in the page colour, so the ring reads on a filled control too. */
  box-shadow: 0 0 0 2px var(--bg);
}

.skip-link {
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
  padding: 0.6rem 1rem;
  background: var(--bg);
  color: var(--link);
  border: 2px solid currentColor;
  border-radius: var(--radius);
  transform: translateY(-200%);
  z-index: 10;
}
.skip-link:focus { transform: none; }

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

h1, h2, h3 {
  line-height: 1.15;
  text-wrap: balance;
  margin-block: 0 0.5em;
  font-weight: 650;
}
h1 { font-size: clamp(2rem, 1.2rem + 3vw, 3.25rem); letter-spacing: -0.01em; }
h2 { font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2rem); }
h3 { font-size: 1.15rem; }

p, li, dd { max-inline-size: var(--measure); text-wrap: pretty; }
p { margin-block: 0 1em; }

a {
  color: var(--link);
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.15em;
}
a:hover { text-decoration-thickness: 0.15em; }

code, kbd, pre {
  font-family: var(--mono);
  font-size: 0.92em;
}
code {
  background: var(--bg-inset);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}
pre {
  background: var(--bg-inset);
  padding: 1rem 1.25rem;
  border-radius: var(--radius);
  overflow-x: auto;
  max-inline-size: 100%;
}
pre code { background: none; padding: 0; }

.lede {
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  color: var(--text-2);
}

.muted { color: var(--text-2); }
.small { font-size: 0.95rem; }
#screenshots .small { margin-block-end: 2rem; }

/* ---- Layout --------------------------------------------------------------- */

.wrap {
  inline-size: min(100% - 2 * var(--gap), 72rem);
  margin-inline: auto;
}

.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: 5;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-block-end: 1px solid var(--rule);
}
.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1rem;
  padding-block: 0.5rem;
}
.brand {
  font-weight: 700;
  font-size: 1.15rem;
  text-decoration: none;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-block-size: 44px;
}
.brand svg { inline-size: 1.75rem; block-size: 1.75rem; color: var(--accent); --halo: var(--bg); }

/* Two groups in one nav: the page's sections beside the brand, and the other
   pages pushed to the far end behind a rule, so they read as a different kind of
   link without a second landmark. */
.site-nav {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1rem;
}
.site-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.site-nav .nav-pages {
  margin-inline-start: auto;
  padding-inline-start: 1rem;
  border-inline-start: 1px solid var(--rule);
}
.nav-pages a { color: var(--text-2); font-size: 0.95rem; }
/* Narrow: two rows, not four. The select joins the brand on the first row and the
   two link groups share the second, the rule between them kept. */
@media (max-width: 48rem) {
  .site-header { position: static; }   /* three rows is too much to pin to a phone */
  .site-header .wrap { gap: 0 0.5rem; padding-block: 0.25rem 0.5rem; }
  .site-header .theme-switch { order: 1; margin-inline-start: auto; }
  .site-header .site-nav { order: 2; flex-basis: 100%; gap: 0.25rem 0.75rem; }
  .site-nav .nav-pages { margin-inline-start: 0; padding-inline-start: 0; border: 0; }
  .site-nav a { padding-inline: 0.5rem; }
}
.site-nav a {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;          /* WCAG 2.5.5 target size, AAA */
  padding-inline: 0.75rem;
  text-decoration: none;
  color: var(--text);
  border-radius: 8px;
}
.site-nav a:hover,
.site-nav a[aria-current] { background: var(--bg-inset); }

/* The colour mode is a setting, not a control anyone reaches for twice: a small
   native select, with a 44px label around it for the target size. */
.theme-switch {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
}
.theme-switch select {
  font: inherit;
  font-size: 0.9rem;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: 0.3rem 0.5rem;
}
.theme-switch[hidden] { display: none; }

.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

main > section {
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
main > section.hero-section {
  padding-block: clamp(2.5rem, 5vw, 4rem) clamp(2rem, 4vw, 3rem);
}
main > section + section { border-block-start: 1px solid var(--rule); }

/* The mark again, large and faint, bleeding off the right edge behind the copy.
   Decoration only: it is hidden from assistive technology, takes no pointer
   events, and is faint enough that the copy over it keeps its contrast. It sits
   at the right rather than the left so it is not the icon's shape drawn twice in
   the same corner. It is centred on the section holding it, and that section is
   its frame: a page that wants one only has to draw it. */
main > section:has(> .page-mark) {
  position: relative;
  overflow: hidden;
}
.page-mark {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: -10vw;
  transform: translateY(-50%);
  inline-size: clamp(24rem, 58vw, 50rem);
  block-size: clamp(24rem, 58vw, 50rem);
  color: var(--accent);
  /* Group opacity composites the whole drawing at once, so the halo still cuts
     the outline inside it before the 7% is applied. */
  --halo: var(--bg);
  opacity: 0.07;
  pointer-events: none;
  z-index: 0;
}
main > section:has(> .page-mark) > .wrap { position: relative; z-index: 1; }

/* A page that is one column of prose is a single section from header to footer,
   so centring the mark on it buries it halfway down. Its centre goes a hero's
   half-height from the top instead — where the hero's own height puts it on a
   wide screen — and a section shorter than that is still centred on itself. */
main > section:has(.prose) > .page-mark { inset-block-start: min(50%, 15rem); }

/* The page's head: the icon takes a column of its own width, top-aligned with the
   heading, and the store line and the platform chips sit under it in the same
   column — where the App Store links will go. Narrow, they drop below the copy so
   the order reads icon, heading, copy, then where to get it, and the page answers
   itself before it says where to buy anything. The home page's hero is this
   shape; so is the head of a page of prose, whose copy is the whole page. */
.masthead {
  --icon: clamp(6.5rem, 16vw, 11rem);
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
  grid-template-columns: 1fr;
  grid-template-areas: "icon" "copy" "cta" "chips";
}
@container (min-width: 48rem) {
  .masthead {
    grid-template-columns: var(--icon) 1fr;
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "icon copy" "cta copy" "chips copy";
    row-gap: 1.25rem;
  }
  .masthead .cta { text-align: center; }
  .masthead .platforms { flex-direction: column; align-items: center; margin: 0; }
}
/* The copy column may hold something that cannot wrap — the self-test command on
   Support — and a grid item will not shrink below its longest unbreakable line
   unless it is told it may. Without this the column pushes the grid wider than
   the page and the section, which clips the mark, clips the copy with it. */
.masthead-copy { grid-area: copy; max-inline-size: 42rem; min-inline-size: 0; }
.masthead-copy > :last-child { margin-block-end: 0; }
.masthead-copy .lede { margin-block-end: 0.75em; }
/* Two renditions of the icon, light and dark, shown by the same rules as the
   screenshot pairs so the colour-mode setting drives both. */
.app-icon {
  grid-area: icon;
  inline-size: var(--icon);
  block-size: auto;
  border-radius: 22.37%;
  box-shadow: 0 12px 30px rgb(0 0 0 / 0.25);
}
.cta {
  grid-area: cta;
  font-weight: 600;
  color: var(--text);
  margin: 0;
  text-wrap: balance;
}

.platforms {
  grid-area: chips;
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.platforms li {
  border: 1px solid var(--rule);
  background: var(--bg-raised);
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
  font-size: 0.95rem;
}

/* Every top-level section is a container, so the grids inside answer to the
   section's width rather than the viewport's. */
main > section { container-type: inline-size; }

.features-lead {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}
/* Beside the sticky heading the body column is three quarters of the section:
   one card per row until three fit across it, never two and an orphan. */
@container (min-width: 52rem) { .features-lead { grid-template-columns: 1fr; } }
@container (min-width: 66rem) { .features-lead { grid-template-columns: repeat(3, 1fr); } }
.features-lead li {
  max-inline-size: none;
  background: var(--bg-raised);
  border-radius: var(--radius);
  padding: 1.5rem 1.6rem 1.6rem;
}
.features-lead h3 { font-size: 1.3rem; margin-block-end: 0.4em; }
.features-lead p { margin: 0; color: var(--text-2); }

/* A section written as a heading and a body: the heading in a column of its own
   that stays put while the body beside it scrolls, so the label of what you are
   reading is always in view. Narrow, the two stack and nothing sticks. The body
   column is what marks a section as this shape — a page that is one column of
   prose has no .section-body, and keeps its own flow. */
main > section > .wrap:has(> .section-body) {
  display: grid;
  gap: 1rem var(--gap);
  grid-template-columns: 1fr;
}
main > section > .wrap:has(> .section-body) > h2,
.section-side > h2 { margin: 0; }
.section-side > h2 { margin-block-end: 1rem; }
@container (min-width: 52rem) {
  main > section > .wrap:has(> .section-body) {
    grid-template-columns: minmax(12rem, 1fr) minmax(0, 3fr);
    align-items: start;
  }
  main > section > .wrap:has(> .section-body) > :first-child { position: sticky; inset-block-start: 5rem; }
  /* The device tabs live under the Screenshots heading, so they stand in a
     column there: a rule down the side, the selected one marked on it. */
  .section-side .tablist {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
    border-block-end: 0;
    border-inline-start: 1px solid var(--rule);
  }
  .section-side .tablist a {
    margin: 0 0 0 -1px;
    border-block-end: 0;
    border-inline-start: 3px solid transparent;
  }
  .section-side .tablist a[aria-selected="true"] { border-inline-start-color: var(--link); }
}
.section-body > :first-child { margin-block-start: 0; }
.section-body > :last-child { margin-block-end: 0; }

.features-more {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 1.1rem;
}
.features-more li {
  max-inline-size: var(--measure);
  color: var(--text-2);
}
.features-more strong { color: var(--text); }

/* ---- Screenshots ---------------------------------------------------------- */

/* Tabs: one device at a time. The selected tab is bold with a thick underline in
   the link colour, so the state is not carried by colour alone. Without scripts the
   panels are all shown and these are plain jump links. */
.tablist {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  border-block-end: 1px solid var(--rule);
}
.tablist a {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  padding-inline: 1rem;
  margin-block-end: -1px;
  text-decoration: none;
  color: var(--text);
  border-block-end: 3px solid transparent;
}
.tablist a:hover { background: var(--bg-raised); }
.tablist a[aria-selected="true"] {
  font-weight: 700;
  color: var(--link);
  border-block-end-color: var(--link);
}
.tablist a:focus-visible { outline-offset: -3px; }

.platform { margin-block-start: 2.5rem; }
.platform[role="tabpanel"] { margin-block-start: 0; }
.tabs-live .platform > h3 {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.platform:focus-visible { outline-offset: 6px; }

.gallery {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  margin: 0;
}
.gallery.tall { grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); }

.gallery figure {
  margin: 0;
  display: grid;
  grid-template-rows: auto 1fr;
  gap: 0.6rem;
}
.gallery figure.pending { grid-template-rows: auto auto 1fr; }
.gallery figcaption {
  order: 1;                       /* caption under the picture visually … */
  color: var(--text-2);
  font-size: 0.95rem;
}
.gallery figcaption strong { color: var(--text); }

/* The picture is the link. A window gets a shadow, a phone brings its own frame,
   an iPad is given one: Apple's convention, and the same on every tab. */
.gallery a.shot {
  display: block;
  border-radius: 10px;
  outline-offset: 6px;
}
.gallery img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}
.gallery.mac img {
  border-radius: 10px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.28), 0 0 0 1px rgb(0 0 0 / 0.08);
}
.gallery.iphone img { filter: drop-shadow(0 8px 18px rgb(0 0 0 / 0.25)); }
.gallery.ipad a.shot {
  padding: 3.2%;
  background: #1c1c1e;
  border-radius: 7.5%;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.28);
}
.gallery.ipad img { border-radius: 2.5%; }
.gallery figure { gap: 0.9rem; }

/* Every screen is in the markup twice, once per appearance, and the page shows the
   one that matches its own colour mode. Same three-way rule as the tokens at the
   top: system, then an explicit choice either way. A hidden lazy image is never
   fetched, so the page costs one picture per screen, not two. */
[data-appearance="dark"] { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) [data-appearance="light"] { display: none; }
  :root:not([data-theme="light"]) [data-appearance="dark"] { display: block; }
}
:root[data-theme="dark"] [data-appearance="light"] { display: none; }
:root[data-theme="dark"] [data-appearance="dark"] { display: block; }

/* A screenshot that could not be taken says so in words, not with a broken image. */
.placeholder {
  border: 2px dashed var(--rule);
  border-radius: var(--radius);
  padding: 1.25rem;
  display: grid;
  place-content: center;
  text-align: center;
  color: var(--text-2);
  min-block-size: 12rem;
  aspect-ratio: 4 / 3;
}
.placeholder strong { color: var(--text); }

/* ---- Details / notes ------------------------------------------------------ */

.note {
  border-inline-start: 4px solid var(--accent);
  background: var(--bg-raised);
  padding: 0.9rem 1.2rem;
  border-radius: 0 var(--radius) var(--radius) 0;
  max-inline-size: var(--measure);
}
.note p:last-child { margin: 0; }

table.facts {
  border-collapse: collapse;
  inline-size: 100%;
  max-inline-size: 56rem;
  margin: 0;
}
table.facts th,
table.facts td {
  text-align: start;
  vertical-align: top;
  padding: 0.85rem 0;
  border-block-end: 1px solid var(--rule);
}
table.facts th { font-weight: 600; white-space: nowrap; padding-inline-end: 2rem; }
table.facts td { max-inline-size: var(--measure); text-wrap: pretty; }
.fn-ref { font-size: 0.6em; line-height: 0; vertical-align: super; margin-inline-start: 0.1em; }
.fn-ref a { text-decoration: none; padding-inline: 0.15em; }
.footnote {
  margin-block: 1.5rem 0;
  font-size: 0.95rem;
  color: var(--text-2);
  max-inline-size: var(--measure);
}
.footnote .fn-num { display: inline-block; min-inline-size: 1.2em; }
.footnote:target { color: var(--text); }
@container (max-width: 30rem) {
  table.facts th, table.facts td { display: block; padding-block: 0.3rem; border: 0; }
  table.facts tr { display: block; padding-block: 0.6rem; border-block-end: 1px solid var(--rule); }
  table.facts th { white-space: normal; }
}

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

.site-footer {
  border-block-start: 1px solid var(--rule);
  padding-block: 2.5rem;
  color: var(--text-2);
  font-size: 0.95rem;
}
.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: start;
  gap: 1.5rem var(--gap);
}
.footer-brand { max-inline-size: 36rem; }
.footer-brand .brand { font-size: 1.05rem; min-block-size: 0; margin-block-end: 0.5rem; }
.footer-brand .brand svg { inline-size: 1.5rem; block-size: 1.5rem; }
.site-footer p { margin: 0; }
.footer-links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.5rem;
}
.footer-links a {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
}
.footer-links a[aria-current="page"] { color: var(--text); text-decoration: none; }

.prose { max-inline-size: var(--measure); }
.prose h2 { font-size: 1.35rem; margin-block: 2rem 0.5em; }
.prose ul { padding-inline-start: 1.25rem; }
.prose li { margin-block-end: 0.4em; }

/* ---- Print ---------------------------------------------------------------- */

@media print {
  .site-header, .skip-link, .theme-switch, .tablist { display: none; }
  .platform[hidden] { display: block; }
  a { color: inherit; text-decoration: none; }
  main > section { break-inside: avoid; }
}

/* ---- Screenshot viewer ---------------------------------------------------- */

/* The dialog fits its content. The stage is sized by the script to the largest
   picture in the set being stepped through, at the picture's natural size, and
   capped by the viewport: a phone gets a phone-sized frame, and stepping within a
   set moves nothing but the picture. --stage-w and --stage-h are set on the dialog. */
.lightbox {
  border: 0;
  padding: 0;
  margin: auto;
  inline-size: fit-content;
  max-inline-size: 96vw;
  max-block-size: 96dvh;
  background: var(--bg);
  color: var(--text);
  border-radius: var(--radius);
  box-shadow: 0 24px 64px rgb(0 0 0 / 0.45);
  overflow: auto;
}
.lightbox::backdrop {
  background: rgb(0 0 0 / 0.72);
}
.lightbox-body {
  display: grid;
  grid-template-rows: auto auto auto;
  justify-items: stretch;
  gap: 0.75rem;
  padding: 0.75rem 1rem 1rem;
}
.lightbox-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.lightbox-status {
  margin: 0;
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  align-items: baseline;
}
.lightbox-title { font-weight: 600; }
.lightbox-counter { color: var(--text-2); font-variant-numeric: tabular-nums; }

.lightbox button {
  min-inline-size: 44px;
  min-block-size: 44px;
  padding-inline: 0.9rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.lightbox button:hover { border-color: var(--accent); }
.lightbox button svg { inline-size: 1.1rem; block-size: 1.1rem; }
.lightbox-close { padding-inline: 0; justify-content: center; flex: none; }

/* The script keeps the stage within the viewport; the caps here only stop a
   stale value from ever pushing the dialog off screen. */
.lightbox-stage {
  position: relative;
  justify-self: center;
  inline-size: min(var(--stage-w, 48rem), 96vw - 2rem);
  block-size: min(var(--stage-h, 32rem), 96dvh - 10rem);
  background: var(--bg-inset);
  border-radius: 6px;
}
/* Positioned rather than laid out: a percentage max-size on a grid item answers
   to an auto track, which is nothing, while a positioned box answers to the stage. */
.lightbox-image {
  position: absolute;
  inset: 0.5rem;
  margin: auto;
  inline-size: auto;
  block-size: auto;
  max-inline-size: calc(100% - 1rem);
  max-block-size: calc(100% - 1rem);
}

.lightbox-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem 1rem;
}
.lightbox-sets {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 0.75rem;
}

/* A segmented control: one pill, a button per choice, every choice visible. The
   pressed one is filled and bold, so the state is not carried by colour alone.
   Used for the colour mode in the header and for device and appearance in the
   viewer. */
.pill {
  display: inline-flex;
  border: 1px solid var(--rule);
  border-radius: 999px;
  overflow: hidden;
  background: var(--bg-raised);
}
.pill button {
  min-inline-size: 44px;
  min-block-size: 44px;
  padding-inline: 0.9rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.pill button + button { border-inline-start: 1px solid var(--rule); }
.pill button:hover { background: var(--bg-inset); }
.pill button[aria-pressed="true"] {
  background: var(--link);
  color: var(--bg);
  font-weight: 700;
}
.pill button:focus-visible { outline-offset: -3px; }
/* The viewer's buttons are all pills or stand-alone; the pill rules above win on
   specificity for the halves. */
.lightbox .pill button { border: 0; border-radius: 0; background: transparent; }
.lightbox .pill button + button { border-inline-start: 1px solid var(--rule); }
.lightbox .pill button:hover { background: var(--bg-inset); }
.lightbox .pill button[aria-pressed="true"] { background: var(--link); }

/* Narrow: the pills take a row of their own above Previous and Next. Set by the
   script from the stage's width (`data-narrow`), and by the viewport as a
   backstop. Not a container query, because inline-size containment would stop a
   fit-content dialog measuring its content. */
.lightbox[data-narrow] .lightbox-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.lightbox[data-narrow] .lightbox-sets {
  grid-column: 1 / -1;
  order: -1;
}
.lightbox[data-narrow] .lightbox-next { justify-self: end; }
@media (max-width: 40rem) {
  .lightbox-nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
  .lightbox-sets {
    grid-column: 1 / -1;
    order: -1;
  }
  .lightbox-next { justify-self: end; }
  .lightbox-stage { block-size: min(var(--stage-h, 32rem), 96dvh - 13.5rem); }
}
