:root {
  --serif: "EB Garamond", Garamond, "Hoefler Text", "Iowan Old Style", Georgia, serif;
  --mono: "SF Mono", ui-monospace, Menlo, monospace;

  /* The two faces of polariscollective.org: Spectral where the page announces
     itself, Inter everywhere the interface speaks in its own voice.

     `--reader` is deliberately not either of them. The spec text is the one
     thing on this page that is neither chrome nor brand, and EB Garamond was
     chosen for it — a long document read for an hour at a time. Restyling the
     tool is no reason to restyle the document it exists to show. */
  --display: "Spectral", Georgia, "Times New Roman", serif;
  --ui: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --reader: var(--serif);

  /* The chrome's two heights, stated once. `.app-shell` subtracts both to fill
     what is left, and got them wrong the moment a footer appeared under a
     hardcoded `calc(100vh - 54px)`. */
  --header-height: 54px;
  --footer-height: 30px;
  /* What the menu leaves behind when it folds: enough for the button that
     brings it back, and nothing else. */
  --sidebar-rail: 40px;
}

body[data-palette="daylight"] {
  --chrome: #EDE6D6;
  --chrome-deep: #E5DCCB;
  --paper: #F8F3E7;
  --ink: #26221A;
  --muted: #5C564A;
  --faint: #8A8272;
  --line: #D8CEBA;
  --line-light: #E4DCCB;
  /* Polaris olive, the exact accent of polariscollective.org. White clears
     4.5:1 on it, which the toggles below rely on. */
  --accent: #5F6B3A;
  --accent-soft: #E1E6CB;
  --on-accent: #FFFFFF;
  --adjacent-mark: #8A5F14;
  --focus: #A93732;
  --gap-soft: #F1DEDA;
  --shadow: rgba(90, 75, 50, .25);

  /* One colour per behaviour, deep enough to read as a wash over cream paper. */
  --hue-1: 74 83 179;
  --hue-2: 176 84 48;
  --hue-3: 31 116 110;
  --hue-4: 160 110 20;
  --hue-5: 129 62 129;
  --hue-6: 95 122 47;
  --hue-7: 62 106 158;
  --hue-8: 165 56 74;
  --hue-9: 123 96 45;
  --hue-10: 44 128 150;
  --hue-11: 44 106 74;
  --hue-12: 146 92 116;

  /* How much of that colour a passage carries: core at full strength, related thinned,
     -strong for the passage the reader is standing on. */
  --tint-core: .21;
  --tint-related: .085;
  --tint-core-strong: .34;
  --tint-related-strong: .19;
  --rule-core: .85;
  --rule-related: .38;

}

body[data-palette="umber"] {
  --chrome: #1A1510;
  --chrome-deep: #211B14;
  --paper: #262017;
  --ink: #EDE5D3;
  --muted: #ABA08D;
  --faint: #6F6659;
  --line: #332B21;
  --line-light: #3D3428;
  /* The olive has nothing to stand against on the umber ground, so it
     lightens — the same substitution evals-playground makes on its dark
     panels. Light enough that what sits *on* it must now be dark: hence
     `--on-accent`, which is why the toggles no longer say `white`. */
  --accent: #B2BD8B;
  --accent-soft: #3D4526;
  --on-accent: #211F1B;
  --adjacent-mark: #BC8A2F;
  --focus: #C95550;
  --gap-soft: #3A2420;
  --shadow: rgba(0, 0, 0, .5);

  /* The same twelve, lifted so they read as light laid on a dark surface. */
  --hue-1: 139 148 236;
  --hue-2: 226 141 100;
  --hue-3: 106 196 186;
  --hue-4: 224 179 82;
  --hue-5: 206 145 206;
  --hue-6: 170 197 110;
  --hue-7: 130 175 226;
  --hue-8: 230 130 146;
  --hue-9: 205 176 116;
  --hue-10: 120 200 220;
  --hue-11: 120 200 160;
  --hue-12: 220 160 185;

  --tint-core: .22;
  --tint-related: .095;
  --tint-core-strong: .34;
  --tint-related-strong: .2;
  --rule-core: .9;
  --rule-related: .4;

}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--chrome);
  color: var(--ink);
  font-family: var(--ui);
  /* 14px, not the 15px this carried under EB Garamond. Inter has much the
     larger x-height: kept at 15 it reads a size bigger and the sidebar, which
     is dense and fixed-width, stops fitting. */
  font-size: 14px;
  overflow: hidden;
}

button, a { -webkit-tap-highlight-color: transparent; }
button { font: inherit; }

.skip-link {
  position: fixed;
  z-index: 100;
  top: 8px;
  left: 8px;
  padding: 9px 13px;
  background: var(--ink);
  /* Not `white`: `--ink` is the cream #EDE5D3 under the umber palette, and the
     link — the one affordance a keyboard user meets first — was white on it. */
  color: var(--chrome);
  transform: translateY(-150%);
}

.skip-link:focus { transform: none; }

.site-header {
  height: var(--header-height);
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--line);
  background: var(--chrome);
}

