/* ------------------------------------------------------------------------ */
/*   FONTS                                                                  */
/* ------------------------------------------------------------------------ */
@font-face {
  font-display: swap;
  font-family: "Cascadia Mono SemiLight";
  font-style: normal;
  font-weight: 350;
  src: url("/static/CascadiaMono-SemiLight.woff2") format("woff2");
}

@font-face {
  font-display: swap;
  font-family: "Latin Modern";
  font-style: normal;
  font-weight: normal;
  src: url("/static/LM-regular.woff2") format("woff2");
}

@font-face {
  font-display: swap;
  font-family: "Latin Modern";
  font-style: normal;
  font-weight: bold;
  src: url("/static/LM-bold.woff2") format("woff2");
}

:root {
  --mono-font: "Cascadia Mono SemiLight", Consolas, Menlo, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
  --math-font: "Latin Modern", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
}

/* ------------------------------------------------------------------------ */
/*   USE LIGHT MODE ONLY                                                    */
/* ------------------------------------------------------------------------ */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: light;
    --bg: #fff;
    --accent-bg: #f5f7ff;
    --text: #212121;
    --text-light: #585858;
    --accent: #0d47a1;
    --accent-hover: #1266e2;
    --accent-text: var(--bg);
    --code: #d81b60;
    --preformatted: #444;
    --marked: #ffdd33;
    --disabled: #efefef;
  }
}

/* ------------------------------------------------------------------------ */
/*   RESET COLOR SCHEME                                                     */
/* ------------------------------------------------------------------------ */

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: revert;
  }

  img,
  video {
    opacity: revert;
  }
}

