@charset "UTF-8";

/*
  The stylesheet of dancroak.com. It follows the rules of the web/css
  article: every rule sits in a layer, every spacing and type rule
  spends a token from :root, and a class is kebab-case.

  A breakpoint is a strict range, and the ranges do not overlap. A
  media query cannot read a custom property, so each breakpoint is a
  literal:

    width <= 47.5em  a phone: narrow page padding, stacked screenshots
    width < 48em     the narrowest text column
    48em to 64em     a tablet
    64em to 75em     a laptop
    75em <= width    a desktop
*/

@layer reset, tokens, base, components, utilities, print;

@layer tokens {
  :root {
    --font-family--serif:
      et-book,
      "Times New Roman",
      "DejaVu Serif",
      "Bitstream Charter",
      Georgia,
      serif;
    --font-family--mono:
      ui-monospace,
      SFMono-Regular,
      Menlo,
      Consolas,
      Liberation Mono,
      monospace;

    --font-size--root: 15px;
    --font-size--xx-small: 0.9rem;
    --font-size--x-small: 1rem;
    --font-size--small: 1.1rem;
    --font-size--medium: 1.4rem;
    --font-size--large: 1.7rem;
    --font-size--x-large: 2.2rem;
    --font-size--xx-large: 3.2rem;
    /* Code in a heading is a share of the heading's size. */
    --font-size--code-in-heading: 0.8em;

    --font-weight--normal: 400;

    --line-height--tight: 1;
    --line-height--code: 1.42;
    --line-height--base: 2rem;

    --spacing--xx-small: 0.25rem;
    --spacing--x-small: 0.5rem;
    --spacing--small: 0.8rem;
    --spacing--medium-small: 1rem;
    --spacing--medium: 1.2rem;
    --spacing--medium-large: 1.4rem;
    --spacing--large: 1.5rem;
    --spacing--x-large: 2rem;
    --spacing--xx-large: 2.1rem;
    --spacing--xxx-large: 3rem;
    --spacing--xxxx-large: 4rem;
    /* Inline code pads by a share of its own size. */
    --spacing--code-block: 0.1em;
    --spacing--code-inline: 0.3em;
    --spacing--code-indent: 2.5%;
    --spacing--blockquote-end: 40px;
    --spacing--profile-image: 8px;
    --spacing--page-inline: 8%;

    --border-radius--small: 2px;
    --border-radius--base: 4px;

    --width--content: 36rem;
    --width--list: 34rem;

    --color--bg: #fffff8;
    --color--bg-secondary: #f8f8f8;
    --color--text: #111111;
    --color--text-light: #444444;
    --color--text-quote: #333333;
    /* initial leaves color unset, so light code takes the color around
       it. */
    --color--code-text: initial;
    --color--link: #111111;
    --color--link-hover: #111111;
    --color--link-underline: rgba(0, 0, 0, 0.3);
    --color--link-underline-hover: rgba(0, 0, 0, 0.6);
    --color--icon-hover: #666666;
    --color--border-base: #e2e2e2;
    --color--border-dark: #cccccc;

    /* Syntax colors: Catppuccin Latte. */
    --color--code-keyword: #8839ef;
    --color--code-name: #1e66f5;
    --color--code-string: #40a02b;
    --color--code-number: #fe640b;
    --color--code-comment: #8c8fa1;
  }

  @media (width <= 47.5em) {
    :root {
      --spacing--page-inline: 6%;
    }
  }

  @media (48em <= width <= 64em) {
    :root {
      --width--content: 45rem;
      --width--list: 43rem;
    }
  }

  @media (64em < width < 75em) {
    :root {
      --width--content: 52rem;
      --width--list: 50rem;
    }
  }

  @media (75em <= width) {
    :root {
      --width--content: 58rem;
      --width--list: 56rem;
    }
  }

  /* Dark mode: Catppuccin Frappe. */
  @media (prefers-color-scheme: dark) {
    :root {
      --color--bg: #303446;
      --color--bg-secondary: #414559;
      --color--text: #c6d0f5;
      --color--text-light: #b5bfe2;
      --color--text-quote: #a5adce;
      --color--code-text: #c6d0f5;
      --color--link: #8caaee;
      --color--link-hover: #babbf1;
      --color--link-underline: rgba(140, 170, 238, 0.4);
      --color--link-underline-hover: rgba(140, 170, 238, 0.8);
      --color--icon-hover: #8caaee;
      --color--border-base: #626880;
      --color--border-dark: #626880;

      --color--code-keyword: #ca9ee6;
      --color--code-name: #8caaee;
      --color--code-string: #a6d189;
      --color--code-number: #ef9f76;
      --color--code-comment: #838ba7;
    }
  }
}

