/**
 * xadmin.css — shared responsive stylesheet for the xapserver admin tools
 * (XEdit, PageEditor, FileCommander, system pages).
 *
 * Every rule is scoped under the .xa wrapper class so nothing leaks into
 * host-site pages that embed the tools. Sites may override the accent via
 * $STYLE['ADMIN_ACCENT'] in their conf (emitted by x_admin_assets() as an
 * inline --xa-accent override).
 */

.xa {
  --xa-accent: #3355aa;
  --xa-accent-text: #ffffff;
  --xa-bg: #f4f5f7;
  --xa-surface: #ffffff;
  --xa-border: #d4d7dd;
  --xa-text: #1c1e21;
  --xa-muted: #667085;
  --xa-danger: #b3261e;
  --xa-font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --xa-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --xa-radius: 6px;

  font-family: var(--xa-font);
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--xa-text);
  -webkit-text-size-adjust: 100%;
}

/* Undo legacy element rules (xtheme's TD/A pt fonts, host-site colors)
   inside .xa */
.xa table, .xa td, .xa th, .xa input, .xa select, .xa textarea, .xa button {
  font-family: var(--xa-font);
  font-size: inherit;
  color: var(--xa-text);
}
.xa p, .xa li, .xa i, .xa b { color: inherit; }
/* ANCHORS BELONG IN THE UNDO BLOCK AND WERE MISSING FROM IT UNTIL 2026-09-05.
   A site's bare `a { font: normal 12px <site font> }` -- the `font` shorthand,
   which sets family and SIZE together -- reached straight into the admin UI.
   The framework's own `.xa-menubar > a { font-weight: 600 }` is more specific
   and survived, so the links kept their weight and lost their size: measured on
   autoflow.net's real sheet, every nav link rendered at 12px in the site's font
   while the text beside it in the same bar was 15px in the framework's.

   That reads as a bar whose links have been "made bold" relative to their
   surroundings, and the root reported it that way. The bold was ours all along
   (:91); what the site changed was the SIZE. A shorthand is the easy way to do
   this by accident -- `font:` sets six properties, and a site author writing it
   is thinking about their own pages.

   font-size and font-family only. NOT colour: `.xa a` at :47 owns that, and a
   site changing link colour inside .xa should go through --xa-accent. */
.xa a { font-family: var(--xa-font); font-size: inherit; }
.xa h1, .xa h2, .xa h3 {
  font-family: var(--xa-font);
  line-height: 1.2;
  margin: 0 0 0.5em;
}
.xa h1 { font-size: 1.4rem; }
.xa h2 { font-size: 1.2rem; }
.xa h3 { font-size: 1.05rem; }
/* WEIGHT MARKS NAVIGATION, AND ONLY NAVIGATION -- root, 2026-09-05:
   "the bold works to differentiate navigation. I'd not use it for links in
   prose (inline) but I do think it works for the navigation elements."

     600      .xa-menubar > a (all three bars), .xa-context-orphan,
              .xa-field-cmd -- a command is an action you take
     inherit  THIS rule and everything under it: a link in a list cell, a
              mail_to/link_to value (.xa-field-link), a link in prose. These
              ARE the data; they happen to be clickable.

   Note there is no font-weight below. That was already true before the ruling,
   by omission -- measured: a list-row link renders 400 and a menubar link 600.
   It is written down now because an absence is not a decision, and "make all
   the links match" is a one-line edit somebody will otherwise make. */
.xa a { color: var(--xa-accent); text-decoration: none; }
.xa a:hover { text-decoration: underline; }
.xa img { border: 0; max-width: 100%; }

/* ---- Panels & chrome ---------------------------------------------------- */

.xa-panel {
  background: var(--xa-surface);
  border: 1px solid var(--xa-border);
  border-radius: var(--xa-radius);
  padding: 0.75rem;
  margin: 0 0 0.5rem;
}

.xa-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem 0.75rem;
  padding: 0.5rem 0.75rem;
}
.xa-toolbar .xa-current { color: var(--xa-text); }

/* Menu-style toolbars (XEdit tab/command bars): thin 1px dividers between
   items instead of literal pipe characters, with tighter spacing. */
