/* Kanoniq — kanoniq.extenza.dev
   Hand-written, no bundler. Reasoning: .ai/notes/brainstorm/2026-09-27-marketing-site-design.md
   Solid stroke = authored. Dashed stroke = derived. That rule is the whole design, and it is
   also the logo. */

@layer tokens, base, layout, components;

@layer tokens {
  @font-face {
    font-family: 'IBM Plex Sans';
    src: url('fonts/ibm-plex-sans-400.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
  }
  @font-face {
    font-family: 'IBM Plex Sans';
    src: url('fonts/ibm-plex-sans-600.woff2') format('woff2');
    font-weight: 600;
    font-display: swap;
  }
  @font-face {
    font-family: 'JetBrains Mono';
    src: url('fonts/jetbrains-mono-400.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
  }
  @font-face {
    font-family: 'Space Grotesk';
    src: url('fonts/space-grotesk-700.woff2') format('woff2');
    font-weight: 700;
    font-display: swap;
  }

  :root {
    --paper: #f1f3f2;
    --ink: #16302c;
    --derived: #6f8781;  /* strokes only — 3.5:1 on paper, enough for graphics, not for text */
    --muted: #4a5c57;    /* muted *text* — 6.4:1 on paper */
    --rule: #c8d1cd;
    --accent: #8a5a00;   /* 5.3:1 on paper */
    --code: #0e4a3e;     /* source text — 8.5:1 on its own surface */
    --surface: #e8ecea;  /* the code block's ground */

    --sans: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
    --mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', 'Consolas', monospace;
    --display: 'Space Grotesk', var(--sans);

    --step--1: 0.875rem;
    --step-0: 1rem;
    --step-1: 1.25rem;
    --step-2: 1.5625rem;
    --step-4: clamp(2.25rem, 1.5rem + 3.4vw, 4rem);

    --measure: 60ch;
    --gutter: 1rem;
    --space-xs: 0.5rem;
    --space-s: 1rem;
    --space-m: 1.5rem;
    --space-l: 2.5rem;
    --space-xl: 4rem;
  }

  /* Spacing scales with the viewport through the tokens, not through overriding .band /
     .hero further down — that fight is how section padding rules cancel each other out. */
  @media (min-width: 48rem) {
    :root {
      --gutter: 2rem;
      --space-l: 3.5rem;
      --space-xl: 6rem;
    }
  }

  @media (prefers-color-scheme: dark) {
    :root {
      --paper: #12201d;
      --ink: #e8edea;
      --derived: #8aa199;
      --muted: #9fb3ac;  /* 7.6:1 on dark paper */
      --rule: #2a3b37;
      --accent: #d9a441;
      --code: #9ff0cf;   /* 11.5:1 on its own surface */
      --surface: #172925;
    }
  }
}

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

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

  body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--sans);
    font-size: var(--step-0);
    line-height: 1.6;
    text-underline-offset: 0.2em;
  }

  h1, h2, h3 {
    margin: 0;
    font-weight: 600;
    line-height: 1.12;
    text-wrap: balance;
  }

  p { margin: 0; }

  a {
    color: var(--accent);
    text-decoration-thickness: 1px;
  }

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

  ::selection {
    background: var(--ink);
    color: var(--paper);
  }
}

