/* seed base — the stylesheet every theme is drawn with.

   Structure, the shell's regions and every `seed-*` component the runtime emits,
   written ONLY in the token names `theme-tokens.toml` lists. A theme supplies the
   values (as name = value pairs in its `{theme}` block) and, if it likes, a
   stylesheet of its own that is linked after this one. Compiled into both
   binaries and linked before any theme's CSS; a theme opts out with
   `base = false`.

   Colours that are the same in every theme are still named, once, below, so a
   theme may change them too. */

:root {
  --stage-bg:    rgba(0, 0, 0, .86);   /* the photo viewer's own dark stage */
  --stage-text:  #ffffff;
  --stage-muted: #eeeeee;
  --stage-control:       rgba(255, 255, 255, .14);   /* a button on that stage */
  --stage-control-hover: rgba(255, 255, 255, .28);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--font-size);
  line-height: var(--line-height);
}
h1, h2, h3, h4 { font-family: var(--font-heading); }
/* Links are the theme's accent, visited or not: a browser's own blue and purple
   are unreadable on a dark page. An element selector, so every component that
   styles its own links (a nav, a button, a card) still does. */
a { color: var(--accent); }
code, pre, kbd, samp { font-family: var(--font-mono); }
pre { background: var(--code-bg); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); overflow-x: auto; }

.site-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .6rem 1rem;
  min-height: var(--nav-height);
  background: var(--header-bg);
  color: var(--header-text);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow);
}
.site-brand { font-weight: 700; color: var(--accent); text-decoration: none; }
.site-nav { flex: 1; }
.site-tools { display: flex; align-items: center; gap: .5rem; }
.seed-nav { display: flex; gap: .25rem; list-style: none; margin: 0; padding: 0; }
.seed-nav a {
  display: flex; align-items: center; gap: .35em; white-space: nowrap;
  padding: .3rem .7rem; border-radius: var(--radius-sm);
  color: var(--muted); text-decoration: none;
}
/* A nav item is a glyph (its icon, or the initial of one without) and a label.
   The initial is shown only where the label is not — a folded side column. */
.seed-nav-glyph { line-height: 1; }
.seed-nav-initial { display: none; }
.seed-nav a:hover { color: var(--text); background: var(--bg); }
.seed-nav .active a { color: var(--accent); background: var(--bg); font-weight: 600; }

.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  border-radius: var(--radius-sm); width: 2rem; height: 2rem; padding: 0;
  font-size: 1rem; line-height: 1; cursor: pointer;
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }

/* "Log in" / "Log out" rendered as a stylized button, not a bare link. */
.site-link {
  display: inline-flex; align-items: center;
  padding: .35rem .8rem; border-radius: var(--radius-sm);
  background: var(--accent); color: var(--accent-text); text-decoration: none;
  font-weight: 600; font-size: .9rem; line-height: 1;
}
.site-link:hover { background: var(--accent-hover); }
.site-user { color: var(--muted); font-size: .9rem; }
/* An administrator signed in AS this account (impersonation): impossible to
   mistake for an ordinary sign-in. */
.site-acting { background: var(--warning, #b45309); color: #fff; border-radius: 4px;
  padding: .1rem .5rem; font-size: .85rem; }
/* The profile's summary: one row per part of the account, its button beside it. */
.seed-profile-summary td:last-child { text-align: right; white-space: nowrap; }
.seed-profile-more { display: flex; flex-wrap: wrap; gap: .5rem; }

.site-main { max-width: var(--content-width); margin: 0 auto; padding: 1.5rem 1rem; }
/* Layout keyword (page `layout = …`) controls the container width — content
   never changes, only the shell. `single` is the centred default; `wide` and
   `board` span the viewport so e.g. a kanban board can scroll many columns. */
.site-main--wide, .site-main--board { max-width: none; }
.site-main--board { padding: 1rem; }
.site-foot {
  display: flex; justify-content: space-between;
  max-width: var(--content-width); margin: 0 auto; padding: 1rem;
  background: var(--footer-bg); color: var(--footer-text); border-top: 1px solid var(--border);
}

/* Components */
.seed-datagrid table { width: 100%; border-collapse: collapse; background: var(--surface); }
.seed-datagrid th, .seed-datagrid td { padding: .5rem .7rem; border-bottom: 1px solid var(--border); text-align: left; }
.seed-datagrid th { color: var(--muted); font-size: .85rem; text-transform: uppercase; letter-spacing: .03em; }

.seed-alert { padding: .7rem 1rem; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); }
.seed-alert-info { border-left: 4px solid var(--accent); }
.seed-alert-success { border-left: 4px solid var(--success); }
.seed-alert-warn, .seed-alert-warning { border-left: 4px solid var(--warn); }
.seed-alert-error { border-left: 4px solid var(--error); }
/* A form that is a table (the admin's Themes panel) needs the page's width. */
.seed-form.seed-themes-admin { max-width: none; }
.seed-themes-admin td { vertical-align: top; }

.seed-form { display: grid; gap: .6rem; max-width: 28rem; }
.seed-form label { display: grid; gap: .2rem; color: var(--muted); }
.seed-form input { padding: .45rem .6rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); color: var(--text); }
.seed-form button { justify-self: start; padding: .5rem 1rem; border: 0; border-radius: var(--radius-sm); background: var(--accent); color: var(--accent-text); cursor: pointer; }
.seed-form button:hover { background: var(--accent-hover); }

.seed-component { padding: .5rem; border: 1px dashed var(--border); border-radius: var(--radius-sm); color: var(--muted); font-size: .85rem; }

