/* Notes Page Styles */

#notes-list-container {
  min-height: 400px; /* Adjust as needed */
  transition: min-height 0.3s ease-in-out;
}


/* Year section styling for 'All Notes' page */
.year-section {
  /* This div groups a year heading and its list of notes. */
  /* Spacing between year groups is handled by .year-heading margin-top */
  /* and .notes-list-by-year margin-bottom. */
  margin-bottom: 0; /* Reset if any previous style existed */
}

/* Style for the H1 'All notes' title added by JS */
main > h1 {
  font-family: var(--font-style-title-family);
  font-size: var(--font-style-title-size);
  font-weight: var(--font-style-title-weight);
  color: var(--font-style-title-color);
  margin-bottom: var(--space-xl); /* L (64px) */
}

.year-heading { /* This is the H2 element for the year, e.g., "2025" */
  font-family: var(--font-style-title-family);
  font-size: var(--font-style-title-size);
  font-weight: var(--font-style-title-weight);
  color: var(--font-style-title-color);
  margin-top: var(--space-xl);    /* XL (80px) - default top margin */
  margin-bottom: var(--space-lg); /* L (64px) - space before the list of notes */
}



.notes-list-by-year { /* This is the UL element containing notes for a year */
  list-style: none;
  padding: 0;
  margin: 0;
  /* Space between this year's notes and the next year's heading */
  /* This effectively creates space between year groups */
  margin-bottom: var(--space-xxl); /* XL (80px) */
}

/* Add extra space after the very last list of notes, before the footer */
main > .year-section:last-of-type > .notes-list-by-year:last-of-type {
    margin-bottom: var(--space-xxxl); /* XXL (128px) or more if needed */
}

.note-item-detailed { /* This is the LI element for each note entry */
  display: flex;
  margin-bottom: var(--space-md); /* S (24px) - space between note items */
  position: relative; /* Make it a positioning context for the stretched link */
}

