/* Schools Finder (schools.publicworks.nyc)
   ------------------------------------------------------------------
   One stylesheet, no build step, no webfonts, light mode only.

   The proportions, hairlines and restraint follow The Pay Gap, because
   the two sites are the same kind of instrument. What is different here
   is that a school profile is mostly a long list of measured values, so
   the work goes into making a value, its definition and its absence all
   legible at the same size. */

/* ---- Tokens ---------------------------------------------------- */

:root {
  /* The palette is the main thing separating this site from The Pay Gap,
     which is warm ivory and civic blue. Here the paper is cool and the accent
     is a deep institutional green: same restraint, different room. */
  --paper:        #f7f8f8;
  --paper-raised: #ffffff;
  --paper-sunken: #eceeee;
  --ink:          #15181b;
  --ink-soft:     #474d52;
  /* Darkened from #6b7280, which measured 4.24:1 against the sunken panel and
     so failed AA for the small text used there. This is 4.8:1 on the sunken
     panel and 5.2:1 on the page. */
  --ink-faint:    #626970;
  --rule:         #dcdfe0;
  --rule-strong:  #c2c7c9;
  /* Hairlines between rows can be faint, but the edge of a control carries
     meaning and WCAG asks for 3:1. --rule-strong measured 1.7:1 on white, so
     inputs and selects use their own darker border. */
  --control:      #7f868a;

  --accent:       #14634a;   /* deep green, 6.8:1 on the paper */
  --on-accent:    #ffffff;
  --accent-soft:  #e3efea;
  --accent-ink:   #0d4b38;
  --warn:         #9c3d16;
  --warn-soft:    #fbe9e0;

  /* Bands for the City's own 1 to 5 score. Deliberately quiet: a tint behind a
     value, never a traffic light. Color never carries the meaning on its own,
     because the score and a written label sit beside it. */
  --band-high-tint:  #e7f2ea;
  --band-high-ink:   #12603f;
  --band-above-tint: #eef5ec;
  --band-above-ink:  #1d6b45;
  --band-below-tint: #fdf1e3;
  --band-below-ink:  #8a5210;
  --band-low-tint:   #fbe9e0;
  --band-low-ink:    #9c3d16;

  --shadow: 0 1px 2px rgba(20,22,28,.05), 0 8px 24px -12px rgba(20,22,28,.18);

  --measure: 34rem;
  --wide:    72rem;

  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto,
          "Helvetica Neue", Arial, sans-serif;
  /* Monospace carries identifiers and readouts: a DBN, a reporting period,
     a count. It is the signal that a thing is a record, not prose. */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", monospace;
}

/* ---- Base ------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { line-height: 1.15; letter-spacing: -.022em; font-weight: 700; margin: 0 0 .5em; }
h1 { font-size: clamp(1.8rem, 3.6vw, 2.6rem); letter-spacing: -.03em; }
h2 { font-size: clamp(1.3rem, 2.4vw, 1.7rem); margin-top: 2.4em; }
h3 { font-size: 1.08rem; margin-top: 1.8em; }
h4 { font-size: .95rem; margin-top: 1.4em; }

p { margin: 0 0 1em; max-width: var(--measure); }
a { color: var(--accent); text-underline-offset: .18em; text-decoration-thickness: .07em; }
a:hover { color: var(--accent-ink); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

.skip { position: absolute; left: -9999px; background: var(--accent);
        color: #fff; padding: .6rem 1rem; z-index: 100; }
.skip:focus { left: .5rem; top: .5rem; }

.mono { font-family: var(--mono); font-size: .92em; }
.muted { color: var(--ink-faint); }
.hidden { display: none !important; }

/* Visible to a screen reader, not on screen. Used for table captions and for
   the live region that announces how many schools a filter left. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- Layout ----------------------------------------------------- */

.wrap { width: min(100% - 2.5rem, var(--wide)); margin-inline: auto; }
.prose { max-width: var(--measure); }
.wrap.prose { max-width: none; }
.wrap.prose > * { max-width: var(--measure); }
main { padding-bottom: 5rem; }

/* ---- Masthead --------------------------------------------------- */

