/* Documentation chrome for the Dovetail site.

   Every value here is a Dovetail token. The site is built from the system it
   documents, so a broken token shows up as a broken page, which is the point.
   Load order: system/styles.css first, then this file. */

:root {
  --site-sidebar: 264px;
  --site-header: 56px;
  --site-measure: 74ch;
}

/* ----------------------------------------------------------------- layout */

body {
  min-height: 100vh;
}

.layout {
  display: grid;
  grid-template-columns: var(--site-sidebar) minmax(0, 1fr);
  align-items: start;
  gap: 0;
}

.main {
  min-width: 0;
  padding: var(--dt-space-inset-xl) var(--dt-space-inset-xl) var(--dt-dim-24);
  max-width: 1040px;
}

.main.wide {
  max-width: 1360px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: var(--dt-z-toast);
  padding: var(--dt-space-inset-sm) var(--dt-space-inset-md);
  background: var(--dt-surface-raised);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-control);
  text-decoration: none;
}

.skip-link:focus {
  left: var(--dt-space-inset-sm);
  top: var(--dt-space-inset-sm);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ----------------------------------------------------------------- header */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--dt-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-md);
  height: var(--site-header);
  padding: 0 var(--dt-space-inset-lg);
  background: var(--dt-surface-base);
  border-bottom: var(--dt-border-width-default) solid var(--dt-border-default);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-space-inline-xs);
  font-family: var(--dt-text-heading-sm-family);
  font-size: var(--dt-font-size-md);
  font-weight: var(--dt-font-weight-semibold);
  letter-spacing: var(--dt-tracking-tight);
  color: var(--dt-text-wordmark, var(--dt-text-primary));
  text-decoration: none;
}

.wordmark-mark {
  height: var(--dt-size-icon-lg);
  width: auto;
  max-width: var(--dt-dim-32);
  object-fit: contain;
}

/* The system's base sheet gives img display: block, which outranks the
   browser's own [hidden] rule, so hidden has to be said here. */
.wordmark-mark[hidden],
.wordmark-logo[hidden],
.wordmark-text[hidden] {
  display: none;
}

/* An uploaded wordmark file stands in for the name. */
.wordmark-logo {
  height: var(--dt-dim-6);
  width: auto;
  max-width: 12rem;
  object-fit: contain;
}

.wordmark-logo-tint {
  display: inline-block;
  height: var(--dt-dim-6);
  aspect-ratio: 4 / 1;
  max-width: 12rem;
  background: currentColor;
  -webkit-mask: center / contain no-repeat;
  mask: center / contain no-repeat;
}

/* The uploaded mark as a mask over the wordmark's colour. */
.wordmark-mark-tint {
  display: inline-block;
  height: var(--dt-size-icon-lg);
  aspect-ratio: 1;
  max-width: var(--dt-dim-32);
  background: currentColor;
  -webkit-mask: center / contain no-repeat;
  mask: center / contain no-repeat;
}

.wordmark-note {
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-tertiary);
}

.header-controls {
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-sm);
  margin-left: auto;
}

.nav-toggle {
  height: var(--dt-size-control-sm);
  padding: 0 var(--dt-space-inset-sm);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-primary);
  background: var(--dt-surface-base);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-control);
}

.nav-toggle {
  display: none;
  cursor: pointer;
  transition: background var(--dt-motion-micro);
}

.nav-toggle:hover {
  background: var(--dt-surface-subtle);
}

/* ---------------------------------------------------------------- sidebar */

.sidebar {
  position: sticky;
  top: var(--site-header);
  height: calc(100vh - var(--site-header));
  overflow-y: auto;
  padding: var(--dt-space-inset-md) var(--dt-space-inset-sm) var(--dt-dim-16);
  border-right: var(--dt-border-width-default) solid var(--dt-border-default);
  background: var(--dt-surface-subtle);
  font-size: var(--dt-font-size-sm);
}

.sidebar ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sidebar a {
  display: block;
  padding: var(--dt-dim-1) var(--dt-space-inset-xs);
  border-radius: var(--dt-radius-control);
  color: var(--dt-text-secondary);
  text-decoration: none;
  transition: background var(--dt-motion-micro), color var(--dt-motion-micro);
}

.sidebar a:hover {
  background: var(--dt-surface-action-ghost-hover);
  color: var(--dt-text-primary);
}

.sidebar a[aria-current="page"] {
  background: var(--dt-surface-selected);
  color: var(--dt-text-on-selected);
  font-weight: var(--dt-font-weight-medium);
}

.nav-section {
  margin-top: var(--dt-space-stack-xs);
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
  padding-top: var(--dt-space-stack-xs);
}

.nav-section > summary {
  cursor: pointer;
  padding: var(--dt-dim-1) var(--dt-space-inset-xs);
  font-size: var(--dt-font-size-2xs);
  font-weight: var(--dt-font-weight-semibold);
  letter-spacing: var(--dt-tracking-wider);
  text-transform: uppercase;
  color: var(--dt-text-tertiary);
}

.nav-group {
  padding: var(--dt-space-stack-xs) var(--dt-space-inset-xs) var(--dt-dim-1);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
  color: var(--dt-text-tertiary);
}

/* ----------------------------------------------------------------- typography */

/* The headings take their family from the type role rather than from the sans
   primitive, so the site follows a display face the way a product built on the
   system would. With no display face chosen the roles point at the sans
   family, which is what they already did. */
/* Every page title is set in Display 1, the whole role: family, size, line,
   weight and tracking. A display face, a context or a theme that retunes
   Display 1 retunes the docs' headers with it. */
h1 {
  margin: 0 0 var(--dt-space-stack-sm);
  color: var(--dt-text-headline, var(--dt-text-primary));
  font-family: var(--dt-text-display-lg-family);
  font-size: var(--dt-text-display-lg-size);
  line-height: var(--dt-text-display-lg-line);
  font-weight: var(--dt-text-display-lg-weight);
  letter-spacing: var(--dt-text-display-lg-tracking);
  text-wrap: balance;
}

h2 {
  margin: var(--dt-dim-12) 0 var(--dt-space-stack-sm);
  color: var(--dt-text-headline, var(--dt-text-primary));
  font-family: var(--dt-text-heading-lg-family);
  font-size: var(--dt-font-size-2xl);
  line-height: var(--dt-line-height-2xl);
  font-weight: var(--dt-font-weight-semibold);
  letter-spacing: var(--dt-tracking-snug);
}

h3 {
  margin: var(--dt-dim-8) 0 var(--dt-space-stack-xs);
  color: var(--dt-text-headline, var(--dt-text-primary));
  font-family: var(--dt-text-heading-md-family);
  font-size: var(--dt-font-size-lg);
  line-height: var(--dt-line-height-lg);
  font-weight: var(--dt-font-weight-semibold);
}

h4 {
  margin: var(--dt-dim-6) 0 var(--dt-dim-2);
  font-family: var(--dt-text-heading-sm-family);
  font-size: var(--dt-font-size-md);
  font-weight: var(--dt-font-weight-semibold);
}

p,
ul,
ol {
  max-width: var(--site-measure);
}

.prose p,
.prose li {
  color: var(--dt-text-secondary);
}

.prose h2 + p,
.prose h3 + p {
  margin-top: 0;
}

.lede {
  max-width: var(--site-measure);
  font-size: var(--dt-font-size-lg);
  line-height: var(--dt-line-height-lg);
  color: var(--dt-text-secondary);
  text-wrap: pretty;
}

.muted {
  color: var(--dt-text-tertiary);
  font-size: var(--dt-font-size-sm);
}

blockquote {
  margin: var(--dt-space-stack-md) 0;
  padding: var(--dt-space-inset-sm) var(--dt-space-inset-md);
  background: var(--dt-surface-subtle);
  border-radius: var(--dt-radius-container);
  color: var(--dt-text-secondary);
}

blockquote p:last-child {
  margin-bottom: 0;
}

hr {
  height: 0;
  margin: var(--dt-dim-12) 0;
  border: 0;
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
}

/* ---------------------------------------------------------------- crumbs */

.crumbs {
  margin-bottom: var(--dt-space-stack-md);
}

.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-space-inline-xs);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-tertiary);
}

.crumbs li + li::before {
  content: "/";
  margin-right: var(--dt-space-inline-xs);
  color: var(--dt-text-disabled);
}

.crumbs a {
  color: var(--dt-text-secondary);
  text-decoration: none;
}

.crumbs a:hover {
  text-decoration: underline;
}

/* ------------------------------------------------------------------- hero */

.hero {
  padding-bottom: var(--dt-dim-8);
  border-bottom: var(--dt-border-width-default) solid var(--dt-border-subtle);
}

.eyebrow {
  margin: 0 0 var(--dt-dim-2);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
  letter-spacing: var(--dt-tracking-wider);
  text-transform: uppercase;
  color: var(--dt-text-tertiary);
}

.hero-lede {
  font-size: var(--dt-font-size-xl);
  line-height: var(--dt-line-height-xl);
  color: var(--dt-text-primary);
  text-wrap: pretty;
}

.hero-sub {
  color: var(--dt-text-secondary);
  text-wrap: pretty;
}

.hero-note {
  margin-top: var(--dt-space-stack-md);
  padding: var(--dt-space-inset-sm) var(--dt-space-inset-md);
  background: var(--dt-surface-subtle);
  border-radius: var(--dt-radius-container);
  font-size: var(--dt-font-size-sm);
  line-height: var(--dt-line-height-sm);
  color: var(--dt-text-secondary);
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-space-inline-sm);
  margin-top: var(--dt-space-stack-md);
}

.btn {
  display: inline-flex;
  align-items: center;
  height: var(--dt-size-control-md);
  padding: 0 var(--dt-space-inset-md);
  border: var(--dt-border-width-default) solid var(--dt-border-action-secondary);
  border-radius: var(--dt-button-radius, var(--dt-radius-control));
  background: var(--dt-surface-action-secondary);
  color: var(--dt-text-on-action-secondary);
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
  text-decoration: none;
  transition: background var(--dt-motion-micro);
}

.btn:hover {
  background: var(--dt-surface-action-secondary-hover);
  color: var(--dt-text-on-action-secondary);
}

.btn-primary {
  background: var(--dt-surface-action);
  border-color: var(--dt-color-transparent);
  color: var(--dt-text-on-action);
}

.btn-primary:hover {
  background: var(--dt-surface-action-hover);
  color: var(--dt-text-on-action);
}

/* ------------------------------------------------------------------ tiles */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--dt-space-inline-md);
  margin: var(--dt-space-stack-lg) 0;
}

.tiles.compact {
  /* Wider than the plain tile grid: a specimen needs room to render at the size
     the component actually is. */
  grid-template-columns: repeat(auto-fill, minmax(264px, 1fr));
}

.tile {
  position: relative;
  display: block;
  padding: var(--dt-card-padding);
  background: var(--dt-card-bg);
  border: var(--dt-card-border-width) solid var(--dt-card-border-color);
  border-radius: var(--dt-card-radius);
  box-shadow: var(--dt-card-elevation);
  color: var(--dt-text-primary);
  text-decoration: none;
  transition: box-shadow var(--dt-motion-micro), border-color var(--dt-motion-micro);
}

.tile:hover {
  border-color: var(--dt-border-strong);
  box-shadow: var(--dt-card-elevation-hover);
  color: var(--dt-text-primary);
}

.tile-icon {
  display: block;
  width: var(--dt-size-icon-lg);
  height: var(--dt-size-icon-lg);
  margin-bottom: var(--dt-space-stack-xs);
  color: var(--dt-text-link);
  /* The chrome follows whichever icon library the Configure sheet has selected:
     each library is drawn at its own weight, and an explicit stroke wins. */
  stroke-width: var(--site-icon-stroke, 2);
}