/* Toolbar */
.seed-toolbar { display: flex; align-items: center; gap: .5rem; padding: .4rem .2rem; border-bottom: 1px solid var(--border); margin-bottom: 1rem; }
.seed-toolbar .tb-left { display: flex; gap: .4rem; align-items: center; flex: 1; }
.seed-toolbar .tb-right { display: flex; gap: .4rem; align-items: center; }
.tb-label { font-weight: 600; color: var(--accent); }
.tb-button, .tb-dropdown, .tb-menu { padding: .3rem .6rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); cursor: pointer; font-size: .9rem; }

/* Board */
.seed-board { display: flex; gap: 1rem; align-items: flex-start; overflow-x: auto; }
.seed-column { flex: 0 0 16rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.seed-column-head { padding: .5rem .7rem; font-weight: 600; border-bottom: 1px solid var(--border); }
.seed-column-body { padding: .5rem; display: grid; gap: .5rem; min-height: 2rem; }
.seed-card { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: .5rem .6rem; box-shadow: var(--shadow); }
.seed-card-title { font-weight: 500; }
.seed-card-badge { display: inline-block; margin-top: .3rem; padding: .05rem .4rem; font-size: .75rem; border-radius: 1rem; background: var(--accent); color: var(--accent-text); }
.seed-board-empty, .seed-gallery-empty, .seed-cardgrid-empty { color: var(--muted); padding: 1rem; }

/* Gallery + cardgrid */
.seed-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: .8rem; }
.seed-tile { margin: 0; }
.seed-tile img { width: 100%; height: 8rem; object-fit: cover; border-radius: var(--radius); background: var(--surface); }
.seed-tile figcaption { font-size: .8rem; color: var(--muted); margin-top: .25rem; }
.seed-cardgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: .8rem; }
.seed-card-link { text-decoration: none; color: inherit; }
.seed-card-field { color: var(--muted); font-size: .9rem; margin: .2rem 0 0; }

/* Settings dropdown (native <details>; no modal JS). */
.site-settings { position: relative; display: inline-block; }
.site-settings > summary { list-style: none; cursor: pointer; }
.site-settings > summary::-webkit-details-marker { display: none; }
.settings-menu { position: absolute; right: 0; margin-top: .4rem; min-width: 12rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: .5rem; display: grid; gap: .5rem; z-index: 20; }
.settings-item { display: block; width: 100%; text-align: left; padding: .35rem .2rem;
  margin-top: .3rem; color: var(--text); text-decoration: none; border-top: 1px solid var(--border); }
.settings-item:hover { color: var(--accent); }
.settings-skins { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center;
  color: var(--muted); font-size: .85rem; }
.settings-skins button { padding: .2rem .5rem; border: 1px solid var(--border);
  border-radius: 1rem; background: var(--bg); color: var(--text); cursor: pointer; }
.settings-langs { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center;
  color: var(--muted); font-size: .85rem; border-top: 1px solid var(--border); padding-top: .4rem; }
.settings-lang { padding: .2rem .5rem; border: 1px solid var(--border); border-radius: 1rem;
  background: var(--bg); color: var(--text); text-decoration: none; }
.settings-lang:hover { color: var(--accent); border-color: var(--accent); }

/* ── Floating popover menus — GLOBAL (every resource inherits) ──────────────────
   Toolbar dropdowns (New/Info/Share, board switcher) + per-row overflow ([⋯]).
   The panel is position:absolute so it NEVER grows the bar or the row and never
   wraps into the flex line (Principle 3: layout decoupled from content). It
   stacks its options vertically and scrolls if long. */
.seed-toolbar .tb-menu, .seed-toolbar .tb-dropdown { position: relative; display: inline-block; }
.seed-toolbar .tb-menu > summary, .seed-toolbar .tb-dropdown > summary {
  list-style: none; cursor: pointer; user-select: none; white-space: nowrap; }
.seed-toolbar .tb-menu > summary::-webkit-details-marker,
.seed-toolbar .tb-dropdown > summary::-webkit-details-marker { display: none; }
.tb-menu-items, .seed-row-more-items {
  position: absolute; top: 100%; z-index: 60; min-width: 13rem; margin-top: .3rem;
  display: flex; flex-direction: column; padding: .3rem;
  max-height: min(70vh, 22rem); overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); }
.tb-menu-items { left: 0; }
.seed-row-more-items { right: 0; }                 /* right-align so it clears the table edge */
.tb-menu-items > .tb-menu-item, .seed-row-more-items > .seed-row-action {
  display: block; width: 100%; text-align: left; white-space: nowrap; text-decoration: none;
  padding: .4rem .6rem; border: none; background: transparent; color: var(--text);
  cursor: pointer; border-radius: var(--radius-sm); font-size: .9rem; }
.tb-menu-items > .tb-menu-item:hover, .seed-row-more-items > .seed-row-action:hover {
  background: var(--surface-2); }

/* Archive-catalog panel — the op result box + health lines. */
.seed-catalog-result { background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: .6rem .8rem; white-space: pre-wrap; font-size: .9rem;
  color: var(--text); overflow-x: auto; }
.seed-catalog-health { font-family: var(--font-mono);
  font-size: .85rem; color: var(--muted); padding: .1rem 0; }
/* One catalogue's section inside the entry dialog. The same bytes may be in
   several catalogues, and each gets a description and tags of its own — without
   a rule between them the three forms read as one long form with its fields
   repeated three times. */
.seed-entry-set { border-top: 1px solid var(--border); padding-top: .7rem;
  margin-top: .9rem; }
.seed-entry-set:first-of-type { border-top: 0; margin-top: .4rem; }
.seed-entry-set h4 { margin: 0 0 .15rem; font-size: 1rem; }
.seed-entry-set textarea { min-height: 4rem; }
/* A 64-character digest is not prose: it wraps mid-word or it overflows the
   dialog, and both are worse than small monospace that may break anywhere. */
/* What a table IS, above it. Three grids in a row are three tables of
   unlabelled columns without this. */
.seed-datagrid-title { margin: .9rem 0 .35rem; font-size: .95rem; font-weight: 600;
  opacity: .9; }