@layer base {
  @font-face {
    font-family: "et-book";
    src: url("/font/et-book-roman-line-figures.woff") format("woff");
    font-weight: normal;
    font-style: normal;
    font-display: swap;
  }

  @font-face {
    font-family: "et-book";
    src: url("/font/et-book-display-italic-old-style-figures.woff")
      format("woff");
    font-weight: normal;
    font-style: italic;
    font-display: swap;
  }

  @font-face {
    font-family: "et-book";
    src: url("/font/et-book-bold-line-figures.woff") format("woff");
    font-weight: bold;
    font-style: normal;
    font-display: swap;
  }

  @font-face {
    font-family: "et-book-roman-old-style";
    src: url("/font/et-book-roman-old-style-figures.woff") format("woff");
    font-weight: normal;
    font-style: normal;
    font-display: swap;
  }

  html {
    font-size: var(--font-size--root);
  }

  body {
    margin-left: auto;
    margin-right: auto;
    padding-right: var(--spacing--page-inline);
    padding-bottom: var(--spacing--xxx-large);
    padding-left: var(--spacing--page-inline);
    font-family: var(--font-family--serif);
    background-color: var(--color--bg);
    color: var(--color--text);
    max-width: 1200px;
  }

  h1 {
    font-weight: var(--font-weight--normal);
    margin-top: var(--spacing--xxxx-large);
    margin-bottom: var(--spacing--large);
    font-size: var(--font-size--xx-large);
    line-height: var(--line-height--tight);
  }

  h2 {
    font-style: italic;
    font-weight: var(--font-weight--normal);
    margin-top: var(--spacing--xx-large);
    margin-bottom: var(--spacing--medium-large);
    font-size: var(--font-size--x-large);
    line-height: var(--line-height--tight);
  }

  h3 {
    font-style: italic;
    font-weight: var(--font-weight--normal);
    font-size: var(--font-size--large);
    margin-top: var(--spacing--x-large);
    margin-bottom: var(--spacing--medium-large);
    line-height: var(--line-height--tight);
  }

  hr {
    display: block;
    height: 1px;
    border: 0;
    border-top: 1px solid var(--color--border-dark);
    margin: var(--spacing--medium-small) 0;
    padding: 0;
  }

  section {
    padding-top: var(--spacing--medium-small);
    padding-bottom: var(--spacing--medium-small);
  }

  p,
  dl,
  ol,
  ul {
    font-size: var(--font-size--medium);
    line-height: var(--line-height--base);
  }

  p {
    margin-top: var(--spacing--medium-large);
    margin-bottom: var(--spacing--medium-large);
    padding-right: 0;
    vertical-align: baseline;
  }

  blockquote {
    font-size: var(--font-size--medium);
    color: var(--color--text-quote);
  }

  blockquote p,
  blockquote footer {
    margin-right: var(--spacing--blockquote-end);
  }

  blockquote footer {
    font-size: var(--font-size--small);
    text-align: right;
  }

  /* The text column. */
  hr,
  section > p:not(:has(img)),
  section > footer,
  section > table,
  blockquote p,
  blockquote footer {
    width: 100%;
    max-width: var(--width--content);
  }

  section > dl,
  section > ol,
  section > ul {
    width: 100%;
    max-width: var(--width--list);
    padding-left: var(--spacing--x-large);
  }

  dt:not(:first-child),
  li:not(:first-child) {
    margin-top: var(--spacing--xx-small);
  }

  a:link,
  a:visited {
    color: var(--color--link);
    text-decoration: none;
    border-bottom: 1px dotted var(--color--link-underline);
  }

  a:hover {
    color: var(--color--link-hover);
    border-bottom-color: var(--color--link-underline-hover);
  }

  img {
    max-width: 100%;
    max-height: 1000px;
    width: auto;
    height: auto;
    object-fit: contain;
    margin: var(--spacing--medium) 0;
  }

  code,
  pre > code {
    font-family: var(--font-family--mono);
    font-size: var(--font-size--x-small);
    line-height: var(--line-height--code);
    /* Prevent adjustments of font size after orientation changes in
       iOS. See https://github.com/edwardtufte/tufte-css/issues/81#issuecomment-261953409 */
    -webkit-text-size-adjust: 100%;
  }

  h1 > code,
  h2 > code,
  h3 > code {
    font-size: var(--font-size--code-in-heading);
  }

  pre {
    background: transparent;
    border-left: 3px solid var(--color--border-base);
    padding-left: var(--spacing--small);
    overflow-x: auto;
    white-space: pre;
  }

  pre > code {
    font-size: var(--font-size--xx-small);
    margin-left: var(--spacing--code-indent);
    overflow-x: auto;
    display: block;
  }

  :not(pre) > code {
    background-color: var(--color--bg-secondary);
    color: var(--color--code-text);
    padding: var(--spacing--code-block) var(--spacing--code-inline);
    border: 1px solid var(--color--border-base);
    border-radius: var(--border-radius--small);
  }

  /* A paragraph that holds two images is a screenshot pair. A phone
     screenshot at content width costs a screen of scrolling, so the
     pair has a capped height. */
  section > p:has(img + img) {
    display: flex;
    gap: var(--spacing--medium-small);
    align-items: flex-start;
  }

  section > p:has(img + img) img {
    max-height: 30rem;
    width: auto;
    margin: 0;
    border: 1px solid var(--color--border-base);
    border-radius: var(--border-radius--base);
  }

  @media (width <= 47.5em) {
    pre > code {
      width: 97%;
    }

    section > dl,
    section > ol,
    section > ul {
      width: 90%;
    }

    blockquote {
      margin-left: var(--spacing--xx-large);
      margin-right: 0;
    }

    img:not(section > p:has(img + img) img) {
      width: 100%;
    }

    /* Two phone screenshots read too small side by side on a phone,
       so they stack. */
    section > p:has(img + img) {
      flex-direction: column;
    }
  }
}

