/* gallery.css — the Material 3 component catalogue. Rides on ../assets/index.css
   for the palette, type and site header; everything here is the rail, the
   component page and the detail view.

   The shape is m3.material.io's: a rail of component families, one page per
   family, each variant drawn beside the source that produced it. That is not
   imitation for its own sake — a catalogue organised by COMPONENT is the only
   arrangement in which "this is what Material 3 looks like from Compose" is a
   claim you can check. Organised by test case, the same pictures say nothing. */

/* Wider than the site's 1140px `.wrap`, because this page's content is not
   prose: half the row is a device and every pixel it gains is a pixel of the
   component. Measured at 1500px of window — 1400 put the component band at
   1.16x, 1560 puts it at 1.27x. */
.g-shell {
  display: grid; grid-template-columns: 264px minmax(0, 1fr);
  align-items: start;
  max-width: 1560px; margin: 0 auto;
}

/* ── Rail ─────────────────────────────────────────────────────────────────── */

.g-rail {
  position: sticky; top: 0; align-self: start;
  height: 100vh; display: flex; flex-direction: column;
  border-right: 1px solid var(--line); background: var(--panel);
}
.g-rail-head {
  flex: none; padding: var(--b3) var(--b2) 12px;
  border-bottom: 1px solid var(--line);
}
.g-rail-title {
  margin: 0 0 10px; font-family: var(--mono); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint);
}
.g-rail-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 10px 10px var(--b4); }

.g-rail-nav a {
  display: flex; align-items: baseline; gap: 8px;
  padding: 8px 12px; border-radius: 999px;
  color: var(--ink-soft); text-decoration: none; font-size: 14.5px;
}
.g-rail-nav a:hover { background: var(--paper-2); color: var(--ink); }
.g-rail-nav a.on { background: var(--accent); color: #fff; font-weight: 600; }
.g-rail-nav a.on .g-rail-n { color: rgba(255,255,255,.75); }
.g-rail-n {
  margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--ink-faint);
}

.g-seg { display: flex; border: 1px solid var(--line-strong); border-radius: 7px; overflow: hidden; }
.g-seg button {
  flex: 1 1 0; border: 0; background: var(--paper); cursor: pointer;
  padding: 6px 0; color: var(--ink-faint);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
}
.g-seg button + button { border-left: 1px solid var(--line); }
.g-seg button:hover { color: var(--ink); }
.g-seg button.on { background: var(--accent); color: #fff; }

/* ── Component page ───────────────────────────────────────────────────────── */

.g-main { padding: var(--b5) var(--b5) var(--b7); min-width: 0; }

.g-note {
  margin: 0 0 var(--b3); padding: 14px 16px;
  border: 1px solid var(--line-strong); border-left: 3px solid var(--accent);
  border-radius: 6px; background: var(--panel);
  font-family: var(--mono); font-size: 13px; line-height: 1.6; color: var(--ink-soft);
}
.g-note code { color: var(--accent-deep); }

.g-eyebrow {
  margin: 0 0 6px; font-family: var(--mono); font-size: 11.5px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--accent);
}
.g-h1 {
  margin: 0; font-family: var(--serif); font-weight: 600;
  font-size: clamp(30px, 4vw, 44px); line-height: 1.08; letter-spacing: -.01em;
}
/* No `pre-wrap`: the source wraps at 76 columns to stay readable as a Kotlin
   comment, and carrying that into the page hard-wrapped every blurb to the
   same three short lines whatever the reader's window. Paragraph breaks are
   what has to survive, and gallery.js makes those into real <p>s. */
.g-blurb { margin: var(--b2) 0 0; max-width: 68ch; }
.g-blurb p { margin: 0; font-size: 16.5px; line-height: 1.65; color: var(--ink-soft); }
.g-blurb p + p { margin-top: 0.7em; }
.g-blurb code, .g-vnote code {
  font-family: var(--mono); font-size: .88em; color: var(--accent-deep);
}