.seed-hash { font-family: var(--font-mono);
  font-size: .78rem; word-break: break-all; opacity: .85; }

/* Per-row overflow trigger ([⋯]) sitting in a datagrid action cell. */
.seed-row-actions { display: flex; align-items: center; gap: .2rem; white-space: nowrap; }
.seed-row-more { position: relative; display: inline-block; }
.seed-row-more > summary { list-style: none; cursor: pointer; padding: .1rem .45rem; border-radius: var(--radius-sm); }
.seed-row-more > summary::-webkit-details-marker { display: none; }
.seed-row-more > summary:hover { background: var(--surface-2); }

/* Documentation search box */
.doc-search { display: flex; gap: .5rem; margin: 1rem 0 1.5rem; }
.doc-search input[type="search"] {
  flex: 1; padding: .5rem .75rem; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--bg); color: var(--text); font: inherit;
}
.doc-search button {
  padding: .5rem 1rem; border: 0; border-radius: var(--radius-sm); cursor: pointer;
  background: var(--accent); color: var(--accent-text); font: inherit;
}

/* #7 toast / snackbar */
#seed-toast { position: fixed; bottom: 1rem; right: 1rem; z-index: 60; display: flex;
  flex-direction: column; gap: .5rem; max-width: 22rem; }
.seed-toast-item { padding: .6rem .9rem; border-radius: var(--radius-sm); color: var(--accent-text); cursor: pointer;
  box-shadow: var(--shadow-lg); opacity: 1; transition: opacity .4s; font-size: .85rem; }
.seed-toast-error { background: var(--error); }
.seed-toast-info { background: var(--info); }
.seed-toast-out { opacity: 0; }

/* Data-grid cell links — readable in light AND dark (text colour + accent underline) */
.seed-datagrid td a { color: var(--text); text-decoration: underline; text-decoration-color: var(--accent); }
.seed-datagrid td a:hover { color: var(--accent); }

/* ── Generic primitive components — forms, modals, field/cell grids, paging.
   These classes are emitted by the engine's components ({form}, {fieldgrid},
   the #seed-modal mount, datagrid paging, breadcrumbs, row actions) for ANY
   resource, so they live in the shared theme (not a per-resource asset). ── */

/* Forms — complete the input set the {form} component emits. */
.seed-form textarea, .seed-form select {
  padding: .45rem .6rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--text); font: inherit; width: 100%; box-sizing: border-box; }
.seed-form textarea { resize: vertical; min-height: 5rem; }
.seed-form input[type="color"] { width: 3rem; height: 2rem; padding: 0; }
.seed-form input[type="checkbox"], .seed-form input[type="radio"] { width: auto; }
.seed-form-actions { display: flex; align-items: center; gap: .5rem; margin-top: .4rem; }
.seed-btn-danger { margin-left: auto; padding: .4rem .8rem; border: 1px solid var(--error);
  border-radius: var(--radius-sm); background: transparent; color: var(--error); cursor: pointer; }
.seed-btn-danger:hover { background: var(--error); color: var(--accent-text); }

/* Modal — a non-empty #seed-modal mount becomes a centered overlay; its child is
   the box. Used by fm per-file actions (info/annotate/tags/move), kanban, etc. */
#seed-modal:empty { display: none; }
#seed-modal:not(:empty) { position: fixed; inset: 0; z-index: 50; display: flex;
  align-items: flex-start; justify-content: center; padding: 4rem 1rem;
  background: var(--overlay); }
.seed-modal-box { background: var(--surface); color: var(--text); border-radius: var(--radius);
  border: 1px solid var(--border); box-shadow: var(--shadow-lg);
  width: min(40rem, 100%); max-height: 80vh; overflow: auto; padding: 1.2rem 1.4rem; }
.seed-modal-box .seed-form { max-width: none; }
/* `modal_size = "wide"` on a fragment view — a dialog holding a table (the
   admin's users and themes): wide enough to read a row without scrolling sideways. */
.seed-modal-box--wide { width: min(72rem, 100%); }
.seed-modal-box textarea { min-height: 10rem; }
.seed-modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .8rem; }
.seed-modal-title { font-size: 1.15rem; font-weight: 700; }
.seed-modal-close { background: none; border: 0; font-size: 1.3rem; line-height: 1;
  color: var(--muted); cursor: pointer; }

/* Field grid — a record's fields as label/value rows (fm details, apiml record). */
.seed-fieldgrid { display: grid; grid-template-columns: minmax(8rem, max-content) 1fr;
  gap: .35rem .9rem; margin: 1rem 0; }
.seed-field-label { color: var(--muted); font-weight: 600; }
.seed-field-value { color: var(--text); overflow-wrap: anywhere; }

/* Cell (element:toon label/value pairs). */
.seed-cell { display: flex; gap: .5rem; padding: .2rem 0; }
.seed-cell-label { color: var(--muted); min-width: 8rem; }
.seed-cell-value { color: var(--text); overflow-wrap: anywhere; }

/* Data-grid paging + breadcrumb + row actions (generic across resources). */
.seed-pager { display: flex; align-items: center; gap: .8rem; margin: .8rem 0; }
.seed-page-prev, .seed-page-next { padding: .3rem .7rem; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface); color: var(--text); text-decoration: none; }
.seed-page-info { color: var(--muted); font-size: .85rem; }
.seed-breadcrumb { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center;
  color: var(--muted); margin: .6rem 0; }
.seed-breadcrumb a { color: var(--accent); text-decoration: none; }
.seed-row-actions { display: inline-flex; gap: .25rem; }
.seed-row-action { padding: .1rem .4rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); text-decoration: none; font-size: .85rem; cursor: pointer; }
.seed-row-action:hover { border-color: var(--accent); color: var(--accent); }