/* Stretched link to make the whole item clickable */
.note-item-detailed .item-link {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.note-date-column { /* Div for the date, e.g., "May 26" */
  flex: 0 0 20%;
  padding-right: var(--space-md); /* S (24px) - gap to content */
  box-sizing: border-box;
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  line-height: 1.6; /* Match body line height for vertical alignment */
}

.note-content-column { /* Div for title and summary */
  flex: 0 0 80%;
}

.note-content-column h3 { /* Note title */
  font-family: var(--font-style-title-family);
  font-size: var(--font-style-title-size);
  font-weight: var(--font-style-title-weight);
  color: var(--font-style-title-color);
  margin-top: 0;
  margin-bottom: var(--space-xs); /* XXS (8px) - space to summary */
  line-height: 1.4; 
}

.note-content-column h3 a {
  color: inherit; /* Inherit color from h3 */
  text-decoration: none;
  position: relative; /* Ensure the title link is on top of the stretched link */
  z-index: 2;
}

/* Underline the title link when hovering over the entire list item */
.note-item-detailed:hover .note-content-column h3 a {
  text-decoration: underline;
}

.note-content-column p { /* Note summary */
  font-family: var(--font-style-body-primary-family);
  font-size: var(--font-style-body-primary-size);
  font-weight: var(--font-style-body-primary-weight);
  color: var(--font-style-body-primary-color);
  line-height: 1.6;
  margin-top: 0;
  margin-bottom: 0; /* No extra margin for the summary paragraph itself */
}

/* Individual note page styles */

/* Title, then meta; the body starts 72px under the meta. */
.note-header {
  margin-bottom: 72px;
}

.note-title {
  font-family: var(--font-family);
  font-size: var(--font-style-h1-size);
  font-weight: var(--font-style-h1-weight);
  line-height: var(--font-style-h1-line-height);
  color: var(--color-text);
  margin-bottom: var(--space-sm);
  text-wrap: balance; /* Even line lengths when the title wraps */
}

.note-meta {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  margin-bottom: 0;
}

/* Topics are links inside the meta line (see typography.css). The one being
   filtered on is set in brackets, in the primary ink. */
.note-topic.selected {
  font-weight: var(--font-style-title-weight-bold, 500);
  color: var(--font-style-body-primary-color);
}

.left-column .read-newer-link.disabled,
.left-column .read-older-link.disabled {
  color: var(--color-text-tertiary);
  pointer-events: none;
}





.note-content-body {
  color: var(--font-style-body-secondary-color);
}

/* Ensure the first element in note body starts right at the top of its row */
.note-content-body>*:first-child {
  margin-top: 0;
}

.note-content-body p {
  margin-bottom: var(--space-md);
}

/* Size, weight and ink come from the h2 and h3 styles (typography.css);
   what a note adds is the space around them. Space belongs to the section a
   heading opens, so it sits closer to the text below than to the paragraph
   above. */
.note-content-body h2 {
  margin-top: var(--space-lg);
  margin-bottom: var(--space-xs);
}

.note-content-body h3 {
  margin-top: var(--space-md);
  margin-bottom: var(--space-xs);
}

.note-content-body ul,
.note-content-body ol {
  margin: 0 0 var(--space-md);
  padding-left: var(--space-md);
}

.note-content-body li {
  margin-bottom: var(--space-xs);
}

/* Links in the body follow typography.css. Buttons and update-card links
   are links dressed as something else, and keep their own hover. */
.note-content-body a.button:hover,
.note-content-body a.update-link:hover {
  text-decoration: none;
}

/* Standardized Media Container */
figure.media-container,
.media-container {
  margin: var(--space-lg) 0;
  width: 100%;
}

/* Whatever opens a section sits as close under its heading as text does.
   A figure's own margin would otherwise collapse with the heading's smaller
   one and win, leaving the heading as far from its section as from the one
   before. After the media rules, which this has to beat. */
.note-content-body :is(h2, h3) + * {
  margin-top: 0;
}

.media-container img {
  width: 100%;
  height: auto;
  display: block;
}

/* A video stands in for a GIF where one would be too heavy. It carries no
   controls (see js/media-replay.js), so it needs to sit in the column exactly
   as an image does — nothing here should betray that it is a video. */
.media-container video,
figure video {
  width: 100%;
  height: auto;
  display: block;
}

/* Safari puts its own furniture on a video unless told otherwise. */
video::-webkit-media-controls,
video::-webkit-media-controls-start-playback-button {
  display: none !important;
  -webkit-appearance: none;
}

.media-container.seamless-group img {
  margin: 0;
}

/* ==========================================================================
   Figure and video numbers

   Every caption in a note is numbered for it, in reading order: "Video 1: "
   when its figure holds a video, "Fig. 1: " otherwise, each counting on its
   own. So a caption is only ever its own words. Poster titles and audio
   clips are names rather than figures, and go without.

   scripts/build-media.js numbers captions by the same rule, so the Images
   view's enlarged view shows the same "Video 2" as the note.
   ========================================================================== */

.note-content-body {
  counter-reset: note-figure note-video;
}

.note-content-body :is(figcaption, .media-caption)::before {
  counter-increment: note-figure;
  content: "Fig. " counter(note-figure) ": ";
}

.note-content-body :is(figure, .media-container, .media-embed):has(video) :is(figcaption, .media-caption)::before {
  counter-increment: note-video;
  content: "Video " counter(note-video) ": ";
}

.note-content-body :is(.poster-entry, figure.audio) :is(figcaption, .media-caption)::before {
  counter-increment: none;
  content: none;
}

.media-caption {
  margin-top: var(--space-xs);
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  line-height: 1.5;
}

.media-caption strong {
  color: var(--font-style-body-primary-color);
  font-weight: var(--font-style-title-weight-bold);
}

/* Poster Entries - One poster at a time */
.poster-entry {
  margin: var(--space-xl) 0;
  display: flex;
  flex-direction: column;
}

.poster-entry:first-of-type {
  margin-top: var(--space-lg);
}

.poster-entry img {
  width: 100%;
  height: auto;
  display: block;
  border: none;
  box-sizing: border-box;
  cursor: zoom-in;
}

.poster-title {
  margin-top: var(--space-xs);
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  line-height: 1.5;
}

/* Poster and Media Grids (for backward compatibility) */
.media-grid,
.poster-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  margin: var(--space-lg) 0;
}

