/* /design gallery layout only. Production patterns stay in components.css/editor.css. */

#ds-layout { display: flex; flex: 1; min-height: 0; overflow: hidden; }
#ds-nav {
  width: 190px;
  flex-shrink: 0;
  overflow-y: auto;
  padding: var(--space-3) 0;
  background: var(--bg-panel);
  border-right: 1px solid var(--border);
}
#ds-main {
  flex: 1;
  overflow-y: auto;
  padding: calc(var(--space-6) + var(--space-4));
  scroll-behavior: smooth;
}
#ds-nav a {
  display: block;
  padding: 6px var(--space-4);
  border-left: 2px solid transparent;
  color: var(--text-secondary);
  font-size: var(--font-base);
  text-decoration: none;
}
#ds-nav a:hover { color: var(--text-bright); background: var(--bg-selected-hover); }
#ds-nav a.active { color: var(--text-strong); border-left-color: var(--accent); }

.ds-file-list { color: var(--text-muted); font-size: var(--font-sm); }
.ds-nav-group,
.ds-kicker,
.ds-example-label {
  color: var(--text-muted);
  font-size: var(--font-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.ds-nav-group { padding: var(--space-3) var(--space-4) var(--space-1); }
.ds-intro { max-width: 720px; margin-bottom: calc(var(--space-6) * 2 + var(--space-2)); }
.ds-intro h1 { margin: var(--space-2) 0; color: var(--text-strong); font-size: 24px; }
.ds-intro > p:last-child,
.ds-section-heading > p {
  color: var(--text-secondary);
  font-size: var(--font-base);
  line-height: 1.7;
}

.ds-section { max-width: 1120px; margin-bottom: calc(var(--space-6) * 3); scroll-margin-top: var(--space-6); }
.ds-section-heading {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
}
.ds-section-heading h2 { margin-top: var(--space-1); color: var(--text-strong); font-size: 18px; }
.ds-section-heading > p { max-width: 520px; text-align: right; }
.ds-subsection { margin-bottom: var(--space-6); }
.ds-subsection h3 { margin-bottom: var(--space-3); color: var(--text-primary); font-size: var(--font-base); }

.ds-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: var(--space-3);
}
.ds-swatch { display: flex; flex-direction: column; gap: var(--space-1); }
.ds-swatch-chip { height: 40px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.ds-swatch code,
.ds-spacing code { color: var(--code-color); font-size: var(--font-xs); }
.ds-swatch small,
.ds-spacing small { color: var(--text-muted); font-size: var(--font-xs); }
.ds-bg-base { background: var(--bg-base); }
.ds-bg-panel { background: var(--bg-panel); }
.ds-bg-deep { background: var(--bg-deep); }
.ds-bg-canvas { background: var(--bg-canvas); }
.ds-bg-selected { background: var(--bg-selected); }
.ds-text-muted { background: var(--text-muted); }
.ds-text-primary { background: var(--text-primary); }
.ds-text-strong { background: var(--text-strong); }
.ds-accent { background: var(--accent); }
.ds-error { background: var(--color-error); }

.ds-theming-note { max-width: 720px; color: var(--text-secondary); font-size: var(--font-base); line-height: 1.7; }
.ds-theming-note code { color: var(--code-color); }
.ds-theming-note em { color: var(--text-primary); font-style: normal; font-weight: 600; }

.ds-spacing { display: flex; flex-wrap: wrap; gap: var(--space-5); }
.ds-spacing > div { display: grid; grid-template-columns: calc(var(--space-6) + var(--space-2)) auto; align-items: center; gap: 0 var(--space-2); }
.ds-spacing small { grid-column: 2; }
.ds-space { display: block; height: 8px; background: var(--accent); border-radius: var(--radius-sm); }
.ds-space-1 { width: var(--space-1); }
.ds-space-2 { width: var(--space-2); }
.ds-space-3 { width: var(--space-3); }
.ds-space-4 { width: var(--space-4); }
.ds-space-5 { width: var(--space-5); }
.ds-space-6 { width: var(--space-6); }

.ds-example-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-5);
}
.ds-example { display: flex; min-width: 0; flex-direction: column; gap: var(--space-2); }
.ds-panel-frame {
  min-height: 330px;
  overflow: hidden;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.ds-panel-frame > .workspace-scroll { min-height: 330px; }

.ds-workspace-frame {
  height: 430px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
}
.ds-workspace-frame .workspace { flex: 1; min-height: 0; }
.ds-workspace-frame .workspace-sidebar { width: 220px; }
.ds-workspace-frame .workspace-inspector { width: 240px; }
.ds-workspace-frame .workspace-scroll { padding: var(--space-4); }
.ds-canvas-sample {
  flex: 1;
  position: relative;
  overflow: hidden;
  background-color: var(--bg-canvas);
  background-image:
    linear-gradient(var(--border) 1px, transparent 1px),
    linear-gradient(90deg, var(--border) 1px, transparent 1px);
  background-size: 24px 24px;
}
.ds-axis { position: absolute; background: var(--canvas-axis); opacity: .55; }
.ds-axis-x { left: 0; right: 0; top: 50%; height: 1px; }
.ds-axis-z { top: 0; bottom: 0; left: 50%; width: 1px; }
.ds-region-sample {
  position: absolute;
  left: 38%;
  top: 30%;
  width: 24%;
  height: 40%;
  border: 1px solid var(--canvas-result-stroke);
  background: color-mix(in oklch, var(--canvas-result-fill) 45%, transparent);
}
/* The canvas-chrome specimen: a scrap of map for the floating controls to sit on, tall enough that the
   readout, the layer bar and the dock are not stacked on top of each other. */
.ds-canvas-bar-example {
  position: relative;
  height: 260px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.ds-state-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.ds-state-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.ds-empty-sample {
  display: flex;
  min-height: 70px;
  align-items: center;
  justify-content: center;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.ds-team-red { background: var(--color-error); }
.ds-team-blue { background: var(--accent); }

.ds-rules-table { width: 100%; border-collapse: collapse; font-size: var(--font-base); }
.ds-rules-table th,
.ds-rules-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  text-align: left;
}
.ds-rules-table th {
  color: var(--text-muted);
  font-size: var(--font-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.ds-rules-table td { color: var(--text-secondary); line-height: 1.6; }
.ds-rules-table td:first-child { color: var(--text-primary); }

@media (max-width: 900px) {
  #ds-nav { display: none; }
  #ds-main { padding: var(--space-6); }
  .ds-section-heading { align-items: start; flex-direction: column; }
  .ds-section-heading > p { text-align: left; }
  .ds-workspace-frame .workspace-inspector,
  .ds-workspace-frame .workspace-inspector + * { display: none; }
}

/* Smart-suggestion design-page sample: pin to sidebar width so density reads true. */
.ds-sug-sample { max-width: 280px; }

/* /concepts/organic — the Organic-generation pipeline demo (each stage = a panel with a live svg). */
.gen-controls {
  display: flex;
  align-items: end;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.gen-field { margin: 0; }
.gen-field .field-input { max-width: 7rem; }
.gen-status { color: var(--text-muted); font-size: var(--font-sm); padding-bottom: 6px; }

.gen-panel {
  overflow: hidden;
  background: var(--bg-canvas);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.gen-canvas { display: block; width: 100%; height: 460px; background: var(--bg-canvas); }

.gen-legend { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5); }
.gen-legend-item { display: flex; align-items: center; gap: var(--space-2); color: var(--text-secondary); font-size: var(--font-base); }
.gen-swatch { width: 14px; height: 14px; border-radius: var(--radius-sm); border: 1px solid var(--border); }
.gen-swatch--mirror { background: var(--canvas-mirror-fill); border-color: var(--canvas-mirror-stroke); }

/* Terrain-paint theme editor (TP10): a monospace, resizable JSON area — the one thing field-input isn't. */
.theme-json { min-height: 200px; font-family: ui-monospace, "SF Mono", Menlo, monospace; resize: vertical; line-height: 1.4; }

/* Theme preview swatches (TP10) — a per-bucket sample grid + the top-down applied-map render. */
.theme-swatches { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--space-3); }
.theme-swatch { margin: 0; display: flex; flex-direction: column; gap: var(--space-1); align-items: center; }
.theme-swatch-img { width: 100%; aspect-ratio: 1; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-deep); }
.theme-swatch-img svg { width: 100%; height: 100%; display: block; }
.theme-swatch figcaption { font-size: var(--font-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
/* The cut-open sample plateau: one picture of a whole theme, so it gets the width a swatch grid doesn't. */
.theme-section-figure { display: flex; justify-content: center; padding: var(--space-2); background: var(--bg-deep); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.theme-section-figure svg { width: 100%; max-width: 320px; height: auto; display: block; image-rendering: pixelated; }
.theme-map-preview { display: flex; justify-content: center; padding: var(--space-3); background: var(--bg-deep); border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: auto; }
.theme-map-preview svg { max-width: 100%; height: auto; }
.theme-json-details > summary { cursor: pointer; font-size: var(--font-xs); color: var(--text-muted); padding: var(--space-1) 0; }

/* Theme Apply-step rail (G157): the theme's four bucket swatches in a row, and the current selection's rows. */
.theme-apply-swatches { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-2); margin-top: var(--space-2); }
.theme-apply-swatch { margin: 0; display: flex; flex-direction: column; gap: var(--space-1); align-items: center; }
.theme-apply-swatch figcaption { font-size: var(--font-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.theme-apply-sel-row { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) 0; flex-wrap: wrap; }

/* Theme editor (G158) — one bucket per section: the material form beside the sample it paints. */
.bucket-editor { display: grid; grid-template-columns: 1fr 120px; gap: var(--space-3); align-items: start; }
.bucket-editor-form { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.bucket-editor-swatch { margin: 0; display: flex; flex-direction: column; gap: var(--space-1); align-items: center; position: sticky; top: var(--space-2); }
.bucket-editor-swatch figcaption { font-size: var(--font-xs); color: var(--text-muted); text-align: center; }
@media (max-width: 640px) { .bucket-editor { grid-template-columns: 1fr; } .bucket-editor-swatch { position: static; max-width: 140px; } }

/* A material and, indented under it, the materials it is made of — the nesting IS the structure. */
.material-editor { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.material-editor--nested { padding-left: var(--space-3); border-left: 2px solid var(--border); }
/* One row of controls: the kind, the extent it claims (HeadExtra), and the way to remove it — all one
   control tall, so a stack of entries reads as a column of aligned selects. The name heads the block above
   the row rather than sharing it. The kind select takes the slack; the extent is a coord-field, sized to
   its own prefix + a two-digit number. */
/* Every control in the row is one --control-height tall, stated rather than left to each element's own
   intrinsic height (a select, a coord-field and an icon button land on 31 / 29 / 26px for the same type
   size, and three heights on one line is the whole of the visual tension). Stating it also makes the height
   DEFINITE, which is what lets the square controls read their width off it. The help mark is a round mark,
   not a control, so it keeps its own size. */
.material-editor-head { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.material-editor-head > *:not(.help-mark) { height: var(--control-height); }
.material-editor-head > select { flex: 1 1 8rem; min-width: 0; }
.material-editor-head .coord-field { flex: 0 0 auto; }
.material-editor-head .coord-field .coord-input { width: 2.75rem; flex: 0 0 auto; }
/* The number reads beside the select's own text, so it takes the same size the select's does. */
.material-editor-head .coord-field .coord-input,
.block-picker-row .coord-field .coord-input { font-size: var(--font-md); }
.material-editor-label { font-size: var(--font-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.material-editor-body { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.material-editor-scalars { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.material-editor-scalars .field { flex: 1 1 6rem; }
/* Under a material's list: the way to add one entry, and the way to fill the whole list from a family. Both
   act on the same list, so they share its footer row rather than sitting at two different altitudes. */
.material-editor-foot { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.material-editor-foot > * { height: var(--control-height); }
.material-editor-foot > select { flex: 1 1 9rem; min-width: 0; }

/* Block picker — the swatch says what the export will actually place. The chip, the name and the (id, data)
   pair that IS that name share one row; the pair's coord-fields hold their size so the name takes the slack,
   and the row wraps rather than overflowing in the narrowest panel that hosts one. */
.block-picker { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.block-picker-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; flex-wrap: wrap; }
.block-picker-row > * { height: var(--control-height); }
.block-picker-row > select { flex: 1 1 5rem; min-width: 0; }
.block-picker-row .coord-field { flex: 0 0 auto; }
.block-picker-row .coord-field .coord-input { width: 2.75rem; flex: 0 0 auto; }
/* The colour chip is a square reading of one block. It takes the row's height like everything else in the
   band and its width from that height, so it stands the same size as the controls beside it instead of a
   couple of pixels short of them — and stays square rather than stretching into a bar. */
.block-chip { flex: 0 0 auto; aspect-ratio: 1; border-radius: var(--radius-sm); border: 1px solid var(--border); }
.block-picker-colors { display: flex; flex-wrap: wrap; gap: 3px; }
.block-swatch { width: 1.25rem; height: 1.25rem; padding: 0; border-radius: var(--radius-sm); border: 1px solid var(--border); cursor: pointer; }
.block-swatch:hover { outline: 1px solid var(--text-muted); }
.block-swatch--on { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Dressing phase (G161) — the two views of a recipe side by side: the patch from above and the same patch
   cut open. Side by side because they answer different questions and an author reads both at once. */
/* Plan beside section. The section crops to what the recipe grew, so its height carries meaning — a meadow
   is a few courses and a forest is thirty. `start` lets each figure keep its own height instead of both
   stretching to the taller one, which would sit a thin strip in the middle of an empty box. */
.dressing-views { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); align-items: start; }
.dressing-views .theme-section-figure { margin: 0; }
.dressing-views svg { max-width: 100%; }
@media (max-width: 720px) { .dressing-views { grid-template-columns: 1fr; } }

/* ── a prop picker's drawn options (decoration.md) ─────────────────────────────────────────────────
   Every option is a picture the pass itself produced, so the card is mostly art with a small label under it.
   A grid rather than a select, because what separates a worn path from stepping stones is what they look
   like — a dropdown of six words says nothing an author can act on. */
.prop-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-1); margin-bottom: var(--space-2); }
.prop-cards--tall { grid-template-columns: repeat(3, 1fr); }
.prop-card {
  display: flex; flex-direction: column; align-items: stretch; gap: 2px;
  padding: 4px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-subtle); cursor: pointer; overflow: hidden;
}
.prop-card:hover { border-color: var(--accent); }
.prop-card--active { border-color: var(--accent); background: var(--accent-subtle); }
.prop-card-art { display: block; line-height: 0; overflow: hidden; }
.prop-card-art svg { width: 100%; height: auto; display: block; }
.prop-card-label { font-size: 10px; color: var(--text-muted); text-align: center; }
.prop-card--active .prop-card-label { color: var(--accent); }
