/* Wise Generative Ontology — Tastewise design language.
 *
 * Tokens lifted from the Tastewise Discover build: Poppins for headings,
 * Nunito for body, JetBrains Mono for the SQL that this product is mostly made
 * of. Fonts are named first and fall back to the system stack, so the app still
 * renders correctly with no network — a Databricks App behind a strict CSP
 * would otherwise lose its typography and nothing else.
 */

:root {
  --bg:            #FAFAFB;
  --surface:       #FFFFFF;
  --line:          #F1F2F5;
  --line-strong:   #E4E7EE;
  --ink:           #190750;
  --ink-2:         #505D70;
  --ink-3:         #8A93A6;

  --primary:       #3E5EE2;
  --primary-ink:   #2B45BC;
  --primary-tint:  #EDF0FC;
  --primary-soft:  #A6B5F2;

  --purple:        #7526C5;
  --purple-tint:   #F5EEFC;
  --green:         #1F9D6B;
  --green-tint:    #F1F5EB;
  --orange:        #F26B3A;
  --orange-tint:   #FFF1E8;

  --radius:        12px;
  --radius-sm:     8px;
  --radius-pill:   999px;
  --shadow:        0 1px 2px rgba(25, 7, 80, .04);
  --shadow-lift:   0 4px 16px rgba(25, 7, 80, .07);

  --sans: 'Nunito', 'Avenir Next', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --display: 'Poppins', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------------------ chrome */

:root { --side: 264px; }

.sidebar {
  position: fixed; inset: 0 auto 0 0; width: var(--side);
  display: flex; flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--line);
  padding: 14px 14px 16px;
  overflow-y: auto;
}

.workspace {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; margin-bottom: 16px;
  border-radius: var(--radius-sm); text-decoration: none;
}
.workspace:hover { background: var(--bg); }
/* The prism is filled with currentColor, so it inherits the brand ink rather
 * than sitting in a coloured tile — the mark was designed to read on the page
 * background, not on a chip. */
.mark { width: 34px; height: 27px; flex: none; color: var(--ink); display: block; }
.workspace-txt { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.workspace-txt strong {
  font-family: var(--display); font-size: 15px; font-weight: 600; color: var(--ink);
}
.workspace-txt small { font-size: 11.5px; color: var(--ink-3); }

.sidebar nav { display: flex; flex-direction: column; gap: 1px; }

.nav-group {
  margin: 16px 0 5px; padding: 0 10px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-3);
}
.nav-group:first-child { margin-top: 0; }

.sidebar nav a {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--ink-2);
  font-size: 14px; font-weight: 600; text-decoration: none;
  transition: background .12s ease, color .12s ease;
}
.sidebar nav a > span:first-child:not(.dot) { flex: 1; min-width: 0; }
.sidebar nav a > .dot + span { flex: 1; min-width: 0; }
.sidebar nav a:hover { background: var(--bg); color: var(--ink); }
.sidebar nav a.active { background: var(--primary-tint); color: var(--primary-ink); }