/* Data-grid: alternating rows + hover for scannability; external-link icon. */
.seed-datagrid tbody tr:nth-child(even){background:color-mix(in srgb,var(--surface-2) 50%,transparent)}
.seed-datagrid tbody tr:hover{background:var(--surface-2)}
.seed-datagrid td{vertical-align:top}
.seed-link-icon{opacity:.6;font-size:.9em}
/* Live search box above the grid. */
.seed-grid-toolbar{display:flex;gap:.6rem;align-items:center;margin:0 0 .6rem}
.seed-search{flex:1;max-width:24rem;padding:.45rem .7rem;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:var(--surface);color:var(--text);font-size:.95rem}
.seed-search:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--focus)}
/* Sortable column headers (click to sort; ▲/▼ shows the active direction). */
.seed-sort{color:var(--muted);text-decoration:none;cursor:pointer;display:inline-flex;gap:.25rem;white-space:nowrap}
.seed-sort:hover{color:var(--accent)}

/* ── The project landing page: one card per installed resource ───────────────
   Each card is contributed by its resource (`models/<res>/landing.md`) and
   wrapped in a `::: seed-res-card` fenced div — markdown, not raw HTML, so an
   author still writes prose. Without the wrapper the page was a run of bare
   headings and default-blue links with nothing to separate one resource from
   the next. */
.seed-res-card { border: 1px solid var(--border); border-radius: var(--radius);
               background: var(--surface); padding: .9rem 1rem 1rem;
               box-shadow: var(--shadow); }
.seed-res-card h2 { margin: 0 0 .35rem; font-size: 1.12rem; }
.seed-res-card p { margin: 0 0 .7rem; color: var(--muted); font-size: .93rem; }
.seed-res-card p:last-child { margin-bottom: 0; color: inherit; }
.seed-res-card a { color: var(--accent); text-decoration: none; font-weight: 500; }
.seed-res-card a:hover { text-decoration: underline; }

/* ── The share dialog ────────────────────────────────────────────────────────
   Shared ground: the links list, the grant line and the people picker are the
   ACCESS ENGINE's interface, not any one resource's, so every resource that
   shares uses these classes. They lived in no stylesheet at all — kanban's
   dialog got by on the modal and form rules alone, and cal's, with more rows,
   did not. */
.seed-link-list, .seed-grant-list, .seed-principal-list { list-style: none; margin: .3rem 0 .8rem; padding: 0; }
.seed-link-row, .seed-grant {
  display: flex; align-items: center; gap: .45rem; flex-wrap: wrap;
  padding: .35rem .5rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  margin-bottom: .35rem; font-size: .9rem; }
.seed-link-type { padding: .05rem .45rem; border-radius: 1rem; font-size: .74rem;
                background: var(--accent); color: var(--accent-text); text-transform: uppercase; }
.seed-type-private { background: var(--muted); }
.seed-link-meta, .seed-link-spent, .seed-link-restrict, .seed-grant-made, .seed-grant-by {
  color: var(--muted); font-size: .82rem; }
.seed-link-window, .seed-grant-window { font-size: .82rem; }
.seed-grant-window.lapsed, .seed-grant-window.expired { color: var(--error); }
.seed-grant-who { font-weight: 500; }
.seed-grant-level { padding: .05rem .45rem; border-radius: 1rem; font-size: .74rem;
                  border: 1px solid var(--border); color: var(--muted); }
/* The remove/copy/regenerate controls sit at the end of their row. */
.seed-link-row .seed-col-ctrl:first-of-type, .seed-grant .seed-col-ctrl:first-of-type { margin-left: auto; }
.seed-col-ctrl { border: 0; background: transparent; cursor: pointer; padding: .1rem .25rem;
               color: var(--muted); border-radius: var(--radius-sm); font-size: .95rem; }
.seed-col-ctrl:hover { background: var(--surface-2); color: var(--text); }
.seed-share-note { color: var(--muted); font-size: .85rem; margin: .2rem 0 .6rem; }
.seed-share-window { display: flex; gap: .6rem; flex-wrap: wrap; }
.seed-share-window label { flex: 1 1 9rem; }
.seed-share-once { display: flex; align-items: center; gap: .4rem; }
.seed-share-vis { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .8rem; }
.seed-add-grant summary { cursor: pointer; display: inline-block; }
.seed-add-grant[open] summary { margin-bottom: .5rem; }
/* The live passphrase verdict. Colour AND a glyph: the one field where a typo
   is unrecoverable is not a good place to rely on colour alone. */
.fm-pass-verdict { font-size: .8rem; margin: .15rem 0 .5rem; min-height: 1rem; }
.fm-pass-waiting { color: var(--muted); }
.fm-pass-ok      { color: var(--success); }
.fm-pass-bad     { color: var(--error); }
/* A key source this deployment cannot offer, greyed with its reason beside it. */
.fm-key-off      { opacity: .55; }

/* The column toggle bar. Chips, not checkboxes: the state a person wants to see
   at a glance is "which columns am I looking at", and five ticked boxes read as
   a form to fill in rather than a row of switches already set. */
.seed-col-toggles { display: flex; flex-wrap: wrap; gap: .3rem; margin: 0 0 .4rem; }
.seed-col-chip { cursor: pointer; font-size: .74rem; padding: .1rem .5rem;
                border: 1px solid var(--border); border-radius: 1rem;
                background: transparent; color: var(--muted); }
.seed-col-chip:hover { border-color: var(--accent); }
/* An ACTIVE chip is filled, not merely bolder: at .74rem a weight change is not
   a state anyone can read across five of them. */
.seed-col-chip.active { background: var(--accent); border-color: var(--accent);
                color: var(--accent-text); }

/* A `type = "browse"` field: the value, and Browse beside it. The input takes
   the room because it is the thing being edited — the button only opens an
   assist, and a chooser as wide as the value it fills reads as the main event. */