.media-grid.grid-3 {
  grid-template-columns: repeat(3, 1fr);
}

.poster-item {
  margin: 0;
  display: flex;
  flex-direction: column;
}

.poster-item img {
  width: 100%;
  height: auto;
  display: block;
  border: none;
  box-sizing: border-box;
  cursor: zoom-in;
}

.poster-item figcaption {
  margin-top: var(--space-xs);
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  line-height: 1.5;
}

.poster-item figcaption strong {
  color: var(--font-style-body-primary-color);
  font-weight: var(--font-style-title-weight-bold);
}

article img.has-border,
.note-content-body img.has-border,
.media-container img.has-border,
.poster-item img.has-border,
img.has-border {
  border: 1px solid var(--color-border);
  box-sizing: border-box;
}

@media (max-width: 600px) {

  .media-grid,
  .poster-grid,
  .media-grid.grid-3 {
    grid-template-columns: 1fr;
  }
}

/* Zoomable cursor for images in notes */
article img,
.note-content-body img,
.media-container img,
.poster-entry img,
.poster-item img {
  cursor: zoom-in;
  border: none;
}

article img.has-border,
.note-content-body img.has-border,
.media-container img.has-border,
.poster-item img.has-border,
img.has-border {
  border: 1px solid var(--color-border);
  box-sizing: border-box;
}

/* Posters get a fainter hairline than the usual has-border grey. This rule
   is as specific as .note-content-body img.has-border, so it has to stay
   below it. */
.poster-entry img.has-border {
  border-color: #ededed;
}

/* ==========================================================================
   Gallery

   A note that is mostly photographs, in series. Each series is a section,
   set apart by space alone, holding a run of rows; each row is one of these
   shapes on three columns:

     gallery-row--3       one photo across
     gallery-row--2-1     a wide photo, then a narrow one
     gallery-row--1-2     the same, mirrored
     gallery-row--1-1-1   three across
     gallery-row--half    two across, a column and a half each
     gallery-row--tall    added to a --3 row whose photo is a portrait

   The gutter is the page's, so the three columns land on the page grid's.
   A wide-and-narrow row takes its height from the narrow photo, and the wide
   one fills that height, cropping a little at its sides; pair a landscape
   with a portrait and almost nothing is lost. Two or three across, keep
   them the same way up. One across, a landscape runs the full width; a portrait
   would run far past the screen, so it stops at the screen's height and
   sits centred.
   ========================================================================== */

.gallery-series {
  margin-top: var(--space-xl);
}

.gallery-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gutter);
  margin-bottom: var(--grid-gutter);
}

.gallery-row figure {
  margin: 0;
  min-width: 0;
}

.gallery-row img {
  display: block;
  width: 100%;
  height: auto;
}

/* Halves split the row down the middle, between the page grid's columns
   rather than on a gutter. */
.gallery-row--half {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Photos straight off different crops are never quite the same shape; the
   tallest in the row sets its height and the others fill it. */
.gallery-row--1-1-1 img,
.gallery-row--half img {
  height: 100%;
  object-fit: cover;
}

.gallery-row--3 figure {
  grid-column: 1 / -1;
}

/* A portrait one across. Sized by its height, which is known before the
   file arrives: the screen's, or a 2:3 photo's at the full column width,
   whichever is less. */
.gallery-row--tall figure {
  container-type: inline-size;
}

.gallery-row--tall img {
  width: auto;
  height: min(85vh, 150cqw);
  margin: 0 auto;
}

.gallery-row--2-1 figure:first-child,
.gallery-row--1-2 figure:last-child {
  grid-column: span 2;
  position: relative;
}

.gallery-row--2-1 figure:first-child img,
.gallery-row--1-2 figure:last-child img {
  position: absolute;
  inset: 0;
  height: 100%;
  object-fit: cover;
}

/* Strip (the note's Layout nav, components.js): every photo one column wide,
   three to a row, in the order the rows hold them. The rows step aside
   (display: contents) so their photos fall straight into the series' own
   grid, and everything a row shape did to a photo is undone: no spans, no
   crops, each photo whole and its own shape. Every photo hangs from the top
   of its row, so a landscape among portraits lines up with their tops. */
.gallery.is-strip .gallery-series {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gutter);
  align-items: start;
}

