/* viewer-chrome.css — shared CARO visual-companion viewer chrome (base).

   Canonical source: dme-shared/viewer/viewer-chrome.css. Byte-identical committed
   copy in each site/viewer/ (guarded by test-viewer-shared-assets.R). The layout,
   the controls, and every sidebar or figure component more than one piece uses.
   A piece's viewer-extra.css, loaded after this file, holds only what is its own:
   it may adjust a shared rule in context but never restate one, and no two pieces
   may declare the same rule (test-viewer-css-canon.R on the main site). Uses
   --cv-* tokens from caro-viewer-tokens-base.css and caro-viewer-tokens.css. */

:root {
  --cv-sidebar-width: 323px; /* canonical viewer sidebar (75% of legacy 430px) */
  --cv-viewer-layout-pad: 20px; /* matches .container padding */
  --cv-viewer-layout-gap: 20px; /* matches .container gap */
  --cv-viewer-stack-bp: 768px; /* sidebar stacks above canvas at or below this width */
  /* Floor for the ages table's scroll box, and its height where the table does not
     fill the column (stacked layout): what it measured before it was made to fill. */
  --cv-ages-table-min-height: 260px;
}

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

/* Every viewer is embedded in an iframe sized to its content: a 100vh floor and
   sidebar clamp would crop it, and flex overflow would crop the canvas. */
body {
  font-family: "Fira Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--cv-bg);
  min-height: auto;
  color: var(--cv-ink);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* Form controls don't inherit font-family/font-size from the page by default
   in browser UA stylesheets (.button already sets this for itself below;
   this covers every select/option/input/textarea a piece adds). */
button, input, select, textarea, optgroup {
  font-family: inherit;
  font-size: 100%;
}

/* Dropdowns: one look across every piece (was flux-only, in its viewer-extra.css). */
.profile-select {
  width: 100%;
  font-size: 14px;
  padding: 8px 10px;
  border: 1px solid var(--cv-border);
  border-radius: 4px;
  background: var(--cv-bg);
  color: var(--cv-ink);
  font-family: inherit;
}

.container { display: flex; width: 100%; max-width: 100%; min-height: auto; padding: 20px; gap: 20px; }

.sidebar {
  width: var(--cv-sidebar-width);
  flex-shrink: 0;
  background: var(--cv-surface);
  border: 1px solid var(--cv-border);
  padding: 26px;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(36, 36, 36, 0.06);
  overflow-y: auto;
  overflow-x: hidden;
  max-height: none;
}

.sidebar h1 {
  font-family: "Literata", Georgia, "Times New Roman", serif;
  font-size: 26px;
  font-weight: 600;
  margin-bottom: 8px;
}

.sidebar .subtitle {
  color: var(--cv-secondary);
  font-size: 14px;
  margin-bottom: 26px;
  line-height: 1.6;
}

.sidebar .subtitle em { font-style: italic; color: var(--cv-warm-text); }

.section-help {
  font-size: 13px;
  color: var(--cv-secondary);
  line-height: 1.55;
  margin: -6px 0 16px 0;
}

.section-help strong { color: var(--cv-ink); font-weight: 600; }
.section-help em { font-style: italic; color: var(--cv-warm-text); }

.control-section { margin-bottom: 26px; }

.control-section h3 {
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 10px;
}

.seed-input {
  width: 100%;
  background: var(--cv-bg);
  padding: 10px 12px;
  border-radius: 4px;
  font-family: "Spline Sans Mono", "Fira Sans", "SFMono-Regular", Consolas, monospace;
  font-size: 14px;
  margin-bottom: 10px;
  border: 1px solid var(--cv-border);
  text-align: center;
}

.seed-input:focus {
  outline: none;
  border-color: var(--cv-primary);
  box-shadow: 0 0 0 2px rgba(140, 29, 64, 0.10);
  background: var(--cv-surface);
}

.seed-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }

.caro-icon {
  width: 1em;
  height: 1em;
  fill: currentColor;
  vertical-align: -0.125em;
}

.button {
  background: var(--cv-ink);
  color: var(--cv-bg);
  border: none;
  padding: 9px 14px;
  border-radius: 4px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease;
  width: 100%;
}

.button:hover { background: color-mix(in srgb, var(--cv-ink) 88%, var(--cv-bg)); }

.button.secondary {
  background: transparent;
  color: var(--cv-ink);
  border: 1px solid var(--cv-border);
}

.button.secondary:hover { background: var(--cv-border); }

.button.active { background: var(--cv-primary); }
.button.active:hover { background: color-mix(in srgb, var(--cv-primary) 88%, var(--cv-ink)); }

.button-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }

.control-group { margin-bottom: 20px; }
.control-group label { display: block; font-size: 15px; font-weight: 500; margin-bottom: 8px; line-height: 1.4; }
/* A control's label: its title, and under it a line saying what it counts. */
.control-group label.control-label {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  margin-bottom: 8px;
  line-height: 1.35;
}
.control-group .label-title { font-size: 15px; font-weight: 500; color: var(--cv-ink); }
.control-group .label-sub {
  display: block;
  font-size: 12.5px;
  font-weight: 400;
  font-style: italic;
  color: var(--cv-secondary);
  line-height: 1.35;
  max-width: 100%;
}

.slider-container { display: flex; align-items: center; gap: 12px; }
.slider-container input[type="range"] {
  flex: 1;
  height: 4px;
  background: var(--cv-border);
  border-radius: 2px;
  outline: none;
  -webkit-appearance: none;
}
.slider-container input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px;
  height: 13px;
  background: var(--cv-primary);
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid var(--cv-bg);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--cv-primary) 35%, var(--cv-border));
}
.slider-container input[type="range"]::-moz-range-thumb {
  width: 13px;
  height: 13px;
  background: var(--cv-primary);
  border-radius: 50%;
  border: 2px solid var(--cv-bg);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--cv-primary) 35%, var(--cv-border));
  cursor: pointer;
}
/* The input draws no outline of its own (outline: none above), so keyboard focus
   rings the thumb instead; a mouse click shows nothing, as before. */
.slider-container input[type="range"]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px var(--cv-primary);
}
.slider-container input[type="range"]:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 3px var(--cv-primary);
}

.value-display {
  font-family: "Spline Sans Mono", "Fira Sans", monospace;
  font-size: 13.5px;
  font-weight: bold;
  color: var(--cv-ink);
  min-width: 58px;
  text-align: right;
}

.color-group { margin-bottom: 16px; }
.color-group label { display: block; font-size: 14px; margin-bottom: 6px; }
.color-picker-container { display: flex; align-items: center; gap: 10px; }
.color-picker-container input[type="color"] {
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  background: none;
  padding: 0;
}
.color-value { font-family: "Spline Sans Mono", "Fira Sans", monospace; font-size: 13px; color: var(--cv-secondary); }

.divider { border: none; border-top: 1px solid var(--cv-border); margin: 4px 0 22px; }

.canvas-area { flex: 1 1 auto; min-width: 0; overflow: visible; display: flex; align-items: flex-start; justify-content: center; }
/* A piece that wraps its figure (and any identity line or table) in one block:
   as a flex item that block would shrink to the canvas's intrinsic size instead
   of filling the column. */
.canvas-area > div { width: 100%; min-width: 0; }
#canvas-container canvas {
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(36, 36, 36, 0.08);
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
}

.loading { color: var(--cv-secondary); font-size: 14px; padding: 40px; }

/* ---- Figure holder -------------------------------------------------------- */

#viewer-canvas-holder { width: 100%; max-width: 100%; }
#viewer-canvas-holder canvas { display: block; width: 100%; height: auto; }

/* ---- Sidebar readouts ------------------------------------------------------
   A panel of boxed statistic badges, and rows of labelled values with a colour
   key. Tints come from color-mix() over --cv-* tokens. */

.stat-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* A piece may stretch the panel from script: an inline height may only ever
     enlarge it, never compress the badges below their content. */
  min-height: max-content;
  padding: 12px;
  background: color-mix(in srgb, var(--cv-border) 22%, var(--cv-bg));
  border: 1px solid var(--cv-border);
  border-radius: 6px;
}

.stat-badge {
  /* Grow to share a stretched panel's extra space, never shrink below content. */
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--cv-surface);
  border-radius: 5px;
  padding: 10px 12px;
  border: 1px solid var(--cv-border);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--cv-ink) 4%, transparent);
}

.stat-badge .stat-label {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--cv-secondary);
  line-height: 1.35;
}

.stat-badge .stat-value {
  margin-top: 4px;
  line-height: 1.3;
}

.stat-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 12.5px;
  margin-bottom: 6px;
}

.stat-label { display: flex; align-items: center; gap: 7px; color: var(--cv-secondary); }
.swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.rule { width: 12px; height: 0; border-top: 2px dashed var(--cv-answer); flex: none; }