.tile:hover .tile-icon {
  color: var(--dt-text-link-hover);
}

.tile h2,
.tile h3 {
  margin: 0 0 var(--dt-dim-1);
  font-size: var(--dt-font-size-md);
  line-height: var(--dt-line-height-md);
  font-weight: var(--dt-font-weight-semibold);
}

.tile p {
  margin: 0;
  /* Three lines, so a long summary does not make one card twice the height of
     its neighbour. The whole description is on the component's own page. */
  max-width: 46ch;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  font-size: var(--dt-font-size-sm);
  line-height: var(--dt-line-height-sm);
  color: var(--dt-text-secondary);
  text-wrap: pretty;
}

.tile-meta,
.tile-specimen-note {
  -webkit-line-clamp: none;
  line-clamp: none;
  display: block;
}

/* A component card holds a link rather than being one, because a menu button
   cannot sit inside an anchor. The link is stretched over the card instead. */
.tile-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--dt-space-inline-xs);
}

.tile-head h3 {
  margin: 0 0 var(--dt-dim-1);
}

.tile-link {
  color: inherit;
  text-decoration: none;
}

.tile-link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.tile-menu-btn {
  position: relative;
  z-index: 1;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--dt-size-control-sm);
  height: var(--dt-size-control-sm);
  margin: calc(-1 * var(--dt-dim-1)) calc(-1 * var(--dt-dim-1)) 0 0;
  padding: 0;
  border: 0;
  border-radius: var(--dt-radius-control);
  background: transparent;
  color: var(--dt-text-tertiary);
  cursor: pointer;
  transition: background var(--dt-motion-micro), color var(--dt-motion-micro);
}

.tile-menu-btn svg {
  width: var(--dt-size-icon-md);
  height: var(--dt-size-icon-md);
  stroke-width: var(--site-icon-stroke, 2);
}

.tile-menu-btn:hover,
.tile-menu-btn[aria-expanded="true"] {
  background: var(--dt-surface-action-ghost-hover);
  color: var(--dt-text-primary);
}

/* A specimen is the component itself, rendered small. It sits inside a link, so
   it takes no pointer events and is hidden from assistive technology: the card
   already has a name, and a second set of controls inside a link is a trap. */
.tile-specimen {
  position: relative;
  height: var(--dt-dim-24);
  margin-bottom: var(--dt-space-stack-sm);
  overflow: hidden;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.tile-specimen[data-rendered]::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: var(--dt-dim-6);
  background: linear-gradient(to bottom, transparent, var(--dt-card-bg));
}

.tile-specimen > * {
  max-width: 100%;
}

.tile-specimen-note {
  justify-content: flex-end;
  height: auto;
  min-height: var(--dt-dim-10);
  font-size: var(--dt-font-size-xs);
  line-height: var(--dt-line-height-xs);
  color: var(--dt-text-tertiary);
  text-wrap: pretty;
}

.tile-component {
  display: flex;
  flex-direction: column;
}

.tile-meta {
  margin-top: var(--dt-dim-2) !important;
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs) !important;
  color: var(--dt-text-tertiary) !important;
}

/* The tier key above a component's token list: three short lines, set apart
   from body copy because they are a legend, not prose. */
.tier-key {
  list-style: none;
  margin: 0 0 var(--dt-space-stack-sm);
  padding: 0;
  font-size: var(--dt-font-size-sm);
  color: var(--dt-text-secondary);
}

.tier-key li + li {
  margin-top: var(--dt-dim-1);
}

.tier-key strong {
  display: inline-block;
  min-width: 9ch;
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  font-weight: var(--dt-font-weight-medium);
  color: var(--dt-text-primary);
}

/* A token the source asks for that no tier declares. It is a defect, so it is
   marked as one rather than left as an empty cell. */
.token-undefined {
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-danger);
}

.group + .group {
  margin-top: var(--dt-dim-12);
}

/* The sentence under a family heading. It reads at body size but in the
   secondary role, so it sits between the heading and the cards rather than
   competing with either. */
.group-note {
  max-width: 68ch;
  margin: calc(var(--dt-dim-1) * -1) 0 var(--dt-space-stack-md);
  color: var(--dt-text-secondary);
}

/* -------------------------------------------------------------- live cards */

.card-block {
  margin: var(--dt-dim-12) 0;
  scroll-margin-top: calc(var(--site-header) + var(--dt-dim-4));
}

.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--dt-space-inline-sm);
}

.card-head h2,
.card-head h3 {
  margin: 0;
}

/* The templates page: a heading per kind (Product, Marketing, Social), the
   same three the menu opens on, with its templates as h3 cards under it. */
.tpl-kind {
  margin-bottom: 0;
  scroll-margin-top: calc(var(--site-header) + var(--dt-dim-4));
}

.tpl-kind-sub {
  margin: var(--dt-dim-1) 0 var(--dt-space-stack-md);
  color: var(--dt-text-tertiary);
}

.card-open {
  flex: none;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-link);
}

.card-sub {
  margin: var(--dt-dim-1) 0 var(--dt-space-stack-sm);
  max-width: var(--site-measure);
  font-size: var(--dt-font-size-sm);
  color: var(--dt-text-secondary);
  text-wrap: pretty;
}

.frame {
  overflow: hidden;
  background: var(--dt-surface-subtle);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-container);
}

.frame iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: transparent;
}

/* --------------------------------------------------------- code and tables */

.code {
  overflow-x: auto;
  margin: var(--dt-space-stack-md) 0;
  padding: var(--dt-space-inset-md);
  background: var(--dt-surface-sunken);
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-container);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  line-height: var(--dt-line-height-sm);
  color: var(--dt-text-primary);
}

.code code {
  font-size: inherit;
}

code {
  font-family: var(--dt-font-family-mono);
  font-size: 0.92em;
}

p code,
li code,
td code,
th code {
  padding: 1px 4px;
  background: var(--dt-surface-sunken);
  border-radius: var(--dt-radius-raw-4);
}

/* A long path in a sentence or a table cell breaks where it must rather than
   widening the page: on a phone that stretched the layout and shrank it. */
p code,
li code,
td code,
th code,
blockquote p {
  overflow-wrap: anywhere;
}

.table-wrap {
  overflow-x: auto;
  margin: var(--dt-space-stack-md) 0;
  border: var(--dt-table-border-width) solid var(--dt-table-border-color);
  border-radius: var(--dt-table-radius);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--dt-font-size-sm);
  background: var(--dt-table-bg);
}

thead th {
  position: sticky;
  top: 0;
  padding: var(--dt-table-cell-padding-y) var(--dt-table-cell-padding-x);
  text-align: left;
  background: var(--dt-table-header-bg);
  color: var(--dt-table-header-fg);
  font-size: var(--dt-table-header-font-size);
  font-weight: var(--dt-table-header-font-weight);
  letter-spacing: var(--dt-table-header-tracking);
  border-bottom: var(--dt-table-border-width) solid var(--dt-table-border-color);
}

tbody th,
tbody td {
  padding: var(--dt-table-cell-padding-y) var(--dt-table-cell-padding-x);
  text-align: left;
  font-weight: var(--dt-font-weight-regular);
  vertical-align: top;
  border-top: var(--dt-table-border-width) solid var(--dt-table-border-color);
  color: var(--dt-text-secondary);
}

tbody tr:hover {
  background: var(--dt-table-row-bg-hover);
}

table.tokens tbody th code {
  color: var(--dt-text-primary);
}

table.tokens .usage {
  color: var(--dt-text-tertiary);
}

.swatch {
  display: inline-block;
  width: var(--dt-size-icon-sm);
  height: var(--dt-size-icon-sm);
  margin-right: var(--dt-space-inline-2xs, 4px);
  vertical-align: -3px;
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-raw-4);
}

.toc ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-space-inline-sm);
  max-width: none;
  margin: var(--dt-space-stack-md) 0;
  padding: 0;
  list-style: none;
  font-size: var(--dt-font-size-sm);
}

/* ------------------------------------------------------------------- meta */

.meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-space-inline-sm);
  max-width: none;
  margin: var(--dt-space-stack-sm) 0 var(--dt-space-stack-lg);
  font-size: var(--dt-font-size-xs);
}

.pill {
  padding: 2px var(--dt-space-inset-xs);
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-pill);
  background: var(--dt-surface-subtle);
  color: var(--dt-text-secondary);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
}

.doc h1:first-child {
  margin-top: 0;
}

/* ----------------------------------------------------------------- footer */

/* A colophon, not a navigation block: one line, set as the comment it is. The
   delimiters are dimmer than the words so the sentence reads first, and they
   are hidden from screen readers, which would otherwise spell them. */
.site-footer {
  padding: var(--dt-dim-12) var(--dt-space-inset-xl) var(--dt-dim-16);
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
  text-align: center;
}

.colophon {
  display: inline-flex;
  gap: var(--dt-space-inline-xs);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
  letter-spacing: var(--dt-tracking-wider);
  color: var(--dt-text-tertiary);
}

.colophon-mark {
  color: var(--dt-text-disabled);
}

/* ------------------------------------------------------------------ small */

@media (max-width: 900px) {
  .layout {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The drawer covers the page rather than pushing it down: a menu that moves
     the thing you were reading costs you your place, and on a phone it moved
     it by a screenful. It stops at the header, so the way out stays visible
     and in the same spot as the way in. */
  .sidebar {
    display: none;
    position: fixed;
    inset: var(--site-header) 0 0 0;
    z-index: calc(var(--dt-z-sticky) - 1);
    height: auto;
    overscroll-behavior: contain;
    padding-bottom: var(--dt-dim-24);
    background: var(--dt-surface-base);
    border-right: 0;
  }

  .sidebar.open {
    display: block;
  }

  /* The page behind the drawer must not scroll under it. */
  body.nav-open {
    overflow: hidden;
  }

  .nav-toggle {
    display: inline-flex;
    align-items: center;
  }

  .nav-toggle[aria-expanded="true"] {
    background: var(--dt-surface-selected);
    color: var(--dt-text-on-selected);
    border-color: var(--dt-surface-selected);
  }

  .wordmark-note {
    display: none;
  }

  .main {
    padding: var(--dt-space-inset-md);
  }

  /* Display 1 at phone width, capped by the screen so a long component
     name still fits on one line; the line height follows the size it
     lands on. */
  h1 {
    font-size: min(var(--dt-text-display-lg-size), 10.5vw);
    line-height: 1.1;
    overflow-wrap: break-word;
  }
}

/* ------------------------------------------------------- configure: the toolbar */

/* The toolbar floats above everything and never moves. Two controls: the one
   people flip constantly, and the one that opens the rest. */

/* Frosted glass, in the one place the system allows a raw alpha: a translucent
   surface is the effect, and there is no token for a fraction of one. The
   colour underneath is still a semantic token, so it follows the theme and the
   colour mode. Where backdrop-filter is unsupported the surface goes solid,
   because unreadable chrome is worse than flat chrome. */
:root {
  --configure-glass: color-mix(in oklab, var(--dt-surface-overlay) 82%, transparent);
  --configure-blur: saturate(1.8) blur(20px);
}

/* Configure's way in: one round button, frosted like the portfolio's tab bar. */
.configure-bar {
  position: fixed;
  right: var(--dt-space-inset-lg);
  bottom: var(--dt-space-inset-lg);
  z-index: var(--dt-z-toast);
  display: flex;
  border-radius: 50%;
  background: var(--configure-glass);
  -webkit-backdrop-filter: var(--configure-blur);
  backdrop-filter: var(--configure-blur);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.12), 0 0 0 1px rgb(0 0 0 / 0.06);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root {
    --configure-glass: var(--dt-surface-overlay);
  }
}