/* This block is the reference implementation of the shared publicworks.nyc
   header, and other projects are copied from it. Only --accent, and any
   control a project genuinely needs, may differ between sites. Retuning the
   sizes here changes the standard, so change it everywhere or not at all.
   The measurements are written down in the publicworks.nyc README. */

.masthead { border-bottom: 1px solid var(--rule); background: var(--paper); }
.masthead-inner {
  display: flex; align-items: center; gap: 1.25rem;
  padding: .55rem 0; flex-wrap: wrap;
}
/* The mark is the product name and nothing else. It deliberately does not
   spell the site's own address, which has moved once already, and it does not
   carry publicworks.nyc either: that is a filing cabinet, and a link at the
   foot of the page is the whole of what it needs here. */
.wordmark {
  font-weight: 700; letter-spacing: -.03em; font-size: 1.25rem;
  color: var(--ink); text-decoration: none; white-space: nowrap;
}

.nav { display: flex; gap: .15rem; flex-wrap: wrap; margin-left: auto; align-items: center; }
.nav a {
  color: var(--ink-soft); text-decoration: none;
  padding: .35rem .6rem; border-radius: 6px;
  font-size: .9rem; font-weight: 500; white-space: nowrap;
}
.nav a:hover { background: var(--paper-sunken); color: var(--ink); }
.nav a[aria-current="page"] { color: var(--accent); background: var(--accent-soft); }

/* ---- Console and section headings -------------------------------- */

.console { padding: clamp(2rem, 5vw, 3.5rem) 0 1.5rem; }
.console-sub { color: var(--ink-soft); max-width: 44rem; font-size: 1.02rem; margin-bottom: 1.75rem; }
.statusline { color: var(--ink-faint); font-size: .8rem; margin: .9rem 0 0; max-width: none; }

.section-label {
  font-size: .78rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-faint);
  margin: 3rem 0 .3rem; border-bottom: 1px solid var(--rule); padding-bottom: .5rem;
}
.hint { font-size: .88rem; color: var(--ink-faint); margin: .6rem 0 1rem; }

/* ---- Search ------------------------------------------------------ */

.search-shell { position: relative; max-width: 42rem; }
.search-row input[type="search"] {
  width: 100%; font-size: 1.05rem; padding: .7rem .9rem;
  border: 1.5px solid var(--control); border-radius: 9px;
  background: var(--paper-raised); color: var(--ink); font-family: inherit;
}
.search-row input[type="search"]:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); outline: none;
}
.results {
  list-style: none; margin: .3rem 0 0; padding: 0;
  border: 1px solid var(--rule); border-radius: 9px;
  background: var(--paper-raised); box-shadow: var(--shadow);
  max-height: 22rem; overflow-y: auto;
  position: absolute; width: 100%; z-index: 15;
}
.results:empty { display: none; }
.results li { border-bottom: 1px solid var(--rule); }
.results li:last-child { border-bottom: 0; }
.results button {
  width: 100%; text-align: left; background: none; border: 0;
  font: inherit; padding: .55rem .8rem; cursor: pointer; color: var(--ink);
  display: flex; justify-content: space-between; gap: 1rem; align-items: baseline;
}
.results button:hover, .results li.active button { background: var(--accent-soft); }
.results .r-name { font-weight: 500; }
.results .meta { color: var(--ink-faint); font-size: .8rem; white-space: nowrap; }

/* ---- Controls ---------------------------------------------------- */

/* A `display` of its own beats the browser's rule for [hidden], so a hidden
   .controls kept drawing its border as an empty box. */
[hidden] { display: none !important; }

.controls {
  display: flex; flex-wrap: wrap; gap: .9rem;
  padding: .9rem 1rem; margin: 1.25rem 0 1rem;
  background: var(--paper-raised); border: 1px solid var(--rule); border-radius: 9px;
}
.control { display: flex; flex-direction: column; gap: .25rem; flex: 1 1 10rem; min-width: 0; }
.control label {
  font-size: .72rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-faint);
}
input[type="search"], input[type="text"], select {
  font: inherit; font-size: .92rem; padding: .45rem .7rem;
  border: 1px solid var(--control); border-radius: 7px;
  background: var(--paper-raised); color: var(--ink); min-width: 0;
}
.control select { width: 100%; }
.count { font-size: .85rem; color: var(--ink-faint); }

