/* Facet docs site styles — presentation of the site's own pages
   (home, library, build). Not part of the library; never in /lib.
   The page header was removed — the floating site menu (bottom-right)
   carries the navigation now. */

/* The "facet" wordmark: heads the site navigation sheet. The bar's
   .tab-brand carries the brand on the pages themselves. */
.wordmark {
  display: inline-block;
  font-weight: var(--weight-heading);
  font-size: var(--text-h3);
  text-decoration: none;
  letter-spacing: -0.02em;
  color: var(--text);
}
.sheet .wordmark { padding: var(--space-control) var(--space-inline) var(--space-inline); }

/* Landing — one centered column: heading, the two tags, a copy
   button and the theme chips. The code block is the focus, so the
   heading stays modest (not display-sized). */
.landing {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: var(--space-stack);
  max-width: 46rem;
  padding-block: var(--space-hero) var(--space-section);
}
.landing-title { font-size: var(--text-h1); line-height: 1.1; margin: 0; max-width: 20ch; }
.landing-lede { color: var(--text-muted); max-width: 52ch; margin: 0; }
.landing-snippet {
  width: 100%;
  max-width: 40rem;
  text-align: left;
  margin: var(--space-control) auto 0;
}
.landing-actions { margin: 0; }
.landing-chips { justify-content: center; margin: 0; }
.landing-size { font-size: var(--text-footnote); color: var(--text-muted); margin: 0; }

/* Deliberate full-width divider — the one clean rule between the
   landing and the library, and reused wherever a real break is meant.
   It rides the --border token, so it is a hairline in the ink theme
   and tinted in every other theme (never a stray white line). */
.section-rule {
  border: none;
  border-top: var(--border-hairline) solid var(--border);
  margin-block: var(--space-control) 0;
}

/* The settings sheet's theme-builder rows: a small round swatch on the
   row's right edge; the native color input is the control. */
.menu-color input[type="color"] {
  width: 1.9rem;
  height: 1.9rem;
  min-height: 0;
  margin-left: auto;
  padding: 0;
  border: var(--border-hairline) solid var(--border);
  border-radius: var(--radius-pill);
  background: none;
  cursor: pointer;
}
.menu-color input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.menu-color input[type="color"]::-webkit-color-swatch { border: none; border-radius: var(--radius-pill); }
/* The settings panel's own mini tab bar: in flow at the panel's top,
   centred, its groove hugging the tabs it holds — never a panel-wide
   trench for two pills — and scrolling sideways if they outgrow it. */
.sheet-tabs {
  position: static;
  transform: none;
  z-index: auto;
  max-width: none;
  padding: 0;
  justify-content: center;
}
.sheet-tabs .tab-set {
  width: fit-content;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.sheet-tabs .tab-set::-webkit-scrollbar { display: none; }
/* Advanced is a desktop concern — phones never see the tab */
.tab-seg-desktop { display: none; }
@media (min-width: 40rem) { .tab-seg-desktop { display: inline-flex; } }

/* The site bar (the tab bar pinned top on wide screens): the page and
   the pinned index clear it. On phones the same bar floats at the
   bottom, so the page gets bottom room instead. */
body { padding-bottom: var(--bar-clearance-bottom); }
@media (min-width: 40rem) {
  body { padding-top: var(--bar-clearance-top); padding-bottom: 0; }
  .docs-index.side-index {
    top: calc(var(--bar-height) + 2 * var(--space-pin));
    height: calc(100dvh - var(--bar-height) - 3 * var(--space-pin));
  }
}

/* The sidebar + wall layout. The grid wrapper exists to put the index
   beside the content — a real layout job. */
.docs-layout {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: var(--space-section);
  align-items: start;
  /* the pin inset all around — full bleed, no centering cap — so the
     sticky index starts exactly where it pins (top: var(--space-pin)),
     ends exactly at the page's bottom inset, and never moves a pixel
     with the scroll */
  max-width: none;
  padding-block: var(--space-pin);
  padding-inline: var(--space-pin);
}
/* The index panel, search box and grouped lists are the library's own
   .side-index block now (promoted from this chrome — the docs dogfood
   it). Only the docs-specific hooks remain here. */
.nav-overview {
  font-family: var(--font-mono);   /* the eyebrow voice, like the group names below it */
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-eyebrow);
  margin-bottom: var(--space-stack);
}
/* the divider under Overview — the same hairline every category divides with */
.docs-index nav > .nav-group:first-of-type { border-top: var(--border-hairline) solid var(--border); }

/* The library sidebar: the search box, then the groups — nothing else.
   Each group carries one of the five vivid palette colors as its thread
   (decoration, per the palette rule): a dot beside the group name, a
   tinted pill on the current link. The same thread colors the layer
   pages' kickers and the entry cards' dots, so sidebar, cards and page
   headers all read as one colored system. */
