/* ── Reset & base ──────────────────────────────────────────── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

/*
 * ── Design tokens ─────────────────────────────────────────────
 *
 * Canonical tokens (colors, font, type scale, spacing, radii) come from the CDN:
 *   https://cdn.neorgon.org/v1.0.0/styles/base.css   (linked in index.html)
 * Do NOT redeclare them here: a local copy is how the fleet drifted. The block
 * below holds only what base.css does not define, plus the per-site accent.
 *
 * Motion: base.css still ships --ease-snap (bounce) for legacy sites, but it is
 * deprecated for new work (impeccable law: ease-out exponential, no bounce).
 * Use --ease-out below.
 */

:root {
  /* Per-site identity: set to this site's hub card accent (PROJECTS.md section 4) */
  --accent: #f97316;
  /* base.css pairs every --accent with a brighter hover; the pair has to move together */
  --accent-bright: #fb923c;
  --neo-auth-accent: #c2410c; /* Orange-700: the Auth Kit paints white on this, 5.18:1; on the site accent it would be 2.80:1 */
  /* Text on an accent-filled control. White on this orange measures 2.8:1
     and fails AA; the fleet ground measures 7.2:1 on --accent and 8.9:1 on
     --accent-bright (WCAG relative luminance, measured 2026-09-14). */
  --accent-ink: #040714;

  /* Site extras base.css does not define */
  --surface-toast: #1a1730;
  --danger: #e11d48;
  --danger-hover: #f43f5e;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --control-height: 44px;
  --control-height-sm: 36px;
  --shadow-card: 0 12px 28px rgba(15, 23, 42, 0.5);
  --shadow-modal: 0 24px 48px rgba(2, 6, 23, 0.58);
  --z-sticky-header: 200;
  --z-modal: 400;
  --z-toast: 500;
}

/* Author display values (e.g. .section/.stack flex) would otherwise defeat the
   hidden attribute, so restore its authority once, globally. */
[hidden] { display: none !important; }

html { height: 100%; }
body {
  font-family: var(--font);
  background: var(--bg);
  min-height: 100%;
  color: var(--text-primary);
  display: flex; flex-direction: column;
}

body.modal-open {
  overflow: hidden;
}

main#main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: 100%;
}

/* ── Layout ────────────────────────────────────────────────── */
/*
 * GOTCHA: body { display:flex; flex-direction:column } + margin: 0 auto
 * on a child collapses its width, so always pair with width: 100%.
 *
 * GOTCHA: External images (YouTube ggpht, Gravatar, etc.) may block loading
 * when the Referer header points to localhost or an unknown origin. Fix:
 * 1. Add <meta name="referrer" content="no-referrer"> in <head> (global)
 * 2. Or add referrerpolicy="no-referrer" on each <img> tag
 */
.container {
  max-width: 900px;
  width: 100%;
  margin: 0 auto;
  padding: var(--space-6);
  flex: 1;
}

/* ── Side-rail shell (opt-in) ──────────────────────────────────
 * A desktop window is far wider than a comfortable line of text, so a single
 * centred column leaves two large empty gutters and still runs the prose to
 * 100+ characters. This puts the section nav in the left gutter and narrows
 * the reading column, without changing .container for sites that do not use it.
 *
 *   <div class="shell">
 *     <nav class="shell__rail" aria-label="Section"> … </nav>
 *     <div class="shell__main"> … </div>
 *   </div>
 *
 * Below 940px it collapses to one column and the rail becomes a scrollable
 * row, so the same markup works on a phone with no JavaScript involved. From
 * 1240px up, the spare width goes to the right margin only, so the reading
 * column walks onto the page's centre line instead of sitting right of it.
 */
.shell {
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-6) 64px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
  align-content: start;
  flex: 1;
}
/* A 1fr track is minmax(auto, 1fr): a wide child (a board, a table, a long
   code line) sets min-content and stretches the column past the viewport. */
.shell > * { min-width: 0; }

.shell__rail {
  display: flex;
  gap: var(--space-1);
  padding: 4px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto;
  scrollbar-width: none;
}
.shell__rail::-webkit-scrollbar { display: none; }

@media (min-width: 940px) {
  .shell {
    grid-template-columns: 208px minmax(0, 1fr);
    gap: var(--space-8);
    padding: var(--space-8) var(--space-8) 80px;
  }
  .shell__rail {
    position: sticky;
    top: 76px;          /* clears the app-mode header */
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: var(--space-2);
    overflow: visible;
    align-self: start;
  }
}