button.pill, a.pill {
  background: var(--paper-sunken); border: 1px solid var(--rule);
  border-radius: 999px; padding: .25rem .8rem; font: inherit; font-size: .84rem;
  color: var(--ink-soft); cursor: pointer; text-decoration: none; display: inline-block;
}
button.pill:hover, a.pill:hover { border-color: var(--accent); color: var(--accent); }
/* Present but not yet usable, rather than absent and appearing later. */
button.pill:disabled { opacity: .5; cursor: default; }
button.pill:disabled:hover { border-color: var(--rule); color: var(--ink-soft); }
button.pill[aria-pressed="true"] {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}

/* ---- School cards ------------------------------------------------ */

.school-grid {
  list-style: none; padding: 0; margin: 0 0 1rem;
  display: grid; gap: .75rem;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}
.school-card {
  display: flex; flex-direction: column; gap: .3rem; height: 100%;
  padding: .95rem 1.1rem; text-decoration: none; color: inherit;
  background: var(--paper-raised);
  border: 1px solid var(--rule); border-left: 3px solid var(--rule-strong);
  border-radius: 0 8px 8px 0;
  transition: border-left-color .12s ease, background .12s ease;
}
.school-card:hover { border-left-color: var(--accent); background: var(--paper-sunken); }
.school-card .name { font-size: 1rem; font-weight: 600; line-height: 1.3; color: var(--ink); }
.school-card .where { font-size: .86rem; color: var(--ink-soft); }
.school-card .ident {
  font-family: var(--mono); font-size: .76rem; color: var(--ink-faint);
  letter-spacing: .02em;
}

/* ---- Profile ----------------------------------------------------- */

.entity-head { margin-bottom: 1.25rem; }
.entity-head .kind {
  font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 .25rem;
}
.entity-head h1 { margin-bottom: .3rem; }
.entity-head .where { color: var(--ink-soft); max-width: 46rem; }

