/* jzero.fun — phosphor terminal, restrained.
   Two families, two accents, no build step. */

@font-face {
  font-family: "Space Grotesk";
  src: url("fonts/space-grotesk.woff2") format("woff2-variations");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --ground: #0A0E0F;
  --raised: #111617;
  --rule: #232A2B;
  --text: #E8E6E0;
  --text-dim: #9AA39F;
  --phosphor: #39FF14;
  --amber: #FFB000;

  --sans: "Space Grotesk", "Trebuchet MS", "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", "DejaVu Sans Mono", Consolas, monospace;

  /* Body measure. 34rem measured at 61.8 characters per line on this face,
     under the 65 to 75 band; 37rem lands at 67 to 72 across the three prose
     pages. Space Grotesk has an unusually wide "0", so its 1ch overstates the
     real average advance by about a third: measure characters, not ch. */
  --measure: 37rem;
  --step: 1.5rem;

  /* Label rank. These are not steps of the display scale, they are one rank in
     three legibility contexts, so they sit close together on purpose. The
     >=1.25 ratio rule applies to h1/h2/h3/body below. */
  --fs-label: 0.75rem;   /* 12.0px  uppercase mono: eyebrow, dt, thead, nav */
  --fs-small: 0.85rem;   /* 13.6px  mono running text */
  --fs-table: 0.95rem;   /* 15.2px  table body cells */
}

/* Light recompute. Every text token here is measured against both --ground and
   --raised at WCAG 2.2 AAA (7:1); the darker --raised is the binding case.
   The phosphor reference is held, its chroma reduced only as far as the floor
   demands. See PRODUCT.md principle 4. */
@media (prefers-color-scheme: light) {
  :root {
    --ground: #F4F2EC;
    --raised: #EBE8E0;
    --rule: #D6D2C8;
    --text: #14181A;
    --text-dim: #464C4A;
    --phosphor: #135704;
    --amber: #684300;
  }
}

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

@media (min-width: 40rem) {
  body { font-size: 18px; }
}

.wrap {
  width: 100%;
  max-width: 46rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* ---- links and focus ---- */

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: color 160ms linear;
}

a:hover { color: var(--phosphor); }

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

/* ---- masthead ---- */

.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.75rem;
  padding: 1.25rem;
  border-bottom: 1px solid var(--rule);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  font-weight: 600;
  letter-spacing: -0.01em;
}

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

.brand .mark { color: var(--phosphor); }

.mark {
  display: block;
  width: 1.5em;
  height: 1.5em;
  flex: none;
}

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* 0.75rem mono gives a 20px line box, under the 24px minimum in WCAG 2.2
   SC 2.5.8. The padding grows the hit area and the negative margin gives it
   back to the layout, so the masthead keeps its height. */
.nav a {
  text-decoration: none;
  color: var(--text-dim);
  display: inline-block;
  padding-block: 0.25rem;
  margin-block: -0.25rem;
}
.nav a:hover { color: var(--text); }
/* The current page is marked twice. Colour alone will not do it: --phosphor and
   --text-dim were both tuned to clear 7:1 and land at the same relative
   luminance, so in the light scheme they differ in hue only and are one swatch
   to a deuteranope. Separating them further would drag the green toward black
   and cost the phosphor reference more than it buys, so the underline is the
   carrier and the colour is the reinforcement. PRODUCT.md: colour is never the
   sole carrier of meaning. */
.nav a[aria-current="page"] {
  color: var(--phosphor);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.35em;
}

@media (max-width: 26rem) {
  .nav {
    flex: 1 0 100%;
    margin-left: 0;
    gap: 0.35rem 0.9rem;
  }
  .masthead { gap: 0.75rem 1rem; padding: 1rem 1.25rem; }
}

/* ---- the mark's one animation ---- */

@media (prefers-reduced-motion: no-preference) {
  .mark-ring {
    animation: ring-resolve 380ms cubic-bezier(0.4, 0, 0.2, 1) 1;
  }
  @keyframes ring-resolve {
    from { stroke-dasharray: 0 144.5; }
    to   { stroke-dasharray: 120 24.5; }
  }
}

/* ---- type ---- */

h1, h2, h3 {
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: clamp(2.1rem, 8vw, 3.4rem); }
h2 { font-size: clamp(1.4rem, 4.5vw, 1.9rem); }
/* Was 1.05rem, which rendered at 16.8px against an 18px body: the third
   heading level was smaller than the text it introduced. 1.45rem restores the
   rank and clears 1.25 against both neighbours (h2/h3 1.31, h3/body 1.29). */
h3 { font-size: 1.45rem; }

p { margin: 0 0 1.1em; max-width: var(--measure); }
h1 + p, h2 + p, h3 + p, .scroller + p { margin-top: 0.85rem; }
h2 + .cores, .lede + .cores, h2 + .scroller, h1 + .suites, .lede + .suites { margin-top: 1.5rem; }
.hero h1 + p { margin-top: 0; }
p:last-child { margin-bottom: 0; }

