/* The Framing Compass — one stylesheet, no framework. */

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-400.ttf') format('truetype');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-600.ttf') format('truetype');
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-700.ttf') format('truetype');
  font-weight: 700;
  font-display: swap;
}

:root {
  /* Names match ensoul.so's tokens wherever both sites need the same thing, so the two can be read
     side by side and a dark override here is the same edit as there. `--paper`/`--ink` are kept as
     aliases because the rest of this file already speaks them. */
  --bg-primary: #fdfcfa;
  --bg-secondary: #ffffff;
  --bg-tertiary: #f4f2ef;
  --surface: #ffffff;
  --text-primary: #111111;
  --text-muted: rgba(17, 17, 17, 0.58);
  --border: rgba(17, 17, 17, 0.1);
  --border-mid: rgba(17, 17, 17, 0.14);

  --paper: var(--bg-primary);
  --ink: var(--text-primary);
  --muted: var(--text-muted);
  --faint: var(--border);
  --hairline: var(--border-mid);

  /* The quadrant colours are the instrument, not the brand. They stay identical in both themes so
     that a card, a screenshot and the site all agree on what pink means. */
  --pink: #f7b8c4;
  --pink-s: #e79aab;
  --blue: #8ed4f2;
  --blue-s: #6cc3e8;
  --green: #cfe6bd;
  --green-s: #bcd8a6;
  --yellow: #f7f3a8;
  --yellow-s: #ebe368;
  --radius: 12px;
  --wrap: 720px;
  --sans: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  /* The accent is the warm stone from ensoul.so, where it is the sitewide accent. It was referenced
     by the filter chips and the profile fields before it was ever defined here, so those rendered
     unstyled. */
  --accent-stone: #605C58;
  --accent-hi: #55514D;
  --lift: 0 10px 34px rgba(17, 17, 17, 0.05);
  --grain: rgba(17, 17, 17, 0.045);
  --nav-bg: rgba(253, 252, 250, 0.86);
  /* Body tiers. These were hardcoded rgba(17,17,17,…) in a dozen rules, which is why dark mode
     rendered the hero and the reading as near-black on near-black — the tokens above adapted and
     these did not. */
  --text-body: rgba(17, 17, 17, 0.8);
  --text-soft: rgba(17, 17, 17, 0.75);
  --rule: rgba(17, 17, 17, 0.35);
  --ring: rgba(17, 17, 17, 0.3);
  --focus: rgba(17, 17, 17, 0.18);
  --hairline-soft: rgba(17, 17, 17, 0.12);
  --tint: rgba(17, 17, 17, 0.025);
}

/* Dark. The same token values as ensoul.so's dark theme, so the two sites match when toggled
   together — including the lifted secondary text, which the site raised to #9E9E9E so that muted
   can sit below it and still pass AA. */
html.dark {
  --bg-primary: #161616;
  --bg-secondary: #1c1c1c;
  --bg-tertiary: #252525;
  --surface: #1c1c1c;
  --text-primary: #ebebeb;
  --text-secondary: #9e9e9e;
  --text-muted: #8c8c8c;
  --border: rgba(255, 255, 255, 0.07);
  --border-mid: rgba(255, 255, 255, 0.12);
  --accent-stone: #a09588;
  --accent-hi: #aaa093;
  --lift: 0 16px 34px -22px rgba(0, 0, 0, 0.5);
  --grain: rgba(255, 255, 255, 0.035);
  --nav-bg: rgba(22, 22, 22, 0.82);
  --text-body: rgba(235, 235, 235, 0.82);
  --text-soft: rgba(235, 235, 235, 0.78);
  --rule: rgba(255, 255, 255, 0.32);
  --ring: rgba(255, 255, 255, 0.34);
  --focus: rgba(255, 255, 255, 0.22);
  --hairline-soft: rgba(255, 255, 255, 0.14);
  --tint: rgba(255, 255, 255, 0.04);
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  font-feature-settings: 'kern' 1, 'liga' 1;
  -webkit-font-smoothing: antialiased;
}

/* A very faint paper grain, so flat colour blocks do not look like a spreadsheet. */
.grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.5;
  background-image: radial-gradient(var(--grain) 1px, transparent 0);
  background-size: 3px 3px;
}

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 22px; position: relative; z-index: 1; }
.wrap.wide { max-width: 1060px; }