/* The rail sits in the left gutter, but with only two tracks it does not stay
   there: the rail plus its gap add to main's left side and nothing balances
   them on the right, so main sits half that distance right of the page's centre
   line (120px at a 208px rail). A column that far off centre reads as a
   misalignment rather than as a nav beside it.
   The correction is to stop splitting the spare width between both margins and
   spend all of it on the right. Main then walks back onto the centre line as the
   window grows, reaching it at 1240 + 208 + 32 = 1480px, and it costs main no
   width at any point on the way: the shell widens, main does not move relative
   to the rail. Below 1240px the shell already fills the viewport, so there is no
   spare width to spend and any correction would come straight out of the
   reading column. That trade is not worth making. */
@media (min-width: 1240px) {
  .shell {
    --shell-nudge: calc(208px + var(--space-8));
    max-width: calc(1240px + var(--shell-nudge));
    padding-right: clamp(
      var(--space-8),
      calc(var(--space-8) + 100vw - 1240px),
      calc(var(--space-8) + var(--shell-nudge))
    );
  }
}

/* Vertical rhythm: use inside .container or nested regions */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.stack--tight { gap: var(--space-4); }
/* Major sections need a real break. At 32px a heading sits almost on top of
   the block above it and the page reads as one undifferentiated column. */
.stack--loose { gap: 56px; }

/* Page section: title row + body (replaces “card everything” for grouping) */
.section {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.section__header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
}
.section__titles {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.section__title {
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-primary);
}
.section__lead {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: 1.6;
  max-width: 64ch;   /* 65-75 characters is the readable measure */
}
.section__lead code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 0.92em;
  color: var(--text-secondary);
}
.stack > .card { margin-bottom: 0; }
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* ── Header ────────────────────────────────────────────────────
 * Owned by the Neorgon Header Kit (css/neorgon-header.css, canonical
 * source: packages/neorgon-ui/header/). Do NOT style .header-bar,
 * .header-logo*, .header-title-link, .header-subtitle, .header-right,
 * .header-actions, or .header-home here. Sign-in is the Neorgon Auth Kit
 * (css/neorgon-auth.css): never style .neo-auth or .auth-* here either.
 */
nav {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ── Buttons (canonical) ─────────────────────────────────────
 * Use .btn + a variant. Alias: .nav-link = toolbar ghost.
 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--space-4);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-primary);
  transition:
    background-color var(--dur),
    color var(--dur),
    border-color var(--dur),
    box-shadow var(--dur),
    transform var(--dur-fast);
  -webkit-tap-highlight-color: transparent;
}
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}
.btn--sm {
  min-height: var(--control-height-sm);
  padding: 0 var(--space-3);
  font-size: var(--text-xs);
}
.btn--block { width: 100%; }
.btn--icon {
  min-width: var(--control-height);
  padding: 0;
}
.btn--primary {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: transparent;
}
.btn--primary:hover { background: var(--accent-bright); }
.btn--secondary {
  background: var(--surface-2);
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.btn--secondary:hover {
  background: rgba(255, 255, 255, 0.1);
}
.btn--ghost {
  background: transparent;
  color: rgba(255,255,255,0.92);
  border-color: rgba(255,255,255,0.18);
}
.btn--ghost:hover {
  background: rgba(255,255,255,0.1);
  color: #fff;
}
.btn--danger {
  background: var(--danger);
  color: #fff;
  border-color: transparent;
}
.btn--danger:hover { background: var(--danger-hover); }

/* Toolbar ghost (header nav): same as .btn.btn--ghost.btn--sm */
.nav-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--control-height);
  padding: 0 var(--space-3);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--radius-sm);
  background: transparent;
  color: rgba(255,255,255,0.92);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  transition: background-color var(--dur), color var(--dur), border-color var(--dur);
}
.nav-link:hover {
  background: rgba(255,255,255,0.1);
  color: #fff;
}

/* ── Modal (blocking overlay) ──────────────────────────────── */
.modal[hidden] {
  display: none !important;
}
.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(2, 4, 12, 0.85);
  -webkit-backdrop-filter: blur(10px); /* Safari still needs the prefix */
  backdrop-filter: blur(10px);
}
.modal__dialog {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: min(100%, 520px);
  max-height: min(90vh, 680px);
  overflow: hidden;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-modal);
}
/* For modals holding option grids or editors: narrow dialogs cramp them */
.modal__dialog--wide {
  width: min(100%, 760px);
}
.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--border-subtle);
}
.modal__header h2 {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text-primary);
}
.modal__body {
  padding: var(--space-6);
  overflow: auto;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.55;
}
.modal__body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 0.9em;
  color: var(--text-primary);
}
.modal__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--border-subtle);
}