.seed-browse-row { display: flex; gap: .4rem; align-items: stretch; }
.seed-browse-row .seed-browse-input { flex: 1 1 auto; min-width: 0; }
.seed-browse-btn { flex: 0 0 auto; white-space: nowrap; cursor: pointer;
                border: 1px solid var(--border); border-radius: var(--radius-sm);
                background: var(--bg); color: var(--text); padding: .3rem .6rem; }
.seed-browse-btn:hover { border-color: var(--accent); }
/* Inset and bounded: the panel sits UNDER the field it fills, and a deep tree
   scrolls inside it rather than growing the dialog past the viewport — which is
   how a Cancel button ends up somewhere you cannot reach. */
.seed-browse-panel { margin: .35rem 0 .6rem; padding: .4rem; max-height: 15rem;
                overflow-y: auto; border: 1px solid var(--border);
                border-radius: var(--radius-sm); background: var(--surface-2); }
.seed-browse-panel[hidden] { display: none; }

/* CHIPS — a multi-value pick, and now a directory's own labels with a way off.
   `picker.js` has created `.seed-chip` / `.seed-chip-x` since the multi-folder
   picker existed and NOTHING styled them: they rendered as bare text with a
   button beside it, which reads as two things rather than one removable one. */
.seed-chips { display: flex; flex-wrap: wrap; gap: .3rem; padding: 0; margin: .3rem 0;
                list-style: none; }
.seed-chip  { display: inline-flex; align-items: center; gap: .3rem;
                border: 1px solid var(--border); border-radius: 1rem;
                background: var(--surface-2); color: var(--text);
                padding: .1rem .5rem; font-size: .85rem; }
.seed-chip-x { border: 0; background: none; color: var(--text); cursor: pointer;
                padding: 0 .1rem; line-height: 1; opacity: .6; }
.seed-chip-x:hover { opacity: 1; color: var(--accent); }

.fm-folder-browse-here { display: flex; align-items: center; gap: .5rem;
                justify-content: space-between; margin-bottom: .4rem; }

.seed-principal-list li { margin-bottom: .25rem; }
.seed-principal { width: 100%; text-align: left; border: 1px solid var(--border);
                border-radius: var(--radius-sm); background: var(--bg); color: var(--text);
                padding: .3rem .5rem; cursor: pointer; }
.seed-principal:hover { border-color: var(--accent); }
.seed-modal-box h4 { margin: .9rem 0 .2rem; font-size: .95rem; }

/* A nav icon that is an IMAGE (a generated one — cal draws today). Sized and
   baseline-aligned like the emoji glyphs it sits beside. */
.seed-nav-icon { display: inline-block; vertical-align: -.22em; width: 1.15em; height: 1.15em; }

/* Whose is this? A shared item says so where you are looking: in the picker (a
   mark after the name), in the listing (a column), and on the item itself (one
   line naming the sharer and what you may do). "shared" alone means full
   access — anything less says so. */
.seed-shared-tag { font-size: .78rem; color: var(--muted); border: 1px solid var(--border);
                 border-radius: 1rem; padding: .05rem .5rem; white-space: nowrap; }

/* ── Save / import component ─────────────────────────────────────────────────
   The export bar, the file picker and the verdict. Styled here rather than per
   resource because kanban and cal already share the component, and a third one
   should inherit the look rather than re-describe it. */
.seed-exportbar{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;margin:.8rem 0}
.seed-exportbar input[type=text]{flex:1 1 14rem;min-width:10rem;padding:.4rem .6rem;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text)}
.seed-picker-list{list-style:none;margin:.4rem 0;padding:0;max-height:22rem;overflow:auto;border:1px solid var(--border);border-radius:var(--radius)}
.seed-picker-list li{border-bottom:1px solid var(--border)}
.seed-picker-list li:last-child{border-bottom:0}
.seed-picker-dir,.seed-picker-file{display:block;width:100%;text-align:left;padding:.45rem .7rem;background:none;border:0;color:var(--text);text-decoration:none;font:inherit;cursor:pointer}
.seed-picker-dir:hover,.seed-picker-file:hover{background:var(--surface-2);color:var(--accent)}
.seed-picker-empty{color:var(--muted);font-size:.9rem;margin:.4rem 0}
.seed-picker-paste{margin:.8rem 0}
.seed-picker-paste summary{cursor:pointer;color:var(--accent)}
.seed-picker-paste textarea{width:100%;font-family:var(--font-mono);font-size:.85rem}
.seed-verify{padding:.5rem .7rem;border-radius:var(--radius-sm);margin:.6rem 0}
.seed-verify-ok{background:color-mix(in srgb,var(--success) 12%,transparent);border:1px solid color-mix(in srgb,var(--success) 40%,transparent)}
.seed-verify-bad{background:color-mix(in srgb,var(--error) 12%,transparent);border:1px solid color-mix(in srgb,var(--error) 45%,transparent)}

/* ── API models ──────────────────────────────────────────────────────────────
   The search form folds into a bar once it has results, so the grid gets the
   width; the spinner shows while a search is out (htmx reveals it). */
.seed-form-collapse{border:1px solid var(--border);border-radius:var(--radius);margin:1rem 0;background:var(--surface)}
.seed-form-collapse>summary{cursor:pointer;padding:.55rem .9rem;font-weight:600;color:var(--accent)}
.seed-form-collapse[open]>summary{border-bottom:1px solid var(--border)}
.seed-form-collapse>.seed-form{padding:0 .9rem .9rem;max-width:none;display:grid;grid-template-columns:repeat(auto-fill,minmax(14rem,1fr));gap:.7rem}
.seed-form-collapse>.seed-form .seed-form-actions{grid-column:1/-1}
.seed-spinner{margin-left:.7rem;color:var(--muted);font-size:.9rem}
.seed-spinner::before{content:"";display:inline-block;width:.9em;height:.9em;margin-right:.4em;vertical-align:-.12em;
  border:2px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:seed-spin .8s linear infinite}
