/* ============================================================================
   GREA · v6-optic
   Macrostructure 20 · Ecosystem Index
   Accent: rose oklch(0.66 0.16 350) — one accent, kept under 3% of the viewport
   (measured: ~1% at rest, ~1.5% with a body selected).
   Faces: Fraunces (display) / IBM Plex Sans (body) / JetBrains Mono (outlier).

   The scene is the index. A core (the studio) carries eleven bodies on four
   shells, and the rail's five groups are exactly the core plus those four
   shells, inside to outside. Selecting a row or a body lights that shell's ring
   in the accent, flies the camera to the body, and swaps the reading column for
   the panel. Delete the canvas and the grouping loses its structure.

   Pre-emit self-critique (NOSLOP §9), scored 1-5:
     Philosophy 5  the shape is the subject: a holding company is bodies around
                   a core, so the page is that system and the HTML is its index.
     Hierarchy  4  h1, then the rail, then the panel. The core is the first thing
                   the eye lands on and the rail repeats it in reading order.
     Execution  5  three type sizes, hairline rules, no shadows, no blur, one
                   accent, leader lines instead of guesswork, all motion on
                   transform/opacity with named properties.
     Specificity 5 four shells, three of them chemistry and materials: sorbent
                   remediation, spent solvent, extraction. No other company's
                   index looks like this one.
     Restraint  4  removed the auto-rotating system, the spokes, the second glow
                   pass, the frosted panels and the third gradient stop. One
                   core, four rings, eleven bodies, one panel, one accent.
     Variety    5  the index is spatial and the reading column swaps with the
                   selection. Nothing here is a colour-swapped template.

   Gate check (NOSLOP §1-§8):
     no #000 / #fff  -> paper/ink tokens, all 0.008-0.016 chroma at h350
     no purple-cyan gradient, no gradient text, no aurora blobs, no lone orbs,
       no 3-column feature grid, no card-in-card, no fake browser chrome
     glassmorphism: none. The column scrims are two-stop paper-to-transparent
       gradients with no blur, and the text is inset past the fade, so the type
       always sits on paper.
     Inter/Roboto/system-ui: absent (audited). Roman display type only.
     transition: all absent. hover:scale absent. No hover-only affordances:
       every body is reachable from the rail, the rail is a real button list,
       and Escape closes. prefers-reduced-motion collapses the camera moves,
       freezes the shader clock and reduces the entrance to an opacity fade.
     overflow-x: clip on html and body. No two-line clickable text: a row's name
       is one line, the domain beside it is not a link.
     tabular-nums on every numeric column (rail numbers, tally, panel eyebrow).
     Two extra type/spacing tiers keep the index whole on short laptop viewports
       (<=880px and <=830px of viewport height, where a 1440x900 window lands).
   ========================================================================= */

:root{
  --paper:      oklch(0.155 0.012 350);
  --paper-2:    oklch(0.20 0.014 350);
  --paper-3:    oklch(0.25 0.016 350);
  --rule:       oklch(0.32 0.014 350);
  --ink-4:      oklch(0.58 0.012 350);
  --ink-3:      oklch(0.70 0.012 350);
  --ink-2:      oklch(0.84 0.010 350);
  --ink:        oklch(0.95 0.008 350);
  --accent:     oklch(0.66 0.16 350);
  --accent-2:   oklch(0.80 0.09 350);
  --accent-dim: oklch(0.52 0.14 350);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:  cubic-bezier(0.7, 0, 0.84, 0);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --d-micro: 120ms;
  --d-short: 220ms;
  --d-long:  420ms;

  --gutter: clamp(1rem, 2.6vw, 2.5rem);
  --rail-w: clamp(15rem, 24vw, 22.5rem);
  --read-w: clamp(16rem, 26vw, 24rem);

  --hair: color-mix(in oklab, var(--rule) 78%, transparent);
}

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