/* EVERY item gets the same padding and there is no first-child exception --
   that exception was the lopsidedness. With it, the first link sat flush after
   the bar's 12px inset while every later link got a 21px gap, so the first item
   was spaced differently from all the others. The context bar's links never
   showed it because the record and its dash provide the lead-in.
   Balanced instead: the bar carries half the gap as its own inset, each item
   carries the other half, so edge and inter-item spacing agree. */
/* Specificity 0,2,0 deliberately, not source order: the responsive block near
   the end of this file re-declares `.xa-toolbar { gap: ... }`, and a menu bar
   carries BOTH classes. At equal specificity the later rule wins, so on narrow
   screens the toolbar gap came back and added ~10px between menu links -- while
   .xa-context-nav, which is not a toolbar, kept gap 0 and looked correct. That
   is why the two bars disagreed ONLY on mobile, and why every desktop
   measurement showed them identical. Measured on the root's phone, 2026-09-05:
   location bar textgap 30px, context nav 20px, same padding on every item. */
.xa-toolbar.xa-menubar, .xa-menubar { gap: 0; }
.xa-menubar > a {
  padding: 0 0.625rem;
  line-height: 1.2;
  font-weight: 600;
}
.xa-menubar > a + a { border-left: 1px solid var(--xa-border); }
/* The end items sit flush against the bar's own inset rather than adding their
   padding to it -- without this the first link starts 22px in (12 bar + 10
   item) which is a lot of dead space on a phone. Restored after being removed
   in the belief that it caused the lopsidedness; it did not, the responsive
   gap did. 12px at both edges, 21px between. */
.xa-menubar > a:first-child { padding-left: 0; }
.xa-menubar > a:last-child  { padding-right: 0; }

.xa-status {
  color: var(--xa-muted);
  padding: 0.375rem 0;
}

.xa-title h2 { margin: 0; }
.xa-subhead {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--xa-bg);
  border: 1px solid var(--xa-border);
  border-radius: var(--xa-radius);
  padding: 0.4rem 0.6rem;
  margin: 0.75rem 0 0.5rem;
}
.xa-subbody { padding: 0.25rem 0 0.75rem; }
.xa-subbody p { margin: 0.5rem 0; }
.xa-treerow { padding: 0.2rem 0; }
.xa-statusbar ul { margin: 0.25rem 0 0; padding-left: 1.25rem; }
.xa-statusbar li { margin: 0.125rem 0; color: var(--xa-danger); }

.xa-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  padding: 0.5rem 0.75rem;
  color: var(--xa-muted);
}

/* ---- Messages ----------------------------------------------------------- */

.xa-msg {
  padding: 0.5rem 0.75rem;
  border-radius: var(--xa-radius);
  margin: 0 0 0.75rem;
  background: color-mix(in srgb, var(--xa-accent) 12%, var(--xa-surface));
  border: 1px solid color-mix(in srgb, var(--xa-accent) 35%, var(--xa-border));
}
.xa-error { color: var(--xa-danger); }
.xa-note { color: var(--xa-muted); }

/* Legacy GenericInterface message classes, kept for compatibility */
.xa .giformmsg { color: var(--xa-accent); }
.xa .giformerror, .xa .xsaformerror { color: var(--xa-danger); }

/* ---- Data tables (list views) ------------------------------------------ */

.xa-table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--xa-border);
  border-radius: var(--xa-radius);
  background: var(--xa-surface);
  margin: 0 0 0.75rem;
}

.xa-list {
  border-collapse: collapse;
  width: 100%;
  min-width: 100%;
}
.xa-list th, .xa-list td {
  padding: 0.45rem 0.6rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--xa-border);
}
.xa-list .xa-nowrap { white-space: nowrap; }
/* A row carrying a per-row actions menu (the Page Editor site browser; XEdit
   reorderable lists) is a single-line, interactive row -- centre its cells so
   the name sits level with the 44px handle and the ⋯, rather than riding high
   against the top. Other .xa-list tables keep top-align for multi-line cells. */
.xa-list tbody tr:has(.xa-row-menu) td { vertical-align: middle; }
/* Neutralize legacy bgcolor attributes emitted by shared list helpers
   (GI_ListPager etc.) so CSS striping wins inside .xa-list tables. */