/* ------------------------------------------------------------------------ */
/*   GENERAL                                                                */
/* ------------------------------------------------------------------------ */
body {
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

a {
  text-decoration: none;
}

dt {
  color: var(--text);
}

pre {
  font-size: 0.8em;
}

textarea {
  font-family: var(--mono-font);
  font-size: 0.8em;
  width: 100%;
}

.math {
  font-family: var(--math-font);
}

/* ------------------------------------------------------------------------ */
/*   FORMAT HEADERS                                                         */
/* ------------------------------------------------------------------------ */

h1 {
  font-size: 2.5rem;
}

h2 {
  font-size: 2.1rem;
}

h3 {
  font-size: 1.75rem;
}

h4 {
  font-size: 1em;
  font-weight: 500;
  margin-bottom: 0;
}

h6 {
  font-size: 1em;
  font-weight: 500;
  letter-spacing: 0.1em;
  margin: 0;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------------ */
/*   LAYOUT UTILITIES                                                       */
/* ------------------------------------------------------------------------ */

.text-center {
  text-align: center;
}

/* Inline-block wrapper that shrinks to its content width and keeps its
   own content left-aligned. Drop inside a .text-center parent to center
   a left-aligned block (e.g., a multi-line form control group) horizontally
   while preserving the parent's centered heading/intro text. */
.controls-block {
  display: inline-block;
  max-width: 100%;
  text-align: left;
}

.text-left {
  text-align: left;
}

.text-right {
  text-align: right;
}

.gap-sm {
  margin-bottom: 0.5rem;
}

.gap-md {
  margin-bottom: 1rem;
}

.gap-lg {
  margin-bottom: 2rem;
}

.bordered {
  border: 1px solid #ccc;
}

.hr-half {
  width: 50%;
}

.hr-three-quarter {
  width: 75%;
}

/* Header brand link: clickable but visually unchanged. */
header h1 a:link,
header h1 a:visited {
  color: inherit;
  text-decoration: none;
}

/* Header logos flanking the brand text, sized to the title's font-size. */
header h1 a {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}

header h1 .brand-logo {
  height: 1em;
  width: auto;
}

/* ------------------------------------------------------------------------ */
/*   DROPDOWN NAV                                                           */
/* ------------------------------------------------------------------------ */

.dropdown-nav {
  display: flex;
  justify-content: center;
  gap: 1.5rem;
  max-width: min(45rem, 90%);
  margin: 0 auto;
}

.dropdown-nav > div {
  flex: 1;
}

.dropdown-nav select {
  width: 100%;
}

.dropdown-nav label,
.page-toolbar label {
  font-weight: 500;
  letter-spacing: 0.1em;
  margin: 0;
  text-align: left;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------------ */
/*   PAGE TOOLBAR                                                           */
/*   For interface pages with one dropdown + Submit. Distinct from          */
/*   .dropdown-nav (which lays out the home page's 4 peer dropdowns as      */
/*   equal columns). Elements size to their natural width and cluster at    */
/*   the center of the toolbar; text content aligns on a common baseline    */
/*   so heterogeneous children (form controls + plain text) sit visually    */
/*   on the same line regardless of each child's box height.                */
/* ------------------------------------------------------------------------ */

.page-toolbar {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  font-size: 1rem;
  gap: 1rem 1.5rem;
  justify-content: center;
  margin: 0 auto;
}

/* ------------------------------------------------------------------------ */
/*   MATRIX LAYOUT                                                          */
/*   2×2 grid placing axis labels around a function-matrix table. Used by   */
/*   the 3D polyfunctional equation picker where the matrix                 */
/*   has both X and Y dimensions to label. The .label-x uses                */
/*   writing-mode: sideways-lr to render the X-axis label as rotated text   */
/*   reading bottom-to-top alongside the matrix (replaces the legacy        */
/*   F<br>u<br>n<br>c... vertical letter stack from the original templates).*/
/* ------------------------------------------------------------------------ */

.matrix-layout {
  align-items: center;
  display: grid;
  gap: 0.5rem;
  grid-template-areas:
    ".       label-y"
    "label-x matrix";
  grid-template-columns: auto auto;
  justify-items: center;
  margin: 1rem 0;
}

.matrix-layout > .label-y {
  grid-area: label-y;
  margin: 0;
  margin-bottom: -0.5rem;
}

.matrix-layout > .label-x {
  grid-area: label-x;
  margin: 0;
  writing-mode: sideways-lr;
}

.function-matrix {
  margin-top: 0.5rem;
  /* Separate (not collapsed) borders so each picker cell owns all four of
     its edges -- a prerequisite for the per-cell outset/inset 3D bevel in
     the MATRIX PICKER CELLS section. simple.css sets table borders to
     collapse, which merges shared edges into one flat line and defeats the
     bevel; .function-matrix beats it on specificity. border-spacing gives
     the gap between buttons that the collapsed layout had no room for. */
  border-collapse: separate;
  border-spacing: 0.35rem;
}

.matrix-layout > .function-matrix {
  grid-area: matrix;
  margin-top: 0;
}

/* Scroll wrapper for matrix tables wider than their container. Local
   horizontal scroll (vs. window scroll) keeps the rest of the page
   stable, and padding-right makes the right end of the matrix visible
   as a defined boundary instead of a flush-with-viewport edge. */
.function-matrix-scroll {
  overflow-x: auto;
  padding-right: 1rem;
}

.matrix-layout > .function-matrix-scroll {
  grid-area: matrix;
  max-width: 100%;
}

/* ------------------------------------------------------------------------ */
/*   MATRIX PICKER CELLS                                                     */
/*   Clickable coefficient cells in the polyfunctional / polynomial-        */
/*   customization / polyrational selection matrices. The "selected" class  */
/*   IS the selection state: JavascriptCommonToFunctionMatrices.js reads it  */
/*   via isSelected() and toggles it via setSelected(); setSelected() also   */
/*   writes that hidden input on every toggle, while its server-rendered     */
/*   initial value keeps the form correct at rest. Both states share a       */
/*   silver face; unselected = raised (outset) bevel, selected = pushed-in   */
/*   (inset) bevel -- selection reads from the bevel direction alone,        */
/*   replacing the legacy inline white/lightgray                             */
/*   style="background-color:rgb(...)" that used to carry this state.        */
/* ------------------------------------------------------------------------ */
td.pick {
  /* Classic raised push-button. The bevel uses EXPLICIT per-edge colors
     rather than the `outset` keyword: modern browsers derive `outset` edges
     from border-color but mostly only darken, so on a light face the
     top/left highlight vanishes and the button looks like it casts a shadow
     instead of standing proud. Setting the four edges by hand -- light
     top/left, dark bottom/right -- reproduces the symmetric Win95 bevel of
     the original site deterministically. border-color shorthand order is
     top right bottom left. */
  background-color: #d3d3d3;
  border: 3px solid;
  border-color: #f4f4f4 #808080 #808080 #f4f4f4;
  cursor: pointer;
  font-size: 75%;
  padding: 0.5rem 0.75rem;
  text-align: center;
  white-space: nowrap;
}

/* Pressed look = inverted bevel (dark top/left, light bottom/right), face
   stays silver. Selected reads as "pushed in" purely from the depressed
   bevel rather than a color change. Applied on mouse-down for tactile
   feedback and persistently while selected. */
td.pick:active,
td.pick.selected {
  border-color: #808080 #f4f4f4 #f4f4f4 #808080;
}

/* ------------------------------------------------------------------------ */
/*   FORM COLUMNS                                                           */
/*   Responsive multi-column layout for X/Y/Z form-field groups. On wide    */
/*   viewports each axis occupies its own column; on narrow viewports they  */
/*   stack to a single column via `auto-fit` + `minmax(min(...), 1fr)`.     */
/*   Replaces the legacy nested-table pattern in divs/*.html.               */
/* ------------------------------------------------------------------------ */

.form-columns {
  display: grid;
  gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
}

/* A visible <legend> that replaced a former column <label> matches its look
   (see the FORM FIELD GROUPS section). `width: 100%` is harmless on the block
   <label> and needed for the <legend> to span the column. */
.form-columns > div > label,
.form-columns > div > fieldset.field-group > legend {
  border-bottom: 1px solid var(--border);
  font-weight: 500;
  display: block;
  width: 100%;
  margin: 0 0 0.5rem 0;
  padding: 0 0 0.25rem 0;
}

/* ------------------------------------------------------------------------ */
/*   FORM FIELD GROUPS + VISUALLY-HIDDEN UTILITY                            */
/*   Radio / checkbox groups (Django RadioSelect / CheckboxSelectMultiple)  */
/*   are grouped in <fieldset class="field-group"><legend>. The reset       */
/*   strips the default fieldset border/padding and the min-content min-    */
/*   width that otherwise blows out grid/flex columns. A legend that        */
/*   replaces a former .form-columns visible <label> is restyled to match   */
/*   that label; legends that only name a group for assistive tech carry    */
/*   .visually-hidden so the page looks byte-identical.                     */
/* ------------------------------------------------------------------------ */

fieldset.field-group {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;
}

/* Two stacked groups (e.g. comma-conversion + weighted-fitting in the data
   editor) were formerly separate <p>s with a 1.5rem gap; the reset above
   zeroed that, merging them visually. Restore the gap between consecutive
   field groups (matches simple.css's `p { margin: 1.5rem 0 }`). */
fieldset.field-group + fieldset.field-group {
  margin-top: 1.5rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------------------ */
/*   FOOTER                                                                 */
/* ------------------------------------------------------------------------ */
body > footer {
  background-color: var(--accent-bg);
  color: var(--text);
  grid-column: 1 / -1;
  padding: 2rem 1rem 0 1rem;
  margin-bottom: 0;
}

body > footer .flex-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 1rem;
  width: 100%;
}

body > footer .centered {
  flex: 1 1 0;
  flex-grow: 1;
  text-align: center;
  width: fit-content;
}

body > footer .content-container {
  display: inline-block;
  flex-wrap: nowrap;
  text-align: left;
  text-wrap: none;
  white-space: nowrap;
}

.business-card {
  background-color: var(--bg);
}

footer > div:last-child {
  margin-top: 1rem;
}

/* ------------------------------------------------------------------------ */
/*   FIELD GRID                                                             */
/*   Two-column grid for label/input pairs. The label column sizes to the   */
/*   widest label (max-content), so input boxes line up at the same x       */
/*   position regardless of glyph-width differences between labels.         */
/* ------------------------------------------------------------------------ */

.field-grid {
  display: grid;
  gap: 0.25rem 0.5rem;
  grid-template-columns: max-content max-content;
  margin: 0.5rem 0;
}

.field-grid label {
  align-self: center;
}

/* ------------------------------------------------------------------------ */
/*   SERVER LOAD                                                            */
/*   Two-column name → value layout; values align in their own column.      */
/* ------------------------------------------------------------------------ */

.server-load {
  display: grid;
  grid-template-columns: max-content max-content;
  gap: 0 1rem;
}

.server-load dt,
.server-load dd {
  margin: 0;
}

.server-load dd {
  text-align: right;
}

/* ------------------------------------------------------------------------ */
/*   FORM TABLE                                                             */
/*   Strips simple.css's data-table chrome (borders, zebra striping) for    */
/*   tables that hold form inputs rather than presentation data. Use on     */
/*   coefficient-entry tables and similar tabular forms where the row ×     */
/*   column shape is real data structure but the heavy visual chrome would  */
/*   overwhelm small inputs and single-letter row labels.                   */
/* ------------------------------------------------------------------------ */

.form-table,
.form-table tr,
.form-table th,
.form-table td {
  background-color: transparent;
  border: none;
}

.form-table th {
  font-weight: 500;
  padding: 0.25rem 0.75rem;
}

.form-table td {
  padding: 0rem 0.75rem;
}

/* ------------------------------------------------------------------------ */
/*   RESULTS TABLE                                                          */
/*   List-of-results display where rows are separated by a horizontal line  */
/*   but columns have no vertical chrome. Used for the function-finder      */
/*   results page where each row is one ranked equation result, with plot   */
/*   images + statistics text in adjacent cells. The row-separator-only    */
/*   look reads as "card list" rather than "data grid."                     */
/* ------------------------------------------------------------------------ */

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

.results-table th,
.results-table td {
  background-color: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 0.5rem 0.75rem;
  vertical-align: top;
}

.results-table th {
  font-weight: 500;
}

.results-table img {
  height: auto;
  max-width: 100%;
}

.results-table h3 {
  margin-top: 1.5rem;
}

/* ------------------------------------------------------------------------ */
/*   STATS LIST                                                             */
/*   Two-column grid for <dl> lists of "metric label → numeric value"       */
/*   stats. Label column sizes to widest label (max-content) so values      */
/*   align in their own column for easy comparison row-to-row.              */
/* ------------------------------------------------------------------------ */

.stats-list {
  display: grid;
  gap: 0.25rem 0.5rem;
  grid-template-columns: max-content auto;
  margin: 0.5rem 0 1rem 0;
}

.stats-list dt,
.stats-list dd {
  margin: 0;
}

/* ------------------------------------------------------------------------ */
/*   SHOW/HIDE SYSTEM                                                       */
/*   .hideable is a marker class for the show/hide nav system; jQuery in    */
/*   generic_page_template.html toggles the .hidden class on these elements */
/*   based on dropdown selection.                                           */
/* ------------------------------------------------------------------------ */

.hidden {
  display: none;
}

/* ------------------------------------------------------------------------ */
/*   COPY BUTTONS ON <pre>                                                  */
/*   <pre> is itself a scroll container for long lines; positioning the     */
/*   button inside <pre> would make it drift with horizontal scroll.        */
/*   copy-code.js wraps each <pre> in a .pre-wrap div, and we position the  */
/*   button against that wrapper so the button stays fixed in the corner    */
/*   regardless of where the user has scrolled the <pre>'s content.        */
/* ------------------------------------------------------------------------ */
.pre-wrap {
  position: relative;
}

/* Injected by /static/copy-code.js. */
.pre-wrap .copy-btn {
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.25rem;
  color: var(--text-light);
  /* Match <pre> background + border so the button blends into the block;
     hover/focus brings the theme color in for affordance. */
  background: var(--accent-bg);
  border: var(--border-width) solid var(--border);
  border-radius: var(--standard-border-radius);
  cursor: pointer;
}

.pre-wrap .copy-btn:hover,
.pre-wrap .copy-btn:focus-visible {
  /* Hold the background -- simple.css's `button:enabled:hover` would
     otherwise repaint to var(--accent-hover) and the button would flash
     solid blue. Affordance comes from the icon + border tinting to the
     theme color. */
  background: var(--accent-bg);
  color: var(--accent-hover);
  border-color: var(--accent-hover);
}

/* ------------------------------------------------------------------------ */
/*   STATUS PAGE                                                            */
/*   Pulsing dot affordance next to the heading while a fit is in progress; */
/*   status card highlights the live currentStatus message.                 */
/* ------------------------------------------------------------------------ */

/* Flex layout on the heading gives reliable vertical centering between the
   dot and the heading text regardless of font metrics. Inline-only
   vertical-align values (middle, text-top) end up looking high or low at
   h2 scale because they snap to glyph-metric reference points, not the
   visual center of the text block. */
.working-heading {
  display: flex;
  align-items: center;
  gap: 0.4em;
}

.status-dot {
  display: inline-block;
  width: 0.6em;
  height: 0.6em;
  border-radius: 50%;
  background: var(--accent);
  animation: status-pulse 2s ease-in-out infinite;
  flex: 0 0 auto;
}

@keyframes status-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.1; }
}

@media (prefers-reduced-motion: reduce) {
  .status-dot { animation: none; }
}

/* The LRP writes server-side HTML into currentStatus (rendered inside
   the simple.css .notice block), sometimes including tables — e.g.
   FunctionFinder's per-family progress grid. simple.css's default
   table chrome (borders, padding, zebra) doubles up against the
   notice background and makes the block much taller than needed.
   Strip the chrome so the table reads as a flat compact list. */
.notice table,
.notice table tr,
.notice table th,
.notice table td {
  background: transparent;
  border: none;
}

.notice table {
  margin: 0;
}

.notice table th,
.notice table td {
  padding: 0.1rem 0.6rem;
}

.notice table td:first-child,
.notice table th:first-child {
  padding-left: 0;
}

/* ------------------------------------------------------------------------ */
/*   DEMO MODE WATERMARK                                                     */
/*   Active only under <body class="demo-mode"> (set by the base template    */
/*   when settings.DEMO_MODE is on). A faint repeating diagonal "DEMO" tile  */
/*   painted BEHIND the main content. `main` gets an explicit z-index so it  */
/*   establishes a stacking context, scoping the z-index:-1 overlay to sit   */
/*   behind main's own content but above its background box. The overlay is  */
/*   pointer-events:none so it never intercepts clicks or typing.            */
/* ------------------------------------------------------------------------ */
body.demo-mode main {
  position: relative;
  z-index: 0;
}

body.demo-mode main::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.08;
  background-repeat: repeat;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='240'%20height='160'%3E%3Ctext%20x='10'%20y='95'%20transform='rotate(-30%20120%2080)'%20font-family='Arial,sans-serif'%20font-size='44'%20font-weight='700'%20fill='%23000000'%3EDEMO%3C/text%3E%3C/svg%3E");
}
