/* Cascade layers: a later layer always beats an earlier one, regardless of
   selector specificity, so rules never need to escalate selectors to win.

   Breakpoints (media queries cannot read custom properties, so these stay
   literal): 700px = single-column content, 430px = stacked header. */
@layer tokens, base, layout, components, pages;

@layer tokens {
  :root {
    /* Each color token holds its light and dark value; light-dark()
       resolves against the active color-scheme.

       Palette: One Light Pro (light) / One Dark Pro (dark) — the editor
       themes' grounds and foregrounds. One accent (blue) carries links and
       the small heading marks; the rest of the syntax spectrum is reserved
       for code surfaces, where it has a real job. */
    color-scheme: light dark;
    --bg: light-dark(#fafafa, #282c34);
    --bg-end: light-dark(#eaeaeb, #21252b);
    --text: light-dark(#383a42, #abb2bf);
    --muted: light-dark(#6a6c75, #9198a6);
    --link: light-dark(#4078f2, #61afef);
    --link-hover: light-dark(#2f63d6, #83c0f4);
    /* Headings sit a shade stronger than body text; blue is reserved for
       links and the small eyebrow accent, never the title itself. */
    --heading: light-dark(#202227, #dcdfe4);
    --control-bg: light-dark(#ffffff, #21252b);
    --control-border: light-dark(#d3d3d4, #3b4048);
    --control-active-bg: light-dark(#e5e5e6, #3e4451);
    --control-active-text: light-dark(#202227, #dcdfe4);
    --control-shadow: light-dark(rgba(64, 120, 242, 0.1), rgba(0, 0, 0, 0.4));

    /* Code surfaces: the editor ground itself, one shade off the page so a
       block reads as "an editor pane" without shouting. */
    --code-bg: light-dark(#f0f0f1, #21252b);
    --code-fg: light-dark(#383a42, #abb2bf);
    --code-border: light-dark(#e2e2e3, #3b4048);
    --code-inline-bg: light-dark(#e9e9ea, #2c313a);

    --measure: 46rem;
    --article-measure: 34rem;
    --list-gap: clamp(1.25rem, 3.2vw, 1.55rem);
    --ease-quick: 140ms ease;
    --font-ui: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  }

  /* The theme picker pins a scheme by setting data-theme; without the
     attribute, "light dark" above follows the system preference. */
  :root[data-theme="light"] {
    color-scheme: light;
  }

  :root[data-theme="dark"] {
    color-scheme: dark;
  }
}

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

  :root {
    font-family: Georgia, "Times New Roman", serif;
    font-size: 17px;
    font-weight: 400;
    line-height: 1.55;

    @media (max-width: 700px) {
      font-size: 16px;
    }
  }

  html {
    min-height: 100%;
    background: var(--bg-end);
  }

  body {
    min-width: 320px;
    min-height: 100vh;
    margin: 0;
    background: linear-gradient(135deg, var(--bg), var(--bg-end));
    color: var(--text);
    text-rendering: optimizeLegibility;
  }

  a {
    color: var(--link);
    text-decoration: underline;
    text-underline-offset: 0.08em;
    transition: color var(--ease-quick);

    &:hover,
    &:focus-visible {
      color: var(--link-hover);
    }

    &:focus-visible {
      outline: 2px solid var(--link-hover);
      outline-offset: 4px;
    }
  }

  .visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

@layer layout {
  .site-shell {
    display: flex;
    flex-direction: column;
    width: min(var(--measure), calc(100vw - 2rem));
    min-height: 100vh;
    min-height: 100dvh;
    margin: 0 auto;
    padding: clamp(1.5rem, 5vw, 3rem) 0 clamp(1.5rem, 4vw, 2.5rem);

    @media (max-width: 700px) {
      width: min(100% - 1.5rem, var(--measure));
    }
  }

  /* Grow the content so the footer is pushed to the viewport bottom on
     short pages, rather than floating up under the content. */
  .site-shell > main {
    flex: 1 0 auto;
  }

  /* Header row wraps: on wide screens brand sits left with nav + theme
     picker pushed to the right by the brand's auto margin. Below 430px the
     nav drops to its own full-width line (flex-basis:100% + order), leaving
     the brand and picker sharing the top row. */
  .site-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.9rem 0.8rem;
    margin-bottom: clamp(3.5rem, 10vw, 5.1rem);

    @media (max-width: 700px) {
      align-items: flex-start;
      margin-bottom: 3rem;
    }
  }

  .brand {
    display: inline-flex;
    min-width: 0;
    /* Consume the free space so nav + picker align to the right edge. */
    margin-right: auto;
    align-items: center;
    gap: 0.62rem;
    color: var(--text);
    text-decoration: none;

    /* The brand link keeps the text color on hover. */
    &:hover,
    &:focus-visible {
      color: var(--text);
    }

    @media (max-width: 700px) {
      max-width: 19rem;
    }
  }

  .brand-text {
    min-width: 0;
    overflow-wrap: anywhere;
    font-size: 1.3rem;
    font-weight: 700;
    letter-spacing: -0.01em;
  }

  .site-nav {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.48rem;

    /* Drop the nav below the brand/picker row and align it left. */
    @media (max-width: 430px) {
      order: 1;
      flex-basis: 100%;
      justify-content: flex-start;
    }
  }

  .site-nav a {
    padding-block: 0.1rem;
  }

  /* Footer: a monospace utility register under the serif body. The hairline
     fades at both edges so it reads as a close, not a hard border. */
  .site-footer {
    margin-top: clamp(3.5rem, 10vw, 5.5rem);
  }

  .footer-rule {
    height: 1px;
    margin: 0 0 1.15rem;
    border: 0;
    background: linear-gradient(90deg, transparent, var(--control-border) 12%, var(--control-border) 88%, transparent);
  }

  .footer-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.9rem 1.5rem;
  }

  .footer-social {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
  }

  .footer-social a {
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.9rem;
    text-decoration: none;

    &:hover,
    &:focus-visible {
      color: var(--heading);
    }
  }

  .footer-credit {
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.78rem;
  }
}

@layer components {
  /* Theme picker */

  .theme-picker {
    display: flex;
    min-inline-size: 0;
    align-items: center;
    gap: 0.08rem;
    margin: 0;
    padding: 0.12rem;
    border: 1px solid var(--control-border);
    border-radius: 999px;
    background: var(--control-bg);
    box-shadow: inset 0 1px 2px var(--control-shadow);
    color: var(--muted);
    font-family: var(--font-ui);
  }

  .theme-option {
    position: relative;
    display: grid;
    width: 1.55rem;
    height: 1.35rem;
    place-items: center;
    color: inherit;
    cursor: pointer;
  }

  .theme-option-auto {
    width: 2.25rem;
  }

  .theme-option input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
    opacity: 0;
  }

  .theme-option-indicator {
    display: grid;
    width: 100%;
    height: 100%;
    place-items: center;
    border-radius: 999px;
    color: currentColor;
    opacity: 0.68;
    transition: background-color var(--ease-quick), color var(--ease-quick), opacity var(--ease-quick);
  }

  .theme-option-text {
    font-size: 0.52rem;
    font-weight: 800;
    line-height: 1;
    text-transform: uppercase;
  }

  .theme-option svg {
    width: 0.82rem;
    height: 0.82rem;
    fill: currentColor;
  }

  .theme-option input:checked + .theme-option-indicator {
    background: var(--control-active-bg);
    color: var(--control-active-text);
    opacity: 1;
    box-shadow: 0 1px 2px var(--control-shadow);
  }

  .theme-option input:focus-visible + .theme-option-indicator {
    outline: 2px solid var(--link-hover);
    outline-offset: 2px;
  }

  /* Dateline list: rows with a date (and optional venue) in the left
     margin. Used by the blog archive and the talks page. */

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

  .dateline-item {
    display: grid;
    grid-template-columns: minmax(7.2rem, 9.8rem) minmax(0, 32rem);
    justify-content: center;
    gap: 0 1.25rem;

    @media (max-width: 700px) {
      grid-template-columns: 1fr;
      justify-content: stretch;
      gap: 0.12rem;
    }
  }

  .dateline-meta {
    margin: 0;
    padding-top: 0.05rem;
    color: var(--muted);
    font-size: 0.88rem;
    font-style: italic;
    text-align: right;

    @media (max-width: 700px) {
      text-align: left;
    }
  }

  .dateline-meta time {
    white-space: nowrap;
  }

  .dateline-copy {
    min-width: 0;
    margin: 0;
  }

  /* Talk rows add a venue line under the date; on narrow screens it
     collapses onto the date line with an "@" separator. */

  .talk-location-line {
    display: block;

    @media (max-width: 700px) {
      display: inline;

      &::before {
        content: " ";
      }
    }
  }

  .talk-at {
    display: none;

    @media (max-width: 700px) {
      display: inline;
    }
  }

  /* Pagination */

  .pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.22rem;
    margin-top: clamp(2.2rem, 6vw, 3.4rem);
    color: var(--text);
  }

  .pagination a,
  .pagination-current,
  .pagination-arrow {
    display: grid;
    min-width: 1.85rem;
    height: 1.85rem;
    place-items: center;
    padding: 0 0.3rem;
    border-radius: 999px;
    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
    text-decoration: none;
    transition: color var(--ease-quick), background-color var(--ease-quick);
  }

  .pagination a:hover,
  .pagination a:focus-visible {
    background: var(--control-active-bg);
    color: var(--control-active-text);
  }

  .pagination-current {
    background: var(--control-active-bg);
    color: var(--control-active-text);
    box-shadow: 0 1px 2px var(--control-shadow);
  }

  .pagination-arrow {
    color: var(--muted);
  }

  .pagination-arrow[aria-disabled="true"] {
    opacity: 0.4;
  }

  .pagination-ellipsis {
    display: grid;
    min-width: 1.85rem;
    height: 1.85rem;
    place-items: center;
    color: var(--muted);
  }
}

@layer pages {
  .article {
    width: min(100%, var(--article-measure));
    margin-inline: auto;
  }

  /* Pages opt into the full site measure with body_class = "article-wide"
     in their frontmatter (e.g. the talks page). */
  .article-wide {
    width: min(100%, var(--measure));
  }

  .article-date {
    margin: 0 0 0.55rem;
    color: var(--muted);
    font-size: 0.92rem;
    font-style: italic;
  }

  /* Ink title with a short teal accent rule: the one teal mark near the
     heading, graphic rather than link-colored text. */
  .article h1 {
    position: relative;
    margin: 0;
    padding-bottom: 0.55rem;
    color: var(--heading);
    font-size: clamp(1.65rem, 6vw, 2.55rem);
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -0.02em;
    text-wrap: balance;
  }

  .article h1::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 2.6rem;
    height: 4px;
    border-radius: 2px;
    background: var(--link);
  }

  .article-summary {
    margin: 0.85rem 0 2rem;
    color: var(--text);
    font-size: 1.08rem;
  }

  /* Pages have no summary, so the body would otherwise butt against the
     title; posts keep their own spacing via the summary above. */
  .article h1 + .article-body {
    margin-top: 1.5rem;
  }

  .article-body {
    color: var(--text);
  }

  .article-body h2 {
    margin: 2.15rem 0 0.5rem;
    padding-left: 0.9rem;
    border-left: 3px solid var(--link);
    color: var(--heading);
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.25;
  }

  .article-body p,
  .article-body ul,
  .article-body ol {
    margin: 0 0 1.1rem;
  }

  .article-body ul,
  .article-body ol {
    padding-left: 1.25rem;
  }

  /* Inline code reads as a small chip lifted off the page; kept at the ink
     color so it clears AA in prose (the syntax colors live in blocks). */
  .article-body code {
    padding: 0.09em 0.36em;
    border-radius: 4px;
    background: var(--code-inline-bg);
    color: var(--heading);
    font-family: var(--font-mono);
    font-size: 0.86em;
  }

  /* Code blocks are an editor pane: the One Dark / One Light Pro ground,
     one shade off the page, scrolling on their own so the body never does. */
  .article-body pre {
    margin: 0 0 1.35rem;
    padding: 0.85rem 1rem;
    overflow-x: auto;
    border: 1px solid var(--code-border);
    border-radius: 8px;
    background: var(--code-bg);
    color: var(--code-fg);
    font-size: 0.86em;
    line-height: 1.55;
    -webkit-overflow-scrolling: touch;
  }

  .article-body pre code {
    padding: 0;
    background: none;
    color: inherit;
    font-size: inherit;
  }

  /* Dateline lists embedded in article prose (the talks page): space the
     lists like paragraphs, but keep the rows' own tight spacing instead of
     the prose list/paragraph styling above. */
  .article-body .dateline-list {
    margin-bottom: 2.15rem;
    padding: 0;
  }

  .article-body .dateline-meta,
  .article-body .dateline-copy {
    margin: 0;
  }

  .article-wide .article-body .dateline-item {
    grid-template-columns: minmax(7.2rem, 8.8rem) minmax(0, 1fr);
    justify-content: stretch;
    gap: 0 1.1rem;

    @media (max-width: 700px) {
      grid-template-columns: 1fr;
      gap: 0.12rem;
    }
  }

  .back-link {
    margin-top: 2rem;
  }
}