.configure-icon-btn,
.configure-open-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dt-space-inline-xs);
  height: var(--dt-size-control-sm);
  border: 0;
  border-radius: var(--dt-radius-pill);
  background: transparent;
  color: var(--dt-text-primary);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
  cursor: pointer;
  transition: background var(--dt-motion-micro);
}

.configure-icon-btn {
  width: var(--dt-size-control-sm);
  font-size: var(--dt-font-size-md);
  line-height: 1;
}

.configure-open-btn {
  width: 52px;
  height: 52px;
  padding: 0;
  border-radius: 50%;
}

.configure-open-btn svg {
  width: 22px;
  height: 22px;
}

.configure-icon-btn:hover,
.configure-open-btn:hover {
  background: var(--dt-surface-action-ghost-hover);
}

.configure-open-btn[aria-expanded="true"] {
  background: var(--dt-surface-selected);
  color: var(--dt-text-on-selected);
}

/* The pill and the sheet it opens never need to show at once: closing the
   sheet is the only way back to it, and the sheet's own close button already
   covers that. */
body.configure-open .configure-bar {
  display: none;
}

.configure-swatch {
  width: var(--dt-size-icon-md);
  height: var(--dt-size-icon-md);
  border-radius: var(--dt-radius-pill);
  box-shadow: inset 0 0 0 var(--dt-border-width-default) oklch(0 0 0 / 0.12);
}

/* --------------------------------------------------------- configure: the sheet */

/* The sheet never dims the page: the point of it is watching the system change
   alongside. On a wide screen it floats over the page as frosted glass, so what
   is behind it stays readable through the blur. On a narrow one it docks to the
   bottom and the page is padded to match, because at that width blurred glass
   over the content is not readable enough to count as visible. */

.configure-sheet {
  position: fixed;
  top: calc(var(--site-header) + var(--dt-dim-3));
  right: var(--dt-dim-3);
  bottom: var(--dt-dim-3);
  z-index: var(--dt-z-dialog);
  display: flex;
  flex-direction: column;
  width: var(--configure-width, 400px);
  max-width: calc(100vw - var(--dt-dim-6));
  overflow: hidden;
  background: var(--dt-surface-overlay);
  border-radius: var(--dt-radius-overlay);
  /* Gainer's menu and sheet shadow: a soft drop plus a hairline ring, so the
     edge reads without a border on any page behind it. */
  box-shadow: var(--configure-shadow);
}

:root {
  --configure-shadow: 0 12px 32px rgb(0 0 0 / 0.16), 0 0 0 1px rgb(0 0 0 / 0.06);
}

.dark {
  --configure-shadow: 0 12px 32px rgb(0 0 0 / 0.5), 0 0 0 1px rgb(255 255 255 / 0.08);
}

/* A class selector outranks the user agent's [hidden] rule, so display: none
   has to be said here or the sheet never closes. */
.configure-sheet[hidden] {
  display: none;
}

.configure-sheet:not([hidden]) {
  animation: configure-in 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes configure-in {
  from { transform: translateY(20px) scale(0.98); opacity: 0; }
}

/* The body scrolls; the bar sticks to its top. As the body scrolls, --p goes
   from 0 to 1 and the big title shrinks away while its small copy fades into
   the bar, the way Gainer's sheets do. */
.configure-body {
  --configure-inset: var(--dt-space-inset-xl);
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  padding: 0 var(--configure-inset) var(--configure-inset);
}

.configure-bar-top {
  position: sticky;
  top: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) 64px;
  align-items: center;
  gap: var(--dt-dim-2);
  margin: 0 calc(-1 * var(--configure-inset) + var(--dt-dim-3));
  padding: var(--dt-dim-3) var(--dt-dim-3) var(--dt-dim-2);
  background: var(--dt-surface-overlay);
  box-shadow: 0 1px 0 rgb(0 0 0 / calc(var(--p, 0) * 0.08));
}

.configure-round {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: var(--dt-surface-sunken);
  color: var(--dt-text-primary);
  cursor: pointer;
  transition: background var(--dt-motion-micro);
}

.configure-round:hover {
  background: var(--dt-border-subtle);
}

.configure-round svg {
  width: 16px;
  height: 16px;
}

.configure-mini {
  margin: 0;
  text-align: center;
  font-size: var(--dt-font-size-md);
  font-weight: var(--dt-font-weight-medium);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: clamp(0, calc((var(--p, 0) - 0.6) * 2.5), 1);
}

.configure-bar-acts {
  justify-self: end;
  display: flex;
  gap: var(--dt-dim-2);
}

.configure-save {
  background: var(--dt-surface-action);
  color: var(--dt-text-on-action);
}

.configure-save:hover {
  background: var(--dt-surface-action-hover);
}

.configure-reset-btn {
  justify-self: end;
  height: 34px;
  padding: 0 15px;
  border: 0;
  border-radius: 17px;
  background: var(--dt-surface-sunken);
  color: var(--dt-text-primary);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
  cursor: pointer;
}

.configure-reset-btn:hover {
  background: var(--dt-border-subtle);
}

.configure-big {
  padding: var(--dt-dim-1) 0 var(--dt-dim-5);
  transform: scale(calc(1 - 0.08 * var(--p, 0)));
  transform-origin: 0 0;
  opacity: calc(1 - 0.8 * var(--p, 0));
}

.configure-eyebrow {
  margin: 0 0 2px;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-tertiary);
}

.configure-big h2 {
  margin: 0;
  font-size: 1.6rem;
  line-height: 1.15;
  font-weight: var(--dt-font-weight-regular);
  letter-spacing: -0.02em;
}

.configure-sub {
  margin: var(--dt-dim-1) 0 0;
  max-width: none;
  font-size: var(--dt-font-size-sm);
  line-height: var(--dt-line-height-sm);
  color: var(--dt-text-secondary);
  text-wrap: pretty;
}

/* The top layer: one row per group, like Gainer's menus. Each opens a layer. */
.configure-menu {
  display: flex;
  flex-direction: column;
  margin: 0 calc(-1 * var(--dt-dim-3));
}

.configure-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) 16px;
  align-items: center;
  gap: var(--dt-dim-3);
  width: 100%;
  padding: var(--dt-dim-3);
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--dt-text-primary);
  font-family: var(--dt-font-family-sans);
  text-align: left;
  cursor: pointer;
}

.configure-row:hover,
.configure-row:focus-visible {
  background: var(--dt-surface-sunken);
  outline: none;
}

.configure-row-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--dt-surface-sunken);
  color: var(--dt-text-primary);
}

.configure-row:hover .configure-row-icon {
  background: var(--dt-surface-overlay);
}

.configure-row-icon svg,
.configure-row-chev {
  width: 16px;
  height: 16px;
}

.configure-row-chev {
  color: var(--dt-text-tertiary);
}

.configure-row-label {
  display: block;
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
}

.configure-row-summary {
  display: block;
  margin-top: 1px;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.configure-panel {
  display: flex;
  flex-direction: column;
  gap: var(--dt-space-stack-lg);
}

.configure-panel:focus {
  outline: none;
}

/* Moving between layers: forward slides in from the right, back from the left. */
.configure-body.is-forward > * {
  animation: configure-fwd 0.24s ease-out both;
}

.configure-body.is-back > * {
  animation: configure-back 0.24s ease-out both;
}

.configure-body.is-forward > .configure-bar-top,
.configure-body.is-back > .configure-bar-top {
  animation: none;
}

@keyframes configure-fwd {
  from { opacity: 0; transform: translateX(28px); }
}

@keyframes configure-back {
  from { opacity: 0; transform: translateX(-28px); }
}

@media (prefers-reduced-motion: reduce) {
  .configure-sheet:not([hidden]),
  .configure-body.is-forward > *,
  .configure-body.is-back > * {
    animation: none;
  }
}

.configure-field {
  display: flex;
  flex-direction: column;
  gap: var(--dt-dim-2);
}

.configure-label {
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
  color: var(--dt-text-primary);
}

.configure-hint {
  margin-top: -2px;
  font-size: var(--dt-font-size-xs);
  line-height: var(--dt-line-height-xs);
  color: var(--dt-text-tertiary);
  text-wrap: pretty;
}

.configure-rule {
  margin: 0;
  height: 0;
  border: 0;
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
}

/* Controls */

.configure-select {
  width: 100%;
  height: var(--dt-size-control-md);
  padding: 0 var(--dt-space-inset-sm);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-sm);
  color: var(--dt-text-primary);
  background: var(--dt-input-bg);
  border: var(--dt-input-border-width) solid var(--dt-input-border);
  border-radius: var(--dt-input-radius);
}

.configure-seg {
  display: flex;
  padding: 2px;
  background: var(--dt-surface-sunken);
  border-radius: var(--dt-radius-control);
}

.configure-seg-btn {
  flex: 1;
  height: var(--dt-dim-8);
  padding: 0 var(--dt-space-inset-xs);
  border: 0;
  border-radius: calc(var(--dt-radius-control) - 1px);
  background: transparent;
  color: var(--dt-text-secondary);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-xs);
  font-weight: var(--dt-font-weight-medium);
  cursor: pointer;
  transition: background var(--dt-motion-micro), color var(--dt-motion-micro);
}

.configure-seg-btn:hover {
  color: var(--dt-text-primary);
}

.configure-seg-btn[aria-pressed="true"] {
  background: var(--dt-surface-raised);
  color: var(--dt-text-primary);
  box-shadow: var(--dt-elevation-1);
}

.configure-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-space-inline-xs);
}

.configure-swatch-btn {
  position: relative;
  width: var(--dt-dim-7);
  height: var(--dt-dim-7);
  padding: 0;
  border: 0;
  border-radius: var(--dt-radius-control);
  box-shadow: inset 0 0 0 var(--dt-border-width-default) oklch(0 0 0 / 0.12);
  cursor: pointer;
  transition: transform var(--dt-motion-micro);
}

.configure-swatch-btn:hover {
  transform: translateY(-1px);
}

.configure-swatch-btn[aria-pressed="true"] {
  outline: var(--dt-focus-ring-width) solid var(--dt-text-primary);
  outline-offset: var(--dt-focus-ring-offset);
}

.configure-swatch-custom {
  display: inline-flex;
  overflow: hidden;
  background: linear-gradient(135deg, var(--dt-color-red-500), var(--dt-color-violet-500), var(--dt-color-cyan-500));
}

.configure-color {
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  opacity: 0;
  cursor: pointer;
}

.configure-group {
  margin: var(--dt-space-stack-sm) 0 calc(-1 * var(--dt-space-stack-xs));
  padding-top: var(--dt-space-stack-sm);
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
  font-weight: var(--dt-font-weight-medium);
  letter-spacing: var(--dt-tracking-wider);
  text-transform: uppercase;
  color: var(--dt-text-tertiary);
}

.configure-stack {
  display: flex;
  flex-direction: column;
  gap: var(--dt-space-stack-xs);
}

.configure-text {
  width: 100%;
  height: var(--dt-size-control-md);
  padding: 0 var(--dt-space-inset-sm);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-sm);
  color: var(--dt-input-fg);
  background: var(--dt-input-bg);
  border: var(--dt-input-border-width) solid var(--dt-input-border);
  border-radius: var(--dt-input-radius);
}

.configure-drop {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--dt-dim-12);
  padding: var(--dt-space-inset-sm);
  text-align: center;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
  background: var(--dt-surface-subtle);
  border: var(--dt-border-width-default) dashed var(--dt-border-default);
  border-radius: var(--dt-radius-container);
  cursor: pointer;
  transition: border-color var(--dt-motion-micro), background var(--dt-motion-micro);
}

.configure-drop:hover,
.configure-drop[data-over] {
  border-color: var(--dt-border-selected);
  background: var(--dt-surface-selected);
}