a { color: inherit; text-decoration-color: var(--faint); text-underline-offset: 3px; }
a:hover { text-decoration-color: currentColor; }

/* ensoul.so sets Inter for everything, headings included. A serif here read as a cousin rather than
   a sibling, so the display face is Inter too, with tighter tracking at size. */
h1, h2, h3 { font-family: var(--sans); font-weight: 600; letter-spacing: -0.022em; line-height: 1.12; margin: 0 0 0.5em; }
h1 { font-size: clamp(2.1rem, 6vw, 3.4rem); }
h2 { font-size: clamp(1.5rem, 3.4vw, 2rem); }
h3 { font-size: 1.15rem; }
p { margin: 0 0 1.1em; }
.lede { font-size: 1.18rem; color: var(--text-soft); }
.muted { color: var(--muted); }
.small { font-size: 0.88rem; }
.fineprint { font-size: 0.8rem; color: var(--muted); line-height: 1.5; }

/* ---------- header / footer ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--nav-bg);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--hairline);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* min-height rather than height: on a narrow screen the nav cannot fit beside the brand, and a
     fixed height made it overflow — the toggle ended up underneath the nav and could not be tapped,
     which is how this was found. It wraps to a second row instead and the header grows. */
  min-height: 58px;
  flex-wrap: wrap;
  padding: 10px 0;
}
.brand { display: inline-flex; align-items: center; gap: 9px; font-weight: 600; text-decoration: none; font-size: 0.95rem; letter-spacing: -0.01em; }
.mark { display: block; }
.site-header nav { display: flex; align-items: center; gap: 20px; font-size: 0.9rem; flex-wrap: wrap; }
.site-header nav a { text-decoration: none; color: var(--muted); }
.site-header nav a[aria-current='page'], .site-header nav a:hover { color: var(--ink); }
.site-header nav a[aria-current='page'] { font-weight: 600; }

.site-footer { margin-top: 72px; padding: 30px 0 54px; border-top: 1px solid var(--hairline); }
.footer-line { font-size: 0.9rem; color: var(--muted); max-width: 62ch; }

/* ---------- hero ---------- */

.hero { padding: 54px 0 12px; }
.hero h1 { margin-bottom: 0.35em; }
.hero .lede { max-width: 58ch; }

.eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-stone);
  font-weight: 600;
  margin-bottom: 18px;
}

/* ---------- the matrix ---------- */

.matrix { display: block; width: 100%; height: auto; }
.matrix-figure { margin: 26px 0; }
.matrix-frame {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  /* Symmetric padding: the labels sit inside the SVG's viewBox, so this is breathing room rather
     than space the labels depend on. */
  padding: 16px;
  box-shadow: var(--lift);
}
/* The SVG's viewBox covers the grid PLUS the four labels that hang outside it, so the whole figure —
   grid and labels together — fits the frame by itself. Do NOT give the SVG a square aspect ratio to
   "make the grid bigger": that maps the grid onto the container's width while the labels are pushed
   outside the element, and they get clipped to "son" and "T". The labels are sized so they stay
   legible at the frame widths this layout actually produces (~11px of label on a 340px phone,
   ~21px on a desktop). */

.quadrant-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 26px 0; }
.quadrant-card { border: 1px solid var(--hairline); border-radius: 12px; padding: 14px 15px; background: var(--surface); }
.quadrant-card .swatch { width: 100%; height: 6px; border-radius: 3px; margin-bottom: 11px; }
.quadrant-card h3 { font-family: var(--sans); font-size: 0.95rem; font-weight: 600; margin-bottom: 4px; }
.quadrant-card p { font-size: 0.86rem; color: var(--muted); margin: 0; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--accent-stone);
  color: #fff;
  border: 1px solid var(--accent-stone);
  border-radius: 999px;
  padding: 13px 26px;
  font: inherit;
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.12s ease, opacity 0.12s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn[disabled] { opacity: 0.4; cursor: not-allowed; transform: none; }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--hairline); }
.btn.small { padding: 9px 17px; font-size: 0.86rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin: 26px 0; }

/* ---------- survey ---------- */

.survey-head { padding: 34px 0 6px; }
.survey-head h1 { font-size: clamp(1.7rem, 4.4vw, 2.4rem); }