@keyframes seed-spin{to{transform:rotate(360deg)}}
.htmx-request.seed-spinner,.htmx-request .seed-spinner{opacity:1}

/* One record: navigation, then a two-column layout the model declares — a
   compact table of fields, and the images (with a lightbox) and the map. */
.seed-rv-nav{display:flex;flex-wrap:wrap;gap:.3rem;margin:.4rem 0 1rem;padding:.45rem .8rem;
  border:1px solid var(--border);border-radius:var(--radius);background:var(--surface)}
.seed-rv-nav p{margin:0}
.seed-recordview{display:grid;gap:1.4rem;grid-template-columns:1fr;align-items:start}
@media (min-width:60rem){.seed-recordview[data-columns="2"]{grid-template-columns:minmax(0,3fr) minmax(0,2fr)}
  .seed-recordview[data-columns="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}}
.seed-rv-col{display:grid;gap:1.2rem;min-width:0}
.seed-rv-fields{width:100%;border-collapse:collapse;font-size:.9rem;border:1px solid var(--border)}
.seed-rv-fields th,.seed-rv-fields td{padding:.3rem .6rem;text-align:left;vertical-align:top;border-bottom:1px solid var(--border)}
.seed-rv-fields th{width:32%;color:var(--muted);font-weight:600;white-space:nowrap}
.seed-rv-fields td{overflow-wrap:anywhere}
.seed-rv-fields tr:nth-child(even){background:color-mix(in srgb,var(--accent) 7%,transparent)}
.seed-rv-fields pre{margin:0;white-space:pre-wrap;font-size:.82rem}
.seed-ext{font-size:.8em;opacity:.75}
.seed-rv-thumbs{display:flex;flex-wrap:wrap;gap:.6rem}
.seed-rv-thumb img{display:block;height:9rem;width:auto;max-width:100%;border:1px solid var(--border);border-radius:var(--radius-sm);object-fit:cover}
.seed-rv-thumb:hover img{border-color:var(--accent)}
.seed-lightbox{display:none}
.seed-lightbox:target{display:flex;position:fixed;inset:0;z-index:1000;flex-direction:column;align-items:center;justify-content:center;
  gap:.6rem;background:var(--stage-bg);padding:1.5rem}
.seed-lightbox img{max-width:94vw;max-height:80vh;object-fit:contain;border-radius:var(--radius-sm)}
.seed-lb-close{position:absolute;top:.8rem;right:1.1rem;color:var(--stage-text);font-size:1.6rem;text-decoration:none}
.seed-lb-bar{display:flex;gap:1rem;align-items:center;color:var(--stage-muted);font-size:.9rem}
.seed-lb-bar a{color:var(--stage-text);text-decoration:none}
.seed-lb-prev,.seed-lb-next{font-size:2rem;line-height:1;padding:0 .6rem}
.seed-rv-map iframe{display:block;width:100%;height:20rem;border:1px solid var(--border);border-radius:var(--radius)}
.seed-rv-map-link{margin:.3rem 0 0;font-size:.85rem}

/* Links on the model pages: the theme's accent, in both modes, whether or not
   they have been visited — a browser's default blue and purple are unreadable
   on the dark background. Buttons for the actions that ARE actions. */
.seed-recordview a, .seed-rv-nav a, .seed-pageinfo a, .seed-row-link,
.seed-recordview a:visited, .seed-rv-nav a:visited, .seed-pageinfo a:visited, .seed-row-link:visited{color:var(--accent)}
.seed-rv-nav{align-items:center;gap:.45rem;color:var(--muted);font-size:.9rem}
.seed-rv-nav p{display:flex;flex-wrap:wrap;gap:.45rem;align-items:center}
.seed-rv-nav a, .seed-btn{display:inline-flex;align-items:center;gap:.3rem;padding:.3rem .7rem;border:1px solid var(--border);
  border-radius:var(--radius-sm);background:var(--bg);color:var(--accent);text-decoration:none;font-size:.88rem;white-space:nowrap}
.seed-rv-nav a:hover, .seed-btn:hover{border-color:var(--accent);background:var(--surface)}
.seed-row-link{text-decoration:none;font-weight:600}
.seed-row-link:hover{text-decoration:underline}
.seed-row-link-icon{display:inline-block;margin-left:.15rem;opacity:.8;transition:transform .12s}
.seed-row-link:hover .seed-row-link-icon{transform:translateX(2px);opacity:1}
.seed-pageinfo{margin:.8rem 0;display:grid;gap:.5rem}
.seed-pageinfo-total{margin:0;color:var(--muted);font-size:.9rem}
.seed-actions{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center}
.seed-actions-label{color:var(--muted);font-size:.88rem;margin-right:.2rem}
.seed-asked{margin:0;color:var(--muted);font-size:.82rem;overflow-wrap:anywhere}
.seed-asked code{color:var(--text)}
.seed-rv-map-link a{text-decoration:none}
.seed-rv-subtitle{margin:-.6rem 0 1rem;font-size:1.05rem;color:var(--muted)}
.seed-page-first,.seed-page-last{font-weight:600}

/* Charts ({chart}), a form's static (read-only / calculated) fields, and the
   pager's links. */
.seed-pager a { text-decoration: none; color: var(--accent); font-weight: 600; cursor: pointer; }
.seed-field-static { display: flex; flex-direction: column; font-size: .8rem; gap: .2rem; margin: .3rem 0; }
.seed-field-static .seed-field-label { color: var(--muted); }
.seed-field-static .seed-field-value { font-weight: 600; }
.seed-chart { margin: 1rem 0; max-width: 720px; }
.seed-chart-svg { width: 100%; height: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.seed-axis { stroke: var(--border); stroke-width: 1; }
.seed-bar { fill: var(--accent); }
.seed-line { stroke: var(--accent); stroke-width: 2; }
.seed-point { fill: var(--accent); }
.seed-tick, .seed-xlabel { fill: var(--muted); font-size: 10px; }
.seed-chart-title { fill: var(--text); font-size: 11px; font-weight: 600; }

/* Session countdown (session.js): the dialog, and the page behind it blurred. */
/* Everything but the dialog, whatever regions a theme's shell is made of. */
.seed-session-locked body > :not(dialog):not(script){filter:blur(6px);transition:filter .2s}
.seed-session-dialog{position:relative;max-width:26rem;padding:1.25rem 1.5rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);color:var(--text);box-shadow:var(--shadow)}
.seed-session-dialog::backdrop{background:var(--overlay)}
.seed-session-dialog h2{margin:0 0 .5rem;font-size:1.2rem}
.seed-session-dialog [data-session-count]{font-variant-numeric:tabular-nums;color:var(--accent)}
.seed-session-x{position:absolute;top:.5rem;right:.6rem;border:0;background:none;color:var(--muted);font-size:1rem;cursor:pointer}
.seed-session-actions{display:flex;gap:.75rem;align-items:center;justify-content:flex-end;margin-top:1rem}
.seed-session-continue{padding:.4rem 1rem;border:1px solid var(--accent);border-radius:var(--radius-sm);background:var(--accent);color:var(--accent-text);font-weight:600;cursor:pointer}
.seed-session-logout{color:var(--muted)}
/* A datagrid's ＋ (`add = {…}`), beside its search box — a toolbar button, in the theme's colours. */
.seed-grid-add{padding:.3rem .7rem;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text);cursor:pointer;font-size:1rem;line-height:1}
.seed-grid-add:hover{border-color:var(--accent);color:var(--accent)}
.seed-check{display:block;min-height:1.1em;margin:-.35rem 0 .5rem;font-size:.85rem;line-height:1.3}
.seed-check-ok{color:var(--success)}
.seed-check-taken{color:var(--error)}
button[type=submit]:disabled{opacity:.5;cursor:not-allowed}

/* ── The shell's regions, for a theme that lays its page out differently ─────
   copper uses the first three; a theme composes the rest in its own shell. */
.site-banner { background: var(--banner-bg) var(--banner-image, none) center / cover no-repeat;
  color: var(--banner-text); padding: var(--space-4) var(--space-3); }
.site-banner-inner { max-width: var(--content-width); margin: 0 auto; }
.site-banner h1 { margin: 0 0 var(--space-1); font-size: 2rem; }
.site-banner p { margin: 0; opacity: .9; }
.site-banner a { color: inherit; }
.site-body { max-width: var(--content-width); margin: 0 auto; }
.site-body--sidebar { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  gap: var(--space-3); padding: 0 var(--space-3); }
.site-body--sidebar .site-main { max-width: none; margin: 0; padding-left: 0; padding-right: 0; }
.site-side { padding: var(--space-3) 0; }
.site-side .seed-nav { flex-direction: column; }
.site-body--wide { max-width: none; }
.site-foot-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: var(--space-3); max-width: var(--content-width); margin: 0 auto; padding: var(--space-3); }
.site-foot-cols h4 { margin: 0 0 var(--space-1); }
.site-foot-cols ul { list-style: none; margin: 0; padding: 0; }
.site-foot-cols a { color: inherit; }
@media (max-width: 48rem) {
  .site-body--sidebar { grid-template-columns: 1fr; }
  .site-side .seed-nav { flex-direction: row; flex-wrap: wrap; }
}