/* The panel keeps no top padding of its own: the sticky search wrapper
   below carries it, so the pinned search sits an equal distance from the
   panel's top, left and right edges with nothing scrolling above it. */
.docs-index { padding: 0 var(--space-stack) var(--space-card); gap: var(--space-inline); }
/* The search wrapper sticks to the top while the menu scrolls; its own
   padding is the breathing room and its surface background masks the
   links sliding beneath. */
.docs-index .side-search {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: var(--space-stack) 0 var(--space-tight);
  background: var(--surface);
}
/* The search box itself: compact, thinner than the 44px field default. */
.docs-index #wall-search {
  min-height: 34px;
  padding: var(--space-tight) var(--space-inline);
  font-size: var(--text-footnote);
}
.side-index-empty {
  margin: 0;
  padding-inline: var(--space-inline);
  font-size: var(--text-caption);
  color: var(--text-muted);
}
.docs-index .nav-group { padding-block: var(--space-stack); }
.docs-index .nav-group:nth-of-type(5n+1) { --group-color: var(--color-1); }
.docs-index .nav-group:nth-of-type(5n+2) { --group-color: var(--color-2); }
.docs-index .nav-group:nth-of-type(5n+3) { --group-color: var(--color-3); }
.docs-index .nav-group:nth-of-type(5n+4) { --group-color: var(--color-4); }
.docs-index .nav-group:nth-of-type(5n+5) { --group-color: var(--color-5); }
.docs-index .nav-group-name::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--group-color, var(--accent-3));
  margin-right: var(--space-control);
}
.docs-index .nav-group a.is-current,
.docs-index .nav-group a[aria-current="page"] {
  background: color-mix(in srgb, var(--group-color, var(--accent-3)) 14%, var(--surface));
}

@media (max-width: 56rem) {
  .docs-layout { grid-template-columns: minmax(0, 1fr); gap: var(--space-card); }
  .docs-index { position: static; height: auto; max-height: none; padding: var(--space-stack); }
  /* On phones the card grids do the navigating — the index keeps only
     the search box. */
  .docs-index nav { display: none; }
}

/* Even spacing between every section and wall entry,
   carried by the gap alone — no per-entry rule, so the page reads as
   open space, not a stack of faint lines. The only rules on the page
   are the deliberate ones: the landing divider and the layer bands. */
#main.stack-loose { gap: var(--space-hero); }
section[id], article[id] { scroll-margin-top: var(--space-card); }

/* Layer bands: the deliberate dividers that split the page into Manual /
   Customizer / Layer 1–4 / Tools. A single hairline, wide space above,
   an accent kicker over a display title — structure without a heavy
   black rule. The kicker carries the emphasis, not the line. */
#main > .layer-band {
  border-top: var(--border-hairline) solid var(--border);
  margin-top: var(--space-card);
  padding-top: var(--space-section);
  display: grid;
  gap: var(--space-control);
}
#main > .layer-band:first-child { border-top: none; margin-top: 0; padding-top: 0; }
.layer-band .layer-kicker {
  font-size: var(--text-caption);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: var(--weight-strong);
  color: var(--accent-3);
}
.layer-band h2 { font-size: var(--text-h1); line-height: 1.05; margin: 0; }
.layer-band p { color: var(--text-muted); max-width: 60ch; margin: 0; }

/* How-to steps: a numbered flow, each step a badge and a short block. */
.steps { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--space-stack); max-width: 60ch; }
.step { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-inline); align-items: start; }
.step-num {
  display: grid; place-items: center;
  width: 2rem; height: 2rem;
  border-radius: var(--radius-pill);
  background: var(--accent-1); color: var(--on-accent-1);
  font-weight: var(--weight-strong);
  font-variant-numeric: tabular-nums;
}
.step-body h3 { margin: 0; }
.step-body p { margin: var(--space-tight) 0 0; color: var(--text-muted); }

/* Features and Rules as a topic grid: each subject is a card you can
   scan; clicking one opens its full text in a popup. The whole
   inventory still ships in the DOM (inside the dialogs), so nothing is
   hidden from a crawler — it is just folded behind a grid. */
.topic-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  gap: var(--space-inline);
}
.topic-card {
  /* reset the button so the .card surface reads as a card, not a control */
  appearance: none;
  width: 100%;
  text-align: left;
  font: inherit;
  display: grid;
  gap: var(--space-control);
  align-content: start;
}
.topic-card-title { font-size: var(--text-h4); font-weight: var(--weight-heading); line-height: 1.2; }
.topic-card-teaser { font-size: var(--text-footnote); color: var(--text-muted); line-height: 1.4; }
.topic-card-more { font-size: var(--text-footnote); color: var(--accent-3); font-weight: var(--weight-strong); }

