/* =============================================================================
   Shared contract-page styling.

   Classes named `.contract-*` are reused across every contract type
   (dimensions today; assumptions and results later). Classes named `.dim-*`
   belong to dimension-specific markup (the collapsible card tree).

   Every rule that competes with a Material default (table, dl, summary,
   details) is double-namespaced under `.md-typeset` so specificity wins
   without `!important` gymnastics. Colours come from CSS variables so the
   layout adapts to the slate/default palette swap.
   ========================================================================== */

/* --- Global content width ----------------------------------------------
   Material caps page content at 61rem by default. Contract pages are
   table-heavy, so a bit more horizontal room helps — ~80rem keeps prose
   comfortably readable while letting the fields table breathe. */
.md-grid {
  max-width: 80rem;
}

/* --- Page shell --------------------------------------------------------- */
.contract-page {
  margin-top: 0.5rem;
}

/* --- Contract metadata block (Contract Name / Type / Description) ------- */
.md-typeset .contract-meta,
.contract-meta {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 0.9rem;
  row-gap: 0.3rem;
  margin: 0 0 1.25rem;
  font-size: 0.85em;
}
.md-typeset .contract-meta dt,
.contract-meta dt {
  margin: 0;
  color: var(--md-default-fg-color--light);
  font-weight: 600;
}
.md-typeset .contract-meta dd,
.contract-meta dd {
  margin: 0;
  color: var(--md-default-fg-color);
}
.md-typeset .contract-meta dd code,
.contract-meta dd code {
  background: transparent;
  padding: 0;
  font-size: 0.9em;
  color: var(--md-default-fg-color);
}

/* --- Primary-key line --------------------------------------------------- */
.md-typeset .contract-primary-key,
.contract-primary-key {
  margin: 0 0 1rem;
  font-size: 0.95em;
}
.md-typeset .contract-primary-key code,
.contract-primary-key code {
  background: var(--md-default-fg-color--lightest);
  padding: 0.05rem 0.35rem;
  border-radius: 4px;
  font-size: 0.9em;
}

/* --- Download buttons ---------------------------------------------------
   Uses --md-accent-fg-color rather than --md-primary-fg-color for
   text/border/fill throughout this file: the site's light-mode header uses
   Material's `white` primary swatch, so --md-primary-fg-color is literally
   white and would render invisible against the (also white) page body. */
.contract-downloads {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 2rem;
  margin-bottom: 1.25rem;
}
.contract-download-btn {
  display: inline-block;
  padding: 0.45rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--md-accent-fg-color);
  color: var(--md-accent-fg-color);
  background: transparent;
  font-size: 0.85em;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.12s ease, color 0.12s ease;
}
.contract-download-btn:hover {
  background: var(--md-accent-fg-color);
  color: var(--md-accent-bg-color);
}