.progress {
  position: sticky;
  /* Sits directly beneath the 58px header; see the scroll-margin note on .q. */
  top: 58px;
  z-index: 15;
  background: var(--nav-bg);
  backdrop-filter: blur(10px);
  padding: 12px 0 10px;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 8px;
}
.progress-row { display: flex; align-items: center; gap: 14px; }
.progress-track { flex: 1; height: 4px; background: var(--faint); border-radius: 2px; overflow: hidden; }
.progress-fill { height: 100%; width: 0; background: var(--ink); border-radius: 2px; transition: width 0.25s ease; }
.progress-label { font-size: 0.8rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

.q {
  padding: 30px 0 26px;
  border-bottom: 1px solid var(--faint);
  /* The header is sticky. Without this, scrolling a question to the top of the viewport leaves its
     first answer row underneath the bar, where a tap lands on the header instead of the radio. */
  scroll-margin-top: 96px;
}
.q:last-of-type { border-bottom: 0; }
.q-axis {
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 9px;
}
.q-text { font-size: 1.16rem; line-height: 1.45; margin: 0 0 18px; }
.q[data-answered='true'] .q-text { color: var(--ink); }

.scale { display: flex; flex-direction: column; gap: 7px; }
.scale-opt {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  cursor: pointer;
  font-size: 0.93rem;
  background: var(--surface);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.scale-opt:hover { border-color: var(--rule); }
.scale-opt input { position: absolute; opacity: 0; pointer-events: none; }
.scale-dot {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1.5px solid var(--ring);
  flex: 0 0 auto;
  transition: all 0.12s ease;
}
.scale-opt input:checked ~ .scale-dot { border-color: var(--ink); border-width: 5px; }
.scale-opt:has(input:checked) { border-color: var(--ink); background: var(--tint); }
.scale-opt input:focus-visible ~ .scale-dot { box-shadow: 0 0 0 3px var(--focus); }

.survey-actions { padding: 30px 0 10px; }
.survey-actions .fineprint { max-width: 60ch; }
.honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.error-box {
  border: 1px solid #d4574f;
  background: rgba(212, 87, 79, 0.07);
  color: #8f2f28;
  padding: 12px 15px;
  border-radius: 10px;
  font-size: 0.9rem;
  margin: 16px 0;
}

/* ---------- results ---------- */

.result-hero { padding: 40px 0 0; }
.quadrant-name { font-size: clamp(2.2rem, 7vw, 3.2rem); margin-bottom: 0.15em; }
.result-thesis { font-size: 1.2rem; color: var(--text-soft); font-weight: 500; margin-bottom: 1.2em; }
.detail { max-width: 60ch; color: var(--text-body); }

.stat-row { display: flex; flex-wrap: wrap; gap: 26px; margin: 26px 0 8px; }
.stat { min-width: 120px; }
.stat dt { font-size: 0.72rem; letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.stat dd { margin: 5px 0 0; font-size: 1.25rem; font-weight: 600; font-variant-numeric: tabular-nums; }

.share-card-preview { border: 1px solid var(--hairline); border-radius: var(--radius); overflow: hidden; background: var(--surface); margin: 22px 0; }
.share-card-preview img { display: block; width: 100%; height: auto; }

.copy-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.copy-field {
  flex: 1 1 240px;
  min-width: 0;
  padding: 11px 14px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  font: inherit;
  font-size: 0.86rem;
  background: var(--surface);
  color: var(--muted);
}
.copied { color: #2f7d4f; font-size: 0.84rem; font-weight: 600; }

.compare { border-left: 3px solid var(--faint); padding-left: 16px; margin: 30px 0; }

/* ---------- map ---------- */

.map-head { padding: 40px 0 10px; }
.map-layout { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: 34px; align-items: start; margin-top: 20px; }
@media (max-width: 820px) { .map-layout { grid-template-columns: 1fr; } }

.legend-list { list-style: none; padding: 0; margin: 0 0 26px; }
.legend-list li { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--faint); }
.legend-list li:last-child { border-bottom: 0; }
.legend-swatch { width: 20px; height: 20px; border-radius: 4px; flex: 0 0 auto; border: 1px solid var(--hairline-soft); }
.legend-name { flex: 1; font-size: 0.94rem; }
.legend-share { font-variant-numeric: tabular-nums; font-weight: 600; }
.legend-count { font-size: 0.8rem; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 54px; text-align: right; }

.quote-list { list-style: none; padding: 0; margin: 0; }
.quote-list li { padding: 16px 0; border-bottom: 1px solid var(--faint); }
.quote-list li:last-child { border-bottom: 0; }
.quote-text { font-size: 0.98rem; margin: 0 0 7px; }
.quote-meta { font-size: 0.78rem; color: var(--muted); display: flex; align-items: center; gap: 8px; }
.quote-chip { width: 10px; height: 10px; border-radius: 3px; border: 1px solid var(--hairline-soft); }

/* ---------- method ---------- */

.prose { max-width: 66ch; }
.prose h2 { margin-top: 1.9em; }
.prose ul { padding-left: 1.2em; }
.prose li { margin-bottom: 0.5em; }
.callout { border: 1px solid var(--hairline); border-left: 3px solid var(--ink); border-radius: 10px; padding: 16px 18px; background: var(--surface); margin: 24px 0; }
.callout p:last-child { margin-bottom: 0; }

table.qtable { width: 100%; border-collapse: collapse; font-size: 0.88rem; margin: 18px 0; }
table.qtable th, table.qtable td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--faint); vertical-align: top; }
table.qtable th { font-size: 0.72rem; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
table.qtable td.dim { color: var(--muted); white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  .btn:hover { transform: none; }
}

/* ---------- map / results filters ---------- */

.filter-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 0; }
.filter-chip {
  display: inline-flex;
  align-items: center;
  padding: 7px 15px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  font-size: 0.85rem;
  text-decoration: none;
  color: var(--muted);
  background: var(--surface);
  transition: border-color 0.12s ease, color 0.12s ease;
}
.filter-chip:hover { border-color: var(--ring); color: var(--ink); }
.filter-chip.is-active { background: var(--accent-stone); border-color: var(--accent-stone); color: #fff; font-weight: 600; }

/* ---------- optional profile block ---------- */

.profile-field { margin: 0 0 14px; max-width: 420px; }
.profile-label { display: block; font-size: 0.86rem; font-weight: 600; margin-bottom: 6px; }
.profile-select {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  font: inherit;
  font-size: 0.92rem;
  background: var(--surface);
  color: var(--ink);
}
.profile-select:focus-visible { outline: 2px solid var(--accent-stone); outline-offset: 1px; }

/* ---------- already answered ---------- */

.already {
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 30px 26px;
  margin: 30px 0 50px;
  box-shadow: var(--lift);
}
.already h2 { margin-bottom: 0.4em; }
.already .btn-row { margin: 20px 0 6px; }

/* ---------- theme toggle ---------- */

.theme-toggle {
  background: none;
  border: 1px solid var(--border-mid);
  border-radius: 8px;
  color: var(--muted);
  cursor: pointer;
  font-size: 0.82rem;
  padding: 6px 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: color 0.15s, border-color 0.15s;
  font-family: inherit;
}
.theme-toggle:hover { color: var(--accent-stone); border-color: var(--accent-stone); }
.theme-toggle .toggle-icon { font-size: 0.9rem; line-height: 1; }

/* ---------- dark-theme corrections ---------- */

/* The matrix keeps its quadrant colours, but the white dot halo was tuned for a light page and
   glows oddly on a dark one. */
html.dark .matrix-frame { box-shadow: 0 16px 34px -22px rgba(0, 0, 0, 0.55); }

/* Form controls do not inherit color-scheme everywhere, so the text inside them is set explicitly. */
html.dark textarea,
html.dark input[type='text'],
html.dark select { color: var(--ink); }

/* The active filter chip uses the stone accent with white text in light mode; in dark the accent is
   a light stone, so the text has to flip to stay legible. */
html.dark .filter-chip.is-active { color: #161616; }

/* The share card is a PNG rendered with a light background by design — it is posted to social
   timelines where a dark card would be the odd one out. Give it a light mat so it does not look
   like a rendering fault on a dark page. */
html.dark .share-card-preview { background: var(--bg-tertiary); }

@media (max-width: 760px) {
  /* Brand on the first row, the links and the theme toggle on the second. The header grows to fit
     rather than clipping, and everything stays tappable. */
  .header-inner { gap: 8px; }
  .brand { font-size: 0.9rem; }
  .site-header nav { gap: 14px; width: 100%; justify-content: space-between; font-size: 0.86rem; }
  .theme-toggle { padding: 5px 9px; }
  /* The header is two rows here, so the sticky offsets below it have to clear the taller bar. */
  .progress { top: 92px; }
  .q { scroll-margin-top: 130px; }
}