/* Aligned on the baseline, not on the boxes. The wordmark is small-caps at
   16px and the collective's name ordinary text at 15px: centred, their boxes
   line up while their letters do not, and the wordmark rides visibly low. The
   star and the rule are not text and keep to the centre. */
.site-brand {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

/* The collective's star, from the header of polariscollective.org. It carries
   the accent while the wordmark keeps the ink: the star says whose site this
   is, the wordmark says what it is. */
.polaris-star {
  width: 13px;
  height: 13px;
  flex: none;
  align-self: center;
  color: var(--accent);
}

/* The star, the collective's name, a rule, then what the site is — the same
   three pieces in the same order as the bar of evals-playground. One
   difference: there the pair is deliberately not a link, that application
   having nowhere else to go. Here it leaves for polariscollective.org, which
   is somewhere else. */
.collective {
  color: var(--accent);
  text-decoration: none;
  font-family: var(--display);
  font-size: 15px;
  white-space: nowrap;
}

.collective:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.brand-divider {
  width: 1px;
  height: 15px;
  flex: none;
  align-self: center;
  background: var(--line);
}

.wordmark {
  font-family: var(--display);
  color: var(--ink);
  text-decoration: none;
  font-size: 16px;
  font-weight: 600;
  font-variant-caps: all-small-caps;
  letter-spacing: .18em;
}

.site-header nav { display: flex; align-items: center; gap: 24px; }
.site-header nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 14px;
  font-variant-caps: all-small-caps;
  letter-spacing: .1em;
}
.site-header nav a:hover,
.site-header nav a.active { color: var(--ink); }
.site-header nav a.active { text-decoration: underline; text-underline-offset: 6px; }
.mode {
  padding: 4px 6px;
  border: 0;
  background: transparent;
  color: var(--faint);
  font-family: var(--serif);
  font-size: 17px;
  cursor: pointer;
}
.mode:hover { color: var(--ink); }

.app-shell {
  --sidebar-width: 292px;
  height: calc(100vh - var(--header-height) - var(--footer-height));
  display: grid;
  grid-template-columns: var(--sidebar-width) 9px minmax(0, 1fr);
}

/* Where the project came from, and who runs it now. One slim bar: this is a
   full-height application, and every pixel here is a pixel of spec text not
   shown. */
.site-footer {
  height: var(--footer-height);
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-top: 1px solid var(--line);
  background: var(--chrome);
  color: var(--faint);
  font-size: 12px;
}

.site-footer a {
  color: var(--muted);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

body.embedded .skip-link,
body.embedded .site-header,
body.embedded .site-footer,
body.embedded .sidebar-toggle,
body.embedded .behaviour-sidebar {
  display: none;
}

body.embedded .sidebar-resizer {
  display: none;
}

body.embedded .app-shell {
  height: 100vh;
  height: 100dvh;
  grid-template-columns: minmax(0, 1fr);
}

body.embedded .reader-toolbar {
  min-height: 62px;
}

.behaviour-sidebar {
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--chrome);
}

.column-resizer {
  position: relative;
  z-index: 4;
  width: 9px;
  min-width: 9px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: col-resize;
  touch-action: none;
}
.column-resizer::before {
  content: "";
  position: absolute;
  inset: 0 4px;
  background: var(--line);
  transition: inset .12s ease, background-color .12s ease;
}
.column-resizer:hover::before,
.column-resizer:focus-visible::before,
.column-resizer.dragging::before {
  inset-right: 3px;
  inset-left: 3px;
  background: var(--accent);
}
.column-resizer::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 3px;
  height: 34px;
  border-top: 1px solid var(--paper);
  border-bottom: 1px solid var(--paper);
  opacity: 0;
  transform: translate(-50%, -50%);
}
.column-resizer:hover::after,
.column-resizer:focus-visible::after,
.column-resizer.dragging::after { opacity: .72; }
body.resizing-columns {
  cursor: col-resize;
  user-select: none;
}

/* The reader's name and nothing else. What this surface is for belongs in the
   note that sends a reviewer here, not standing over the menu they came to use --
   the sidebar's whole height is worth more as behaviours than as an explanation read once. */
