@layer base {

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

  body { margin: 0; }

  body,
  .sans {
    font-family: sans-serif;
  }

  main {
    margin: auto;
    width: var(--content-width);
  }

  /* The breakpoint itself has to stay a literal - custom properties can't
     be read inside a media feature query - but the width below it still
     tracks --content-width like everywhere else that uses it. */
  @media (max-width: 42rem) {
    main {
      padding: 0 1rem;
      width: 100%;
    }
  }

  p,
  article,
  .prose :not(h1, h2, h3, h4, h5, h6),
  .serif {
    font-family: serif;
  }

  :root {
    --ctrl-padding: 0.5em;
    --std-margin: 0.5em;
    --std-radius: 5px;
    --color-primary: #66d;
    --content-width: 40rem;
  }

  /* Buttons and text inputs otherwise differ in height because only
     buttons had explicit padding - plain text inputs were left at the
     browser's own (smaller, inconsistent) default. Sharing one variable
     across both, in one merged rule, keeps that in sync going forward
     instead of relying on separate literals staying equal. */
  button,
  .btn,
  input[type="text"],
  input[type="password"],
  input[type="email"],
  input[type="url"],
  input[type="tel"],
  input[type="search"],
  input[type="number"],
  input[type="date"],
  input[type="datetime-local"],
  input[type="month"],
  input[type="week"],
  input[type="time"] {
    padding: var(--ctrl-padding);
  }

  button, .btn {
    font-size: 1rem;
    border-radius: var(--std-radius);
    background: white;
    border: solid 1px #ccc;
    color: #333;
    cursor: pointer;

    &.primary {
      background: var(--color-primary);
      color: white;
      border: solid 1px white;
    }

    &.small {
      font-size: 0.875rem;
    }

    &.large {
      font-size: 1.25rem;
    }
  }

  /* accent-color recolours the native widget rather than replacing it, so
     radios stay fully native (keyboard/screen-reader behaviour intact)
     while picking up the same blue already used for .btn.primary. Sized in
     em so it scales with its own font-size context, same as buttons. */
  input[type="radio"] {
    width: 1.2em;
    height: 1.2em;
    accent-color: var(--color-primary);
    cursor: pointer;
  }

  /* flexbox rather than vertical-align, since it guarantees the radio and
     its text line up on their centres regardless of font metrics. Targets
     any label wrapping a radio directly, wherever it appears - not scoped
     to one example, so this is true everywhere by default rather than
     something each new radio group has to opt into. Only responsible for
     the label's own internal layout - spacing between separate labels is
     the containing cluster's job (below), not this rule's. */
  label:has(> input[type="radio"]) {
    display: inline-flex;
    align-items: center;
  }

  label:has(> input[type="radio"]) span {
    margin-left: var(--std-margin);
  }

  /* Monospace fonts render visually larger than the surrounding proportional
     text at the same nominal font-size, so normalize.css's font-size: 1em
     leaves code looking oversized even though it matches numerically. rem,
     not em, since this should track the document's global scale like any
     other text, not one component's own local size. */
  code {
    font-size: 0.875rem;
  }

  /* Title-left, content-right list: dt's right edge and dd's left edge line
     up down the whole list, with dd wrapping onto multiple lines sharing its
     own left margin. No class needed - dl already means term/description
     pairs, so this is just what a dl looks like, same as buttons/inputs
     getting styled directly. Grid auto-placement drops alternating dt/dd
     children into the two columns in document order, so neither needs an
     explicit grid-column. */
  dl:has(> dt) {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: calc(var(--std-margin) * 2);
    row-gap: var(--std-margin);
  }

  dt {
    font-weight: bold;
    text-align: right;
  }

  dd {
    margin: 0;
  }

  table {
    border-spacing: 0;
    border: solid 1px lightblue;
    border-radius: var(--std-radius);

    > thead {
      background: lightgrey;
      text-align: left;
    }
    th, td {
      padding: 0.2em;
      padding-left: 1rem;
    }
    th:first-child, td:first-child {
      padding-left: 0.5rem;
    }
  }

  /* If label wraps an input field, it is styled to be placed above
   * the input field, with both elements displayed as block. */
  label:has(> input) {
    display: block;
    width: 100%;
  }

  label:has(> input) > input {
    display: block;
  }

  /*
   * == SECTION ==
   *
   * Stand-alone decorators
   */

  /* Standard border - the same border style already used by button/.btn in
     base.css, pulled out so anything else that needs an ordinary border
     (e.g. making a layout's edges visible) can reuse the one value rather
     than repeating the literal. */
  .std-border {
    border: 1px solid #ccc;
    border-radius: var(--std-radius);
  }


}