.g-variants {
  margin-top: var(--b5); display: grid; gap: var(--b4);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.g-variant { min-width: 0; }

/* The picture. Its height is whatever the catalogue file declared: a Switch
   centred in 915pt of nothing is a dot, and a Scaffold cropped to 150 is a
   stripe, so each family says how tall its own screens should be. */
.g-shot {
  display: block; width: 100%; padding: 0; cursor: pointer;
  border-radius: 12px; overflow: hidden; background: #FEF7FF;
  border: 1px solid var(--line);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.g-shot:hover { border-color: var(--accent); box-shadow: 0 8px 24px -14px rgba(27,25,22,.5); }
.g-shot:focus-visible { border-color: var(--accent); }
.g-shot img { display: block; width: 100%; height: auto; }
body.g-dark-art .g-shot { background: #141218; border-color: #2b2930; }

.g-vhead { display: flex; align-items: baseline; gap: 10px; margin: 12px 0 0; }
.g-vname { font-size: 16px; font-weight: 600; color: var(--ink); }
.g-vmeta {
  margin-left: auto; font-family: var(--mono); font-size: 10.5px; color: var(--ink-faint);
  white-space: nowrap;
}
.g-vmeta .bound { color: var(--accent-deep); }
.g-vnote { margin: 6px 0 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }

/* A known limitation, on the card that has it. A catalogue that shows only
   what works is marketing; this module's discipline is that a gap is visible. */
.g-gap {
  margin: 10px 0 0; padding: 9px 12px;
  border-radius: 7px; background: var(--paper-2);
  border-left: 3px solid var(--line-strong);
  font-size: 13.5px; line-height: 1.55; color: var(--ink-soft);
}
.g-gap b {
  display: block; font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink-faint);
  margin-bottom: 3px;
}

.g-src { margin: 10px 0 0; }
.g-src summary {
  cursor: pointer; font-family: var(--mono); font-size: 11.5px;
  color: var(--ink-faint); list-style: none; padding: 3px 0;
}
.g-src summary::-webkit-details-marker { display: none }
.g-src summary::before { content: '▸ '; }
.g-src[open] summary::before { content: '▾ '; }
.g-src summary:hover { color: var(--accent); }
.g-src pre {
  margin: 6px 0 0; padding: 12px 14px; overflow: auto; max-height: 340px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--paper);
  font-family: var(--mono); font-size: 12px; line-height: 1.6; tab-size: 2;
}

/* ── Corpus page (whole screens, not variants) ────────────────────────────── */

.g-grid {
  margin-top: var(--b4); display: grid; gap: var(--b3);
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.g-card { min-width: 0; }
.g-card-name {
  margin: 9px 0 0; font-family: var(--mono); font-size: 13px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.g-card-meta {
  display: flex; flex-wrap: wrap; gap: 4px 8px; margin-top: 3px;
  font-family: var(--mono); font-size: 10.5px; color: var(--ink-faint);
}
.g-card-meta b { font-weight: 600; color: var(--ink-soft); }
.g-card-meta .bound { color: var(--accent-deep); }

/* ── Variant strip ────────────────────────────────────────────────────────── */

/* Compact on purpose. Each chip used to carry the variant's whole note, which
   pushed the workbench — the part you came for — a screen and a half down the
   page. The note now sits in the workbench, beside the thing it describes. */

/* Every variant of the family, laid out at once with its own explanation. The
   picture is the BAKED still — accurate, instant, and there can be as many as
   the family has. Picking one opens the workbench below. */
/* `auto-fit`, with a ceiling. Ten of the twenty-four families have exactly one
   variant and ten have two, so an `auto-fill` grid of 190px tracks drew a 240px
   still beside two empty columns — the picture was small because the row was
   sized for a family that does not exist. Collapsing the empty tracks lets one
   or two stills take the width they have; the 380px ceiling stops a lone
   variant from becoming a billboard. */
.g-strip {
  margin-top: var(--b4); display: grid; gap: var(--b3);
  grid-template-columns: repeat(auto-fit, minmax(230px, 380px));
  justify-content: start;
}
.g-strip-note {
  margin: 12px 0 0; max-width: 74ch;
  font-family: var(--mono); font-size: 11px; line-height: 1.65; color: var(--ink-faint);
}
.g-strip-note[hidden] { display: none; }

.g-chip {
  display: flex; flex-direction: column; gap: 0; text-align: left;
  padding: 0; border: 0; background: none; font: inherit; color: inherit; cursor: pointer;
  min-width: 0;
}
.g-chip .g-shot { transition: border-color .15s ease, box-shadow .15s ease; }
.g-chip:hover .g-shot { border-color: var(--line-strong); }
.g-chip.on .g-shot {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.g-chip.on .g-vname { color: var(--accent-deep); }

/* ── Workbench ────────────────────────────────────────────────────────────── */

.g-bench {
  margin-top: var(--b5); padding-top: var(--b4);
  border-top: 1px solid var(--line);
}
.g-bench[hidden] { display: none; }
.g-bench-head { display: flex; align-items: flex-start; gap: var(--b2); }
.g-bench-head h2 {
  margin: 0; font-family: var(--serif); font-size: 26px; font-weight: 600;
}
.g-bench-sub {
  margin: 3px 0 0; font-family: var(--mono); font-size: 11.5px; color: var(--ink-faint);
}
#b-note { margin: 10px 0 0; max-width: 74ch; }
#b-note:empty { display: none; }

/* Editor LEFT, preview RIGHT — and now an even split. The preview used to be
   an `auto` column bounded by height, which measured 301x403: a 440x943 phone
   fits that at 0.398x, and at 0.398x a Slider's track is 1.6 pixels. Half the
   row puts the 412pt component band at ~1.35x instead, so the thing the page is
   about is the thing you can see. The editor's longest catalogue line is 105
   characters and already scrolled at the old width, so the trade is a scrollbar
   it had anyway against a component that was unreadable.

   The HEIGHT is set per variant from gallery.js — a 150pt band and a 700pt
   screen do not want the same box, and one fixed number gave the first an ocean
   of empty pane and the second half of what it needed. This is the fallback for
   before the engine loads. */
.g-bench-body {
  margin-top: var(--b3);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 1fr); gap: var(--b3);
  align-items: stretch;
  height: min(460px, 60vh);
}
.g-pane {
  min-width: 0; min-height: 0; display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  background: var(--paper);
}
.g-pane-preview { background: var(--paper-2); }
/* The device gets its own box to be centred in, so the pane's title and the
   caption below cannot push it out of the pane — which is what "the preview is
   cut off" looked like every time. */
.g-stage-wrap {
  flex: 1 1 auto; min-height: 0; padding: 14px;
  display: flex; align-items: center; justify-content: center;
}

.g-pane-title {
  flex: none; margin: 0; padding: 9px 14px; border-bottom: 1px solid var(--line);
  background: var(--panel);
  display: flex; align-items: center; gap: 10px;
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
}
.g-pane-title span span { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--ink-faint); }

/* The viewport switch. Reads as a control in the pane's own chrome rather than
   as a heading, because it changes what the pane shows. */
.g-modes {
  margin-left: auto; display: flex; flex: none;
  border: 1px solid var(--line-strong); border-radius: 6px; overflow: hidden;
}
.g-modes button {
  border: 0; background: var(--paper); cursor: pointer; padding: 3px 10px;
  color: var(--ink-faint);
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}
.g-modes button + button { border-left: 1px solid var(--line); }
.g-modes button:hover { color: var(--ink); }
.g-modes button.on { background: var(--accent); color: #fff; }

/* A textarea laid exactly over a highlighted <pre>. The <pre> is what you see;
   the textarea is transparent and carries the caret, the selection and the
   typing. They must agree on every metric that affects layout — font, size,
   line-height, padding, tab size — or the caret drifts from the glyph. */
.g-edit { flex: 1 1 auto; min-height: 0; position: relative; }
.g-edit > pre,
.g-edit > textarea {
  margin: 0; padding: 14px 16px; border: 0;
  font-family: var(--mono); font-size: 12.5px; line-height: 1.65;
  tab-size: 2; white-space: pre; overflow: auto;
}
.g-edit > pre { position: absolute; inset: 0; pointer-events: none; color: var(--ink); }
.g-edit > textarea {
  position: absolute; inset: 0; width: 100%; height: 100%;
  resize: none; outline: none; background: transparent;
  color: transparent; caret-color: var(--accent);
}
.g-edit > textarea::selection { background: rgba(187,74,24,.22); color: transparent; }
.g-edit > textarea[readonly] { caret-color: transparent; }

.g-editbar {
  flex: none; display: flex; align-items: center; gap: 9px;
  padding: 7px 14px; border-top: 1px solid var(--line); background: var(--panel);
  font-family: var(--mono); font-size: 11px; color: var(--ink-faint);
}
.g-editbar .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }
.g-editbar.err { color: var(--accent-deep); }
.g-editbar .g-reset {
  margin-left: auto; cursor: pointer; padding: 3px 9px;
  border: 1px solid var(--line-strong); border-radius: 6px;
  background: var(--paper); color: var(--ink-faint);
  font-family: var(--mono); font-size: 10.5px;
}
.g-editbar .g-reset:hover { color: var(--ink); border-color: var(--ink-faint); }

/* Shrink-wraps the canvas, whose size the renderer sets from the device frame
   and the mount zoom — both computed against this box in gallery.js. No
   aspect-ratio here any more: the ratio is the variant's, not the phone's.
   The hairline stands in for the bezel the component viewport does not draw. */
.g-stage-live {
  position: relative; line-height: 0;
  min-width: 150px; min-height: 110px;
  max-width: 100%; max-height: 100%;
  border-radius: 8px; overflow: hidden;
  box-shadow: 0 0 0 1px var(--line);
}
.g-stage-live canvas { display: block; }
.g-stage-live[data-empty]::after {
  content: attr(data-empty);
  position: absolute; inset: 0; display: grid; place-items: center;
  padding: 12px; text-align: center;
  font-family: var(--mono); font-size: 10px; line-height: 1.6; color: var(--ink-faint);
}
.g-live-note {
  flex: none; margin: 0; padding: 0 12px 12px; text-align: center;
  font-family: var(--mono); font-size: 10px; line-height: 1.5; color: var(--ink-faint);
}
.g-live-note.err { color: var(--accent-deep); }

.kw  { color: var(--kw); font-weight: 600; }
.ty  { color: var(--type); }
.str { color: var(--str); }
.num { color: var(--num); }
.fn  { color: var(--fn); }
.com { color: var(--com); font-style: italic; }
.key { color: var(--fn); }

@media (max-width: 1160px) {
  .g-bench-body { grid-template-columns: 1fr; height: auto !important; }
  .g-pane { min-height: 300px; }
  /* Content-driven: the canvas is sized from the width here, so the pane has to
     be free to be as tall as the component it is showing. */
  .g-pane-preview { min-height: 0; }
  .g-stage-wrap { min-height: 180px; }
}
@media (max-width: 1000px) {
  .g-shell { grid-template-columns: 1fr; }
  .g-rail { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .g-rail-nav { max-height: 240px; }
  .g-main { padding: var(--b4) var(--b3) var(--b6); }
}