.configure-file {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.configure-mark-row {
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-sm);
}

.configure-mark {
  width: auto;
  height: var(--dt-dim-8);
  max-width: var(--dt-dim-24);
  object-fit: contain;
}

.configure-mark.is-wordmark {
  max-width: var(--dt-dim-48, 12rem);
}

.configure-bad {
  margin: 0;
  max-width: none;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-danger);
}

.configure-export-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--dt-space-stack-xs);
}

.configure-export {
  width: 100%;
  resize: vertical;
  padding: var(--dt-space-inset-sm);
  background: var(--dt-surface-sunken);
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-container);
  color: var(--dt-text-secondary);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
  line-height: var(--dt-line-height-xs);
}

.configure-actions {
  display: flex;
  gap: var(--dt-space-inline-xs);
}

.configure-btn {
  flex: 1;
  height: var(--dt-size-control-md);
  padding: 0 var(--dt-space-inset-md);
  border: var(--dt-button-border-width) solid var(--dt-button-secondary-border);
  border-radius: var(--dt-button-radius);
  background: var(--dt-button-secondary-bg);
  color: var(--dt-button-secondary-fg);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
  cursor: pointer;
  transition: background var(--dt-motion-micro);
}

.configure-btn:hover {
  background: var(--dt-button-secondary-bg-hover);
}

.configure-btn-primary {
  border-color: var(--dt-color-transparent);
  background: var(--dt-button-primary-bg);
  color: var(--dt-button-primary-fg);
}

.configure-btn-primary:hover {
  background: var(--dt-button-primary-bg-hover);
}

.configure-note {
  margin: 0;
  max-width: none;
  font-size: var(--dt-font-size-xs);
  line-height: var(--dt-line-height-sm);
  color: var(--dt-text-tertiary);
  text-wrap: pretty;
}

.configure-hex-row {
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-sm);
}

.configure-hex-row .configure-hint {
  margin: 0;
  flex: none;
}

.configure-hex {
  flex: 1;
  font-family: var(--dt-font-family-mono);
  text-transform: lowercase;
}

.configure-ramp {
  display: grid;
  gap: 3px;
}

.configure-ramp-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
  cursor: pointer;
}

.configure-ramp-swatch {
  position: relative;
  display: block;
  width: 100%;
  height: var(--dt-dim-8);
  border-radius: var(--dt-radius-raw-4);
  box-shadow: inset 0 0 0 var(--dt-border-width-default) oklch(0 0 0 / 0.08);
}

.configure-ramp-swatch .configure-color {
  position: absolute;
  inset: 0;
}

.configure-ramp-chip[data-anchor] .configure-ramp-swatch,
.configure-ramp-chip[data-edited] .configure-ramp-swatch {
  outline: var(--dt-focus-ring-width) solid var(--dt-text-primary);
  outline-offset: 1px;
}

.configure-ramp-chip[data-edited] .configure-ramp-swatch {
  outline-style: dashed;
}

.configure-ramp-chip:focus-within .configure-ramp-swatch {
  outline: var(--dt-focus-ring-width) solid var(--dt-focus-ring-color);
}

.configure-ramp-step,
.configure-ramp-tag {
  font-family: var(--dt-font-family-mono);
  font-size: 9px;
  line-height: 1.2;
  color: var(--dt-text-tertiary);
}

.configure-ramp-tag {
  min-height: 1.2em;
  color: var(--dt-text-secondary);
}

.configure-good {
  color: var(--dt-text-success);
}

.configure-checks-wrap summary {
  cursor: pointer;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
}

/* Collapsed by default, so a failing pair says so where it can be seen. */
.configure-checks-wrap.has-fail summary {
  color: var(--dt-text-danger);
}

.configure-checks {
  list-style: none;
  margin: var(--dt-space-stack-xs) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--dt-space-stack-2xs);
  font-size: var(--dt-font-size-xs);
}

.configure-checks li {
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-xs);
}

.configure-check-mark {
  flex: none;
  width: 1.2em;
  text-align: center;
  font-weight: var(--dt-font-weight-semibold);
  color: var(--dt-text-success);
}

.configure-checks .is-fail .configure-check-mark,
.configure-checks .is-fail .configure-check-ratio {
  color: var(--dt-text-danger);
}

.configure-check-label {
  flex: 1;
  min-width: 0;
  color: var(--dt-text-secondary);
}

.configure-check-ratio {
  flex: none;
  font-family: var(--dt-font-family-mono);
  color: var(--dt-text-tertiary);
}

.configure-steps-preview {
  display: grid;
  grid-template-columns: repeat(11, minmax(0, 1fr));
  gap: 2px;
  height: var(--dt-dim-6);
}

.configure-steps-preview span {
  border-radius: var(--dt-radius-raw-2);
}

.configure-ramphue-list {
  display: flex;
  flex-direction: column;
  gap: var(--dt-space-stack-xs);
}

.configure-ramphue-row {
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-sm);
}

.configure-ramphue-row .configure-swatch-btn {
  flex: none;
  width: var(--dt-dim-7);
  height: var(--dt-dim-7);
}

.configure-ramphue-label {
  flex: 1;
  font-size: var(--dt-font-size-sm);
  color: var(--dt-text-primary);
}

.configure-btn-mini {
  flex: none;
  height: var(--dt-dim-6);
  padding: 0 var(--dt-space-inset-xs);
  border: 0;
  border-radius: var(--dt-radius-control);
  background: var(--dt-surface-sunken);
  color: var(--dt-text-secondary);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-2xs);
  font-weight: var(--dt-font-weight-medium);
  cursor: pointer;
}

.configure-btn-mini:hover {
  background: var(--dt-surface-action-ghost-hover);
  color: var(--dt-text-primary);
}

/* On a narrow screen the sheet takes the whole screen. At phone width there is
   no room to watch the page change beside it, and a half-height sheet left the
   controls cramped; closing it shows the result. The surface goes solid,
   because blurred glass over a full screen of content is not readable, and
   the page behind stops scrolling so a swipe moves the controls, not the page. */
@media (max-width: 720px) {
  .configure-sheet {
    top: auto;
    right: var(--dt-dim-2);
    bottom: calc(var(--dt-dim-2) + env(safe-area-inset-bottom, 0px));
    left: var(--dt-dim-2);
    width: auto;
    max-width: none;
    max-height: calc(100dvh - 64px);
    border-radius: 24px;
  }

  .configure-sheet:not([hidden]) {
    animation: configure-up 0.42s cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  .configure-body {
    --configure-inset: var(--dt-space-inset-lg);
  }

  .configure-bar-top {
    grid-template-columns: 76px minmax(0, 1fr) 76px;
  }

  body.configure-open {
    overflow: hidden;
  }

  .configure-bar {
    right: var(--dt-space-inset-md);
    bottom: var(--dt-space-inset-md);
  }
}

@keyframes configure-up {
  from { transform: translateY(100%); }
}

/* ------------------------------------------------------- the files menu */

/* Drawn on <body>, positioned against the button: on a narrow screen the card
   is inside a horizontal scroller, and a popup drawn in the card would be
   clipped by that overflow. */

.file-menu {
  position: fixed;
  z-index: var(--dt-z-dropdown);
  min-width: 210px;
  padding: 6px;
  background: var(--dt-surface-overlay);
  border-radius: 14px;
  box-shadow: var(--configure-shadow);
  transform-origin: top right;
}

.file-menu-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--dt-space-inline-md);
  width: 100%;
  padding: 11px 12px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-sm);
  color: var(--dt-text-primary);
  text-align: left;
  cursor: pointer;
  transition: background var(--dt-motion-micro);
}

.file-menu-item:hover {
  background: var(--dt-surface-action-ghost-hover);
}

.file-menu-name {
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
  color: var(--dt-text-tertiary);
}

/* ------------------------------------------------------ the file viewer */

.file-viewer[hidden] {
  display: none;
}

.file-viewer {
  position: fixed;
  inset: 0;
  z-index: var(--dt-z-dialog);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--dt-space-inset-lg);
}

.file-viewer-scrim {
  position: absolute;
  inset: 0;
  background: var(--dt-surface-scrim);
}

.file-viewer-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(760px, 100%);
  max-height: 100%;
  background: var(--dt-surface-overlay);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-overlay);
  box-shadow: var(--dt-elevation-5);
  overflow: hidden;
}

.file-viewer-head {
  display: flex;
  align-items: flex-start;
  gap: var(--dt-space-inline-sm);
  padding: var(--dt-space-inset-lg) var(--dt-space-inset-lg) var(--dt-space-inset-sm);
}

.file-viewer-head h2 {
  margin: 0;
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-md);
  font-weight: var(--dt-font-weight-semibold);
}

.file-viewer-note {
  margin: var(--dt-dim-1) 0 0;
  max-width: none;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
}

.file-viewer-close {
  margin-left: auto;
  width: var(--dt-size-control-sm);
  height: var(--dt-size-control-sm);
  flex: none;
  border: 0;
  border-radius: var(--dt-radius-control);
  background: transparent;
  color: var(--dt-text-secondary);
  font-size: var(--dt-font-size-xl);
  line-height: 1;
  cursor: pointer;
}

.file-viewer-close:hover {
  background: var(--dt-surface-action-ghost-hover);
  color: var(--dt-text-primary);
}

.file-viewer-tabs {
  display: flex;
  gap: var(--dt-dim-1);
  padding: 0 var(--dt-space-inset-lg) var(--dt-space-inset-sm);
}

.file-viewer-tab {
  height: var(--dt-dim-8);
  padding: 0 var(--dt-space-inset-sm);
  border: 0;
  border-radius: var(--dt-radius-pill);
  background: transparent;
  color: var(--dt-text-secondary);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-xs);
  font-weight: var(--dt-font-weight-medium);
  cursor: pointer;
}

.file-viewer-tab:hover {
  background: var(--dt-surface-action-ghost-hover);
  color: var(--dt-text-primary);
}

.file-viewer-tab[aria-selected="true"] {
  background: var(--dt-surface-action);
  color: var(--dt-text-on-action);
}

.file-viewer-body {
  flex: 1;
  overflow: auto;
  margin: 0;
  padding: var(--dt-space-inset-md) var(--dt-space-inset-lg);
  background: var(--dt-surface-sunken);
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-bottom: var(--dt-border-width-default) solid var(--dt-border-subtle);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  line-height: var(--dt-line-height-sm);
  color: var(--dt-text-primary);
  white-space: pre;
  tab-size: 2;
}

.file-viewer-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-space-inline-md);
  padding: var(--dt-space-inset-sm) var(--dt-space-inset-lg);
}

.file-viewer-link {
  font-size: var(--dt-font-size-sm);
  color: var(--dt-text-link);
}

body.file-viewer-open {
  overflow: hidden;
}

/* --------------------------------------------------- cards on a phone */

/* Every card grid becomes one swipeable row per group. Cards are equal height
   because the row is a flex line, the next one peeks past the edge so the
   swipe is discoverable, and the row bleeds to the page edges so nothing looks
   cropped by the gutter. */
@media (max-width: 720px) {
  .tiles {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--dt-space-inline-sm);
    margin-inline: calc(-1 * var(--dt-space-inset-md));
    padding-inline: var(--dt-space-inset-md);
    padding-block: var(--dt-dim-1);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--dt-space-inset-md);
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .tiles::-webkit-scrollbar {
    display: none;
  }

  .tiles > * {
    flex: 0 0 82%;
    scroll-snap-align: start;
  }

  .tile-specimen {
    height: var(--dt-dim-20);
  }

  .file-viewer {
    padding: 0;
    align-items: flex-end;
  }

  .file-viewer-panel {
    max-height: 88vh;
    border-radius: var(--dt-radius-overlay) var(--dt-radius-overlay) 0 0;
    border-width: var(--dt-border-width-default) 0 0;
  }
}

