/* ==========================================================================
   PrepMora — base layer
   Tokens, reset, typography, and the primitives shared by every page.
   ========================================================================== */

/* --- Font fallback ------------------------------------------------------ */

/* Shown until the web fonts arrive, sized to their metrics so text does not
   re-wrap when they swap in. Without it the home page's lede grew a line on
   phones and pushed everything below it 28px down (PageSpeed mobile CLS
   0.204, 2026-10-09). size-adjust = web font width / Arial width over the
   public pages' own text, tuned at 375px until 388 of 391 text blocks
   wrapped identically. Bricolage's 600 and 700 differ because its optical
   size makes small headings wider. */
@font-face {
  font-family: "Public Sans Fallback";
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("Arimo"), local("Helvetica");
  font-weight: 100 549;
  size-adjust: 104.5%;
  ascent-override: 90.9%;
  descent-override: 22%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Public Sans Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("Arimo Bold"), local("Helvetica Bold");
  font-weight: 550 900;
  size-adjust: 98.5%;
  ascent-override: 96.4%;
  descent-override: 23.4%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Bricolage Fallback";
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("Arimo"), local("Helvetica");
  font-weight: 100 549;
  size-adjust: 100.4%;
  ascent-override: 92.6%;
  descent-override: 26.9%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Bricolage Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("Arimo Bold"), local("Helvetica Bold");
  font-weight: 550 649;
  size-adjust: 101%;
  ascent-override: 92.1%;
  descent-override: 26.7%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Bricolage Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("Arimo Bold"), local("Helvetica Bold");
  font-weight: 650 900;
  size-adjust: 97.3%;
  ascent-override: 95.6%;
  descent-override: 27.7%;
  line-gap-override: 0%;
}

/* --- Theme tokens ------------------------------------------------------- */

:root {
  color-scheme: dark;

  /* Surfaces: near-black with a green cast so turquoise belongs to the family */
  --bg: #060f0e;
  --bg-deep: #030908;
  --surface: #0c1a18;
  --surface-2: #112320;
  --surface-3: #17302c;
  --line: #1b322d;
  --line-soft: #132522;

  /* Ink */
  --text: #e4f1ee;
  --text-2: #a3bdb7;
  --text-3: #6b8983;

  /* Accent */
  --accent: #2fe3c6;
  --accent-2: #12a88f;
  --accent-ink: #04211c;
  --accent-wash: rgba(47, 227, 198, 0.12);
  --accent-line: rgba(47, 227, 198, 0.28);

  /* Domain identity — one hue per SAT domain, used as a card spine */
  --d-1: #4c8dff;
  --d-2: #a97bff;
  --d-3: #ff9f5a;
  --d-4: #2fe3c6;

  /* Status */
  --good: #3fd68c;
  --warn: #ffb454;
  --bad: #ff6f6f;
  --good-wash: rgba(63, 214, 140, 0.13);
  --warn-wash: rgba(255, 180, 84, 0.13);
  --bad-wash: rgba(255, 111, 111, 0.13);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 18px 40px -24px rgba(0, 0, 0, 0.9);
  --shadow-3: 0 28px 70px -30px rgba(0, 0, 0, 0.95);

  /* Type */
  --font-display: "Bricolage Grotesque", "Bricolage Fallback", "Segoe UI", system-ui, sans-serif;
  --font-body: "Public Sans", "Public Sans Fallback", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* Question typography — deliberately fixed at 16px */
  --q-size: 16px;
  --q-leading: 1.75;
  --q-measure: 68ch;

  /* Space (4px base) */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s7: 32px;
  --s8: 40px;
  --s9: 56px;
  --s10: 72px;
  --s11: 96px;

  /* Radius */
  --r1: 8px;
  --r2: 12px;
  --r3: 16px;
  --r4: 22px;
  --rp: 999px;

  --sidebar-w: 264px;
  --page-max: 1180px;
}