.facts {
  display: grid; gap: 0; margin: 1.5rem 0 2rem;
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-radius: 10px; overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}
.fact { padding: .9rem 1.1rem; box-shadow: 1px 0 0 var(--rule), 0 1px 0 var(--rule); }
.fact dt { font-size: .76rem; color: var(--ink-faint); font-weight: 600; margin-bottom: .25rem; }
.fact dd { margin: 0; font-size: 1.05rem; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.fact dd.big { font-size: clamp(1.4rem, 2.6vw, 1.8rem); letter-spacing: -.03em; }
.fact dd .note { display: block; font-size: .8rem; color: var(--ink-faint); font-weight: 400; }

/* At a glance, and the jump list.
   ------------------------------------------------------------------
   A profile can run to a hundred and eighty measures. These two blocks are
   the way in: the handful of measures people actually ask for, then a list
   of the sections. Neither summarizes anything. */

.glance-grid {
  display: grid; gap: 0; margin: .75rem 0 1rem; padding: 0; list-style: none;
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-radius: 10px; overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.glance {
  padding: .9rem 1.1rem; box-shadow: 1px 0 0 var(--rule), 0 1px 0 var(--rule);
  display: flex; flex-direction: column; gap: .2rem;
}
.glance .g-label { font-size: .8rem; color: var(--ink-faint); font-weight: 600; line-height: 1.3; }
.glance .m-figure { flex-wrap: wrap; }
.glance .m-value { font-size: clamp(1.3rem, 2.4vw, 1.6rem); }
.glance .g-year { font-size: .78rem; color: var(--ink-faint); }

.section-jump {
  display: flex; flex-wrap: wrap; gap: .35rem;
  margin: 1.25rem 0 0; padding: .7rem .8rem;
  background: var(--paper-sunken); border-radius: 9px;
}
.section-jump a {
  font-size: .84rem; text-decoration: none; color: var(--accent-ink);
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-radius: 999px; padding: .18rem .7rem;
}
.section-jump a:hover { border-color: var(--accent); }

/* Measures.
   ------------------------------------------------------------------
   One card per measure, not a table. A school profile is a long list of
   single numbers, and a table of two useful columns forces a reader to
   track a header row that has scrolled away. The card puts the value, its
   scale, its period and its standing against similar schools in one place
   at one glance, and never scrolls sideways. */

.measure-list { list-style: none; padding: 0; margin: 0; }
.measure {
  border-top: 1px solid var(--rule);
  padding: .85rem 0;
}
.measure:first-child { border-top: 0; }

.m-head {
  display: flex; flex-wrap: wrap; gap: .2rem 1rem;
  align-items: baseline; justify-content: space-between;
}
.m-label { font-weight: 600; flex: 1 1 14rem; min-width: 0; }
.m-figure { display: flex; align-items: baseline; gap: .45rem; white-space: nowrap; }
.m-value { font-size: 1.3rem; font-weight: 700; letter-spacing: -.025em; }
/* The maximum of the scale, printed next to the value, so "3.35" reads as
   "3.35 of 4.5" without anyone opening a definition. */
.m-scale { font-size: .9rem; color: var(--ink-faint); font-weight: 500; }
.m-value.absent { font-size: .95rem; font-weight: 600; color: var(--ink-faint); }

/* The standing band. A tint, the City's own score, and a written label: the
   color is a shortcut, never the only carrier of the meaning. */
.band {
  display: inline-flex; align-items: baseline; gap: .4rem;
  border-radius: 6px; padding: .12rem .45rem;
  font-size: .8rem; font-weight: 600; white-space: nowrap;
}
.band .score { font-family: var(--mono); font-weight: 700; }
.band-high  { background: var(--band-high-tint);  color: var(--band-high-ink); }
.band-above { background: var(--band-above-tint); color: var(--band-above-ink); }
.band-below { background: var(--band-below-tint); color: var(--band-below-ink); }
.band-low   { background: var(--band-low-tint);   color: var(--band-low-ink); }

.m-meta {
  font-size: .84rem; color: var(--ink-faint);
  display: flex; flex-wrap: wrap; gap: .1rem .7rem; margin-top: .25rem;
}
.m-meta .sep { color: var(--rule-strong); }

/* The comparison, written as a sentence rather than a bare second number.
   "5.4 points above the 89.2% average of its comparison group" is a fact a
   reader can use; "89.2" on its own is not. */
.m-compare { font-size: .86rem; color: var(--ink-soft); margin-top: .3rem; }
.m-compare b { font-weight: 600; color: var(--ink); }
.m-compare .up { color: var(--band-high-ink); }
.m-compare .down { color: var(--band-low-ink); }

.measure details { margin-top: .45rem; }
.measure summary {
  font-size: .82rem; color: var(--accent); cursor: pointer; width: max-content;
}
.m-detail {
  font-size: .86rem; color: var(--ink-soft); margin: .5rem 0 .2rem;
  padding-left: .9rem; border-left: 2px solid var(--rule); max-width: 46rem;
}
.m-detail p { margin: 0 0 .45rem; max-width: none; }
.m-detail p:last-child { margin-bottom: 0; }

/* The panel is a short table of labelled facts. Prose here made a reader
   consume four sentences to reach the one line they opened it for; a label
   column lets them jump straight to it. */
.m-facts { margin: 0; display: grid; gap: .1rem 0; }
.m-facts > div {
  display: grid; grid-template-columns: 8.5rem 1fr; gap: .2rem .9rem;
  padding: .22rem 0; align-items: baseline;
}
.m-facts dt {
  font-size: .74rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-faint);
}
.m-facts dd { margin: 0; color: var(--ink); }
.m-facts .mono-row dd { font-family: var(--mono); font-size: .82rem; color: var(--ink-soft); }
.m-facts .careful dd { color: var(--band-below-ink); }

/* Standing sits in the first row, where the band has room to carry its own
   label instead of floating next to a number it does not belong to. */
.standing { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem .6rem; }
.standing .up { color: var(--band-high-ink); font-weight: 600; }
.standing .down { color: var(--band-low-ink); font-weight: 600; }

.m-facts-label {
  font-size: .74rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-faint);
  margin: .8rem 0 0;
}