/* --------------------------------------------------------------- copying */

.code-wrap {
  position: relative;
}

/* Quiet until the block is under the pointer, like the graph row buttons: a
   page of eight code blocks should not read as a page of eight buttons. */
.copy-btn {
  position: absolute;
  top: var(--dt-space-inset-sm);
  right: var(--dt-space-inset-sm);
  height: var(--dt-size-control-xs);
  padding: 0 var(--dt-space-inset-sm);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-2xs);
  color: var(--dt-text-secondary);
  background: var(--dt-surface-base);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-control);
  opacity: 0;
  cursor: pointer;
  transition: opacity var(--dt-motion-micro), color var(--dt-motion-micro);
}

.code-wrap:hover .copy-btn,
.copy-btn:focus-visible,
.copy-btn.is-done {
  opacity: 1;
}

.copy-btn:hover {
  color: var(--dt-text-primary);
}

.copy-btn.is-done {
  color: var(--dt-text-success);
  border-color: var(--dt-text-success);
}

/* Open in builder sits at the foot of a JSX example, apart from Copy, with
   room left under the code so a one-line example doesn't put them together. */
.code-wrap:has(.open-btn) > pre {
  padding-bottom: calc(var(--dt-size-control-xs) + 2 * var(--dt-space-inset-sm));
}

/* Open in builder sits at the foot of a JSX example, apart from Copy. */
.open-btn {
  top: auto;
  bottom: var(--dt-space-inset-sm);
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

/* Touch has no hover. */
@media (hover: none) {
  .copy-btn {
    opacity: 1;
  }
}

/* In the file viewer the button lives in the header, so it is always visible
   and sits beside the close control rather than over the code. */
.file-viewer-actions {
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-xs);
}

.file-viewer-actions .copy-btn {
  position: static;
  height: var(--dt-size-control-sm);
  font-size: var(--dt-font-size-xs);
  opacity: 1;
}

/* ------------------------------------------------------- the node graph */

/* The visualiser is a dialog over the page, unlike the Configure sheet: there
   is nothing to watch behind it, and reading a graph wants the whole width. */

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.btn-graph {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-space-inline-xs);
  height: var(--dt-size-control-sm);
  padding: 0 var(--dt-space-inset-sm);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-xs);
  font-weight: var(--dt-font-weight-medium);
  color: var(--dt-text-on-action);
  background: var(--dt-surface-action);
  border: var(--dt-border-width-default) solid var(--dt-surface-action);
  border-radius: var(--dt-button-radius, var(--dt-radius-control));
  cursor: pointer;
  transition: background var(--dt-motion-micro);
}

.btn-graph:hover {
  background: var(--dt-surface-action-hover);
}

/* A row button is quiet until the row is under the pointer: hundreds of them
   at full strength would read as a column of controls rather than a table. */
.token-cell {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-space-inline-xs);
}

.graph-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--dt-size-icon-lg);
  height: var(--dt-size-icon-lg);
  padding: 0;
  color: var(--dt-text-tertiary);
  background: none;
  border: 0;
  border-radius: var(--dt-radius-control);
  opacity: 0;
  cursor: pointer;
  transition: opacity var(--dt-motion-micro), color var(--dt-motion-micro);
}

.graph-btn .icon {
  width: var(--dt-size-icon-sm);
  height: var(--dt-size-icon-sm);
}

tr:hover .graph-btn,
.graph-btn:focus-visible {
  opacity: 1;
}

.graph-btn:hover {
  color: var(--dt-text-link);
}

/* Touch has no hover, so the buttons are simply always there. */
@media (hover: none) {
  .graph-btn {
    opacity: 1;
  }
}

.graph-overlay[hidden] {
  display: none;
}

.graph-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--dt-z-dialog);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--dt-space-inset-lg);
  background: var(--dt-surface-scrim);
}

body.graph-open {
  overflow: hidden;
}

/* The Configure toolbar sits on the toast rung, which is above a dialog by the
   system's own ladder and correct in general. It is not reachable while a modal
   is up, though, so it steps aside rather than being demoted out of order. */
body.graph-open .configure-bar,
body.graph-open .configure-sheet {
  visibility: hidden;
}

.graph-panel {
  display: flex;
  flex-direction: column;
  width: min(1180px, 100%);
  max-height: 100%;
  background: var(--dt-surface-base);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-overlay);
  box-shadow: var(--dt-elevation-4);
  overflow: hidden;
}

.graph-head {
  display: flex;
  align-items: center;
  gap: var(--dt-space-inline-sm);
  padding: var(--dt-space-inset-sm) var(--dt-space-inset-md);
  border-bottom: var(--dt-border-width-default) solid var(--dt-border-subtle);
}

.graph-back,
.graph-close {
  height: var(--dt-size-control-sm);
  padding: 0 var(--dt-space-inset-sm);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-primary);
  background: var(--dt-surface-base);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-control);
  cursor: pointer;
}

.graph-close {
  margin-left: auto;
  width: var(--dt-size-control-sm);
  padding: 0;
  font-size: var(--dt-font-size-md);
  line-height: 1;
}

.graph-back[hidden] {
  display: none;
}

.graph-search {
  flex: 1;
  min-width: 0;
}

.graph-search input {
  width: 100%;
  height: var(--dt-size-control-sm);
  padding: 0 var(--dt-space-inset-sm);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-primary);
  background: var(--dt-surface-base);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-control);
}

.graph-body {
  position: relative;
  display: grid;
  grid-template-columns: 1fr minmax(0, 0.95fr) 1fr;
  gap: var(--dt-dim-12);
  padding: var(--dt-space-inset-md);
  overflow-y: auto;
}

.graph-wires {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

.graph-wire {
  fill: none;
  stroke: var(--dt-border-default);
  stroke-width: var(--dt-border-width-default);
}

/* The headings sit above the wires and the scrolled rows. */
.graph-col > h2 {
  position: sticky;
  top: 0;
  z-index: 2;
  padding-bottom: var(--dt-dim-1);
  background: var(--dt-surface-base);
  margin: 0 0 var(--dt-space-stack-xs);
  font-family: var(--dt-text-eyebrow-family);
  font-size: var(--dt-font-size-2xs);
  font-weight: var(--dt-font-weight-semibold);
  letter-spacing: var(--dt-tracking-wider);
  text-transform: uppercase;
  color: var(--dt-text-tertiary);
}

.graph-list {
  display: flex;
  flex-direction: column;
  gap: var(--dt-dim-2);
}

/* The selected node sticks to the top of the scroller. Centring it against a
   column of forty consumers put it off-screen, which is the one node that must
   never leave the view. */
.graph-col-focus .graph-list {
  position: sticky;
  top: var(--dt-dim-8);
}

.graph-node {
  display: block;
  width: 100%;
  padding: var(--dt-space-inset-sm);
  text-align: left;
  background: var(--dt-surface-base);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-container);
  cursor: pointer;
  transition: background var(--dt-motion-micro), border-color var(--dt-motion-micro);
}

.graph-node:hover {
  background: var(--dt-surface-subtle);
}

/* The tier a node belongs to is marked by a dot before its tier label. */
.graph-node { --graph-tier: var(--dt-border-default); }
.graph-node[data-tier="primitive"] { --graph-tier: var(--dt-color-primary-300); }
.graph-node[data-tier="semantic"] { --graph-tier: var(--dt-color-primary-500); }
.graph-node[data-tier="component"] { --graph-tier: var(--dt-color-primary-700); }
.graph-node[data-tier="consumer"] { --graph-tier: var(--dt-text-primary); }
.graph-node[data-tier="undeclared"] { --graph-tier: var(--dt-text-danger); }

.graph-node-meta::before {
  content: "";
  display: inline-block;
  width: var(--dt-dim-2);
  height: var(--dt-dim-2);
  margin-right: var(--dt-space-inline-2xs);
  border-radius: var(--dt-radius-pill);
  background: var(--graph-tier);
  vertical-align: 0.05em;
}

.graph-node.is-focus {
  background: var(--dt-surface-selected);
  cursor: default;
  position: relative;
  z-index: 1;
}

.graph-node-name {
  display: block;
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-primary);
  overflow-wrap: anywhere;
}

.graph-node-meta {
  display: block;
  margin-top: var(--dt-dim-1);
  font-size: var(--dt-font-size-2xs);
  color: var(--dt-text-tertiary);
}

.graph-node-value {
  display: block;
  margin-top: var(--dt-dim-1);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-2xs);
  color: var(--dt-text-secondary);
  overflow-wrap: anywhere;
}

.graph-node-warn {
  color: var(--dt-text-danger);
}

.graph-empty {
  margin: 0;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-tertiary);
}

.graph-foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-space-inline-sm);
  margin: 0;
  padding: var(--dt-space-inset-sm) var(--dt-space-inset-md);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
}

/* On a phone the three columns become three stacked sections, and the wires
   would cross the whole page to connect them, so they are dropped: the column
   headings already say which side you are reading. */
@media (max-width: 760px) {
  .graph-overlay {
    padding: 0;
  }

  .graph-panel {
    max-height: 100%;
    height: 100%;
    border: 0;
    border-radius: 0;
  }

  .graph-body {
    grid-template-columns: minmax(0, 1fr);
  }

  .graph-wires {
    display: none;
  }

  .graph-col-focus .graph-list {
    position: static;
  }
}

/* ------------------------------------------------- on this page, page menu */

/* Pages with three or more sections get a right-hand column listing them. The
   main column keeps its reading width and the list takes the space beside it,
   so it only appears where the viewport has that space to give. */
.main.has-toc {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: var(--dt-space-inline-xl);
}

.doc {
  min-width: 0;
}

.page-toc {
  display: none;
}

/* The column starts level with the breadcrumb, the first line of the page,
   and sticks just under the header as the page scrolls. */
@media (min-width: 1200px) {
  .main.has-toc:not(.wide) {
    grid-template-columns: minmax(0, 1fr) var(--dt-dim-56);
    max-width: calc(1040px + var(--dt-dim-56) + var(--dt-space-inline-xl));
  }

  .main.has-toc:not(.wide) .page-toc {
    display: block;
  }
}

/* Wide pages (tokens, showcase) hold tables and full-width cards that need
   the width more than a list of sections does, and the tokens page has its
   own section links; they get the column only on a genuinely wide screen. */
@media (min-width: 1600px) {
  .main.wide.has-toc {
    grid-template-columns: minmax(0, 1fr) var(--dt-dim-56);
    max-width: calc(1360px + var(--dt-dim-56) + var(--dt-space-inline-xl));
  }

  .main.wide.has-toc .page-toc {
    display: block;
  }
}

.page-toc {
  position: sticky;
  top: calc(var(--site-header) + var(--dt-space-inset-lg));
  max-height: calc(100vh - var(--site-header) - var(--dt-space-inset-lg) * 2);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-top: var(--dt-dim-1);
  /* Room to scroll the last entries clear of the Configure pill, which sits
     fixed in the same corner. */
  padding-bottom: var(--dt-dim-20);
}

.page-toc-title {
  margin: 0 0 var(--dt-space-stack-xs);
  font-family: var(--dt-text-label-sm-family);
  font-size: var(--dt-font-size-xs);
  font-weight: var(--dt-font-weight-semibold);
  color: var(--dt-text-primary);
}

.page-toc ol {
  margin: 0;
  padding: 0;
  list-style: none;
  border-left: var(--dt-border-width-default) solid var(--dt-border-subtle);
}

