/**
 * Fluid Theme - Base Element Styles
 * @layer base
 *
 * Native elements, no classes needed. A quality-press page: a serif for
 * display and headings, a grotesk for text and labels, one accent used like
 * spice, square corners, no shadows. Nothing moves on hover except colour
 * and underline.
 */

@layer base {
  /* ========================================
     DOCUMENT
     ======================================== */

  body {
    font-family: var(--font-body);
    font-size: var(--step-0);
    line-height: var(--leading-body);
    color: var(--color-text);
    background-color: var(--color-background);
    text-wrap: pretty;
  }

  ::selection {
    background-color: var(--color-selection);
    color: var(--color-text);
  }


  /* ========================================
     HEADINGS
     A big, obvious ladder: serif h1-h3 at the scale's top, a change of face
     at h4, the label voice at h5 and h6. Every weight adds --_dark-weight
     (30 in dark mode and on dark bands).
     ======================================== */

  h1, h2, h3, h4, h5, h6 {
    color: var(--color-text);
    margin-block: 0 var(--space-4);
  }

  /* The trim is over the cap height only: trimming the alphabetic baseline
     too let descenders (p, q, g) hang into the next block at display sizes. */
  h1, h2, h3 {
    font-family: var(--font-heading);
    font-weight: calc(var(--weight-display) + var(--_dark-weight));
    line-height: var(--leading-heading);
    text-wrap: balance;
    text-box: trim-start cap alphabetic;
  }

  /* --h1-size, --h2-size, --h3-size (knobs, no default) set a heading's
     size outright; unset, the steps. legacy-1x sets them to the 1.x clamps,
     so the steps (also the nav brand, lede, card title) keep their values. */
  h1 { font-size: var(--h1-size, var(--step-4)); letter-spacing: var(--tracking-tight); }
  /* --weight-heading (a knob, no default) sets h2 and h3 to one weight;
     unset, h2 follows the display weight and h3 sits 100 above it, but
     never above 700 unless the display is (display 700 gives h3 700, not
     an h3 heavier than its h2). */
  h2 {
    font-size: var(--h2-size, var(--step-2));
    font-weight: calc(var(--weight-heading, var(--weight-display)) + var(--_dark-weight));
    letter-spacing: var(--tracking-heading);
  }
  h3 {
    font-size: var(--h3-size, var(--step-1));
    font-weight: calc(var(--weight-heading, min(var(--weight-display) + 100, max(var(--weight-display), 700))) + var(--_dark-weight));
    letter-spacing: var(--tracking-normal);
  }

  h4 {
    font-family: var(--font-body);
    font-size: var(--font-size-lg);
    font-weight: calc(650 + var(--_dark-weight));
    line-height: 1.3;
  }

  /* The label voice: every small uppercase label is this one rule. Longhands,
     so nothing else is reset; lining but proportional figures (tabular ones
     gap the comma: "GOGH , 1889"; a numeric head takes .num); :where(), so
     each element keeps its own low specificity. */
  :where(.eyebrow, h5, h6, thead th, .plate, cite, legend, dt, .toc__label) {
    font-family: var(--font-body);
    font-size: var(--step--2);
    font-weight: calc(var(--weight-semibold) + var(--_dark-weight));
    line-height: var(--leading-tight);
    font-style: normal;
    text-transform: uppercase;
    letter-spacing: var(--tracking-caps);
    font-variant-numeric: lining-nums;
    color: var(--color-text-muted);
  }

  .eyebrow { color: var(--accent-ink); margin-block: 0 var(--space-s); }
  :where(h5, .plate) { color: var(--color-text); }
  h6 { color: var(--color-text-muted); }


  /* ========================================
     DISPLAY HEADLINES
     The font size is a fixed share of the column's width, so a hand break
     (<br>) stays put and every line keeps filling the column as the screen
     grows. --fit is the longest line's width in em (characters × 0.5,
     rounded up; fit-text.js measures it once for [data-fit]). Optical size
     is pinned so glyph width scales linearly with size. The cap is also
     15svh, so a three-line headline leaves the lede and actions above the
     fold on a 900px-tall laptop (160px type pushed them under it). Setting
     --hero-headline-size on :root overrides the fit.
     ======================================== */

  .display,
  .hero__headline {
    font-family: var(--font-display);
    font-weight: calc(var(--weight-display) + var(--_dark-weight));
    font-size: var(--hero-headline-size,
               clamp(var(--step-4), 100cqi / var(--fit, 8), min(var(--display-max), 15svh)));
    font-variation-settings: "opsz" 72;
    line-height: 1;
    letter-spacing: var(--tracking-display);
    text-wrap: balance;
    text-box: trim-start cap alphabetic;
  }


  /* ========================================
     TEXT
     ======================================== */

  p {
    margin-block: 0 var(--space-5);
    max-inline-size: var(--measure);
  }

  p:last-child { margin-block-end: 0; }

  .lede {
    font-family: var(--font-heading);
    font-weight: calc(var(--weight-light) + var(--_dark-weight));
    font-size: var(--step-1);
    line-height: 1.4;
    letter-spacing: -0.005em;
    max-inline-size: 30em;
  }

  :is(.meta, figcaption) {
    font-family: var(--font-body);
    font-size: var(--step--1);
    font-weight: 400;
    line-height: 1.45;
    letter-spacing: 0.01em;
    color: var(--color-text-muted);
    /* Lining but proportional: tabular figures in these faces also widen
       the comma and full stop, which gaps running caption text. */
    font-variant-numeric: lining-nums proportional-nums;
  }

  strong, b { font-weight: calc(var(--weight-semibold) + var(--_dark-weight)); }

  em, i { font-style: italic; }

  small {
    font-size: var(--step--1);
    color: var(--color-text-muted);
  }

  sub, sup {
    font-size: 75%;
    line-height: 0;
    position: relative;
    vertical-align: baseline;
  }

  sup { inset-block-start: -0.5em; }
  sub { inset-block-end: -0.25em; }


  /* ========================================
     LINKS
     Text colour; the underline marks the link (WCAG 1.4.1). Hover turns
     the underline to the accent and thickens it. Only colour and the
     underline transition.
     ======================================== */

  a {
    color: inherit;
    text-decoration-line: underline;
    text-decoration-color: color-mix(in oklch, var(--accent-ink) 55%, transparent);
    text-decoration-thickness: 0.06em;
    text-underline-offset: 0.22em;
    text-decoration-skip-ink: auto;
    transition:
      color var(--duration-fast) var(--ease-fluid),
      text-decoration-color var(--duration-fast) var(--ease-fluid),
      text-decoration-thickness var(--duration-fast) var(--ease-fluid);
  }

  a:hover {
    text-decoration-color: var(--accent-ink);
    text-decoration-thickness: 0.12em;
  }

  /* Links that look like text and show their underline on hover */
  a[data-subtle] { text-decoration-line: none; }
  a[data-subtle]:hover { text-decoration-line: underline; }


  /* ========================================
     LISTS
     ======================================== */

  ul, ol {
    padding-inline-start: var(--space-6);
    margin-block: 0 var(--space-5);
  }

  /* Chrome draws markers with tabular figures, which in these faces widen
     the full stop ("1 ."). */
  ::marker { font-variant-numeric: lining-nums proportional-nums; }

  li { margin-block-end: var(--space-2); }
  li:last-child { margin-block-end: 0; }

  li > :is(ul, ol) { margin-block: var(--space-2) 0; }

  /* A term in the label voice (above), its value flush under it. */
  dl { margin-block: 0 var(--space-5); }

  dt { margin-block-end: var(--space-1); }

  dd {
    margin-inline-start: 0;
    margin-block-end: var(--space-4);
  }


  /* ========================================
     QUOTES
     ======================================== */

  blockquote {
    margin-inline: 0;
    margin-block: var(--space-l);
    padding-inline-start: 1.25em;
    border-inline-start: var(--border-width-thick) solid var(--accent);
    font-family: var(--font-heading);
    font-size: var(--step-1);
    font-style: italic;
    line-height: 1.4;
  }

  blockquote cite {
    display: block;
    margin-block-start: var(--space-s);
  }

  /* A pull quote repeats the text, so it is a <p class="pullquote">, not
     an <aside> (a complementary landmark nested in the article) and not a
     <blockquote> (it quotes no one else). */
  .pullquote {
    margin-inline: 0;
    margin-block: var(--space-l);
    padding-block: var(--space-m);
    border-block: var(--border-width) solid var(--color-border-strong);
    font-family: var(--font-heading);
    font-size: var(--step-3);
    font-weight: calc(var(--weight-light) + var(--_dark-weight));
    line-height: var(--leading-heading);
    letter-spacing: var(--tracking-heading);
    text-wrap: balance;
  }


  /* ========================================
     CODE
     ======================================== */

  :is(code, kbd, samp, pre) { font-family: var(--font-mono); }

  code {
    font-size: 0.9em;
    background-color: var(--color-surface);
    padding: 0.1em 0.3em;
    border-radius: var(--radius-control);
  }

  pre {
    font-size: var(--step--1);
    line-height: var(--leading-relaxed);
    background-color: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-card);
    padding: var(--space-m);
    overflow-x: auto;
    margin-block: 0 var(--space-5);
    tab-size: 2;
  }

  pre code {
    background: none;
    padding: 0;
    font-size: inherit;
  }

  kbd {
    font-size: 0.875em;
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-control);
    padding: 0.1em 0.35em;
  }

  var {
    font-style: italic;
    font-weight: var(--weight-medium);
  }


  /* ========================================
     RULES
     ======================================== */

  hr {
    border: none;
    border-block-start: var(--border-width) solid var(--color-border);
    max-inline-size: var(--measure);
    margin-block: var(--space-xl);
  }

  hr[data-variant="ornament"] {
    border: 0;
    text-align: center;
    overflow: visible;
  }

  /* Three asterisks in the heading face: the asterism glyph (⁂) is not in
     the latin subset of the fonts file, so it fell back to another face. */
  hr[data-variant="ornament"]::before {
    content: "*\2003*\2003*";
    font: var(--step-1) / 1 var(--font-heading);
    color: var(--color-text-muted);
  }


  /* ========================================
     MEDIA
     Images in true colour at their natural ratio. data-aspect crops any
     img or video; data-focus (on it or a wrapper) sets the crop's focal point.
     ======================================== */

  :is(img, video) { object-position: var(--focus, 50% 50%); }

  [data-aspect="square"] { --_aspect: 1; }
  [data-aspect="video"] { --_aspect: 16 / 9; }
  [data-aspect="portrait"] { --_aspect: 3 / 4; }
  [data-aspect="wide"] { --_aspect: 21 / 9; }

  :is(img, video)[data-aspect] {
    aspect-ratio: var(--_aspect, auto);
    object-fit: cover;
  }

  [data-focus="top"] { --focus: 50% 0; }
  [data-focus="bottom"] { --focus: 50% 100%; }
  [data-focus="left"] { --focus: 0 50%; }
  [data-focus="right"] { --focus: 100% 50%; }
  [data-focus="center"] { --focus: 50% 50%; }

  figure { margin: 0; margin-block: var(--space-l); }

  figure :is(img, picture, video) {
    inline-size: 100%;
    border-radius: var(--radius-card);
  }

  /* An uncropped image is never taller than the screen: a portrait at the
     column's full width ran two screens tall. The box keeps the column's
     width and the width/height attributes' ratio, so a lazy image holds
     its space before it loads (inline-size: auto made it 0 × 0); a
     portrait capped at 85svh is fitted inside the box at the start edge,
     never squashed. Full-bleed figures and the hero plate are not capped:
     they are the full width at their natural ratio. */
  figure:not([data-bleed="full"], .alignfull, .hero__plate) > :is(img, video):not([data-aspect]),
  figure:not([data-bleed="full"], .alignfull, .hero__plate) > picture > img:not([data-aspect]) {
    block-size: auto;
    max-block-size: 85svh;
    object-fit: contain;
    object-position: var(--focus, 0% 50%);
  }

  figcaption {
    margin-block-start: var(--space-xs);
    max-inline-size: 48ch;
  }

  /* A credit in <small>, a plate number in .plate or b, a work title in <i>. */
  figcaption :is(.plate, b) {
    margin-inline-end: 0.75em;
  }

  figcaption small { font-size: inherit; }

  @container (inline-size > 60rem) {
    figure[data-caption="side"] {
      display: grid;
      grid-template-columns: 1fr 16rem;
      column-gap: var(--space-m);
      align-items: end;
    }
  }


  /* ========================================
     TABLES
     Label-voice head over a 2px ink rule, hairline rows, tabular figures.
     ======================================== */

  /* Lining but proportional: tabular figures also widen the comma, which
     gapped prose cells ("Boston , MA"). Numeric cells opt in below. */
  table {
    inline-size: 100%;
    margin-block: 0 var(--space-5);
    border-collapse: collapse;
    font-size: var(--step--1);
    font-variant-numeric: lining-nums proportional-nums;
  }

  :is(th, td) {
    padding-block: 0.85em;
    padding-inline: 0 var(--space-4);
    text-align: start;
    border-block-end: var(--border-width) solid var(--color-border);
  }

  :is(td, th):is([data-type="number"], .num) {
    font-variant-numeric: lining-nums tabular-nums;
    text-align: end;
  }

  th { font-weight: calc(var(--weight-semibold) + var(--_dark-weight)); }

  thead th {
    vertical-align: bottom;
    border-block-end: var(--border-width-thick) solid var(--color-border-strong);
  }

  caption {
    caption-side: top;
    text-align: start;
    margin-block-end: var(--space-xs);
  }


  /* ========================================
     FORMS
     Square fields on the page colour with an ink edge, 3rem tall, body-size
     text (which also stops iOS zooming on focus). Focus is an outline, so an
     invalid field keeps its error border and still shows focus.
     ======================================== */

  label {
    display: block;
    font-size: var(--step--1);
    font-weight: calc(var(--weight-semibold) + var(--_dark-weight));
    margin-block-end: var(--space-2);
    color: var(--color-text);
  }

  input,
  textarea,
  select {
    inline-size: 100%;
    min-block-size: 3rem;
    padding: 0.6em 0.8em;
    font: inherit;
    font-size: var(--step-0);
    line-height: 1.4;
    color: var(--color-text);
    background-color: var(--color-background);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-control);
    transition: border-color var(--duration-fast) var(--ease-fluid);
  }

  :is(input, textarea, select):focus {
    outline: var(--focus-ring-width) solid var(--color-focus);
    outline-offset: 1px;
  }

  :is(input, textarea)::placeholder {
    color: var(--color-text-subtle);
    opacity: 1;
  }

  :is(input, textarea, select):disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  /* Bare checkboxes and radios keep a box shape: the text-field rules above
     (full width, padding, border) would turn <label><input type="checkbox">
     Text</label> into a full-width bar. Same weight as `input`, so the custom
     .checkbox / .radio / .switch inputs (one class) still win. */
  input:where([type="checkbox"], [type="radio"]) {
    inline-size: 1.25rem;
    block-size: 1.25rem;
    min-block-size: 0;
    padding: 0;
    margin: 0;
    margin-inline-end: var(--space-2);
    vertical-align: -0.2em;
    border: 0;
    accent-color: var(--accent);
    cursor: pointer;
  }

  input:where([type="checkbox"], [type="radio"]):focus { outline: 0; }

  input:where([type="checkbox"], [type="radio"]):focus-visible {
    outline: var(--focus-ring-width) solid var(--color-focus);
    outline-offset: 2px;
  }

  /* Date and time boxes take their cell's width. iOS Safari sizes a native
     date/time input to its own content and ignores inline-size, so in a grid
     it ran into the next column (#65). Without the native appearance it
     behaves like a text field. */
  input:where([type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"]) {
    display: block;
    min-inline-size: 0;
    max-inline-size: 100%;
    -webkit-appearance: none;
    appearance: none;
  }

  input:where([type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"])::-webkit-date-and-time-value {
    text-align: start;
  }

  textarea {
    min-block-size: 8rem;
    resize: vertical;
  }

  /* Fieldset: no box, a top hairline, the legend in the label voice. */
  fieldset {
    margin: 0;
    margin-block-end: var(--space-l);
    padding: 0;
    padding-block-start: var(--space-s);
    border: 0;
    border-block-start: var(--border-width) solid var(--color-border);
    min-inline-size: 0;
  }

  legend {
    float: inline-start;
    inline-size: 100%;
    padding: 0;
    margin-block-end: var(--space-m);
  }

  legend + * { clear: both; }


  /* ========================================
     DETAILS
     ======================================== */

  details {
    margin-block: 0 var(--space-4);
    border-block: var(--border-width) solid var(--color-border);
  }

  details + details { border-block-start: 0; margin-block-start: calc(-1 * var(--space-4)); }

  summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 var(--space-2);
    min-block-size: 2.75rem;
    padding-block: var(--space-2);
    font-weight: calc(var(--weight-semibold) + var(--_dark-weight));
    cursor: pointer;
  }

  details[open] > summary { margin-block-end: var(--space-s); }

  summary::-webkit-details-marker { display: none; }
  summary::marker { content: ""; }

  /* The chevron is decoration: empty alt text keeps it out of the
     summary's accessible name (and so out of a landmark's name). */
  summary::before {
    content: "▸";
    content: "▸" / "";
    display: inline-block;
    transition: rotate var(--duration-fast) var(--ease-settle);
  }

  /* Logical: the marker points along the inline direction and turns down. */
  summary:dir(rtl)::before { scale: -1 1; }
  details[open] > summary::before { rotate: 90deg; }
  details[open] > summary:dir(rtl)::before { rotate: -90deg; }


  /* ========================================
     SEMANTIC ELEMENTS
     ======================================== */

  mark {
    background-color: light-dark(oklch(90% 0.08 90), oklch(40% 0.08 90));
    color: var(--color-text);
    padding-inline: var(--space-1);
  }

  abbr[title] {
    text-decoration: underline dotted;
    cursor: help;
  }

  address {
    font-style: normal;
    margin-block-end: var(--space-5);
  }

  time { font-variant-numeric: lining-nums; }


  /* ========================================
     METER & PROGRESS
     ======================================== */

  meter,
  progress {
    inline-size: 100%;
    block-size: var(--space-2);
    overflow: hidden;
  }

  progress {
    appearance: none;
    border: 0;
    background-color: var(--color-surface);
  }

  progress::-webkit-progress-bar { background-color: var(--color-surface); }
  progress::-webkit-progress-value { background-color: var(--accent); }
  progress::-moz-progress-bar { background-color: var(--accent); }


  /* ========================================
     DIALOG
     ======================================== */

  dialog {
    max-inline-size: min(90vw, var(--container-sm));
    padding: var(--space-6);
    color: var(--color-text);
    background-color: var(--color-background);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-card);
  }

  dialog::backdrop { background-color: oklch(0 0 0 / 0.5); }


  /* ========================================
     SKIP LINK
     Hidden until focused for keyboard users
     ======================================== */

  .skip-link {
    position: absolute;
    inset-block-start: var(--space-4);
    inset-inline-start: var(--space-4);
    z-index: var(--z-max);
    padding: var(--space-3) var(--space-5);
    background-color: var(--accent);
    color: var(--on-accent);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    translate: 0 -200%;
  }

  .skip-link:focus {
    translate: none;
    outline: var(--focus-ring-width) solid var(--color-focus);
    outline-offset: 2px;
    /* A halo in the page colour: the link lands on the nav bar, which is
       the page's other scheme. */
    box-shadow: 0 0 0 calc(2px + var(--focus-ring-width)) var(--color-background);
  }


  /* ========================================
     PRINT
     ======================================== */

  @media print {
    body {
      font-size: 12pt;
      line-height: 1.5;
    }

    h1, h2, h3, h4, h5, h6 { break-after: avoid; }

    p, blockquote, ul, ol, table { break-inside: avoid; }

    a { color: inherit; }

    a[href^="http"]::after {
      content: " (" attr(href) ")";
      font-size: 0.8em;
      color: var(--color-text-muted);
    }

    .modal,
    .toast-container,
    .nav {
      display: none !important;
    }

    .badge,
    .alert {
      print-color-adjust: exact;
      border: var(--border-width) solid currentColor;
    }
  }
}
