/* The Airfoil tool (docs/plan_airfoil_ui_v1.md, the window of
   docs/plan_airfoil_ui.md section 3): the canvas takes the whole window, and
   every box floats over it, translucent (the HUD, CLAUDE.md 8.5), so the
   canvas never reflows when a box opens or closes. Only the boxes take the
   mouse; everything else reaches the canvas. The page's own file: nothing
   here is shared with the design app's web/style.css. */

:root {
  color-scheme: only light;    /* see airfoils.html: no forced dark mode */
  --hud-alpha: 0.55;           /* the boxes' transparency (the View box sets it) */
  --ink: #1d2a38;
  --ink-quiet: #4a5866;
  --accent: #2f6fe0;
  --canvas-bg: #cfd4da;        /* the three.js scene's own background */
  --box-border: rgba(29, 42, 56, 0.14);
  --left-width: 220px;
  --gutter: 12px;
  --header-height: 40px;
  --strip-height: 30px;
}

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--canvas-bg);
  color: var(--ink);
  font: 13px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

#at-canvas-host {
  position: fixed;
  inset: 0;
  background: var(--canvas-bg);  /* the three.js canvas is transparent over it */
}
#at-canvas-host canvas {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}
#at-canvas-host .at-layer {
  pointer-events: none;
}

/* A box: light, translucent, the canvas visible through it; a low blur keeps
   the curve under it readable. Text and controls stay opaque. */
.at-box, #at-header {
  background: rgba(255, 255, 255, var(--hud-alpha));
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  border: 1px solid var(--box-border);
}

#at-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--header-height);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
  border-width: 0 0 1px 0;
}
.at-brand {
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}
.at-brand:hover {
  text-decoration: underline;
}
.at-sep {
  color: var(--ink-quiet);
}

#at-left {
  position: fixed;
  top: calc(var(--header-height) + var(--gutter));
  left: var(--gutter);
  width: var(--left-width);
  max-height: calc(100% - var(--header-height) - 2 * var(--gutter) - 64px);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.at-box {
  border-radius: 8px;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.at-box-title {
  margin: 0;
  padding: 8px 12px 4px;
  font-size: 12px;
  font-weight: 600;
}
.at-box-body {
  padding: 0 4px 8px;
  min-height: 0;
  overflow: auto;
}

.at-library {
  list-style: none;
  margin: 0;
  padding: 0;
}
.at-library button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 4px 8px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.at-library button:hover {
  background: rgba(47, 111, 224, 0.10);
}
.at-library button.current {
  background: rgba(47, 111, 224, 0.18);
  font-weight: 600;
}
.at-lib-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.at-lib-value {
  color: var(--ink-quiet);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.at-lib-mark {
  color: #8a6d3b;
  font-size: 11px;
}

.at-button {
  align-self: flex-start;
  padding: 4px 12px;
  border: 1px solid var(--box-border);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.85);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}
.at-button:hover {
  border-color: var(--accent);
}
/* Busy: waiting for the server (Remove point's re-fit). */
.at-button[aria-busy="true"] {
  cursor: progress;
  opacity: 0.6;
}

/* Words over the canvas, outside any box: a light halo keeps them readable
   over the fill and the grid. They take no pointer events. */
.at-hud-text {
  pointer-events: none;
  text-shadow: 0 0 3px rgba(255, 255, 255, 0.9), 0 0 1px rgba(255, 255, 255, 0.9);
}

/* The top strip: tabs in a row right of the left column, each box opening
   downward over the canvas. Only the tabs and an open box take the mouse. */
#at-strip {
  position: fixed;
  top: calc(var(--header-height) + var(--gutter));
  left: calc(var(--left-width) + 3 * var(--gutter));
  right: var(--gutter);
  height: var(--strip-height);
  display: flex;
  gap: 6px;
  pointer-events: none;
}
.at-strip-item {
  position: relative;
  pointer-events: auto;
}
.at-tab {
  height: var(--strip-height);
  padding: 0 14px;
  border: 1px solid var(--box-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, var(--hud-alpha));
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.at-tab[aria-expanded="true"] {
  border-color: var(--accent);
}
.at-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 240px;
  padding-top: 8px;
}
.at-panel[hidden] {
  display: none;
}
/* A box's "?": its section of the help page, shaper.xyz/help/airfoil-tool/
   (D-053), in a new tab; top right of the box, in a band of its own so it
   never covers a row, or at the right of the Library's title. */
.at-panel {
  padding-top: 26px;
}
.at-help {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 18px;
  height: 18px;
  border: 1px solid var(--box-border);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85);
  color: var(--ink-quiet);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  text-align: center;
  text-decoration: none;
}
.at-help:hover {
  color: var(--ink);
  border-color: var(--ink-quiet);
}
.at-acc {
  position: relative;
}
.at-help-acc {
  top: 7px;
}
.at-field-title {
  margin: 0 8px 4px;
  font-size: 12px;
  font-weight: 600;
}
.at-check, .at-field {
  display: block;
  margin: 2px 8px;
}
.at-field {
  margin-top: 8px;
}
.at-field select, .at-field input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-top: 2px;
  font: inherit;
}