.page-toc a {
  display: block;
  margin-left: calc(-1 * var(--dt-border-width-default));
  padding: var(--dt-dim-1) 0 var(--dt-dim-1) var(--dt-space-inset-sm);
  border-left: var(--dt-border-width-strong) solid transparent;
  font-size: var(--dt-font-size-xs);
  line-height: var(--dt-line-height-sm);
  color: var(--dt-text-tertiary);
  text-decoration: none;
  transition: color var(--dt-motion-micro), border-color var(--dt-motion-micro);
}

.page-toc li.nested a {
  padding-left: calc(var(--dt-space-inset-sm) + var(--dt-space-inset-sm));
}

.page-toc a:hover {
  color: var(--dt-text-primary);
}

.page-toc a[aria-current="true"] {
  color: var(--dt-text-primary);
  border-left-color: var(--dt-border-selected);
}

/* Anchored headings clear the sticky header when a link jumps to them. */
.main [id] {
  scroll-margin-top: calc(var(--site-header) + var(--dt-space-inset-md));
}

/* Page actions: the ⋯ in the fixed header opens a sheet of actions for this
   page. A bottom sheet on a phone, a small dialog on a wide screen. */
.page-actions-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--dt-text-primary);
  cursor: pointer;
  transition: background var(--dt-motion-micro);
}

.page-actions-btn .ic {
  width: var(--dt-size-icon-md);
  height: var(--dt-size-icon-md);
  stroke-width: 3;
}

.page-actions-btn:hover,
.page-actions-btn[aria-expanded="true"] {
  background: var(--dt-surface-sunken);
}

.asheet-bg {
  position: fixed;
  inset: 0;
  z-index: calc(var(--dt-z-dialog) + 1);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--dt-dim-4);
  background: rgb(0 0 0 / 0.38);
  animation: search-scrim 0.24s ease-out;
}

.asheet-bg[hidden] {
  display: none;
}

.asheet {
  width: min(400px, 100%);
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--dt-dim-4) var(--dt-dim-4) var(--dt-dim-3);
  border-radius: 20px;
  background: var(--dt-surface-overlay);
  color: var(--dt-text-primary);
  box-shadow: var(--configure-shadow);
  animation: configure-in 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.asheet-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--dt-dim-3);
  padding: var(--dt-dim-1) var(--dt-dim-2) var(--dt-dim-3);
}

.asheet-titles {
  min-width: 0;
}

.asheet-title {
  margin: 0;
  overflow: hidden;
  font-size: 1.35rem;
  line-height: 1.2;
  font-weight: var(--dt-font-weight-regular);
  letter-spacing: -0.02em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.asheet-x {
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--dt-surface-sunken);
  color: var(--dt-text-primary);
  cursor: pointer;
}

.asheet-x .ic {
  width: 16px;
  height: 16px;
}

.page-menu {
  margin: 0;
  padding: 0;
  list-style: none;
}

.page-menu-item {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 13px 12px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-md);
  color: var(--dt-text-primary);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.page-menu-item svg {
  flex: none;
  width: var(--dt-size-icon-md);
  height: var(--dt-size-icon-md);
  margin: 0;
  color: var(--dt-text-secondary);
}

.page-menu-item:hover,
.page-menu-item:focus-visible {
  background: var(--dt-surface-sunken);
  outline: none;
}

.page-actions-status {
  min-height: 1.4em;
  margin: var(--dt-dim-1) 0 0;
  padding: 0 var(--dt-dim-3);
  font-size: var(--dt-font-size-sm);
  color: var(--dt-text-secondary);
}

.page-actions-status:empty {
  min-height: 0;
}

body.asheet-open {
  overflow: hidden;
}

@media (max-width: 900px) {
  .asheet-bg {
    align-items: flex-end;
    padding: 0 var(--dt-dim-2) calc(var(--dt-dim-2) + env(safe-area-inset-bottom, 0px));
  }

  .asheet {
    width: 100%;
    border-radius: 24px;
    animation-name: configure-up;
    animation-duration: 0.36s;
  }

  .app-head .head-r {
    display: flex;
    flex: none;
    align-items: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .asheet-bg,
  .asheet {
    animation: none;
  }
}

/* -------------------------------------------------------------- home page */

/* Laid out like the marketing template (system/kits/marketing-kit.card.html):
   sections alternate the base and subtle surfaces, run edge to edge of the
   content area, and keep their content to a 1080px measure. */

.main.home {
  --home-pad: 40px;
  position: relative;
  max-width: none;
  padding: 0;
}

.main.home .sec {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  padding: 72px var(--home-pad);
  background: var(--dt-surface-base);
}

.main.home .sec > * {
  width: 100%;
  max-width: 1080px;
}

.main.home .sec.alt {
  background: var(--dt-surface-subtle);
}

.main.home .home-hero-sec {
  padding-top: 88px;
}

.main.home .eyebrow {
  margin: 0;
  font-family: var(--dt-font-family-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dt-text-tertiary);
}

.main.home .hero-h {
  margin: 0;
  color: var(--dt-text-headline, var(--dt-text-primary));
  font-size: var(--dt-text-display-sm-size);
  line-height: var(--dt-text-display-sm-line);
  font-weight: var(--dt-text-display-sm-weight);
  letter-spacing: var(--dt-text-display-sm-tracking);
  text-wrap: balance;
}

.main.home .sec-h {
  margin: 0;
  color: var(--dt-text-headline, var(--dt-text-primary));
  font-size: var(--dt-text-heading-lg-size);
  line-height: var(--dt-text-heading-lg-line);
  font-weight: var(--dt-text-heading-lg-weight);
  letter-spacing: var(--dt-text-heading-lg-tracking);
  text-wrap: balance;
}

.main.home .lead {
  margin: 0;
  max-width: 56ch;
  font-size: var(--dt-text-body-lg-size);
  line-height: var(--dt-text-body-lg-line);
  color: var(--dt-text-secondary);
  text-wrap: pretty;
}

.main.home .hero {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 48px;
  align-items: center;
  padding: 0;
  border: 0;
}

.main.home .hero-copy,
.main.home .stack {
  display: flex;
  flex-direction: column;
  gap: var(--dt-dim-4);
}

.main.home .hero-actions {
  margin: 0;
}

.main.home .hero-actions.centred {
  justify-content: center;
}

.main.home .btn {
  gap: var(--dt-dim-2);
}

.main.home .ic {
  width: var(--dt-size-icon-sm);
  height: var(--dt-size-icon-sm);
  flex: none;
}

/* The install command sits in the hero's column, as wide as its buttons. */
.main.home .code-wrap:has(> .hero-install) {
  width: fit-content;
  max-width: 100%;
}

.main.home .hero-install {
  margin: 0;
  padding-right: calc(var(--dt-space-inset-md) + 4.5em);
}

.main.home .pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-dim-1);
  margin: 0;
}

.main.home .pills span {
  padding: 4px 10px;
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-pill);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
}

/* The hero's picture is live components on a framed stage, where the
   template has its product photo. */
.main.home .hero-stage {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--dt-dim-3);
  padding: var(--dt-dim-5);
  background: var(--dt-surface-subtle);
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-media);
}

.main.home .hero-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 132px;
  padding: var(--dt-dim-4);
  background: var(--dt-surface-raised);
  border-radius: var(--dt-radius-container);
  overflow: hidden;
}

.main.home .sec-head {
  display: flex;
  flex-direction: column;
  gap: var(--dt-dim-2);
}

.main.home .sec-head.centred {
  align-items: center;
  text-align: center;
}

.main.home .three {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.main.home .feature {
  display: flex;
  flex-direction: column;
  gap: var(--dt-dim-2);
  padding: var(--dt-card-padding, 24px);
  background: var(--dt-card-bg, var(--dt-surface-raised));
  border: var(--dt-card-border-width, 1px) solid var(--dt-card-border-color, var(--dt-border-subtle));
  border-radius: var(--dt-card-radius, var(--dt-radius-container));
}

.main.home .feature h3 {
  margin: var(--dt-dim-2) 0 0;
  font-size: var(--dt-text-heading-sm-size);
  line-height: var(--dt-text-heading-sm-line);
  font-weight: var(--dt-text-heading-sm-weight);
  letter-spacing: var(--dt-text-heading-sm-tracking);
}

.main.home .feature p {
  margin: 0;
  font-size: var(--dt-text-body-sm-size);
  line-height: var(--dt-text-body-sm-line);
  color: var(--dt-text-secondary);
}

.main.home .icon-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start;
  width: 40px;
  height: 40px;
  border-radius: var(--dt-radius-control);
  background: var(--dt-surface-brand-muted);
  color: var(--dt-text-on-brand-muted);
}

.main.home .icon-tile .ic {
  width: var(--dt-size-icon-md);
  height: var(--dt-size-icon-md);
}

.main.home .two {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 32px;
  align-items: center;
}

.main.home .checks {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.main.home .checks li {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
}

.main.home .checks .ic {
  color: var(--dt-text-brand);
}

.main.home .stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin-top: var(--dt-dim-2);
}

.main.home .stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.main.home .stat .icon-tile {
  margin-bottom: var(--dt-dim-2);
}

.main.home .stat-label,
.main.home .stat-cap {
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
}

.main.home .stat-value {
  font-size: var(--dt-font-size-3xl);
  line-height: 1.1;
  font-weight: var(--dt-font-weight-semibold);
  letter-spacing: var(--dt-tracking-tight);
}

.main.home .home-gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--dt-dim-3);
}

.main.home .home-spec {
  display: flex;
  flex-direction: column;
  background: var(--dt-surface-raised);
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-container);
  color: var(--dt-text-primary);
  text-decoration: none;
  overflow: hidden;
}

.main.home .home-spec:hover {
  border-color: var(--dt-border-default);
}

.main.home .home-spec-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  padding: var(--dt-dim-4);
  pointer-events: none;
  overflow: hidden;
}

.main.home .home-spec-name {
  padding: var(--dt-dim-2) var(--dt-dim-4);
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
}

.main.home .home-thumb {
  display: block;
}

/* The frame renders the card at desktop width and scales it down, so the
   picture is the live template, themed with everything else. */
.main.home .home-thumb-frame {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--dt-surface-subtle);
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-media);
}

.main.home .home-thumb-frame iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 1280px;
  height: 800px;
  border: 0;
  transform: scale(var(--thumb-scale, 0.4));
  transform-origin: 0 0;
  pointer-events: none;
}

.main.home .tiles {
  margin: 0;
}

.main.home .narrow {
  max-width: 760px;
}

.main.home .narrow > * + * {
  margin-top: var(--dt-dim-12);
}

.main.home .cta {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 280px);
  gap: 48px;
  align-items: center;
}

.main.home .cta-art {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: var(--dt-radius-container);
  background: var(--dt-surface-brand-muted);
  color: var(--dt-text-on-brand-muted);
  overflow: hidden;
}

.main.home .home-sketch {
  width: 55%;
  height: 55%;
}

.main.home .cta-art img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

button.btn {
  font-family: inherit;
  cursor: pointer;
}

@media (max-width: 900px) {
  .main.home {
    --home-pad: 20px;
  }

  .main.home .sec {
    gap: 24px;
    padding-top: 48px;
    padding-bottom: 48px;
  }

  .main.home .hero,
  .main.home .two,
  .main.home .cta {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }

  .main.home .three {
    grid-template-columns: minmax(0, 1fr);
  }

  .main.home .cta-art {
    max-width: 240px;
  }
}

@media (max-width: 560px) {
  .main.home .stats {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }

  .main.home .hero-stage,
  .main.home .home-gallery {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ------------------------------------------------------------ site search */

.search-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-dim-2);
  height: var(--dt-size-control-sm);
  min-width: 200px;
  padding: 0 var(--dt-dim-2) 0 var(--dt-dim-3);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-pill);
  background: var(--dt-surface-base);
  color: var(--dt-text-tertiary);
  font-family: var(--dt-font-family-sans);
  font-size: var(--dt-font-size-xs);
  cursor: pointer;
}