/* ── Card ──────────────────────────────────────────────────── */
/*
 * GOTCHA: backdrop-filter creates a stacking context, so dropdowns inside
 * a card can be clipped by a later card's stacking context. Fix by adding
 * position: relative; z-index: 10 to the card that owns the open dropdown.
 *
 * Default: static surface (no hover lift, avoids generic “dashboard demo”).
 * Use .card--interactive for raised hover + entrance motion.
 *
 * GOTCHA: a <button> or <a> used AS a card does not inherit body text color,
 * buttons default to canvas text (near-black), rendering invisible on the dark
 * bg. When a card is an interactive element, set color: var(--text-primary)
 * and font-family: var(--font) explicitly on it.
 */
.card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
  backdrop-filter: blur(10px);
  transition: border-color var(--dur), box-shadow var(--dur);
}
.card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 8px 20px rgba(15, 23, 42, 0.45);
}
.card--interactive {
  transition:
    transform var(--dur) ease-out,
    box-shadow var(--dur) ease-out,
    border-color var(--dur);
  animation: fadeIn 0.35s ease-out both;
}
.card--interactive:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-card);
  border-color: var(--border-strong);
}
.card--enter {
  animation: fadeIn 0.35s ease-out both;
}
.card--flat:hover {
  box-shadow: none;
}
/* Card with an action row, in an equal-height grid: pin the toolbar to the
   bottom so buttons align across cards whose text wraps differently. */
.card--actions {
  display: flex;
  flex-direction: column;
}
.card--actions > .toolbar:last-child {
  margin-top: auto;
}

/* ── Button press feedback ─────────────────────────────────── */
button:active,
.btn:active,
.nav-link:active {
  transform: scale(0.98);
  transition-duration: var(--dur-fast);
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Skeleton loading ──────────────────────────────────────── */
@keyframes shimmer { to { background-position: -200% 0; } }
.skeleton {
  background: linear-gradient(90deg, var(--surface-1) 25%, var(--surface-2) 50%, var(--surface-1) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
  border-radius: var(--radius);
}

/* ── Toast ─────────────────────────────────────────────────── */
.toast {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  z-index: var(--z-toast);
  max-width: min(360px, calc(100vw - var(--space-8)));
  background: var(--surface-toast);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-primary);
  box-shadow: var(--shadow-card);
  pointer-events: none;
  transform: translateY(8px);
  opacity: 0;
  transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}
.toast.visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── Footer ────────────────────────────────────────────────────
   Owned by the Neorgon Footer Kit (css/neorgon-footer.css).
   Don't add .neo-footer rules here. Edit packages/neorgon-ui/footer/
   and re-run sync-footer.sh.

   The one sanctioned form is a token override (footer README, "Per-site
   override"). The kit's app mode pads its shell with --space-6 and reserves
   no inline room for the two fixed 40px controls the fleet pins at the
   bottom corners, the beacon at left:20px and back-to-top at right:20px, so
   on this site the note started under the beacon and the meta bar ended
   under the arrow. Until the kit reads an inline token of its own, the
   token the shell reads is widened on the footer alone: offset 20 + control
   40 + 12 of air. Below 701px the kit switches to --space-4 and the bar
   wraps under the note, where nothing overlaps. */
@media (min-width: 701px) {
  .neo-footer[data-footer-mode="app"] { --space-6: 72px; }
}
/* Below 701px the kit reads --space-4 for the same inline padding, and the two
   fixed controls still sit at the corners, so the same 72px applies there;
   --space-4 is read once in footer.css, for this padding only. */
@media (max-width: 700px) {
  .neo-footer[data-footer-mode="app"] { --space-4: 72px; }
}

/* ── Focus styles ──────────────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
}

/* ── Skip link ─────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  z-index: 1000;
  padding: var(--space-2) var(--space-4);
  background: var(--accent-bright);
  color: #000;
  font-weight: 600;
  font-size: var(--text-sm);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  text-decoration: none;
  transition: top var(--dur);
}
.skip-link:focus { top: 0; }

/* ── Reduced motion ────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .card--interactive:hover { transform: none; }
}

/* ── Responsive ────────────────────────────────────────────── */
@media (max-width: 600px) {
  .container { padding: var(--space-4); }
  .toast {
    left: var(--space-4);
    right: var(--space-4);
    max-width: none;
  }
}

/* ══════════════════════════════════════════════════════════════
   Enamel: the studio
   Tokens come from the CDN base.css. Nothing below declares a colour, a space
   or a radius of its own beyond the two identity values at the top of this
   file, and nothing below touches the header or footer kit.
   ══════════════════════════════════════════════════════════════ */

/* ── Studio layout ─────────────────────────────────────────── */

.studio {
  display: grid;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-4);
  width: min(1400px, 100%);
  margin: 0 auto;
  align-items: start;
}

@media (min-width: 1000px) {
  .studio { grid-template-columns: minmax(0, 1fr) minmax(380px, 460px); }
  .studio__stage { position: sticky; top: 72px; }
}

.stage-head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

.preview-stage {
  display: grid;
  place-items: center;
  padding: var(--space-6);
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  min-height: 320px;
}

.preview-frame { width: 100%; display: grid; place-items: center; }
.preview-svg { width: 100%; max-width: 520px; height: auto; display: block; }

.preview-parody {
  color: var(--text-secondary);
  font-size: var(--text-sm);
  margin: var(--space-3) 0 0;
  max-width: 62ch;
}

.preview-note {
  color: var(--text-muted);
  font-size: var(--text-sm);
  margin: var(--space-3) 0 0;
  max-width: 62ch;
}

/* ── Warnings ──────────────────────────────────────────────── */

.warn-list { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }

.warn {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--surface-1);
  font-size: var(--text-sm);
}

