/* ------------------------------------------------------------------
   A. E. Cobley VST plug-ins - site styles
   Dark studio look: charcoal panel greys, phosphor-green accents,
   borrowed from the plug-in panels themselves.
   ------------------------------------------------------------------ */

:root {
  --bg:          #16181a;
  --bg-raised:   #1e2124;
  --bg-sunken:   #101214;
  --line:        #2e3338;
  --line-bright: #3d444b;
  --ink:         #d8dde2;
  --ink-dim:     #8d979f;
  /* 4.5:1 or better on all three backgrounds (5.41 / 4.92 / 5.71).
     #6b747b, used until 2026-09-16, was 3.74 / 3.40 / 3.94 and failed
     WCAG 1.4.3 for normal-size text. Check any change with tools/a11y.py. */
  --ink-faint:   #868f96;
  --accent:      #4ade80;
  --accent-dim:  #2f9e5c;
  --amber:       #f0b429;
  --radius:      10px;
  --maxw:        1100px;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  padding: 0 16px;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* One focus style for the whole site. Chrome's default two-tone ring happens
   to show up on this dark background, but Firefox and Safari draw a thinner
   single-colour ring that does not - so do not leave it to the browser. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
figure.tall:focus-visible,
.table-scroll:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Visually hidden, still announced. Used to give repeated link text its
   destination, and to caption tables without changing the design. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The skip link is the exception: hidden until focused, then visible. */
.skip {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 10;
  background: var(--bg-raised);
  color: var(--ink);
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 10px 16px;
  transition: top 0.15s ease;
}

.skip:focus { top: 12px; text-decoration: none; }

img { max-width: 100%; height: auto; display: block; }

code, kbd, .mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  /* A path like /Library/Audio/Plug-Ins/Components/SpaceDub.component has no
     spaces to break at, so at 320px it pushed the page wider than the screen
     (WCAG 1.4.10). Let it break mid-token rather than scroll the document. */
  overflow-wrap: anywhere;
  word-break: break-word;
}

.wrap { max-width: var(--maxw); margin: 0 auto; }

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

.site-head {
  border-bottom: 1px solid var(--line);
  padding: 28px 0 22px;
  margin-bottom: 40px;
}

.site-head .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 20px;
}

.site-title {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin: 0;
  color: var(--ink);
}

.site-title a { color: inherit; }
.site-title .dot { color: var(--accent); }

.site-sub {
  margin: 0;
  color: var(--ink-faint);
  font-size: 0.9rem;
}

.crumb {
  margin-left: auto;
  font-size: 0.88rem;
  color: var(--ink-faint);
}

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

.hero { margin-bottom: 48px; }

.hero h1 {
  font-size: clamp(1.7rem, 4.5vw, 2.6rem);
  line-height: 1.2;
  margin: 0 0 14px;
  letter-spacing: -0.01em;
}

.hero p {
  max-width: 62ch;
  color: var(--ink-dim);
  margin: 0 0 10px;
}

.hero .note {
  font-size: 0.9rem;
  color: var(--ink-faint);
}

/* ----------------------------------------------------------- cards */

.card-grid {
  display: grid;
  /* min(320px, 100%) keeps the 320px preference on a wide screen but lets a
     track shrink below it when there is not room. A bare 320px floor plus the
     16px body padding needs 352px, so the page scrolled sideways at 320. */
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 26px;
  margin: 0 0 56px;
  padding: 0;
  list-style: none;
}

.card {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.card:hover { border-color: var(--line-bright); transform: translateY(-2px); }

.card-shot {
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--line);
  aspect-ratio: 16 / 7;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.card-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

.card-body { padding: 18px 20px 20px; flex: 1; display: flex; flex-direction: column; }

.card-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}

.card h2 { font-size: 1.15rem; margin: 0; }
.card h2 a { color: var(--ink); }
.card h2 a:hover { color: var(--accent); text-decoration: none; }

.card .tagline {
  margin: 0 0 12px;
  color: var(--accent-dim);
  font-size: 0.86rem;
  letter-spacing: 0.01em;
}

.card .summary {
  margin: 0 0 18px;
  color: var(--ink-dim);
  font-size: 0.93rem;
  flex: 1;
}

.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.84rem;
  color: var(--ink-faint);
  border-top: 1px solid var(--line);
  padding-top: 14px;
}

