.progress {
  height: 10px;
}

.big-and-narrow {
  width: 250px;
  font-size: 2rem;
}

.stripe-btn {
  color: #fff !important;
  background-color: rgb(88, 80, 247);
}

.stripe-btn:hover {
  background-color: rgb(78, 70, 237);
}

.stripe-btn:active {
  background-color: rgb(68, 60, 227) !important;
  border-color: rgb(68, 60, 227) !important;;
}

.stripe-btn svg {
  vertical-align: sub;
}
.card-brand {
  width: 50px;
  height: 32px;
  color: white;
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.card-brand.visa { background: rgb(12, 77, 144); }
.card-brand.mastercard { background: rgb(255, 0, 27); }
.card-brand.amex { background: rgb(24, 135, 195); }
.card-brand.discover { background: rgb(237, 110, 40); }

.card-number {
  font-family: 'Courier New', monospace;
  letter-spacing: 1px;
}

.card-option:has(input:checked) {
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.1);
}

@media (prefers-color-scheme: dark) {
  .card-option:has(input:checked) {
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1);
  }
}
/* The faces of a chronicle's people, overlapping a little, see
   ChroniclesHelper#chronicle_card */
.chronicle-people {
  display: flex;
}

/* A historical person's events, as knobs on a line, see
   UsersHelper#historical_event */
.chronicle-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
}

.chronicle-timeline > li {
  position: relative;
  padding: 0 0 1.5rem 1.75rem;
}

/* The line, from knob to knob */
.chronicle-timeline > li::before {
  content: "";
  position: absolute;
  left: calc(0.4375rem - 1px);
  top: 0.5lh;
  bottom: -0.5lh;
  width: 2px;
  background: var(--bs-border-color);
}

.chronicle-timeline > li:last-child::before {
  display: none;
}

/* The knob, centered on the first line of text */
.chronicle-timeline > li::after {
  content: "";
  position: absolute;
  left: 0;
  top: calc((1lh - 0.875rem) / 2);
  width: 0.875rem;
  height: 0.875rem;
  border-radius: 50%;
  border: 2px solid var(--bs-secondary-color);
  background: var(--bs-body-bg);
}

/* The whole card is its title's link; hovering anywhere on it says so. */
.chronicle-card:has(.stretched-link:hover) h2 a {
  text-decoration: underline;
}

.chronicle-people img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border: 2px solid var(--bs-tertiary-bg);
}

.chronicle-people img + img {
  margin-left: -8px;
}
.copy-button {
  position: absolute;
  top: 0.8rem;
  right: 0.8rem;
  font-family: revert;
}
#discussion-footer {
  max-height: 80lvh;
  z-index: 10;
  transition: transform 500ms ease;
}

#discussion-footer.discussion-footer--hidden {
  transform: translateY(100%);
  pointer-events: none;
}

.discussion-footer-float-btn {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 20;
}

.headroom--unpinned {
  transform: translateY(100%);  /* hide */
}

.headroom--pinned {
  transform: translateY(0);     /* show */
}

/* Embedded discussions */
.footer-beta-pill {
  vertical-align: 1px !important;
}
/* The visual discussion tree, ported from refute.us. See forest_controller.js
   and ForestHelper. */

:root {
  --forest-width: clamp(320px, 42vw, 960px);
  --forest-bg: var(--bs-body-bg);
  --forest-crit: rgb(var(--theme-color));
  --forest-idea: rgb(62, 140, 255);
  --forest-comment: #8a8f94;
  --forest-link: rgba(33, 37, 41, 0.45);
  --forest-label: #212529;
  --forest-label-dim: rgba(33, 37, 41, 0.75);
  --forest-tip-bg: #212529;
  --forest-tip-fg: #f7f1e4;
  --forest-tip-muted: #c7c7c7;
  --forest-lift: rgb(var(--theme-color));
  --forest-halo: rgb(var(--theme-color));
  --forest-halo-idea: #6c757d;
  --forest-ring: #6c757d;
  --forest-focus: rgb(13, 84, 191);
  /* Over the portraits behind a chronicle's visual: what fades them, so the
     visual stands out, and the caption and buttons on them */
  --forest-veil: linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.55));
  --forest-caption: rgba(33, 37, 41, 0.9);
  --forest-caption-glow: rgba(255, 255, 255, 0.9);
  --forest-over-btn: rgba(255, 255, 255, 0.8);
  --forest-over-btn-hover: rgba(233, 236, 239, 0.92);
  --forest-over-btn-border: rgba(0, 0, 0, 0.15);
}

[data-bs-theme="dark"] {
  --forest-veil: linear-gradient(rgba(18, 17, 14, 0.55), rgba(18, 17, 14, 0.75));
  --forest-caption: rgba(245, 239, 226, 0.9);
  --forest-caption-glow: rgba(0, 0, 0, 0.8);
  --forest-over-btn: rgba(18, 17, 14, 0.8);
  --forest-over-btn-hover: rgba(48, 45, 40, 0.9);
  --forest-over-btn-border: rgba(255, 255, 255, 0.25);
  --forest-link: rgba(222, 226, 230, 0.55);
  --forest-label: #eceff1;
  --forest-label-dim: rgba(236, 239, 241, 0.8);
  --forest-tip-bg: #dee2e6;
  --forest-tip-fg: #1a1a1a;
  --forest-tip-muted: #424242;
  --forest-lift: #fff;
  --forest-halo: #fff;
  --forest-halo-idea: #adb5bd;
  --forest-ring: #fff;
  --forest-focus: rgb(144, 192, 251);
}

/* ---------- where the pane goes ---------- */

.forest-pane {
  display: none;
  flex-direction: column;
  background: var(--forest-bg);
}

/* The menu item that finds an idea in the visual only makes sense on a page
   with one. It comes first in its group in the menu, so when it’s the only
   item there, the divider after it goes too. */
body:not(.has-forest) li:has(> .forest-locate),
body:not(.has-forest) li:has(> .forest-locate) + li:has(> .dropdown-divider) {
  display: none;
}

/* The visual and its report are rendered after the text column (#content),
   see ForestHelper#forest_pane. This wrapper takes no part in the layout,
   so they’re laid out as parts of the page. */
.forest-root {
  display: contents;
}

/* Side by side (lg and up, see SIDE_BY_SIDE in forest_controller.js): the
   visual is a column of its own on the right, the full height of the window,
   and the text makes room for it. The navbar spans both and covers the top
   of the visual, uncovering it as it scrolls away. The report sits right
   under the navbar, and stays at the top once that’s gone.

   Both are sticky rather than fixed, and nothing is moved by script, so
   they move with the page exactly, even as it bounces past its top. The
   body is a flex column, so `order` puts them before the text column, where
   sticky positioning works, and negative margins keep them from taking up
   room in it. */

.forest-report-top {
  display: none;
}

@media (min-width: 992px) {
  body.has-forest .forest-pane {
    display: flex;
    position: sticky;
    top: 0;
    order: -2;
    align-self: flex-end;
    width: var(--forest-width);
    height: 100vh;
    margin-bottom: -100vh;
    z-index: 9;
    border-left: 1px solid var(--bs-border-color);
  }

  body.has-forest #navbar {
    order: -1;
    position: relative;
    z-index: 10;
    background-color: var(--bs-body-bg);
  }

  /* It covers the top of the divider (see .forest-divider), so it carries
     on the divider’s line itself. It takes the pointer, so its text can be
     selected; the divider can still be grabbed from its left half. */
  body.has-forest .forest-report-top {
    display: block;
    order: -1;
    position: sticky;
    top: 0;
    z-index: 10;
    align-self: flex-end;
    width: var(--forest-width);
    height: 2.25rem;
    margin-bottom: -2.25rem;
    padding: 0 1rem;
    line-height: 2.25rem;
    text-align: center;
    border-left: 1px solid var(--bs-border-color);
    /* The line along the bottom is a shadow rather than a border, so it goes
       under the divider’s line instead of over it in the corner. */
    box-shadow: inset 0 -1px 0 var(--bs-border-color);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
  }

  /* Blue with the divider’s line, which is 2px wide: the pane’s border and
     the pixel to its right, since the divider is positioned inside the
     border */
  .forest-root:has(.forest-divider:hover, .forest-divider:focus-visible) .forest-report-top,
  body.forest-resizing .forest-report-top {
    border-left-color: var(--bs-primary);
    box-shadow: inset 1px 0 0 var(--bs-primary), inset 0 -1px 0 var(--bs-border-color);
  }

  body.has-forest .forest-report-bottom {
    display: none;
  }

  /* Set outright, since #content is a .container-fluid, whose width of 100%
     would carry it on under the visual rather than make it narrower, and
     then it couldn’t scroll sideways when the ideas don’t fit. */
  body.has-forest #content,
  body.has-forest #footer {
    width: calc(100% - var(--forest-width));
    margin-right: var(--forest-width);
  }

  body.has-forest #discussion-footer {
    width: calc(100% - var(--forest-width)) !important;
  }

  body.has-forest .discussion-footer-float-btn {
    right: calc(var(--forest-width) + 1rem);
  }
}

/* Narrower, the visual takes over the screen when shown. */
@media (max-width: 991.98px) {
  body.forest-visual .forest-pane {
    display: flex;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 30;
  }

  body.forest-visual #discussion-footer,
  body.forest-visual .discussion-footer-float-btn {
    display: none !important;
  }
}

/* The divider between the text and the visual. It straddles the pane’s
   border, so it’s easy to grab without covering either side much. */
.forest-divider {
  display: none;
}