.xa-list td[bgcolor], .xa-list tr[bgcolor], .xa-list tr[bgcolor] > td { background-color: transparent; }
.xa-list th {
  background: var(--xa-bg);
  font-weight: normal;
  white-space: nowrap;
}
.xa-list thead th {
  cursor: pointer;              /* column-sort affordance */
  position: sticky;
  top: 0;
}
.xa-list .xa-list-title {
  background: var(--xa-bg);
  word-break: break-all;        /* long unbroken paths must not force table width */
}
.xa-list tbody tr:nth-child(even) { background: color-mix(in srgb, var(--xa-bg) 45%, var(--xa-surface)); }
/* Row hover is ROW-TRACKING, not an affordance -- rows are not clickable and
   never have been. This mixed --xa-accent, the colour every actual control in
   this sheet uses, so it read as "click me" and then did nothing. A neutral
   tint keeps the one thing it is genuinely for: following a row across a wide
   table. If rows ever DO become clickable, this is the line to change back. */
.xa-list tbody tr:hover { background: color-mix(in srgb, var(--xa-text) 6%, var(--xa-surface)); }

/* The click target is the CELL, not the word. A cell whose only content is a
   link makes the whole cell clickable -- which is most of what row click-through
   would have bought, without the JS it would have needed to respect nested
   links, middle-click, and text selection.
   :only-child is deliberate: a cell with more than one element is left alone,
   so nothing can stack into a column. */
.xa-list td > a:only-child { display: block; }
.xa-list tbody tr:last-child td { border-bottom: 0; }
.xa-list .xa-num { text-align: right; }

/* Drag-to-reorder, on a table that opts in with T_META 'reorder'. The form
   wraps the list and adds nothing to its box. The handle shows only once
   xedit-reorder.js has started (it adds .xa-reorder-js to the form), and
   touch-action: none on the HANDLE is what lets a finger drag it on a phone
   instead of scrolling -- the rest of the row still scrolls. The up/down
   buttons stay visible either way: they are the no-JavaScript path and the
   keyboard path. */
.xa-reorder { margin: 0; }
/* padding:0 so the 44px handle fills the existing row height instead of adding
   to it (the row is already ~45px from its other cells). */
.xa-list .xa-reorder-cell { width: 1%; white-space: nowrap; vertical-align: middle; padding: 0; }
/* The drag handle sits alone at the left; the `⋯` actions menu is a trailing
   cell at the right. */
.xa-list .xa-reorder-menu-cell { width: 1%; white-space: nowrap; vertical-align: middle; text-align: right; }
.xa-reorder-handle {
  display: none;
  padding: 0 0.45rem;
  color: var(--xa-muted);
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;   /* no long-press selection/callout on the grab */
}
/* A 40px compact touch baseline -- the bare glyph was ~25x21, too small to grab
   reliably on a phone. 40 (5x the 8pt grid) is the estate's one tap-target value
   across the ⋯ trigger, the menu items and this handle: Microsoft Fluent's touch
   size, IBM Carbon / Ant Design's "large" control height, above WCAG 2.2 §2.5.8
   (24) and just under Apple HIG (44) -- a hair tighter than HIG but grid-clean
   where 44 (5.5x8) is a half-step. inline-flex centres the glyph in the target. */
.xa-reorder-js .xa-reorder-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  min-height: 2.5rem;
  padding: 0;
}
.xa-reorder-handle:active { cursor: grabbing; }
/* iOS-style reorder: once the script is live, a reorderable row SLIDES to the
   slot it is displaced to; the grabbed row's transition is switched off in JS
   so it tracks the finger 1:1, and it lifts (raised, shadowed) above the rest.
   Only .xa-reorder-js rows animate, so a no-JavaScript list never transitions. */
.xa-reorder-js .xa-list tbody tr { transition: transform 0.18s ease; }
/* Must out-specify the slide rule above (JS also sets this inline, which wins
   regardless) or the grabbed row keeps the transition and chases the finger. */
/* While dragging, the real row is an invisible placeholder holding the gap, and
   a fixed <table.xa-reorder-overlay> clone follows the pointer. The overlay is
   OUTSIDE the table, so its z-index is honored on every browser (Safari does not
   honor z-index between transformed table rows) and it escapes the list's
   overflow:auto clip box -- the same reasons the ⋯ panel is lifted out. Its
   cells are opaque so nothing shows through as it passes over other rows. */