/* --- Overview tables (Name / Title / Description, sortable) ------------- */
.md-typeset .contract-index-table,
.contract-index-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9em;
  margin: 0.5rem 0 0;
  display: table;
}
.md-typeset .contract-index-table th,
.md-typeset .contract-index-table td,
.contract-index-table th,
.contract-index-table td {
  padding: 0.6rem 0.8rem;
  text-align: left;
  vertical-align: top;
  border: none;
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
}
.md-typeset .contract-index-table thead th,
.contract-index-table thead th {
  font-weight: 600;
  color: var(--md-default-fg-color);
  border-bottom: 2px solid var(--md-default-fg-color--lighter);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
/* Sort indicators — see the shared `table.sortable thead th::after` block
   at the end of the file. The contract-index-table uses that unified rule. */
/* Full-row clickable overlay: row is the positioning context; the first-cell
   anchor's ::after pseudo-element stretches across the whole row. */
.md-typeset .contract-index-table tbody tr.contract-index-row,
.contract-index-table tbody tr.contract-index-row {
  position: relative;
  /* Safari doesn't treat `position: relative` on a table-row as a containing
     block for absolutely-positioned descendants — the full-row `::after`
     link below escapes to an ancestor further up the tree, so every row's
     click target ends up overlapping and only the last row's link wins.
     A (no-op) transform reliably creates a containing block regardless of
     display type, sidestepping the table-row quirk. */
  transform: translate(0, 0);
  transition: background 0.12s ease;
}
.md-typeset .contract-index-table tbody tr.contract-index-row:not(.contract-index-row-static):hover,
.contract-index-table tbody tr.contract-index-row:not(.contract-index-row-static):hover {
  background: var(--md-default-fg-color--lightest);
}
.md-typeset .contract-index-table tbody tr.contract-index-row-static,
.contract-index-table tbody tr.contract-index-row-static {
  color: var(--md-default-fg-color--light);
}
.md-typeset .contract-index-table tbody .contract-index-name a,
.contract-index-table tbody .contract-index-name a {
  text-decoration: none;
}
.md-typeset .contract-index-table tbody .contract-index-name a code,
.contract-index-table tbody .contract-index-name a code {
  color: var(--md-accent-fg-color);
  background: transparent;
  font-weight: 600;
  padding: 0;
}
.md-typeset .contract-index-table tbody .contract-index-name a::after,
.contract-index-table tbody .contract-index-name a::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* --- Frictionless fields table ----------------------------------------- */
.md-typeset .contract-fields-table,
.contract-fields-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88em;
  margin: 0.5rem 0 1.5rem;
  display: table;
}
.md-typeset .contract-fields-table th,
.md-typeset .contract-fields-table td,
.contract-fields-table th,
.contract-fields-table td {
  padding: 0.5rem 0.7rem;
  text-align: left;
  vertical-align: top;
  border: none;
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
}
.md-typeset .contract-fields-table thead th,
.contract-fields-table thead th {
  font-weight: 600;
  color: var(--md-default-fg-color);
  border-bottom: 2px solid var(--md-default-fg-color--lighter);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
/* Sort indicators — see the shared `table.sortable thead th::after` block
   at the end of the file. */
.md-typeset .contract-fields-table tbody tr:hover,
.contract-fields-table tbody tr:hover {
  background: var(--md-default-fg-color--lightest);
}
.md-typeset .contract-fields-table td code,
.contract-fields-table td code {
  background: transparent;
  padding: 0;
  font-size: 0.95em;
}
/* Required column: centred ✓. */
.md-typeset .contract-fields-table .contract-fields-req,
.contract-fields-table .contract-fields-req {
  text-align: center;
  color: var(--md-accent-fg-color);
  font-weight: 700;
}
/* Name column (1st): give it enough width that most field names fit on one
   line instead of wrapping — long names like the ones with a foreign-key
   link were getting squeezed into a narrow auto-sized column. */
.md-typeset .contract-fields-table td:nth-child(1),
.md-typeset .contract-fields-table th:nth-child(1),
.contract-fields-table td:nth-child(1),
.contract-fields-table th:nth-child(1) {
  white-space: nowrap;
  width: 1%;
}

/* Type column (3rd): keep values like "integer" on one line — a narrow column
   wastes a character break on a short, self-contained token. */
.md-typeset .contract-fields-table td:nth-child(3),
.md-typeset .contract-fields-table th:nth-child(3),
.contract-fields-table td:nth-child(3),
.contract-fields-table th:nth-child(3) {
  white-space: nowrap;
}

/* Section heading shown before the fields table. Smaller than the page
   title; no top border; tight margin against the table below. */
.md-typeset .contract-fields-heading,
.contract-fields-heading {
  margin: 1.25rem 0 0.25rem;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--md-default-fg-color);
}

/* Foreign-key field name: the whole name is the link (styled the same colour
   as every other link on the site) when the target dimension has a
   renderable page. When it doesn't (e.g. an index_only dimension), it's
   plain code wrapped in a dotted-underline <abbr> tooltip instead — see
   .contract-fk-link usage in contracts.py. Both states get the same dotted
   underline (scoped to the fields table only, not all links site-wide), so
   it reads as "this is a foreign key" regardless of whether it happens to
   be clickable. */
.md-typeset .contract-fk-link,
.contract-fk-link {
  color: var(--md-typeset-a-color);
  text-decoration: none;
  border-bottom: 0.05rem dotted var(--md-typeset-a-color);
}
.md-typeset .contract-fk-link:hover,
.contract-fk-link:hover {
  color: var(--md-accent-fg-color);
  border-bottom-color: var(--md-accent-fg-color);
}
.md-typeset .contract-fk-link code,
.contract-fk-link code {
  color: inherit;
}
.md-typeset .contract-fields-table abbr,
.contract-fields-table abbr {
  cursor: help;
  text-decoration: none;
  border-bottom: 0.05rem dotted var(--md-default-fg-color--light);
}