@media (min-width: 992px) {
  .forest-divider {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: -5px;
    width: 10px;
    z-index: 4;
    cursor: col-resize;
    touch-action: none;
  }

  .forest-divider::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 4px;
    width: 2px;
    background: transparent;
    transition: background-color 0.15s ease;
  }

  /* Chevrons either side of the line, halfway down */
  .forest-divider-grip {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    gap: 0.6rem;
    font-size: 0.7rem;
    color: var(--bs-secondary-color);
    opacity: 0.6;
    pointer-events: none;
    transition: color 0.15s ease, opacity 0.15s ease;
  }

  .forest-divider:hover .forest-divider-grip,
  .forest-divider:focus-visible .forest-divider-grip,
  body.forest-resizing .forest-divider-grip {
    color: var(--bs-primary);
    opacity: 1;
  }

  /* A collapsed side has its own way back: the tab, or the Text button. */
  body.forest-collapsed-visual .forest-divider-grip,
  body.forest-collapsed-text .forest-divider-grip {
    display: none;
  }

  .forest-divider:hover::after,
  .forest-divider:focus-visible::after,
  body.forest-resizing .forest-divider::after {
    background: var(--bs-primary);
  }

  .forest-divider:focus-visible {
    outline: none;
  }

  /* While dragging, the cursor stays the same everywhere and nothing gets
     selected. */
  body.forest-resizing,
  body.forest-resizing * {
    cursor: col-resize !important;
    user-select: none !important;
  }
}

/* A side dragged well past its limit collapses, see forest_controller.js.
   The !important beats the width set on the body while dragging. */
.forest-tab {
  display: none;
}

@media (min-width: 992px) {
  body.forest-collapsed-visual {
    --forest-width: 0px !important;
  }

  body.forest-collapsed-visual .forest-pane {
    border-left: 0;
  }

  /* Keeps the divider on screen at the right edge. */
  body.forest-collapsed-visual .forest-divider {
    left: -10px;
  }

  body.forest-collapsed-visual .forest-report,
  body.forest-collapsed-visual .forest-report-top,
  body.forest-collapsed-visual .forest-canvas {
    display: none;
  }

  /* Sticks out of the right edge, so there’s something to click or drag. */
  body.forest-collapsed-visual .forest-tab {
    display: block;
    position: absolute;
    top: 50%;
    right: 0;
    transform: translateY(-50%);
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    padding: 0.5rem 0.4rem;
  }

  body.forest-collapsed-text {
    --forest-width: 100vw !important;
  }

  /* The navbar stays, the text goes, and the page no longer scrolls. */
  body.forest-collapsed-text {
    overflow: hidden;
  }

  body.forest-collapsed-text #content,
  body.forest-collapsed-text #footer {
    visibility: hidden;
  }

  body.forest-collapsed-text #discussion-footer,
  body.forest-collapsed-text .discussion-footer-float-btn {
    display: none !important;
  }

  body.forest-collapsed-text .forest-pane {
    visibility: visible;
    border-left: 0;
  }

  /* Keeps the divider on screen at the left edge. */
  body.forest-collapsed-text .forest-divider {
    left: 0;
  }

  body.forest-collapsed-text .forest-divider::after {
    left: 0;
  }

  /* Below the navbar and the report, see #placeTextButton */
  body.forest-collapsed-text .forest-text-btn {
    display: inline-block !important;
    top: calc(var(--forest-covered, 0px) + 0.75rem);
  }

  /* At the edge of the window, there’s no border to carry on, only the
     divider’s line while it’s hovered or dragged. */
  body.forest-collapsed-text .forest-report-top {
    border-left: 0;
  }

  .forest-root:has(.forest-divider:hover, .forest-divider:focus-visible) .forest-report-top:is(body.forest-collapsed-text *),
  body.forest-collapsed-text.forest-resizing .forest-report-top {
    box-shadow: inset 2px 0 0 var(--bs-primary), inset 0 -1px 0 var(--bs-border-color);
  }
}

/* Beside the visual, ideas are only as wide as what’s in them, up to the
   usual 70ch (see .idea-width in application.css), instead of always 70ch.
   The text column is narrower here, and it otherwise scrolls sideways a
   long way past short ideas. Their reply forms keep the full width. */
@media (min-width: 992px) {
  /* max-content rather than fit-content, which would also shrink to the
     column and wrap long text early */
  body.has-forest #content .idea.idea-width,
  body.has-forest #content .idea .idea-width {
    width: max-content;
    max-width: 70ch;
  }

  body.has-forest #content .idea .form-container {
    width: 70ch;
  }
}

/* ---------- the timeline ---------- */
/* Along the bottom of the window, across both panes, see
   ForestHelper#forest_timeline. Sticky like the visual, at the end of the
   page. The text column’s form and the visual’s buttons sit above it. */

body.has-forest-timeline {
  --forest-timeline-gutter: 0px;
  --forest-timeline-height: calc(4.25rem + var(--forest-timeline-gutter));
}

/* On a touch screen, the slider keeps clear of the bottom edge, where
   swiping sideways switches apps on an iPad or iPhone. */
@media (pointer: coarse) {
  body.has-forest-timeline {
    --forest-timeline-gutter: 1.5rem;
  }
}

/* Two rows, like refute.us: what happened and when, then the slider across
   the full width, so it doesn’t move as the text changes. */
.forest-timeline {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  align-items: baseline;
  gap: 0.25rem 1rem;
  order: 99;
  position: sticky;
  bottom: 0;
  z-index: 11;
  height: var(--forest-timeline-height);
  padding: 0 1rem var(--forest-timeline-gutter);
}

.forest-timeline[hidden] {
  display: none;
}

.forest-timeline-label {
  flex: 1 1 0;
  min-width: 0;
}

.forest-timeline-count {
  flex: none;
}

.forest-timeline-track {
  position: relative;
  order: 3;
  flex-basis: 100%;
  display: flex;
  align-items: center;
  height: 1.5rem;
}

.forest-timeline-slider {
  position: relative;
  z-index: 1;
  cursor: pointer;
}

/* Veritula fills inputs in dark mode, which would box in the slider. */
input.forest-timeline-slider.form-range {
  background-color: transparent !important;
}

/* Arrows on the thumb, and everywhere for as long as it’s dragged, like
   refute.us; a pointer elsewhere on the track, where a click jumps there. */
.forest-timeline-slider::-webkit-slider-thumb { cursor: ew-resize; }
.forest-timeline-slider::-moz-range-thumb { cursor: ew-resize; }

body.forest-scrubbing,
body.forest-scrubbing * {
  cursor: ew-resize !important;
}

/* The thumb only does the dragging; the knob drawn over it is what shows,
   so it can be solid or hollow like the ticks. Same size as the knob, which
   the ticks are lined up with. */
.forest-timeline-slider::-webkit-slider-thumb {
  width: 1.25rem;
  height: 1.25rem;
  margin-top: -0.375rem;
  background: transparent;
  box-shadow: none !important;
}

.forest-timeline-slider::-moz-range-thumb {
  width: 1.25rem;
  height: 1.25rem;
  border: 0;
  background: transparent;
  box-shadow: none !important;
}

/* On top of the slider’s track, where the thumb stops for each point. Only
   the ticks themselves take the pointer. */
.forest-timeline-ticks {
  z-index: 2;
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 0;
  pointer-events: none;
}

/* Like refute.us: a little larger than the track is high, solid when some
   top-level idea was rationally adoptable then, hollow when none was */
.forest-timeline-tick,
.forest-timeline-knob {
  position: absolute;
  top: 0;
  left: calc(0.625rem + (100% - 1.25rem) * var(--at, 0));
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

.forest-timeline-tick {
  width: 13px;
  height: 13px;
  padding: 0;
  border: 2px solid var(--forest-idea);
  background: var(--forest-bg);
  pointer-events: auto;
  cursor: pointer;
  transition: border-color 0.15s ease;
  /* The browser hands the whole gesture over, rather than reading part of
     it as a scroll */
  touch-action: none;
}

.forest-timeline-tick.is-live {
  background: var(--forest-idea);
}

.forest-timeline-tick:hover {
  border-color: var(--forest-focus);
}

.forest-timeline-tick[hidden] {
  display: none;
}

/* The point being looked at: bigger than a tick, and ringed so it stands
   apart from them. It lets the pointer through to the thumb underneath. */
.forest-timeline-knob {
  z-index: 3;
  top: 50%;
  width: 1.25rem;
  height: 1.25rem;
  border: 2.5px solid var(--forest-idea);
  background: var(--forest-bg);
  box-shadow: 0 0 0 2px #fff, 0 1px 4px 2px rgba(0, 0, 0, 0.3);
  pointer-events: none;
}

.forest-timeline-knob.is-live {
  background: var(--forest-idea);
}

@media (min-width: 992px) {
  body.has-forest-timeline .forest-pane {
    padding-bottom: var(--forest-timeline-height);
  }

  body.has-forest-timeline #discussion-footer {
    bottom: var(--forest-timeline-height) !important;
  }

  body.has-forest-timeline .discussion-footer-float-btn {
    bottom: calc(var(--forest-timeline-height) + 1rem);
  }

  /* Only the visual goes back in time so far, so the timeline goes with it. */
  body.forest-collapsed-visual .forest-timeline {
    display: none;
  }
}

/* On a phone, the timeline is part of the visual, which takes over the
   screen. */