/* Topic popup: a wide, scrollable modal for the long-form text.
   dialog.topic-modal to out-specify dialog.modal's 34rem width. */
dialog.topic-modal { width: min(92vw, 44rem); }
.topic-modal { max-height: 85dvh; overflow-y: auto; }
.topic-modal h3 { margin: 0; }
.topic-modal ul { line-height: 1.5; }
.topic-modal li { margin-block: var(--space-control); }
.topic-modal-foot {
  position: sticky;
  bottom: calc(var(--space-page) * -1);
  display: flex;
  justify-content: flex-end;
  padding-top: var(--space-inline);
  margin-top: var(--space-control);
  background: linear-gradient(to top, var(--surface) 70%, transparent);
}

/* Solo mode (initSoloWall): on a desktop the sidebar selects ONE wall
   entry at a time; everything else on the path to <main> is hidden with
   this class. !important so it beats the layout classes' own display. */
.solo-hidden { display: none !important; }

/* The library's pages (initLibraryPages). The intro and every layer
   page lay their cards on one responsive grid; an entry page shows the
   component fully open — no folds anywhere anymore — under a slim
   previous/next bar. */
.layer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
  gap: var(--space-card);
}
/* The intro's category cards cycle the five threads in sidebar order —
   the same colors their groups wear; the generated category pages carry
   theirs as --group-color set by the router. */
#intro .layer-grid > :nth-child(5n+1) { --group-color: var(--color-1); }
#intro .layer-grid > :nth-child(5n+2) { --group-color: var(--color-2); }
#intro .layer-grid > :nth-child(5n+3) { --group-color: var(--color-3); }
#intro .layer-grid > :nth-child(5n+4) { --group-color: var(--color-4); }
#intro .layer-grid > :nth-child(5n+5) { --group-color: var(--color-5); }
.layer-grid-sub {
  grid-column: 1 / -1;
  margin: var(--space-control) 0 0;
  font-family: var(--font-mono);   /* the eyebrow voice */
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  font-weight: var(--weight-eyebrow);
  color: var(--text-muted);
}
.layer-card,
.entry-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-tight);
  text-decoration: none;
  color: inherit;
}
.layer-card-kicker,
.layer-page-kicker {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  /* the group's thread color, anchored in ink so it stays readable */
  color: color-mix(in srgb, var(--group-color, var(--accent-3)) 45%, var(--text));
  margin: 0;
}
.entry-card strong::before {
  content: "";
  display: inline-block;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--group-color, var(--border-strong));
  margin-right: var(--space-control);
  vertical-align: 0.14em;
}
.layer-card:hover,
.entry-card:hover {
  border-color: color-mix(in srgb, var(--group-color, var(--accent-3)) 45%, var(--border));
}
.layer-card strong,
.entry-card strong { font-size: var(--text-body); }
.layer-card > span:last-child,
.entry-card-line {
  color: var(--text-muted);
  font-size: var(--text-footnote);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.layer-page-lead { color: var(--text-muted); }

/* Previous/next on an entry page: the two neighbours' names at the top
   corners of the content column, each on ONE line. */
.entry-nav {
  display: flex;
  justify-content: space-between;
  gap: var(--space-stack);
  margin-bottom: var(--space-control);
}
.entry-nav-link {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-control);
  max-width: 46%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-decoration: none;
  color: inherit;
  padding: var(--space-control) var(--space-inline);
  border-radius: var(--radius-control);
}
.entry-nav-link:hover { background: var(--surface-hover); }
.entry-nav-cue {
  font-size: var(--text-caption);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
.entry-nav-link strong {
  font-size: var(--text-footnote);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The entry page itself: the title carries the page (display-sized), no
   hairline divider under the previous/next row, and the entry's text
   runs the full content column — the reading-measure cap is for prose
   pages, not a reference pane. */
main.is-entry article.element:not(.solo-hidden),
main.is-entry > section:not(.solo-hidden) {
  border-top: none;
  padding-top: 0;
}
main.is-entry article.element > h3 { font-size: var(--text-h1); line-height: var(--leading-heading); }
article.element > p { max-width: none; line-height: var(--leading-snug); }

/* AI instructions: the technical half of an entry, addressed to the
   agent that will build with the component. */
.ai-notes { max-width: none; }
#bg-controls-custom .field-label {
  font-weight: var(--weight-body);
  font-size: var(--text-caption);
  color: var(--text-subtle);
}
.ai-notes p { max-width: none; color: var(--text-muted); font-size: var(--text-footnote); }

/* On phones an opened entry slides in like a screen of its own. */
@media (max-width: 56rem) {
  main.is-entry article.element:not(.solo-hidden),
  main.is-entry > section:not(.solo-hidden) {
    animation: facet-modal-in var(--duration-normal) var(--ease-spring);
  }
}

/* A hairline divider above every collapsible block — the token sections,
   the component entries and their category headings — so each reads as a
   separate, self-contained section down the page. */
article.element {
  border-top: var(--border-hairline) solid var(--border);
  padding-top: var(--space-card);
}

/* One wall entry. The demo is a distinct panel — a surface fill a shade
   off the page, a solid hairline and a soft lift — so each live component
   reads as sitting inside its own section, not floating on the page. */
.element .demo {
  background: var(--surface);
  border: var(--border-hairline) solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-raised);
  padding: var(--space-card);
  min-height: 13rem;
}