.warn p { margin: var(--space-1) 0 0; color: var(--text-secondary); }
.warn--error { border-left-color: var(--danger); }
.warn--warn { border-left-color: var(--accent); }
.warn--note { border-left-color: var(--border-strong); }

.warn__tag {
  flex: none;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--text-muted);
  padding-top: 2px;
  min-width: 5.5em;
}

/* ── Save bar and notices ──────────────────────────────────── */

.save-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  margin-bottom: var(--space-4);
}

.save-bar__state { font-size: var(--text-sm); color: var(--text-secondary); }

/* Signed out: one sentence and the control that opens the Auth Kit's dialog,
   on its own line under the two disabled buttons. The explicit [hidden] rule
   is needed because display:flex would otherwise beat the UA's hidden. */
.save-bar__signin {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.save-bar__signin[hidden] { display: none; }

.notice {
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-1);
  margin-bottom: var(--space-4);
  font-size: var(--text-sm);
}

.notice p { margin: 0 0 var(--space-2); color: var(--text-secondary); }
.notice p:last-child { margin-bottom: 0; }
.notice h3 { font-size: var(--text-base); margin: 0 0 var(--space-2); }
.notice--warn { border-left-color: var(--accent); }
.notice--error { border-left-color: var(--danger); }
.notice__aside { color: var(--text-muted) !important; }
.notice a { color: inherit; text-decoration: underline; text-underline-offset: 2px; } /* the browser default blue measured 2.04:1 on the notice ground */

/* ── The editor form ───────────────────────────────────────── */

.editor { display: flex; flex-direction: column; gap: var(--space-3); }

.editor__group {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  background: var(--surface-1);
}

.editor__summary {
  cursor: pointer;
  padding: var(--space-3) var(--space-4);
  font-weight: 600;
  list-style: none;
}

.editor__summary::-webkit-details-marker { display: none; }
.editor__summary::before { content: '▸ '; color: var(--text-muted); }
.editor__group[open] > .editor__summary::before { content: '▾ '; }

.editor__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: 0 var(--space-4) var(--space-4);
}

/* Scoped to <details> on purpose: `.editor__group:not([open])` also matched the
   plain <div> that holds the font pairing, because a div can never carry `open`,
   and hid a control that is meant to be on the page at all times. */
details.editor__group:not([open]) > .editor__body { display: none; }

/* ── Fields ────────────────────────────────────────────────── */

.fld { display: flex; flex-direction: column; gap: var(--space-1); }
.fld--inline { flex-direction: row; align-items: center; gap: var(--space-2); }
.fld--wide { grid-column: 1 / -1; }

.fld__label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-muted);
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
}

.fld__out { color: var(--text-secondary); text-transform: none; letter-spacing: 0; }

.fld__input {
  width: 100%;
  min-height: var(--control-height-sm);
  padding: 0 var(--space-3);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--text-sm);
}

/* The page rule's 2px ring, kept: a 1px border colour change on its own is
   not the focus area WCAG 2.4.13 asks for. */