@media (max-width: 991.98px) {
  /* Except for a chronicle, whose story the text column tells, see
     ForestHelper#forest_event_slot */
  body:not(.forest-visual):not(:has(#forest-event)) .forest-timeline {
    display: none;
  }

  body.forest-visual.has-forest-timeline .forest-pane {
    padding-bottom: var(--forest-timeline-height);
  }

  body.forest-visual .forest-timeline {
    position: fixed;
    left: 0;
    right: 0;
    z-index: 31;
  }

}

/* ---------- linking the two trees ---------- */

/* The highlight behind an idea that’s hovered here or in the visual. The
   controller sizes it to what’s in the idea, from the avatar to the end of
   the header, text or badges, see #contentRect. It’s drawn by the idea’s
   own content, which the lines next to the idea are positioned in already,
   and behind everything, so those lines stay on top. */
body.has-forest .idea-own-content::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: var(--forest-box-left, 0);
  top: var(--forest-box-top, 0);
  width: var(--forest-box-width, 0);
  height: var(--forest-box-height, 0);
  border-radius: var(--bs-border-radius-lg);
  background-color: rgba(var(--bs-info-rgb), 0.1);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease, background-color 0.6s ease;
}

body.has-forest .idea-own-content.forest-linked::after {
  opacity: 1;
  transition: none;
}

body.has-forest .idea-own-content.forest-flash::after {
  opacity: 1;
  background-color: rgba(var(--bs-info-rgb), 0.25);
  transition: none;
}

/* An idea in a chronicle's story, highlighted with its node in the visual
   beside it, either way round, like an idea in the text tree, see
   #onStoryMove and #highlight in forest_controller.js */
@media (min-width: 992px) {
  .forest-story-idea {
    border-radius: var(--bs-border-radius-lg);
    transition: background-color 0.6s ease;
  }

  div.forest-story-idea {
    margin-inline: -0.5rem;
    padding: 0.25rem 0.5rem;
  }

  /* So the highlight ends with the text */
  div.forest-story-idea .ugc > :last-child {
    margin-bottom: 0;
  }

  .forest-story-idea:hover,
  .forest-story-idea.forest-linked {
    background-color: rgba(var(--bs-info-rgb), 0.1);
    transition: none;
  }
}

/* ---------- the pane ---------- */

.forest-report {
  flex: none;
  padding: 0.5rem 1rem;
  /* Digits all as wide as each other, so a number changing doesn’t shift
     the rest of the (centered) text */
  font-variant-numeric: tabular-nums;
  /* Cut off rather than wrapped when the pane is narrow */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.forest-canvas {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

.forest-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 2rem;
  color: var(--forest-label-dim);
  pointer-events: none;
}

.forest-empty[hidden] {
  display: none;
}

.forest-btn {
  position: absolute;
  z-index: 3;
}

.forest-tools {
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  z-index: 3;
}

.forest-text-btn {
  top: 0.75rem;
  left: 0.75rem;
}

.forest-legend-btn {
  bottom: 0.75rem;
  left: 0.75rem;
}

.forest-tip {
  position: absolute;
  z-index: 2;
  max-width: min(18rem, calc(100% - 1rem));
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--forest-tip-fg);
  background: var(--forest-tip-bg);
  border-radius: var(--bs-border-radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}

.forest-tip[hidden] {
  display: none;
}

.forest-tip-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 8;
  overflow: hidden;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  font-family: eb-garamond, Georgia, serif;
  font-size: 1.2rem;
}

.forest-tip-text:empty {
  display: none;
}

.forest-tip-text:empty + .forest-tip-status {
  margin-top: 0;
}

.forest-tip-status {
  margin-top: 0.25rem;
  color: var(--forest-tip-muted);
  font-size: 0.8rem;
  font-weight: 600;
}

.forest-legend {
  position: absolute;
  left: 0.75rem;
  bottom: 3.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.8rem;
  color: var(--forest-label-dim);
  pointer-events: none;
}

.forest-legend[hidden] {
  display: none;
}

.forest-legend li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.forest-legend svg {
  flex: none;
}

.forest-legend .key-on {
  fill: var(--forest-label);
  transform: scale(1.15);
  transform-box: fill-box;
  transform-origin: center;
}

.forest-legend .key-off {
  fill: var(--forest-bg);
  stroke: var(--forest-label);
  stroke-width: 2px;
}

.forest-legend-hint {
  max-width: 16rem;
}

/* Nothing to hover with on a touch screen */
@media (hover: none) {
  .forest-legend-hover {
    display: none;
  }
}

/* The first hint, after the keys */
li:not(.forest-legend-hint) + .forest-legend-hint {
  margin-top: 0.25rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--forest-link);
}

@media (max-width: 991.98px) {
  .forest-legend {
    left: 0.5rem;
    bottom: 2.6rem;
    gap: 0.15rem;
    font-size: 0.72rem;
  }

  .forest-legend svg {
    width: 18px;
    height: 18px;
  }

  .forest-tools { right: 0.5rem; bottom: 0.5rem; }
  .forest-text-btn { top: 0.5rem; left: 0.5rem; }
  .forest-legend-btn { bottom: 0.5rem; left: 0.5rem; }
}

/* ---------- the chart ---------- */