/* Font specimens: a clean column — each role's label hugs its sample line,
   with a comfortable gap between roles. Kills the runaway em-based paragraph
   margins that made the display samples drift far apart. */
#fonts .demo { display: flex; flex-direction: column; gap: var(--space-card); }
#fonts .demo article { gap: var(--space-tight); }
#fonts .demo p { margin: 0; }

/* The variant/state chips are the library's own .chip now —
   promoted by extraction. Nothing docs-only left to style. */

/* Icon gallery: one bordered cell per glyph, click to copy. */
.icon-cell {
  display: grid;
  place-items: center;
  gap: var(--space-tight);
  padding: var(--space-inline);
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-panel);
  background: var(--surface);
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.icon-cell:hover { border-color: var(--text-muted); }
.icon-cell svg { width: 1.5rem; height: 1.5rem; }
#icon-gallery { grid-template-columns: repeat(auto-fill, minmax(min(6.5rem, 100%), 1fr)); }

/* Typography specimen: a real article, each block tagged with its token. */
.type-label {
  display: block;
  color: var(--text-muted);
  font-size: var(--text-caption);
  font-family: var(--font-mono);
  margin-top: var(--space-tight);
}
.callout {
  background: var(--surface);
  border: var(--border-element) solid var(--border);
  border-left: var(--border-highlight) solid var(--accent-3);
  border-radius: var(--radius-control);
  padding: var(--space-inline) var(--space-stack);
  max-width: 65ch;
}

/* Color: the same mini-interface twice, light and dark side by side.
   The panels carry data-mode, which facet.css applies to any subtree. */
.mode-pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-stack); }
@media (max-width: 56rem) { .mode-pair { grid-template-columns: 1fr; } }
.mode-panel {
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-panel);
  padding: var(--space-card);
  display: flex;
  flex-direction: column;
  gap: var(--space-inline);
}
.swatch-row { display: flex; flex-wrap: wrap; gap: var(--space-control); padding: 0; list-style: none; }
.swatch-row li { font-size: var(--text-caption); font-family: var(--font-mono); }
.swatch-row .swatch {
  height: var(--space-page);
  width: var(--space-hero);
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-control);
  margin-bottom: var(--space-tight);
}

/* Spacing: real components on a tinted ground, so padding and gaps
   show up as the tint between solid pieces. */
.space-viz {
  background: color-mix(in srgb, var(--accent-3) 10%, var(--surface));
  border-radius: var(--radius-panel);
}
.space-viz .demo-box { color: var(--text); }

.demo-box {
  background: var(--surface);
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-control);
  padding: var(--space-control) var(--space-inline);
  font-size: var(--text-footnote);
  color: var(--text-muted);
}

/* Shape and elevation tiles. */
.shape-row { display: flex; flex-wrap: wrap; gap: var(--space-stack); padding: 0; list-style: none; }
.shape-row li { font-size: var(--text-caption); text-align: center; }
.shape-row .tile {
  width: var(--space-hero);
  height: var(--space-hero);
  background: var(--surface);
  border: var(--border-element) solid var(--border);
  margin-bottom: var(--space-tight);
}

/* Interface controls shown statically inside wall demos: the real things
   are position:fixed; here they sit in the flow so the page reads. */
.element .demo .tab-bar,
.element .demo .float-btn,
.element .demo .nav-menu { position: relative; inset: auto; transform: none; }
/* the fixed cluster is shown in the flow here: it sits at the bottom-left
   of a tall box and both stacks rise ABOVE their own trigger (their real
   position), so opening one shifts nothing — exactly like the real thing
   floating bottom-left over the page. */
#nav-menu .demo { min-height: 20rem; display: flex; align-items: flex-end; }
#nav-menu .demo .nav-menu { position: relative; z-index: 40; }
#tab-bar .demo { overflow-x: auto; }   /* the pill outgrows tiny phones */
.element .demo .nudge-scrim,
.element .demo .overlay-guide { position: static; border-radius: var(--radius-panel); }
.element .demo .overlay-guide { padding: var(--space-page); gap: var(--space-inline); }
#scroll-gauge .demo { position: relative; }
#scroll-gauge .demo-scroller {
  height: 12rem; overflow-y: auto; padding-right: var(--space-card);
}