/* The airfoil's name: the last item of the header's breadcrumb, larger and
   heavier, cut with an ellipsis when long (the full name on hover). */
#at-name {
  min-width: 0;
  flex: 0 1 auto;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* A number on the geometry with no clear spot beside an open box: a small
   opaque chip over the box (page.js showChips; UI-10). */
.at-chips {
  position: fixed;
  inset: 0;
  pointer-events: none;
}
.at-chip {
  position: absolute;
  box-sizing: border-box;
  height: 14px;
  padding: 0 3px;
  margin-left: -3px;
  background: #ffffff;
  border: 1px solid rgba(29, 42, 56, 0.35);
  border-radius: 3px;
  font: 12px/12px system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  white-space: nowrap;
}
.at-chip-coords {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

/* The results line and the status line, at the foot of the canvas. */
#at-bottom {
  position: fixed;
  left: calc(var(--left-width) + 3 * var(--gutter));
  right: var(--gutter);
  bottom: var(--gutter);
  display: flex;
  flex-direction: column;
  gap: 4px;
  pointer-events: none;
}
/* The results line is a box of its own, never empty ("Loading..." until the
   first airfoil), so it always reads at load and the standard zoom measures
   it the same before and after. */
#at-results {
  display: block;              /* one line of words that wraps, not a column of boxes */
  align-self: flex-start;
  max-width: 100%;
  box-sizing: border-box;
  padding: 6px 12px;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
/* The legend of the analysis curves: a swatch and a name each, a toggle. */
#at-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
}
.at-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 1px 2px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  pointer-events: auto;
  text-shadow: 0 0 3px rgba(255, 255, 255, 0.9);
}
.at-legend-item[aria-pressed="false"] {
  opacity: 0.45;
  text-decoration: line-through;
}
.at-swatch {
  display: inline-block;
  width: 18px;
  height: 3px;
  border-radius: 2px;
}

/* The status: one line at a fixed height; a longer one ends in an
   ellipsis, the whole of it on hover (setStatus sets the title). */
#at-status {
  height: var(--status-line);
  line-height: var(--status-line);
  font-size: 12px;
  color: var(--ink-quiet);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- the header's right side, and its buttons ---- */
/* No box of its own: Guide, the account and ? are items of the header, so
   the header's own shrinking cuts the airfoil's and the account's names
   (both min-width 0) and never Guide or ?. A nested flex box shrank as one
   item: a guest's short "Sign in" let ? out past the edge, a long account
   name kept the whole group from shrinking (UI-28). */
.at-header-right {
  display: contents;
}
.at-header-right > :first-child {
  margin-left: auto;
}
.at-header-button {
  height: 26px;
  min-width: 26px;
  padding: 0 8px;
  border: 1px solid var(--box-border);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.85);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
#at-menu {
  display: none;               /* small screens only */
}
/* On a narrow header only the names give way, the airfoil's and the
   account's, each cut with an ellipsis; Menu, the brand, Guide and ? keep
   their width (a squeezed Menu ran its text into Shaper.xyz on a phone, and
   a long account name pushed ? off the screen). */
#at-menu, .at-brand, .at-sep, .at-header-link, #at-keys-open {
  flex-shrink: 0;
}
#at-header-account {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#at-header-account a,
.at-header-link {
  color: var(--ink);
}

/* ---- the left column's boxes: one open at a time ---- */
.at-acc-title {
  display: block;
  width: 100%;
  margin: 0;
  padding: 8px 12px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.at-acc-title::after {
  content: " +";
  color: var(--ink-quiet);
}
.at-acc-title[aria-expanded="true"]::after {
  content: " -";
}
.at-box-body[hidden] {
  display: none;
}
.at-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 8px;
  margin: 0 8px;
}
.at-facts dt {
  color: var(--ink-quiet);
}
.at-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}
.at-credit, .at-text {
  margin: 6px 8px 0;
  font-size: 12px;
  overflow-wrap: anywhere;
}
.at-credit a, .at-text a {
  color: var(--ink);
}
.at-search {
  display: block;
  width: calc(100% - 16px);
  box-sizing: border-box;
  margin: 0 8px 6px;
  padding: 3px 6px;
  border: 1px solid var(--box-border);
  border-radius: 4px;
  font: inherit;
}
.at-lib-thumb {
  flex: none;
  width: 48px;
  height: 14px;
}
.at-full-library {
  display: block;
  margin-top: 6px;
  font-size: 12px;
}

.at-compare {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.at-compare-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.at-compare-list li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
}

.at-compare-list i {
  width: 16px;
  border-top: 2px dashed;
}

.at-compare-list span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.at-compare-remove {
  border: 0;
  background: transparent;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0 4px;
}