.lede { font-size: 1.12em; }
.dim { color: var(--text-dim); }

.eyebrow {
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0 0 0.9rem;
}

code, .mono { font-family: var(--mono); font-size: 0.9em; }

/* ---- sections ---- */

main { padding: calc(var(--step) * 2) 0 calc(var(--step) * 3); }

section + section {
  margin-top: calc(var(--step) * 2.5);
  padding-top: calc(var(--step) * 2.5);
  border-top: 1px solid var(--rule);
}

/* ---- hero: must clear a 360x640 viewport ---- */

.hero {
  padding: calc(var(--step) * 1.5) 0 0;
}

.hero h1 { margin-bottom: 0.6rem; }

.hero .lede { margin-bottom: 0.9rem; }

/* Three mono lines under the claim, in the order a reader needs them: what the
   board is, where the project actually stands, what the mark means. The accent
   sits on the standing, not on the motto. Amber is already this project's
   colour for a state that is not yet confirmed (see .status). */
.hero .runs,
.hero .standing,
.tagline {
  font-family: var(--mono);
  font-size: var(--fs-small);
  letter-spacing: 0.04em;
  margin: 0;
}

.hero .runs { color: var(--text-dim); }
.hero .standing { color: var(--amber); margin-top: 0.5rem; }
.tagline { color: var(--text-dim); margin-top: 1.4rem; }

/* ---- suites catalogue ----
   auto-fill so one card sits at its natural width and six wrap cleanly. */

.suites {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 27rem));
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.suite {
  border: 1px solid var(--rule);
  background: var(--raised);
  padding: 1.4rem;
}

.suite h3 { margin-bottom: 0.9rem; }

.suite dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.45rem 1.1rem;
  margin: 0;
  font-family: var(--mono);
  font-size: var(--fs-small);
  line-height: 1.5;
}

.suite dt {
  color: var(--text-dim);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: var(--fs-label);
  padding-top: 0.15em;
}

.suite dd { margin: 0; }

.status { color: var(--amber); }

/* ---- ceiling table ---- */

/* The table cannot reflow below 34rem without breaking the tier/platform/
   verdict reading, so it scrolls. A scroll container is not reachable by
   keyboard unless it is focusable, so tabindex="0" is load-bearing here, not
   decoration: without it the clipped columns are mouse-only. */
.scroller {
  overflow-x: auto;
  border: 1px solid var(--rule);
}

/* Announced by the region label; shown only where the table actually
   overflows. 34rem of table plus 2 x 1.25rem of .wrap gutter is 36.5rem, so
   37rem is the measured threshold rather than a guessed one. */
.scrollnote {
  display: none;
  font-family: var(--mono);
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0 0 0.75rem;
}

@media (max-width: 36.5625rem) {
  .scrollnote { display: block; }
}

table {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  font-size: var(--fs-table);
}

/* Was a <caption> inside the table, which put the one line explaining what the
   table is inside the horizontal scroll box: on a phone it was clipped, and it
   scrolled away from the rows it describes. It is now a sibling above the
   scroller, and names the table through aria-labelledby, so it reads without
   scrolling and still names the table to a screen reader. */
.tablenote {
  font-family: var(--mono);
  font-size: var(--fs-small);
  color: var(--text-dim);
  max-width: var(--measure);
  margin: 0 0 0.75rem;
}

th, td {
  text-align: left;
  vertical-align: top;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--rule);
}

thead th {
  font-family: var(--mono);
  font-size: var(--fs-label);
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
}

tbody tr:last-child th, tbody tr:last-child td { border-bottom: 0; }

tbody th {
  font-family: var(--mono);
  font-size: var(--fs-small);
  font-weight: 400;
  white-space: nowrap;
}

.tier-comfortable { color: var(--phosphor); }
.tier-marginal { color: var(--amber); }
.tier-out { color: var(--text-dim); }

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

/* ---- cores list ---- */

/* Two columns held these when each row was a bare core name. Each row now
   carries the core's role from CONOPS.md 4.6, so the list is a term/definition
   pair and gets laid out as one. */
.cores {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.6rem;
  font-family: var(--mono);
  font-size: var(--fs-small);
}

.cores li {
  display: grid;
  grid-template-columns: minmax(0, 13rem) 1fr;
  gap: 0.15rem 1.25rem;
}

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

@media (max-width: 34rem) {
  .cores li { grid-template-columns: 1fr; }
}

/* Where the numbers on this page come from. PRODUCT.md names a second reader:
   someone who already knows the project and is checking whether the site still
   tells the truth about it. This line is for them. */
.provenance {
  font-size: var(--fs-small);
  margin-top: 2.25rem;
}

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

.foot {
  border-top: 1px solid var(--rule);
  padding: 1.5rem 0 2.5rem;
  font-family: var(--mono);
  font-size: var(--fs-small);
  color: var(--text-dim);
}

.foot p { margin: 0; max-width: none; }