.search-btn:hover {
  border-color: var(--dt-border-strong, var(--dt-border-default));
  color: var(--dt-text-secondary);
}

.search-btn .ic {
  width: 15px;
  height: 15px;
}

.search-btn kbd {
  margin-left: auto;
  padding: 1px 6px;
  border-radius: 6px;
  background: var(--dt-surface-sunken);
  font-family: var(--dt-font-family-mono);
  font-size: 11px;
}

.search-bg {
  position: fixed;
  inset: 0;
  z-index: calc(var(--dt-z-dialog) + 1);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 10vh var(--dt-dim-2) 0;
  background: rgb(0 0 0 / 0.28);
  animation: search-scrim 0.2s ease-out;
}

.search-bg[hidden] {
  display: none;
}

@keyframes search-scrim {
  from { opacity: 0; }
}

.search-sheet {
  display: flex;
  flex-direction: column;
  width: min(640px, 100%);
  max-height: min(560px, 76vh);
  overflow: hidden;
  background: var(--dt-surface-overlay);
  border-radius: 20px;
  box-shadow: var(--configure-shadow);
  animation: configure-in 0.26s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.search-field {
  display: flex;
  align-items: center;
  gap: var(--dt-dim-2);
  padding: var(--dt-dim-3) var(--dt-dim-3) var(--dt-dim-3) var(--dt-dim-5);
  border-bottom: var(--dt-border-width-default) solid var(--dt-border-subtle);
  color: var(--dt-text-tertiary);
}

.search-field svg {
  flex: none;
}

.search-field input {
  flex: 1;
  min-width: 0;
  height: 40px;
  border: 0;
  background: transparent;
  color: var(--dt-text-primary);
  font: inherit;
  font-size: 16px;
  outline: none;
}

.search-field input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

.search-close {
  flex: none;
  height: 34px;
  padding: 0 14px;
  border: 0;
  border-radius: 17px;
  background: var(--dt-surface-sunken);
  color: var(--dt-text-primary);
  font-family: inherit;
  font-size: var(--dt-font-size-sm);
  cursor: pointer;
}

.search-list {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px;
}

.search-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px var(--dt-dim-3);
  padding: 10px 12px;
  border-radius: 10px;
  color: var(--dt-text-primary);
  text-decoration: none;
}

.search-row[aria-selected="true"] {
  background: var(--dt-surface-sunken);
}

.search-row-t {
  font-size: var(--dt-font-size-sm);
  font-weight: var(--dt-font-weight-medium);
}

.search-row-s {
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-tertiary);
  white-space: nowrap;
}

.search-row-d {
  grid-column: 1 / -1;
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-empty {
  margin: 0;
  padding: var(--dt-dim-6) var(--dt-dim-4);
  color: var(--dt-text-secondary);
  font-size: var(--dt-font-size-sm);
  text-align: center;
}

body.search-open {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .search-bg,
  .search-sheet {
    animation: none;
  }
}

/* ------------------------------------------------------------ phone chrome */

/* The portfolio's app layout, on phones only: see phoneChrome() in
   tools/build-site.mjs. */

.app-head,
.fab {
  display: none;
}

@media (max-width: 900px) {
  .site-header {
    display: none;
  }

  /* The header sticks to the top. Its top padding scrolls away first (the
     negative top), and the title shrinks as --hc goes from 0 to 1 on scroll,
     with a hairline fading in once it's compact. */
  .app-head {
    --hc: 0;
    position: sticky;
    top: -16px;
    z-index: var(--dt-z-sticky);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 28px 20px 8px;
    background: color-mix(in oklab, var(--dt-surface-base) 82%, transparent);
    -webkit-backdrop-filter: saturate(1.6) blur(18px);
    backdrop-filter: saturate(1.6) blur(18px);
    box-shadow: 0 1px 0 color-mix(in oklab, var(--dt-border-default) calc(var(--hc) * 100%), transparent);
  }

  .h-txt {
    min-width: 0;
  }

  .h-title {
    margin: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 2rem;
    line-height: 1.1;
    font-weight: var(--dt-font-weight-medium);
    letter-spacing: -0.04em;
    transform-origin: left center;
    transform: scale(calc(1 - 0.38 * var(--hc)));
  }

  /* The header already says where you are, so the page's own h1 and the
     breadcrumb step back (the h1 stays for screen readers). */
  .main:not(.home) .doc > h1:first-of-type {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .main:not(.home) .crumbs {
    display: none;
  }

  .search-bg {
    padding-top: 8px;
  }

  .search-sheet {
    max-height: calc(100dvh - 16px);
  }
}



/* Chrome icons drawn with icon() take the site's stroke, like the tiles do. */
.ic {
  stroke-width: var(--site-icon-stroke, 1.75);
}

.nav-toggle .ic {
  stroke-width: 3;
}

/* ---------------------------------------------------- phone menu (menu.js) */

/* After the progressive menu sheet on Graham's folio: a floating pill with
   search, Configure and menu; the menu sheet grows out of the menu button. */
@media (max-width: 900px) {
  .sidebar,
  .sidebar.open,
  .configure-bar {
    display: none;
  }

  body {
    padding-bottom: calc(88px + env(safe-area-inset-bottom, 0px));
  }

  .fab {
    position: fixed;
    right: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px) + var(--kb, 0px));
    z-index: var(--dt-z-toast);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 2px;
    height: 60px;
    padding: 5px;
    overflow: hidden;
    border-radius: 30px;
    background: color-mix(in oklab, var(--dt-surface-overlay) 86%, transparent);
    -webkit-backdrop-filter: saturate(1.8) blur(18px);
    backdrop-filter: saturate(1.8) blur(18px);
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.14), 0 0 0 1px rgb(0 0 0 / 0.06);
    transition: width 0.44s cubic-bezier(0.2, 0.85, 0.25, 1), opacity 0.2s;
  }

  .fab.gone {
    opacity: 0;
    pointer-events: none;
  }

  .fab-btn,
  .fab .configure-open-btn {
    display: grid;
    place-items: center;
    flex: none;
    width: 50px;
    height: 50px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--dt-text-primary);
    cursor: pointer;
  }

  .fab-btn .ic,
  .fab .configure-open-btn svg {
    width: 22px;
    height: 22px;
  }

  .fab-btn:hover,
  .fab .configure-open-btn:hover {
    background: var(--dt-surface-sunken);
  }

  .fab-q {
    display: none;
    flex: 1;
    min-width: 0;
    align-items: center;
    gap: 8px;
    height: 50px;
    padding: 0 0 0 14px;
    color: var(--dt-text-tertiary);
  }

  .fab-q > .ic {
    width: 19px;
    height: 19px;
    flex: none;
  }

  .fab-q input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    color: var(--dt-text-primary);
    font: inherit;
    font-size: 16px;
    outline: none;
  }

  .fab-q input::-webkit-search-cancel-button {
    -webkit-appearance: none;
  }

  .fab-q-close {
    display: grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 50%;
    background: var(--dt-surface-sunken);
    color: var(--dt-text-primary);
  }

  .fab-q-close .ic {
    width: 16px;
    height: 16px;
  }

  .fab.searching {
    width: calc(100vw - 32px);
  }

  .fab.searching > :not(.fab-q) {
    display: none;
  }

  .fab.searching .fab-q {
    display: flex;
    animation: search-scrim 0.3s 0.12s both;
  }

  .q-scrim {
    position: fixed;
    inset: 0;
    z-index: calc(var(--dt-z-toast) - 2);
    background: rgb(0 0 0 / 0.2);
    animation: search-scrim 0.25s ease-out;
  }

  .q-res {
    position: fixed;
    right: 16px;
    bottom: calc(86px + env(safe-area-inset-bottom, 0px) + var(--kb, 0px));
    z-index: calc(var(--dt-z-toast) - 1);
    width: calc(100vw - 32px);
    max-height: min(60vh, 520px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 6px;
    border-radius: 24px;
    background: var(--dt-surface-overlay);
    box-shadow: 0 18px 50px rgb(0 0 0 / 0.18), 0 0 0 1px rgb(0 0 0 / 0.06);
    transform-origin: 100% 100%;
    animation: q-res-in 0.34s cubic-bezier(0.2, 0.85, 0.25, 1);
  }

  .q-scrim[hidden],
  .q-res[hidden] {
    display: none;
  }

  @keyframes q-res-in {
    from { opacity: 0; transform: translateY(10px) scale(0.97); }
  }

  .q-h {
    margin: 10px 10px 4px;
    font-size: 0.8rem;
    color: var(--dt-text-tertiary);
  }

  .q-none {
    margin: 0;
    padding: 14px 12px;
    color: var(--dt-text-secondary);
  }

  .q-row,
  .mrow {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    color: var(--dt-text-primary);
    text-align: left;
    text-decoration: none;
  }

  .q-row {
    padding: 10px 12px;
    border-radius: 16px;
  }

  .q-row:hover {
    background: var(--dt-surface-sunken);
  }

  .q-row .t,
  .mrow .t {
    flex: 1;
    min-width: 0;
  }

  .q-row b,
  .mrow b {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 1.02rem;
    font-weight: var(--dt-font-weight-medium);
  }

  .q-row small,
  .mrow small {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 0.85rem;
    color: var(--dt-text-tertiary);
  }

  .q-row > .ic,
  .mrow > .ic {
    width: 16px;
    height: 16px;
    flex: none;
    color: var(--dt-text-tertiary);
  }

  /* The menu sheet: inset from the edges, nearly full height. */
  .msheet-bg {
    position: fixed;
    inset: 0;
    z-index: var(--dt-z-dialog);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgb(0 0 0 / 0.38);
  }

  .msheet-bg[hidden] {
    display: none;
  }

  .msheet-bg.closing {
    animation: msheet-scrim-out 0.26s ease-in forwards;
  }

  @keyframes msheet-scrim-out {
    to { background: rgb(0 0 0 / 0); }
  }

  .msheet {
    display: flex;
    flex-direction: column;
    width: calc(100% - 16px);
    height: calc(100% - 44px - env(safe-area-inset-top, 0px));
    margin-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    padding: 22px 24px 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: 24px;
    background: var(--dt-surface-overlay);
    color: var(--dt-text-primary);
  }

  .msheet-bg.morph .msheet > :not(.mfoot) {
    animation: msheet-body-in 0.5s 0.16s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  }

  .msheet-bg.morph .mfoot [data-close] .ic {
    animation: msheet-x-in 0.5s cubic-bezier(0.2, 0.85, 0.25, 1) both;
  }

  .msheet-bg.morphout .msheet > * {
    opacity: 0;
    transition: opacity 0.16s;
  }

  @keyframes msheet-body-in {
    from { opacity: 0; transform: translateY(22px); }
  }

  @keyframes msheet-x-in {
    from { opacity: 0; transform: rotate(-90deg) scale(0.6); }
  }

  .msheet.snext > :not(.mfoot) {
    animation: msheet-next 0.36s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  }

  .msheet.sprev > :not(.mfoot) {
    animation: msheet-prev 0.36s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  }

  .msheet.snext > .mp-head,
  .msheet.sprev > .mp-head {
    animation: search-scrim 0.3s ease-out both;
  }

  .msheet.hdrag > :not(.mfoot) {
    transform: translateX(var(--sx, 0px));
  }

  @keyframes msheet-next {
    from { opacity: 0; transform: translateX(40px); }
  }

  @keyframes msheet-prev {
    from { opacity: 0; transform: translateX(-40px); }
  }

  .mp-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 2px 0 6px;
  }

  .mp-head .crumb {
    flex: 1;
  }

  /* Home: text at the right of the head, set like "Menu" at its left. */
  .mp-home {
    flex: none;
    padding: 6px 0;
    font-size: 0.92rem;
    color: var(--dt-text-tertiary);
    text-decoration: none;
  }

  .mp-home:hover,
  .mp-home[aria-current="page"] {
    color: var(--dt-text-primary);
  }

  /* A leading icon in a small tile: Foundations, and the template kinds. */
  .mrow .row-ic {
    display: grid;
    flex: none;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 12px;
    background: var(--dt-surface-sunken);
    color: var(--dt-text-primary);
  }

  .mrow .row-ic .ic {
    width: 19px;
    height: 19px;
  }

  /* Guide in the menu: cards, the README full width and the rest two up. */
  .mcards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    padding-top: 6px;
  }

  .mcard {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
    padding: 14px;
    border-radius: 20px;
    background: var(--dt-surface-sunken);
    color: var(--dt-text-primary);
    text-decoration: none;
  }

  .mcard:first-child {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    padding: 18px;
  }

  .mcard .row-ic {
    display: block;
    flex: none;
    width: auto;
    height: auto;
    background: none;
  }

  .mcard .row-ic .ic {
    display: block;
    width: 22px;
    height: 22px;
  }

  .mcard .t {
    min-width: 0;
  }

  .mcard b {
    display: block;
    font-size: 1rem;
    font-weight: var(--dt-font-weight-medium);
    line-height: 1.25;
  }

  .mcard:first-child b {
    font-size: 1.2rem;
  }

  .mcard small {
    display: block;
    margin-top: 2px;
    font-size: 0.82rem;
    color: var(--dt-text-tertiary);
  }

  .mcard[aria-current="page"] {
    box-shadow: inset 0 0 0 var(--dt-border-width-strong, 2px) var(--dt-text-primary);
  }

  .mrow.drill {
    padding: 16px 0;
  }

  .mrow.drill .row-ic {
    width: 48px;
    height: 48px;
    border-radius: 14px;
  }

  .mrow.drill b {
    font-size: 1.2rem;
  }

  .mrow .n {
    flex: none;
    min-width: 28px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--dt-surface-sunken);
    color: var(--dt-text-tertiary);
    font-size: 0.8rem;
    text-align: center;
  }

  .crumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    min-height: 22px;
    margin: 0;
    font-size: 0.92rem;
    color: var(--dt-text-tertiary);
  }

  /* The crumb is the way back, so its tap target is taller than its text. */
  .crumb-up {
    padding: 11px 0;
    margin: -11px 0;
    border: 0;
    background: none;
    color: var(--dt-text-tertiary);
    font: inherit;
    text-decoration: underline;
    text-decoration-color: var(--dt-border-subtle);
    text-underline-offset: 3px;
    cursor: pointer;
  }

  .crumb .sep {
    opacity: 0.5;
  }

  .crumb-cur {
    color: var(--dt-text-primary);
  }

  .mp-body {
    flex: 1 0 auto;
  }

  .big-links {
    display: flex;
    flex-direction: column;
    margin-top: 4px;
  }

  .big-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    width: 100%;
    padding: 10px 0;
    border: 0;
    border-bottom: var(--dt-border-width-default) solid var(--dt-border-subtle);
    background: none;
    color: var(--dt-text-primary);
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
  }

  .big-link .lbl {
    display: block;
    font-size: clamp(1.85rem, 7.8vw, 2.35rem);
    font-weight: var(--dt-font-weight-regular);
    letter-spacing: -0.035em;
    line-height: 1.05;
    white-space: nowrap;
  }

  .big-link small {
    display: block;
    margin-top: 3px;
    font-size: 0.92rem;
    color: var(--dt-text-tertiary);
  }

  .big-link > .ic {
    width: 24px;
    height: 24px;
    flex: none;
    color: var(--dt-text-tertiary);
  }

  .big-link[aria-current="page"] .lbl {
    color: var(--dt-text-tertiary);
  }

  .big-link[aria-current="page"] small::before,
  .mrow[aria-current="page"] small::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 7px;
    border-radius: 50%;
    background: var(--dt-text-primary);
    vertical-align: 2px;
  }

  .sub-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 18px;
  }

  .sub-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border-radius: 999px;
    background: var(--dt-surface-sunken);
    color: var(--dt-text-primary);
    font-size: 1rem;
    text-decoration: none;
  }

  .mlist {
    display: flex;
    flex-direction: column;
  }

  .mrow {
    padding: 12px 0;
    border: 0;
    border-bottom: var(--dt-border-width-default) solid var(--dt-border-subtle);
    background: none;
    font: inherit;
    cursor: pointer;
  }

  /* Search and close in a footer; close sits where the menu button was. */
  .mfoot {
    position: sticky;
    bottom: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: auto -24px 0;
    padding: 16px 13px calc(13px + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(to top, var(--dt-surface-overlay) 68%, transparent);
  }

  .msh-x {
    display: grid;
    place-items: center;
    width: 50px;
    height: 50px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--dt-text-primary);
    cursor: pointer;
  }

  .msh-x .ic {
    width: 22px;
    height: 22px;
  }

  .msh-x:hover {
    background: var(--dt-surface-sunken);
  }

  body.msheet-open {
    overflow: hidden;
  }
}