.gallery.is-strip .gallery-row {
  display: contents;
}

.gallery.is-strip .gallery-row figure {
  grid-column: auto;
  position: static;
  container-type: normal;
}

.gallery.is-strip .gallery-row img {
  position: static;
  width: 100%;
  height: auto;
  margin: 0;
  object-fit: fill;
}

@media (max-width: 600px) {
  .gallery-row {
    gap: var(--space-xs);
    margin-bottom: var(--space-xs);
  }

  .gallery.is-strip .gallery-series {
    gap: var(--space-xs);
  }
}

/* Media embeds */
.media-embed {
  margin: var(--space-lg) 0;
  width: 100%;
}


.image-embed img {
  width: 100%;
  height: auto;
}

.video-embed {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 aspect ratio */
  height: 0;
  overflow: hidden;
}

.video-embed iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Quote: 20px, italic (typography.css) */
blockquote,
.quote,
.note-quote {
  font-family: var(--font-style-quote-family);
  font-size: var(--font-style-quote-size);
  font-style: var(--font-style-quote-style);
  font-weight: var(--font-style-quote-weight);
  line-height: var(--font-style-quote-line-height);
  color: var(--color-text);
  margin: var(--space-md) 0 var(--space-lg) 0;
  padding: 0;
  border: none;
  background: none;
  quotes: none;
}

blockquote p,
.quote p,
.note-quote p {
  margin: 0;
  font-style: inherit;
  font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
    color: inherit;
}

blockquote cite,
.quote cite,
.note-quote cite {
  display: block;
  margin-top: var(--space-sm);
  font-family: var(--font-style-body-secondary-family);
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--color-text-light);
  font-style: normal;
}

/* Code blocks and UI prototype embeds */
.code-block, .prototype-embed {
  margin: var(--space-lg) 0;
  background-color: var(--color-background);
  border-radius: 4px;
  overflow: hidden;
}

.code-block pre {
  padding: var(--space-md);
  overflow-x: auto;
}

.prototype-embed iframe {
  width: 100%;
  border: 0;
  min-height: 400px;
}

/* Update note / callout card */
.update-card {
  margin: var(--space-xl) 0;
  padding: var(--space-md) var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background-color: rgba(0, 0, 0, 0.02);
}

.update-card .update-tag {
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-title-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--font-style-body-secondary-color);
  margin-bottom: var(--space-xs);
}

.update-card .update-title {
  margin-top: 0;
  margin-bottom: var(--space-sm);
  font-size: var(--font-style-h3-size);
  line-height: 1.4;
}

.update-card p {
  margin-bottom: var(--space-sm);
}

.update-card p:last-of-type {
  margin-bottom: 0;
}

.update-card .update-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-xs);
  font-weight: var(--font-style-title-weight-bold);
  color: var(--color-link);
  text-decoration: none;
}

.update-card .update-link:hover {
  text-decoration: underline;
}
/* Responsive design */

@media (max-width: 768px) {
  .note-entry {
    flex-direction: column;
  }

  .note-date {
    margin-bottom: var(--space-xs);
  }
}

/* Custom embed styles */
.soundcloud-embed {
  margin: var(--space-lg) 0;
}

/* ==========================================================================
   Buttons are shadcn's, in ui.css. A note only adds the space around one.
   ========================================================================== */

/* A button standing on its own in the flow of a note wants air around it. */
.note-content-body p > a.button { margin: var(--space-xs) 0; }

/* ==========================================================================
   Play again, under every GIF and every video.

   See js/media-replay.js. A video is seeked back to zero; a GIF cannot be
   rewound at all, so the button swaps in a fresh object URL over the same
   bytes. It sits under the figure and its caption, never over the media.
   ========================================================================== */

/* A video, its controls laid over it, and the progress line under it — see
   js/media-replay.js. The controls sit centred on a dimmed picture whenever
   the video is stopped; while it plays they get out of the way and come back
   on hover, keyboard focus, or (on touch) a tap. */