html{
  overflow-x: clip;
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
}
body{
  margin: 0;
  min-height: 100%;
  overflow-x: clip;
  overflow-y: hidden;
  background: var(--paper);
  color: var(--ink-3);
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 16px;
  line-height: 1.6;
  font-synthesis-weight: none;
}

ol,ul,dl{ margin: 0; padding: 0; list-style: none; }
p{ margin: 0; }
button{ font: inherit; color: inherit; background: none; border: 0; padding: 0; }
a{ color: var(--ink-2); text-decoration: underline; text-decoration-color: var(--rule); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover, a:focus-visible{ text-decoration-color: var(--accent); }
a:focus-visible, button:focus-visible{ outline: 1px solid var(--accent); outline-offset: 3px; }

/* ---------------------------------------------------------------- the scene */

.stage{
  position: fixed;
  inset: 0;
  z-index: 0;
  opacity: 0;
  transition: opacity var(--d-long) var(--ease-out);
}
.is-live .stage{ opacity: 1; }
.stage canvas{ display: block; width: 100%; height: 100%; cursor: grab; touch-action: none; }
.stage canvas.is-over{ cursor: pointer; }
.stage canvas.is-drag{ cursor: grabbing; }

/* ------------------------------------------------------------------ overlay */

.overlay{
  position: fixed;
  inset: 0;
  z-index: 2;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  padding: 0 var(--gutter);
  pointer-events: none;          /* the canvas below stays draggable */
}
.overlay a, .overlay button, .masthead, .rail, .read, .panel, .foot{
  pointer-events: auto;          /* only real boxes take the pointer */
}

.sheet{ display: contents; }

.labels{
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.leaders{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.leader{
  stroke: color-mix(in oklab, var(--ink-4) 88%, transparent);
  stroke-width: 1;
  fill: none;
}
.leader.is-on{ stroke: var(--accent); }
.leader.is-off{ display: none; }
.node-label{
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  gap: .4em;
  align-items: baseline;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .74rem;
  letter-spacing: .01em;
  line-height: 1.05;
  white-space: nowrap;
  color: var(--ink-2);
  /* a dark halo behind the type: the scene has bright glows in it and the
     labels have to stay readable over them */
  text-shadow: 0 0 2px var(--paper), 0 0 4px var(--paper), 0 1px 7px var(--paper);
  opacity: 0;
  transition: opacity var(--d-long) var(--ease-out), color var(--d-micro) linear;
  transition-delay: calc(var(--i, 0) * 22ms);
}
.is-live .node-label{ opacity: 1; }
.node-label.is-off{ opacity: 0; }
.node-label__no{ color: var(--ink-3); font-variant-numeric: tabular-nums; }
.node-label.is-on{ color: var(--accent); }
.node-label.is-on .node-label__no{ color: var(--accent-2); }
/* with a panel open, the untouched labels step back and the selection stays lit */
.is-detail .node-label{ opacity: .4; }
.is-detail .node-label.is-on{ opacity: 1; }

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

.masthead{
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--read-w);
  column-gap: var(--gutter);
  align-items: baseline;
  padding: 1.5rem 0 1.1rem;
}
.masthead__mark{ display: flex; align-items: baseline; gap: .8rem; min-width: 0; }
.masthead__word{
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: .06em;
  color: var(--ink);
}
.masthead__sub{
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .66rem;
  letter-spacing: .02em;
  color: var(--ink-4);
}
.masthead__nav{
  grid-column: 3;
  display: flex;
  gap: 1.1rem;
  justify-content: flex-end;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .68rem;
  letter-spacing: .02em;
}
.masthead__nav a{ color: var(--ink-3); text-decoration: underline; text-decoration-color: var(--rule); text-underline-offset: 3px; }
.masthead__nav a:hover, .masthead__nav a:focus-visible{ color: var(--ink-2); text-decoration-color: var(--accent); }

/* ------------------------------------------------------------------ the deck */

/* Legibility scrims. Two stops, no blur, no border: the scene's glow can kiss
   the inner margin of each column, while the type itself always sits on paper.
   The text is inset past the fade on purpose (see the column padding). */
.rail{ background: linear-gradient(to right, var(--paper) 0 88%, transparent 100%); }
.read, .panel{ background: linear-gradient(to left, var(--paper) 0 88%, transparent 100%); }

.deck{
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--read-w);
  column-gap: var(--gutter);
  min-height: 0;
  padding-bottom: 1.5rem;
}

.rail{
  grid-column: 1;
  grid-row: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
  padding-right: 3rem;
}
.rail__h2{
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: 1.35rem;
  line-height: 1;
  letter-spacing: -.01em;
  color: var(--ink);
  margin: 0 0 .6rem;
}
.group__h{
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: .59rem;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin: .7rem 0 .2rem;
}
.group:first-child .group__h{ margin-top: 0; }

.node{
  position: relative;
  display: grid;
  grid-template-columns: 1.7rem minmax(0, 1fr);
  align-items: baseline;
  column-gap: .3rem;
  padding: .26rem 0 .3rem;
  border-top: 1px solid var(--hair);
}
.node__no{
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .64rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
  color: var(--ink-4);
}
.node__col{ display: grid; gap: .1rem; min-width: 0; }
.node__name{
  justify-self: start;
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: .97rem;
  line-height: 1.15;
  text-align: left;
  color: var(--ink-2);
  cursor: pointer;
  transition: color var(--d-micro) linear;
}
.node__name::after{ content: ""; position: absolute; inset: 0; }     /* row-wide hit area, one line of text */
.node__dom{
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .62rem;
  line-height: 1.25;
  letter-spacing: .01em;
  color: var(--ink-4);
  overflow-wrap: anywhere;
}
.node:hover .node__name{ color: var(--ink); }
.node.is-active{ border-top-color: color-mix(in oklab, var(--accent) 45%, var(--rule)); }
.node.is-active .node__name{ color: var(--accent); }
.node.is-active::before{
  content: "";
  position: absolute;
  left: -1.35rem;
  top: .55rem;
  bottom: .6rem;
  width: 2px;
  background: var(--accent);
}
.rail__foot{
  margin-top: .75rem;
  padding-top: .55rem;
  border-top: 1px solid var(--hair);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .62rem;
  line-height: 1.5;
  color: var(--ink-4);
}

/* ------------------------------------------------------------- reading column */

.read, .panel{
  grid-column: 3;
  grid-row: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
  padding-left: 3.2rem;
  padding-right: .4rem;
}
.read{ transition: opacity var(--d-short) var(--ease-out); }
.read.is-away{ opacity: 0; pointer-events: none; }

.read__h1{
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: clamp(1.85rem, 1rem + 1.7vw, 2.6rem);
  line-height: 1.07;
  letter-spacing: -.018em;
  color: var(--ink);
  overflow-wrap: anywhere;
  min-width: 0;
  margin: 0;
}
.read__lede{ margin-top: .9rem; font-size: .92rem; line-height: 1.62; color: var(--ink-3); }
.tally{
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.05rem;
  margin-top: 1.3rem;
  padding: .72rem 0;
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .68rem;
  line-height: 1.95;
  letter-spacing: .01em;
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.tally b{ font-weight: 500; color: var(--ink); }
.read__fine{ margin-top: .55rem; font-size: .72rem; line-height: 1.55; color: var(--ink-4); }
.read__h2{
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: 1.12rem;
  line-height: 1.2;
  color: var(--ink-2);
  margin: 1.5rem 0 .6rem;
}
.caps{ display: grid; gap: .38rem; }
.caps li{
  position: relative;
  padding-left: 1.05rem;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--ink-3);
}
.caps li::before{
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: .5rem;
  height: 1px;
  background: color-mix(in oklab, var(--ink-4) 55%, transparent);
}
.read__hint{
  margin-top: 1.4rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .66rem;
  line-height: 1.6;
  color: var(--ink-4);
}

/* ------------------------------------------------------------- detail panel */

.panel{ opacity: 0; visibility: hidden; }
.panel.is-in{ opacity: 1; visibility: visible; transition: opacity var(--d-short) var(--ease-out); }
.panel__back{
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .66rem;
  letter-spacing: .02em;
  color: var(--ink-4);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1px;
  cursor: pointer;
  transition: color var(--d-micro) linear, border-color var(--d-micro) linear;
}
.panel__back:hover, .panel__back:focus-visible{ color: var(--ink-2); border-bottom-color: var(--accent); }
.panel__eyebrow{
  margin-top: 1.6rem;
  padding-top: .8rem;
  border-top: 1px solid var(--hair);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .64rem;
  letter-spacing: .04em;
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.panel__name{
  font-family: 'Fraunces', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: clamp(1.5rem, .9rem + 1.2vw, 2rem);
  line-height: 1.08;
  letter-spacing: -.015em;
  color: var(--ink);
  overflow-wrap: anywhere;
  margin: .7rem 0 0;
}
.panel__what{ margin-top: .8rem; font-size: .92rem; line-height: 1.62; color: var(--ink-3); }
.panel__facts{
  display: grid;
  grid-template-columns: minmax(6.4rem, auto) minmax(0, 1fr);
  gap: .2rem .9rem;
  margin-top: 1.2rem;
  padding-top: .8rem;
  border-top: 1px solid var(--hair);
}
.panel__facts dt{
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .64rem;
  line-height: 1.55;
  letter-spacing: .03em;
  color: var(--ink-4);
}
.panel__facts dd{ margin: 0 0 .35rem; font-size: .8rem; line-height: 1.5; color: var(--ink-2); }
.panel__go{ margin-top: 1.1rem; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: .72rem; }
.panel__go a{ color: var(--accent); text-decoration-color: color-mix(in oklab, var(--accent) 45%, transparent); }
.panel__none{ color: var(--ink-4); }

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

.foot{
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--read-w);
  column-gap: var(--gutter);
  align-items: end;
  padding: 1.1rem 0 1.4rem;
  border-top: 1px solid var(--hair);
}
.foot__lead{
  grid-column: 1 / 3;
  max-width: 52ch;
  font-size: .78rem;
  line-height: 1.5;
  color: var(--ink-4);
}
.foot__links{
  grid-column: 3;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0 .5rem;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: .68rem;
  line-height: 1.7;
  color: var(--ink-4);
  text-align: right;
}
.foot__links > *{ white-space: nowrap; }

/* --------------------------------------------------------- the opening moment */

@keyframes rise{ from{ opacity: 0; transform: translate3d(0, 7px, 0); } to{ opacity: 1; transform: none; } }
.masthead, .read > *, .rail__h2, .group, .rail__foot, .foot > *{
  animation: rise var(--d-long) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 26ms);
}
/* one stagger, capped: the last element starts 234ms after the first */
.masthead{ --i: 0; }
.read > :nth-child(1){ --i: 1; }
.read > :nth-child(2){ --i: 2; }
.read > :nth-child(3){ --i: 3; }
.read > :nth-child(4){ --i: 4; }
.read > :nth-child(5){ --i: 5; }
.read > :nth-child(6){ --i: 6; }
.read > :nth-child(7){ --i: 7; }
.rail__h2{ --i: 2; }
.rail__list > .group:nth-child(1){ --i: 4; }
.rail__list > .group:nth-child(2){ --i: 5; }
.rail__list > .group:nth-child(3){ --i: 6; }
.rail__list > .group:nth-child(4){ --i: 7; }
.rail__list > .group:nth-child(5){ --i: 8; }
.rail__foot{ --i: 9; }
.foot__lead{ --i: 5; }
.foot__links{ --i: 6; }