/* Rows of copy buttons under snippets sit side by side. */
.element p:has(> [data-copy]) { display: flex; gap: var(--space-control); flex-wrap: wrap; max-width: none; }

/* Framed mini page (the Skin Lab preview cells). */
.lab-frame {
  width: 100%;
  height: 21rem;
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-panel);
  background: transparent;
}

/* Wall category headings: a clean uppercase overline before each component
   group — sans caps, so it reads as a divider distinct from the serif entry
   titles below it. The following entry carries its own hairline, so the label
   needs no border of its own. Hidden by JS when its group is filtered out. */
.wall-group {
  margin-top: var(--space-hero);
  margin-bottom: 0;
  font-family: var(--font-body);
  font-size: var(--text-footnote);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}
/* Category filter chip row sits above the wall; wraps on narrow screens. */
/* An article the category filter has excluded (composes with [hidden]). */
.cat-hidden { display: none !important; }

/* Device preview: a real template page in an iframe, scaled to fit the
   column, with Desktop / Tablet / Phone width chips. The frame is set to
   each device's LOGICAL width and transform-scaled down, so what you see
   is the template's genuine responsive layout at that breakpoint — not a
   squashed desktop. JS (initDevicePreview) sets the size and scale. */
.device-preview { display: flex; flex-direction: column; gap: var(--space-inline); }
.device-stage {
  position: relative;
  width: 100%;
  overflow: hidden;
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
}
.device-frame {
  position: absolute;
  top: 0;
  left: 50%;               /* centred; JS margin-left = -width/2 */
  border: 0;
  background: var(--background);
  transform-origin: top center;
}

/* Site polish: status chips, permalinks, token copy, badges. */
/* Entry status tag. Every wall entry's h3 carries data-status with one
   of two values: "live" — the maintainer has personally reviewed and
   validated the piece, ready to rely on — or "dev" (rendered as
   "in development") — shipped and usable, but not yet signed off.
   New entries always land as dev; only the maintainer flips one to live.
   docs.js copies the value onto each entry card, so the tag shows on
   the closed card in the layer grid as well as in the opened entry. */
.element h3[data-status]::after,
.entry-card[data-status] strong::after {
  content: attr(data-status);
  margin-left: var(--space-control);
  font-size: var(--text-caption);
  font-weight: var(--weight-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-pill);
  padding: 1px var(--space-control);
  vertical-align: middle;
  white-space: nowrap;
}
.element h3[data-status="live"]::after,
.entry-card[data-status="live"] strong::after {
  content: "live";
  background: var(--success-tint);
  color: var(--success);
  border-color: var(--success-edge);
}
.element h3[data-status="dev"]::after,
.entry-card[data-status="dev"] strong::after {
  content: "in development";
  background: var(--warning-tint);
  color: var(--warning);
  border-color: var(--warning-edge);
}
.token-copy {
  display: inline-flex;
  align-items: center;
  gap: var(--space-control);
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.token-copy:hover { color: var(--accent-3); }
.contrast-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-control);
  font-size: var(--text-caption);
  max-width: none;
}
.contrast-badges span {
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-pill);
  padding: 1px var(--space-control);
  color: var(--text-muted);
}
.demo-width-chips { margin-top: 0; }
/* Part labels inside an opened wall entry: a small caption over each
   region (a chip group, the preview, the code) so it is clear what it
   is and what it does. */
.part-label {
  display: block;
  font-family: var(--font-mono);   /* the eyebrow voice */
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-eyebrow);
  color: var(--text-muted);
  /* hug the region it captions: the negative bottom margin eats most
     of the stack gap, so label and content read as one unit */
  margin-top: var(--space-inline);
  margin-bottom: calc(-1 * var(--space-inline));
}
.part-label + * { margin-top: 0; }

/* Backgrounds demo: a fixed-height canvas so the pattern reads. */
#backgrounds .demo > section { min-height: 11rem; border-radius: var(--radius-panel); }

/* Docs-only frames for specific demos. */
#snap-section .demo { padding: 0; overflow: hidden; }   /* clips the mini viewport */
#snap-section .snap { height: 20rem; }
#snap-section .snap-section { min-height: 20rem; }
#snap-section .snap-section:nth-child(even) { background: var(--surface); }
#container .demo > * {
  outline: var(--border-element) dashed var(--text-muted);
  padding-block: var(--space-control);
  font-size: var(--text-footnote);
  color: var(--text-muted);
}

/* -------------------------------------------------------------------------
   HOME PAGE — the centered manual: philosophy, features, how-to, rules.
   Everything after the landing hero is centered; features and rules are
   grouped grids of one-tap cards, each opening its detail in a popup.
   ------------------------------------------------------------------------- */