.xa-list tbody tr.xa-reorder-src { visibility: hidden; }
.xa-reorder-overlay {
  position: fixed;
  z-index: 1000;
  margin: 0;
  pointer-events: none;
  table-layout: fixed;
  /* .xa-list sets min-width:100%, which would stretch the overlay to the
     container and let table-layout:fixed widen the columns (the ⋯ drifts right).
     The overlay's width is pinned to the row's rect inline. */
  min-width: 0;
  background: var(--xa-surface);
  /* Appended FLAT (no scale, no shadow) so it exactly replaces the row with no
     pop; xedit-reorder.js adds .xa-lifted on the next frame to animate the lift,
     and settle() removes it to animate the drop back down. */
  transform: scale(1);
  transform-origin: center center;
  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
  transition: transform 0.16s ease, box-shadow 0.16s ease;
}
.xa-reorder-overlay.xa-lifted {
  transform: scale(1.02);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.24);
}
/* The clone's cell widths are frozen from the source cells' border-box rects, so
   the cells must be border-box too -- otherwise padding is added on top, the
   overlay grows wider than the row, and its cells (the ⋯ especially) sit shifted
   right of the rows beneath. */
.xa-reorder-overlay, .xa-reorder-overlay td { box-sizing: border-box; }
.xa-reorder-overlay td { background: var(--xa-surface); }
/* The clone is the only row in its tbody, so `.xa-list tbody tr:last-child td`
   (0,2,3) would strip its bottom hairline -- out-specify it (0,3,3) to keep the
   lifted row looking like a mid-list row. */
.xa-list.xa-reorder-overlay tbody tr:last-child td { border-bottom: 1px solid var(--xa-border); }

/* Per-row actions menu -- a native <details>, so it opens with no JavaScript and
   is keyboard-reachable; xa-row-menu.js adds close-on-outside-click and keeps
   one open at a time. Shared by XEdit lists and the Page Editor site browser:
   the row's actions live here (Navigation vs Mutation groups) instead of a
   cluttered strip of buttons or a bottom bar keyed off a radio. */
.xa-row-menu { position: relative; display: inline-block; }
.xa-row-menu > summary {
  list-style: none;
  cursor: pointer;
  /* A 40px tap target -- the estate's one compact touch baseline, matching the
     drag handle and the menu items. inline-flex centres the glyph as the box
     grows past its line height. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  min-height: 2.5rem;
  padding: 0 0.55rem;
  line-height: 1.2;
  text-align: center;
  color: var(--xa-muted);
  user-select: none;
  -webkit-user-select: none;
}
.xa-row-menu > summary::-webkit-details-marker { display: none; }
.xa-row-menu > summary::marker { content: ""; }
.xa-row-menu[open] > summary { color: var(--xa-text); }
/* position: absolute is the no-JS fallback; xa-row-menu.js re-pins it fixed at
   the trigger so the list's overflow-x:auto box cannot clip it. */
.xa-row-menu-pop {
  position: absolute;
  right: 0;
  z-index: 5;
  min-width: 11rem;
  max-width: calc(100vw - 8px);
  padding: 0.25rem 0;
  background: var(--xa-surface);
  border: 1px solid var(--xa-border);
  border-radius: var(--xa-radius);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  text-align: left;
  white-space: nowrap;
}
.xa-row-menu-group + .xa-row-menu-group { border-top: 1px solid var(--xa-border); margin-top: 0.15rem; padding-top: 0.15rem; }
.xa-row-menu-label {
  display: block;
  padding: 0.1rem 0.75rem;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--xa-muted);
}
/* ONE visual token for a menu item, whatever fires it. An item is an <a>
   (navigation) or a <button type=submit> (a form action) purely by mechanism;
   the eye must not be able to tell. So reset every element-specific default an
   <a> and a <button> disagree on -- the native button chrome (appearance) above
   all, which on iOS/Safari otherwise renders the form actions as rounded system
   buttons next to flat links -- and pin the shared box: full width, left, flat,
   inherited type, one padding, one line-height. The only DELIBERATE difference
   is danger (destructive), which is about CONSEQUENCE, not mechanism. */