[data-theme="light"] {
  color-scheme: light;

  --bg: #f1f6f5;
  --bg-deep: #e6eeec;
  --surface: #ffffff;
  --surface-2: #f4f8f7;
  --surface-3: #e9f1ef;
  --line: #dce8e5;
  --line-soft: #e9f0ee;

  /* Every colour used as text clears 4.5:1 on every light surface, the
     washes included (--bg-deep is the hardest). Before 2026-10-24 --text-3,
     --accent, --good and --warn sat at 3.2-4.0:1 and --bad dipped to 4.0:1;
     white button text on --accent was 4.0:1, now 5.6:1. Same hues, deeper. */
  --text: #08201c;
  --text-2: #456058;
  --text-3: #526b65;

  --accent: #057563;
  --accent-2: #04614f;
  --accent-ink: #ffffff;
  --accent-wash: rgba(11, 143, 121, 0.09);
  --accent-line: rgba(11, 143, 121, 0.24);

  --d-1: #2f6fe0;
  --d-2: #6a3fc8;
  --d-3: #d97a2b;
  --d-4: #0b9d85;

  --good: #0b744a;
  --warn: #8f5a0a;
  --bad: #b83636;
  --good-wash: rgba(18, 145, 93, 0.1);
  --warn-wash: rgba(184, 115, 22, 0.1);
  --bad-wash: rgba(207, 63, 63, 0.1);

  --shadow-1: 0 1px 2px rgba(12, 40, 34, 0.06);
  --shadow-2: 0 16px 34px -22px rgba(12, 40, 34, 0.34);
  --shadow-3: 0 26px 60px -28px rgba(12, 40, 34, 0.4);
}

/* --- Reset -------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg {
  display: block;
  max-width: 100%;
}

/* Component classes set `display`, which would otherwise beat the UA rule for
   [hidden]. Everything toggled from JS relies on this winning. */
[hidden] {
  display: none !important;
}

/* Two fractions on consecutive lines (\dfrac, <br>, \dfrac) touched: the upper
   denominator ran into the lower numerator, because a line box ends exactly at
   a tall inline formula's edge (Practice Test #3 math1:21, 2026-09-26). An
   inline-block's margin box counts toward its line box, so a formula carrying a
   fraction or an array gets air above and below it. Display math keeps KaTeX's
   own block margins. Same rule in bluebook.css and exam.css. */
:not(.katex-display) > .katex:has(.mfrac, .mtable) {
  display: inline-block;
  margin: 0.25em 0;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

h1,
h2,
h3,
h4,
p {
  margin: 0;
}

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

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: var(--s6) 0;
}

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

::selection {
  background: var(--accent);
  color: var(--accent-ink);
}

/* --- Typography --------------------------------------------------------- */

.display-xl,
.display,
.h1,
.h2,
.h3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.028em;
  line-height: 1.04;
}

.display-xl {
  font-size: clamp(2.6rem, 6.2vw, 4.6rem);
  line-height: 0.98;
  letter-spacing: -0.038em;
}

.display {
  font-size: clamp(1.9rem, 3.6vw, 2.85rem);
  letter-spacing: -0.032em;
}

.h1 {
  font-size: 1.75rem;
  font-weight: 600;
}

.h2 {
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.h3 {
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.35;
}

.eyebrow {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--text-3);
  line-height: 1.4;
}

.eyebrow-accent {
  color: var(--accent);
}

.lede {
  font-size: 1.0625rem;
  line-height: 1.7;
  color: var(--text-2);
}

.muted {
  color: var(--text-2);
}

.dim {
  color: var(--text-3);
}

.small {
  font-size: 0.875rem;
  line-height: 1.55;
}

.tiny {
  font-size: 0.8125rem;
  line-height: 1.5;
}

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}

.accent-text {
  color: var(--accent);
}