#main.container { padding-block: var(--space-section) var(--space-hero); }
.home-section { text-align: center; }
.home-section > h2 { font-size: var(--text-h1); margin: 0; }
.home-section > p { max-width: 62ch; margin-inline: auto; }
.home-kicker {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: var(--text-caption);
  font-weight: var(--weight-strong);
  color: var(--accent-3);
  margin: 0;
}

.feat-group { display: grid; gap: var(--space-stack); margin-top: var(--space-section); }
.feat-group-name { font-size: var(--text-h4); margin: 0; }
.feat-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 17rem));
  justify-content: center;
}
/* Feature/rule card: a button that reads as a small card, centered content. */
.feat-card {
  appearance: none;
  font: inherit;
  text-align: center;
  display: grid;
  gap: var(--space-tight);
  align-content: start;
  padding: var(--space-inline);
}
.feat-card-name { font-size: var(--text-body); font-weight: var(--weight-strong); line-height: 1.25; }
.feat-card-phrase { font-size: var(--text-footnote); color: var(--text-muted); line-height: 1.4; }

/* How-to on the home page: a centered 3×2 grid of borderless steps —
   a numbered circle, a centered title and a centered line, no card. */
#how-to .steps {
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  max-width: 62rem;
  margin-inline: auto;
  gap: var(--space-section) var(--space-stack);
}
#how-to .step {
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: center;
  gap: var(--space-inline);
}
#how-to .step-num { margin: 0; }
#how-to .step-body p { margin-top: var(--space-tight); }

/* How-to as two audience tracks (people / AI): two left-aligned cards
   inside the centred home section, stacking to one column on phones. */
.how-tracks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-stack);
  max-width: 60rem;
  margin-inline: auto;
  text-align: left;
}
.how-track { align-items: stretch; min-width: 0; }   /* long code lines scroll inside, never widen the page */
.how-track pre { overflow-x: auto; max-width: 100%; }
.how-track-who {
  margin: 0;
  font-size: var(--text-caption);
  font-weight: var(--weight-strong);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.how-list,
.how-files {
  display: flex;
  flex-direction: column;
  gap: var(--space-inline);
  margin: 0;
}
.how-list { padding-left: 1.2rem; }
.how-files { list-style: none; padding-left: 0; }
.how-track pre { white-space: pre-wrap; }

/* The Copy action sits fully INSIDE the snippet's bottom-left corner;
   the block reserves room below the last line so nothing overlaps. */
.code-wrap { position: relative; }
.code-wrap > pre { padding-bottom: 3.6rem; margin-bottom: 0; }
.code-tools {
  position: absolute;
  bottom: var(--space-inline);
  left: var(--space-inline);
  display: flex;
}
.code-tools .btn {
  min-height: 0;
  width: auto;
  height: 2.1rem;
  padding: 0 var(--space-inline);
  display: inline-flex;
  align-items: center;
  gap: var(--space-tight);
  background: var(--surface);
  border: var(--border-element) solid var(--border);
  color: var(--text-muted);
  font-size: var(--text-footnote);
  font-weight: var(--weight-strong);
}
.code-tools .btn:hover { color: var(--text); background: var(--background); }
.code-tools .btn svg { width: 1rem; height: 1rem; }

/* -------------------------------------------------------------------------
   THEMES PAGE — styles for build.html only: the studio layout (scenes on
   the left, the pinned token rail on the right), the scene canvas, the
   token pickers, and the Skin Lab gallery. Every selector is a build-page
   class, so nothing here reaches the other pages. The shared pieces
   build.html also uses — the wordmark, .part-label and .lab-frame —
   already live above.
   ------------------------------------------------------------------------- */

/* The studio grid: the content column and the 21rem rail beside it. The
   rail is an interface control (user-select: none, print-hidden), so it
   may sit visually right while authored after the content in the DOM. */
.studio-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 21rem;
  gap: var(--space-card);
  align-items: start;
  padding: var(--space-pin);
}

/* The rail reuses the library's .side-index chrome but sizes to its
   content: height auto with a max, so folding it shrinks the panel
   instead of leaving a tall empty box. */
.theme-rail {
  height: auto;
  max-height: calc(100dvh - 2 * var(--space-pin));
  padding: 0;
}
@media (min-width: 40rem) {
  .theme-rail {
    top: calc(48px + 2 * var(--space-pin));
    max-height: calc(100dvh - 48px - 3 * var(--space-pin));
  }
}
.rail-fold > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--space-control);
  padding: var(--space-inline) var(--space-stack);
  font-weight: var(--weight-medium);
}
.rail-fold > summary::-webkit-details-marker { display: none; }
.rail-fold > summary .inspector-caret {
  margin-left: auto;
  width: 0.55rem; height: 0.55rem;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  rotate: 45deg;
  transition: rotate var(--duration-normal) var(--ease-spring);
}
.rail-fold[open] > summary .inspector-caret { rotate: 225deg; }
.rail-body {
  padding: 0 var(--space-stack) var(--space-card);
  border-top: var(--border-hairline) solid var(--border-subtle);
}
/* The control search pins to the rail's top while the controls scroll
   beneath it — the same pattern as the library index's search. */