/* ── Content layout a VIEW may compose, with fenced divs ─────────────────────
   `::: seed-cols` lays its children out in as many columns as fit;
   `seed-cols-2` / `seed-cols-3` fix the count (one column on a phone).
   `::: seed-banner` is a banner inside the page, `::: seed-media` a figure. */
.seed-cols { display: grid; gap: var(--space-3); margin: var(--space-3) 0;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); align-items: start; }
.seed-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.seed-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.seed-cols > * { min-width: 0; }
.seed-banner { background: var(--banner-bg); color: var(--banner-text); border-radius: var(--radius);
  padding: var(--space-3) var(--space-4); margin: var(--space-3) 0; }
.seed-banner h2, .seed-banner h3 { margin-top: 0; color: inherit; }
.seed-banner a { color: inherit; }
.seed-media { margin: var(--space-3) 0; }
.seed-media img { display: block; max-width: 100%; height: auto; border-radius: var(--radius);
  border: 1px solid var(--border); }
.seed-media p { margin: var(--space-1) 0 0; color: var(--muted); font-size: .9rem; }
@media (max-width: 48rem) {
  .seed-cols-2, .seed-cols-3 { grid-template-columns: 1fr; }
}

/* ── A side column folded to a strip of icons ────────────────────────────────
   A shell with `.site-body--sidebar` puts a `.site-side-toggle` button
   (data-toggle="side") in its `.site-side`; theme.js flips `data-side` on
   <html> and remembers it. Folded, the column is `--sidebar-collapsed` wide,
   shows each item's glyph (with its label as the tooltip), and the content
   takes the room. On a phone the column is a row above the page instead, and
   there is nothing to fold. */