.forest {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.forest.is-dragging {
  cursor: grabbing;
}

.forest .bg {
  fill: transparent;
}

/* Plain and gray: the edges to criticisms that aren’t rationally adoptable,
   and to comments, which don’t bear on their parent either. Dashed lines
   are only for ties between versions, see .version-link. */
.forest .link {
  fill: none;
  stroke: var(--forest-link);
  stroke-width: 1.5px;
}

/* An edge to a rationally adoptable criticism takes on its color. The light
   moving along it toward the parent rides on top. */
.forest .link.is-adoptable {
  stroke: color-mix(in srgb, var(--forest-crit) 85%, var(--forest-lift));
}

.forest .link-flow {
  fill: color-mix(in srgb, var(--forest-crit) 45%, var(--forest-lift));
  opacity: 0.9;
  pointer-events: none;
}

.forest .link-flow-near,
.forest .link-flow-far {
  fill: color-mix(in srgb, var(--forest-crit) 60%, var(--forest-lift));
  pointer-events: none;
}

.forest .link-flow-near { opacity: 0.2; }
.forest .link-flow-far { opacity: 0.09; }

@media (prefers-reduced-motion: no-preference) {
  .forest .flow-layer {
    animation: forest-flow-pulse 2.6s ease-in-out infinite;
  }
}

@keyframes forest-flow-pulse {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}

.forest .node-layer {
  filter: drop-shadow(0 1.5px 2px rgba(0, 0, 0, 0.35));
}

.forest .node {
  cursor: pointer;
}

.forest .node:focus {
  outline: none;
}

/* Solid discs are rationally adoptable, hollow ones aren’t. Ideas are blue,
   criticisms red. */
.forest .node circle.core {
  fill: var(--forest-crit);
  stroke: none;
}

.forest .node.is-idea circle.core {
  fill: var(--forest-idea);
}

.forest .node:not(.is-adoptable) circle.core {
  fill: var(--forest-bg);
  stroke: var(--forest-crit);
  stroke-width: 2px;
}

.forest .node.is-idea:not(.is-adoptable) circle.core {
  stroke: var(--forest-idea);
}

/* Comments are gray, solid or hollow like the rest, but without the glow. */
.forest .node.is-comment circle.core {
  fill: var(--forest-comment);
}

.forest .node.is-comment:not(.is-adoptable) circle.core {
  fill: var(--forest-bg);
  stroke: var(--forest-comment);
  stroke-width: 1.5px;
}

.forest .node.is-comment .halo {
  display: none;
}

/* Hovered or focused here, hovered in the text tree, or found from it */
.forest .node.is-highlighted circle.core,
.forest .node.is-located circle.core {
  stroke: var(--forest-ring) !important;
  stroke-width: 2.5px;
}

/* An idea whose comments are hidden in the text tree */
.forest .node .collapsed-ring {
  display: none;
  fill: none;
  stroke: var(--forest-label-dim);
  stroke-width: 1.2px;
  stroke-dasharray: 3 3;
}

.forest .node.is-collapsed .collapsed-ring {
  display: block;
}

/* Fingers are blunter than cursors: an invisible ring makes the tappable
   surface wider than the circle. */
.forest .node .touch-hit {
  fill: transparent;
  pointer-events: none;
}

@media (pointer: coarse) {
  .forest .node .touch-hit {
    pointer-events: all;
  }
}

/* A slow pulse marks rationally adoptable ideas as live. Their fills pulse,
   not the circles themselves, see #buildChart in forest_controller.js. */
.forest .node .halo {
  fill: url(#forest-halo-fade);
  opacity: 0;
  pointer-events: none;
}

.forest .node.is-idea .halo {
  fill: url(#forest-halo-fade-idea);
}

#forest-halo-fade stop { stop-color: var(--forest-halo); }
#forest-halo-fade-idea stop,
#forest-halo-flash stop { stop-color: var(--forest-halo-idea); }

@media (prefers-reduced-motion: no-preference) {
  .forest .node.is-adoptable .halo {
    opacity: 1;
  }

  #forest-halo-fade stop,
  #forest-halo-fade-idea stop {
    animation: forest-adopt-glow 2.6s ease-in-out infinite;
  }

  .forest .node.is-located .halo {
    fill: url(#forest-halo-flash);
    animation: forest-located-glow 0.8s ease-in-out 2;
  }
}

@keyframes forest-adopt-glow {
  0%, 100% { stop-opacity: 0; }
  50% { stop-opacity: var(--forest-peak); }
}

@keyframes forest-located-glow {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}

.forest .node text {
  fill: var(--forest-label);
  font-family: eb-garamond, Georgia, serif;
  font-size: 14.4px;
  paint-order: stroke;
  stroke: var(--forest-bg);
  stroke-width: 3px;
  stroke-linejoin: round;
  pointer-events: none;
}

.forest .node.is-root text {
  font-size: 15.6px;
  font-weight: 600;
}

.forest .node:not(.is-adoptable) text {
  fill: var(--forest-label-dim);
}

.forest .node text.preview {
  text-anchor: middle;
  font-size: 12.6px;
}

/* A run of older versions that aren’t rationally adoptable, folded into a
   little stack, standing in for them until it’s opened. Its chevrons point
   apart; the control that folds the run back up points them together. */
.forest .node .stack,
.forest .node .pile-mark {
  display: none;
}

.forest .node.is-pile .stack,
.forest .node.is-pile .pile-mark {
  display: block;
}

.forest .node.is-pile circle.core,
.forest .node .stack,
.forest .fold-control .fold-ring,
.forest-legend .key-pile {
  fill: var(--forest-bg);
  stroke: var(--forest-label-dim);
  stroke-width: 1.5px;
}

.forest .node .pile-mark,
.forest .fold-control .fold-mark,
.forest-legend .key-pile-mark {
  fill: none;
  stroke: var(--forest-label-dim);
  stroke-width: 1.2px;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.forest .node.is-pile .halo {
  display: none;
}

/* A control, not an idea: nothing about the discussion changes. */
.forest .fold-control {
  cursor: pointer;
}

.forest .fold-control .hit {
  fill: transparent;
}

.forest .fold-control:hover .fold-ring,
.forest .fold-control:hover .fold-mark,
.forest .fold-control:focus-visible .fold-ring,
.forest .fold-control:focus-visible .fold-mark {
  stroke: var(--forest-label);
}

.forest .fold-control:focus {
  outline: none;
}

/* Joins two versions of the same idea. Not an attack, so it’s a quiet
   dashed tie rather than a solid edge. */
.forest .version-link {
  fill: none;
  stroke: var(--forest-label-dim);
  stroke-width: 1.5px;
  stroke-dasharray: 5 4;
  opacity: 0.75;
  pointer-events: none;
}

/* ---------- the text in the past ---------- */

/* While the text for another point in the timeline is on its way, see
   #followText in forest_controller.js */
.forest-loading {
  opacity: 0.55;
  transition: opacity 0.15s;
}

/* Nothing can be added to the past, see ForestHelper#forest_past_banner. */
body:has(.forest-past-banner) #discussion-footer,
body:has(.forest-past-banner) .discussion-footer-float-btn {
  display: none !important;
}

/* ---------- a discussion that took place before Veritula ---------- */

/* The story, above the text tree, see ForestHelper#forest_event_slot. It
   takes up the first screen, out to the edges of the text column, and is
   dark, like the visual beside it, whatever the color scheme. */
.forest-event {
  display: flex;
  flex-direction: column;
  /* The navbar's height is measured, see #setNavbarHeight in
     forest_controller.js. */
  min-height: calc(100svh - var(--forest-navbar-height, 4rem) - var(--forest-timeline-height, 0px));
  margin: -1rem -1rem 2rem;
  padding: 3rem 1rem 1.5rem;
  /* The text column scrolls sideways for wide ideas, see #content; the
     story stays where it is, so no gap opens beside it. Sticking keeps it
     clear of the column's padding, which it otherwise covers, hence the
     offset. */
  position: sticky;
  left: -1rem;
  /* Sideways, a finger moves through the history, see #onSwipeStart in
     forest_controller.js, rather than scrolling the column or the page. */
  touch-action: pan-y pinch-zoom;
}

@media (min-width: 992px) {
  .forest-event {
    padding: 4.5rem 3rem 1.5rem 4rem;
  }
}

.forest-event-when {
  letter-spacing: 0.12em;
  color: var(--bs-secondary-color);
}

.forest-event-title {
  font-size: clamp(2.25rem, 4vw, 3.5rem);
  line-height: 1.05;
  margin-bottom: 1.25rem;
}

.forest-event-narration {
  font-size: 1.35rem;
  line-height: 1.5;
}

/* Where the discussion stands after the event, see
   ForestHelper#forest_event_recap */
.forest-event-recap {
  margin: 2.5rem 0;
  padding: 1rem 0;
  border-block: 1px solid var(--bs-border-color);
}

.forest-event-recap .serif-font {
  font-size: 1.35rem;
  line-height: 1.5;
  margin-bottom: 0;
}

/* Like the event's place and date */
.forest-event-recap-label {
  letter-spacing: 0.12em;
  color: var(--bs-secondary-color);
  margin-bottom: 0.35rem;
}


/* What the event put forward, in full, with a dot in its color in the
   visual */
.forest-event-idea {
  margin: 1.5rem 0;
}

/* Dots as in the visual: blue for ideas, red for criticisms, gray for
   comments, filled if rationally adoptable at the event's end and hollow if
   not, see ForestHelper#forest_event_idea and #forest_event_recap */
.forest-event-idea > p::before,
.forest-dot {
  content: "";
  display: inline-block;
  width: 0.6em;
  height: 0.6em;
  margin-right: 0.5em;
  border-radius: 50%;
  /* Centered on the text's capitals and lowercase letters alike, rather
     than sitting on its baseline */
  vertical-align: 0.08em;
  background: var(--dot);
}

.forest-event-idea,
.forest-dot {
  --dot: var(--forest-idea);
}

.forest-event-idea.is-criticism {
  --dot: var(--forest-crit);
}

.forest-event-idea.is-comment {
  --dot: var(--forest-comment);
}

/* As wide as the space before it, in the recap's text */
.forest-dot {
  margin-right: 0.25em;
}

.forest-event-idea.is-pending > p::before,
.forest-dot.is-pending {
  background: transparent;
  box-shadow: inset 0 0 0 0.12em var(--dot);
}

/* Rationally adoptable ideas and criticisms glow, as in the visual, see
   forest-adopt-glow */
@media (prefers-reduced-motion: no-preference) {
  .forest-event-idea:not(.is-pending, .is-comment) > p::before,
  .forest-dot:not(.is-pending) {
    animation: forest-dot-glow 2.6s ease-in-out infinite;
  }
}

@keyframes forest-dot-glow {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0.5em 0.15em color-mix(in srgb, var(--dot) 65%, transparent); }
}

/* Replies to an idea from the same event, under it, with a line down from
   its dot, see ForestHelper#forest_event_ideas */
.forest-event-replies {
  margin-left: 0.25rem;
  padding-left: 1.25rem;
  border-left: 1px solid var(--bs-border-color);
}

.forest-event-idea:has(+ .forest-event-replies) {
  margin-bottom: 0.75rem;
}

.forest-event-replies > .forest-event-idea:first-child {
  margin-top: 0;
}

.forest-event-sources {
  color: var(--bs-secondary-color);
}

.forest-event-person {
  display: inline-block;
  padding: 0.3rem 0.85rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
  color: var(--bs-body-color);
  text-decoration: none;
}

.forest-event-person:hover {
  border-color: var(--bs-secondary-color);
}

.forest-event-lifespan {
  color: var(--bs-secondary-color);
}

.forest-event-hint {
  color: var(--bs-secondary-color);
}

.forest-hint-swipe {
  display: none;
}

@media (pointer: coarse) {
  .forest-hint-keys {
    display: none;
  }

  .forest-hint-swipe {
    display: inline;
  }
}

/* On a phone, the portrait on top of the story, out to its edges and
   fading into it, see ForestHelper#forest_event_card */
/* Moving on, the next card fades in on a phone, as the portrait behind the
   visual does beside the text, see #showEvent in forest_controller.js */
@media (max-width: 991.98px) and (prefers-reduced-motion: no-preference) {
  .forest-event-card.is-entering {
    animation: forest-card-in 0.5s ease;
  }
}

@keyframes forest-card-in {
  from { opacity: 0; }
}

.forest-event-portrait {
  position: relative;
  width: calc(100% + 2rem);
  margin: -3rem -1rem 1.5rem;
  /* For the zoom below */
  overflow: hidden;
}

/* The picture zooms in a little as it scrolls away, driven by the scroll
   itself, so it's as smooth as the scrolling, where browsers can. By the
   page's scrolling, since the picture is at its top and the nearest
   scroller, #content, only scrolls sideways. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .forest-event-portrait img {
      transform-origin: center 30%;
      animation: forest-picture-zoom linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 28rem;
    }
  }
}

@keyframes forest-picture-zoom {
  to { transform: scale(1.08); }
}

/* On a phone or tablet, where the story has the screen to itself, its text
   fills it, rather than leaving a gap beside it the width of the visual's
   column on larger screens. */
@media (max-width: 991.98px) {
  .forest-event .max-idea-width {
    max-width: none;
  }
}

/* On a phone or tablet, the event's place, date and title go over the top
   of its picture, light and shadowed, so the first screen says what the
   event is, see ForestHelper#forest_event_card */
@media (max-width: 991.98px) {
  .forest-event-card:has(> .forest-event-portrait) {
    position: relative;
  }

  .forest-event-card:has(> .forest-event-portrait) > .forest-event-heading {
    position: absolute;
    top: 1rem;
    left: 0;
    right: 0;
    z-index: 2;
    color: #fff;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9), 0 0 12px rgba(0, 0, 0, 0.5);
  }

  .forest-event-card:has(> .forest-event-portrait) > .forest-event-heading .forest-event-when {
    color: rgba(255, 255, 255, 0.85);
    margin-bottom: 0.25rem;
  }

  /* Smaller, so it covers less of the picture, faces included */
  .forest-event-card:has(> .forest-event-portrait) > .forest-event-heading .forest-event-title {
    font-size: 1.6rem;
  }

  /* Darker at the top, under the title */
  .forest-event-portrait::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 50%;
    z-index: 1;
    background: linear-gradient(rgba(0, 0, 0, 0.5), transparent);
    pointer-events: none;
  }
}

/* Its height goes by its width, not the window's height, which changes on a
   phone as the browser's toolbars shrink and grow while the page scrolls. */
.forest-event-portrait img {
  display: block;
  width: 100%;
  aspect-ratio: 20 / 17;
  max-height: 28rem;
  object-fit: cover;
  /* Cropped around its subject, see picture_focus_controller.js */
  filter: brightness(0.85);
  mask-image: linear-gradient(black 55%, transparent);
}

/* Who's pictured, and where the portrait is from, at the bottom right of
   the portrait, see #showEvent in forest_controller.js. Above the visual's
   Fit button there. */
.forest-portrait-caption {
  position: absolute;
  right: 1rem;
  bottom: 0;
  z-index: 2;
  margin: 0;
  text-align: right;
  color: var(--forest-caption);
  text-shadow: 0 1px 3px var(--forest-caption-glow);
  pointer-events: none;
}

.forest-canvas .forest-portrait-caption {
  right: 0.75rem;
  bottom: 3.25rem;
  /* Clear of the legend, at the bottom left */
  max-width: min(18rem, 45%);
}

.forest-portrait-credit {
  display: block;
  font-size: 0.85em;
  opacity: 0.75;
}

/* Only as wide as its words, rather than the whole column it's in */
.forest-event-more {
  align-self: flex-start;
  margin-top: auto;
  padding-top: 1rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
}

/* Who the event is about, behind the visual and faded under it, see
   #showEvent in forest_controller.js. The visual is drawn over it, since
   it comes after it. */
.forest-portrait,
.forest-portrait-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* One portrait fades into the next, see #showPortrait, each with its veil,
   so nothing is veiled without one. */
.forest-portrait-layer {
  background-position: center top;
  background-size: cover;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.forest-portrait-layer.is-shown {
  opacity: 1;
}

.forest-portrait-layer::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--forest-veil);
}

@media (prefers-reduced-motion: reduce) {
  .forest-portrait-layer {
    transition: none;
  }
}

/* A negative, like the plates of the 1919 eclipse, shows as a positive in
   dark mode. Inverting the layer inverts its veil too, so that veil is the
   inverse of the one wanted. */
[data-bs-theme="dark"] .forest-portrait-layer.is-negative,
[data-bs-theme="dark"] .forest-event-portrait.is-negative img {
  filter: invert(1);
}

[data-bs-theme="dark"] .forest-portrait-layer.is-negative::after {
  background: linear-gradient(rgba(237, 238, 241, 0.55), rgba(237, 238, 241, 0.75));
}

/* A drawing in the story, in its text's colors, see
   ForestHelper#forest_figure. Wide margins set it apart from the text, as
   much as the drawing of Mercury's orbit leaves itself, see .orbit-figure;
   drawings are at most 34rem wide. */
.forest-event-figure {
  margin: calc(1.5rem + min(11.9%, 4.05rem)) 0;
}

.forest-event-figure svg {
  display: block;
  width: 100%;
  max-width: 34rem;
  height: auto;
  margin-inline: auto;
  color: var(--bs-body-color);
}

/* What a drawing points out, in the color of criticisms, and Earth in that
   of ideas. The drawings' own colors are for when they're seen alone. */
.forest-event-figure .figure-accent {
  stroke: var(--forest-crit);
}

.forest-event-figure .figure-accent-fill {
  fill: var(--forest-crit);
}

/* What hides what's behind it, in the story's own background */
.forest-event-figure .figure-ground {
  fill: var(--bs-tertiary-bg);
}

/* See motion_controller.js */
.forest-event-figure .is-moving .figure-still {
  display: none;
}

/* Labels outlined in it, so lines under them don't cross the letters */
.forest-event-figure .figure-halo {
  stroke: var(--bs-tertiary-bg);
}

.forest-event-figure .figure-earth {
  fill: var(--forest-idea);
}

/* Stars shifted by the Sun's bending of their light, see lensing_controller.js */
.lensing-figure canvas {
  display: block;
  width: 100%;
  max-width: 34rem;
  aspect-ratio: 520 / 300;
  margin-inline: auto;
  color: var(--bs-body-color);
}

/* Its Sun can be grabbed and dragged, see lensing_controller.js. */
.lensing-figure.is-over-sun canvas {
  cursor: grab;
}

body.lensing-dragging,
body.lensing-dragging * {
  cursor: grabbing !important;
}

/* A drawing that runs time forward, see orbit_controller.js: its slider is a
   hairline, like the drawing */
.orbit-figure {
  max-width: 34rem;
  margin-inline: auto;
}

/* At the slider's starting point, the drawing of Mercury's orbit leaves
   about 12% of its width empty at its top, which takes the place of the
   extra space other figures get above them. */
.forest-event-figure:has(.orbit-figure.has-headroom) {
  margin-top: 1.5rem;
}

.orbit-figure svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Arrows on the thumb, and everywhere for as long as it's dragged, like the
   timeline's, see orbit_controller.js */
.orbit-figure-time input[type="range"]::-webkit-slider-thumb { cursor: ew-resize; }
.orbit-figure-time input[type="range"]::-moz-range-thumb { cursor: ew-resize; }

body.orbit-dragging,
body.orbit-dragging * {
  cursor: ew-resize !important;
}

.orbit-figure-time {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.5rem;
  font: 500 0.7rem/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: 0.08em;
  color: var(--bs-secondary-color);
}

.orbit-figure-time input[type="range"] {
  flex: 1;
  height: 1.5rem;
  margin: 0;
  /* Veritula fills inputs in dark mode, which would box in the slider. */
  background-color: transparent !important;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.orbit-figure-time input::-webkit-slider-runnable-track {
  height: 1px;
  background: var(--bs-secondary-color);
}

.orbit-figure-time input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px;
  height: 13px;
  margin-top: -6px;
  border: 1px solid var(--bs-body-color);
  border-radius: 50%;
  background: var(--bs-tertiary-bg);
}

.orbit-figure-time input::-moz-range-track {
  height: 1px;
  background: var(--bs-secondary-color);
}

.orbit-figure-time input::-moz-range-thumb {
  width: 11px;
  height: 11px;
  border: 1px solid var(--bs-body-color);
  border-radius: 50%;
  background: var(--bs-tertiary-bg);
}

.forest-event-figure figcaption {
  margin-top: 1.5rem;
  text-align: center;
  color: var(--bs-secondary-color);
}

/* The key over a portrait, glowing like the portrait's caption, see
   .forest-portrait-caption */
.forest-pane:has(.forest-portrait-layer.is-shown) .forest-legend {
  color: var(--forest-caption);
  text-shadow: 0 1px 3px var(--forest-caption-glow);
}

/* Buttons over a portrait stand out from it. .btn-schemed's hover and
   pressed colors are !important, so these are too. */
.forest-pane:has(.forest-portrait-layer.is-shown) .btn-schemed {
  background-color: var(--forest-over-btn);
  border-color: var(--forest-over-btn-border);
  color: var(--bs-body-color);
  backdrop-filter: blur(4px);
}

.forest-pane:has(.forest-portrait-layer.is-shown) .btn-schemed:hover,
.forest-pane:has(.forest-portrait-layer.is-shown) .btn-schemed:focus,
.forest-pane:has(.forest-portrait-layer.is-shown) .btn-schemed:active {
  background-color: var(--forest-over-btn-hover) !important;
  border-color: var(--forest-over-btn-border) !important;
}
/* Modified from Twitter icons */
.ugc a[href^="https://twitter.com"]::after,
.ugc a[href^="https://www.twitter.com"],
.ugc a[href^="https://x.com"]::after,
.ugc a[href^="https://www.x.com"]::after,
.ugc a[href^="https://youtube.com"]::after,
.ugc a[href^="https://www.youtube.com"]::after,
.ugc a[href^="https://youtu.be"]::after,
.ugc a[href^="https://github.com"]::after,
.ugc a[href^="https://www.github.com"]::after,
.ugc a[href^="https://stackoverflow.com"]::after,
.ugc a[href^="https://www.stackoverflow.com"]::after,
.ugc a[href^="https://wikipedia.org"]::after,
.ugc a[href^="https://en.wikipedia.org"]::after,
.ugc a[href^="https://reddit.com"]::after,
.ugc a[href^="https://www.reddit.com"]::after,
.ugc a[href^="https://redd.it"]::after,
.ugc a[href^="https://substack.com"]::after,
.ugc a[href^="https://www.substack.com"]::after {
  font-family: bootstrap-icons !important;
  font-style: normal;
  font-weight: normal !important;
  font-variant: normal;
  text-transform: none;
  line-height: 1;
  vertical-align: -.125em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;

  /* My own addition */
  color: var(--bs-secondary-color);
  font-size: 0.8em;

  /* Inline-block display so the icon doesn’t get underlined on hover */
  display: inline-block;
  margin-left: 0.25em;
  margin-right: 0.1em;
}

.ugc a[href^="https://twitter.com"]::after,
.ugc a[href^="https://www.twitter.com"],
.ugc a[href^="https://x.com"]::after,
.ugc a[href^="https://www.x.com"]::after {
  content: '\f5ef';
}

.ugc a[href^="https://youtube.com"]::after,
.ugc a[href^="https://www.youtube.com"]::after,
.ugc a[href^="https://youtu.be.com"]::after {
  content: '\f62b';
}

.ugc a[href^="https://github.com"]::after,
.ugc a[href^="https://www.github.com"]::after {
  content: '\f3ed';
}

.ugc a[href^="https://stackoverflow.com"]::after,
.ugc a[href^="https://www.stackoverflow.com"]::after {
  content: '\f667';
}

.ugc a[href^="https://wikipedia.org"]::after,
.ugc a[href^="https://en.wikipedia.org"]::after {
  content: '\f8cc';
}

.ugc a[href^="https://reddit.com"]::after,
.ugc a[href^="https://www.reddit.com"]::after,
.ugc a[href^="https://redd.it"]::after {
  content: '\f650';
}

.ugc a[href^="https://substack.com"]::after,
.ugc a[href^="https://www.substack.com"]::after {
  content: '\f8D7';
}
.top-level-idea {
  padding-bottom: 2rem;
}

.idea-id {
  font-size: 95%;
}

.serif-font .idea-id {
  font-size: 85%;
}

.idea {
  scroll-margin-top: 1rem;
  scroll-margin-left: -32px;
}

/*
 * The line from a parent down to where the branch of its lowest pending
 * criticism starts is drawn in red on top of the gray one, and the branches of
 * pending criticisms are red. Everything follows from the .pending-flag inside
 * each idea, see IdeasHelper#pending_flag, and the order of the ideas as they
 * are on the page, which doesn't have to be the sort order: a newly posted idea
 * is shown above its siblings. Each element draws the part of the line next to
 * itself, since only it knows how tall it is.
 */
.pending-flag {
  display: none;
}

/* Like the gray line turns black or white when hovering over it, the red one
 * turns darker or lighter. application.js adds .hover to everything that
 * belongs to the line under the mouse. Each idea sets the color for the parts
 * of the line inside of it, which are the ones that belong to it. */
:root {
  /* Darker than the red, but not so dark that it looks like the black gray
   * lines turn into when hovering over them in light mode */
  --red-line-hover-color: color-mix(in srgb, var(--bs-danger) 70%, black);
}

[data-bs-theme='dark'] {
  --red-line-hover-color: var(--bs-danger-text-emphasis);
}

.idea {
  --red-line-color: var(--bs-danger);
}

.idea.hover {
  --red-line-color: var(--red-line-hover-color);
}

.idea-own-content {
  position: relative;
  /* Keeps the margins of what's in it from collapsing out of it, which would
   * leave a gap in the red line */
  display: flow-root;
}

/* Next to an idea's own content if it has a pending criticism (unless its
 * comments are collapsed, see below), next to a pending criticism, and next to
 * any idea above the lowest pending one */
.idea-own-content:has(~ .idea-children-parent:not(.d-none) > .list-group > .idea-list-group-item > .pending-flag.is-pending)::before,
.idea-list-group-item:has(> .pending-flag.is-pending)::before,
.idea-list-group-item:has(~ .idea-list-group-item > .pending-flag.is-pending)::before {
  content: '';
  position: absolute;
  /* The line is part of the gutter as far as the user is concerned, so clicks
   * have to reach the gutter underneath to collapse the comments */
  pointer-events: none;
  /* Same as the gray line, which is 1px wide and centered 24px to the left of
   * the content */
  left: -24.5px;
  width: 1px;
  top: 0;
  bottom: 0;
  background-color: var(--red-line-color);
  /* Above the branches, which are z-1, so the red line is always on top */
  z-index: 2;
}

/* Next to an idea's own content it starts below the avatar (32px) and the gap
 * above the gray line (0.5rem) */
.idea-own-content:has(~ .idea-children-parent:not(.d-none) > .list-group > .idea-list-group-item > .pending-flag.is-pending)::before {
  top: 40px;
}

/* When the comments are collapsed the whole line is dashed, so make it red if
 * one of the hidden comments is a pending criticism. This replaces the solid red
 * next to the idea's own content, which would end before the dashed line does. */
.idea:has(> .flex-grow-1 > .idea-children-parent.d-none > .list-group > .idea-list-group-item > .pending-flag.is-pending) > .gutter-column > .gutter-parent > .comment-gutter {
  background-image: repeating-linear-gradient(
    to bottom,
    var(--red-line-color) 0,
    var(--red-line-color) 10px,
    transparent 10px,
    transparent 20px
  );
}

/* The lowest pending criticism only goes down to where its branch starts */
.idea-list-group-item:has(> .pending-flag.is-pending):not(:has(~ .idea-list-group-item > .pending-flag.is-pending))::before {
  bottom: auto;
  height: 16px;
}

/* The branch of a pending criticism. It's part of the child, but belongs to the
 * line of its parent, so it has its own hover state. */
.idea-list-group-item:has(> .pending-flag.is-pending) > turbo-frame > .idea > .gutter-column > .child-indicator {
  border-color: var(--bs-danger);
}

.idea-list-group-item:has(> .pending-flag.is-pending) > turbo-frame > .idea > .gutter-column > .child-indicator.hover {
  border-color: var(--red-line-hover-color);
}

.idea-core .ugc > :last-child {
  margin-bottom: 0 !important;
}

.footnotes hr {
  width: 175px !important;
}

.idea-header {
  margin-top: 3px;
}

.idea-core .ugc {
  margin-bottom: -0.25rem;
}

.idea-list-group-item .avatar {
  width: 32px;
  height: 32px;
}

.badges-and-reactions:has(.badge, .reaction) {
  margin-top: 0.75rem;
}

.badges-and-reactions:has(.badge) .reactions {
  margin-left: 0.75rem;
}

.exclusion-check {
  vertical-align: -3px;
  margin-left: 0.125rem;
}

.has-preview-placeholder [data-markdown-preview-target="output"]:empty:before {
  content: 'Nothing to preview.';
  line-height: 2;
}

[data-revision-preview-target="output"]:empty:before {
  content: 'No changes to show.';
  line-height: 2;
}

.has-preview-placeholder [data-markdown-preview-target="output"]:empty:before,
[data-revision-preview-target="output"]:empty:before {
  font-style: italic;
  font-family: var(--bs-body-font-family);;
  color: rgb(var(--bs-secondary-rgb)) !important;
  font-size: var(--bs-body-font-size);
}

#idea-search-form-container {
  margin-top: -1rem;
}