/* Constraint chips (one per non-required constraint, rendered side-by-side). */
.contract-constraint {
  display: inline-block;
  max-width: 100%;
  padding: 0.05rem 0.4rem;
  margin: 0 0.25rem 0.2rem 0;
  border-radius: 4px;
  background: var(--md-default-fg-color--lightest);
  font-family: var(--md-code-font-family, monospace);
  font-size: 0.85em;
  color: var(--md-default-fg-color);
  /* A long enum= chip (a big comma-separated value list) needs to wrap
     within the cell instead of forcing the whole table wider than the
     page — nowrap made every constraint a single unbreakable line. */
  white-space: normal;
  overflow-wrap: break-word;
}

/* =============================================================================
   Dimension-specific tree markup (`.dim-*`). Not reused by other contract
   types because only dimensions have hierarchical rows.
   ========================================================================== */

.dim-tree {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.dim-children {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0.25rem 0 0 1.1rem;
}

/* Cards (shared by node + leaf) — same look at every depth, only indentation differs.
   Namespaced under .md-typeset and !important on the colour-bearing properties:
   `<details>` elements otherwise pick up Material's own default admonition look
   (blue border + tinted background), which outranks a bare `.dim-card` selector
   on specificity — !important removes any doubt regardless of cascade order. */
.md-typeset .dim-card,
.dim-card {
  border: 1px solid var(--md-default-fg-color--lighter) !important;
  border-radius: 8px;
  box-shadow: none !important;
  /* !important: `<details>` has different Material padding rules for the
     open vs. closed state (`:not([open])` zeroes padding-bottom), which
     otherwise wins on specificity over a plain `.dim-card` padding value
     and made the two states look lopsided. */
  padding: 0.65rem 0.9rem !important;
  margin: 0 !important; /* override user content */
  background: var(--md-default-bg-color) !important;
  transition: border-color 0.12s ease;
}
.md-typeset .dim-card:hover,
.dim-card:hover {
  border-color: var(--md-default-fg-color--light) !important;
}
/* Open (expanded) card reads as the "active" one — accent-coloured border,
   using the same accent variable the rest of the site is themed with. */
.md-typeset .dim-card[open],
.dim-card[open] {
  border-color: var(--md-accent-fg-color) !important;
}

/* Header row: id followed by label, with a clear gap. Material's own
   `.md-typeset summary` styling (blue tint background, left padding reserved
   for an admonition icon, negative margins) otherwise wins on specificity —
   reset it all here, same reasoning as the .dim-card fix above. */
.md-typeset .dim-head,
.dim-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  cursor: pointer;
  background: transparent !important;
  border: none !important;
  margin: 0 !important;
  padding: 0 !important;
  min-height: 0 !important;
  font-weight: normal;
}
/* Suppress the native disclosure marker on every browser. */
.dim-card > summary {
  list-style: none !important;
}
.dim-card > summary::-webkit-details-marker {
  display: none !important;
}
.dim-card > summary::marker {
  content: "" !important;
  display: none !important;
}
/* Defensive: kill any chevron icons themes may inject via pseudo-elements.
   Material draws its own arrow on `.md-typeset details > summary::after` using
   `mask-image`, which is namespaced and has higher specificity than a bare
   `.dim-card` selector — we mirror the namespace and explicitly clear the mask. */
.md-typeset .dim-card > summary::before,
.md-typeset .dim-card > summary::after,
.dim-card > summary::before,
.dim-card > summary::after {
  content: none !important;
  display: none !important;
  background: none !important;
  background-image: none !important;
  -webkit-mask-image: none !important;
  mask-image: none !important;
}
/* Collapsible cards (non-leaf) get a circle badge with +/− that swaps on open.
   Namespaced under .md-typeset to outrank Material's own summary pseudo-element. */