/* Group breakdowns, under the all-students figure they belong to. */
.m-groups { margin-top: .5rem; }
.m-groups > summary { font-size: .82rem; }
.group-theme {
  font-size: .72rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-faint);
  margin: .7rem 0 .2rem;
}
.group-list { list-style: none; padding: 0; margin: 0; }

/* Name, then how many students it is over, then the figure hard against the
   right edge. The figure last and aligned is what makes a column of these
   scannable: the eye runs down one edge instead of hunting for where each
   number starts. */
.group-row {
  /* Fixed widths on the last two columns, not auto. Each row is its own grid,
     so auto sizing let every row choose its own edge and the figures came out
     ragged, which is the one thing this layout exists to prevent. */
  display: grid; grid-template-columns: minmax(0, 1fr) 6rem 6.5rem;
  align-items: baseline; gap: .2rem .7rem;
  padding: .28rem 0; border-top: 1px dotted var(--rule);
  font-size: .9rem;
}
.group-row .g-name { min-width: 0; }
.group-row .g-meta {
  color: var(--ink-faint); font-size: .8rem; white-space: nowrap;
  text-align: right;
}
.group-row .g-value {
  font-weight: 700; white-space: nowrap;
  text-align: right; min-width: 4.5rem;
}
.group-row .g-value.absent { font-weight: 500; color: var(--ink-faint); font-size: .85rem; }

@media (max-width: 26rem) {
  /* Too narrow for three columns: the count drops under the name and the
     figure keeps its edge. */
  .group-row { grid-template-columns: 1fr auto; }
  .group-row .g-meta { grid-row: 2; grid-column: 1; text-align: left; }
}

/* A compact history strip. Values only, no drawn chart: the point is to show
   that a series exists and where it moved, not to invite a reading of slope. */
.history { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .45rem; }
.history .h-year {
  font-family: var(--mono); font-size: .74rem; color: var(--ink-faint);
  background: var(--paper-sunken); border: 1px solid var(--rule);
  border-radius: 5px; padding: .1rem .4rem; white-space: nowrap;
}
.history .h-year b { color: var(--ink); font-weight: 600; }

/* Programs. Cards, not a wide table: each program is six short facts and a
   priority list, which a table turns into a sideways scroll for no gain. */