.site-side-toggle { display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; margin-bottom: var(--space-2); padding: 0; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--muted); font: inherit; line-height: 1; }
.site-side-toggle:hover { color: var(--accent); border-color: var(--accent); }
.site-side-toggle::before { content: "«"; }
@media (min-width: 48.0625rem) {
  /* Flush to the window's left edge, as wide as the icons; the content takes
     everything else. */
  html[data-side="collapsed"] .site-body--sidebar {
    grid-template-columns: var(--sidebar-collapsed) minmax(0, 1fr);
    max-width: none; margin: 0; padding-left: 0; }
  html[data-side="collapsed"] .site-side-toggle::before { content: "»"; }
  html[data-side="collapsed"] .site-side { padding-left: 0; padding-right: 0; text-align: center;
    min-width: 0; }
  html[data-side="collapsed"] .site-side-toggle { width: calc(var(--sidebar-collapsed) - 2 * var(--space-1));
    margin-left: auto; margin-right: auto; }
  html[data-side="collapsed"] .site-side .seed-nav-label,
  html[data-side="collapsed"] .site-side .site-side-head { display: none; }
  html[data-side="collapsed"] .site-side .seed-nav-initial { display: inline; font-weight: 700; }
  html[data-side="collapsed"] .site-side .seed-nav a { justify-content: center;
    padding-left: 0; padding-right: 0; font-size: 1.15rem; }
}

/* ── Responsive ──────────────────────────────────────────────────────────────
   Every theme drawn on this base works on a phone without trying: the bar
   wraps and its nav scrolls sideways on a row of its own, tables scroll inside
   their own box, a datagrid's low-priority columns give way (`priority` in the
   view), forms and field grids go to one column, a dialog fills the screen,
   and on a touch screen everything you press is at least 44px. */
img, video { max-width: 100%; height: auto; }
.site-head { flex-wrap: wrap; }
.seed-datagrid { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* A box that scrolls one way clips the other: `overflow-x: auto` makes the grid
   clip VERTICALLY too, so a row's [⋯] menu on the last rows opened inside the
   grid and needed a scroll to reach. While one is open the grid clips nothing;
   it scrolls sideways again the moment the menu closes. */
.seed-datagrid:has(.seed-row-more[open]) { overflow: visible; }
.seed-toolbar, .seed-grid-toolbar, .seed-pager { flex-wrap: wrap; }
@media (max-width: 60rem) {
  .seed-datagrid .seed-p3 { display: none; }
}
@media (max-width: 40rem) {
  .seed-datagrid .seed-p2 { display: none; }
  .site-head { gap: var(--space-2); padding-left: var(--space-2); padding-right: var(--space-2); }
  .site-nav { order: 3; flex: 1 1 100%; overflow-x: auto; }
  .site-nav .seed-nav { flex-wrap: nowrap; }
  .site-main { padding-left: var(--space-2); padding-right: var(--space-2); }
  .site-foot { flex-direction: column; gap: var(--space-1); }
  .seed-form { max-width: none; }
  .seed-search { max-width: none; }
  .seed-fieldgrid { grid-template-columns: 1fr; gap: 0 var(--space-2); }
  .seed-field-label { margin-top: var(--space-2); }
  .seed-cell { flex-direction: column; gap: 0; }
  .seed-cell-label { min-width: 0; }
  .seed-column { flex-basis: 85vw; }
  #seed-modal:not(:empty) { padding: 0; align-items: stretch; }
  .seed-modal-box { width: 100%; max-height: none; min-height: 100%; border-radius: 0; border: 0; }
  #seed-toast { left: var(--space-2); right: var(--space-2); max-width: none; }
  .settings-menu { position: fixed; left: var(--space-2); right: var(--space-2); min-width: 0; }
  .site-foot-cols { grid-template-columns: 1fr; }
}
@media (pointer: coarse) {
  .seed-nav a, .site-link, .theme-toggle, .site-side-toggle, .tb-button, .tb-menu > summary,
  .tb-dropdown > summary, .seed-row-action, .seed-row-more > summary, .seed-page-prev,
  .seed-page-next, .settings-lang, .settings-skins button, .settings-item, .seed-grid-add,
  .seed-form button, .seed-form input, .seed-form select, .seed-search, .seed-col-chip {
    min-height: 44px; }
  .theme-toggle, .site-side-toggle, .seed-grid-add { min-width: 44px; }
}

/* A form field no person fills (S14, the `honeypot` field type): off-screen,
   not display:none — a form-filling bot skips what is not rendered. */
.seed-hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* The Darwin Core Archive designer (apiml, Q7): the kinds of record, the term
   tables, the check. */
.seed-dwc-cores { display: flex; gap: var(--space-2); flex-wrap: wrap; margin: var(--space-2) 0; }
.seed-dwc-core-selected { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }
.seed-dwc-table { width: 100%; border-collapse: collapse; margin: var(--space-2) 0; }
.seed-dwc-table th, .seed-dwc-table td { text-align: left; vertical-align: top; padding: var(--space-1) var(--space-2); border-bottom: 1px solid var(--border); }
.seed-dwc-table input { width: 100%; min-width: 12em; }
.seed-dwc-required td:first-child a { font-weight: 600; }
.seed-dwc-need, .seed-dwc-vocab, .seed-dwc-suggested, .seed-dwc-sample { color: var(--muted); font-size: 0.9em; }
.seed-dwc-class { margin: var(--space-1) 0; }
.seed-dwc-class > summary { cursor: pointer; }
.seed-dwc-row, .seed-dwc-meta { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-2); align-items: center; margin: var(--space-2) 0; }
.seed-dwc-row { grid-template-columns: max-content minmax(8em, 16em) max-content 6em max-content; }
.seed-dwc-check { list-style: none; padding: 0; }
.seed-dwc-check li { padding: var(--space-1) var(--space-2); border-left: 3px solid var(--border); margin: var(--space-1) 0; }
.seed-dwc-error { border-left-color: var(--error) !important; }
.seed-dwc-warning { border-left-color: var(--warning, var(--accent)) !important; }
.seed-dwc-ok { border-left-color: var(--success) !important; }
.seed-dwc-url { width: 100%; font-family: monospace; }
@media (max-width: 40em) { .seed-dwc-row { grid-template-columns: max-content 1fr; } }