/* 24x24 is the WCAG 2.2 minimum target; this link measured 132x22. */
.card-foot a { display: inline-block; padding: 3px 0; }

.pill {
  display: inline-block;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border: 1px solid var(--line-bright);
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}

.pill-accent { color: var(--accent-dim); border-color: var(--accent-dim); }

/* ------------------------------------------------- download button */

.dl-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px 22px;
  margin: 0 0 40px;
}

.dl {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  background: linear-gradient(180deg, #2b3136 0%, #1b1f22 100%);
  border: 1px solid #454d54;
  border-radius: 12px;
  padding: 13px 22px 13px 18px;
  color: var(--ink);
  text-decoration: none;
  box-shadow: 0 1px 0 rgba(255,255,255,0.06) inset, 0 2px 8px rgba(0,0,0,0.4);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.dl:hover {
  text-decoration: none;
  border-color: var(--accent-dim);
  box-shadow: 0 1px 0 rgba(255,255,255,0.08) inset, 0 4px 14px rgba(0,0,0,0.5);
}

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

.dl svg { flex: none; }

.dl-text { display: flex; flex-direction: column; line-height: 1.3; }

.dl-text .lead {
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

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

.dl-text .meta {
  font-size: 0.78rem;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
}

.dl-aside {
  font-size: 0.85rem;
  color: var(--ink-faint);
  max-width: 34ch;
}

.dl-aside a { color: var(--ink-dim); }
.dl-aside a:hover { color: var(--accent); }

/* -------------------------------------------------------- articles */

.plugin-title {
  margin: 0 0 6px;
  font-size: clamp(1.8rem, 5vw, 2.5rem);
  letter-spacing: -0.01em;
}

.plugin-tagline {
  margin: 0 0 8px;
  color: var(--accent-dim);
  font-size: 1.02rem;
}

.plugin-origin {
  margin: 0 0 30px;
  color: var(--ink-faint);
  font-size: 0.9rem;
}

.prose { max-width: 70ch; }

.prose h2, .section-head {
  font-size: 1.25rem;
  margin: 42px 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
  max-width: 70ch;
}

.prose h3 { font-size: 1.02rem; margin: 28px 0 8px; color: var(--ink); }
.prose p  { margin: 0 0 14px; color: var(--ink-dim); }
.prose ul { margin: 0 0 16px; padding-left: 20px; color: var(--ink-dim); }
.prose li { margin-bottom: 7px; }
.prose strong { color: var(--ink); font-weight: 600; }
.prose code { background: var(--bg-sunken); padding: 1px 5px; border-radius: 4px; color: var(--accent); }

.callout {
  border-left: 3px solid var(--amber);
  background: var(--bg-raised);
  padding: 14px 18px;
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 0 0 18px;
}

.callout p:last-child { margin-bottom: 0; }
.callout strong { color: var(--amber); }

/* ---------------------------------------------------------- figure */

figure {
  margin: 0 0 34px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
}

figure.sunken { background: var(--bg-sunken); }

figure img { border-radius: 4px; margin: 0 auto; }

/* A routing drawing is up to 4234px tall, so it is capped and scrolled.
   That makes it a scrollable region, which must therefore be reachable from
   the keyboard - the pages carry tabindex="0" and role="region" on these,
   and the focus style below is what makes the resulting tab stop visible. */
figure.tall { max-height: 640px; overflow-y: auto; }

figcaption {
  margin-top: 12px;
  font-size: 0.84rem;
  color: var(--ink-faint);
  line-height: 1.55;
}

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

.spec {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin: 0 0 30px;
}

.spec th, .spec td {
  text-align: left;
  padding: 9px 14px 9px 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.spec th {
  color: var(--ink-faint);
  font-weight: 500;
  width: 12em;
  /* No white-space: nowrap. With it, a 12em header column could not shrink
     and every plug-in page scrolled sideways at 320px (WCAG 1.4.10). */
}

.spec td { color: var(--ink-dim); }

/* Below 480px a two-column key/value table has no room to be a table, so the
   rows stack: header above value, one pair per block. Presentation only -
   the markup stays a real table with real <th scope="row">, so the
   relationships survive for anyone not seeing the layout. */
@media (max-width: 480px) {
  .spec, .spec tbody, .spec tr, .spec th, .spec td {
    display: block;
    width: auto;
  }
  .spec th { border-bottom: 0; padding: 0 0 2px; }
  .spec td { padding: 0 0 14px; }
  .spec tr { border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 10px; }
  .spec tr:last-child { border-bottom: 0; }
  /* the vowel table is real tabular data and cannot usefully stack; it keeps
     its own horizontal scroll box instead */
  .spec.vowels, .spec.vowels tbody, .spec.vowels tr,
  .spec.vowels th, .spec.vowels td { display: revert; width: revert; }
  .spec.vowels th, .spec.vowels td { padding: 9px 16px 9px 0; }
}

/* A wide data table is the one thing allowed to scroll sideways, in its own
   box, rather than pushing the page body wider than the screen. */
.table-scroll {
  overflow-x: auto;
  margin: 0 0 30px;
  -webkit-overflow-scrolling: touch;
}

.table-scroll .spec { margin-bottom: 0; }

.spec.vowels th { width: auto; }
.spec.vowels td { padding-right: 16px; white-space: nowrap; }

/* --------------------------------------------------------- licence */

/* The CC text is hard-wrapped at about 72 columns already, so pre-wrap only
   kicks in on a narrow screen - where wrapping beats a sideways scroll
   through 400 lines of legal text. */
.licence-text {
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--ink-dim);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 24px;
  margin: 0 0 40px;
  max-width: 80ch;
  tab-size: 4;
}

@media (max-width: 560px) {
  .licence-text { font-size: 0.72rem; padding: 16px 14px; }
}

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

.site-foot {
  border-top: 1px solid var(--line);
  margin-top: 64px;
  padding: 24px 0 40px;
  font-size: 0.85rem;
  color: var(--ink-faint);
}

.site-foot p { margin: 0 0 6px; }

.site-foot .foot-nav { margin-top: 12px; }

/* These are navigation, not links inside a sentence, so WCAG 2.2's 24x24
   target minimum applies to them. They measured 15px tall. */
.site-foot .foot-nav a {
  color: var(--ink-dim);
  display: inline-block;
  padding: 5px 0;
}

.site-foot .foot-nav a:hover { color: var(--accent); }

.backlink { display: inline-block; margin-bottom: 28px; font-size: 0.9rem; }

/* ------------------------------------------------ sample projects */

/* Only on a plug-in page with sample projects: the heading and download bar
   on the left, the "Sample projects" box on the right, both starting at the
   top. The download bar just takes the narrower column - .dl-bar already
   wraps, and the button inside it is untouched. */
.plugin-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 17rem;
  column-gap: 36px;
  align-items: start;
}
.plugin-head-main { min-width: 0; }
/* In the narrower column the note beside the button would otherwise wrap
   under it at its usual 34ch and leave a hole to its right. Let it take
   whatever width is left: beside the button when that is 14rem or more,
   otherwise the full width of the bar underneath it. */
.plugin-head .dl-aside { flex: 1 1 14rem; max-width: none; }

/* A bordered box with its title set into the top border, like a legend. */
.samples {
  /* the title rides up out of the box by about 0.8em; this lines its top up
     with the top of the page heading beside it */
  margin: 14px 0 40px;
  padding: 22px 18px 12px;
  position: relative;
  background: var(--bg-raised);
  border: 2px solid var(--accent-dim);
  border-radius: var(--radius);
}
.samples h2 {
  position: absolute;
  top: -0.8em;
  left: 12px;
  margin: 0;
  padding: 0 8px;
  background: var(--bg);      /* breaks the border line behind the title */
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
}
.samples p  { font-size: 0.88rem; color: var(--ink-dim); margin: 0 0 12px; }
.samples ul { list-style: none; margin: 0; padding: 0; }
.samples li { border-top: 1px solid var(--line); }
/* A full-width block link: a 24px-plus target (WCAG 2.5.8), and a long file
   name wraps rather than widening the box. */
.samples a  { display: block; padding: 9px 0; overflow-wrap: anywhere; }

/* Too narrow for two columns: stack them, download first, then the box. */
@media (max-width: 900px) {
  .plugin-head { display: block; }
  .samples { margin: 0 0 40px; }
}

/* ----------------------------------------------------- small print */

@media (max-width: 560px) {
  .dl { width: 100%; }
  .dl-aside { max-width: none; }
  .crumb { margin-left: 0; width: 100%; }
}

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

/* Nothing here animates much - a 2px card lift and some colour fades - but
   respecting the preference costs three lines. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  .card:hover { transform: none; }
}
