/* ============================================================================
   SKILLSPACE — fonts, reset, type, and the component vocabulary.

   Borrowed wholesale from XY Space's page grammar: EyebrowRow, SectionBand,
   NumberChip, BigStat, Pill, DisplayHeading, CTASection. Same shapes, evergreen
   instead of ultramarine.

   ONE RULE FROM THE SOURCE, INHERITED AND BINDING: white sections carry NOTHING
   but space and a soft vertical wash. No horizontal rules, no dot lattice, no
   radial colour. What separates a section from the one under it is the gap and
   the change in ground. Do not rule this paper.
   ========================================================================= */

@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 400; font-display: swap; src: url("/fonts/Satoshi-Regular.woff2") format("woff2"); }
@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 500; font-display: swap; src: url("/fonts/Satoshi-Medium.woff2") format("woff2"); }
@font-face { font-family: "Satoshi"; font-style: normal; font-weight: 700; font-display: swap; src: url("/fonts/Satoshi-Bold.woff2") format("woff2"); }
@font-face { font-family: "Archivo Narrow"; font-style: normal; font-weight: 500; font-display: swap; src: url("/fonts/ArchivoNarrow-Medium.woff2") format("woff2"); }
@font-face { font-family: "Archivo Narrow"; font-style: normal; font-weight: 600; font-display: swap; src: url("/fonts/ArchivoNarrow-SemiBold.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("/fonts/IBMPlexMono-Regular.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url("/fonts/IBMPlexMono-Medium.woff2") format("woff2"); }

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

body {
  margin: 0;
  background: var(--ss-paper);
  color: var(--ss-ink);
  font-family: var(--ss-font);
  font-size: var(--ss-t-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, canvas, video { max-width: 100%; display: block; }
[hidden] { display: none !important; }

/* Heavy weight is reserved for the hero, the wordmark and the footer. Anything
   else that reaches for 700 is competing with the one thing on the page that
   should be loudest. */
h1, h2, h3, h4 { margin: 0; font-weight: 500; letter-spacing: -0.02em; text-wrap: balance; line-height: 1.12; }
h1 { font-size: var(--ss-t-3xl); }
h2 { font-size: var(--ss-t-2xl); }
h3 { font-size: var(--ss-t-lg); letter-spacing: -0.01em; }
h4 { font-size: var(--ss-t-md); letter-spacing: 0; }
p  { margin: 0 0 1rem; max-width: var(--ss-measure); }
a  { color: inherit; text-decoration-color: color-mix(in srgb, currentColor 35%, transparent); text-underline-offset: 3px; }
a:hover { text-decoration-color: currentColor; }
:focus-visible { outline: 2px solid var(--ss-accent); outline-offset: 3px; border-radius: var(--ss-r-sm); }
.band--dark :focus-visible { outline-color: var(--ss-dark-mark); }

code, kbd, samp { font-family: var(--ss-font-mono); font-size: .875em; }
/* Inline code (a path such as ~/.claude/skills/skillspace/SKILL.md) has no break opportunity of its own, and widened /mcp
   by 22 px at 320 px: it may break anywhere. A code block keeps its lines and scrolls inside its own box. */
:not(pre) > code { overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- layout -- */
.container { width: 100%; max-width: var(--ss-max); margin-inline: auto; padding-inline: var(--ss-gutter); }
.container--narrow { max-width: 820px; }
.stack { display: flex; flex-direction: column; }
.section { padding-block: var(--ss-section); }

/* The soft vertical wash that is the ONLY thing a white section carries. */
.band { position: relative; }
.band--paper { background: var(--ss-paper); }
.band--paper::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,.022) 0%, transparent 22%, transparent 78%, rgba(0,0,0,.022) 100%);
}
.band--alt { background: var(--ss-paper-alt); }
.band--dark { background: var(--ss-dark); color: var(--ss-on-dark); }
.band--dark h1, .band--dark h2, .band--dark h3 { color: var(--ss-on-dark); }
.band--dark .lede, .band--dark .dim { color: var(--ss-on-dark-dim); }

/* --------------------------------------------------------------- eyebrow -- */
.eyebrow {
  font-family: var(--ss-font-label);
  font-size: var(--ss-t-xs);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin: 0 0 1rem;
  display: flex; align-items: center; gap: .6rem;
}
.eyebrow::before { content: ""; width: 22px; height: 2px; background: var(--ss-accent-mark); flex: none; border-radius: 2px; }
.band--dark .eyebrow::before { background: var(--ss-dark-mark); }

/* ------------------------------------------------------------------ type -- */
.display { font-size: var(--ss-t-hero); font-weight: 700; letter-spacing: -0.035em; line-height: 1.02; }
.lede { font-size: var(--ss-t-md); max-width: 60ch; }
.dim { color: #3a3a38; }
.band--dark .dim { color: var(--ss-on-dark-dim); }
.label { font-family: var(--ss-font-label); font-size: var(--ss-t-xs); font-weight: 600; letter-spacing: .13em; text-transform: uppercase; }
.mono { font-family: var(--ss-font-mono); font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------------- pills -- */
.pill {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--ss-font-label); font-size: var(--ss-t-xs); font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  padding: .3rem .7rem; border-radius: var(--ss-r-pill);
  border: 1px solid var(--ss-line); background: var(--ss-card); color: var(--ss-ink);
}
.pill--fill { background: var(--ss-accent); border-color: var(--ss-accent); color: #fff; }
.band--dark .pill { border-color: var(--ss-line-dark); background: transparent; color: var(--ss-on-dark); }
.band--dark .pill--fill { background: var(--ss-dark-mark); border-color: var(--ss-dark-mark); color: var(--ss-dark); }

/* --------------------------------------------------------------- buttons -- */
.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--ss-font); font-size: var(--ss-t-sm); font-weight: 500;
  padding: .7rem 1.15rem; border-radius: var(--ss-r-pill);
  border: 1px solid var(--ss-accent); background: var(--ss-accent); color: #fff;
  text-decoration: none; cursor: pointer; transition: background .16s ease, transform .16s ease;
}
.btn:hover { background: var(--ss-accent-deep); border-color: var(--ss-accent-deep); }
.btn:active { transform: translateY(1px); }
.btn--ghost { background: transparent; color: var(--ss-ink); border-color: var(--ss-line); }
.btn--ghost:hover { background: var(--ss-card); border-color: var(--ss-ink); }
.band--dark .btn { background: var(--ss-dark-mark); border-color: var(--ss-dark-mark); color: var(--ss-dark); }
.band--dark .btn:hover { background: var(--ss-dark-mark-2); border-color: var(--ss-dark-mark-2); }
.band--dark .btn--ghost { background: transparent; color: var(--ss-on-dark); border-color: var(--ss-line-dark); }
.band--dark .btn--ghost:hover { border-color: var(--ss-dark-mark); background: rgba(0,210,134,.08); }

/* ----------------------------------------------------------------- cards -- */
.card {
  background: var(--ss-card); border: 1px solid var(--ss-line);
  border-radius: var(--ss-r); padding: 1.5rem;
}
.band--dark .card { background: var(--ss-dark-2); border-color: var(--ss-line-dark); }
.grid { display: grid; gap: 1rem; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
/* An explicit pair. `auto-fit` on a four-item set fits three columns at desktop
   width and orphans the fourth on its own row, which reads as a mistake rather
   than a layout. Anything that is genuinely 2x2 asks for this instead. */
.grid--pair { grid-template-columns: 1fr; }
/* An explicit three. `auto-fit` fits four columns at desktop width, which breaks
   a six-item list as 4+2 and leaves a hole where the reader expects a row. */
.grid--three { grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid--three { grid-template-columns: 1fr 1fr; } }
@media (min-width: 940px) { .grid--three { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 760px) { .grid--pair { grid-template-columns: 1fr 1fr; } }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/* ------------------------------------------------------------ stat + chip -- */
.bigstat { display: flex; flex-direction: column; gap: .35rem; }
.bigstat__n { font-size: var(--ss-t-3xl); font-weight: 700; letter-spacing: -0.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.bigstat__k { font-family: var(--ss-font-label); font-size: var(--ss-t-xs); font-weight: 600; letter-spacing: .13em; text-transform: uppercase; }
.bigstat__sub { font-size: var(--ss-t-sm); }

.numchip {
  display: inline-grid; place-items: center; width: 1.9rem; height: 1.9rem; flex: none;
  border-radius: var(--ss-r-pill); background: var(--ss-accent); color: #fff;
  font-family: var(--ss-font-mono); font-size: var(--ss-t-xs); font-weight: 500;
}
.band--dark .numchip { background: var(--ss-dark-mark); color: var(--ss-dark); }

/* ---------------------------------------------------------------- grades -- */
.grade {
  display: inline-grid; place-items: center; width: 1.75rem; height: 1.75rem; flex: none;
  border-radius: var(--ss-r-sm); font-family: var(--ss-font-mono); font-weight: 500;
  font-size: var(--ss-t-sm); color: #fff;
}
.grade--a { background: var(--ss-grade-a); }
.grade--b { background: var(--ss-grade-b); }
.grade--c { background: var(--ss-grade-c); }
.grade--d { background: var(--ss-grade-d); }
.grade--f { background: var(--ss-grade-f); }

/* ---------------------------------------------------------------- tables -- */
.scroller { overflow-x: auto; border: 1px solid var(--ss-line); border-radius: var(--ss-r); background: var(--ss-card); }
.band--dark .scroller { border-color: var(--ss-line-dark); background: var(--ss-dark-2); }
table { border-collapse: collapse; width: 100%; font-size: var(--ss-t-sm); min-width: 560px; }
th, td { padding: .7rem .9rem; text-align: left; border-bottom: 1px solid var(--ss-line); vertical-align: middle; }
.band--dark th, .band--dark td { border-bottom-color: var(--ss-line-dark); }
thead th { font-family: var(--ss-font-label); font-size: var(--ss-t-xs); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-family: var(--ss-font-mono); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------- bar -- */
/* A score bar. The fill is the mark; the track is a hairline box. */
.bar { position: relative; height: .4rem; background: var(--ss-paper-alt); border-radius: var(--ss-r-pill); overflow: hidden; min-width: 60px; }
.band--dark .bar { background: rgba(255,255,255,.09); }
.bar__f { position: absolute; inset-block: 0; left: 0; background: var(--ss-accent); border-radius: inherit; }
.band--dark .bar__f { background: var(--ss-dark-mark); }

/* ------------------------------------------------------------------- nav -- */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--ss-paper) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--ss-line);
  transition: background .25s ease, border-color .25s ease, color .25s ease;
}

/* OVER THE HERO, THE NAV IS NOT A BAR.

   Every page opens on the ink ground, and a paper-coloured bar sitting on top of
   it reads as a separate object bolted above the page. So while the hero is still
   under it the nav goes fully transparent and borrows the hero's own colours,
   then fades its ground back in once the hero has scrolled away and there is
   paper underneath that the white text could not survive.

   The class is added by JS (see lib/site.js), which means the no-JS default is
   the SAFE one: an opaque paper bar with ink text, legible over anything. A
   transparent-by-default nav would strand white links on white paper the moment
   scripting failed. */
.nav--over-hero {
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
  color: var(--ss-on-dark);
}
.nav--over-hero .nav__brand { color: var(--ss-on-dark); }
.nav--over-hero .nav__links a { color: var(--ss-on-dark-dim); }
.nav--over-hero .nav__links a:hover,
.nav--over-hero .nav__links a[aria-current="page"] { color: var(--ss-on-dark); }
.nav--over-hero .nav__links a:hover { text-decoration-color: var(--ss-dark-mark); }
/* The wordmark tile and the primary action both flip to the on-dark accent,
   since deep evergreen on the ink ground is very close to invisible. */
.nav--over-hero .mark { background: var(--ss-dark-mark); }
.nav--over-hero .mark svg g { fill: var(--ss-dark); }
.nav--over-hero .nav__links .btn {
  background: var(--ss-dark-mark); border-color: var(--ss-dark-mark); color: var(--ss-dark);
}
.nav--over-hero .nav__links .btn:hover {
  background: var(--ss-dark-mark-2); border-color: var(--ss-dark-mark-2);
}
.nav--over-hero :focus-visible { outline-color: var(--ss-dark-mark); }
.nav__in { display: flex; align-items: center; gap: 1.5rem; height: var(--ss-nav-h); }
.nav__brand { display: flex; align-items: center; gap: .55rem; font-weight: 700; letter-spacing: -.02em; text-decoration: none; font-size: var(--ss-t-md); }
.nav__links { display: flex; gap: 1.25rem; margin-left: auto; align-items: center; }
/* The bar's own button is smaller than a page button. `.btn` is sized for a
   hero, and at that padding the pill stands 44px inside a 60px bar, leaving 8px
   of air above and below: it reads as jammed against the top of the window
   rather than sitting in a bar. */
.nav__links .btn { padding: .45rem .95rem; font-size: .8125rem; }
.nav__links a { font-size: var(--ss-t-sm); text-decoration: none; }
.nav__links a:hover { text-decoration: underline; text-decoration-color: var(--ss-accent-mark); }
/* The nav carries five items, which is one more than a 390px viewport can hold.
   Below 800px the two secondary links go; below 560px the leaderboard link goes
   too, leaving the wordmark, Benchmarks and the primary action. Measured at
   390px: without this the page overflows horizontally by 38px. */
@media (max-width: 800px) { .nav__links a.hide-sm { display: none; } }
@media (max-width: 560px) {
  .nav__in { gap: .75rem; }
  .nav__links { gap: .85rem; }
  .nav__links a.hide-xs { display: none; }
  .nav__links .btn { padding: .55rem .85rem; font-size: .8125rem; }
  .nav__brand { font-size: var(--ss-t-base); }
}

/* A FULL-HEIGHT HERO, on the homepage only.

   `min-height`, never `height`: on a short laptop window the content still has
   to be able to push the band taller rather than spill out of it.

   `svh` is the small-viewport unit, which is the height with mobile browser
   chrome VISIBLE. Plain `100vh` on iOS resolves to the LARGE viewport, so the
   bottom of the hero sits behind the address bar until the user scrolls. The
   `vh` line stays first as the fallback for anything that does not know `svh`.

   The band already carries a 60px transparent top border so it can run under the
   nav, and box-sizing is border-box everywhere here, so that border is inside
   this height. The centred content therefore centres in the space BELOW the bar,
   which is what the eye reads as centred. */
.hero--full {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
}
.hero--full > .container { width: 100%; }

/* The hero is text beside the graph on a wide screen and stacked below it on a
   narrow one. This rule used to live in a <style> block inside the page and was
   lost when the page was rewritten for the closed beta, which silently dropped
   the hero to one column at every width. It lives here now. */
.hero-grid { grid-template-columns: 1fr; }
@media (min-width: 940px) { .hero-grid { grid-template-columns: 1.05fr 1fr; } }

/* A full-height hero puts the fold exactly at its own bottom edge, so nothing
   tells the reader there is a page under it. This is the smallest honest cue:
   a hairline and an arrow, sitting in the band's own bottom padding. It is a
   link rather than decoration, so it works on a keyboard and actually goes
   somewhere. Hidden below 760px, where the hero already overflows the fold and
   the cue would be answering a question nobody has. */
.hero__cue {
  position: absolute; left: 50%; bottom: 1.5rem; transform: translateX(-50%);
  display: none; flex-direction: column; align-items: center; gap: .5rem;
  color: var(--ss-on-dark-dim); text-decoration: none;
}
@media (min-width: 760px) { .hero__cue { display: flex; } }
.hero__cue span {
  font-family: var(--ss-font-label); font-size: .6875rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
}
.hero__cue svg { width: 14px; height: 14px; animation: cue-bob 2.4s ease-in-out infinite; }
.hero__cue:hover { color: var(--ss-dark-mark); }
@keyframes cue-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(4px); } }
@media (prefers-reduced-motion: reduce) { .hero__cue svg { animation: none; } }