/* Scoped under .xa-row-menu-pop (0,2,0) so it OUT-SPECIFIES the framework's
   `.xa button` and `.xa a` (both 0,1,1) -- otherwise a button keeps its native
   padding/border/radius/background and a link keeps its accent colour, and the
   two items look nothing alike. */
.xa-row-menu-pop .xa-row-menu-item {
  appearance: none;
  -webkit-appearance: none;
  /* A 40px tap target (the estate's compact touch baseline, matching the drag
     handle and the ⋯ trigger); flex keeps the label vertically centred as the
     item grows past the text's own line box. */
  display: flex;
  align-items: center;
  min-height: 2.5rem;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 0 0.75rem;
  border: 0;
  border-radius: 0;
  background: none;
  font: inherit;
  line-height: 1.4;
  color: var(--xa-text);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.xa-row-menu-pop .xa-row-menu-item:hover,
.xa-row-menu-pop .xa-row-menu-item:focus { background: rgba(127, 127, 127, 0.18); outline: none; }
.xa-row-menu-pop .xa-row-menu-item-danger { color: var(--xa-danger); }
.xa-section-header td {
  background: var(--xa-bg);
}

/* ---- Forms -------------------------------------------------------------- */

.xa-form {
  display: grid;
  grid-template-columns: minmax(9em, 20%) 1fr;
  gap: 0.5rem 0.75rem;
  align-items: start;
}
.xa-form .xa-label {
  text-align: right;
  padding-top: 0.35rem;
  color: var(--xa-muted);
}
.xa-form .xa-value { min-width: 0; }
.xa-form .xa-span { grid-column: 1 / -1; }
.xa-required { color: var(--xa-danger); }

.xa-input,
.xa input[type="text"], .xa input[type="password"], .xa input[type="email"],
.xa input[type="date"], .xa input[type="datetime-local"], .xa input[type="time"],
.xa input[type="file"], .xa select, .xa textarea {
  font: inherit;
  color: inherit;
  max-width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--xa-border);
  border-radius: var(--xa-radius);
  background: var(--xa-surface);
  padding: 0.35rem 0.5rem;
}
.xa textarea { width: 100%; resize: vertical; }
/* Read-only value shown as a disabled-looking field so it aligns with the
   editable inputs (same box metrics, muted, non-interactive). */