.md-typeset .dim-card:not(.dim-leaf) > summary.dim-head::before,
.dim-card:not(.dim-leaf) > summary.dim-head::before {
  content: "+" !important;
  display: inline-flex !important;
  position: static !important; /* Material's summary::before is absolutely positioned by default */
  align-items: center;
  justify-content: center;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  background: var(--md-accent-fg-color) !important;
  background-image: none !important;
  -webkit-mask-image: none !important;
  mask-image: none !important;
  color: var(--md-accent-bg-color);
  font-size: 0.85em;
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
  margin-right: 0.5rem;
  transition: background 0.12s ease;
}
.md-typeset .dim-card:not(.dim-leaf)[open] > summary.dim-head::before,
.dim-card:not(.dim-leaf)[open] > summary.dim-head::before {
  content: "\2212" !important; /* − minus sign */
}
/* Leaves: no children, so disable the toggle affordance entirely. They also
   get no +/- badge, so pad the row by the badge's own width (1.1rem +
   0.5rem gap) to keep every id column aligned whether or not its row has
   the toggle. */
.md-typeset .dim-leaf > summary.dim-head,
.dim-leaf > summary.dim-head {
  cursor: default;
  padding-left: 1.6rem !important;
}

.md-typeset .dim-id,
.dim-id {
  font-size: 0.85em;
  color: var(--md-default-fg-color--light);
  background: transparent !important;
  padding: 0 !important;
}
.dim-label {
  margin-left: 1rem;
  color: var(--md-default-fg-color);
  font-weight: 600;
}
/* Rendered inline after the label, e.g. "id label – description" — the dash
   is a decorative prefix so the source description string stays plain text. */
.dim-desc {
  margin-left: 0.35rem;
  color: var(--md-default-fg-color--light);
  font-size: 0.9em;
}
.dim-desc::before {
  content: "– "; /* en dash + space — as a hex escape, "\2013 " would have the
                    trailing space consumed as the escape's terminator */
}

/* =============================================================================
   Shared sort-indicator glyphs.

   Any `<table class="sortable">` gets a stacked up/down arrow in each header
   by default, a single up-arrow on the ascending column and a single
   down-arrow on the descending column. tablesort.js sets the `aria-sort`
   attribute on the active <th>, which these rules key off of.

   Glyphs are drawn with inline SVG via `mask-image` (not text content), so
   rendering is identical regardless of the body font. The mask colour is
   `currentColor`, so the indicator inherits the cell colour — `background`
   on the pseudo-element is what you tweak to change it (primary colour on
   the active column).
   ========================================================================== */
.md-typeset table.sortable thead th,
table.sortable thead th {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.md-typeset table.sortable thead th::after,
table.sortable thead th::after {
  content: "";
  display: inline-block;
  width: 0.45em;
  height: 0.7em;
  margin-left: 0.35em;
  vertical-align: 0;
  background: currentColor;
  opacity: 0.5;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: contain;
          mask-size: contain;
  /* Default (neutral): stacked up + down triangles. */
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 16'><polygon points='5,0 10,7 0,7'/><polygon points='5,16 10,9 0,9'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 16'><polygon points='5,0 10,7 0,7'/><polygon points='5,16 10,9 0,9'/></svg>");
}
.md-typeset table.sortable thead th[aria-sort="ascending"]::after,
table.sortable thead th[aria-sort="ascending"]::after {
  background: var(--md-accent-fg-color);
  opacity: 1;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,0 10,9 0,9'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,0 10,9 0,9'/></svg>");
}
.md-typeset table.sortable thead th[aria-sort="descending"]::after,
table.sortable thead th[aria-sort="descending"]::after {
  background: var(--md-accent-fg-color);
  opacity: 1;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,10 10,1 0,1'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,10 10,1 0,1'/></svg>");
}

/* --- Dimension bundle version badge ------------------------------------- */
.md-typeset .dimensions-version-badge,
.dimensions-version-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.25rem 0.6rem;
  margin: 0.1rem 0 1rem;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 0.4rem;
  background: var(--md-code-bg-color);
  font-size: 0.85em;
}
.md-typeset .dimensions-version-badge .dimensions-version-label,
.dimensions-version-badge .dimensions-version-label {
  color: var(--md-default-fg-color--light);
  font-weight: 600;
}
.md-typeset .dimensions-version-badge code,
.dimensions-version-badge code {
  background: transparent;
  padding: 0;
  font-weight: 600;
}