.count {
  flex: none; padding: 1px 7px;
  background: var(--bg); border-radius: var(--radius-pill);
  font-size: 11.5px; font-weight: 700; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.sidebar nav a.active .count { background: #fff; color: var(--primary-ink); }

.dot { width: 7px; height: 7px; flex: none; border-radius: 50%; background: var(--green); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The reference puts a plan card at the foot of the rail. The equivalent fact
 * here is whose identity the queries run under, which is the entire governance
 * story — so it gets the same permanent, unmissable slot. */
.side-card {
  margin-top: auto; padding: 13px 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.side-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: 7px;
}
.side-card-value {
  font-size: 13px; font-weight: 700; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis;
}
.side-card-note { margin-top: 6px; font-size: 11.5px; line-height: 1.45; color: var(--ink-3); }
.side-card-meta {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--line-strong);
  font-size: 11px; color: var(--ink-3);
}
.side-card-meta code { font-size: 10.5px; padding: 1px 5px; }

.badge {
  padding: 2px 8px; border-radius: var(--radius-pill);
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
.badge-green  { background: var(--green-tint);  color: var(--green); }
.badge-orange { background: var(--orange-tint); color: var(--orange); }

/* ------------------------------------------------------------------- shell */

.shell { margin-left: var(--side); min-height: 100vh; }

header {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  height: 60px; padding: 0 28px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.crumbs { font-size: 13px; color: var(--ink-2); overflow: hidden; }
.crumbs code { font-size: 12px; }

.conn {
  text-align: right; font-size: 13px; font-weight: 700; color: var(--green);
  line-height: 1.3; white-space: nowrap;
}
.conn small { display: block; font-weight: 500; color: var(--ink-3); }
.conn.warn { color: var(--orange); }

main {
  max-width: 1180px;
  margin: 0 auto;
  padding: 34px 28px 90px;
}

/* Narrow viewports: the rail becomes a normal block above the content rather
 * than a fixed overlay that eats half the screen. */
@media (max-width: 980px) {
  .sidebar { position: static; width: auto; flex-direction: column; }
  .sidebar nav { flex-flow: row wrap; }
  .nav-group { width: 100%; }
  .side-card { margin-top: 16px; }
  .shell { margin-left: 0; }
}

/* -------------------------------------------------------------- typography */

h1 {
  font-family: var(--display);
  font-size: 30px; font-weight: 600; letter-spacing: -.02em;
  color: var(--ink);
  margin-bottom: 10px;
}
h2 {
  font-family: var(--display);
  font-size: 17px; font-weight: 600; letter-spacing: -.01em;
  color: var(--ink);
  margin-bottom: 10px;
}
.lede { color: var(--ink-2); max-width: 68ch; margin-bottom: 22px; }
.muted { color: var(--ink-3); }
.small { font-size: 13px; }
.bad  { color: var(--orange); font-weight: 700; }
.ok   { color: var(--green); }
.num  { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

code {
  font-family: var(--mono); font-size: .88em;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 5px;
  color: var(--purple);
}

pre {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.65;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  overflow-x: auto;
  color: var(--ink);
}
pre code { background: none; border: none; padding: 0; color: inherit; }

/* ------------------------------------------------------------------ panels */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px 22px;
  margin-bottom: 18px;
}
.panel.ok    { border-color: #CFE9DD; background: linear-gradient(0deg, var(--green-tint), var(--green-tint)) padding-box, var(--surface); }
.panel.error { border-color: #F6D2C1; background: var(--orange-tint); }
.panel.error pre { background: rgba(255,255,255,.7); border-color: #F6D2C1; }

details.panel > summary {
  cursor: pointer; list-style: none;
  font-family: var(--display); font-weight: 600; font-size: 15px;
  color: var(--ink);
}
details.panel > summary::-webkit-details-marker { display: none; }
details.panel > summary::before {
  content: '▸'; color: var(--ink-3); margin-right: 8px; display: inline-block;
  transition: transform .15s ease;
}
details.panel[open] > summary::before { transform: rotate(90deg); }
details.panel[open] > summary { margin-bottom: 14px; }

.stmt { padding: 14px 0; border-top: 1px solid var(--line); }
.stmt:first-of-type { border-top: none; padding-top: 4px; }
.purpose {
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
  color: var(--ink-2); margin-bottom: 8px;
}

.flag {
  margin-top: 6px; padding: 7px 10px;
  background: var(--orange-tint); border-left: 3px solid var(--orange);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 12.5px; color: #8A3512;
}

/* ------------------------------------------------------------------- chips */

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }

.chip {
  display: inline-flex; align-items: center;
  padding: 5px 13px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  font-size: 12.5px; font-weight: 700; color: var(--ink-2);
}
.chip-unpopulated,
.chip-no_target_entity,
.chip-out_of_scope,
.chip-unresolved { background: var(--bg); color: var(--ink-3); }
.chip-column_alias_of { background: var(--purple-tint); border-color: #E4D4F5; color: var(--purple); }
.chip-value_asserts_entity,
.chip-column_asserts_entity { background: var(--primary-tint); border-color: #D6DEFA; color: var(--primary-ink); }

/* ------------------------------------------------------------------ tables */

table { border-collapse: collapse; width: 100%; }

table.grid {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  margin-bottom: 22px;
}
table.grid th {
  text-align: left; padding: 11px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--line-strong);
  font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-3);
}
table.grid td {
  padding: 13px 16px;
  border-top: 1px solid var(--line);
  vertical-align: top;
  font-size: 13.5px;
}
table.grid tbody tr:hover { background: #FCFCFD; }
table.grid tr.row-warn { background: var(--orange-tint); }
table.grid tr.row-warn:hover { background: #FFE9DC; }
table.grid tr.row-dim td { color: var(--ink-3); }

table.kv th {
  text-align: left; padding: 7px 22px 7px 0;
  font-weight: 600; color: var(--ink-3); font-size: 13px; white-space: nowrap;
}
table.kv td { padding: 7px 0; }

/* ------------------------------------------------------------------ inputs */

.btn, button {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 18px;
  background: var(--primary); color: #fff;
  border: 1px solid var(--primary);
  border-radius: var(--radius-sm);
  font-family: var(--sans); font-size: 14px; font-weight: 700;
  text-decoration: none; cursor: pointer;
  transition: background .12s ease, box-shadow .12s ease;
}
.btn:hover, button:hover { background: var(--primary-ink); box-shadow: var(--shadow-lift); }
.btn:disabled, button:disabled {
  background: var(--bg); color: var(--ink-3);
  border-color: var(--line-strong); cursor: not-allowed; box-shadow: none;
}

input, select, textarea {
  font-family: var(--sans); font-size: 13.5px; color: var(--ink);
  padding: 8px 11px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  outline: none;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--primary-soft);
  box-shadow: 0 0 0 3px var(--primary-tint);
}
textarea { font-family: var(--mono); font-size: 12.5px; line-height: 1.6; }
select.small, input.small { padding: 5px 8px; font-size: 12.5px; }

label { display: block; margin-bottom: 12px; font-size: 13px; font-weight: 600; color: var(--ink-2); }
label input, label select { display: block; margin-top: 5px; min-width: 260px; }
label.small { font-weight: 600; }

/* The decision cell drives row height on a 77-column table, so its controls
 * flow inline and only wrap when they must. Stacked block elements here turned
 * every row into a 150px band and made the grid unreadable. */
td.decision {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  min-width: 250px;
}
td.decision select { flex: 0 1 auto; max-width: 100%; }
td.decision input.wide { flex: 1 1 100%; }
td.decision .flag { flex: 1 1 100%; margin-top: 2px; }

/* --------------------------------------------------------------- polarity */

.pol { margin-bottom: 3px; font-size: 12.5px; }
.pol code { background: none; border: none; padding: 0; color: inherit; font-weight: 600; }
.pol-asserts { color: var(--green); }
.pol-asserts::before { content: '✓ '; }
.pol-negates { color: var(--orange); font-weight: 700; }
.pol-negates::before { content: '✕ '; }
.pol-level   { color: var(--purple); }
.pol-level::before { content: '≈ '; }
.pol-unknown { color: var(--ink-3); }
.pol-unknown::before { content: '? '; }

a { color: var(--primary-ink); }

/* The polarity cell carries the product's headline evidence — value, sign and
 * the inversion warning. Left to shrink-to-fit it collapsed into a 90px ribbon
 * and the warning read one word per line. */
table.grid th:nth-child(3), table.grid td:nth-child(3) { min-width: 210px; }
table.grid th:nth-child(1), table.grid td:nth-child(1) { min-width: 170px; }
table.grid th:nth-child(2), table.grid td:nth-child(2) { min-width: 130px; }

/* ---------------------------------------------------------------- loading */

.progress-bar {
  position: fixed; top: 0; left: 0; z-index: 100;
  height: 3px; width: 0;
  background: linear-gradient(90deg, var(--primary), var(--purple));
  box-shadow: 0 0 8px rgba(62, 94, 226, .5);
  transition: width .18s ease-out;
}

.spinner {
  width: 13px; height: 13px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%;
  animation: spin .6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.btn.is-busy, button.is-busy {
  /* Keep the filled treatment while working. The :disabled greying is for
   * "you cannot do this", not "this is happening" — using it for both makes a
   * running action look refused. */
  background: var(--primary); color: #fff; border-color: var(--primary);
  cursor: progress; opacity: .85;
}
.btn.is-busy:disabled, button.is-busy:disabled {
  background: var(--primary); color: #fff; border-color: var(--primary);
}

@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2s; }
  .progress-bar { transition: none; }
}

/* ---------------------------------------------------------------- rhythm */
/* The reset zeroes every margin, which is right for layout primitives and
 * wrong for prose and form rows — buttons ended up flush against the control
 * above and the panel below. Restored here rather than per-template. */

p  { margin-bottom: 12px; }
ol, ul { margin: 0 0 12px 20px; }
li { margin-bottom: 4px; }
p:last-child, ol:last-child, ul:last-child { margin-bottom: 0; }

form { margin-bottom: 20px; }
form:last-child { margin-bottom: 0; }

/* Action rows: the button and its explanatory note sit on one line with real
 * space around them, and wrap together on narrow viewports. */
.actions,
form > p:has(> button),
form > p:has(> .btn) {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  margin: 16px 0 0;
}

textarea { display: block; width: 100%; }
form textarea + p, form textarea + .actions { margin-top: 12px; }

/* Buttons that stand alone still need clearance from whatever precedes them. */
.stmt > .btn, .stmt > button { margin-top: 4px; }

/* Block elements the reset zeroed. `pre` is the one that bit twice: a button
 * placed directly after a code block, or as a bare child of a form with no
 * wrapping <p>, had no rule granting it any clearance at all. */
pre, table, h1, h2 { margin-bottom: 12px; }
pre:last-child, table:last-child { margin-bottom: 0; }
h1 { margin-bottom: 10px; }
h2 { margin-bottom: 10px; }

/* A button that is a direct child of a form — no <p> wrapper — still needs
 * space from whatever block precedes it. */
form > button, form > .btn { margin-top: 4px; }

/* ------------------------------------------------------ flow spacing floor */
/* The reset zeroes every margin and the rhythm section restores it BY ELEMENT
 * NAME, so any block whose tag is not on that list lands flush against its
 * neighbour. That is the bug that shipped twice — <textarea> + <p><button>,
 * then <pre> + <form><button>. Stop enumerating tags: set a floor instead, so
 * adjacent children of a flow container are at least 12px apart whatever they
 * are. Top margins only, so nothing can add dead space to the bottom of a
 * panel, and margin collapsing leaves every existing larger gap untouched. */
main > * + *,
.panel > * + *:not(.stmt),
.stmt > * + * {
  margin-top: 12px;
}

/* Prose lists: 4px is tighter than the leading inside a multi-line item, so
 * the points read as one paragraph. */
li + li { margin-top: 8px; }

/* The inversion callout rendered at 8px in the decision cell and 6px in the
 * polarity cell — same component, two clearances, because only one cell is a
 * flex container. 8px in both. */
.flag { margin-top: 8px; }

/* `.side-card { margin-top: auto }` is free-space distribution, not spacing:
 * it resolves to 0 the moment the rail is taller than the viewport, which it
 * is on any short laptop, and the last nav link then sits on the card border. */
.sidebar nav { margin-bottom: 16px; }

@media (max-width: 980px) {
  /* Stacked, the divider is on the edge that no longer faces the content, so
   * the white rail and the white header fuse into one unbroken slab. */
  .sidebar { border-right: 0; border-bottom: 1px solid var(--line-strong); }
  /* `flex-flow: row wrap` does not touch `gap`, so the 1px dense-column value
   * became the row gap and hovered links touched the row above. */
  .sidebar nav { gap: 6px; }
  .side-card { margin-top: 0; }
}


/* ------------------------------------------------------------ attribution */

.powered {
  display: flex; align-items: center; gap: 8px;
  margin-top: 12px; padding: 9px 10px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background .12s ease;
}
.powered:hover { background: var(--bg); }
.powered-label { font-size: 11px; color: var(--ink-3); }
.powered-brand {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--display); font-size: 13px; font-weight: 600;
  color: var(--ink);
}
.powered-brand svg { width: 16px; height: 18px; flex: none; }

/* Copy row: a long URL with a secret in it is unusable if you have to select it
 * by hand, and a mis-selected token fails with an unhelpful 404. */
.copyrow { display: flex; align-items: stretch; gap: 10px; }
.copyrow pre { flex: 1; margin: 0; word-break: break-all; white-space: pre-wrap; }
.copyrow .btn { flex: none; align-self: flex-start; }