@layer components {
  .site-header {
    margin: var(--spacing--x-large) 0 var(--spacing--x-small) 0;
  }

  .profile-link {
    border: none;
  }

  .profile-image {
    border-radius: 50%;
    display: block;
    margin-right: var(--spacing--profile-image);
    width: 64px;
    height: 64px;
  }

  .social {
    display: flex;
    gap: var(--spacing--medium-small);
    margin-block-end: var(--spacing--x-small);
    align-items: center;

    a {
      border: none;
      display: flex;
      align-items: center;
      justify-content: center;
      line-height: var(--line-height--tight);
      padding-bottom: 0;
      min-height: 24px;
    }

    svg {
      fill: var(--color--text);
      height: 24px;
      transition: all 0.2s ease;
      width: 24px;
      vertical-align: middle;
      display: block;

      &:hover {
        fill: var(--color--icon-hover);
      }
    }
  }

  /* A topic on the home page. */
  .dir {
    padding: var(--spacing--medium-large) 0;

    h3 {
      margin-block-start: 0;
      margin-block-end: var(--spacing--medium-small);
    }

    ul {
      width: 100%;
      padding-left: var(--spacing--large);
      margin: 0;
    }

    li {
      margin-top: var(--spacing--xx-small);
    }
  }

  .byline {
    color: var(--color--text-light);
    font-style: italic;
  }

  /* Syntax highlighting: five classes, which is all
     github.com/croaky/highlight emits: k keywords, n names, s strings,
     m numbers, and c comments. Operators and punctuation carry no class
     and take the text color. */
  .code {
    .k {
      color: var(--color--code-keyword);
    }

    .n {
      color: var(--color--code-name);
    }

    .s {
      color: var(--color--code-string);
    }

    .m {
      color: var(--color--code-number);
    }

    .c {
      color: var(--color--code-comment);
      font-style: italic;
    }
  }
}