.at-library .at-empty {
  padding: 4px 8px;
  color: var(--ink-quiet);
}

/* ---- tables and fields in the boxes ---- */
.at-table {
  border-collapse: collapse;
  margin: 0 8px;
}
.at-table th {
  padding: 2px 10px 2px 0;
  font-weight: normal;
  color: var(--ink-quiet);
  text-align: left;
  white-space: nowrap;
}
.at-table td {
  padding: 2px 6px 2px 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.at-num {
  width: 64px;
  padding: 1px 4px;
  border: 1px solid var(--box-border);
  border-radius: 4px;
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.at-quiet {
  color: var(--ink-quiet);
}
.at-note {
  max-width: 300px;
  margin: 6px 8px 0;
  font-size: 11px;
  color: var(--ink-quiet);
}
.at-row {
  margin: 0 8px 6px;
}
.at-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 8px;
}
.at-button[aria-pressed="true"] {
  border-color: #ff5050;
}
.at-table-scroll {
  max-height: 40vh;
  margin-top: 8px;
  overflow: auto;
}
.at-row-unlink {
  margin-left: 4px;
  padding: 0 5px;
  border: 1px solid var(--box-border);
  border-radius: 4px;
  background: transparent;
  font-size: 11px;
  cursor: pointer;
}

.at-points tbody tr {
  cursor: pointer;
}
.at-points tbody tr:hover {
  background: rgba(47, 111, 224, 0.08);
}
.at-points tbody tr.selected {
  background: rgba(255, 176, 32, 0.35);
}

/* ---- the foot: the status line and the credits ---- */
/* The foot at a fixed height (UI-24): the status on one line, the credit
   below it on up to --credit-lines lines. A text that changes - a status, a
   longer credit after an edit ("based on ... by ...") - never changes the
   bottom panel's height, so the view never refits for it (it did: the
   airfoil moved 6.3 px after the first edit of a library airfoil). The
   credit is never cut: for a UIUC-derived airfoil it is a condition of the
   permission, so it wraps, fully readable, inside its lines. */
#at-foot {
  --status-line: 17px;
  --credit-line: 15px;
  --credit-lines: 2;
  display: flex;
  flex-direction: column;
  gap: 2px;
  height: calc(var(--status-line) + 2px + var(--credit-lines) * var(--credit-line));
}
#at-footer {
  height: calc(var(--credit-lines) * var(--credit-line));
  line-height: var(--credit-line);
  font-size: 11px;
  color: var(--ink-quiet);
  text-shadow: 0 0 3px rgba(255, 255, 255, 0.9);
}
#at-footer a {
  color: var(--ink-quiet);
  pointer-events: auto;
}

/* ---- the key list ---- */
#at-keys {
  position: fixed;
  top: calc(var(--header-height) + var(--gutter));
  right: var(--gutter);
  padding-bottom: 8px;
  background: rgba(255, 255, 255, 0.92);
}
#at-keys[hidden] {
  display: none;
}

/* ---- clean canvas (Tab): the boxes, the results, the legend and the curves
   go; the name, the airfoil and the status line stay ---- */
body.at-clean #at-strip,
body.at-clean #at-left,
body.at-clean #at-legend,
body.at-clean #at-results,
body.at-clean #at-footer {
  display: none;
}

/* ---- smaller windows: the boxes shrink ---- */
@media (max-width: 1000px) {
  :root {
    --left-width: 180px;
  }
}

/* ---- a phone: the airfoil and its numbers; the boxes behind Menu ---- */
@media (max-width: 640px) {
  :root {
    --left-width: 0px;
  }
  #at-menu {
    display: inline-block;
  }
  #at-left, #at-strip, .at-page-title, .at-sep {
    display: none;
  }
  .at-sep-name {
    display: inline;
  }
  body.at-menu-open #at-left {
    display: flex;
    left: var(--gutter);
    width: min(260px, calc(100% - 2 * var(--gutter)));
    z-index: 2;
  }
  body.at-menu-open #at-left .at-box {
    background: rgba(255, 255, 255, 0.95);
  }
  #at-bottom {
    left: var(--gutter);
  }
  #at-results {
    font-size: 12px;
  }
  #at-canvas-host canvas {
    touch-action: none;
  }
}

/* A value with a hover note (the camber's, from the chord line). */
.at-noted {
  cursor: help;
}
#at-results-camber {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  pointer-events: auto;
}

/* ---- the Airfoil box's actions and the admin's Save as new ---- */
.at-air-actions {
  margin-top: 8px;
}
.at-save[hidden] {
  display: none;
}
.at-save .at-field input {
  padding: 2px 4px;
  border: 1px solid var(--box-border);
  border-radius: 4px;
}
#at-link {
  padding: 2px 4px;
  border: 1px solid var(--box-border);
  border-radius: 4px;
  color: var(--ink-quiet);
}