/* THE HERO HAS TO RUN UP UNDER THE NAV, or transparency buys nothing.

   `position: sticky` leaves the nav IN FLOW: it occupies the first 60px of the
   document and the hero begins beneath it. Making it transparent therefore
   exposed the BODY's paper ground, not the hero, and the bar still read as a
   white strip bolted above a dark page.

   So the opening dark band is pulled up by the nav's height and given a
   transparent border of the same height. The border-box background paints behind
   that border, so the ink ground extends up to y=0 while the band's content
   stays exactly where it was. This is safe with scripting off too: the nav is
   simply an opaque bar sitting on top of the band it now overlaps. */
main > section.band--dark:first-child,
main > article > header.band--dark:first-child {
  margin-top: calc(-1 * var(--ss-nav-h));
  border-top: var(--ss-nav-h) solid transparent;
}

/* The wordmark: a rounded evergreen tile with the S monogram, echoing the
   product icon rather than inventing a second identity. */
.mark { width: 26px; height: 26px; border-radius: 7px; background: var(--ss-accent); display: grid; place-items: center; flex: none; }
.mark svg { width: 13px; height: 13px; }
.band--dark .mark { background: var(--ss-dark-mark); }

/* ---------------------------------------------------------------- footer -- */
.footer { background: var(--ss-dark); color: var(--ss-on-dark); padding-block: 4rem 2.5rem; }
.footer a { color: var(--ss-on-dark-dim); text-decoration: none; font-size: var(--ss-t-sm); }
/* The footer is a dark ground but not a `.band--dark`, so the shared `.dim`
   (a grey chosen for paper) resolved to near-black on it. */
