/* Universal Core — one shared, plain stylesheet. No build step, no
   framework: this kernel renders server-side HTML/HTMX (CLAUDE.md), so
   the styling story stays exactly as dependency-light as the markup
   itself. Deliberately minimal — enough to make the app usable and
   legible, not a design system. */

:root {
  --uc-border: #d8dee4;
  --uc-bg: #f6f8fa;
  --uc-text: #1f2328;
  --uc-muted: #57606a;
  --uc-accent: #0969da;
  --uc-accent-bg: #0969da;
  --uc-nav-bg: #24292f;
  --uc-nav-text: #ffffff;
  --uc-highlight: #e6f4ea;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  color: var(--uc-text);
  background: var(--uc-bg);
  line-height: 1.5;
}

h1, h2, h3 {
  font-weight: 600;
  line-height: 1.25;
}

a {
  color: var(--uc-accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* Top nav — the module switcher every page shares (see nav.go). */
.uc-nav {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 0.75rem 1.5rem;
  background: var(--uc-nav-bg);
  flex-wrap: wrap;
}

.uc-nav-brand {
  color: var(--uc-nav-text);
  font-weight: 700;
  font-size: 1.05rem;
  margin-inline-end: 0.5rem;
}

.uc-nav-brand:hover {
  text-decoration: none;
  opacity: 0.85;
}

.uc-nav-link {
  color: var(--uc-nav-text);
  opacity: 0.85;
  font-size: 0.92rem;
}

.uc-nav-link:hover {
  opacity: 1;
  text-decoration: none;
}

/* Pushes the language switcher to the far end of the nav — the far
   *end*, not "right": in an RTL document (dir="rtl", see layout.go's
   shellTmpl) flex's main-axis direction itself flips, so this lands at
   the visual left with no extra rule needed. */
.uc-nav-spacer {
  flex: 1;
}

/* Tenant switcher (#25) — a native <details> dropdown so it needs no
   script; only rendered when the session can access >1 tenant. */
.uc-nav-tenant {
  position: relative;
  color: var(--uc-nav-text);
  font-size: 0.85rem;
}

.uc-nav-tenant > summary::-webkit-details-marker {
  /* Safari ignores list-style:none on summary; this is its own opt-out. */
  display: none;
}

.uc-nav-tenant > summary {
  cursor: pointer;
  list-style: none;
  opacity: 0.85;
  padding: 0.15rem 0.5rem;
  border: 1px solid color-mix(in srgb, var(--uc-nav-text) 35%, transparent);
  border-radius: 4px;
}

.uc-nav-tenant[open] > summary,
.uc-nav-tenant > summary:hover {
  opacity: 1;
}

.uc-nav-tenant-menu {
  position: absolute;
  inset-inline-end: 0;
  top: 100%;
  z-index: 30;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.uc-nav-tenant-form {
  margin: 0;
}

.uc-nav-tenant-form button {
  display: block;
  width: max-content;
  min-width: 100%;
  background: var(--uc-surface, #fff);
  color: var(--uc-text, #1a1a1a);
  border: 1px solid #d0d0d0;
  padding: 0.4rem 0.8rem;
  cursor: pointer;
}

.uc-nav-tenant-form button:hover {
  background: #f0f0f0;
}

.uc-nav-lang {
  color: var(--uc-nav-text);
  opacity: 0.6;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.uc-nav-lang:hover {
  opacity: 0.9;
  text-decoration: none;
}

.uc-nav-lang-active {
  opacity: 1;
  font-weight: 700;
  text-decoration: underline;
}

.uc-container {
  max-width: 72rem;
  margin: 0 auto;
  padding: 2rem 1.5rem;
}

/* Dashboard hub-and-spoke module switcher (internal/api/dashboard.go's
   hubLayout computes node positions server-side; sizes here must match
   hubNodeSizePx/hubCenterSizePx in that file). */
.uc-hub-wrap {
  overflow-x: auto;
  margin-top: 1.5rem;
}

.uc-hub {
  position: relative;
  margin: 0 auto;
}

.uc-hub-lines {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
}

.uc-hub-lines line {
  stroke: var(--uc-border);
  stroke-width: 2;
}

.uc-hub-center {
  position: absolute;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0.5rem;
  background: var(--uc-nav-bg);
  color: #fff;
  font-weight: 700;
  font-size: 1.15rem;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
  z-index: 2;
}

.uc-hub-node {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 140px;
  height: 140px;
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  text-align: center;
  padding: 0.6rem;
  color: #fff;
  font-weight: 600;
  font-size: 0.85rem;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  z-index: 1;
  transition: transform 0.12s ease;
}

.uc-hub-node-icon {
  font-size: 1.9rem;
  line-height: 1;
}

/* An entity-hub node's technical code sub-label (modulemenu.go) — the
   module-switcher hub's own nodes never set Code, so this simply never
   renders there. */
.uc-hub-node-code {
  display: block;
  font-size: 0.7rem;
  font-weight: 500;
  opacity: 0.85;
}

a.uc-hub-node:hover {
  transform: translate(-50%, -50%) scale(1.06);
  text-decoration: none;
}

.uc-hub-node-0 { background: #e8590c; }
.uc-hub-node-1 { background: #d6336c; }
.uc-hub-node-2 { background: #ae3ec9; }
.uc-hub-node-3 { background: #7048e8; }
.uc-hub-node-4 { background: #3b5bdb; }
.uc-hub-node-5 { background: #1098ad; }
.uc-hub-node-6 { background: #0ca678; }
.uc-hub-node-7 { background: #66a80f; }
.uc-hub-node-8 { background: #f08c00; }
.uc-hub-node-9 { background: #e8590c; }

/* Non-clickable "coming soon" placeholder nodes (see dashboard.go's
   plannedModuleKeys) — deliberately muted/dashed, distinct from the
   vivid real-module colors above, so it reads as "not available yet"
   at a glance, not as a broken/uncolored real module. */
.uc-hub-node-placeholder {
  background: #fff;
  color: var(--uc-muted);
  border: 2px dashed var(--uc-border);
  box-shadow: none;
  cursor: default;
}

.uc-hub-node-badge {
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--uc-muted);
  background: var(--uc-bg);
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
}

/* A module's own searchable menu (internal/api/modulemenu.go) */
.uc-menu-search {
  width: 100%;
  max-width: 24rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--uc-border);
  border-radius: 4px;
  font-size: 0.95rem;
  margin: 0.75rem 0 1.25rem;
}

.uc-menu-item-code {
  color: var(--uc-muted);
  font-weight: 400;
  font-size: 0.8rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* A module menu's own report link(s), e.g. Purchasing's "Reports"
   (internal/api/modulemenu.go's moduleReportLinks). */
.uc-module-reports {
  margin: -0.5rem 0 1rem;
}

.uc-module-reports a {
  font-weight: 600;
}

/* The mgmt reporting workbench (internal/api/reporting.go) — a row of
   at-a-glance stat cards above each report's tables. */
.uc-report-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 1rem 0 1.5rem;
}

.uc-report-card {
  background: #fff;
  border: 1px solid var(--uc-border);
  border-radius: 6px;
  padding: 0.85rem 1.1rem;
  min-width: 9rem;
}

.uc-report-card-label {
  color: var(--uc-muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin-bottom: 0.25rem;
}

.uc-report-card-value {
  font-size: 1.4rem;
  font-weight: 700;
}

.uc-report-card-sub {
  color: var(--uc-muted);
  font-size: 0.85rem;
  margin-top: 0.15rem;
}

/* Record list tables */
.uc-list-toolbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

table.uc-table {
  width: 100%;
  border-collapse: collapse;
  background: #fff;
  border: 1px solid var(--uc-border);
  border-radius: 6px;
  overflow: hidden;
}

table.uc-table th,
table.uc-table td {
  text-align: start;
  padding: 0.55rem 0.85rem;
  border-bottom: 1px solid var(--uc-border);
  font-size: 0.92rem;
}

table.uc-table th {
  background: var(--uc-bg);
  color: var(--uc-muted);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

table.uc-table tbody tr:hover {
  background: var(--uc-bg);
}

/* uc-rfq-vendor-col: the RFQ comparison report (rfq_report.go) puts real
   Party names in column <th> cells, unlike every other uc-table header
   (fixed labels like "Item"/"Quantity"). table.uc-table th's blanket
   text-transform: uppercase is fine for a fixed label but visually
   defaces a real vendor's name (a proper noun, possibly a registered
   brand) — this opts those specific header cells back out, same
   font-weight/size/color as any other header, just not re-cased. */
table.uc-table th.uc-rfq-vendor-col {
  text-transform: none;
}

table.uc-table tbody tr:last-child td {
  border-bottom: none;
}

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

/* related_list (uc-infra#103): unlike master_detail, which gets column
   alignment for free from the browser's native <table> layout, this is
   div/span markup (deliberately not a table — see the section's own
   comment in formrender/render.go) with no ancestor to lay its cells out
   for it. Without this, .uc-related-header-cell/.uc-related-cell stay
   `display: inline` and run together into one unbroken string that
   doesn't align with the row below it. flex (not grid) needs no column
   count threaded through from Go: every header cell and every row's
   cells share the same flex-basis, so column N of the header and column
   N of every row land at the same x position regardless of how many
   columns a given child Definition declares. */
.uc-related-header,
.uc-related-row {
  display: flex;
  gap: 0.5rem 1rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--uc-border);
}

.uc-related-row:last-child {
  border-bottom: none;
}

.uc-related-header-cell,
.uc-related-cell {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* No text-transform here, unlike table.uc-table th: this section's
   sibling component, master_detail's <th>, gets no custom CSS at all
   (native browser table styling only, no case change), and matching
   that -- not the unrelated list-page table -- keeps a translated
   label's real casing on screen instead of forcing e.g. Turkish
   "İ"/"i" through an uppercase transform. */
.uc-related-header-cell {
  color: var(--uc-muted);
  font-weight: 600;
  font-size: 0.8rem;
}

/* The RFQ vendor-comparison report's cheapest-price marking (#9) — a
   real computed style (background + bold weight), not just a CSS class
   name in the markup, so a browser test can assert against something
   the eye actually perceives, not a string match on a class attribute. */
.uc-rfq-lowest {
  background: var(--uc-highlight);
  font-weight: 700;
}

/* The project budget report's "some logged hours could not be priced"
   note (uc-infra#187) — a real computed style (muted, italic), not just
   a class name in the markup, so the note reads as a caveat attached to
   the row rather than blending into the plain category label next to
   it. Same "assert a real computed style, not just a class attribute"
   reasoning .uc-rfq-lowest's own comment gives. */
.uc-project-budget-unpriced {
  color: var(--uc-muted);
  font-style: italic;
  font-weight: 400;
}

/* The rendered 403 (see denied.go). Styled as a real page rather than
   left as unstyled default markup: a permission refusal is one of the
   few pages a user hits without meaning to, so it has to read as part of
   this app rather than as something broken. */
.uc-denied {
  max-width: 34rem;
  margin: 3rem auto;
  padding: 2rem;
  background: #ffffff;
  border: 1px solid var(--uc-border);
  border-radius: 6px;
  text-align: center;
}

.uc-denied h1 {
  margin-top: 0;
  font-size: 1.25rem;
}

.uc-denied p {
  color: var(--uc-muted);
  margin-bottom: 0;
}

.uc-list-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 1rem;
  color: var(--uc-muted);
}

.uc-list-pager a {
  font-weight: 600;
}

/* Forms (formrender) */
form.uc-form {
  background: #fff;
  border: 1px solid var(--uc-border);
  border-radius: 6px;
  padding: 1.5rem;
  max-width: 48rem;
}

.uc-form label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--uc-muted);
  margin-bottom: 0.3rem;
}

.uc-form input,
.uc-form select,
.uc-form textarea {
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--uc-border);
  border-radius: 4px;
  font-size: 0.95rem;
  margin-bottom: 1rem;
  font-family: inherit;
}

.uc-form button,
.uc-container button,
button.uc-btn {
  background: var(--uc-accent-bg);
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 0.5rem 1rem;
  font-size: 0.92rem;
  cursor: pointer;
}

.uc-form button:hover,
.uc-container button:hover,
button.uc-btn:hover {
  opacity: 0.9;
}

/* Global htmx-error toast (see layout.go's shellTmpl doc comment) —
   fixed top-right, hidden until .uc-toast-visible is added, so a failed
   htmx request (a validation 400, a version-conflict 409, a network
   failure) is always visibly reported somewhere on screen instead of
   the click just appearing to do nothing. */
.uc-toast {
  position: fixed;
  top: 1rem;
  inset-inline-end: 1rem;
  max-width: 24rem;
  background: #b42318;
  color: #fff;
  padding: 0.75rem 1rem;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  font-size: 0.92rem;
  z-index: 1000;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.5rem);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}

.uc-toast-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* A pending approval the viewer cannot action (workflow inbox). Rendered
   in place of the Approve button rather than hiding the row: the job is
   still information they may need — it is why their document is sitting
   there — so it greys the action out instead of concealing the work. */
.uc-inbox-blocked {
  color: var(--uc-muted);
  font-style: italic;
  font-size: 0.9em;
}

/* List-page filter box and sortable headers (R14). */
.uc-list-filter { display: flex; gap: 0.5rem; align-items: center; margin: 0 0 1rem; flex-wrap: wrap; }
.uc-list-filter input[type="search"] {
  padding: 0.4rem 0.6rem; border: 1px solid var(--uc-border); border-radius: 4px;
  font-size: 0.9rem; min-width: 14rem;
}
th a.uc-sort { color: inherit; text-decoration: none; display: inline-block; }
th a.uc-sort:hover { text-decoration: underline; }

/* Searchable reference-field combobox (#24). */
.uc-ref { position: relative; }
.uc-ref-search {
  width: 100%; padding: 0.4rem 0.6rem; border: 1px solid var(--uc-border);
  border-radius: 4px; font-size: 0.95rem;
}
.uc-ref-results {
  position: absolute; z-index: 5; left: 0; right: 0; top: 100%;
  background: #fff; border: 1px solid var(--uc-border); border-top: none;
  border-radius: 0 0 4px 4px; max-height: 14rem; overflow-y: auto;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.uc-ref-option { padding: 0.4rem 0.6rem; cursor: pointer; font-size: 0.9rem; }
.uc-ref-option:hover { background: var(--uc-bg); }

/* Inline reference-picker quick-create (part 2 of #24): the "+ Create
   new {Entity}" affordance below the search box, and the <dialog> its
   click opens (see layout.go's shellTmpl for the markup/JS). */
.uc-ref-create {
  display: block; margin-top: 0.3rem; padding: 0; border: none; background: none;
  color: var(--uc-accent, #1c7ed6); font-size: 0.85rem; cursor: pointer; text-align: start;
}
.uc-ref-create:hover { text-decoration: underline; }

.uc-modal {
  border: 1px solid var(--uc-border); border-radius: 8px; padding: 0;
  width: min(32rem, 92vw); max-height: 85vh; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
}
.uc-modal::backdrop { background: rgba(0, 0, 0, 0.45); }
.uc-modal-header { display: flex; justify-content: flex-end; padding: 0.5rem 0.5rem 0; }
.uc-modal-close {
  border: none; background: none; font-size: 1.4rem; line-height: 1; cursor: pointer;
  color: var(--uc-muted); padding: 0.25rem 0.5rem;
}
.uc-modal-close:hover { color: inherit; }
.uc-modal-body { padding: 0 1.25rem 1.25rem; overflow-y: auto; }

/* Multilingual (i18n_text) field: one input per locale (ADR-0009, #23). */
.uc-i18n { display: flex; flex-direction: column; gap: 0.3rem; }
.uc-i18n-row { display: flex; align-items: center; gap: 0.5rem; }
.uc-i18n-locale {
  flex: 0 0 2.5rem; text-transform: uppercase; font-size: 0.75rem;
  color: var(--uc-muted, #666); font-weight: 600;
}
.uc-i18n-row input { flex: 1 1 auto; }

/* In-product help affordance (ADR-0023, uc-infra#143): a "?" on every
   generated form/list page, linking to its derived help topic once
   content exists (internal/help.HasContent), inert until then. Always
   in the tab order (tabindex="0" set in the template regardless of
   state) — an <a> with no href drops out of the default tab order,
   which the disabled state deliberately overrides rather than accepts,
   per ADR-0023's "stay focusable even while inert" decision.

   .uc-form-toolbar wraps the affordance on form pages only (list pages
   put it inline inside the existing .uc-list-toolbar's <h1> instead,
   see the <h1> rule this file already has) — right-aligned rather than
   the block element's default left-aligned full-width row, which
   independent review found left the "?" sitting alone above the first
   field with nothing to anchor it to. */
.uc-form-toolbar { display: flex; justify-content: flex-end; margin: 0 0 0.5rem; }
.uc-help-affordance {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.4rem; margin-inline-start: 0.5rem;
  border: 1px solid var(--uc-border); border-radius: 50%;
  font-size: 0.8rem; font-weight: 600; line-height: 1;
  text-decoration: none; color: var(--uc-accent, #1c7ed6);
  vertical-align: middle;
}
.uc-help-affordance:hover { background: var(--uc-bg); }
.uc-help-affordance[aria-disabled="true"] {
  color: var(--uc-muted); cursor: default; opacity: 0.5;
}
.uc-help-affordance[aria-disabled="true"]:hover { background: none; }

/* The in-product help manual's two-pane viewer (ADR-0023, uc-infra#144
   — internal/api/help.go). A left topic tree + search box, a right
   detail panel — plain flexbox, not grid, specifically so it flips
   sides correctly under dir="rtl" (layout.go's shellTmpl threads
   <html dir="{{.Dir}}"> per-locale) for free: flexbox's row axis
   already follows the document's writing direction, so Arabic/Farsi
   sees the topic tree on the right and the detail panel on the left
   with no [dir=rtl] override rule needed here, the same reasoning this
   file's own margin-inline-start (not margin-left) already applies one
   level down. */
.uc-help-layout {
  display: flex; gap: 1.5rem; align-items: flex-start;
  margin-top: 1rem;
}
.uc-help-topics {
  flex: 0 0 18rem; min-width: 0;
  border: 1px solid var(--uc-border); border-radius: 6px;
  padding: 0.75rem; background: #fff;
}
.uc-help-search {
  width: 100%; margin-bottom: 0.75rem;
}
.uc-help-module-group + .uc-help-module-group { margin-top: 1rem; }
.uc-help-module-label {
  font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--uc-muted); margin: 0 0 0.35rem;
}
.uc-help-topic-list { list-style: none; margin: 0; padding: 0; }
.uc-help-topic-list li { margin: 0; }
.uc-help-topic {
  display: block; padding: 0.3rem 0.4rem; border-radius: 4px;
  color: var(--uc-text); text-decoration: none; font-size: 0.9rem;
}
.uc-help-topic:hover { background: var(--uc-bg); }
.uc-help-topic-active {
  background: var(--uc-highlight); color: var(--uc-accent); font-weight: 600;
}
.uc-help-topic-admin {
  display: inline-block; margin-inline-start: 0.35rem;
  font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.03em;
  padding: 0.05rem 0.35rem; border-radius: 3px;
  background: var(--uc-nav-bg); color: var(--uc-nav-text);
}
.uc-help-empty { color: var(--uc-muted); font-size: 0.9rem; }
.uc-help-detail {
  flex: 1 1 auto; min-width: 0;
  border: 1px solid var(--uc-border); border-radius: 6px;
  padding: 1rem 1.25rem; background: #fff;
}
.uc-help-empty-state { color: var(--uc-muted); }
.uc-help-not-found { padding: 1rem 0; }
/* A captured screenshot (uc-infra#145) ships at a fixed 1280x800 pixel
   size, always wider than #uc-help-detail's own content column — without
   this rule it overflows the pane and forces the whole page to scroll
   horizontally (independent review: measured for real in headless
   Chrome, the image rendered at its native 1280px width inside a 792px
   pane). display:block clears the small inline baseline gap under an
   <img> the same way every other block-level element in this pane
   already sits flush. */
.uc-help-image {
  display: block; max-width: 100%; height: auto;
  border: 1px solid var(--uc-border); border-radius: 4px;
  margin: 0.75rem 0;
}

@media (max-width: 48rem) {
  .uc-help-layout { flex-direction: column; }
  .uc-help-topics { flex: 1 1 auto; width: 100%; }
}