.theme-rail .side-search {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: var(--space-inline) 0 var(--space-tight);
  background: var(--surface);
}
.theme-rail #control-search {
  min-height: 34px;
  padding: var(--space-tight) var(--space-inline);
  font-size: var(--text-footnote);
}
.rail-actions { max-width: none; }
.theme-rail pre { overflow-x: auto; }
/* Five tabs never fit the rail on one line — let them wrap. */
.rail-body .tabs { flex-wrap: wrap; }

/* On narrow screens the rail becomes a folding bottom sheet over the
   page (docs.js closes it on arrival), clear of the floating tab bar. */
@media (max-width: 56rem) {
  .studio-layout { grid-template-columns: minmax(0, 1fr); }
  .theme-rail {
    position: fixed;
    top: auto;
    left: var(--space-inline);
    right: var(--space-inline);
    bottom: var(--space-inline);
    max-height: min(72dvh, 34rem);
    z-index: 60;
    box-shadow: var(--shadow-overlay);
  }
}
@media (max-width: 40rem) {
  .theme-rail { bottom: calc(48px + 2 * var(--space-inline) + var(--safe-bottom, 0px)); }
}
.page-head { padding-block: var(--space-inline) 0; }
.page-head h1 { margin: 0; font-size: var(--text-h1); }
.page-head p { color: var(--text-muted); max-width: 60ch; margin: 0; }

/* Token pickers. */
.mixer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(11rem, 100%), 1fr));
  gap: var(--space-inline);
}
.mixer-grid label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-control);
  font-size: var(--text-footnote);
  background: var(--surface);
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-panel);
  padding: var(--space-control) var(--space-inline);
}
.mixer-grid input[type="color"] {
  inline-size: 2.6rem;
  block-size: 1.9rem;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
}

/* Stacked token sliders inside a tab panel. */
.build-sliders { display: grid; gap: var(--space-stack); }
.build-sliders .field { gap: var(--space-tight); }
/* Sub-headings that group the type controls (Weight / Line height / …). */
.build-subhead {
  margin: var(--space-inline) 0 0;
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-weight: var(--weight-medium);
  color: var(--text-subtle);
}
/* A range row with a live value readout in its label. */
.mix-row .field-label { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-control); }
.slider-out { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--text-muted); }

/* The scene canvas: one full-width live preview the build restyles. The
   build writes its tokens as custom properties on this element alone, so
   the scenes recolor while the site chrome and the rail hold still. */
.builder-canvas {
  background: var(--background);
  color: var(--text);
  border: var(--border-element) solid var(--border);
  border-radius: var(--radius-card);
  /* padding rides --space-page and the scene gap rides --space-section,
     so those sliders visibly move the preview too. */
  padding: var(--space-page);
  display: grid;
  gap: var(--space-section);
}
/* One scene: a slice of a fictional product, its pieces spaced like an
   app screen. Scenes divide with the same hairline every section uses,
   and each wears one of the five vivid threads on its tag dot. */
.scene { display: grid; gap: var(--space-stack); }
.scene + .scene { border-top: var(--border-hairline) solid var(--border); padding-top: var(--space-section); }
.scene:nth-of-type(5n+1) { --scene-color: var(--color-1); }
.scene:nth-of-type(5n+2) { --scene-color: var(--color-2); }
.scene:nth-of-type(5n+3) { --scene-color: var(--color-3); }
.scene:nth-of-type(5n+4) { --scene-color: var(--color-4); }
.scene:nth-of-type(5n+5) { --scene-color: var(--color-5); }
.scene-tag {
  margin: 0;
  max-width: none;
  font-family: var(--font-mono);   /* the eyebrow voice */
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  font-weight: var(--weight-eyebrow);
  color: var(--text-muted);
}
.scene-tag::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--scene-color, var(--accent-3));
  margin-right: var(--space-control);
}

/* Skin Lab: the theme-by-mode gallery of framed mini pages (the frame
   itself, .lab-frame, is a shared docs style above). */
.lab-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
  gap: var(--space-stack);
}
.lab-cell { display: grid; gap: var(--space-tight); }
.lab-cell figcaption {
  font-size: var(--text-caption);
  color: var(--text-muted);
}

/* Syntax color for the snippets: VS Code's default HTML look — Light+
   on light, Dark+ on dark. Docs-only presentation, raw hex on purpose
   (these mirror an external palette, not the theme). */