.media-player {
  position: relative;
  cursor: pointer;
}

.media-player video {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  opacity: 0.4;
  transition: opacity 0.2s ease;
}

.media-player__controls {
  position: absolute;
  inset: 0 0 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  opacity: 1;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.media-player__btn {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--color-text-light);
  cursor: pointer;
  pointer-events: auto;
  transition: transform 0.15s ease, color 0.15s ease;
}

.media-player__btn .material-symbols-outlined {
  font-family: 'Material Symbols Outlined';
  font-weight: normal;
  font-style: normal;
  font-size: 40px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
  font-variation-settings: 'FILL' 0, 'wght' 200, 'GRAD' 0, 'opsz' 24;
}

/* Play and pause carry their own circle. */
.media-player__toggle { color: var(--color-text); }

.media-player__btn:hover { transform: scale(1.06); }
.media-player__replay:hover { color: var(--color-text); }
.media-player__toggle:hover { color: #000; }

.media-player__btn:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* Nothing to play again before it has played at all. */
.media-player:not(.has-played) .media-player__replay { display: none; }

/* Playing: full picture, no controls — until someone reaches for them. */
.media-player.is-playing video { opacity: 1; }
.media-player.is-playing .media-player__controls { opacity: 0; }
.media-player.is-playing .media-player__btn { pointer-events: none; }

.media-player.is-playing.is-peeking video,
.media-player.is-playing:has(:focus-visible) video { opacity: 0.4; }
.media-player.is-playing.is-peeking .media-player__controls,
.media-player.is-playing:has(:focus-visible) .media-player__controls { opacity: 1; }
.media-player.is-playing.is-peeking .media-player__btn,
.media-player.is-playing:has(:focus-visible) .media-player__btn { pointer-events: auto; }

@media (hover: hover) {
  .media-player.is-playing:hover video { opacity: 0.4; }
  .media-player.is-playing:hover .media-player__controls { opacity: 1; }
  .media-player.is-playing:hover .media-player__btn { pointer-events: auto; }
}

/* Where the animation has got to, flush under the picture. Not interactive. */
.media-progress {
  position: relative;
  height: 2px;
  background-color: #dfdfdf;
  overflow: hidden;
}

.media-progress span {
  display: block;
  width: 0;
  height: 100%;
  background-color: #111;
}

/* A figure that is wide, dense, and meant to be opened rather than read in
   place — the sprite sheet. Spaced like any other figure in the column. */
.note-figure {
  margin: var(--space-lg) 0;
}

.note-figure img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--color-border);
  cursor: zoom-in;
}

.note-figure figcaption {
  margin-top: var(--space-xs);
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  color: var(--font-style-body-secondary-color);
  line-height: 1.5;
}

/* The caption and the replay control share a line — see js/media-replay.js,
   which puts them in this row. The caption takes what it needs and the button
   sits at the far end, the two centred against each other so a caption that
   runs to two lines keeps the button level with its middle. */
.media-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: var(--space-xs);
}

/* The caption's own top margin is the row's job now. */
.media-foot > .media-caption,
.media-foot > figcaption {
  flex: 1 1 auto;
  min-width: 0;
  margin-top: 0;
}

.gif-replay {
  flex: none;
}

@media (max-width: 480px) {
  /* Two things side by side stop fitting; the button takes its own line. */
  .media-foot {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-xs);
  }
}

.gif-replay::before {
  content: '\21BB';
  font-size: 13px;
  line-height: 1;
}

/* ==========================================================================
   Carousel.

   For a figure that is a set of photographs rather than one. The track is a
   scroll container with snap points, so the swipe and the momentum are the
   browser's own; see js/carousel.js, which builds the bar of controls.
   ========================================================================== */

figure.carousel {
  margin: var(--space-lg) 0;
  width: 100%;
}

.carousel__track {
  display: flex;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* The dots are the position indicator; a scrollbar under the photographs
     would only be a second one, drawn worse. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.carousel__track::-webkit-scrollbar { display: none; }

/* The track is what a reader tabs to, and where the arrow keys are answered,
   so it has to show when it has the focus. */
.carousel__track:focus { outline: none; }

.carousel__track:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 3px;
}