.fld__input:focus-visible { border-color: var(--accent); outline: 2px solid var(--accent-bright); outline-offset: 1px; }
.fld__input--mini { min-width: 0; }
textarea.fld__input, .fld__area { padding: var(--space-2) var(--space-3); resize: vertical; line-height: 1.5; }

.fld__hint { font-size: var(--text-xs); color: var(--text-muted); line-height: 1.5; }

.fld__note {
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: 1.6;
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--border);
}

.fld__range { width: 100%; accent-color: var(--accent); }
.fld--check { flex-direction: row; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
.fld--check input { accent-color: var(--accent); width: 16px; height: 16px; }

.fld__swatchwrap { display: flex; align-items: center; gap: var(--space-2); }
.fld__color {
  width: 44px;
  height: var(--control-height-sm);
  padding: 2px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.fld__hex { font-size: var(--text-xs); color: var(--text-muted); }

.repeat { display: flex; flex-direction: column; gap: var(--space-2); }
.repeat__row {
  display: grid;
  grid-template-columns: 1.4fr .8fr .8fr auto auto;
  gap: var(--space-2);
  align-items: center;
}

.certtext { display: flex; flex-direction: column; gap: var(--space-2); }
.certtext__row { display: grid; grid-template-columns: 1.4fr .7fr auto; gap: var(--space-2); }

.art__thumb {
  width: 96px;
  height: 96px;
  object-fit: contain;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-subtle);
}

/* ── Segmented control ─────────────────────────────────────── */

.segmented {
  display: inline-flex;
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  padding: 2px;
}

.segmented__btn {
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--text-sm);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.segmented__btn.is-on { background: var(--accent); color: var(--accent-ink); }

/* ── Presets ───────────────────────────────────────────────── */

.preset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.preset {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: center;
  text-align: center;
  padding: var(--space-3);
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.preset:hover { border-color: var(--border-strong); }
.preset.is-on { border-color: var(--accent); }
.preset__name { font-weight: 600; font-size: var(--text-sm); }
.preset__note { font-size: var(--text-xs); color: var(--text-muted); line-height: 1.5; }

.thumb { width: var(--thumb-size, 132px); display: grid; place-items: center; }
.thumb svg { width: 100%; height: auto; display: block; }
.thumb--broken { font-size: var(--text-xs); color: var(--text-muted); }

/* ── Lists: templates, versions, links ─────────────────────── */

.empty {
  padding: var(--space-6);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  text-align: center;
  color: var(--text-muted);
}

.empty p { margin: var(--space-2) 0 0; font-size: var(--text-sm); }

.pill {
  display: inline-block;
  font-size: var(--text-xs);
  padding: 2px var(--space-2);
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  color: var(--text-secondary);
}

.pill--good { border-color: var(--accent); color: var(--accent); }
.pill--muted { color: var(--text-muted); }
.pill--bad { border-color: var(--danger); color: var(--danger); }

.template__head { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: space-between; align-items: flex-start; }
.template__name { font-size: var(--text-lg); margin: 0 0 var(--space-2); }
.template__meta { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin: 0; }
.template__id code { font-size: var(--text-xs); color: var(--text-muted); }
.template__when { font-size: var(--text-xs); color: var(--text-muted); margin: 0; }
.template__desc { font-size: var(--text-sm); color: var(--text-secondary); margin: var(--space-3) 0 0; }

.versions { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.versions__row { display: grid; grid-template-columns: auto 1fr auto; gap: var(--space-3); align-items: baseline; font-size: var(--text-sm); }
.versions__n { font-weight: 600; color: var(--accent); }
.versions__log { color: var(--text-secondary); }
.versions__when { color: var(--text-muted); font-size: var(--text-xs); }

.link__head { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; justify-content: space-between; }
.link__url { font-size: var(--text-sm); word-break: break-all; color: var(--text-primary); }
.link__meta { font-size: var(--text-xs); color: var(--text-muted); margin: var(--space-2) 0 0; }
.link__claimants { margin-top: var(--space-3); }

.claimants { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.claimants li { display: flex; flex-wrap: wrap; gap: var(--space-3); font-size: var(--text-sm); align-items: baseline; }
.claimants code { font-size: var(--text-xs); color: var(--text-muted); }

.mint-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

/* ── Public catalogue (templates.html) ─────────────────────── */

.catalogue {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-4);
}

.catalogue__card { display: flex; flex-direction: column; gap: var(--space-3); }
.catalogue__thumb { display: grid; place-items: center; min-height: 150px; }
.catalogue__thumb .thumb { max-width: 100%; }
.catalogue__body { display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.catalogue__body .toolbar { margin-top: auto; }