/* --- Buttons ------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  padding: 11px 18px;
  border-radius: var(--rp);
  border: 1px solid transparent;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.008em;
  white-space: nowrap;
  transition: background-color 0.16s ease, border-color 0.16s ease,
    color 0.16s ease, transform 0.16s ease, box-shadow 0.16s ease;
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 0 0 1px var(--accent-line), 0 10px 26px -14px var(--accent);
}

.btn-primary:hover {
  background: color-mix(in oklab, var(--accent) 88%, #ffffff);
}

.btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--text);
}

.btn-ghost:hover {
  border-color: var(--accent-line);
  background: var(--accent-wash);
  color: var(--accent);
}

.btn-quiet {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--text-2);
}

.btn-quiet:hover {
  color: var(--text);
  border-color: var(--text-3);
}

.btn-sm {
  padding: 7px 13px;
  font-size: 0.8125rem;
}

.btn-lg {
  padding: 14px 26px;
  font-size: 1rem;
}

.btn-block {
  width: 100%;
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--accent);
  font-size: 0.8125rem;
  font-weight: 600;
}

.link-arrow svg {
  transition: transform 0.16s ease;
}

.link-arrow:hover svg {
  transform: translateX(3px);
}

/* --- Surfaces ----------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r3);
  box-shadow: var(--shadow-1);
}

.card-pad {
  padding: var(--s6);
}

.card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s5);
  margin-bottom: var(--s5);
}

/* Domain spine — a 3px rule that encodes which SAT domain a card belongs to */
.spine {
  position: relative;
  overflow: hidden;
}

.spine::before {
  content: "";
  position: absolute;
  inset: 14px auto 14px 0;
  width: 3px;
  border-radius: var(--rp);
  background: var(--spine, var(--accent));
}

.spine-1 {
  --spine: var(--d-1);
}
.spine-2 {
  --spine: var(--d-2);
}
.spine-3 {
  --spine: var(--d-3);
}
.spine-4 {
  --spine: var(--d-4);
}

/* --- Chips, tags, badges ------------------------------------------------ */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: var(--rp);
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-2);
  letter-spacing: 0.01em;
}

.chip-accent {
  border-color: var(--accent-line);
  background: var(--accent-wash);
  color: var(--accent);
}

.chip-good {
  border-color: transparent;
  background: var(--good-wash);
  color: var(--good);
}

.chip-warn {
  border-color: transparent;
  background: var(--warn-wash);
  color: var(--warn);
}

.chip-bad {
  border-color: transparent;
  background: var(--bad-wash);
  color: var(--bad);
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: var(--rp);
  background: currentColor;
  flex: none;
}

/* --- Forms -------------------------------------------------------------- */

.field {
  display: block;
  margin-bottom: var(--s5);
}

.field-label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 7px;
}

.input,
.select,
.textarea {
  width: 100%;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  font-size: 0.9375rem;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.input::placeholder,
.textarea::placeholder {
  color: var(--text-3);
}

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
}

.select {
  appearance: none;
  padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 55%, calc(100% - 12px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.field-hint {
  font-size: 0.8125rem;
  color: var(--text-3);
  margin-top: 6px;
}

.field-input-wrap {
  position: relative;
}

.field-input-wrap .input {
  padding-right: 44px;
}

.eye-btn {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--r2);
  color: var(--text-3);
  transition: color 0.15s ease;
}

.eye-btn:hover {
  color: var(--accent);
}

/* --- Segmented control -------------------------------------------------- */

.segment {
  display: inline-flex;
  padding: 4px;
  gap: 2px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--rp);
}

.segment button {
  padding: 7px 16px;
  border-radius: var(--rp);
  font-size: 0.8438rem;
  font-weight: 600;
  color: var(--text-3);
  transition: background-color 0.16s ease, color 0.16s ease;
}

.segment button:hover {
  color: var(--text);
}

.segment button[aria-selected="true"] {
  background: var(--accent);
  color: var(--accent-ink);
}

/* --- The signature: 400–1600 score rail --------------------------------- */

.rail {
  --rail-pct: 50%;
  --rail-target: 75%;
  display: block;
  width: 100%;
}

.rail-track {
  position: relative;
  height: 8px;
  border-radius: var(--rp);
  background: var(--surface-3);
  overflow: visible;
}

.rail-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--rail-pct);
  border-radius: var(--rp);
  background: linear-gradient(90deg, var(--accent-2), var(--accent));
  transition: width 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}

.rail-target {
  position: absolute;
  top: -6px;
  bottom: -6px;
  left: var(--rail-target);
  width: 2px;
  background: var(--text-3);
  border-radius: var(--rp);
}

.rail-marker {
  position: absolute;
  top: 50%;
  left: var(--rail-pct);
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border-radius: var(--rp);
  background: var(--accent);
  border: 3px solid var(--bg);
  box-shadow: 0 0 0 1px var(--accent), 0 0 22px -2px var(--accent);
  transition: left 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}