.program-list { list-style: none; padding: 0; margin: 0; display: grid; gap: .9rem; }
.program {
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-left: 3px solid var(--accent-soft);
  border-radius: 0 9px 9px 0; padding: .95rem 1.1rem;
}
.program h3 { margin: 0 0 .15rem; font-size: 1rem; }
.program .p-code { font-family: var(--mono); font-size: .78rem; color: var(--ink-faint); }
.program .p-method {
  display: inline-block; margin-top: .35rem;
  background: var(--accent-soft); color: var(--accent-ink);
  border-radius: 6px; padding: .1rem .5rem; font-size: .82rem; font-weight: 600;
}
.p-numbers {
  display: grid; gap: .1rem 1.2rem; margin: .7rem 0 0;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.p-numbers div { font-size: .88rem; }
.p-numbers dt { font-size: .74rem; color: var(--ink-faint); }
.p-numbers dd { margin: 0; font-weight: 600; }
.p-priorities { margin: .7rem 0 0; padding-left: 1.1rem; font-size: .87rem; color: var(--ink-soft); }
.p-priorities li { margin-bottom: .1rem; }
.p-eligibility { font-size: .87rem; color: var(--ink-soft); margin: .55rem 0 0; max-width: none; }

.section-note { font-size: .88rem; color: var(--ink-faint); margin: .2rem 0 1rem; max-width: 46rem; }

/* ---- Cards, notes, tables ---------------------------------------- */

.card {
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-radius: 10px; padding: 1.25rem; box-shadow: var(--shadow);
}

.note-box {
  border-left: 3px solid var(--rule-strong); background: var(--paper-sunken);
  padding: .85rem 1rem; border-radius: 0 8px 8px 0;
  font-size: .89rem; color: var(--ink-soft); margin: 1.5rem 0; max-width: 46rem;
}
.note-box strong { color: var(--ink); }
.note-box.caution { border-left-color: var(--warn); background: var(--warn-soft); }
.note-box p:last-child { margin-bottom: 0; }
.note-box p { max-width: none; }

.table-wrap {
  overflow-x: auto; border: 1px solid var(--rule);
  border-radius: 10px; background: var(--paper-raised);
}
table { border-collapse: collapse; width: 100%; font-size: .92rem; }
th, td { padding: .55rem .8rem; text-align: left; white-space: nowrap; }
thead th {
  position: sticky; top: 0; z-index: 2; background: var(--paper-sunken);
  border-bottom: 1px solid var(--rule-strong);
  font-size: .78rem; color: var(--ink-soft); font-weight: 700;
}
tbody tr + tr td { border-top: 1px solid var(--rule); }
tbody tr:hover td { background: var(--paper-sunken); }
td.num, th.num { text-align: right; }
td.name, th.name { white-space: normal; min-width: 14rem; }
td.wrap-cell { white-space: normal; min-width: 18rem; }

th.sortable { cursor: pointer; user-select: none; }
th.sortable::after { content: "\2195"; opacity: .3; margin-left: .35rem; font-size: .9em; }
th[aria-sort="ascending"]::after  { content: "\2191"; opacity: 1; }
th[aria-sort="descending"]::after { content: "\2193"; opacity: 1; }

.table-tools { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; margin-bottom: .75rem; }

code {
  font-family: var(--mono); font-size: .9em; background: var(--paper-sunken);
  padding: .1em .35em; border-radius: 4px; border: 1px solid var(--rule);
}
.code-block {
  background: var(--paper-sunken); border: 1px solid var(--rule);
  border-radius: 8px; padding: .9rem 1rem; overflow-x: auto; max-width: var(--measure);
}
.code-block code { background: none; border: 0; padding: 0; }

/* ---- Comparison --------------------------------------------------- */

/* Schools are rows and measures are columns. With a dozen schools the other way
   round is unreadable, and a row per school is the shape a shortlist actually
   has. No row is ever marked as better than another. */
.compare-table td.value { font-variant-numeric: tabular-nums; }
.compare-table th.school { min-width: 12rem; white-space: normal; }

/* Long measure names are the hard part of this table. Three things together,
   rather than truncating and hiding the name:
     a fixed narrow column, so headers cannot each choose their own width;
     the qualifier and unit on a quieter second line;
     bottom alignment, so however many lines a header takes, every header ends
     on the same baseline and the row reads as one band instead of a ragged
     edge. Wrapping is unavoidable at this length. Made deliberate, it stops
     looking like an accident. */
.compare-table thead th.num {
  width: 11rem; min-width: 11rem; max-width: 11rem;
  white-space: normal; vertical-align: bottom;
  font-size: .74rem; line-height: 1.22;
  padding-top: .7rem;
  /* No hyphenation. Breaking "Index" into "In-dex" to save a few pixels makes
     a reader stop and reassemble the word, which costs more than the line it
     saved. Words break between words only. */
  hyphens: none;
  overflow-wrap: normal;
  /* Even the lines out rather than leaving one orphan word on the last line,
     which is what makes a wrapped header look accidental. Ignored by browsers
     that do not support it, with no fallback needed. */
  text-wrap: balance;
}
.compare-table .th-main { display: block; }
.compare-table .th-sub {
  display: block; margin-top: .15rem;
  font-weight: 500; font-size: .72rem; color: var(--ink-faint);
  text-transform: none; letter-spacing: 0;
}

/* The school name stays put while the measures scroll under it. Without this,
   scrolling right leaves a grid of numbers with nothing to attach them to. */
.compare-table th[scope="row"] {
  white-space: normal; min-width: 13rem; font-weight: 600;
  position: sticky; left: 0; z-index: 1;
  background: var(--paper-raised);
  box-shadow: 1px 0 0 var(--rule);
}
.compare-table tbody tr:hover th[scope="row"] { background: var(--paper-sunken); }
.compare-table thead th:first-child {
  position: sticky; left: 0; z-index: 3;
  background: var(--paper-sunken);
  box-shadow: 1px 0 0 var(--rule-strong);
}
.compare-table td.value .cell-band {
  display: inline-block; border-radius: 5px; padding: .05rem .4rem; font-weight: 600;
}
.compare-table .period { font-size: .76rem; color: var(--ink-faint); display: block; }
.compare-picker { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.picked-measures { display: flex; flex-wrap: wrap; gap: .4rem; margin: .6rem 0 0; padding: 0; list-style: none; }
.chosen { display: flex; flex-wrap: wrap; gap: .5rem; margin: .75rem 0 0; padding: 0; list-style: none; }
.chosen li {
  display: flex; align-items: center; gap: .5rem;
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-radius: 999px; padding: .2rem .3rem .2rem .8rem; font-size: .88rem;
}
.chosen button {
  border: 0; background: var(--paper-sunken); color: var(--ink-soft);
  border-radius: 999px; width: 1.5rem; height: 1.5rem; cursor: pointer;
  font: inherit; line-height: 1;
}
.chosen button:hover { background: var(--warn-soft); color: var(--warn); }

/* ---- Downloads ---------------------------------------------------- */

.downloads { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); padding: 0; list-style: none; }
.download {
  display: block; height: 100%; background: var(--paper-raised);
  border: 1px solid var(--rule); border-radius: 10px; padding: 1.1rem 1.2rem;
  text-decoration: none; color: inherit;
}
.download:hover { border-color: var(--accent); }
.download h3 { margin: 0 0 .3rem; font-size: 1.02rem; }
.download p { margin: 0; font-size: .89rem; color: var(--ink-soft); max-width: none; }
.download .size { font-family: var(--mono); font-size: .78rem; color: var(--ink-faint); }

/* ---- Home entry points -------------------------------------------- */
/* The landing page is a search box and a way in. It carries no citywide
   statistics: a number about all of New York answers a question nobody came
   here with, and it would be the one figure on the site with no school
   attached to it. */

.entry-grid {
  display: grid; gap: .6rem; padding: 0; margin: .75rem 0 0; list-style: none;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.entry {
  display: block; text-decoration: none; color: inherit;
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-radius: 9px; padding: .7rem .9rem;
}
.entry:hover { border-color: var(--accent); }
.entry .e-name { display: block; font-weight: 600; }
.entry .e-count { display: block; font-size: .8rem; color: var(--ink-faint); }

.chapters { display: grid; gap: 1rem; margin: 2rem 0; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); padding: 0; list-style: none; }
.chapters a {
  display: block; height: 100%; background: var(--paper-raised);
  border: 1px solid var(--rule); border-radius: 10px; padding: 1.1rem 1.2rem;
  text-decoration: none; color: inherit;
}
.chapters a:hover { border-color: var(--accent); }
.chapters h3 { margin: 0 0 .3rem; font-size: 1.02rem; color: var(--ink); }
.chapters p { margin: 0; font-size: .89rem; color: var(--ink-soft); max-width: none; }

/* ---- Footer ------------------------------------------------------- */

.footer {
  border-top: 1px solid var(--rule); margin-top: 4rem; padding: 2rem 0 3rem;
  font-size: .87rem; color: var(--ink-faint);
}
.footer p { max-width: 42rem; }
.footer a { color: var(--ink-soft); }
.footer a:hover { color: var(--accent); }
.footer-grid { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.footer h4 {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-faint); margin: 0 0 .5rem;
}
.footer ul { list-style: none; padding: 0; margin: 0; }
.footer li { margin-bottom: .25rem; }
.colophon { margin-top: 1.5rem; font-size: .82rem; }

@media print {
  .masthead, .nav, .table-tools, .controls { display: none; }
  body { background: #fff; color: #000; }
  .card, .table-wrap { box-shadow: none; }
}

/* ---- Glossary ----------------------------------------------------- */
/* Definition lists read better than paragraphs for terms someone is
   scanning for, and this one exists because three of four design reviewers
   asked what a comparison group was. */

.glossary { margin: 1.25rem 0 2rem; max-width: 44rem; }
.glossary dt {
  font-weight: 700; margin-top: 1.1rem; font-family: var(--mono);
  font-size: .95rem;
}
.glossary dd { margin: .2rem 0 0; color: var(--ink-soft); }

abbr[title] { text-decoration: underline dotted; cursor: help; }

/* ---- The comparison sheet -------------------------------------------- */
/* One sheet: schools across the top, every fact down the side in labelled
   groups. The schools stay pinned while the sheet scrolls, because a figure
   two hundred rows down is useless if you cannot see whose column it is in. */

.sheet-wrap { max-height: 80vh; overflow: auto; border: 1px solid var(--rule); border-radius: 9px; }
.spec-sheet { width: 100%; border-collapse: separate; border-spacing: 0; font-size: .93rem; }

.spec-sheet th, .spec-sheet td {
  padding: .5rem .75rem; text-align: left; vertical-align: baseline;
  border-bottom: 1px solid var(--rule);
}

/* Two sticky axes meet at the corner, which needs the highest layer of the
   three or the school names slide underneath it. */
.spec-sheet thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--paper-sunken); vertical-align: bottom;
  border-bottom: 1px solid var(--rule-strong);
}
.spec-sheet thead th.corner {
  left: 0; z-index: 3;
  font-size: .72rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-faint);
}
.spec-sheet .school-head { min-width: 9rem; text-align: right; }
/* The column a first school will land in, held open so the sheet does not
   change shape the moment one is chosen. */