.sidebar-intro {
  padding: 15px 25px 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  border-bottom: 1px solid var(--line);
}
.eyebrow {
  margin: 0;
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.behaviour-toolbar {
  padding: 10px 25px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  border-bottom: 1px solid var(--line-light);
  color: var(--muted);
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.behaviour-toolbar[hidden] { display: none; }
.behaviour-toolbar-actions { display: inline-flex; gap: 4px; }
.behaviour-toolbar-actions button {
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
}
.behaviour-toolbar-actions button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.behaviour-toolbar-actions button:disabled { opacity: .4; cursor: default; }

.behaviour-list { flex: 1; min-height: 0; overflow: auto; padding: 8px 0 18px; }
.behaviour-group { border-bottom: 1px solid var(--line-light); }
.behaviour-group h2 {
  margin: 0;
  padding: 15px 25px 7px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  line-height: 1.35;
  text-transform: uppercase;
}
.behaviour-group ul { list-style: none; margin: 0; padding: 0 10px 10px; }
.behaviour-option {
  position: relative;
  width: 100%;
  min-height: 34px;
  padding: 7px 12px 7px 12px;
  display: flex;
  gap: 9px;
  align-items: baseline;
  border-radius: 5px;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.behaviour-option:hover { background: var(--chrome-deep); }
.behaviour-option.checked {
  background: var(--paper);
  box-shadow: inset 3px 0 0 rgb(var(--bh) / var(--rule-core));
}
.behaviour-check {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.behaviour-box {
  width: 12px;
  height: 12px;
  flex: none;
  align-self: center;
  border: 1px solid var(--faint);
  border-radius: 3px;
  background: transparent;
}
.behaviour-option:hover .behaviour-box { border-color: rgb(var(--bh) / var(--rule-core)); }
.behaviour-option.checked .behaviour-box {
  position: relative;
  border-color: rgb(var(--bh) / var(--rule-core));
  background: rgb(var(--bh) / var(--rule-core));
}
.behaviour-option.checked .behaviour-box::after {
  content: "";
  position: absolute;
  top: 1px;
  left: 3.5px;
  width: 3px;
  height: 6px;
  border: solid var(--paper);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(42deg);
}
.behaviour-check:focus-visible + .behaviour-box {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
/* A stippled group is marked in the menu as well as in the text: its heading rule and the
   selected row's spine are broken the same way the passage's margin rule is, so the group
   reads as a different kind of row before a spec is even open. */
.behaviour-group.texture-stipple h2 {
  display: flex;
  align-items: center;
  gap: 7px;
}
.behaviour-group.texture-stipple h2::after {
  content: "";
  height: 3px;
  flex: 1;
  border-radius: 2px;
  background-image: repeating-linear-gradient(
    to right, currentColor 0 3px, transparent 3px 6px);
  opacity: .45;
}
.behaviour-option.texture-stipple.checked {
  background-image: repeating-linear-gradient(
    to bottom, rgb(var(--bh) / var(--rule-core)) 0 3px, transparent 3px 6px);
  background-size: 3px 100%;
  background-position: 0 0;
  background-repeat: no-repeat;
  box-shadow: none;
}
.behaviour-option .number {
  width: 20px;
  flex: none;
  color: var(--faint);
  font-family: var(--reader);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.behaviour-option .name { flex: 1; font-size: 12px; line-height: 1.35; }
.behaviour-option.checked .name { color: var(--ink); }

/* The export sits at the foot of the menu rather than in the toolbar at its head: it acts on
   the ticked set, so it reads as the end of the list it takes away and not as a third control
   beside All and None. The line under it counts what would come out, so the reader knows what
   they are asking for before the file lands. */
.sidebar-export {
  padding: 12px 22px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-top: 1px solid var(--line);
}
.download-passages {
  width: 100%;
  padding: 7px 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--chrome-deep);
  color: var(--ink);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
}
.download-passages:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--paper);
}
.download-passages:disabled { opacity: .4; cursor: default; }
.download-hint {
  color: var(--muted);
  font-size: 10px;
  line-height: 1.4;
  text-align: center;
}

.sidebar-key {
  padding: 12px 22px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 13px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 10px;
}
/* Each entry opens a note saying what the mark means and what the judge was
   asked for it. Buttons rather than the spans they were: the thing is clickable
   and reachable by keyboard, and only a button says both. */
.key-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 4px;
  margin: -2px -4px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.key-item:hover { background: var(--chrome-deep); color: var(--ink); }
.key-item:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }

/* The note. `position: fixed` with the corner set from the button it belongs to:
   a popover lands in the top layer, where the browser's own centring would put
   it in the middle of the window rather than beside what was clicked. */
.key-note {
  position: fixed;
  inset: auto;
  width: min(360px, calc(100vw - 32px));
  max-height: min(70vh, 520px);
  overflow: auto;
  padding: 16px 18px 18px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 14px 40px var(--shadow);
}

.key-note::backdrop { background: transparent; }

.key-note-title {
  margin: 0 0 10px;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 600;
}

.key-note-body { font-size: 13px; line-height: 1.55; }
.key-note-body p { margin: 0 0 10px; }
.key-note-body p:last-child { margin-bottom: 0; }

/* The two halves of every note: what the judge was asked, and what the reader
   draws from the answers. They are not the same thing, and the whole point of
   the note is that they are told apart. */
.key-note-body h3 {
  margin: 14px 0 4px;
  color: var(--accent);
  font-family: var(--ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.key-note-body h3:first-child { margin-top: 0; }
.key-note-body em { color: var(--muted); font-style: italic; }
/* The key is painted the way a passage is: the margin rules on the right, the wash behind. */
.key-swatch {
  width: 16px;
  height: 10px;
  display: inline-block;
  border-radius: 2px;
  background:
    linear-gradient(to left, rgb(var(--hue-1) / var(--rule-core)) 0 2px, transparent 2px),
    linear-gradient(rgb(var(--hue-1) / var(--tint-core)), rgb(var(--hue-1) / var(--tint-core)));
}
/* Defining carries the widest margin rule, the same way .legend-mark.defining is the
   widest mark in the header: the tier the shipped 3-point data actually puts its
   passages in was missing from the key entirely. */
.key-swatch.defining {
  background:
    linear-gradient(to left, rgb(var(--hue-1) / var(--rule-core)) 0 4px, transparent 4px),
    linear-gradient(rgb(var(--hue-1) / var(--tint-core)), rgb(var(--hue-1) / var(--tint-core)));
}
.key-swatch.related {
  background:
    linear-gradient(to left, rgb(var(--hue-1) / var(--rule-related)) 0 2px, transparent 2px),
    linear-gradient(rgb(var(--hue-1) / var(--tint-related)), rgb(var(--hue-1) / var(--tint-related)));
}
.key-swatch.overlap {
  background:
    linear-gradient(to left,
      rgb(var(--hue-3) / var(--rule-core)) 0 2px,
      transparent 2px 3px,
      rgb(var(--hue-1) / var(--rule-core)) 3px 5px,
      transparent 5px),
    linear-gradient(100deg,
      rgb(var(--hue-1) / var(--tint-core)),
      rgb(var(--hue-3) / var(--tint-core)));
}
/* The group key: the same wash, with the margin rule broken instead of solid. */
.key-swatch.stipple {
  background:
    repeating-linear-gradient(to bottom,
      rgb(var(--hue-1) / var(--rule-core)) 0 3px,
      transparent 3px 6px) 100% 0 / 2px 100% no-repeat,
    linear-gradient(rgb(var(--hue-1) / var(--tint-core)), rgb(var(--hue-1) / var(--tint-core)));
}

.workspace { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
/* The toolbar gained a third group (the compare picker), and the spec switcher grows
   with every registered document, so it wraps rather than overflowing the page. */
.reader-toolbar {
  min-height: 72px;
  padding: 10px 18px 10px 23px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 10px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--chrome);
}

/* One option per registered document, so the row grows with every user spec and
   must wrap rather than push the toolbar past the viewport. */
.spec-switcher { display: flex; flex-wrap: wrap; gap: 4px; padding: 4px; border-radius: 8px; background: var(--chrome-deep); }
.spec-option {
  min-width: 165px;
  padding: 7px 12px 6px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  text-align: left;
}
.spec-option span { display: block; font-size: 12px; font-weight: 600; }
.spec-option small { display: block; margin-top: 2px; font-size: 10px; letter-spacing: .02em; }
.spec-option.active { background: var(--paper); color: var(--ink); box-shadow: 0 1px 2px var(--shadow); }

.view-actions { display: flex; align-items: center; gap: 7px; margin-left: auto; }
.compare-toggle, .source-link {
  min-height: 34px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: transparent;
  color: var(--ink);
  font-size: 11px;
  text-decoration: none;
  cursor: pointer;
}
.compare-toggle { display: inline-flex; align-items: center; gap: 8px; }
.compare-toggle[aria-pressed="true"] { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
/* The menu folds away. On a document this wide it is consulted in bursts and
   read past the rest of the time, and the reader is the point.

   Folded, the column keeps a rail rather than going to nothing. The button that
   brings the menu back has to live somewhere, and a control that moves when you
   use it is a control you hunt for the second time — so it stays at the head of
   its own column in both states, and the rail is what that costs. */
.sidebar-toggle {
  flex: none;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 5px;
  background: transparent;
  color: var(--faint);
  cursor: pointer;
}

.sidebar-toggle:hover { border-color: var(--line); color: var(--ink); }

.chevron { width: 12px; height: 12px; }

/* Folded, the chevron turns around: the button points where the menu will go,
   not where it is. */
body.sidebar-collapsed .chevron { transform: scaleX(-1); }

/* Everything the rail does not keep. The head of the column stays, holding the
   button; its eyebrow goes, having no room to be read. */
body.sidebar-collapsed .eyebrow,
body.sidebar-collapsed .behaviour-toolbar,
body.sidebar-collapsed .behaviour-list,
body.sidebar-collapsed .sidebar-export,
body.sidebar-collapsed .sidebar-key,
body.sidebar-collapsed .sidebar-run {
  display: none;
}

/* Only above the breakpoint. Below it the shell is a single column with the
   menu stacked on top, where a 40px rail beside the document means nothing —
   the rules above already reduce it to a strip carrying the button. */
@media (min-width: 901px) {
  /* Two tracks, not three with a zero in the middle: the resizer below is
     `display: none`, which takes it out of the grid altogether, and the
     workspace would then land in that zero-width column. */
  body.sidebar-collapsed .app-shell {
    grid-template-columns: var(--sidebar-rail) minmax(0, 1fr);
  }

  /* The 9px resizer column carried the separation; folded, it is gone. */
  body.sidebar-collapsed .behaviour-sidebar {
    border-right: 1px solid var(--line);
  }

  body.sidebar-collapsed .sidebar-intro {
    padding: 15px 0 14px;
    justify-content: center;
  }
}

body.sidebar-collapsed .sidebar-resizer {
  display: none;
}

.split-icon { width: 12px; height: 12px; display: inline-block; border: 1px solid currentColor; }
.split-icon::after { content: ""; display: block; width: 1px; height: 100%; margin: 0 auto; background: currentColor; }
.source-link:hover, .compare-toggle:hover { border-color: var(--muted); }

.finding-bar {
  min-height: 54px;
  padding: 8px 20px 8px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.finding-behaviour {
  margin-right: 10px;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  vertical-align: -1px;
  font-size: 11px;
  font-weight: 600;
}
.finding-behaviour:empty { display: none; }
.behaviour-chip {
  padding: 3px 8px;
  border-radius: 3px;
  background: rgb(var(--bh) / var(--tint-core-strong));
  box-shadow: inset 2px 0 0 rgb(var(--bh) / var(--rule-core));
  white-space: nowrap;
}
.finding-definition { color: var(--muted); font-family: var(--reader); font-size: 14px; font-style: italic; }
.passage-controls { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.passage-controls span { margin-right: 7px; color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.passage-controls button {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.passage-controls button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.passage-controls button:disabled { opacity: .35; cursor: default; }

.reader-status {
  display: none;
  padding: 12px 20px;
  border-bottom: 1px solid var(--focus);
  background: var(--gap-soft);
  color: var(--ink);
  font-size: 12px;
}
.reader-status.visible { display: block; }

.document-grid {
  --compare-first: 50%;
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  background: var(--line);
}
.document-grid.compare {
  grid-template-columns:
    minmax(0, var(--compare-first))
    9px
    minmax(0, calc(100% - var(--compare-first) - 9px));
}
.document-resizer { height: 100%; }
.document-panel { min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--paper); }
.document-header {
  min-height: 72px;
  padding: 12px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  border-bottom: 1px solid var(--line-light);
}
.document-lab {
  margin: 0 0 2px;
  color: var(--accent);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.document-title { margin: 0; font-family: var(--reader); font-size: 21px; font-weight: 500; }
.document-meta {
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  justify-items: end;
  gap: 3px 10px;
  color: var(--muted);
  font-size: 9px;
}
.document-version { grid-column: 1 / -1; }
.document-focus-toggle {
  padding: 2px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font-size: 9px;
  cursor: pointer;
}
.document-focus-toggle:hover { border-color: var(--accent); color: var(--accent); }
/* The toggles carry their counts, which makes the legend wide enough to overrun a
   phone-width header. Each button stays unbroken (nowrap); the row wraps instead. */
.rail-legend {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
/* Neutral: the legend explains intensity, and the colour belongs to the behaviour. */
.legend-mark { width: 3px; height: 9px; display: inline-block; border-radius: 2px; background: var(--muted); }
.legend-mark.adjacent { margin-left: 3px; opacity: .4; }

/* Tier toggles: the legend is the control. Each mark-and-word pair is a button; a
   pressed pair sits enclosed in a small bordered well, an unpressed one fades but
   keeps its footprint. Mark weight orders the tiers: heavy bar = defining, solid =
   core, faint = related -- the same weights the passage rail carries. */
.tier-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: var(--faint);
  cursor: pointer;
  transition: color .12s ease, border-color .12s ease, background-color .12s ease;
}
.tier-toggle .legend-mark { background: currentColor; }
.tier-toggle .legend-mark.adjacent { margin-left: 0; }
.tier-toggle:hover { color: var(--muted); border-color: var(--line-light); }
.tier-toggle[aria-pressed="true"] {
  border-color: var(--line);
  background: var(--chrome-deep);
  color: var(--ink);
}
/* The run block sits under the key, closing the sidebar: collapsed it is one line of
   run identity, opened it is the payload's full provenance. */
.sidebar-run {
  padding: 10px 22px 14px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 10px;
}
.sidebar-run > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
}
.sidebar-run > summary::-webkit-details-marker { display: none; }
.sidebar-run > summary::before { content: "▸"; opacity: .6; font-size: 9px; }
.sidebar-run[open] > summary::before { content: "▾"; }
.sidebar-run > summary:hover { color: var(--ink); }
/* A pin that could not be served still renders the page; the marker is the only
   on-screen sign that what you asked for is not what you are looking at. */
.sidebar-run.fell-through > summary::after {
  content: "pin unavailable";
  margin-left: auto;
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 3px;
  color: var(--warn, #b4690e);
  font-size: 9px;
}
.run-detail { margin: 9px 0 0; display: grid; grid-template-columns: 1fr; gap: 2px; }
.run-detail dt { color: var(--faint); text-transform: uppercase; letter-spacing: .04em; font-size: 9px; }
.run-detail dd { margin: 0 0 7px; color: var(--muted); overflow-wrap: anywhere; }

.tier-count { font-variant-numeric: tabular-nums; opacity: .7; }
/* A tier this data cannot reach: dimmed, not clickable, and it keeps its count (0)
   so the reason is legible rather than implied by silence. */
.tier-toggle.unreachable {
  opacity: .4;
  cursor: not-allowed;
  text-decoration: line-through;
}
.tier-toggle.unreachable:hover { color: var(--faint); border-color: transparent; }
.legend-mark.defining { width: 5px; }
.document-scroll { position: relative; flex: 1; min-height: 0; overflow: auto; scroll-behavior: smooth; }

/* Half the window of text, a quarter of it either side.
 *
 * Proportional rather than the 780px box this used to be: with the menu folded
 * the panel is most of the window, and a fixed measure left the spec as a
 * ribbon down the middle of a wide empty field.
 *
 * Measured against the window, not the panel. A quarter of the *panel* would
 * make the column narrower whenever the menu is open than the fixed box it
 * replaces — 570px against 624px — which is the opposite of the point. Against
 * the window the measure holds at half the screen whether the menu is there or
 * not, and only the gutters move.
 *
 * The `max` is a floor, for the case where the panel is narrower than half the
 * window: the subtraction goes negative, and a negative padding is not dropped
 * politely, it takes the whole declaration with it. Compare mode reaches that
 * case on every screen and sets its own gutters below anyway — a quarter of a
 * half-width panel is a column too narrow to read.
 *
 * Gutters as padding rather than margins, so the passage rules and washes,
 * which are laid on the block and bleed into the space beside the text, still
 * have something to bleed into. */
.document-body {
  width: 100%;
  padding: 56px max(28px, (100% - 50vw) / 2) 120px;
  font-family: var(--reader);
  font-size: 17px;
  line-height: 1.65;
}
.document-grid.compare .document-body { padding-right: 58px; padding-left: 58px; font-size: 16px; }
.document-body h1, .document-body h2, .document-body h3,
.document-body h4, .document-body h5 {
  color: var(--ink);
  font-family: var(--reader);
  font-weight: 500;
  line-height: 1.16;
  scroll-margin-top: 60px;
}
.document-body h1 { margin: 0 0 30px; font-size: 42px; letter-spacing: -.03em; }
.document-body h2 { margin: 62px 0 17px; padding-top: 17px; border-top: 1px solid var(--line); font-size: 29px; letter-spacing: -.02em; }
.document-body h3 { margin: 42px 0 14px; font-size: 23px; }
.document-body h4 { margin: 32px 0 12px; font-size: 19px; }
.document-body h5 { margin: 26px 0 9px; color: var(--muted); font-family: var(--ui); font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.document-body .section-heading { position: relative; }
.section-heading-button {
  width: 100%;
  padding: 0;
  display: flex;
  align-items: baseline;
  gap: 12px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  line-height: inherit;
  text-align: left;
  cursor: pointer;
}
.section-heading-button .section-title { flex: 1; }
.section-heading-button .section-chevron {
  flex: none;
  color: var(--faint);
  font-family: var(--ui);
  font-size: 11px;
  transition: transform .15s ease;
}
.section-heading.section-collapsed {
  margin: 8px 0 !important;
  padding: 0 !important;
  border: 0 !important;
}
.section-heading.section-collapsed .section-heading-button {
  min-height: 34px;
  padding: 7px 10px;
  border: 1px solid var(--line-light);
  border-radius: 4px;
  background: var(--chrome-deep);
  color: var(--muted);
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.35;
  text-transform: none;
}
.section-heading.section-collapsed .section-heading-button:hover {
  border-color: var(--line);
  background: var(--chrome);
  color: var(--ink);
}
.section-heading.section-collapsed .section-chevron { transform: rotate(-90deg); }
.section-heading.section-has-passage > .section-heading-button::before {
  content: "";
  width: 5px;
  height: 5px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  transform: translateY(-2px);
}
.document-body p { margin: 0 0 1.05em; }
.document-body a { color: var(--accent); text-decoration-color: var(--line); text-underline-offset: 2px; }
.document-body strong { font-weight: 600; }
.document-body em { color: var(--muted); }
.document-body ul, .document-body ol { margin: 0 0 1.2em; padding-left: 1.45em; }
.document-body li { margin: .35em 0; padding-left: .18em; }
.document-body blockquote {
  margin: 1.4em 0;
  padding: .2em 0 .2em 1.2em;
  border-left: 2px solid var(--line);
  color: var(--muted);
}
.document-body hr { height: 1px; margin: 45px 0; border: 0; background: var(--line); }
.document-body .code-block {
  margin: 1.1em 0 1.8em;
  padding: 15px 17px;
  overflow-x: auto;
  border: 1px solid var(--line-light);
  border-radius: 4px;
  background: var(--chrome-deep);
  color: var(--muted);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 11px;
  line-height: 1.55;
  white-space: pre-wrap;
}
.document-body .admonition {
  margin: 1.35em 0;
  padding: 13px 16px 2px;
  border: 1px solid var(--line-light);
  border-left: 3px solid var(--line);
  background: var(--chrome-deep);
}
.document-body .admonition-label {
  margin-bottom: 7px;
  color: var(--muted);
  font-family: var(--ui);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.document-body .raw-table { overflow: auto; font-family: ui-monospace, monospace; font-size: 10px; white-space: pre; }
.zero-coverage {
  margin: 0 0 36px;
  padding: 16px 18px;
  border: 1px solid var(--adjacent-mark);
  border-radius: 4px;
  background: var(--gap-soft);
  font-family: var(--ui);
  font-size: 12px;
  line-height: 1.45;
}
.zero-coverage strong { display: block; margin-bottom: 3px; color: var(--focus); }
.zero-coverage span { color: var(--muted); }

/* Every colour on a passage is written by app.js into --tint (the wash), --gutter (one
   margin rule per behaviour, solid or broken by group) and --bh-primary, all of them in
   terms of the palette's --hue-N, so switching surfaces repaints the highlights without
   re-annotating them. The gutter's -size and -pos place each behaviour's rule in its own
   column; the wash is a single layer and needs neither.

   The rules hang off the right margin, not the left: on the left they sat in the same
   column as an ordered list's numbers and a blockquote's rule, and a highlighted list item
   had its marker struck through. Nothing but the passage rail lives on the right. */
.passage {
  position: relative;
  margin-right: -12px !important;
  margin-left: -12px !important;
  padding: 5px 12px;
  border-radius: 3px;
  background-image: var(--tint);
  box-decoration-break: clone;
}
.passage::before {
  content: "";
  position: absolute;
  top: 5px;
  bottom: 5px;
  right: calc(-7px - var(--gutter-width, 2px));
  width: var(--gutter-width, 2px);
  border-radius: 2px;
  background-image: var(--gutter);
  background-size: var(--gutter-size, auto);
  background-position: var(--gutter-pos, 0 0);
  background-repeat: no-repeat;
}
.passage.current {
  background-image: var(--tint-strong);
  box-shadow: 0 0 0 1px rgb(var(--bh-primary) / .5);
}
.passage.current::before { top: 2px; bottom: 2px; }
/* The strip above a passage carries the behaviour names only. Why the passage was selected
   sits behind the question mark at the right of the strip: the role sentences are long
   enough that set out in the open they read as a second document over the first. */
.passage-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 2px 0 5px;
}
.passage-label {
  color: rgb(var(--bh));
  font-family: var(--ui);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1.35;
  text-transform: uppercase;
}
.passage-label + .passage-label::before {
  content: "·";
  margin-right: 8px;
  color: var(--faint);
}

.passage-why {
  flex: none;
  position: relative;
  width: 15px;
  height: 15px;
  margin-left: auto;
  padding: 0;
  border: 1px solid rgb(var(--bh-primary) / .45);
  border-radius: 50%;
  background: transparent;
  color: rgb(var(--bh-primary));
  font-family: var(--ui);
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  opacity: .62;
  transition: opacity .12s ease, background-color .12s ease;
}
.passage-why:hover,
.passage-why:focus-visible,
.passage-why[aria-expanded="true"] {
  opacity: 1;
  background: rgb(var(--bh-primary) / .14);
}
/* The hover legend. Anchored to the right edge so it opens inwards over the text rather
   than off the panel, and never intercepts the pointer on its way to the button. */
.passage-why::after {
  content: attr(data-tip);
  position: absolute;
  z-index: 4;
  top: calc(100% + 5px);
  right: 0;
  padding: 3px 7px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--chrome);
  box-shadow: 0 2px 8px var(--shadow);
  color: var(--muted);
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.3;
  text-transform: none;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
}
.passage-why:hover::after,
.passage-why:focus-visible::after { opacity: 1; }
.passage-why[aria-expanded="true"]::after { content: none; }

.passage-rationale {
  display: block;
  margin: 0 0 7px;
  padding: 6px 9px;
  border-right: 2px solid rgb(var(--bh-primary) / .5);
  border-radius: 3px 0 0 3px;
  background: rgb(var(--bh-primary) / .07);
  font-family: var(--ui);
  font-size: 12px;
  line-height: 1.45;
}
.passage-rationale[hidden] { display: none; }
.passage-reason { display: block; color: var(--muted); }
.passage-reason + .passage-reason { margin-top: 5px; }
.passage-reason-behaviour {
  color: rgb(var(--bh));
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.passage-reason-behaviour::after { content: " · "; }

.passage-rail {
  position: sticky;
  z-index: 3;
  top: 0;
  float: right;
  width: 14px;
  height: 100%;
  margin-left: -14px;
  pointer-events: none;
}
.passage-rail::before {
  content: "";
  position: absolute;
  top: 8px;
  right: 5px;
  bottom: 8px;
  width: 1px;
  background: var(--line);
}
.rail-mark {
  position: absolute;
  right: 3px;
  width: 4px;
  min-height: 4px;
  padding: 0;
  border: 0;
  border-radius: 2px;
  background-color: transparent;
  background-image: var(--rail);
  opacity: .85;
  pointer-events: auto;
  cursor: pointer;
}
.rail-mark:hover { width: 7px; opacity: 1; }
/* A mark banded down its height is a passage more than one behaviour cites. */
.rail-mark.overlap { width: 6px; }
.rail-mark.current {
  right: 1px;
  width: 9px;
  min-height: 7px;
  box-shadow: 0 0 0 1px var(--paper), 0 0 0 2px var(--focus);
  opacity: 1;
}

button:focus-visible, a:focus-visible, .column-resizer:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

@media (max-width: 900px) {
  body { overflow: auto; }
  .site-header nav a:not(.active) { display: none; }
  .app-shell { height: auto; min-height: calc(100vh - 54px); grid-template-columns: 1fr; }
  .behaviour-sidebar { border-bottom: 1px solid var(--line); }
  .column-resizer { display: none; }
  .sidebar-intro { padding: 14px 20px; }
  .behaviour-list { display: flex; overflow-x: auto; padding: 8px; }
  .behaviour-group { min-width: 220px; border-bottom: 0; border-right: 1px solid var(--line); }
  .sidebar-export {
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 10px 20px;
  }
  .download-passages { width: auto; }
  .download-hint { text-align: left; }
  .sidebar-key { display: none; }
  .workspace { min-height: 75vh; }
  .reader-toolbar { flex-wrap: wrap; }
  .finding-definition { display: none; }
  .document-grid, .document-grid.compare { min-height: 70vh; grid-template-columns: 1fr; }
  .document-panel { min-height: 70vh; }
  .document-grid.compare .document-panel { min-height: 65vh; }
  body.embedded { overflow: hidden; }
  body.embedded .app-shell { min-height: 0; }
  body.embedded .workspace { min-height: 0; }
  body.embedded .document-grid,
  body.embedded .document-grid.compare,
  body.embedded .document-panel,
  body.embedded .document-grid.compare .document-panel { min-height: 0; }
}

@media (max-width: 620px) {
  .site-header { padding: 0 16px; }
  .site-footer { padding: 0 16px; }
  /* Two names and a menu do not fit. The star carries the collective on its
     own here, and its name is still a link in the footer. */
  .collective,
  .brand-divider { display: none; }
  /* The credit line alone. The bar's height is a constant the shell subtracts,
     so nothing here may wrap: at this width the two halves together take three
     lines and the second is cut off mid-sentence. The pointer it carries is in
     the README and on the methodology page, both of which have room. */
  .site-footer span + span { display: none; }
  .reader-toolbar { padding: 10px; }
  .spec-switcher { width: 100%; }
  .spec-option { min-width: 0; flex: 1; }
  .view-actions { width: 100%; justify-content: space-between; }
  .finding-bar { padding: 8px 12px; }
  .document-header { padding: 11px 15px; }
  /* Asymmetric on a phone: the right margin has to hold the passage rules and the rail,
     the left holds nothing. */
  .document-body, .document-grid.compare .document-body { padding: 38px 46px 90px 28px; font-size: 16px; }
  .document-body h1 { font-size: 34px; }
  .document-body h2 { font-size: 25px; }
}

@media (prefers-reduced-motion: reduce) {
  .document-scroll { scroll-behavior: auto; }
  .section-heading-button .section-chevron { transition: none; }
}

/* ---------- reader test: no behaviour under test ---------- */

.behaviour-empty {
  margin: 4px 14px;
  padding: 16px 15px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--chrome-deep);
  color: var(--muted);
  font-size: 12px;
  line-height: 1.55;
}
.behaviour-empty strong { display: block; margin-bottom: 5px; color: var(--ink); }
.behaviour-empty p { margin: 0; }

/* The Mapped / Mapping pending key describes nothing while the payload is empty, and there is
   nothing to take away either. */
body.no-behaviours .sidebar-key,
body.no-behaviours .sidebar-export { display: none; }

/* .rail-legend sets its own display, which would otherwise beat the [hidden] default
   when the reader hides the highlight legend for want of a behaviour. */
.document-meta [hidden] { display: none; }

/* panel rationale: model-vote list uses newlines */
.passage-reason-role { white-space: pre-line; }

/* The compare picker: two selects that only appear when there is a third document to
   choose between. Sized to sit in the toolbar without pushing the spec switcher. */
.compare-picker { display: inline-flex; align-items: center; gap: 8px; }
.compare-picker[hidden] { display: none; }
.compare-picker-field {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.compare-picker select {
  max-width: 190px;
  padding: 3px 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  text-transform: none;
  letter-spacing: 0;
}
.compare-picker select:hover { border-color: var(--accent); }

/* Local mode: the marker that this page is showing specifications registered on this
   machine, and the nav link to the analysis surface that only exists once a user
   specification is registered. Added by site/shared/local-mode.js. */
.local-data-note {
  /* Third child of a space-between header built for two: without an auto margin the
     free space is split into two equal gaps and the marker floats to the middle of
     them -- a position that varies with nav length and jumps ~200px when the 900px
     query collapses the nav. margin-right:auto absorbs that space before
     justify-content sees it, so the marker stays beside the wordmark at every width. */
  margin: 0 auto 0 16px;
  padding: 2px 8px;
  border: 1px solid var(--accent);
  border-radius: 3px;
  color: var(--accent);
  font-size: 10px;
  font-variant-caps: all-small-caps;
  letter-spacing: .12em;
  white-space: nowrap;
  cursor: help;
}
nav a[data-local-only] { font-variant-caps: all-small-caps; }

/* The 16px above is 16px the wordmark no longer has, which moves its wrap threshold
   up: measured, the margin alone pushes the width at which the wordmark breaks out of
   the fixed-height header from 380 to 395 on the panel, newly breaking 390/393. Below
   400 there is not room for wordmark + marker + nav on one row at all, so the marker
   stands down. Scoped to the body flag local-mode.js sets, so a bundled-only site --
   which never sets it -- is untouched: measured drift 0 at every width. */
@media (max-width: 400px) {
  body[data-local-data] .local-data-note { display: none; }
}