.xa-readonly {
  display: block;
  width: 100%;
  min-height: calc(1.4em + 0.7rem + 2px);
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--xa-border);
  border-radius: var(--xa-radius);
  background: var(--xa-bg);
  color: var(--xa-text);
  box-sizing: border-box;
}
.xa-readonly.xa-readonly-empty { color: var(--xa-muted); font-style: italic; }
.xa-readonly code { font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.xa input:focus, .xa select:focus, .xa textarea:focus {
  outline: 2px solid color-mix(in srgb, var(--xa-accent) 55%, transparent);
  outline-offset: 0;
  border-color: var(--xa-accent);
}
.xa input[type="checkbox"], .xa input[type="radio"] {
  accent-color: var(--xa-accent);
  width: 1.05rem;
  height: 1.05rem;
  vertical-align: middle;
}

/* ---- Buttons ------------------------------------------------------------ */

.xa-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.75rem 0 0.25rem;
}
.xa a.xa-btn { display: inline-block; color: var(--xa-text); }
.xa a.xa-btn:hover { text-decoration: none; }
.xa-btn,
.xa input[type="submit"], .xa input[type="button"], .xa input[type="reset"], .xa button {
  -webkit-appearance: none;
  appearance: none;
  font: inherit;
  cursor: pointer;
  border: 1px solid var(--xa-border);
  border-radius: var(--xa-radius);
  background: var(--xa-bg);
  color: var(--xa-text);
  padding: 0.4rem 0.9rem;
}
.xa-btn:hover,
.xa input[type="submit"]:hover, .xa input[type="button"]:hover, .xa input[type="reset"]:hover, .xa button:hover {
  background: color-mix(in srgb, var(--xa-accent) 12%, var(--xa-bg));
  border-color: var(--xa-accent);
}
.xa .xa-btn-primary {
  background: var(--xa-accent);
  border-color: var(--xa-accent);
  color: var(--xa-accent-text);
}
.xa .xa-btn-primary:hover { background: color-mix(in srgb, #000 15%, var(--xa-accent)); }
.xa .xa-btn-danger {
  color: var(--xa-danger);
  border-color: color-mix(in srgb, var(--xa-danger) 50%, var(--xa-border));
}
.xa .xa-btn-danger:hover {
  background: color-mix(in srgb, var(--xa-danger) 10%, var(--xa-surface));
  border-color: var(--xa-danger);
}

/* iOS Safari renders no calendar/clock glyph on date-time inputs (the whole
   field opens the system picker on tap) -- add one as a visual affordance.
   The @supports guard matches only iOS/iPadOS Safari, so Chrome and desktop
   browsers keep their own native indicator untouched. */
@supports (-webkit-touch-callout: none) {
  .xa input[type="date"], .xa input[type="datetime-local"], .xa input[type="time"] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M16 3v4M8 3v4M3 11h18'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.5rem center;
    background-size: 1rem 1rem;
    padding-right: 2rem;
    min-height: 2.2rem;
    -webkit-appearance: none;
    appearance: none;
  }
}

/* ---- Small screens ------------------------------------------------------ */

@media (max-width: 640px) {
  /* Columns/elements marked low-priority are dropped on phones.
     Mark BOTH the th and its tds with .xa-hide-sm. */
  .xa .xa-hide-sm { display: none; }
  .xa-form { grid-template-columns: 1fr; gap: 0.125rem 0; }
  .xa-form .xa-label { text-align: left; padding-top: 0.5rem; }
  .xa-toolbar { gap: 0.25rem 0.6rem; }
  /* 16px floor prevents iOS auto-zoom on focus */
  .xa input[type="text"], .xa input[type="password"], .xa input[type="email"],
  .xa select, .xa textarea { font-size: 16px; width: 100%; }
  .xa input[type="date"], .xa input[type="datetime-local"], .xa input[type="time"] { font-size: 16px; }
}

/* ---- Print -------------------------------------------------------------- */

@media print {
  .xa-actions, .xa-toolbar, .xa-breadcrumb, .xa-pager { display: none !important; }
  .xa-table-scroll { overflow: visible; border: 0; }
  .xa-list th, .xa-list td { border: 1px solid #999; }
  .xa-list thead th { position: static; cursor: default; }
  .xa { color: #000; }
}

/* ── XEdit bar vocabulary ──────────────────────────────────────────────────
   Three bars used to emit the identical class string, so neither a stylesheet
   nor a test could tell them apart. Each now carries a distinct name ALONGSIDE
   its existing classes -- these hooks add no properties, so nothing restyles.
   Names match doc/xedit-anatomy.md and the methods that emit them.

     .xa-locationbar    top-level tables      XEdit::location_bar()
     .xa-contextbar  the selected record   XEdit::context_bar()
     .xa-commandbar  New / Search / View   XEdit::command_bar()
*/
.xa-locationbar, .xa-contextbar, .xa-commandbar { /* structural hooks only */ }

/* ── The context bar's two halves ──────────────────────────────────────────
   The record you are inside, and the navigation into its subtables. They are
   separate elements so the stylesheet can separate them; ROW VS COLUMN IS THE
   ONE PROPERTY BELOW, so trying the side-by-side variant costs a single edit
   (`flex-direction: row` + `align-items: center`).

   .xa-context-nav carries .xa-menubar as well, so the subtable links get the
   SAME 1px dividers as the location bar's -- one idiom for two link sets that
   are the same kind of thing: a fixed set of peers with one current. */
.xa-contextbar {
  flex-direction: row;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.3rem 0.6rem;
}
.xa-context-record { line-height: 1.2; }
/* The record you are ON is named rather than linked -- you cannot navigate to
   where you already are.

   ROOT'S RULING 2026-09-05, after four variants rendered side by side in both
   navigation states: "Let's stick w/ A, it's the most natural, w/ user-provided
   text not bolded, and nothing shifting due to state transitions."

   ⭐ THE RULE IS ABOUT PROVENANCE, NOT CLICKABILITY, and that is sharper than
   what this file said before. WEIGHT MARKS FRAMEWORK CHROME; USER-PROVIDED
   TEXT IS NEVER BOLD, wherever it appears and whether or not it is a link.

     bold 600   nav links in all three bars, .xa-context-orphan, .xa-field-cmd
                -- all of them words the FRAMEWORK chose
     inherit    the record name, a list-row link, a mail_to/link_to value --
                all of them the USER's content, which happens to be clickable

   That resolves a conflict the clickable-based reading could not. The record
   name IS a link once you are inside a subtable, so "bold marks clickable"
   demanded bold there and not on the record page -- and MEASURED, that costs
   5.5px of movement in everything after it as you navigate between the two
   (137.6px vs 143.1px on an 18-character name). Provenance does not change
   with navigation state, so a rule keyed on it cannot shift. It also explains
   the list-row link, which was already unbolded and had no stated reason.

   ⚠️ AND IT CORRECTS THE OLD RATIONALE THIS COMMENT USED TO CARRY. "Bold
   changes glyph widths, so the name shifted" was written as though it
   condemned bold generally. It does not: bolding the name in BOTH states was
   measured at 0.0px shift. What the old note actually ruled out was bold that
   DEPENDS ON STATE. The right reason for A is the one above.

   Colour still marks clickability, independently: --xa-accent for links,
   --xa-text for the record name, --xa-muted for the "Song:" prefix. Size is
   the framework's in all cases -- see :55, which stops a site's bare `a` rule
   resizing the bars. */

/* The dash between the record and its subtable links. A SEPARATOR, so it is
   CSS rather than markup: it carries no meaning to read aloud, and putting it
   in the emitted text would push a presentational character through hsc() and
   into the harness's content assertions.

   An EN dash, U+2013. All three were compared live on staging via a ?dash=
   toggle on the demo page -- em, en, hyphen -- and this is the one that reads
   as a separator without the width of an em dash.
   The sibling combinator is load-bearing -- without a record in front of it
   (a `record` context shows subtable links alone) there is nothing to separate
   FROM, and the bar would open with a stray dash. */
/* The label prefix -- "Song:" in "Song: Party Spy". It was a bare text node
   until 2026-09-05, so a site could not tell it from the record name; both
   simply inherited. Muted by default because the prefix says WHICH KIND of
   record and the name says WHICH ONE, and the second is the one you are
   looking for. A site that wants them identical sets one colour. */
.xa-context-label { color: var(--xa-muted); }
.xa-context-record .xa-current { color: var(--xa-text); font-weight: inherit; }

.xa-context-record + .xa-context-nav::before {
  content: "\2013";
  color: var(--xa-muted);
  margin-right: 0.6rem;
}
.xa-context-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}
/* The orphan anchor is not a link, but it is still a member of the set, so it
   takes the same spacing and divider treatment its siblings would. */
.xa-menubar > .xa-context-orphan { line-height: 1.2; font-weight: 600; }


/* ---------------------------------------------------------------------------
   FIELD-LEVEL DEFAULTS -- elements XEdit emits with no class before 2026-09-05.

   These are the two places where "the framework has no rule" meant "the
   browser's default stylesheet decides how a framework-emitted element
   lays out". Neither was reachable by a site: an audit of .xa-* selectors
   showed 30 of 32 emitted classes styled, and could not see these at all,
   because the elements carried no class to audit.
   --------------------------------------------------------------------------- */

/* x_type => 'pretext', the read-only pre-formatted field (a chart, a log, a
   fixed-width block). The browser default is `margin: 1em 0`, which pushed the
   content 15px BELOW the top of its own value cell while the label sat at the
   top -- measured in headless Chrome: label top 292, cell top 292, pre top 307.
   That gap is the whole of the reported "misalignment"; nothing else moved.

   Margin goes to zero so the block starts where its cell starts. Wrapping is
   allowed because a chart line is often wider than the cell and the
   alternative is a horizontal scrollbar inside a form row. */
.xa-pre {
  margin: 0;
  font-family: var(--xa-mono);
  font-size: 0.9375em;
  line-height: 1.35;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* print_cmd / link_cmd: the per-field command links ("Chart", "Print"). They
   were unclassed anchors glued on with &nbsp;&nbsp;, so a site could reach them
   only through `.xa-value a` -- which also catches every other link in a field
   -- and their spacing was a text entity rather than a rule.

   WHAT THIS DOES NOT CLAIM TO FIX: vertical alignment. A first reading of the
   probe called the anchor "8px lower than the input" from tops of 250 and 258.
   That comparison is meaningless between boxes of different heights: input
   250+34 and anchor 258+18 have the SAME centre, 267. It was aligned all
   along, and a `vertical-align: middle` added on the strength of that reading
   moved the centre to 268.5 -- a fix making it marginally worse. Baseline is
   the default and it is correct; nothing here overrides it.

   The weight matches the nav links because a command IS a navigation
   affordance; the spacing is a margin so a site can change it. */
/* The value cell is a wrapping flex row so a trailing command has a DEFINED
   place to go when it does not fit.

   THE COMMON CASE IS FRAMEWORK-ON-FRAMEWORK, and no site is involved. A
   link_cmd on a `blob` column is emitted after a TEXTAREA (XEdit routes blob
   to form_input_textarea), and `.xa textarea` at :240 of this file sets
   `width: 100%` UNCONDITIONALLY. The field fills the cell, so the framework's
   own command has nowhere to sit but the next line. Measured with NO site CSS
   at all: textarea (345, 250) 1234px wide, command (345, 521).

   ⚠️ AN EARLIER VERSION OF THIS COMMENT BLAMED A SITE RULE -- "`.xa-value
   input { width: 100% }`, which is what autoflow.net uses". They use no such
   rule: `.xa-value` occurs ZERO times in their repo, and this sheet's own
   input-width rule is at :338, inside `@media (max-width: 640px)`, so it was
   not applying at the 1600px the measurement was taken at. The reproduction
   had been built by INJECTING that rule, which made the attribution circular.
   Autoflow found it and the correction is theirs.

   The rule below is unchanged by that, because it was measured on the effect
   rather than the cause: the wrapped command lands flush at 345 instead of
   indented 12px by its own margin.

   SCOPED WITH :has() DELIBERATELY. The unscoped `.xa-value { display: flex }`
   was tried first and measured: it shrank the pretext <pre> from 1234px to
   245px, because a flex item sizes to its content. That is an element the rule
   was not aimed at, in every form in the estate, to fix a 12px indent on one.
   Scoped, the cells without a command stay `display: block` -- verified, the
   <pre> reads 1234 again.

   Where :has() is unsupported (Safari below 15.4) the rule simply does not
   apply and the layout is what it was before this release. A degradation to
   the status quo, not a break. */
.xa-value:has(.xa-field-cmd) {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.75rem;
}
.xa-field-cmd { font-weight: 600; }

/* A VALUE rendered as a link -- mail_to, link_to, and a file link in a list
   cell. Distinct from .xa-field-cmd on purpose: a command is an action you
   take, a field link IS the data, so it stays at the weight of the text around
   it and only takes the link colour. Both were unclassed anchors until
   2026-09-05, reachable from a site only as `.xa-value a`, which catches the
   other kind too -- which is precisely why they need separate names. */
.xa-field-link { font-weight: inherit; }
/* The divider between two commands, replacing the literal "|" XEdit used to
   emit. SAME rule shape as .xa-menubar > a + a -- one divider idiom in this
   stylesheet, not two, for the same reason the context bar reuses .xa-menubar:
   two inventions for one job is how a sheet stops being learnable.

   ⚠️ BUT THE GEOMETRY UNDERNEATH IS DIFFERENT, and that difference cost the
   symmetry until 2026-09-15 (Autoflow measured it on a real band_db form, a
   root request). The menubar sits in a `gap: 0` flow where each `> a` carries
   its own left/right padding, so the border falls between two PADDED boxes:
   10 + 1 + 10, symmetric. This row is a FLEX with `column-gap: 0.75rem` and no
   item padding -- and a flex gap falls on only ONE side of a border box. So
   the 12px landed entirely LEFT of the rule and 0 right of it. The padding-left
   restores the right side to match the gap on the left: 12 / rule / 12. Keep it
   equal to the column-gap above, or the asymmetry returns. The old
   `:first-of-type { padding-left: 0 }` reset was a no-op (nothing set
   padding-left on a lone .xa-field-cmd) and is dropped -- the padding now lives
   only on the second-and-later command, which is exactly where the rule is. */
.xa-field-cmd + .xa-field-cmd { border-left: 1px solid var(--xa-border); padding-left: 0.75rem; }