.spec-sheet .school-head.ghost { color: var(--ink-faint); font-weight: 400; }
.spec-sheet td.ghost { background: repeating-linear-gradient(
  -45deg, transparent, transparent 6px, var(--paper-sunken) 6px, var(--paper-sunken) 7px); }
.spec-sheet .school-head a { text-decoration: none; font-weight: 600; }
.spec-sheet .school-head a:hover { text-decoration: underline; }

/* The label column is the axis a reader keeps their place on, so it stays put
   while the schools scroll sideways. */
.spec-sheet th.spec-label, .spec-sheet thead th.corner {
  position: sticky; left: 0;
  min-width: 14rem; max-width: 20rem;
  background: var(--paper-raised); font-weight: 500; white-space: normal;
}
.spec-sheet th.spec-label { z-index: 1; box-shadow: 1px 0 0 var(--rule); }
.spec-sheet thead th.corner { box-shadow: 1px 0 0 var(--rule-strong); }

/* A group heading spans the sheet and breaks the list into sections, the way
   a profile groups the same measures. */
.spec-sheet tr.group th {
  position: sticky; left: 0;
  background: var(--paper-sunken); color: var(--ink-soft);
  font-size: .72rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
  border-top: 1px solid var(--rule-strong);
  padding-top: .7rem; padding-bottom: .45rem;
}

.spec-sheet tbody tr:hover td { background: var(--paper-sunken); }
.spec-sheet tbody tr:hover th.spec-label { background: var(--paper-sunken); }

.spec-sheet td { text-align: right; font-variant-numeric: tabular-nums; }
.spec-sheet td.muted { font-variant-numeric: normal; font-size: .86rem; }
.spec-sheet .cell-band {
  display: inline-block; border-radius: 5px; padding: .05rem .4rem; font-weight: 600;
}
.spec-sheet .period { display: block; font-size: .76rem; color: var(--ink-faint); }
.spec-sheet .th-main { display: block; }
.spec-sheet .th-sub {
  display: block; font-size: .76rem; font-weight: 400; color: var(--ink-faint);
}

/* Below about 34rem the label column would leave no room for a single figure,
   so it stops being sticky and simply narrows. */
@media (max-width: 34rem) {
  .spec-sheet th.spec-label, .spec-sheet thead th.corner { position: static; min-width: 9rem; }
  .spec-sheet th.spec-label { box-shadow: none; }
}

/* The status line under the search doubles as the place a refused action is
   reported, so it needs to read as a message rather than as a caption. */
.hint.warned { color: var(--warn); font-weight: 600; }

