/*
 * Loaded after bootstrap.min.css: keep selectors identical to Bootstrap's so overrides win
 * by cascade order. Variant colors are hex literals compiled into component variables
 * (.btn-primary{--bs-btn-bg:#0d6efd}), so changing --bs-primary does nothing — redefine
 * those variables. Token values come from vercel.com's --ds-* properties (docs/ui.md).
 */

@font-face {
  font-family: "Ubuntu";
  src: url("/assets/ubuntu-latin-400-normal-c1bb3829.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Ubuntu";
  src: url("/assets/ubuntu-latin-500-normal-7185e354.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "Ubuntu";
  src: url("/assets/ubuntu-latin-700-normal-acb7d6b6.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

/* Ubuntu has no 600; .fw-semibold (600) lands on the 700 face by font matching. */

@font-face {
  font-family: "Ubuntu Mono";
  src: url("/assets/ubuntu-mono-latin-400-normal-f2bda096.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Ubuntu Mono";
  src: url("/assets/ubuntu-mono-latin-700-normal-9316c6c1.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root,
[data-bs-theme="light"] {
  /* Bootstrap's CSS only ships `color-scheme: dark` (inside its own dark block), so
     light has to be declared here or native controls and scrollbars follow the OS. */
  color-scheme: light;

  /* Geist tokens — light */
  --ds-background-100: #fff;
  --ds-background-200: #fafafa;
  --ds-gray-100: #f2f2f2;
  --ds-gray-200: #ebebeb;
  --ds-gray-300: #e6e6e6;
  --ds-gray-400: #eaeaea;
  --ds-gray-500: #c9c9c9;
  --ds-gray-600: #a8a8a8;
  --ds-gray-700: #8f8f8f;
  --ds-gray-800: #7d7d7d;
  --ds-gray-900: #4d4d4d;
  --ds-gray-1000: #171717;
  --ds-gray-alpha-400: rgba(0, 0, 0, 0.08);
  --ds-gray-alpha-600: rgba(0, 0, 0, 0.24);
  --ds-blue-700: #0070f7;
  --ds-red-100: #ffeef0;
  --ds-red-400: #ffd8d7;
  --ds-red-800: #e70022;
  --ds-red-900: #d60020;
  --ds-red-1000: #46000c;
  --ds-amber-100: #fff6e1;
  --ds-amber-400: #ffdd84;
  --ds-amber-1000: #541c00;
  --ds-green-100: #ecfdec;
  --ds-green-400: #b9f5bc;
  --ds-green-800: #279141;
  --ds-green-1000: #00370d;
  --ds-focus-ring: rgba(0, 0, 0, 0.16);
  --ds-focus-border: 0 0 0 1px var(--ds-gray-alpha-600), 0 0 0 4px var(--ds-focus-ring);
  --ds-radius: 6px;
  /* Primary button under the cursor and while pressed: Vercel lifts black by one step,
     then goes all the way. Dark mode inverts the button, so both flip with the theme. */
  --ds-primary-hover: #383838;
  --ds-primary-active: #000;
  /* Translucent, so the blurred page shows through under the sticky navbar. */
  --ds-navbar-bg: rgba(255, 255, 255, 0.8);
  --ds-font-sans-fallback: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ds-font-mono-fallback: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;

  /* Bootstrap mapped onto the tokens above */
  --bs-body-font-family: "Ubuntu", var(--ds-font-sans-fallback);
  /* Bootstrap points code, kbd, pre, samp and .font-monospace at this one. */
  --bs-font-monospace: "Ubuntu Mono", var(--ds-font-mono-fallback);
  --bs-body-color: var(--ds-gray-1000);
  --bs-body-color-rgb: 23, 23, 23;
  --bs-body-bg: var(--ds-background-100);
  --bs-body-bg-rgb: 255, 255, 255;
  --bs-body-font-weight: 400;
  --bs-emphasis-color: var(--ds-gray-1000);
  --bs-secondary-color: var(--ds-gray-900);
  --bs-tertiary-bg: var(--ds-gray-100);
  --bs-tertiary-bg-rgb: 242, 242, 242;
  --bs-border-color: var(--ds-gray-alpha-400);
  --bs-border-color-translucent: var(--ds-gray-alpha-400);
  --bs-border-radius: var(--ds-radius);
  --bs-border-radius-sm: 4px;
  --bs-border-radius-lg: 8px;
  --bs-link-color: var(--ds-gray-1000);
  --bs-link-hover-color: var(--ds-gray-900);
  /* Components read the *-rgb triples, not the hex values, so overriding only the hex
     forms leaves links and badges blue; both forms are set here. */
  --bs-primary: var(--ds-gray-1000);
  --bs-primary-rgb: 23, 23, 23;
  --bs-primary-text-emphasis: var(--ds-gray-1000);
  --bs-primary-bg-subtle: var(--ds-gray-100);
  --bs-primary-border-subtle: var(--ds-gray-300);
  --bs-link-color-rgb: 23, 23, 23;
  --bs-link-hover-color-rgb: 77, 77, 77;
  --bs-secondary-rgb: 77, 77, 77;
  --bs-focus-ring-color: var(--ds-focus-ring);
  --bs-form-invalid-color: var(--ds-red-800);
  --bs-form-invalid-border-color: var(--ds-red-800);
  --bs-form-valid-color: var(--ds-green-800);
  --bs-form-valid-border-color: var(--ds-green-800);
}

/* Geist tokens — dark. Bootstrap's own dark palette loses to the `:root` block above
   (equal specificity, this file loads last), so only the literals need restating. */
[data-bs-theme="dark"] {
  color-scheme: dark;

  --ds-background-100: #000;
  --ds-background-200: #000;
  --ds-gray-100: #1a1a1a;
  --ds-gray-200: #1f1f1f;
  --ds-gray-300: #292929;
  --ds-gray-400: #2e2e2e;
  --ds-gray-500: #454545;
  --ds-gray-600: #878787;
  --ds-gray-700: #8f8f8f;
  --ds-gray-800: #7d7d7d;
  --ds-gray-900: #a0a0a0;
  --ds-gray-1000: #ededed;
  --ds-gray-alpha-400: rgba(255, 255, 255, 0.14);
  --ds-gray-alpha-600: rgba(255, 255, 255, 0.51);
  --ds-blue-700: #0071f6;
  --ds-red-100: #330a11;
  --ds-red-400: #6f101b;
  --ds-red-800: #e2162a;
  --ds-red-900: #ff5e63;
  --ds-red-1000: #ffeaed;
  --ds-amber-100: #291800;
  --ds-amber-400: #573200;
  --ds-amber-1000: #fff3d9;
  --ds-green-100: #00250a;
  --ds-green-400: #004616;
  --ds-green-800: #009335;
  --ds-green-1000: #daffe5;
  --ds-focus-ring: rgba(255, 255, 255, 0.16);
  --ds-primary-hover: #cccccc;
  --ds-primary-active: #fff;
  --ds-navbar-bg: rgba(0, 0, 0, 0.8);

  /* Bootstrap mapped onto the tokens above — the literals only */
  --bs-body-color-rgb: 237, 237, 237;
  --bs-body-bg-rgb: 0, 0, 0;
  --bs-primary-rgb: 237, 237, 237;
  --bs-link-color-rgb: 237, 237, 237;
  --bs-link-hover-color-rgb: 160, 160, 160;
  --bs-secondary-rgb: 160, 160, 160;
  --bs-tertiary-bg-rgb: 26, 26, 26;
}

body {
  -webkit-font-smoothing: antialiased;
}

/* Vercel sets its headings tight. */
h1, h2, h3, h4 {
  letter-spacing: -0.02em;
}

/* Buttons: flat, 14px, black primary. */
.btn {
  --bs-btn-font-size: 0.875rem;
  --bs-btn-font-weight: 500;
  --bs-btn-padding-x: 0.875rem;
  --bs-btn-padding-y: 0.375rem;
  --bs-btn-box-shadow: none;
  --bs-btn-focus-box-shadow: 0 0 0 4px rgba(0, 112, 247, 0.25);
}

.btn-primary {
  --bs-btn-color: var(--ds-background-100);
  --bs-btn-bg: var(--ds-gray-1000);
  --bs-btn-border-color: var(--ds-gray-1000);
  --bs-btn-hover-color: var(--ds-background-100);
  --bs-btn-hover-bg: var(--ds-primary-hover);
  --bs-btn-hover-border-color: var(--ds-primary-hover);
  --bs-btn-active-color: var(--ds-background-100);
  --bs-btn-active-bg: var(--ds-primary-active);
  --bs-btn-active-border-color: var(--ds-primary-active);
  --bs-btn-disabled-color: var(--ds-background-100);
  --bs-btn-disabled-bg: var(--ds-gray-1000);
  --bs-btn-disabled-border-color: var(--ds-gray-1000);
}

/* Dark mode's pressed (and hovered) red is near-white, so the label flips to black to
   stay readable — in light mode both fills are dark and keep Bootstrap's white. */
[data-bs-theme="dark"] .btn-danger {
  --bs-btn-hover-color: #000;
  --bs-btn-active-color: #000;
}

.btn-danger {
  --bs-btn-bg: var(--ds-red-800);
  --bs-btn-border-color: var(--ds-red-800);
  --bs-btn-hover-bg: var(--ds-red-900);
  --bs-btn-hover-border-color: var(--ds-red-900);
  --bs-btn-active-bg: var(--ds-red-1000);
  --bs-btn-active-border-color: var(--ds-red-1000);
}

.btn-outline-secondary {
  --bs-btn-color: var(--ds-gray-1000);
  --bs-btn-border-color: var(--ds-gray-alpha-400);
  --bs-btn-hover-color: var(--ds-gray-1000);
  --bs-btn-hover-bg: var(--ds-gray-100);
  --bs-btn-hover-border-color: var(--ds-gray-alpha-400);
  --bs-btn-active-color: var(--ds-gray-1000);
  --bs-btn-active-bg: var(--ds-gray-200);
  --bs-btn-active-border-color: var(--ds-gray-300);
  --bs-btn-disabled-color: var(--ds-gray-700);
  --bs-btn-disabled-border-color: var(--ds-gray-300);
}

/* Badges: Vercel tints a light background with dark text; Bootstrap's .text-bg-* is a solid
   fill with white text, so these roles carry the colors instead. */
/* Bootstrap's badge in Vercel's tag shape. Every knob is a variable because the variants
   below set nothing but colour. */
.badge {
  --bs-badge-font-weight: 500;
  --bs-badge-font-size: 0.75rem;
  --bs-badge-padding-x: 0.5rem;
  --bs-badge-padding-y: 0.25rem;
  --bs-badge-border-radius: 9999px;
}

.badge-primary {
  background-color: var(--ds-gray-1000);
  color: var(--ds-background-100);
}

/* The label shape: gray-1000 on gray-100, Vercel's gray-tag contrast. */
.badge-neutral {
  background-color: var(--ds-gray-100);
  color: var(--ds-gray-1000);
}

.badge-success {
  background-color: var(--ds-green-100);
  color: var(--ds-green-1000);
}

.badge-danger {
  background-color: var(--ds-red-100);
  color: var(--ds-red-1000);
}

.badge-attention {
  background-color: var(--ds-amber-100);
  color: var(--ds-amber-1000);
}

/* Forms: Vercel's focus is a hairline black ring, not Bootstrap's blue glow. */
.form-label {
  font-size: 0.875rem;
  font-weight: 500;
}

.form-text {
  font-size: 0.8125rem;
}

.form-control:focus,
.form-select:focus {
  border-color: var(--ds-gray-alpha-600);
  box-shadow: var(--ds-focus-border);
}

.form-check-input:checked,
.form-check-input[type="checkbox"]:indeterminate {
  background-color: var(--ds-gray-1000);
  border-color: var(--ds-gray-1000);
}

.form-check-input:focus {
  border-color: var(--ds-gray-alpha-600);
  box-shadow: var(--ds-focus-border);
}

.alert {
  --bs-alert-border-radius: var(--ds-radius);
  --bs-alert-padding-y: 0.75rem;
}

.alert-danger {
  --bs-alert-color: var(--ds-red-1000);
  --bs-alert-bg: var(--ds-red-100);
  --bs-alert-border-color: var(--ds-red-400);
}

.alert-success {
  --bs-alert-color: var(--ds-green-1000);
  --bs-alert-bg: var(--ds-green-100);
  --bs-alert-border-color: var(--ds-green-400);
}

/* Pagination: borderless, gray hover. */
.pagination {
  --bs-pagination-border-width: 0;
  --bs-pagination-color: var(--ds-gray-1000);
  --bs-pagination-hover-color: var(--ds-gray-1000);
  --bs-pagination-hover-bg: var(--ds-gray-100);
  --bs-pagination-active-color: var(--ds-background-100);
  --bs-pagination-active-bg: var(--ds-gray-1000);
  --bs-pagination-disabled-color: var(--ds-gray-900); /* gray-700 is 3.2:1 on white */
  --bs-pagination-disabled-bg: transparent;
  --bs-pagination-focus-box-shadow: var(--ds-focus-border);
  gap: 0.25rem;
}

/* Bootstrap compiles #0d6efd straight into --bs-dropdown-link-active-bg, so the active
   item stays blue until that variable is redefined. */
.dropdown-menu {
  --bs-dropdown-font-size: 0.875rem;
  --bs-dropdown-link-active-color: var(--ds-background-100);
  --bs-dropdown-link-active-bg: var(--ds-gray-1000);
}

/* The issue feedback menu's "Something else" box (issues/_feedback_menu) sits inside the
   dropdown, whose width is its longest item; a sentence needs more room than that. */
.issue-feedback__note {
  min-width: 18rem;
}

/* Navbar: Vercel's is 64px tall, translucent, with a hairline bottom border. */
.navbar {
  --bs-navbar-padding-y: 0;
  --bs-navbar-color: var(--ds-gray-900);
  --bs-navbar-hover-color: var(--ds-gray-1000);
  --bs-navbar-active-color: var(--ds-gray-1000);
  --bs-navbar-brand-color: var(--ds-gray-1000);
  --bs-navbar-brand-hover-color: var(--ds-gray-1000);
  --bs-navbar-toggler-border-color: var(--ds-gray-alpha-400);
  --bs-navbar-toggler-padding-x: 0.5rem;
  --bs-navbar-toggler-focus-width: 0;
  --bs-navbar-nav-link-padding-x: 0.75rem;
}

/* Bootstrap hard-codes a blue keyboard-focus ring on nav links; everywhere else the
   theme uses the hairline black one. */
.nav-link:focus-visible {
  box-shadow: var(--ds-focus-border);
}

.site-navbar {
  background-color: var(--ds-navbar-bg);
  backdrop-filter: saturate(180%) blur(5px);
  border-bottom: 1px solid var(--ds-gray-alpha-400);
}

/* The 64px is a min-height on the row, not the <header>: Bootstrap's align-items then
   centers it, and it still grows when the mobile menu expands. */
.site-navbar .navbar {
  min-height: 64px;
  /* `.navbar`'s padding shorthand (x defaults to 0) beats the container's gutter on this
     shared element, so the half-gutter is restored explicitly. */
  --bs-navbar-padding-x: calc(var(--bs-gutter-x) * 0.5);
}

/* Block, so the link is exactly the logo's height; never shrunk, so a narrow phone
   squeezes the gap rather than the wordmark. */
.site-logo {
  display: block;
  flex-shrink: 0;
}

/* 24px so the trigger stays the height of the links beside it. */
.nav-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: var(--ds-gray-alpha-400);
}

/* The home page's technology tiles: the whole card is the link target. */
.topic-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 88px;
  padding: 1rem;
  border: 1px solid var(--ds-gray-alpha-400);
  border-radius: var(--ds-radius);
  color: var(--ds-gray-1000);
  font-weight: 500;
  text-decoration: none;
}

.topic-tile:hover {
  background-color: var(--ds-gray-100);
  color: var(--ds-gray-1000);
}

.topic-tile:focus-visible {
  outline: none;
  box-shadow: var(--ds-focus-border);
}

/* The Hacktoberfest hero and campaign banner share the theme's amber, which the dark
   block already restates. */
.event-hero {
  background-color: var(--ds-amber-100);
  border: 1px solid var(--ds-amber-400);
}

.campaign-banner {
  background-color: var(--ds-amber-100);
  border-bottom: 1px solid var(--ds-amber-400);
}

/* shared/_stat_strip. column-reverse puts the value on top while keeping <dt> before
   <dd> in the DOM. Hairlines are a 1px gap over a tinted background, and flex rather than
   grid so a short last row grows to fill instead of leaving tinted empty cells. */
.stat-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  margin: 0;
  background-color: var(--ds-gray-alpha-400);
  border: 1px solid var(--ds-gray-alpha-400);
  border-radius: var(--ds-radius);
  overflow: hidden;
}

.stat-strip__item {
  display: flex;
  flex: 1 1 8.5rem;
  flex-direction: column-reverse;
  gap: 0.125rem;
  padding: 0.625rem 0.875rem;
  background-color: var(--bs-body-bg);
}

.stat-strip__value {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.3;
}

/* shared/_fact_list. `--framed` is the standalone variant, held between two hairlines. */
.fact-list {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.375rem 1.25rem;
  margin: 0;
  font-size: 0.875rem;
}

.fact-list--framed {
  padding: 0.625rem 0;
  border-top: 1px solid var(--ds-gray-alpha-400);
  border-bottom: 1px solid var(--ds-gray-alpha-400);
}

.fact-list__item {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
}

.fact-list__value {
  margin: 0;
}

.fact-list__value .badge + .badge {
  margin-left: 0.25rem;
}

/* A badge is inline-block, which the link's underline does not reach; without this a
   linked badge has no affordance. */
.fact-list__value a:hover > .badge,
.fact-list__value a:focus-visible > .badge {
  text-decoration: underline;
}

/* Small caps in the secondary colour, so a label reads as an index to its value. */
.stat-strip__label,
.fact-list__label {
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ds-gray-900);
}

/* Loading state is driven by Turbo's [aria-busy] on <turbo-frame>, not JS state, so it
   cannot get stuck on. */
turbo-frame[aria-busy] .list-group {
  opacity: 0.5;
}

[data-issues-loader] {
  display: none;
}

turbo-frame[aria-busy] [data-issues-loader] {
  display: inline-block;
}

/* /advanced-issues' slow-count note: the same [aria-busy] switch, held back three
   seconds by an animation delay so a fast answer never flashes it. */
[data-slow-loading-note] {
  display: none;
}

turbo-frame[aria-busy] [data-slow-loading-note] {
  display: block;
  opacity: 0;
  animation: slow-loading-note-appear 0.3s ease-in 3s forwards;
}

@keyframes slow-loading-note-appear {
  to { opacity: 1; }
}

/* ui/multi_select: the domain facet has forty-odd values, so the menu must scroll
   rather than run off the viewport. */
.multi-select-menu {
  max-height: 16rem;
  min-width: 15rem;
  overflow-y: auto;
}

/* <iconify-icon> renders asynchronously; sizing the empty box to 1em keeps the icon
   from shifting layout when it arrives (docs/ui.md §6). */
iconify-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
}

/* Rendered issue text (docs/markdown.md): wide tables and long URLs must not push the
   page sideways, and `pre` scrolls rather than wraps. Colours are theme tokens only. */
.markdown-body {
  overflow-wrap: anywhere;
}

.markdown-body > :first-child {
  margin-top: 0;
}

.markdown-body > :last-child {
  margin-bottom: 0;
}

.markdown-body pre {
  padding: 0.75rem 1rem;
  border-radius: var(--ds-radius);
  background-color: var(--ds-gray-100);
  overflow-x: auto;
}

.markdown-body code {
  padding: 0.125rem 0.25rem;
  border-radius: var(--ds-radius);
  background-color: var(--ds-gray-100);
}

/* Inside a fence the box has the tint and the padding already; a second layer reads as a
   rendering bug. */
.markdown-body pre code {
  padding: 0;
  background-color: transparent;
}

.markdown-body table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
}

.markdown-body th,
.markdown-body td {
  padding: 0.375rem 0.75rem;
  border: 1px solid var(--bs-border-color);
}

.markdown-body th {
  font-weight: 500;
}

.markdown-body img {
  max-width: 100%;
  height: auto;
  border-radius: var(--ds-radius);
}

.markdown-body blockquote {
  margin: 0 0 1rem;
  padding-left: 1rem;
  border-left: 2px solid var(--ds-gray-300);
  color: var(--ds-gray-900);
}

/* GFM's task list: no bullet (the checkbox is the marker), and the box is pulled back
   into the space the bullet would have used so it lines up with the text above it. */
.markdown-body li:has(> input[type="checkbox"]) {
  list-style: none;
}

.markdown-body li > input[type="checkbox"] {
  margin: 0 0.375rem 0 -1.25rem;
}

/* Blog headings are the page's own sections; the scrubber drops classes, so their
   scale is set here. */
.blog-post h2 {
  margin-top: 2.5rem;
  font-size: calc(1.275rem + 0.3vw);
  font-weight: 600;
}

.blog-post h3 {
  margin-top: 1.5rem;
  font-size: 1.25rem;
  font-weight: 600;
}

@media (min-width: 1200px) {
  .blog-post h2 {
    font-size: 1.5rem;
  }
}