@media (prefers-color-scheme: dark) {
  .has-preview-placeholder [data-markdown-preview-target="output"]:empty:before,
  [data-revision-preview-target="output"]:empty:before {
    color: #c7c7c7 !important; /* same as .text-secondary */
  }
}

/* The emoji just chosen, popping up from the button it was chosen with and
   fading, see reaction_controller.js */
.react-button {
  position: relative;
}

.react-pop {
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 1.15rem;
  line-height: 1;
  pointer-events: none;
  transform: translate(-50%, -50%);
  animation: react-pop 1s ease-out forwards;
}

@keyframes react-pop {
  0% { transform: translate(-50%, -50%) scale(0.4); opacity: 0; }
  25% { transform: translate(-50%, -90%) scale(1.3); opacity: 1; }
  100% { transform: translate(-50%, -200%) scale(1); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .react-pop {
    animation: none;
    transform: translate(-50%, -160%);
  }
}
.unread-notification {
  padding-right: 1rem !important;
  position: relative;
}

/* This is how Stack Overflow does rounded corners
   for the left border, along with the relative
   positioning above. */
.unread-notification:before {
  background: orange;
  border-radius: 8px;
  top: 10px;
  right: 0;
  bottom: 10px;
  content: "";
  position: absolute;
  width: 3px;
}
.emoji-picker__wrapper {
  z-index: 15;
}

.emoji-picker__search-icon {
  display: none;
}

.emoji-picker__emoji {
  border-radius: var(--bs-border-radius) !important;
}

.reaction button {
  width: 20px;
  height: 20px;
  padding: 0;
  line-height: 1;
  font-size: 20px !important;
  background-color: transparent !important;
  border: none;
}

.reaction button:hover {
  background-color: transparent !important;
}

@media (prefers-color-scheme: dark) {
  .emoji-picker.auto {
    background: var(--bs-body-bg) !important;
  }
}
em.vdd, strong.vdd,
.vdd em, .vdd strong {
  color: revert !important;
}

:not(pre).vdd, :not(pre).vdd, :not(pre).vdd {
  width: fit-content;
}

/* A code block that is added or removed as a whole must still fit its
 * container, with long lines scrolling inside it, not stretch to the width
 * of its longest line. */
.code-block-container.vdd {
  width: auto;
}

#preview-changes-tabs {
  min-height: 2rem;
}