@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .fab,
  .q-res,
  .q-scrim,
  .msheet-bg,
  .msheet > *,
  .fab.searching .fab-q {
    animation: none !important;
    transition: none !important;
  }
}

/* ------------------------------------------------------ filter chips */

/* Gainer's filter chips: a hairline pill with a count; the chosen one fills
   with ink. Used on the components index and in the phone menu. */
.pan-opt {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: 999px;
  background: transparent;
  color: var(--dt-text-primary);
  font-family: var(--dt-font-family-sans);
  font-size: 0.87rem;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dt-motion-micro), border-color var(--dt-motion-micro), color var(--dt-motion-micro);
}

.pan-opt .n {
  padding-left: 1px;
  color: var(--dt-text-tertiary);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.pan-opt:hover {
  border-color: var(--dt-border-default);
}

.pan-opt[aria-pressed="true"] {
  background: var(--dt-surface-action);
  border-color: var(--dt-surface-action);
  color: var(--dt-text-on-action);
}

.pan-opt[aria-pressed="true"] .n {
  color: var(--dt-text-on-action);
  opacity: 0.7;
}

/* On the components index the chips stay in reach as the families scroll
   past, just under the header. */
.filter-chips {
  position: sticky;
  top: var(--site-header);
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: var(--dt-space-stack-md) 0 0;
  padding: var(--dt-dim-2) 0;
  background: var(--dt-surface-base);
}

@media (max-width: 900px) {
  .filter-chips {
    position: static;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin-right: calc(-1 * var(--dt-space-inset-md));
    margin-left: calc(-1 * var(--dt-space-inset-md));
    padding: 6px var(--dt-space-inset-md);
  }

  .filter-chips::-webkit-scrollbar {
    display: none;
  }

  /* The menu's chips scroll sideways under the breadcrumb. */
  .mchips {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 4px -24px 4px;
    padding: 6px 24px 8px;
  }

  .mchips::-webkit-scrollbar {
    display: none;
  }

  /* Search: the footer becomes a field fixed to the bottom of the sheet. */
  .mfoot.msearch {
    display: block;
    padding: 12px 13px calc(13px + env(safe-area-inset-bottom, 0px));
  }

  .ms-field {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 50px;
    padding: 0 5px 0 16px;
    border-radius: 25px;
    background: var(--dt-surface-sunken);
    color: var(--dt-text-tertiary);
  }

  .ms-field > .ic {
    width: 19px;
    height: 19px;
    flex: none;
  }

  .ms-field input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    color: var(--dt-text-primary);
    font: inherit;
    font-size: 16px;
    outline: none;
  }

  .ms-field input::-webkit-search-cancel-button {
    -webkit-appearance: none;
  }

  .ms-close {
    display: grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--dt-surface-overlay);
    color: var(--dt-text-primary);
    cursor: pointer;
  }

  .ms-close .ic {
    width: 16px;
    height: 16px;
  }

  /* Keep the sheet, and the field at its foot, above the keyboard. */
  .msheet.is-searching {
    height: calc(100% - 44px - env(safe-area-inset-top, 0px) - var(--kb, 0px));
    margin-bottom: calc(8px + env(safe-area-inset-bottom, 0px) + var(--kb, 0px));
  }
}

/* The menu's chips lead with an icon; "Open in Claude" carries Claude's mark
   in its orange. */
.sub-link .ic {
  flex: none;
  width: 18px;
  height: 18px;
  stroke-width: var(--site-icon-stroke, 2);
}

.sub-link-claude .claude-mark {
  flex: none;
  color: #d97757;
}

/* ------------------------------------------------------------ playground */

/* The live component beside its prop controls, with the JSX underneath. */
.playground-wrap {
  margin: var(--dt-space-stack-xl) 0;
}

.playground-wrap h2 {
  margin-bottom: var(--dt-dim-1);
}

.playground {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  margin-top: var(--dt-space-stack-md);
  overflow: hidden;
  border: var(--dt-border-width-default) solid var(--dt-border-subtle);
  border-radius: var(--dt-radius-container);
  background: var(--dt-surface-raised);
}

.pg-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 240px;
  padding: var(--dt-space-inset-xl);
  overflow: auto;
  background: var(--dt-surface-base);
  color: var(--dt-text-primary);
}

.pg-controls {
  display: flex;
  flex-direction: column;
  gap: var(--dt-dim-4);
  max-height: 420px;
  padding: var(--dt-space-inset-lg);
  overflow-y: auto;
  border-left: var(--dt-border-width-default) solid var(--dt-border-subtle);
}

.pg-row {
  display: flex;
  flex-direction: column;
  gap: var(--dt-dim-2);
}

.pg-label {
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  color: var(--dt-text-secondary);
}

.pg-label[title] {
  cursor: help;
}

.pg-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pg-controls .pan-opt {
  padding: 5px 12px;
  font-size: var(--dt-font-size-xs);
}

.pg-input {
  height: var(--dt-size-control-sm);
  padding: 0 var(--dt-space-inset-sm);
  border: var(--dt-border-width-default) solid var(--dt-border-default);
  border-radius: var(--dt-radius-control);
  background: var(--dt-surface-base);
  color: var(--dt-text-primary);
  font: inherit;
  font-size: var(--dt-font-size-sm);
}

.pg-code {
  grid-column: 1 / -1;
  margin: 0;
  padding: var(--dt-space-inset-md) var(--dt-space-inset-lg);
  overflow-x: auto;
  border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
  background: var(--dt-surface-sunken);
  font-family: var(--dt-font-family-mono);
  font-size: var(--dt-font-size-xs);
  white-space: pre-wrap;
  word-break: break-word;
}

.pg-error {
  margin: 0;
  color: var(--dt-text-secondary);
  font-size: var(--dt-font-size-sm);
  text-align: center;
}

@media (max-width: 900px) {
  .playground {
    grid-template-columns: minmax(0, 1fr);
  }

  .pg-controls {
    max-height: none;
    border-top: var(--dt-border-width-default) solid var(--dt-border-subtle);
    border-left: 0;
  }

  .pg-stage {
    min-height: 180px;
    padding: var(--dt-space-inset-lg);
  }
}

.pg-row > .pan-opt {
  align-self: flex-start;
  min-width: 56px;
  justify-content: center;
}

.file-menu {
  animation: menu-in 0.22s cubic-bezier(0.2, 0.9, 0.25, 1.05);
}

@keyframes menu-in {
  from { opacity: 0; transform: scale(0.5); }
}

@media (prefers-reduced-motion: reduce) {
  .file-menu {
    animation: none;
  }
}

/* The floating buttons step aside while the page actions sheet is up. */
body.asheet-open .fab,
body.asheet-open .configure-bar {
  display: none;
}