.stat-value {
  font-family: "Spline Sans Mono", "Fira Sans", monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The headline figure: Literata, the answer's colour. Two classes, so the serif
   wins over .stat-value's mono whatever the rule order: with one class the later
   .stat-value rule took the face, and the serif two pieces declared never showed. */
.stat-value.headline-num {
  font-family: "Literata", Georgia, serif;
  font-size: 19px;
  font-weight: 600;
  color: var(--cv-answer);
  font-variant-numeric: tabular-nums;
}

.stat-unit {
  font-family: "Fira Sans", sans-serif;
  font-size: 12px;
  font-weight: 400;
  color: var(--cv-secondary);
  margin-left: 4px;
}

/* A framed one-line readout above the badges: how far the replacement has
   reached, or the period clock. */
.readout {
  font-family: "Spline Sans Mono", "Fira Sans", monospace;
  font-size: 12px;
  font-weight: 600;
  text-align: center;
  background: var(--cv-bg);
  color: var(--cv-secondary);
  border: 1px solid var(--cv-border);
  padding: 6px 10px;
  border-radius: 4px;
  margin-bottom: 10px;
  letter-spacing: 0.06em;
  white-space: nowrap;
  overflow: hidden;
}

.readout .readout-value { color: var(--cv-ink); font-weight: 600; }

/* ---- Pair picker: a reference and a comparison, each a row of selects ------ */

.pair-label { display: block; margin-bottom: 6px; }
.pair-selects { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.pair-selects .profile-select { min-width: 0; }
#snap-note:empty { display: none; }

/* ---- Under the figure: the identity line and the ages table ---------------- */

.identity {
  margin-top: 11px;
  padding: 8px 11px;
  border: 1px solid var(--cv-border);
  border-radius: 3px;
  font-family: "Spline Sans Mono", "Fira Sans", monospace;
  font-size: 11.5px;
  color: var(--cv-secondary);
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-wrap: wrap;
  gap: 3px 15px;
}

.identity b { color: var(--cv-ink); font-weight: 500; }

.ages-table { margin-top: 10px; font-size: 12px; }
.ages-table summary { cursor: pointer; color: var(--cv-secondary); }

.ages-table-wrap {
  max-height: var(--cv-ages-table-min-height);
  overflow: auto;
  margin-top: 8px;
  border: 1px solid var(--cv-border);
  border-radius: 3px;
}

.ages-table table {
  border-collapse: collapse;
  width: 100%;
  font-family: "Spline Sans Mono", "Fira Sans", monospace;
  font-variant-numeric: tabular-nums;
}

.ages-table th,
.ages-table td {
  padding: 3px 8px;
  text-align: right;
  border-bottom: 1px solid var(--cv-border);
}

/* The row label never wraps: an age or a cause reads as one unit. */
.ages-table th:first-child,
.ages-table td:first-child {
  text-align: left;
  white-space: nowrap;
}

.ages-table th {
  position: sticky;
  top: 0;
  background: var(--cv-bg);
  color: var(--cv-secondary);
  font-weight: 500;
}

/* Stacked mobile layout, touch targets (48px satisfies Apple 44pt + Google 48dp),
   CLS reservation, and control touch-action. Desktop layout unchanged above the breakpoint. */
@media (max-width: 768px) {
  .container { flex-direction: column; }
  .sidebar { width: 100%; }
  .canvas-area { width: 100%; }
  #canvas-container { aspect-ratio: var(--cv-canvas-aspect, auto); width: 100%; }

  .button { min-height: 48px; }
  .slider-container input[type="range"] {
    height: 48px;
    background: transparent;
    touch-action: manipulation;
  }
  /* The 48px input is transparent, so the track draws the line the desktop
     input draws itself; the thumb is re-centred on it. */
  .slider-container input[type="range"]::-webkit-slider-runnable-track {
    height: 4px;
    background: var(--cv-border);
    border-radius: 2px;
  }
  .slider-container input[type="range"]::-webkit-slider-thumb { margin-top: -6.5px; }
  .slider-container input[type="range"]::-moz-range-track {
    height: 4px;
    background: var(--cv-border);
    border-radius: 2px;
  }
  .profile-select { min-height: 48px; }
  .button,
  .profile-select { touch-action: manipulation; }
}

/* The ages table fills the column beside the figure instead of stopping at a
   fixed height: stretching the column and letting the scroll box take the slack
   is right at every size, where any fixed height is right at one. Only a column
   that holds an ages table (:has), only when the table is open (a collapsed
   <details> must not stretch), and only on the desktop layout (stacked, the
   cross axis is width and a grown box has no height to resolve against). */
@media (min-width: 769px) {
  .canvas-area:has(> div > .ages-table) { align-items: stretch; }

  .canvas-area > div:has(> .ages-table) {
    display: flex;
    flex-direction: column;
  }

  /* The figure and the identity line keep their own height; only the table flexes. */
  .canvas-area > div:has(> .ages-table) > #viewer-canvas-holder,
  .canvas-area > div:has(> .ages-table) > .identity { flex: none; }

  /* flex-basis 0 with min-height 0: with an auto basis or an auto minimum the
     table's own content height (every row) becomes the column's, the sidebar
     stretches to match, and no scroll box is left. The floor lives on the scroll
     box below, where overflow keeps it from propagating. */
  .ages-table[open] {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  .ages-table[open] > summary { flex: none; }

  /* Chrome interposes a ::details-content box between <details> and its children;
     making it a flex column too passes the height through. Its own rule: an engine
     that does not know the pseudo-element drops the whole rule it appears in, and
     there the children are direct flex items already. */
  .ages-table[open]::details-content {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  .ages-table[open] > .ages-table-wrap {
    flex: 1 1 0;
    min-height: var(--cv-ages-table-min-height);
    max-height: none;
  }
}