/* Links aren’t generally underlined except in changes highlighted in
 * diffs. By specifically re-enabling underlining for links in changes,
 * we ensure they are underlined *with their own color*. */
a.vdd, .vdd a {
  text-decoration: underline;
}

a.bg-success-schemed, .bg-success-schemed a,
a.bg-danger-schemed, .bg-danger-schemed a {
  color: #004dbe;
}

.vdd-added, .vdd-added a {
  text-decoration-skip-ink: none !important;
  text-decoration-color: #4a9e13 !important;
}

.vdd-added a:hover, a.vdd-added:hover {
  text-decoration-color: initial !important;
}

.vdd-removed {
  text-decoration-color: #dd0062 !important;
}

/*
 * Need the .ugc here so the rule is specific enough to
 * override other .ugc img styles
 */
.ugc img.vdd, .ugc .vdd img {
  background: none !important;
  border-radius: 0 !important;
}

img.vdd-added, .vdd-added img {
  border: 1px solid #4a9e13;
}

img.vdd-removed, .vdd-removed img {
  border: 1px solid #dd0062;
}

@media (prefers-color-scheme: dark) {
  .vdd-added, .vdd-added a {
    text-decoration-color: #31670e !important;
  }

  .vdd-removed {
    text-decoration-color: #900040 !important;
  }
}

/* The default border color for hrs is hard to see against the backgrounds
 * used for changes. Use the text color instead. */
.vdd hr {
  border-top-color: currentColor;
}

/* An hr that starts a marked block, such as the one above footnotes, has a top
 * margin that would collapse through the block and leave the hr on its top
 * edge. Use padding instead so the hr sits inside the mark. */
.vdd:has(> hr:first-child) {
  padding-top: 1rem;
}

.vdd > hr:first-child {
  margin-top: 0;
}