.rail-ticks {
  display: flex;
  justify-content: space-between;
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--text-3);
  letter-spacing: 0.02em;
}

/* --- Progress bars ------------------------------------------------------ */

.bar {
  height: 6px;
  border-radius: var(--rp);
  background: var(--surface-3);
  overflow: hidden;
}

/* display: block because most fills are spans (inside a button, or written
   inline by the page scripts), and an inline span ignores width and height:
   until 2026-10-12 every span fill on the site drew empty. */
.bar-fill {
  display: block;
  height: 100%;
  border-radius: var(--rp);
  background: var(--accent);
  width: 0;
  transition: width 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

/* --- Tables ------------------------------------------------------------- */

.table-wrap {
  overflow-x: auto;
}

.table {
  min-width: 640px;
}

.table th {
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 0 var(--s4) var(--s3);
  white-space: nowrap;
}

.table td {
  padding: var(--s4);
  border-top: 1px solid var(--line-soft);
  font-size: 0.9063rem;
  vertical-align: middle;
}

.table tbody tr {
  transition: background-color 0.14s ease;
}

.table tbody tr:hover {
  background: var(--surface-2);
}

.table .num-cell {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.875rem;
}

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

.stack > * + * {
  margin-top: var(--s5);
}

.stack-tight > * + * {
  margin-top: var(--s3);
}

.stack-loose > * + * {
  margin-top: var(--s7);
}

.row {
  display: flex;
  align-items: center;
  gap: var(--s3);
}

.row-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
}

.wrap {
  flex-wrap: wrap;
}

.grow {
  flex: 1;
  min-width: 0;
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5);
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s5);
}

.grid-4 {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s4);
}

.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;
}

.skip-link {
  position: absolute;
  left: var(--s4);
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: var(--rp);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
  transition: top 0.16s ease;
}

.skip-link:focus {
  top: var(--s4);
}

/* --- Brand mark --------------------------------------------------------- */

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 10px;
  background: linear-gradient(150deg, var(--accent), var(--accent-2));
  color: var(--accent-ink);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.0625rem;
  letter-spacing: -0.04em;
  box-shadow: 0 8px 22px -12px var(--accent);
}

.brand-name {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.035em;
}

.brand-name em {
  font-style: normal;
  color: var(--accent);
}

/* A school's wide logo (brand.js logoShape: a wordmark that already says
   the name) stands alone, larger. Three classes, so it wins over each
   page's own 34px .brand-logo rule (app.css, site.css, parent.html). */
.brand .brand-logo.brand-logo-wide {
  width: auto;
  height: auto;
  max-width: 190px;
  max-height: 48px;
  border-radius: 0;
}

.sidebar .brand .brand-logo.brand-logo-wide {
  max-height: 60px;
}

/* A school address on its first visit: PrepMora's logo and name stay blank
   until brand.js knows the school's (at most four seconds). */
.brand-wait [data-brand-slot],
.brand-wait [data-brand-name] {
  visibility: hidden;
}

/* Dark ink on a clear background: light on the dark theme, as it is on
   the light theme and on paper. */
:root:not([data-theme="light"]) .brand-logo-mono {
  filter: invert(0.94);
}

@media print {
  .brand-logo-mono {
    filter: none !important;
  }
}

@media (min-width: 768px) and (max-width: 960px) {
  .sidebar .brand .brand-logo.brand-logo-wide {
    max-width: 72px;
  }
}

/* PrepMora's own logo: the seal + a vector wordmark (brand/build_logo.py
   writes both inline). A white-label company keeps .brand-mark above. */
.brand-seal {
  display: block;
  width: 34px;
  height: 34px;
  flex: none;
  color: var(--text);
}

.brand-seal svg,
.brand-word svg {
  display: block;
  width: 100%;
  height: 100%;
}

.brand-word {
  display: block;
  height: 25px;
  aspect-ratio: 146.88 / 38;
  color: var(--text);
}

/* --- Motion ------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media (max-width: 900px) {
  .grid-3,
  .grid-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: minmax(0, 1fr);
  }
}