.carousel__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  display: flex;
  flex-direction: column;
}

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

/* A caption belonging to one image rather than to the set. It rides inside
   the track, so the track takes the height of the tallest slide and the
   figure does not change height as you move through it. */
.carousel__cap {
  margin: var(--space-xs) 0 0;
  padding: 0 2px;
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  color: var(--font-style-body-secondary-color);
  line-height: 1.5;
}

.carousel__cap strong {
  color: var(--font-style-body-primary-color);
  font-weight: var(--font-style-title-weight-bold);
}

/* One arrow at each end, the dots centred between them, so the row reads as
   centred on the images above it. */
.carousel__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--space-sm);
}

/* Bare arrows in the nav's ink rather than buttons: the glyph is the whole
   control, with a 24px square of room around it to hit. An arrow has no
   word under it to underline, so hovering brings it up to the primary ink
   instead — the one hover on the site that moves a colour. */
.carousel__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: none;
  font-family: var(--font-family);
  font-size: var(--font-style-body-primary-size);
  line-height: 1;
  color: var(--font-style-body-secondary-color);
  cursor: pointer;
  transition: color 160ms ease;
}

.carousel__step:hover {
  color: var(--color-text);
}

.carousel__step[disabled] {
  color: var(--color-text-tertiary);
  cursor: default;
}

.carousel__step:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

.carousel__dots {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

/* A generous hit area around a small mark: the dot is 7px, the target 18. */
.carousel__dot {
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.carousel__dot::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: var(--color-border);
  transition: background-color 160ms ease;
}

.carousel__dot:hover::before { background-color: var(--color-text-tertiary); }
.carousel__dot[aria-current='true']::before { background-color: var(--color-text); }

.carousel__dot:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 0;
  border-radius: 50%;
}

.carousel figcaption {
  margin-top: var(--space-xs);
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  font-weight: var(--font-style-body-secondary-weight);
  color: var(--font-style-body-secondary-color);
  line-height: 1.5;
}

/* ==========================================================================
   Audio player.

   SoundCloud's shape: a play button, a waveform that is also the scrubber,
   and the clock on the end. Built by js/audio-player.js from a figure with a
   data-src and a caption.
   ========================================================================== */

figure.audio {
  margin: var(--space-md) 0;
  padding: 14px 16px 12px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background-color: var(--bv-surface, #fbfbfa);
}

.audio + .audio { margin-top: var(--space-sm); }

.audio__row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.audio__play {
  flex: none;
  width: 34px;
  height: 34px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-text);
  border-radius: 50%;
  background-color: var(--color-text);
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease;
}

.audio__play:hover { background-color: #000; border-color: #000; }

.audio__play:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* A triangle, and a pair of bars once it is running. Drawn in CSS so there is
   no icon file to load for two shapes. */
.audio__play::before {
  content: '';
  width: 0;
  height: 0;
  margin-left: 2px;
  border-left: 10px solid #fff;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
}

.audio[data-playing='true'] .audio__play::before {
  margin-left: 0;
  width: 9px;
  height: 11px;
  border: none;
  background:
    linear-gradient(#fff, #fff) left / 3px 100% no-repeat,
    linear-gradient(#fff, #fff) right / 3px 100% no-repeat;
}

.audio__wave {
  flex: 1 1 auto;
  min-width: 0;
  height: 34px;
  cursor: pointer;
}

.audio__bars { fill: var(--color-border); }
.audio__bars--played { fill: var(--color-text); }

.audio__time {
  flex: none;
  font-family: var(--bv-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-light);
}

.audio figcaption {
  margin-top: 10px;
  font-family: var(--font-style-body-secondary-family);
  font-size: var(--font-style-body-secondary-size);
  color: var(--font-style-body-secondary-color);
  line-height: 1.5;
}

.audio figcaption strong {
  color: var(--font-style-body-primary-color);
  font-weight: var(--font-style-title-weight-bold);
}

@media (max-width: 560px) {
  .audio__time { font-size: 10px; }
  .audio__row { gap: 10px; }
}