/* An hr that is itself added, removed or modified has no height, so its
 * background would be barely visible. Give it a band with the line in the
 * middle. */
hr.vdd {
  height: 1.25rem;
  border: 0;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-position: center;
  background-repeat: no-repeat;
}

/* The pink for inline code is hard to see against the dark mode backgrounds
 * used for changes. Pick a pink to match each. */
@media (prefers-color-scheme: dark) {
  .vdd-added code:not(pre code), code.vdd-added,
  .vdd-removed code:not(pre code), code.vdd-removed {
    color: #5a0a30;
  }

  .vdd-modified code:not(pre code), code.vdd-modified {
    color: #ffa6cf;
  }
}

/* The placeholder for a collapsed run of list items must be a list item to be
 * valid, but shouldn't look or count like one. Only display: list-item
 * increments the counter that numbers ordered lists. */
.diff-collapsed-item {
  display: block;
  list-style: none;
}

/* Collapsed run of unchanged blocks: the text between two thin lines
 * across the whole width. Clicking it shows them. */
.diff-collapsed-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font-size: 0.875rem;
  font-style: italic;
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.diff-collapsed-divider::before,
.diff-collapsed-divider::after {
  content: '';
  flex: 1;
  /* The content is only as wide as its widest part, so without this the lines
   * vanish when the label is the widest thing */
  min-width: 2rem;
  border-top: 1px solid currentColor;
  opacity: 0.5;
}

.diff-collapsed-divider:hover {
  color: var(--bs-body-color);
}

/* Collapsed run of unchanged lines in a code block. Clicking it shows them. */
pre.highlight > .diff-collapsed-line {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  /* As tall as the other lines so the gutter stays lined up. A flex item would
   * otherwise only be as tall as its text. */
  height: 1lh;
  /* Lines the text and dashes up with the gutter's dots, which sit a little
   * lower than the middle of the row */
  padding-top: 0.25rem;
  color: var(--bs-secondary-color);
  cursor: pointer;
  user-select: none;
}

/* Same size as the label of a collapsed run of unchanged blocks */
.diff-collapsed-label {
  font-size: 0.875rem;
  font-style: italic;
}

/* A little less than Bootstrap's me-2, which is 0.5rem */
.diff-collapsed-icon {
  margin-right: 0.4375rem;
}

.diff-collapsed-dash {
  flex: 1;
  border-top: 1px solid currentColor;
  opacity: 0.5;
}

/* Needs the same specificity as the rule setting the color above */
pre.highlight > .diff-collapsed-line:hover {
  color: var(--bs-body-color);
}

/* Gutter of code blocks with changes: the old line number on the left, the new
 * one on the right. See revision_preview_controller.js. */
.diff-line-number {
  display: inline-block;
  min-width: 2ch;
  text-align: right;
}

.diff-line-number + .diff-line-number {
  margin-left: 1rem;
}
.shadow-overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0.75rem;
  pointer-events: none;
  z-index: 1;
  transition: opacity 0.2s ease;
  opacity: 0;
  --shadow-color: rgba(0, 0, 0, 0.1);
}

.shadow-left {
  background: linear-gradient(to right, var(--shadow-color), transparent);
}

.shadow-right {
  right: 0;
  background: linear-gradient(to left, var(--shadow-color), transparent);
}

@media (prefers-color-scheme: dark) {
  .shadow-overlay {
    --shadow-color: rgba(255, 255, 255, 0.07);
  }
}
.subscription-dropdown {
  width: 31ch;
}

.subscription-dropdown .dropdown-item {
  white-space: normal;
}
/* Bootstrap gives toasts a fixed width, which leaves short messages with lots
   of empty space. Fit them to their text instead, up to that width. */
.toast {
  width: auto;
  max-width: var(--bs-toast-max-width);
  /* Swiping up dismisses a toast instead of scrolling the page, see
     toast_controller.js */
  touch-action: none;
}
.user-profile .avatar {
  width: 75px;
  height: 75px;
}

/* The pill beside a historical person's name sits about on the name's
   baseline, see UsersHelper#historical_profile. */
.user-profile h1 + .badge {
  vertical-align: super;
}

.user-list-item .avatar {
  width: 50px;
  height: 50px;
}

.avatar-xs {
  width: 20px;
  height: 20px;
}

.avatar-xs + .avatar-xs {
  margin-left: 2px;
}

#user-activities .list-group-item:first-of-type {
  padding-top: 0 !important;
}
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *


 */

:root {
  --bs-body-bg: #f7f1e4;
  --bs-body-bg-rgb: 247, 241, 228;
  --bs-highlight-bg: #fcd865;
  --theme-color: 220, 2, 40;

  color-scheme: light dark;

  /* Override Bootstrap’s yucky smooth scroll animation and make it instant */
  scroll-behavior: auto !important;
}

body {
  background-color: var(--bs-body-bg);
}

.transparent-blur {
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

.mh-lvh-100 {
  /* lvh to avoid flickering on mobile (as opposed to vh) */
  min-height: 100lvh;
}

.mb-n2 {
  margin-bottom: -0.5rem;
}

.mb-n3 {
  margin-bottom: -1rem;
}

.scroll-mt-3 {
  scroll-margin-top: 1rem;
}

.autosize {
  field-sizing: content;
  resize: none;
}

a, .btn-link {
  text-decoration: none;
}

a:hover, a:active,
.btn-link:hover, .btn-link:active {
  text-decoration: underline;
}

h1, h2, h3, h4, h5, h6 {
  text-wrap: pretty;
}

mark, .mark {
  padding: revert;
}

/* Adjusted from https://www.coding-dude.com/wp/css/highlight-text-css/ */
.smear-badge {
  position:relative;
  transform: rotate(-2deg);
  color: #212529 !important;
  user-select: none;
}

.smear-badge:before {
  content: "";
  background-color: #ffc107;
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: -1;
  filter: url(#marker-shape);
  left: 0;
  top: 0;
}

.ugc strong:not(a strong) {
  color: rgb(var(--theme-color));
}

.ugc img {
  max-width: 100%;
  height: auto;
  border-radius: var(--bs-border-radius) !important;
  display: block;
  margin-top: .5rem !important;
  margin-bottom: .5rem !important;
}

.text-primary-light {
  color: rgb(62 140 255) !important;
}

.resize-none {
  resize: none;
}

textarea {
  min-height: 74px !important; /* 2lh */
}

.top-level textarea {
  min-height: 37px !important; /* 1lh */
}

textarea, input:not(:checked), select {
  background-color: rgb(255, 255, 255) !important;
}

.dropdown-menu {
  background-color: #fff;
}

.dropdown-menu a {
  text-decoration: none;
}

.dropdown-menu .dropdown-item {
  cursor: default;
}

.highlight .dropdown-item {
  color: var(--bs-dropdown-link-hover-color);
  background-color: var(--bs-dropdown-link-hover-bg);
}

.tribute-container .dropdown-menu {
  width: 340px;
  z-index: 10000;
}

.active .text-success {
  color: #15dd80 !important;
}

.text-decoration-none {
  text-decoration: none;
}

.preserve-white-space {
  white-space: pre;
}

#navbar-brand {
  margin-top: -4px !important;
  font-size: 2rem;
}

.navbar-brand {
  text-decoration: none !important;
}

.nav-link.active {
  background-color: var(--bs-tertiary-bg) !important;
  border-bottom-color: var(--bs-tertiary-bg) !important;
}

#navbar .nav-link.active {
  background-color: var(--bs-primary-bg-subtle) !important;
  border-bottom-color: revert !important;
}

.huge {
  font-size: 20rem;
  line-height: 1;
}

.big {
  font-size: 5.5rem;
}

.smaller {
  font-size: 14px;
}

.theme-color {
  color: rgb(var(--theme-color));
}

.list-group > .idea-list-group-item.list-group-item:last-child {
  padding-bottom: 0 !important;
}

.cursor-pointer {
  cursor: pointer;
}

.padded-middot {
  padding-left: 0.5em;
  padding-right: 0.5em;
}

.comment-gutter {
  width: 1px;
  min-width: 1px;
  background-color: #d7d7d7;
  margin-top: 0.5rem;
}

.gutter-parent:hover .comment-gutter, .gutter-parent.hover .comment-gutter {
  background-color: #000;
}

.gutter-parent.children-hidden .comment-gutter {
  background-color: transparent !important;
  background-image: repeating-linear-gradient(
    to bottom,
    #bbb 0, /* darker than default due to stripes looking lighter */
    #bbb 10px, /* darker than default due to stripes looking lighter */
    transparent 10px,
    transparent 20px
  );
}

.gutter-parent.children-hidden:hover .comment-gutter, .gutter-parent.children-hidden.hover .comment-gutter {
  background-color: transparent !important;
  background-image: repeating-linear-gradient(
    to bottom,
    #000 0,
    #000 10px,
    transparent 10px,
    transparent 20px
  );
}

.child-indicator {
  width: 25px;
  height: 24px;
  position: absolute;
  top: 16px;
  left: -24.5px;
  border-bottom: 1px solid #d7d7d7;
  border-left: 1px solid #d7d7d7;
  border-bottom-left-radius: 24px;
}

.child-indicator:hover, .child-indicator.hover {
  border-color: #000;
}

.gutter-hider {
  background: var(--bs-body-bg);
  position: absolute;
  width: 32px;
  left: -40px;
  top: 16px;
}

.gutter-hider {
  display: none;
}

/*
  Because the .idea-list-group-items are nested, we need to be specific about
  the hierarchy of elements or else we will end up selecting all gutter hiders
  starting in the second level of .idea-list-group-items.
  It ain’t pretty but it’s far better than conditionally rendering the gutter
  hiders in the markup! */