:root {
  --hl-tag: #800000;
  --hl-attr: #E50000;
  --hl-value: #0000FF;
  --hl-punct: #800000;
  --hl-comment: #008000;
  --hl-text: #000000;
}
[data-mode="dark"] {
  --hl-tag: #569CD6;
  --hl-attr: #9CDCFE;
  --hl-value: #CE9178;
  --hl-punct: #808080;
  --hl-comment: #6A9955;
  --hl-text: #D4D4D4;
}
article.element pre code { color: var(--hl-text); }
.hl-tag { color: var(--hl-tag); }
.hl-attr { color: var(--hl-attr); }
.hl-value { color: var(--hl-value); }
.hl-punct { color: var(--hl-punct); }
.hl-comment { color: var(--hl-comment); }

/* AI instructions pull straight from llms.txt (initAiNotes), so people
   read exactly what the AI reads. Rendered as the file reads. */
.ai-notes-body {
  margin: 0;
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: var(--text-footnote);
  line-height: 1.55;
  color: var(--text-muted);
  max-width: none;
}


/* -------------------------------------------------------------------------
   HOME HERO — the Tell-your-AI ask. The quote is the how-to: the app idea
   types itself in the typewriter face (initHeroTypewriter) with a blinking
   caret; reduced motion keeps the first idea, still.
   ------------------------------------------------------------------------- */
.hero-ask { margin-top: var(--space-stack); }
.hero-quote {
  margin: 0;
  font-family: var(--font-quote);
  font-style: italic;
  font-size: clamp(1.625rem, 4.5vw, 2.625rem);
  line-height: var(--leading-heading);
}
.hero-idea {
  font-family: var(--font-typewriter);
  font-style: normal;
}
.hero-idea::after {
  content: "";
  display: inline-block;
  width: 2px;
  height: 0.9em;
  margin-left: 0.08em;
  vertical-align: -0.08em;
  background: var(--accent-3);
  animation: hero-caret 1.1s steps(1) infinite;
}
@keyframes hero-caret { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .hero-idea::after { animation: none; } }
.hero-explain { color: var(--text-muted); max-width: 56ch; margin: 0; }

/* -------------------------------------------------------------------------
   HOME FEATURES — three tiers of prominence. Headliners are big cards,
   the system is the familiar card grid, the small conveniences are quiet
   lines. Every card carries its area as a mono tag.
   ------------------------------------------------------------------------- */
.feat-hero-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 1fr));
  gap: var(--space-stack);
}
.feat-hero h3 { margin: 0; font-size: var(--text-h3); }
.feat-hero p { margin: 0; color: var(--text-muted); max-width: none; font-size: var(--text-footnote); }
.feat-tag {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-eyebrow);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--accent-3);
}
.feat-card .feat-tag { justify-self: center; }
.feat-lines {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(22rem, 100%), 1fr));
  gap: var(--space-control) var(--space-card);
  color: var(--text-muted);
  font-size: var(--text-footnote);
}
.feat-lines li { max-width: none; }
.feat-lines li + li { margin-top: 0; }

/* The archived feature wall: a quiet fold at the foot of the page. */
.home-archive summary {
  cursor: pointer;
  color: var(--text-muted);
  font-size: var(--text-footnote);
  padding: var(--space-control) 0;
}
.home-archive[open] summary { margin-bottom: var(--space-card); }


/* Motion tokens entry: three dots race their duration and easing across
   a track; Replay re-runs them. The dots read the live tokens, so the
   personality chips retune the race itself. */
.race-track {
  position: relative;
  height: 1.5rem;
  border-radius: var(--radius-pill);
  background: var(--surface-hover);
  border: var(--border-hairline) solid var(--border);
}
.race-dot {
  position: absolute;
  left: 4px;
  top: 50%;
  translate: 0 -50%;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: var(--accent-1);
}
.race.is-running .race-dot { left: calc(100% - 1.25rem); }
.race.race-reset .race-dot { transition: none !important; left: 4px; }

/* Demos read left to right whatever chrome surrounds them. */
.element .demo { text-align: left; }
.element .demo .type-label,
.element .demo .motion-part,
.element .demo .motion-note { max-width: none; margin-inline: 0; text-align: left; }

/* The Motion tokens demo: each cluster opens with a mono eyebrow over a
   hairline, with real air between clusters. */
#motion .demo .motion-part {
  width: 100%;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: var(--weight-eyebrow);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin: var(--space-card) 0 0;
  padding-top: var(--space-card);
  border-top: var(--border-hairline) solid var(--border);
}
#motion .demo .motion-part:first-child { margin-top: 0; padding-top: 0; border-top: none; }
#motion .demo .motion-note { color: var(--text-muted); max-width: 60ch; margin: 0; }