.footer .dim { color: var(--ss-on-dark-dim); }
.footer a:hover { color: var(--ss-dark-mark); }
.footer__top { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: center; justify-content: space-between; }
.footer__bot { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--ss-line-dark); display: flex; flex-wrap: wrap; gap: .6rem 2rem; font-size: var(--ss-t-xs); color: var(--ss-on-dark-dim); align-items: center; }
.footer__bot a { font-size: inherit; color: var(--ss-on-dark); text-decoration-color: color-mix(in srgb, currentColor 40%, transparent); }
.footer__bot a:hover { color: var(--ss-dark-mark); }
/* Were inline style attributes; classes let skill pages run a strict CSP. */
.footer .footer__brand, .footer .footer__brand:hover { color: #fff; margin-bottom: .75rem; }
.footer .footer__tagline { font-size: .875rem; max-width: 34ch; margin: 0; }
.footer .footer__legal { margin-left: auto; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ----------------------------------------------------------------- prose -- */
.prose { max-width: var(--ss-measure); }
.prose h2 { margin: 2.75rem 0 .85rem; font-size: var(--ss-t-xl); }
.prose h3 { margin: 2rem 0 .6rem; }
.prose ul, .prose ol { padding-left: 0; margin: 0 0 1rem; list-style: none; display: flex; flex-direction: column; gap: .5rem; }
.prose ul li { padding-left: 1.25rem; position: relative; }
.prose ul li::before { content: ""; position: absolute; left: 2px; top: .68em; width: 7px; height: 1px; background: var(--ss-accent-mark); }
.prose ol { counter-reset: n; }
.prose ol li { padding-left: 1.6rem; position: relative; counter-increment: n; }
.prose ol li::before { content: counter(n) "."; position: absolute; left: 0; font-family: var(--ss-font-mono); font-size: .85em; }
.prose blockquote { margin: 1.5rem 0; padding-left: 1.1rem; border-left: 2px solid var(--ss-accent-mark); font-size: var(--ss-t-md); }
.prose figure { margin: 2rem 0; }
.prose figcaption { font-size: var(--ss-t-xs); font-family: var(--ss-font-label); letter-spacing: .04em; margin-top: .6rem; color: #3a3a38; }
.prose img { border-radius: var(--ss-r); border: 1px solid var(--ss-line); }

/* ------------------------------------------------------------ shot frame -- */
/* Product screenshots sit in a frame, never bare on the page. */
.shot { border-radius: var(--ss-r); overflow: hidden; border: 1px solid var(--ss-line); background: var(--ss-card); }
.band--dark .shot { background: var(--ss-dark-2); border-color: var(--ss-line-dark); box-shadow: 0 24px 60px rgba(0,0,0,.45); }
/* That `background` is a contrast fix, not decoration. The frame's default ground
   is white, and `.shot__bar` on the ink band only adds rgba(255,255,255,.04) —
   which composites over white and stays white, dropping the bar's on-dark title
   colour to about 1.6:1. The frame has to carry the dark panel itself. */
.shot img { width: 100%; height: auto; }
/* `height: auto` is load-bearing, not tidiness. The markup carries width/height
   attributes so the browser can reserve space before the image arrives, and
   without `height: auto` the attribute wins over the intrinsic ratio: a 3200x2000
   shot rendered 562px wide was being given a 1000px-tall box and letterboxed
   inside it, which is where the page's blank gaps came from. */
.shot__bar { display: flex; align-items: center; gap: .4rem; padding: .55rem .8rem; border-bottom: 1px solid var(--ss-line); background: var(--ss-paper-alt); }
.band--dark .shot__bar { background: rgba(255,255,255,.04); border-bottom-color: var(--ss-line-dark); }
.shot__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ss-line); }
.band--dark .shot__dot { background: var(--ss-line-dark); }
.shot__t { margin-left: .5rem; font-family: var(--ss-font-mono); font-size: var(--ss-t-xs); color: #3a3a38; }
.band--dark .shot__t { color: var(--ss-on-dark-dim); }

/* --------------------------------------------------------- reveal on scroll */
.rise { opacity: 0; transform: translateY(14px); transition: opacity .6s ease, transform .6s ease; }
.rise.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .rise { opacity: 1; transform: none; transition: none; } }

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

/* ------------------------------------------------------------- skill graph --
   The ported org graph reads its palette from CSS custom properties on its own
   host, so it can be dropped onto any ground and stay legible. On the hero it
   sits on the ink band, where the page-level `--ss-ink` (true black) and
   `--ss-accent` (deep evergreen) would both paint invisibly. These scoped
   values are the dark-ground counterparts, and they are the same ones the
   desktop app's evergreen colourway uses so the two draw the same picture.

   Department hues encode GROUP, never identity — three groups, three hues,
   matching buckets.ts (Engineering / Growth / Product & Ops). */
[data-graph-wrap] {
  --ss-ink: #e6efec;          /* labels and counts on the ink ground */
  --ss-paper: #061a1a;        /* the ground the graph clears to */
  --ss-accent: #00d286;       /* the core node and live wiring */
  --ss-accent-soft: #2ce39c;
  --ss-dim: #8fa8a2;
  --ss-dim-link: #17403a;
  --ss-dim-node: #123433;
  --ss-line: #17403a;
  --ss-group-0: #00d286;      /* Engineering */
  --ss-group-1: #ffd23f;      /* Growth */
  --ss-group-2: #7c8cff;      /* Product & Ops */
  --ss-state-gap: #ff6b6b;
  --ss-state-dormant: #56706b;
  --ss-state-thin: #ffd23f;
  --ss-state-strong: #00d286;
}


/* ---------------------------------------------------------- harness row -- */
/* The agents Skillspace links skills into. Marks are set in currentColor so the
   row inherits whichever ground it sits on, which also keeps a set of very
   different brand colours from turning the row into a fruit salad. */
.harness {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 1rem 2.25rem; align-items: center;
}
.harness__item {
  display: flex; align-items: center; gap: .55rem;
  font-size: var(--ss-t-sm); color: var(--ss-ink); white-space: nowrap;
}
.band--dark .harness__item { color: var(--ss-on-dark-dim); }
.harness__item svg { flex: none; opacity: .9; }
/* Codex has no licensed mark, so its slot carries a wordmark sized to sit on the
   same baseline as the glyphs beside it. */
.harness__wordmark {
  display: inline-flex; align-items: center; height: 22px; flex: none;
  font-family: var(--ss-font-mono); font-size: 12px; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; opacity: .9;
}
.harness--hero { gap: .85rem 1.75rem; }
.harness--hero .harness__item { font-size: .8125rem; }


/* --------------------------------------------------------------- q-rows -- */
/* Modelled on XY Space's ComparisonRows: hairline-separated rows, a mono index
   beside the claim, and the answer in its own column. The rule is the structure,
   so there is no card, no shadow and no fill. Hover warms the top border toward
   the accent and nothing else moves. */
.qrows { display: flex; flex-direction: column; }
.qrow {
  display: grid; gap: .4rem 2.5rem;
  grid-template-columns: 1fr;
  border-top: 1px solid var(--ss-line);
  padding: 1.15rem 0;
  transition: border-color .3s ease;
}
.qrow:hover { border-top-color: var(--ss-accent-mark); }
@media (min-width: 780px) { .qrow { grid-template-columns: 2rem minmax(0,1fr) minmax(0,1fr); align-items: baseline; } }
.qrow__n {
  font-family: var(--ss-font-mono); font-size: .6875rem; letter-spacing: .22em;
  color: #6b6b67;
}
.qrow__q { font-size: var(--ss-t-md); }
.qrow__a { font-size: .9375rem; color: #3a3a38; }
.qrow__a b { font-weight: 500; color: var(--ss-ink); }

/* ------------------------------------------------------------ scatter -- */
/* Flat hairline panels, XY Space's CardGrid shape: they sit on the page rather
   than floating, and the gutter is tight enough to read as one object. */
/* Three across, so six cards read as 3+3. `auto-fit` fitted five and orphaned
   the sixth on its own row, which reads as a mistake rather than a grid. */
.scatter { display: grid; gap: .5rem; grid-template-columns: 1fr; }
@media (min-width: 620px) { .scatter { grid-template-columns: 1fr 1fr; } }
@media (min-width: 940px) { .scatter { grid-template-columns: repeat(3, 1fr); } }
.scatter__c {
  border: 1px solid var(--ss-line); background: var(--ss-card);
  border-radius: var(--ss-r-md); padding: 1.1rem 1.15rem;
  display: flex; flex-direction: column; gap: .55rem;
  transition: background .2s ease;
}
.scatter__c:hover { background: var(--ss-paper-alt); }
/* A fixed icon slot. Codex has no licensed mark and renders as a wordmark, which
   is a different shape from a 20px glyph; without a shared slot height its card's
   name dropped a line and the row lost its baseline. */
.scatter__i { height: 22px; display: flex; align-items: center; }
.scatter__c svg, .scatter__c .harness__wordmark { opacity: .85; }
.scatter__n { font-size: .9375rem; font-weight: 500; }
.scatter__p { font-family: var(--ss-font-mono); font-size: .75rem; color: #6b6b67; }


/* ------------------------------------------------------------- diagrams -- */
/* Hand-authored SVG rather than a chart library: these explain a mechanism, they
   do not plot data, and a library would ship 40kB to draw six rectangles.
   Colours come from the tokens so a diagram works on paper and on the ink
   ground without a second copy. */
.dgm { width: 100%; height: auto; display: block; }
.dgm text { font-family: var(--ss-font-label); font-size: 10px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.dgm .dgm-t { fill: var(--ss-ink); }
.band--dark .dgm .dgm-t { fill: var(--ss-on-dark); }
.dgm .dgm-d { fill: #6b6b67; }
.band--dark .dgm .dgm-d { fill: var(--ss-on-dark-dim); }
.dgm .dgm-box { fill: var(--ss-card); stroke: var(--ss-line); }
.band--dark .dgm .dgm-box { fill: var(--ss-dark-2); stroke: var(--ss-line-dark); }
.dgm .dgm-src { fill: var(--ss-accent); stroke: var(--ss-accent); }
.band--dark .dgm .dgm-src { fill: var(--ss-dark-mark); stroke: var(--ss-dark-mark); }
.dgm .dgm-on-src { fill: #fff; }
.band--dark .dgm .dgm-on-src { fill: var(--ss-dark); }
.dgm .dgm-wire { stroke: var(--ss-accent-mark); fill: none; opacity: .55; }
.band--dark .dgm .dgm-wire { stroke: var(--ss-dark-mark); }
.dgm .dgm-cut { stroke: var(--ss-grade-f); fill: none; }
.dgm figcaption, .dgm-cap {
  font-family: var(--ss-font-label); font-size: var(--ss-t-xs); letter-spacing: .04em;
  color: #6b6b67; margin-top: .75rem;
}
.band--dark .dgm-cap { color: var(--ss-on-dark-dim); }

/* The cap chart: intrinsic score, then what the security ceiling leaves. */
.capbar { display: grid; grid-template-columns: minmax(120px,1fr) 2fr 3.5rem; gap: .75rem; align-items: center; margin-bottom: .5rem; }
.capbar__t { position: relative; height: .8rem; background: var(--ss-paper-alt); border-radius: var(--ss-r-pill); overflow: hidden; }
.band--dark .capbar__t { background: rgba(255,255,255,.08); }
.capbar__was { position: absolute; inset-block: 0; left: 0; background: var(--ss-data-2); opacity: .45; border-radius: inherit; }
.capbar__is { position: absolute; inset-block: 0; left: 0; background: var(--ss-grade-f); border-radius: inherit; }


/* ------------------------------------------------------------- waitlist -- */
.wait { max-width: 480px; }
.wait__row { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: 1.25rem; }
.wait__in {
  flex: 1 1 220px; font: inherit; font-size: var(--ss-t-sm);
  padding: .7rem 1rem; border-radius: var(--ss-r-pill);
  border: 1px solid var(--ss-line-dark); background: rgba(255,255,255,.05);
  color: var(--ss-on-dark);
}
.wait__in::placeholder { color: var(--ss-on-dark-dim); opacity: .7; }
.wait__in:focus-visible { outline: 2px solid var(--ss-dark-mark); outline-offset: 2px; }
.wait__note { font-size: var(--ss-t-xs); color: var(--ss-on-dark-dim); margin-top: .85rem; }
.wait__msg { margin-top: 1rem; font-size: var(--ss-t-sm); }
.wait__msg[data-state="ok"] { color: var(--ss-dark-mark); }
.wait__msg[data-state="err"] { color: var(--ss-grade-f); }
/* The Turnstile check (src/lib/waitlist.js renders it here on the first interaction with the form). */
.wait__check { margin-top: .85rem; }

/* The product video sits in the same frame as the screenshots, so the two read
   as one object rather than two treatments of the same app. */
.shot video { width: 100%; height: auto; display: block; background: var(--ss-dark); }

/* ----------------------------------------------------------------- atlas --
   Skill, category and hub pages. Skill pages run a strict CSP (no inline style
   attributes), so everything here is a class, and bars are <meter> elements. */
.crumbs { font-family: var(--ss-font-label); font-size: var(--ss-t-sm); color: #57574f; margin: 0 0 1rem; }
.crumbs a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--ss-line); }
.crumbs a:hover { color: var(--ss-accent); border-bottom-color: currentColor; }
.skill h1, .category h1, .hub h1 { font-size: var(--ss-t-2xl); line-height: 1.15; margin: .25rem 0 .75rem; overflow-wrap: anywhere; }
/* The direct answer under every atlas h1, the sentence answer engines lift: a step up from body
   copy, on the accent rule the evidence line uses. */
.answer { font-size: var(--ss-t-md); line-height: 1.55; border-left: 3px solid var(--ss-accent); padding: .15rem 0 .15rem 1rem; margin: .5rem 0 1.25rem; overflow-wrap: anywhere; }
/* Category FAQs: the question is an h3, the answer the paragraph under it. */
.faq { margin-top: 2.5rem; }
.faq h2 { font-size: var(--ss-t-xl); margin: 0 0 .25rem; }
.faq h3 { font-size: var(--ss-t-md); margin: 1.5rem 0 .4rem; }
.faq p { margin: 0; }
.safety-warning { background: #fdf0ef; border: 1px solid var(--ss-grade-f); border-radius: 12px; padding: .9rem 1.1rem; margin: 1rem 0; color: #5c0d10; }
.scorecard { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .75rem; margin: 1.5rem 0 1rem; }
.scorecard > div { background: var(--ss-card); border: 1px solid var(--ss-line); border-radius: 14px; padding: .9rem 1rem; }
.scorecard dt { font-family: var(--ss-font-label); font-size: var(--ss-t-xs); text-transform: uppercase; letter-spacing: .06em; color: #57574f; }
.scorecard dd { margin: .35rem 0 0; font-size: var(--ss-t-xl); font-weight: 700; }
.scorecard dd small { font-size: var(--ss-t-sm); font-weight: 500; color: #57574f; }
.evidence { border-left: 3px solid var(--ss-accent); padding: .2rem 0 .2rem 1rem; margin: 1rem 0; font-weight: 500; }
.evidence--unproven { border-left-color: var(--ss-state-dormant); color: #3a3a38; font-weight: 400; }
.note { font-size: var(--ss-t-sm); color: #3a3a38; }
/* Why a skill graded A to C with a clean verdict has a short page (excludedNote in skill-page.mjs). */
.note--excluded { border-left: 3px solid var(--ss-state-thin); padding: .15rem 0 .15rem 1rem; }
.actions { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1.25rem 0 2rem; }
.review, .related, .alternates { margin-top: 2.5rem; }
.review h2, .related h2, .alternates h2 { font-size: var(--ss-t-xl); margin: 0 0 1rem; }
.review h3 { font-size: var(--ss-t-md); margin: 1.75rem 0 .5rem; }
.facts { display: grid; grid-template-columns: max-content 1fr; gap: .45rem 1.25rem; margin: 0; }
.facts dt { color: #57574f; }
.facts dd { margin: 0; }
.dims { list-style: none; padding: 0; margin: .75rem 0; display: grid; gap: .45rem; }
.dims li { display: grid; grid-template-columns: 8.5rem 1fr 2.25rem; align-items: center; gap: .75rem; font-size: var(--ss-t-sm); }
.dims li > span:last-child { font-family: var(--ss-font-mono); text-align: right; }
.dims meter { width: 100%; height: 6px; -webkit-appearance: none; appearance: none; border: 0; border-radius: 99px; background: var(--ss-paper-alt); }
.dims meter::-webkit-meter-bar { height: 6px; border: 0; border-radius: 99px; background: var(--ss-paper-alt); }
.dims meter::-webkit-meter-optimum-value,
.dims meter::-webkit-meter-suboptimum-value,
.dims meter::-webkit-meter-even-less-good-value { border-radius: 99px; background: var(--ss-accent); }
.dims meter::-moz-meter-bar { border-radius: 99px; background: var(--ss-accent); }
.notes blockquote { margin: .75rem 0; padding: .8rem 1rem; background: var(--ss-card); border: 1px solid var(--ss-line); border-radius: 12px; }
.findings, .outstanding { padding-left: 1.1rem; margin: .5rem 0; }
.outstanding { color: #3a3a38; font-size: var(--ss-t-sm); }
.related ul, .alternates ul, .ranked, .hub ul { list-style: none; padding: 0; margin: 0; }
.related li, .alternates li, .ranked li, .hub li { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: .6rem 0; border-bottom: 1px dotted rgba(103, 103, 103, .35); }
.ranked { counter-reset: rank; }
/* The rank is text: #6b6b67 is 4.99:1 on the paper (WCAG AA), where #8a8a86 was 3.23:1. */
.ranked li::before { counter-increment: rank; content: counter(rank); font-family: var(--ss-font-mono); font-size: var(--ss-t-sm); color: #6b6b67; min-width: 2rem; }
.ranked li a, .hub li a, .related li a { margin-right: auto; }
/* A listed skill whose safety verdict is not "ok", or that is flagged (safetyMark in skill-page.mjs): the verdict
   or the flag in words, beside its grade. Risky, unsafe and a flag share the red; only review is milder. */
.safety-mark { flex: none; font-family: var(--ss-font-label); font-size: var(--ss-t-xs); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; padding: .15rem .5rem; border-radius: var(--ss-r-pill); border: 1px solid var(--ss-grade-f);
  background: #fdf0ef; color: #5c0d10; }
.safety-mark--review { border-color: var(--ss-grade-c); background: #fdf6e3; color: #5c4400; }
/* A flag names its kind, so it is longer than a verdict, too long to share a phone's row with the name, the grade and the
   Add button. In a list row it takes a line of its own, under the name (the row's ::after is the line break), and on the
   narrowest screens it wraps inside a rounded box rather than widen the row. Only the flag wraps: the name takes what the
   first line has left, so the grade and the button stay beside it however long it is. */
.safety-mark--flagged { border-radius: 12px; }
:is(.ranked, .related, .alternates) li:has(> .safety-mark--flagged) { flex-wrap: wrap; row-gap: .2rem; }
:is(.ranked, .related, .alternates) li:has(> .safety-mark--flagged) > a { flex: 1 1 0; min-width: 0; overflow-wrap: anywhere; }
:is(.ranked, .related, .alternates) li:has(> .safety-mark--flagged)::after { content: ""; order: 1; flex-basis: 100%; }
:is(.ranked, .related, .alternates) li > .safety-mark--flagged { order: 2; flex: 0 1 auto; min-width: 0; }
.ranked li > .safety-mark--flagged { margin-left: 3rem; }
/* Every row's name is its author's text, and can be one long word: it wraps inside its own box rather than widen the row
   (WCAG 1.4.10, reflow at 320 px). */
:is(.ranked, .related, .alternates) li > a { min-width: 0; overflow-wrap: anywhere; }
/* On a narrow screen a verdict has no room beside the name, the grade and the Add button (a "Risky" row was 24 px too
   wide at 320 px): like a flag at every width, it takes a line of its own under the name. */
@media (max-width: 480px) {
  :is(.ranked, .related, .alternates) li:has(> .safety-mark) { flex-wrap: wrap; row-gap: .2rem; }
  :is(.ranked, .related, .alternates) li:has(> .safety-mark) > a { flex: 1 1 0; }
  :is(.ranked, .related, .alternates) li:has(> .safety-mark)::after { content: ""; order: 1; flex-basis: 100%; }
  :is(.ranked, .related, .alternates) li > .safety-mark { order: 2; }
  .ranked li > .grade + .safety-mark { margin-left: 3rem; }
}
.hub h2 { font-size: var(--ss-t-xl); margin: 2.25rem 0 .5rem; }
.hub h3 { font-size: var(--ss-t-md); margin: 1.25rem 0 .25rem; }
.cta { margin-top: 3rem; background: var(--ss-dark); color: var(--ss-on-dark); border-radius: 18px; padding: 1.4rem 1.5rem; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; }
.cta p { margin: 0; font-weight: 500; }
.cta .btn { background: var(--ss-dark-mark); border-color: var(--ss-dark-mark); color: var(--ss-dark); }
.cta .btn:hover { background: var(--ss-dark-mark-2); border-color: var(--ss-dark-mark-2); }
.disclaimer { font-size: var(--ss-t-sm); color: #57574f; margin-top: 1.5rem; }
@media (max-width: 640px) {
  .facts { grid-template-columns: 1fr; gap: .1rem; }
  .facts dd { margin-bottom: .6rem; }
  .dims li { grid-template-columns: 6.5rem 1fr 2rem; }
}

/* ------------------------------------------------------- nav + footer links -- */
.nav__links { display: flex; align-items: center; gap: 1.25rem; }
.nav__link { color: inherit; text-decoration: none; font-weight: 500; font-size: var(--ss-t-sm); }
.nav__link:hover { color: var(--ss-accent); }
.nav--over-hero .nav__link { color: var(--ss-on-dark); }
.nav--over-hero .nav__link:hover { color: var(--ss-dark-mark); }
@media (max-width: 520px) { .nav__link { display: none; } }
.footer__links { display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; margin-top: 2rem; }
/* ------------------------------------------------------------------ prose -- */
.prose h2 { font-size: var(--ss-t-xl); margin: 2.25rem 0 .6rem; }
.prose h3 { font-size: var(--ss-t-md); margin: 1.5rem 0 .4rem; }
.prose p, .prose li { max-width: 68ch; }
.prose ul, .prose ol { padding-left: 1.2rem; }
.prose li + li { margin-top: .4rem; }
.prose pre { background: var(--ss-dark); color: var(--ss-on-dark); border-radius: 12px; padding: 1rem 1.1rem; overflow-x: auto; font-family: var(--ss-font-mono); font-size: var(--ss-t-sm); }
.prose code { font-family: var(--ss-font-mono); font-size: .92em; }
.prose dl dt { font-weight: 700; margin-top: 1rem; }
.prose dl dd { margin: .25rem 0 0; }
/* Copy blocks (the /mcp setup prompt): text to paste into an agent, and the button src/lib/copy.js
   reveals to copy it. The prompt is prose, so it wraps instead of scrolling sideways on a phone. */
.prose pre.copyable { white-space: pre-wrap; overflow-wrap: anywhere; }
.copy-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem; margin: 0 0 1.5rem; }
.copy-row__status { font-size: var(--ss-t-sm); color: #3a3a38; }
/* ------------------------------------------------------------------ atlas -- */
.steps { padding-left: 1.4rem; margin: 1rem 0 1.5rem; }
.steps li { margin: .55rem 0; padding-left: .35rem; }
.steps li::marker { font-family: var(--ss-font-mono); font-size: var(--ss-t-sm); color: var(--ss-accent); }
.steps strong { font-weight: 600; }
/* ----------------------------------------------------------- methodology --
   The methodology page's own components. They were a <style> block in the page, which the static CSP
   (style-src 'self', no style-src-elem) blocks, so the page rendered without them. Every selector is
   under .methodology, the class on that page's <main> (layout mainClass), so none reaches another page. */
/* A formula block. It scrolls inside itself rather than widening the page on a phone. */
.methodology .formula {
  font-family: var(--ss-font-mono);
  font-size: .8125rem;
  line-height: 1.7;
  margin: .5rem 0 0;
  padding: .85rem 1rem;
  background: var(--ss-paper-alt);
  border-radius: var(--ss-r-md);
  overflow-x: auto;
  white-space: pre;
}
/* Penalty rows: the rule on the left, the cost on the right, hanging together so the eye can scan the
   column of numbers. */
.methodology .penlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .45rem; }
.methodology .penlist li { display: flex; gap: .3rem 1rem; align-items: baseline; justify-content: space-between; flex-wrap: wrap; font-size: .875rem; }
.methodology .penlist li > span:first-child { flex: 1 1 11rem; min-width: 0; }
.methodology .penlist li .mono { flex: 0 1 auto; font-size: .8125rem; text-align: right; }
/* A maturity signal row: mark, name, corpus rate. */
.methodology .sig { display: grid; grid-template-columns: auto 1fr auto; gap: .75rem; align-items: start; padding: .7rem 0; }
.methodology .sig__dot { width: 9px; height: 9px; margin-top: .45rem; border-radius: 3px; background: var(--ss-accent-mark); }
.methodology .sig__n { font-size: .875rem; }
.methodology .sevdot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.methodology .rulelist { list-style: none; margin: 1rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.methodology .rulelist code { word-break: break-word; }
.methodology .rulelist__n { font-size: .75rem; opacity: .7; }
/* -------------------------------------------------------- atlas showcase --
   The homepage's atlas section and the categories index's org chart. Classes only: atlas pages carry
   no inline styles. */

/* Nothing adds .is-in with scripts off, which left every .rise element on the homepage invisible. */
@media (scripting: none) { .rise { opacity: 1; transform: none; } }

/* Homepage: the claim and the two ways in, beside four numbers; then what makes the atlas different, its
   largest departments, and the Skillspace tease. */
.atlas-head { display: grid; gap: 2.5rem; align-items: center; }
@media (min-width: 940px) { .atlas-head { grid-template-columns: 1.05fr 1fr; gap: clamp(2rem, 4vw, 3.5rem); } }
.atlas-head .lede { margin-top: 1rem; }
.atlas-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1.75rem 0 0; }
.atlas-stats { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.atlas-stats .bigstat { padding: 1.1rem 1.15rem 1.2rem; container-type: inline-size; }
/* The figure scales with its tile, so six digits fit two-up on a phone. */
.atlas-stats .bigstat__n { font-size: 2rem; font-size: clamp(1.5rem, 18cqi, 2.5rem); }
.atlas-stats .bigstat__sub { color: #3a3a38; line-height: 1.45; }
.atlas-points { margin-top: clamp(2.5rem, 5vw, 3.5rem); border-bottom: 1px solid var(--ss-line); }
@media (min-width: 780px) { .atlas-points .qrow { grid-template-columns: 2.5rem minmax(0, .9fr) minmax(0, 1.6fr); } }
.atlas-points .qrow__q { font-size: var(--ss-t-md); line-height: 1.35; }
.atlas-points .qrow__a { margin: 0; }
.atlas-sub { font-size: var(--ss-t-md); margin: clamp(2.5rem, 5vw, 3.5rem) 0 1rem; }
.atlas-depts { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 760px) { .atlas-depts { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.atlas-dept {
  display: flex; flex-direction: column; justify-content: space-between; gap: .6rem; height: 100%;
  padding: 1rem 1.1rem; background: var(--ss-card); border: 1px solid var(--ss-line); border-radius: var(--ss-r-md);
  text-decoration: none; transition: border-color .2s ease;
}
.atlas-dept:hover { border-color: var(--ss-ink); }
.atlas-dept__name { font-weight: 500; line-height: 1.3; }
.atlas-dept:hover .atlas-dept__name { text-decoration: underline; text-decoration-color: var(--ss-accent-mark); }
.atlas-dept__n { font-family: var(--ss-font-mono); font-size: var(--ss-t-xs); color: #3a3a38; }

/* The categories index: the intro, the filter, a card per department, then every category. Cards and
   teams sit in columns rather than a grid, so a department with nine teams beside one with three leaves
   no hole. */
.atlas-index__intro { max-width: 820px; }
.atlas-filter { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem; margin: 2rem 0 0; }
.atlas-filter__label { flex: 1 0 100%; font-weight: 500; }
.atlas-filter__in {
  flex: 0 1 26rem; min-width: 0; font: inherit; padding: .7rem 1.1rem; -webkit-appearance: none; appearance: none;
  border: 1px solid var(--ss-line); border-radius: var(--ss-r-pill); background: var(--ss-card); color: var(--ss-ink);
}
.atlas-filter__in::placeholder { color: #6b6b67; }
.atlas-filter__in:focus-visible { outline: 2px solid var(--ss-accent); outline-offset: 2px; }
.atlas-filter__count { margin: 0; font-size: var(--ss-t-sm); color: #3a3a38; font-variant-numeric: tabular-nums; }
.org { list-style: none; margin: 1.75rem 0 0; padding: 0; columns: 3 17rem; column-gap: 1rem; }
.org__dept {
  break-inside: avoid; margin: 0 0 1rem; padding: 1.2rem 1.3rem .7rem;
  background: var(--ss-card); border: 1px solid var(--ss-line); border-radius: var(--ss-r);
}
.org__name { font-size: var(--ss-t-lg); line-height: 1.2; }
.org__name a { text-decoration: none; }
.org__name a:hover { text-decoration: underline; text-decoration-color: var(--ss-accent-mark); }
.org__meta { margin: .35rem 0 .75rem; font-size: var(--ss-t-sm); color: #3a3a38; }
/* Each team row has its rule above it, not below, so a card the filter has thinned never ends on one. */
.org__teams { list-style: none; margin: 0; padding: 0; }
.org__teams li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: .5rem 0;
  border-top: 1px dotted rgba(103, 103, 103, .35); font-size: var(--ss-t-sm);
}
.org__teams span { flex: none; color: #57574f; font-variant-numeric: tabular-nums; }
.atlas-list { margin-top: clamp(2.5rem, 5vw, 4rem); }
.atlas-list > h2 { margin: 0 0 .25rem; }
.atlas-list .atlas-list__dept > h3 { font-size: var(--ss-t-lg); margin: 2.25rem 0 0; }
.atlas-list__teams { columns: 3 16rem; column-gap: 2.5rem; }
/* Padding, not a heading margin: a column truncates the margin at its top, which dropped the first team
   in the first column below the first team in the others. */
.atlas-list__team { break-inside: avoid; padding-top: 1.25rem; }
.atlas-list .atlas-list__team h4 { font-size: var(--ss-t-md); margin: 0 0 .25rem; }
/* In a column this narrow a long category name wraps; its count keeps its line. */
.atlas-list li > span { flex: none; }

/* ------------------------------------------------------ the shopping list --
   The Add to list buttons (skill and category pages), the nav's List link and the /list page. Skill pages run
   the strict CSP, so everything is a class. A button ships invisible but holding its space, so nothing moves
   when src/lib/list.js shows it (.is-ready); with scripts off it is not there at all. */
.list-add { visibility: hidden; }
.list-add.is-ready { visibility: visible; }
@media (scripting: none) { .list-add { display: none; } }
/* The tick is decoration: the text and aria-pressed already say the skill is listed. */
.list-add[aria-pressed="true"]::before { content: "✓" / ""; }
.list-add:disabled { opacity: .55; cursor: not-allowed; }
.skill-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: 1.25rem 0 2rem; }
.skill-actions > .actions { margin: 0; }
/* A <button> does not inherit line-height, so without this it stands shorter than the link buttons beside it. */
.btn.list-add { line-height: inherit; }
.btn.list-add[aria-pressed="true"] { border-color: var(--ss-accent); }
/* One width for Add, Added and List full, so the grades beside a ranked list stay in one column. */
.list-add--compact {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: .3rem; min-width: 5rem;
  font: inherit; font-size: var(--ss-t-xs); font-weight: 500; line-height: 1.2; white-space: nowrap; padding: .3rem .7rem;
  border-radius: var(--ss-r-pill); border: 1px solid var(--ss-line); background: var(--ss-card); color: var(--ss-ink); cursor: pointer;
}
.list-add--compact:hover { border-color: var(--ss-ink); }
.list-add--compact[aria-pressed="true"] { background: var(--ss-accent); border-color: var(--ss-accent); color: #fff; }
/* A full list disables Add: no hover state that would say otherwise. */
.list-add--compact:disabled:hover { border-color: var(--ss-line); }
.btn.list-add:disabled:hover { background: transparent; border-color: var(--ss-line); }
.nav__list { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Below 520px the nav drops Browse skills but keeps the List link, which on a phone is the only way to the list.
   Below 380px the bar's gaps tighten so it still fits beside the waiting-list button (the links sit at the right,
   so with no list nothing visibly moves), and below 356px there is no room for it at all. */
@media (max-width: 520px) { .nav__links .nav__list { display: inline; } }
@media (max-width: 380px) { .nav__in, .nav__links { gap: .5rem; } }
@media (max-width: 355px) { .nav__links .nav__list { display: none; } }

/* /list: the intro, one of three states (no storage, an empty list, the list), the comparison table, which
   scrolls sideways inside its frame on a narrow screen rather than widening the page, and the two prompts. */
.list-page__intro { max-width: 820px; }
.list-page h1 { font-size: var(--ss-t-2xl); line-height: 1.15; margin: .25rem 0 .75rem; }
.list-off, .list-empty { margin-top: 2rem; }
.list-empty h2 { font-size: var(--ss-t-xl); margin: 0 0 .5rem; }
.list-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem 1rem; margin: 2rem 0 .75rem; }
.list-head__count { margin: 0; font-weight: 500; font-variant-numeric: tabular-nums; }
/* The frame is the containing block for the visually hidden text in the table, so that text scrolls with
   the table instead of widening the page. */
.list-body .scroller { position: relative; }
.list-table { min-width: 880px; }
.list-table thead th.num { font-family: var(--ss-font-label); }
.list-table tbody th, .list-table tbody td { vertical-align: top; }
.list-table tbody th { font-weight: 500; min-width: 9rem; overflow-wrap: anywhere; }
.list-table tbody a { overflow-wrap: anywhere; }
.list-table__evidence { min-width: 15rem; color: #3a3a38; }
.list-remove {
  font: inherit; font-size: var(--ss-t-xs); line-height: 1.2; white-space: nowrap; padding: .3rem .7rem;
  border-radius: var(--ss-r-pill); border: 1px solid var(--ss-line); background: transparent; color: var(--ss-ink); cursor: pointer;
}
.list-remove:hover { border-color: var(--ss-grade-f); color: var(--ss-grade-f); }
.list-prompts { margin-top: .5rem; }
/* A long list makes a long prompt: it scrolls inside its block, and the copy button still copies all of it. */
.list-prompts pre.copyable { max-height: 24rem; overflow-y: auto; }