/* ------------------------------------------------------------------- tablet */

@media (max-width: 1023px){
  .overlay{ display: block; padding: 0; }

  .masthead{
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 1rem;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    padding: 1.1rem var(--gutter) .5rem;
    z-index: 3;
  }
  .masthead__nav{ grid-column: 2; }

  .sheet{
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 54vh;
    height: 54dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 3;
    padding: 1.4rem var(--gutter) 2.2rem;
    background: linear-gradient(to top, var(--paper) 0%, var(--paper) 68%, color-mix(in oklab, var(--paper) 62%, transparent) 100%);
    border-top: 1px solid var(--hair);
    scrollbar-width: thin;
    scrollbar-color: var(--rule) transparent;
  }

  .labels{ display: none; }

  .deck{ display: block; padding-bottom: 0; }
  .rail{ overflow: visible; padding-right: 0; margin-top: 1.7rem; background: none; }
  .read, .panel{ overflow: visible; padding-left: 0; padding-right: 0; background: none; }
  .panel{ margin-top: 0; }

  .read__h1{ font-size: clamp(1.9rem, 6.4vw, 2.5rem); }
  .tally{ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 .8rem; }
  .foot{ grid-template-columns: minmax(0, 1fr); align-items: start; padding: 1.1rem 0 0; }
  .foot__lead{ grid-column: 1; max-width: none; }
  .foot__links{ grid-column: 1; justify-content: flex-start; text-align: left; }

  .is-detail .read, .is-detail .rail{ display: none; }
}