.idea-list-group-item:last-child > turbo-frame > .idea > .gutter-column > .gutter-hider {
  display: block;
}

.serif-font {
  font-family: eb-garamond, Georgia, serif !important;
}

/* For UI inside user-generated content, which is serif */
.sans-serif-font {
  font-family: var(--bs-body-font-family) !important;
}

.ugc {
  font-family: eb-garamond, Georgia, serif !important;
  width: fit-content;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.ugc hr {
  width: 35ch;
}

.fit-content {
  width: fit-content;
}

blockquote {
  color: #424242;
  padding-left: 1rem;
  margin-left: 2px;
  position: relative;
}

/* This is how Stack Overflow does rounded corners
   for the left border, along with the relative
   positioning of the blockquote proper. */
blockquote:before {
  /* Neutral, not red, which means criticism, see the line in the gutter next
     to pending criticisms */
  background: var(--bs-secondary);
  border-radius: 8px;
  top: 0;
  left: 0;
  bottom: 0px;
  content: "";
  position: absolute;
  width: 3px;
}

.blockquote-body > *:last-child {
  margin-bottom: 1.5rem !important;
}

/* Eg while the user has typed the source but not the quote yet. Otherwise the
   footer’s negative top margin pulls it out of the quote. */
.blockquote-body:empty + .blockquote-footer {
  margin-top: 0;
}

.idea-width {
  width: 100vw;
}

.max-idea-width {
  max-width: 100vw;
}

.max-card-width {
  max-width: 500px;
}

.addresses-check-parent {
  width: 60px;
}

.addresses-idea-parent {
  width: calc(100% - 60px);
}

.badge {
  vertical-align: text-top;
}

.badge-xs {
  font-size: 0.7rem !important;
}

small .badge, .small .badge {
  /* Restore badge’s original font size inside small and .small */
  font-size: 0.75rem;
}

.alert {
  width: fit-content;

  /* As opposed to Bootstrap's default 0.75rem 1.25rem */
  padding: 0.5rem .75rem;
}

.alert-success {
  border-color: #1cac3d;
}

.alert-info {
  border-color: #00bcff;
}

.alert-warning {
  border-color: chocolate;
}

.alert-danger {
  border-color: #e21d32;
}

hr {
  border-color: var(--bs-border-color);
  opacity: 1;
}

.breadcrumb {
  border-radius: 0.5rem;
  padding: 0.5rem 0.75rem;
}

pre code, .ugc pre code {
  font-size: 0.7em;
}

.ugc code, .ugc .font-monospace {
  font-size: 0.8em;
}

pre {
  padding: 1rem;
}

pre, .pre-background {
  background-color: #fffdfa !important;
}

.code-block-container {
  min-width: 300px;
}

/* .ugc is only as wide as its contents, which would make code blocks as wide
 * as their longest line, up to the available width. Let content with a code
 * block fill the width of its container, which is the width of an idea, so
 * short snippets don’t look cramped. */
.ugc:has(.code-block-container) {
  width: 100%;
}

.card {
  border-radius: var(--bs-border-radius-lg) !important;
}

.footnotes,
/* My fork of visual-dom-diff results in the footnotes div
   not getting the .footnotes class when adding footnotes
   for the first time in a diff. Workaround: */
div:has(> ol > li[id^="fn"]) {
  font-size: 80%;
}

.bg-success-schemed {
  background-color: #c3efcc;
}

.bg-primary-schemed {
  background-color: #c7ebf8;
}

.bg-danger-schemed {
  background-color: #f6d3ce;
}

.btn {
  cursor: default !important;
}

.btn-link {
  cursor: pointer !important;
}

.btn-schemed {
  background-color: rgb(220, 220, 220);
}

.btn-schemed:hover, .btn-schemed:focus {
  background-color: rgb(210, 210, 210) !important;
  border-color: rgb(210, 210, 210) !important;
}

.btn-schemed:focus-visible {
  outline: 2px solid rgb(13, 84, 191);
}

.btn-schemed:active {
  background-color: rgb(200, 200, 200) !important;
  border-color: rgb(200, 200, 200) !important;
}

.btn-schemed:disabled, .btn-schemed.disabled {
  background-color: rgb(200, 200, 200);
  border-color: rgb(200, 200, 200);
}

.btn-icon {
  border-radius: 10rem;
  padding-left: 0.35rem;
  padding-right: 0.35rem;
  vertical-align: baseline;
  --bs-btn-font-size: 0.875rem;
  --bs-btn-padding-y: 0.1rem;
}

.btn-icon i {
  vertical-align: middle;
}

.btn-icon.dropdown-toggle:after {
  vertical-align: middle;
}

a.btn {
  text-decoration: none !important;
}

.slight-vertical-align {
  vertical-align: 0.5px;
}

.faded-truncate {
  overflow: hidden;
}

.faded-truncate .footnote-ref {
  pointer-events: none;
  color: inherit;
}

.faded-truncate-3 {
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0%, transparent);
  max-height: 3rem;
}

.faded-truncate-15 {
  mask-image: linear-gradient(180deg, #000 30%, transparent);
  max-height: 15rem;
}

.shadow-top {
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.05);
}

html[data-ready="false"] .btn,
html[data-ready="false"] .gutter-parent,
html[data-ready="false"] .child-indicator {
  pointer-events: none;
  opacity: 0.5;
}

.code-gutter {
  user-select: none;
  pointer-events: none;
  text-align: right;
  font-size: inherit;
  margin: 0;
  flex: 0 0 auto;
}

.language-indicator {
  position: absolute;
  top: 15px;
  left: 1rem;
  font-size: 0.8rem;
  user-select: none;
  pointer-events: none;
  opacity: 65%;
  font-family: monospace;

  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
  max-width: calc(100% - 4rem);
}

.highlight {
  margin: 0;
  font-size: inherit;
}

.align-super {
  vertical-align: super;
}

.only-mobile {
  display: none;
}

.stable-font {
  font-variant-numeric: tabular-nums;
}

/* Detect mobile when viewport width is set manually */
@media (max-device-width: 767px) {
  .only-mobile {
    display: block !important;
  }
}

/* sm */
@media (min-width: 576px) {
  .idea-width {
    width: 55ch;
  }

  .max-idea-width {
    max-width: 55ch;
  }
}

/* md */
@media (min-width: 768px) {
  .top-level textarea {
    min-height: 74px !important;
  }

  .idea-width {
    width: 70ch;
  }

  .max-idea-width {
    max-width: 70ch;
  }
}

/* Touch screens */
@media (hover: none) and (pointer: coarse) {
  .d-touch-none {
    display: none !important;
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --theme-color: 249, 68, 73;
    --bs-body-bg: #1a1a1a;
    --bs-body-bg-rgb: 26, 26, 26;
    --bs-highlight-bg: #664d03;
  }

  body {
    background-color: var(--bs-body-bg);
  }

  blockquote {
    color: #c7c7c7;
  }

  ol.breadcrumb {
    border: 1px solid var(--bs-primary-border-subtle);
  }

  textarea, input:not(:checked), select {
    background-color: rgb(33, 37, 41) !important;
  }

  #navbar .nav-link.active {
    border: 1px solid var(--bs-primary-border-subtle) !important;
    margin: -1px;
  }

  a.link-primary, a.link-primary:hover {
    color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)) !important;
  }

  .text-bg-warning a {
    color: #3e6db3;
  }

  .text-secondary {
    color: #c7c7c7 !important;
  }

  .text-success {
    color: #0ed176 !important;
  }

  pre, .pre-background {
    background-color: var(--bs-dark) !important;
  }

  .dropdown-menu {
    background-color: var(--bs-dark);
  }

  .bg-success-schemed {
    background-color: #32a972;
  }

  .bg-primary-schemed {
    background-color: #143d79;
  }

  .bg-danger-schemed {
    background-color: #e5534b;
  }

  .btn-schemed {
    background-color: rgb(80, 80, 80);
  }

  .btn-schemed:hover, .btn-schemed:focus {
    background-color: rgb(70, 70, 70) !important;
    border-color: rgb(70, 70, 70) !important;
  }

  .btn-schemed:focus-visible {
    outline: 2px solid rgb(144, 192, 251);
  }

  .btn-schemed:active {
    background-color: rgb(60, 60, 60) !important;
    border-color: rgb(60, 60, 60) !important;
  }

  .btn-schemed:disabled, .btn-schemed.disabled {
    background-color: rgb(60, 60, 60);
    border-color: rgb(60, 60, 60);
  }

  .gutter-parent:hover .comment-gutter, .gutter-parent.hover .comment-gutter {
    background-color: #fff;
  }

  .comment-gutter {
    background-color: var(--bs-secondary);
  }

  .child-indicator {
    border-bottom: 1px solid var(--bs-secondary);
    border-left: 1px solid var(--bs-secondary);
  }

  .child-indicator:hover, .child-indicator.hover {
    border-color: #fff;
  }

  .gutter-parent.children-hidden .comment-gutter {
    background-color: transparent !important;
    background-image: repeating-linear-gradient(
      to bottom,
      var(--bs-secondary) 0, /* darker than default due to stripes looking lighter */
      var(--bs-secondary) 10px, /* darker than default due to stripes looking lighter */
      transparent 10px,
      transparent 20px
    );
  }

  .gutter-parent.children-hidden:hover .comment-gutter, .gutter-parent.children-hidden.hover .comment-gutter {
    background-color: transparent !important;
    background-image: repeating-linear-gradient(
      to bottom,
      #fff 0,
      #fff 10px,
      transparent 10px,
      transparent 20px
    );
  }

  .shadow-top {
    box-shadow: 0 -4px 20px rgba(255, 255, 255, 0.05);
  }
}