@layer layout {
  .wrap {
    max-width: 64rem;
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  /* The figure and the footer run wider than the reading measure; the text inside them keeps
     its own max-width, so line length is unaffected. */
  .wrap--wide { max-width: 76rem; }

  .band { padding-block: var(--space-l); }
  header.band { padding-block: var(--space-m) 0; }
  .hero { padding-block: var(--space-l) var(--space-xl); }

  .vh {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .skip {
    position: absolute;
    left: var(--gutter);
    top: -4rem;
    z-index: 1;
    padding: var(--space-xs) var(--space-s);
    background: var(--ink);
    color: var(--paper);
    text-decoration: none;
    transition: top 120ms ease-out;
  }
  .skip:focus { top: var(--space-xs); }
}

@layer components {

  /* ---- logo ------------------------------------------------------------- */
  /* One solid bar over two dashed ones: one authored model, several derived views. */

  .logo {
    display: flex;
    align-items: center;
    gap: 0.7rem;
  }

  .logo-mark {
    width: 2.4rem;
    height: 2.4rem;
    flex: none;
  }

  .mark-a,
  .mark-d {
    fill: none;
    stroke-width: 1.7;
  }

  /* The logo carries the accent. The solid/dashed distinction still reads, because the dash
     pattern does that work — colour was only reinforcing it. */
  .mark-a { stroke: var(--accent); }

  .mark-d {
    stroke: var(--accent);
    stroke-dasharray: 2.6 2.1;
    opacity: 0.6;
  }

  .logo-word {
    font-family: var(--display);
    font-weight: 700;
    font-size: 1.85rem;
    letter-spacing: -0.02em;
    color: var(--accent);
  }

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

  .hero-top {
    display: grid;
    gap: var(--space-l);
    align-items: center;
  }

  /* The illustration sets tone; the three-stage figure below proves the claim. Keeping it to
     a fraction of the column is what stops the hero having two focal points. */
  .hero-il {
    display: block;
    width: 100%;
    max-width: 30rem;
    height: auto;
    justify-self: center;
  }

  .il-a { fill: var(--ink); }
  .il-b { fill: var(--derived); }

  @media (min-width: 64rem) {
    .hero-top {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
      gap: var(--space-l);
    }

    .hero-il { max-width: 38rem; justify-self: end; }
  }

  .hero h1 {
    font-size: var(--step-4);
    letter-spacing: -0.025em;
    max-width: 18ch;
  }

  .lede {
    max-width: var(--measure);
    margin-top: var(--space-m);
    font-size: var(--step-1);
    line-height: 1.5;
  }

  /* ---- the three stages -------------------------------------------------- */

  .figure { margin: var(--space-xl) 0 0; }

  .stages {
    display: grid;
    gap: var(--space-m);
    justify-items: start;
  }

  .stage-lbl {
    margin-bottom: var(--space-s);
    font-family: var(--mono);
    font-size: 1.125rem;
    color: var(--ink);
  }

  .kq {
    margin: 0;
    padding: var(--space-s);
    border: 1px solid var(--rule);
    border-radius: 3px;
    background: var(--surface);
    font-family: var(--mono);
    font-size: 0.8125rem;
    line-height: 1.7;
    color: var(--code);
    overflow-x: auto;
  }

  .kq code { font: inherit; }

  /* `derived` is spelled in the derived motif rather than the derived colour, which is a
     stroke colour and too light to carry text. */
  .kw-d {
    color: var(--muted);
    text-decoration: underline dashed var(--derived) 1px;
    text-underline-offset: 3px;
  }

  .flow {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding-left: 3.5rem;
  }

  .flow-arrow {
    width: 3rem;
    height: 1rem;
    flex: none;
    transform: rotate(90deg);
  }

  .flow-lbl {
    font-family: var(--mono);
    font-size: var(--step--1);
    color: var(--muted);
  }

  .dg {
    display: block;
    width: 100%;
    height: auto;
  }

  .dg--model { max-width: 160px; }
  .dg--views { max-width: 330px; }

  @media (min-width: 64rem) {
    .stages {
      grid-auto-flow: column;
      grid-auto-columns: max-content;
      align-items: center;
      justify-content: space-between;
      gap: var(--space-s);
    }

    .flow {
      flex-direction: column;
      gap: 0.35rem;
      padding-left: 0;
    }

    .flow-arrow { transform: none; }

    .dg--model { width: 160px; }
    .dg--views { width: 330px; }
  }

  /* ---- diagram strokes: the one rule ------------------------------------- */

  .node,
  .link {
    fill: none;
    stroke: var(--ink);
    stroke-width: 1.5;
  }

  .cap {
    font-family: var(--sans);
    font-size: 15px;
    fill: var(--ink);
    text-anchor: middle;
  }

  .band-l,
  .node-d,
  .link-d,
  .arrow {
    fill: none;
    stroke: var(--derived);
    stroke-width: 1.5;
    stroke-dasharray: 5 4;
  }

  .head-a { fill: var(--ink); stroke: none; }
  .head-d { fill: var(--derived); stroke: none; }
  .chip { fill: var(--rule); stroke: none; }

  .cap-d {
    font-family: var(--sans);
    font-size: 15px;
    fill: var(--muted);
    text-anchor: middle;
  }

  /* One orchestrated reveal, in the order Kanoniq produces things: source, then the model it
     parses into, then the views derived from that. Three steps, not five — the arrow arrives
     with the thing it points at. */
  .rv {
    opacity: 0;
    animation: settle 350ms ease-out forwards;
  }

  .rv-1 { animation-delay: 100ms; }
  .rv-2 { animation-delay: 380ms; }
  .rv-3 { animation-delay: 660ms; }

  @keyframes settle {
    from { opacity: 0; }
    to { opacity: 1; }
  }

  @media (prefers-reduced-motion: reduce) {
    .rv {
      opacity: 1;
      animation: none;
    }
    .skip { transition: none; }
  }

  figcaption {
    max-width: var(--measure);
    margin-top: var(--space-m);
    color: var(--muted);
    font-size: var(--step--1);
    line-height: 1.5;
  }

  figcaption code {
    font-family: var(--mono);
    font-size: 0.95em;
    color: var(--code);
  }

  /* ---- section headings, format and stage lists --------------------------- */

  .band h2 {
    font-size: var(--step-2);
    letter-spacing: -0.02em;
    max-width: 20ch;
  }

  .formats,
  .stages-list {
    display: grid;
    margin: var(--space-l) 0 0;
    padding: 0;
    list-style: none;
  }

  .stages-list { counter-reset: stage; }

  .formats > li,
  .stages-list > li {
    display: grid;
    gap: var(--space-xs);
    padding-block: var(--space-m);
    border-top: 1px solid var(--rule);
  }

  /* Numbered because the stages genuinely are a sequence — each one depends on the last. */
  .stages-list > li { counter-increment: stage; }

  /* Large but quiet: the <ol> carries the sequence for assistive tech, so the numeral is
     structure rather than content and can sit at the low-contrast end. */
  .stages-list > li::before {
    content: counter(stage);
    font-family: var(--mono);
    font-size: 3rem;
    line-height: 0.85;
    color: var(--derived);
  }

  .formats h3,
  .stages-list h3 { font-size: var(--step-1); }

  .formats p,
  .stages-list p { max-width: 56ch; }

  .when {
    display: block;
    margin-top: 0.2rem;
    font-family: var(--mono);
    font-size: var(--step--1);
    font-weight: 400;
    color: var(--muted);
  }

  @media (min-width: 48rem) {
    .formats > li {
      grid-template-columns: 14rem 1fr;
      gap: var(--space-m);
    }

    .stages-list > li {
      grid-template-columns: 4.5rem 14rem 1fr;
      gap: var(--space-m);
      align-items: start;
    }
  }

  /* ---- the three points -------------------------------------------------- */

  .points {
    display: grid;
    gap: var(--space-l);
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .points > li {
    border-top: 1px solid var(--rule);
    padding-top: var(--space-s);
  }

  /* Decorative: the heading beneath carries the meaning, so the icons are aria-hidden.
     They inherit `color`, which is what makes them follow the theme. */
  .pt-icon {
    display: block;
    width: 5rem;
    height: 5rem;
    margin-bottom: var(--space-m);
    color: var(--muted);
  }

  .points h3 {
    font-size: var(--step-1);
    margin-bottom: var(--space-xs);
  }

  .points p { max-width: 44ch; }

  @media (min-width: 48rem) {
    .points {
      grid-template-columns: repeat(3, 1fr);
      gap: var(--space-m);
    }
  }

  /* ---- call to action ----------------------------------------------------- */

  .band--cta { border-top: 1px solid var(--rule); }

  .status {
    max-width: var(--measure);
    font-size: var(--step-2);
    line-height: 1.3;
    letter-spacing: -0.015em;
  }

  .status-sub {
    max-width: var(--measure);
    margin-top: var(--space-m);
    color: var(--muted);
  }

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

  footer {
    padding-block: var(--space-l) var(--space-m);
    color: var(--muted);
    font-size: var(--step--1);
  }

  /* The logo, drawn as a rule: one solid line, one dashed beneath it. */
  .foot-motif { border-top: 1px solid var(--ink); }

  .foot-motif::after {
    content: '';
    display: block;
    margin-top: 5px;
    border-top: 1px dashed var(--derived);
  }

  .foot-grid {
    display: grid;
    gap: var(--space-l);
    margin-top: var(--space-l);
  }

  .foot-brand p {
    max-width: 38ch;
    margin-top: var(--space-s);
  }

  .foot-brand .logo-word { font-size: 1.45rem; }
  .foot-brand .logo-mark { width: 1.9rem; height: 1.9rem; }

  .foot-h {
    margin-bottom: var(--space-xs);
    font-size: var(--step-0);
    color: var(--ink);
  }

  .foot-legal { margin-top: var(--space-l); }

  .dim { font-family: var(--mono); }

  @media (min-width: 48rem) {
    .foot-grid {
      grid-template-columns: 1.7fr 1.2fr;
      gap: var(--space-m);
    }
  }
}