@media (max-width: 420px){
  .masthead__sub{ display: none; }
  .masthead__nav{ gap: .85rem; }
}

/* ------------------------------------------------------------------ motion */

/* Short laptop viewports (a 1440x900 window has ~790-815px of viewport once
   the browser chrome is counted). The index has to stay whole, so the two
   columns tighten instead of scrolling a row out of sight. */
@media (min-width: 1024px) and (max-height: 880px){
  .masthead{ padding: 1.1rem 0 .8rem; }
  .foot{ padding: .8rem 0 1rem; }
  .foot__lead{ font-size: .72rem; }
  .deck{ padding-bottom: 1rem; }
  .rail__h2{ font-size: 1.25rem; margin-bottom: .6rem; }
  .group__h{ font-size: .57rem; margin: .6rem 0 .2rem; }
  .node{ padding: .2rem 0 .24rem; }
  .node__name{ font-size: .94rem; }
  .node__dom{ font-size: .6rem; }
  .rail__foot{ margin-top: .6rem; font-size: .6rem; }
  .read__h1{ font-size: clamp(1.7rem, .8rem + 1.5vw, 2.2rem); }
  .read__lede{ margin-top: .7rem; font-size: .88rem; line-height: 1.56; }
  .tally{ margin-top: 1rem; padding: .55rem 0; font-size: .64rem; line-height: 1.8; }
  .read__fine{ font-size: .68rem; }
  .read__h2{ font-size: 1rem; margin: 1.15rem 0 .45rem; }
  .caps{ gap: .3rem; }
  .caps li{ font-size: .78rem; }
  .read__hint{ margin-top: 1rem; font-size: .62rem; }
}

/* and again for the shortest laptop viewports */
@media (min-width: 1024px) and (max-height: 830px){
  .masthead{ padding: .95rem 0 .7rem; }
  .foot{ padding: .7rem 0 .9rem; }
  .rail__h2{ margin-bottom: .4rem; }
  .group__h{ margin: .45rem 0 .16rem; }
  .node{ padding: .12rem 0 .16rem; }
  .node__name{ font-size: .89rem; }
  .rail__foot{ margin-top: .45rem; }
  .read__lede{ font-size: .85rem; line-height: 1.52; }
  .caps li{ font-size: .75rem; }
  .read__h2{ margin: .95rem 0 .4rem; }
  .tally{ margin-top: .85rem; padding: .45rem 0; }
}

@media (prefers-reduced-motion: reduce){
  @keyframes rise{ from{ opacity: 0; } to{ opacity: 1; } }
  .masthead, .read > *, .rail__h2, .group, .rail__foot, .foot > *{
    animation-duration: var(--d-micro);
    animation-delay: 0ms;
  }
  .stage, .read, .panel, .node-label, .node__name, .panel__back{
    transition-duration: var(--d-micro);
    transition-delay: 0ms;
  }
}
