/*
 * bevel.css
 *
 * Bootstrap 2.0's look, built only on CSS that has been in every major
 * browser for at least 30 months. One file, no build step, no JavaScript.
 *
 * Everything sits in the five bevel.* layers below. Write your app's own CSS
 * outside any layer and it overrides the library without !important or
 * specificity tricks.
 *
 * Selectors stay at or under one class plus one state (0,2,0). Element and
 * structural parts of a selector go inside :where() so they add nothing.
 *
 * Reference: site/reference.html shows every class, variant and state.
 */

@layer bevel.reset, bevel.base, bevel.layout, bevel.components, bevel.utilities;


/* ==========================================================================
   Reset
   ========================================================================== */

@layer bevel.reset {
  *,
  ::before,
  ::after {
    box-sizing: border-box;
  }

  :where(h1, h2, h3, h4, h5, h6, p, ul, ol, dl, dd) {
    margin: 0;
  }

  /* An image or video wider than the screen shrinks to fit instead of
     scrolling the page sideways (WCAG 1.4.10). */
  :where(img, video) {
    max-inline-size: 100%;
    block-size: auto;
  }
}


/* ==========================================================================
   Tokens
   Override any of these in your app's own (unlayered) :root rule.
   ========================================================================== */

@layer bevel.base {
  :where(:root) {
    /* Neutrals */
    --bv-color-text: #333333;
    --bv-color-muted: #6E6E6E;
    --bv-color-input-text: #555555;
    --bv-color-surface: #FFFFFF;
    --bv-color-surface-alt: #F5F5F5;
    --bv-color-stripe: #F9F9F9;
    --bv-color-border: #DDDDDD;
    --bv-color-border-soft: #EEEEEE;
    --bv-color-border-strong: #CCCCCC;
    --bv-color-border-bottom: #BBBBBB;
    --bv-color-grid: rgba(0, 0, 0, 0.027);

    /* Action and focus */
    --bv-color-link: #006DA3;
    --bv-color-link-hover: #005580;
    --bv-color-primary-top: #0088CC;
    --bv-color-primary-bottom: #0055CC;
    --bv-color-primary: #0074CC;
    --bv-color-primary-active: #004099;
    --bv-color-danger-top: #E0524E;
    --bv-color-danger-bottom: #BD362F;
    --bv-color-danger: #CF443E;
    --bv-color-danger-active: #942A25;
    --bv-color-focus: #0088CC;
    --bv-color-focus-glow: rgba(82, 168, 236, 0.6);

    /* Navbar */
    --bv-color-navbar-top: #333333;
    --bv-color-navbar-bottom: #222222;
    --bv-color-navbar: #2C2C2C;
    --bv-color-navbar-link: #999999;
    --bv-color-navbar-link-active: #FFFFFF;
    --bv-color-navbar-current: #0088CC;
    --bv-color-brand: #FFFFFF;

    /* Labels and badges: pastel chips in the alert hues, a step stronger so
       a small chip still reads as a tint. Inverse stays dark. */
    --bv-label-default-bg: #E9E9E9;
    --bv-label-default-border: #D4D4D4;
    --bv-label-default-text: #676767;
    --bv-label-success-bg: #D0F5D7;
    --bv-label-success-border: #B3E2BC;
    --bv-label-success-text: #17793A;
    --bv-label-warning-bg: #F8EAB5;
    --bv-label-warning-border: #E7D48F;
    --bv-label-warning-text: #955B00;
    --bv-label-important-bg: #FFE1E0;
    --bv-label-important-border: #F9C6C4;
    --bv-label-important-text: #AA474C;
    --bv-label-info-bg: #D5EDFF;
    --bv-label-info-border: #B2DAF7;
    --bv-label-info-text: #346D93;
    --bv-label-inverse-bg: #333333;
    --bv-label-inverse-border: #333333;
    --bv-label-inverse-text: #FFFFFF;

    /* Alerts: pastel tints, not 2.0's. Backgrounds share one lightness;
       each text color keeps its tint's hue at 4.6:1 on it. */
    --bv-alert-warning-bg: #FFF7D9;
    --bv-alert-warning-border: #F0E2AD;
    --bv-alert-warning-text: #9F6204;
    --bv-alert-error-bg: #FFEBEA;
    --bv-alert-error-border: #FFD3D2;
    --bv-alert-error-text: #B4484E;
    --bv-alert-success-bg: #DFF9E3;
    --bv-alert-success-border: #C7EBCD;
    --bv-alert-success-text: #297C43;
    --bv-alert-info-bg: #E2F3FF;
    --bv-alert-info-border: #C3E5FE;
    --bv-alert-info-text: #387197;

    /* Progress bars: the primary and danger buttons' gradients, with green
       and amber at the same depth, so a bar keeps 3:1 against its track. */
    --bv-progress-default-top: var(--bv-color-primary-top);
    --bv-progress-default-bottom: var(--bv-color-primary-bottom);
    --bv-progress-success-top: #2B9F4A;
    --bv-progress-success-bottom: #017F31;
    --bv-progress-warning-top: #E18500;
    --bv-progress-warning-bottom: #C16300;
    --bv-progress-danger-top: var(--bv-color-danger-top);
    --bv-progress-danger-bottom: var(--bv-color-danger-bottom);

    /* Form errors and code */
    --bv-color-error: #B94A48;
    --bv-color-error-border: #EE5F5B;
    --bv-color-error-focus: #E9322D;
    --bv-color-error-glow: #F8B9B7;
    --bv-color-code-text: #DD1144;
    --bv-color-code-bg: #F7F7F9;
    --bv-color-code-border: #E1E1E8;

    /* Type: 13px on an 18px line */
    --bv-font-sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
    --bv-font-mono: Menlo, Monaco, Consolas, "Courier New", monospace;
    --bv-font-size: 0.8125rem;
    --bv-line-height: 1.125rem;

    /* Spacing */
    --bv-space-1: 0.25rem;    /* 4px */
    --bv-space-2: 0.3125rem;  /* 5px */
    --bv-space-3: 0.5625rem;  /* 9px, half rhythm */
    --bv-space-4: 0.875rem;   /* 14px */
    --bv-space-5: 1.125rem;   /* 18px, one rhythm line */
    --bv-space-6: 1.25rem;    /* 20px, gutter */
    --bv-space-7: 2.25rem;    /* 36px, two rhythm lines */
    --bv-space-8: 3.75rem;    /* 60px, above each page section */

    /* Radius */
    --bv-radius-sm: 3px;
    --bv-radius: 4px;
    --bv-radius-lg: 5px;
    --bv-radius-xl: 6px;
    --bv-radius-pill: 9px;

    /* Shadows: light comes from above */
    --bv-shadow-button: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
    --bv-shadow-button-pressed: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
    --bv-shadow-field: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    --bv-shadow-field-focus: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px var(--bv-color-focus-glow);
    --bv-shadow-field-error-focus: 0 0 6px var(--bv-color-error-glow);
    --bv-shadow-navbar: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
    --bv-shadow-pagination: 0 1px 2px rgba(0, 0, 0, 0.05);
    --bv-shadow-well: inset 0 1px 1px rgba(0, 0, 0, 0.05);
    --bv-shadow-progress: inset 0 1px 2px rgba(0, 0, 0, 0.1);
    --bv-shadow-progress-bar: inset 0 0 0 1px rgba(0, 0, 0, 0.1), inset 0 -1px 0 rgba(0, 0, 0, 0.15);

    /* Text emboss */
    --bv-emboss-light: 0 1px 1px rgba(255, 255, 255, 0.75);
    --bv-emboss-soft: 0 1px 0 rgba(255, 255, 255, 0.5);
    --bv-emboss-dark: 0 -1px 0 rgba(0, 0, 0, 0.25);

    /* Motion: color, background and shadow only */
    --bv-duration-fast: 100ms;
    --bv-duration: 150ms;
    --bv-duration-slow: 200ms;
    --bv-ease: linear;
  }
}


/* ==========================================================================
   Base: text
   ========================================================================== */

@layer bevel.base {
  /* 18px lines at 13px, as a ratio rather than a length, so text an app sets
     larger keeps proportional leading instead of inheriting a fixed 18px.
     Long words, paths and hashes break before they widen the page. */
  :where(body) {
    margin: 0;
    font-family: var(--bv-font-sans);
    font-size: var(--bv-font-size);
    line-height: 1.3847;
    color: var(--bv-color-text);
    overflow-wrap: break-word;
    background-color: var(--bv-color-surface);
  }

  /* About 70 characters a line at any text size. */
  :where(p) {
    max-inline-size: 56ch;
    margin-block: 0 var(--bv-space-3);
  }

  /* Every link keeps a faint underline, so it doesn't rely on color alone:
     the link blue is under 3:1 against body text (WCAG 1.4.1). Navbar links,
     the brand and link buttons turn it off. */
  :where(a) {
    color: var(--bv-color-link);
    text-decoration-line: underline;
    text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
    transition: color var(--bv-duration) var(--bv-ease);
  }

  /* Hover styles only where there's a pointer that hovers: on touch, :hover
     sticks after a tap until the next tap elsewhere. */
  @media (hover: hover) {
    :where(a:hover) {
      color: var(--bv-color-link-hover);
      text-decoration-color: currentColor;
    }
  }

  /* One focus ring for everything that can take focus. Components that need
     it inside their own box change only the offset. */
  :where(:focus-visible) {
    outline: 2px solid var(--bv-color-focus);
    outline-offset: 1px;
  }

  /* A heading sits half a line above what it introduces and a full line below
     whatever came before it, so it always reads with the block under it. At
     the top of a column, alert or well there's nothing above it, so it gets
     no space there and lines up with its neighbours. */
  :where(h1, h2, h3, h4, h5, h6) {
    margin-block: 0 var(--bv-space-3);
    font-weight: 700;
    color: var(--bv-color-text);
    text-rendering: optimizeLegibility;
  }

  :where(h1, h2, h3, h4, h5, h6):where(:not(:first-child)) {
    margin-block-start: var(--bv-space-5);
  }

  :where(h1) { font-size: 1.875rem; line-height: 2.25rem; }
  :where(h2) { font-size: 1.5rem; line-height: 2.25rem; }
  :where(h3) { font-size: 1.125rem; line-height: 1.6875rem; }
  :where(h4) { font-size: 0.875rem; line-height: 1.125rem; }
  :where(h5) { font-size: 0.75rem; line-height: 1.125rem; }

  :where(h6) {
    font-size: 0.6875rem;
    line-height: 1.125rem;
    color: var(--bv-color-muted);
    text-transform: uppercase;
  }

  :where(h1 small, h2 small, h3 small) {
    font-size: 1.125rem;
    font-weight: 400;
    color: var(--bv-color-muted);
  }

  :where(h3 small) {
    font-size: 0.875rem;
  }

  /* 2.0 asked for 200, which today maps to the hairline Thin cut. */
  :where(.lead) {
    margin-block-end: var(--bv-space-5);
    font-size: 1.25rem;
    font-weight: 300;
    line-height: 1.6875rem;
  }

  :where(strong, b) {
    font-weight: 700;
  }

  /* Outside headings, small keeps the surrounding size, as in 2.0. */
  :where(small) {
    font-size: 100%;
  }

  :where(code, pre) {
    font-family: var(--bv-font-mono);
  }

  /* line-height 1 keeps a line with inline code at 18px. At the inherited
     18px, the mono font's taller metrics stretch it to 18.5px in Firefox and
     WebKit. Inside pre, the pre's own line height still sets each line. */
  :where(code) {
    padding: 0.125rem 0.25rem;
    font-size: 0.75rem;
    line-height: 1;
    color: var(--bv-color-code-text);
    background-color: var(--bv-color-code-bg);
    border: 1px solid var(--bv-color-code-border);
    border-radius: var(--bv-radius-sm);
  }

  :where(pre) {
    display: block;
    padding: 0.5rem;
    margin-block: 0 var(--bv-space-3);
    font-size: 0.75rem;
    line-height: var(--bv-line-height);
    color: var(--bv-color-text);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    background-color: var(--bv-color-surface-alt);
    border: 1px solid rgba(0, 0, 0, 0.15);
    border-radius: var(--bv-radius);
  }

  :where(pre code) {
    padding: 0;
    font-size: inherit;
    color: inherit;
    background-color: transparent;
    border: 0;
  }

  /* 2.0's etched line: a soft rule over a white one. */
  :where(hr) {
    margin-block: var(--bv-space-5);
    margin-inline: 0;
    border: 0;
    border-block-start: 1px solid var(--bv-color-border-soft);
    border-block-end: 1px solid var(--bv-color-surface);
  }
}


/* ==========================================================================
   Base: form controls
   A bare field already looks right; classes add grouping, help and errors.
   ========================================================================== */

@layer bevel.base {
  :where(label) {
    display: block;
    margin-block-end: var(--bv-space-2);
    font-size: var(--bv-font-size);
    font-weight: 400;
    line-height: var(--bv-line-height);
    color: var(--bv-color-text);
  }

  /* A fieldset groups controls, such as a set of radios, without drawing a
     box; its legend reads like a label. */
  :where(fieldset) {
    min-inline-size: 0;
    padding: 0;
    margin: 0;
    border: 0;
  }

  :where(legend) {
    padding: 0;
    margin-block-end: var(--bv-space-2);
    font-size: var(--bv-font-size);
    line-height: var(--bv-line-height);
    color: var(--bv-color-text);
  }

  :where(
    input:not([type]),
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="search"],
    input[type="number"],
    input[type="url"],
    input[type="tel"],
    input[type="date"],
    input[type="datetime-local"],
    input[type="month"],
    input[type="week"],
    input[type="time"],
    select,
    textarea
  ) {
    display: block;
    width: 100%;
    max-width: 17.5rem;
    height: 1.75rem;
    padding: 0.25rem 0.375rem;
    margin: 0;
    font-family: inherit;
    font-size: var(--bv-font-size);
    line-height: var(--bv-line-height);
    color: var(--bv-color-input-text);
    background-color: var(--bv-color-surface);
    border: 1px solid var(--bv-color-border-strong);
    border-radius: var(--bv-radius-sm);
    box-shadow: var(--bv-shadow-field);
    transition:
      border-color var(--bv-duration-slow) var(--bv-ease),
      box-shadow var(--bv-duration-slow) var(--bv-ease);
  }

  /* The native arrow stays. */
  :where(select) {
    padding-block: 0.1875rem;
  }

  /* A list box shows its rows, not one 28px line of them. */
  :where(select[multiple], select[size]) {
    height: auto;
  }

  :where(textarea) {
    height: auto;
    min-height: 5.125rem;
  }

  /* Not yet Widely available; browsers without it keep their own resizing. */
  @supports (resize: vertical) {
    :where(textarea) {
      resize: vertical;
    }
  }

  :where(input, textarea)::placeholder {
    color: var(--bv-color-muted);
    opacity: 1;
  }

  :where(input, select, textarea):where(:disabled, [readonly]) {
    background-color: var(--bv-color-surface-alt);
    border-color: var(--bv-color-border);
  }

  :where(input, select, textarea):where(:disabled) {
    cursor: not-allowed;
  }

  /* Text fields only, so checkboxes and submit inputs keep the focus ring.
     The border and glow replace the outline; a transparent outline still
     shows in forced-colors mode, where shadows are dropped. */
  :where(
    input:not([type]),
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="search"],
    input[type="number"],
    input[type="url"],
    input[type="tel"],
    input[type="date"],
    input[type="datetime-local"],
    input[type="month"],
    input[type="week"],
    input[type="time"],
    select,
    textarea
  ):where(:focus) {
    border-color: var(--bv-color-focus);
    outline: 2px solid transparent;
    outline-offset: 0;
    box-shadow: var(--bv-shadow-field-focus);
  }

  /* Not yet Widely available; browsers without it keep their native tint. */
  @supports (accent-color: auto) {
    :where(input[type="checkbox"], input[type="radio"]) {
      accent-color: var(--bv-color-link);
    }
  }
}


/* ==========================================================================
   Layout
   ========================================================================== */

@layer bevel.layout {
  /* Max width is the content width plus 20px of padding each side. */
  .container {
    margin-inline: auto;
    padding-inline: var(--bv-space-6);
  }

  @media (width >= 768px) {
    .container { max-width: 764px; }
  }

  @media (width >= 980px) {
    .container { max-width: 980px; }
  }

  @media (width >= 1200px) {
    .container { max-width: 1210px; }
  }

  /* Equal columns, as many as fit at 220px or wider. A row ends with one
     rhythm line, like a table or an alert; see Utilities for why that holds
     whatever the columns end with. */
  .row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    gap: var(--bv-space-5) var(--bv-space-6);
    margin-block-end: var(--bv-space-5);
  }

  /* Fixed counts from 768px up; one column below. At the 940px container
     these give 2.0's span6, span4 and span3 widths. */
  .cols-2,
  .cols-3,
  .cols-4 {
    grid-template-columns: minmax(0, 1fr);
  }

  @media (width >= 768px) {
    .cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  }

  .section {
    padding-block-start: var(--bv-space-8);
  }

  .section:first-child {
    padding-block-start: var(--bv-space-5);
  }

  .page-header {
    padding-block-end: 1.0625rem;
    margin-block: var(--bv-space-5);
    border-block-end: 1px solid var(--bv-color-border-soft);
  }

  /* The header's padding and rule set the space around its title. */
  .page-header :where(h1, h2, h3, h4, h5, h6) {
    margin: 0;
  }

  .page-header :where(h1) {
    font-size: 2.25rem;
    line-height: 2.5rem;
  }
}


/* ==========================================================================
   Navbar
   ========================================================================== */

@layer bevel.components {
  /* The first thing in the page: off-screen until it takes keyboard focus,
     then over the top-left of the bar, so keyboard users can jump past the
     navbar to the page's main content. */
  .skip-link {
    position: absolute;
    inset-block-start: 0.375rem;
    inset-inline-start: -999rem;
    z-index: 1031;
    padding: var(--bv-space-1) 0.625rem;
    color: var(--bv-color-link);
    background-color: var(--bv-color-surface);
    border-radius: var(--bv-radius);
    box-shadow: var(--bv-shadow-navbar);
  }

  .skip-link:focus {
    inset-inline-start: var(--bv-space-6);
  }

  .navbar-inner {
    min-height: 2.5rem;
    background-color: var(--bv-color-navbar);
    background-image: linear-gradient(var(--bv-color-navbar-top), var(--bv-color-navbar-bottom));
    background-repeat: no-repeat;
    box-shadow: var(--bv-shadow-navbar);
  }

  /* Stays at the top while the page scrolls under it, as in the 2.0 docs.
     Below 768px the links wrap onto more rows, so the bar scrolls away
     instead of covering the top of a small screen. */
  @media (width >= 768px) {
    .navbar-sticky {
      position: sticky;
      inset-block-start: 0;
      z-index: 1030;
    }

    /* Anchor jumps and keyboard focus stop below the bar, never under it
       (WCAG 2.4.11). */
    :where(html:has(.navbar-sticky)) {
      scroll-padding-block-start: calc(2.5rem + var(--bv-space-5));
    }
  }

  .navbar .container {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
  }

  .nav {
    display: flex;
    flex-wrap: wrap;
  }

  .nav > :where(a) {
    display: block;
    padding: 0.625rem 0.625rem 0.6875rem;
    font-size: var(--bv-font-size);
    line-height: 1.1875rem;
    color: var(--bv-color-navbar-link);
    text-decoration: none;
    text-shadow: var(--bv-emboss-dark);
    transition: color var(--bv-duration) var(--bv-ease);
  }

  @media (hover: hover) {
    .nav > :where(a):hover {
      color: var(--bv-color-navbar-link-active);
    }
  }

  /* White on the dark tab, plus a 3px bar along the bottom, so the current
     page doesn't rely on brightness alone; a hovered link turns white too.
     The bar takes its height from the bottom padding: the link stays 40px. */
  .nav > :where(a):is(.active, [aria-current="page"]) {
    padding-block-end: calc(0.6875rem - 3px);
    color: var(--bv-color-navbar-link-active);
    background-color: var(--bv-color-navbar-bottom);
    border-block-end: 3px solid var(--bv-color-navbar-current);
  }

  /* Keep the ring inside the bar. */
  .nav > :where(a):focus-visible,
  .brand:focus-visible {
    outline-offset: -2px;
  }

  /* 1px of shadow and 1px of highlight; hidden once links start to wrap. */
  .divider-vertical {
    display: none;
    box-sizing: content-box;
    width: 1px;
    margin-inline: var(--bv-space-3);
    background-color: var(--bv-color-navbar-bottom);
    border-inline-end: 1px solid var(--bv-color-navbar-top);
  }

  @media (width >= 768px) {
    .divider-vertical { display: block; }
  }

  /* Source order picks the side: first in the bar, the brand sits on the
     left; after the links, it is pushed to the right. As in 2.0, padding on
     both sides and a negative margin on the outer one keep the text on the
     content edge while leaving room for the focus ring inside the box. */
  .brand {
    display: block;
    padding-block: 0.5rem 0.625rem;
    padding-inline: 1.25rem;
    margin-inline-start: -1.25rem;
    font-size: 1.25rem;
    font-weight: 200;
    line-height: 1.375rem;
    color: var(--bv-color-brand);
    text-decoration: none;
    text-shadow: var(--bv-emboss-dark);
  }

  .nav ~ .brand {
    margin-inline: auto -1.25rem;
  }

  /* Takes the free space and sets its links at the far end, which pushes the
     group, and everything after it, to the right. Growing rather than an
     auto margin leaves a brand after it flush against the links, and still
     pushed right when it wraps onto a row of its own. */
  .nav-end {
    flex-grow: 1;
    justify-content: flex-end;
  }
}


/* ==========================================================================
   Buttons
   Variants and sizes only reassign the --bv-btn-* variables.
   ========================================================================== */

@layer bevel.components {
  .btn {
    --bv-btn-color: var(--bv-color-text);
    --bv-btn-emboss: var(--bv-emboss-light);
    --bv-btn-gradient: linear-gradient(#FFFFFF, #FFFFFF 25%, #E6E6E6);
    --bv-btn-bg: #FAFAFA;
    --bv-btn-bg-hover: #E6E6E6;
    --bv-btn-bg-active: #E6E6E6;
    --bv-btn-border: var(--bv-color-border-strong);
    --bv-btn-border-bottom: var(--bv-color-border-bottom);
    --bv-btn-padding: 0.25rem 0.625rem;
    --bv-btn-font-size: var(--bv-font-size);
    --bv-btn-line-height: var(--bv-line-height);
    --bv-btn-radius: var(--bv-radius);

    display: inline-flex;
    gap: var(--bv-space-2);
    align-items: center;
    justify-content: center;
    padding: var(--bv-btn-padding);
    margin: 0;
    font-family: inherit;
    font-size: var(--bv-btn-font-size);
    font-weight: 400;
    line-height: var(--bv-btn-line-height);
    color: var(--bv-btn-color);
    text-align: center;
    text-decoration: none;
    text-shadow: var(--bv-btn-emboss);
    vertical-align: middle;
    cursor: pointer;
    background-color: var(--bv-btn-bg);
    background-image: var(--bv-btn-gradient);
    background-repeat: no-repeat;
    border: 1px solid var(--bv-btn-border);
    border-block-end-color: var(--bv-btn-border-bottom);
    border-radius: var(--bv-btn-radius);
    box-shadow: var(--bv-shadow-button);
    /* Leaving hover: slide the gradient back down, and keep the hover fill
       under it until the gradient covers it again. Swapping the fill at once
       would show the rest fill as a strip along the bottom, wiping from top
       to bottom. */
    transition:
      background-position var(--bv-duration-fast) var(--bv-ease),
      background-color 0s var(--bv-duration-fast);
  }

  /* Slide the gradient up to show the hover fill along the bottom. The fill
     changes at once: it matches the gradient's last stop, so the slide is
     seamless. Pointers that hover only: on touch it would stick after a tap. */
  @media (hover: hover) {
    .btn:hover {
      background-color: var(--bv-btn-bg-hover);
      background-position: 0 -15px;
      transition: background-position var(--bv-duration-fast) var(--bv-ease);
    }
  }

  .btn:is(:active, .active, [aria-pressed="true"]) {
    background-color: var(--bv-btn-bg-active);
    background-image: none;
    box-shadow: var(--bv-shadow-button-pressed);
  }

  /* Last, so a disabled button never shows hover or press. */
  .btn:is(:disabled, .disabled, [aria-disabled="true"]) {
    cursor: not-allowed;
    background-color: var(--bv-btn-bg);
    background-image: none;
    box-shadow: none;
    opacity: 0.65;
  }

  .btn-primary,
  .btn-danger {
    --bv-btn-color: #FFFFFF;
    --bv-btn-emboss: var(--bv-emboss-dark);
    --bv-btn-border: rgba(0, 0, 0, 0.1);
    --bv-btn-border-bottom: rgba(0, 0, 0, 0.25);
  }

  .btn-primary {
    --bv-btn-gradient: linear-gradient(var(--bv-color-primary-top), var(--bv-color-primary-bottom));
    --bv-btn-bg: var(--bv-color-primary);
    --bv-btn-bg-hover: var(--bv-color-primary-bottom);
    --bv-btn-bg-active: var(--bv-color-primary-active);
  }

  .btn-danger {
    --bv-btn-gradient: linear-gradient(var(--bv-color-danger-top), var(--bv-color-danger-bottom));
    --bv-btn-bg: var(--bv-color-danger);
    --bv-btn-bg-hover: var(--bv-color-danger-bottom);
    --bv-btn-bg-active: var(--bv-color-danger-active);
  }

  /* Both sizes keep the 28px default height; large is 40px. */
  .btn-small {
    --bv-btn-padding: 0.3125rem 0.5625rem;
    --bv-btn-font-size: 0.6875rem;
    --bv-btn-line-height: 1rem;
  }

  .btn-large {
    --bv-btn-padding: 0.5625rem 0.875rem;
    --bv-btn-font-size: 0.9375rem;
    --bv-btn-line-height: 1.25rem;
    --bv-btn-radius: var(--bv-radius-lg);
  }

  .btn-group {
    display: inline-flex;
    vertical-align: middle;
  }

  .btn-group > :where(.btn + .btn) {
    margin-inline-start: -1px;
  }

  .btn-group > :where(.btn:not(:first-child)) {
    border-start-start-radius: 0;
    border-end-start-radius: 0;
  }

  .btn-group > :where(.btn:not(:last-child)) {
    border-start-end-radius: 0;
    border-end-end-radius: 0;
  }

  /* Lift the hovered or focused button so its whole border shows. */
  .btn-group > :where(.btn):is(:hover, :focus-visible) {
    z-index: 1;
  }

  .btn-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
    align-items: center;
    margin-block-end: var(--bv-space-5);
  }
}


/* ==========================================================================
   Forms
   ========================================================================== */

@layer bevel.components {
  .control-group {
    margin-block-end: var(--bv-space-5);
  }

  .help-block {
    display: block;
    margin-block: var(--bv-space-2) 0;
    font-size: var(--bv-font-size);
    line-height: var(--bv-line-height);
    color: var(--bv-color-muted);
  }

  .input-block {
    max-width: none;
  }

  .input-small {
    max-width: 5.625rem;
  }

  /* A field with a fixed prefix or suffix, such as $ or MB. The add-on's
     place in the markup picks its side, so both 2.x class names do the same
     thing. The field keeps its own width and gives way on a narrow screen. */
  .input-prepend,
  .input-append {
    display: flex;
  }

  .input-prepend > :where(input, select),
  .input-append > :where(input, select) {
    min-width: 0;
  }

  /* Over the add-on beside it, so its glow isn't cut off. */
  .input-prepend > :where(input, select):focus,
  .input-append > :where(input, select):focus {
    z-index: 1;
  }

  /* Square at least: 2.0's 16px minimum plus padding and border. */
  .add-on {
    flex-shrink: 0;
    min-width: 1.75rem;
    padding: var(--bv-space-1) var(--bv-space-2);
    font-size: var(--bv-font-size);
    line-height: var(--bv-line-height);
    color: var(--bv-color-muted);
    text-align: center;
    text-shadow: var(--bv-emboss-light);
    white-space: nowrap;
    background-color: var(--bv-color-surface-alt);
    border: 1px solid var(--bv-color-border-strong);
    border-radius: var(--bv-radius-sm);
  }

  /* One line between the add-on and the field: the add-on gives up its
     side, and the joined corners are square. */
  .add-on:first-child {
    border-inline-end-width: 0;
  }

  .add-on:last-child {
    border-inline-start-width: 0;
  }

  .input-prepend > :where(:not(:first-child)),
  .input-append > :where(:not(:first-child)) {
    border-start-start-radius: 0;
    border-end-start-radius: 0;
  }

  .input-prepend > :where(:not(:last-child)),
  .input-append > :where(:not(:last-child)) {
    border-start-end-radius: 0;
    border-end-end-radius: 0;
  }

  .checkbox,
  .radio {
    display: flex;
    gap: 0.375rem;
    align-items: flex-start;
    width: fit-content;
    max-width: 100%;
    margin-block: 0;
  }

  /* 6px, not 2.0's 5px, so stacked controls sit 24px apart (WCAG 2.5.8). */
  :is(.checkbox, .radio) + :is(.checkbox, .radio) {
    margin-block-start: 0.375rem;
  }

  /* Centre the 13px control on the first 18px line of text. */
  .checkbox > :where(input),
  .radio > :where(input) {
    flex-shrink: 0;
    margin: calc((var(--bv-line-height) - 13px) / 2) 0 0;
  }

  .control-group.error :where(label, legend, .help-block) {
    color: var(--bv-color-error);
  }

  .control-group.error :where(input:not(.btn), select, textarea),
  :where(input, select, textarea)[aria-invalid="true"] {
    color: var(--bv-color-error);
    border-color: var(--bv-color-error-border);
  }

  .control-group.error :where(input:not(.btn):focus, select:focus, textarea:focus),
  :where(input, select, textarea)[aria-invalid="true"]:focus {
    border-color: var(--bv-color-error-focus);
    box-shadow: var(--bv-shadow-field-error-focus);
  }

  /* The error alert's tint, so the text keeps 4.5:1 on it. */
  .control-group.error :where(.add-on) {
    color: var(--bv-alert-error-text);
    background-color: var(--bv-alert-error-bg);
    border-color: var(--bv-color-error-border);
  }

  .form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--bv-space-2);
    align-items: center;
    padding: 1.0625rem 1.25rem 1.125rem;
    margin-block: var(--bv-space-5);
    background-color: var(--bv-color-surface-alt);
    border-block-start: 1px solid var(--bv-color-border);
  }
}


/* ==========================================================================
   Tables
   ========================================================================== */

@layer bevel.components {
  .table {
    --bv-table-cell-padding: 0.5rem;

    width: 100%;
    margin-block-end: var(--bv-space-5);
    border-collapse: separate;
    border-spacing: 0;
  }

  .table :where(th, td) {
    padding: var(--bv-table-cell-padding);
    font-size: var(--bv-font-size);
    font-variant-numeric: tabular-nums;
    line-height: var(--bv-line-height);
    text-align: start;
    vertical-align: middle;
    border-block-start: 1px solid var(--bv-color-border);
  }

  .table :where(th) {
    font-weight: 700;
  }

  .table :where(thead th) {
    vertical-align: bottom;
  }

  /* The table's first row has no rule above it. */
  .table :where(thead, tbody:first-child, caption + tbody) > :where(tr:first-child) > :where(th, td) {
    border-block-start: 0;
  }

  .table :where(tbody th, tbody td) {
    transition: background-color var(--bv-duration-fast) var(--bv-ease);
  }

  .table-striped :where(tbody > tr:nth-child(odd)) > :where(th, td) {
    background-color: var(--bv-color-stripe);
  }

  /* Higher than the stripe, so hover always wins. Pointers that hover only:
     on touch, a tapped row would stay grey. */
  @media (hover: hover) {
    .table :where(tbody > tr):hover > :where(th, td) {
      background-color: var(--bv-color-surface-alt);
    }
  }

  .table-bordered {
    border: 1px solid var(--bv-color-border);
    border-radius: var(--bv-radius);
  }

  .table-bordered :where(th, td) + :where(th, td) {
    border-inline-start: 1px solid var(--bv-color-border);
  }

  /* Round the corner cells too, so stripes and hover stay inside the edge. */
  .table-bordered :where(thead, tbody:first-child, caption + tbody) > :where(tr:first-child) > :where(:first-child) {
    border-start-start-radius: calc(var(--bv-radius) - 1px);
  }

  .table-bordered :where(thead, tbody:first-child, caption + tbody) > :where(tr:first-child) > :where(:last-child) {
    border-start-end-radius: calc(var(--bv-radius) - 1px);
  }

  .table-bordered :where(tbody:last-child, tfoot:last-child) > :where(tr:last-child) > :where(:first-child) {
    border-end-start-radius: calc(var(--bv-radius) - 1px);
  }

  .table-bordered :where(tbody:last-child, tfoot:last-child) > :where(tr:last-child) > :where(:last-child) {
    border-end-end-radius: calc(var(--bv-radius) - 1px);
  }

  .table-condensed {
    --bv-table-cell-padding: 0.25rem 0.3125rem;
  }
}


/* ==========================================================================
   Alerts
   Variants only reassign the --bv-alert-* variables.
   ========================================================================== */

@layer bevel.components {
  /* The 35px end padding leaves room for a close button later. */
  .alert {
    --bv-alert-bg: var(--bv-alert-warning-bg);
    --bv-alert-border: var(--bv-alert-warning-border);
    --bv-alert-text: var(--bv-alert-warning-text);

    padding-block: 0.5rem;
    padding-inline: var(--bv-space-4) 2.1875rem;
    margin-block-end: var(--bv-space-5);
    font-size: var(--bv-font-size);
    line-height: var(--bv-line-height);
    color: var(--bv-alert-text);
    text-shadow: var(--bv-emboss-soft);
    background-color: var(--bv-alert-bg);
    border: 1px solid var(--bv-alert-border);
    border-radius: var(--bv-radius);
  }

  .alert-error {
    --bv-alert-bg: var(--bv-alert-error-bg);
    --bv-alert-border: var(--bv-alert-error-border);
    --bv-alert-text: var(--bv-alert-error-text);
  }

  .alert-success {
    --bv-alert-bg: var(--bv-alert-success-bg);
    --bv-alert-border: var(--bv-alert-success-border);
    --bv-alert-text: var(--bv-alert-success-text);
  }

  .alert-info {
    --bv-alert-bg: var(--bv-alert-info-bg);
    --bv-alert-border: var(--bv-alert-info-border);
    --bv-alert-text: var(--bv-alert-info-text);
  }

  .alert-block {
    padding-block: var(--bv-space-4);
  }

  .alert-block :where(p) {
    margin: 0;
  }

  .alert-block :where(p + p) {
    margin-block-start: var(--bv-space-3);
  }

  .alert-heading {
    margin-block-end: var(--bv-space-1);
    color: inherit;
  }
}


/* ==========================================================================
   Labels and badges
   Badges share the label's --bv-label-* variables, so one variant class
   covers both.
   ========================================================================== */

@layer bevel.components {
  /* The edge is an inset shadow, not a border, so chips keep 2.0's size. */
  .label,
  .badge {
    --bv-label-bg: var(--bv-label-default-bg);
    --bv-label-border: var(--bv-label-default-border);
    --bv-label-text: var(--bv-label-default-text);
    --bv-label-emboss: var(--bv-emboss-soft);

    display: inline-block;
    padding: 0.0625rem 0.25rem 0.125rem;
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 0.8125rem;
    color: var(--bv-label-text);
    text-shadow: var(--bv-label-emboss);
    white-space: nowrap;
    vertical-align: middle;
    background-color: var(--bv-label-bg);
    border-radius: var(--bv-radius-sm);
    box-shadow: inset 0 0 0 1px var(--bv-label-border);
  }

  .badge {
    padding: 0.0625rem 0.5625rem 0.125rem;
    font-size: 0.75rem;
    line-height: 0.875rem;
    border-radius: var(--bv-radius-pill);
  }

  .label-success,
  .badge-success {
    --bv-label-bg: var(--bv-label-success-bg);
    --bv-label-border: var(--bv-label-success-border);
    --bv-label-text: var(--bv-label-success-text);
  }

  .label-warning,
  .badge-warning {
    --bv-label-bg: var(--bv-label-warning-bg);
    --bv-label-border: var(--bv-label-warning-border);
    --bv-label-text: var(--bv-label-warning-text);
  }

  .label-important,
  .badge-important {
    --bv-label-bg: var(--bv-label-important-bg);
    --bv-label-border: var(--bv-label-important-border);
    --bv-label-text: var(--bv-label-important-text);
  }

  .label-info,
  .badge-info {
    --bv-label-bg: var(--bv-label-info-bg);
    --bv-label-border: var(--bv-label-info-border);
    --bv-label-text: var(--bv-label-info-text);
  }

  .label-inverse,
  .badge-inverse {
    --bv-label-bg: var(--bv-label-inverse-bg);
    --bv-label-border: var(--bv-label-inverse-border);
    --bv-label-text: var(--bv-label-inverse-text);
    --bv-label-emboss: var(--bv-emboss-dark);
  }
}


/* ==========================================================================
   Hero unit
   Opt in: nothing is styled until a page uses the class.
   ========================================================================== */

@layer bevel.components {
  /* Below 768px, a 20px inset and the page header's title size, so the
     heading still fits a 320px screen. 2.0 had no small-screen hero. */
  .hero-unit {
    padding: var(--bv-space-6);
    margin-block-end: 1.875rem;
    background-color: var(--bv-color-surface-alt);
    border-radius: var(--bv-radius-xl);
  }

  .hero-unit :where(h1) {
    margin: 0;
    font-size: 2.25rem;
    line-height: 2.5rem;
  }

  /* Weight 300, not 2.0's 200: see the note on .lead. */
  .hero-unit :where(p) {
    font-size: 1.125rem;
    font-weight: 300;
    line-height: 1.6875rem;
  }

  @media (width >= 768px) {
    .hero-unit {
      padding: var(--bv-space-8);
    }

    .hero-unit :where(h1) {
      font-size: 3.75rem;
      line-height: 3.75rem;
      letter-spacing: -1px;
    }
  }

  /* The 2.0 docs' 18px grid on white: a line every rhythm line, and every
     fifth vertical one darker where two layers overlap. The edge is an
     inset shadow, not a border, so the box keeps its size. */
  .hero-unit-grid {
    background-color: var(--bv-color-surface);
    background-image:
      repeating-linear-gradient(90deg, var(--bv-color-grid) 0 1px, transparent 1px calc(var(--bv-space-5) * 5)),
      repeating-linear-gradient(90deg, var(--bv-color-grid) 0 1px, transparent 1px var(--bv-space-5)),
      repeating-linear-gradient(var(--bv-color-grid) 0 1px, transparent 1px var(--bv-space-5));
    box-shadow: inset 0 0 0 1px var(--bv-color-border-soft);
  }
}


/* ==========================================================================
   Pagination
   ========================================================================== */

@layer bevel.components {
  /* Each link a 36px box, two rhythm lines, joined into one strip that wraps
     on a narrow screen. Like a table, it ends with one rhythm line and has
     none above, where 2.0 had both. */
  .pagination {
    margin-block-end: var(--bv-space-5);
  }

  .pagination :where(ul) {
    display: flex;
    flex-wrap: wrap;
    row-gap: var(--bv-space-1);
    padding: 0;
    margin: 0;
    list-style: none;
  }

  .pagination :where(li + li) {
    margin-inline-start: -1px;
  }

  .pagination :where(li) > :where(a, span) {
    display: block;
    padding: 0 0.875rem;
    font-variant-numeric: tabular-nums;
    line-height: 2.125rem;
    text-decoration: none;
    white-space: nowrap;
    background-color: var(--bv-color-surface);
    border: 1px solid var(--bv-color-border);
    box-shadow: var(--bv-shadow-pagination);
    transition: background-color var(--bv-duration-fast) var(--bv-ease);
  }

  .pagination :where(li:first-child) > :where(a, span) {
    border-start-start-radius: var(--bv-radius-sm);
    border-end-start-radius: var(--bv-radius-sm);
  }

  .pagination :where(li:last-child) > :where(a, span) {
    border-start-end-radius: var(--bv-radius-sm);
    border-end-end-radius: var(--bv-radius-sm);
  }

  @media (hover: hover) {
    .pagination :where(li > a:hover) {
      background-color: var(--bv-color-surface-alt);
    }
  }

  /* Over its neighbours, so the whole ring shows. */
  .pagination :where(li > a:focus-visible) {
    position: relative;
    z-index: 1;
  }

  /* A page you can't go to, such as Previous on the first page, or a gap
     between page numbers: a span, or a link marked disabled. */
  .pagination :where(li > span, .disabled > a, li > a[aria-disabled="true"]) {
    color: var(--bv-color-muted);
    cursor: default;
    background-color: var(--bv-color-surface);
  }

  /* The current page sinks in like a pressed button, so it doesn't rely on
     color alone. */
  .pagination :where(.active > a, .active > span, li > [aria-current="page"]) {
    color: var(--bv-color-text);
    cursor: default;
    background-color: var(--bv-color-surface-alt);
    box-shadow: var(--bv-shadow-button-pressed);
  }
}

/* ==========================================================================
   Progress bars
   Variants only reassign the --bv-progress-* variables.
   ========================================================================== */

@layer bevel.components {
  /* A recessed track one rhythm line tall; the bar's width, set inline,
     is the value. At least as wide as a small field, so it keeps its size
     in a table column with nothing else in it. */
  .progress {
    --bv-progress-top: var(--bv-progress-default-top);
    --bv-progress-bottom: var(--bv-progress-default-bottom);

    min-inline-size: 5.625rem;
    height: var(--bv-line-height);
    margin-block-end: var(--bv-space-5);
    overflow: hidden;
    background-image: linear-gradient(var(--bv-color-surface-alt), var(--bv-color-stripe));
    border-radius: var(--bv-radius);
    box-shadow: var(--bv-shadow-progress);
  }

  /* Empty until the page sets a width. 2.0 also eased the width; that moves
     layout, and a server-rendered page never changes it anyway. */
  .progress :where(.bar) {
    width: 0;
    height: 100%;
    background-image: linear-gradient(var(--bv-progress-top), var(--bv-progress-bottom));
    box-shadow: var(--bv-shadow-progress-bar);
  }

  /* 2.0's 40px stripes, laid over the bar's own gradient. */
  .progress-striped :where(.bar) {
    background-image:
      linear-gradient(135deg, rgba(255, 255, 255, 0.15) 25%, transparent 25% 50%, rgba(255, 255, 255, 0.15) 50% 75%, transparent 75%),
      linear-gradient(var(--bv-progress-top), var(--bv-progress-bottom));
    background-size: 40px 40px, auto;
  }

  /* bevel's one looping animation, for work under way. Reduced motion
     stops it, in Utilities. */
  @keyframes bv-progress-stripes {
    from { background-position: 0 0; }
    to { background-position: 40px 0; }
  }

  .progress.active :where(.bar) {
    animation: bv-progress-stripes 2s var(--bv-ease) infinite;
  }

  .progress-success {
    --bv-progress-top: var(--bv-progress-success-top);
    --bv-progress-bottom: var(--bv-progress-success-bottom);
  }

  .progress-warning {
    --bv-progress-top: var(--bv-progress-warning-top);
    --bv-progress-bottom: var(--bv-progress-warning-bottom);
  }

  .progress-danger {
    --bv-progress-top: var(--bv-progress-danger-top);
    --bv-progress-bottom: var(--bv-progress-danger-bottom);
  }

  /* In a table the row sets the spacing. */
  .table :where(.progress) {
    margin-block-end: 0;
  }
}


/* ==========================================================================
   Stats
   ========================================================================== */

@layer bevel.components {
  /* A big figure with a small label above it, for the numbers a home page
     opens with: a <dl>, with each dt and dd pair in a div when the list is
     also a .row. The figure is the h1's size at the lead's weight, two
     rhythm lines tall. */
  .stats {
    margin-block-end: var(--bv-space-5);
  }

  .stats :where(dt) {
    font-size: var(--bv-font-size);
    line-height: var(--bv-line-height);
    color: var(--bv-color-muted);
  }

  .stats :where(dd) {
    font-size: 1.875rem;
    font-weight: 300;
    line-height: 2.25rem;
    color: var(--bv-color-text);
  }

  /* A unit or the rest of a fraction, as in a heading's subtitle. */
  .stats :where(dd small) {
    font-size: 1.125rem;
    color: var(--bv-color-muted);
  }
}


/* ==========================================================================
   Wells and empty states
   ========================================================================== */

@layer bevel.components {
  /* 2.0's inset panel. Its last block drops its bottom margin, so the
     padding alone sets the space inside. */
  .well {
    padding: 1.1875rem;
    margin-block-end: var(--bv-space-5);
    background-color: var(--bv-color-surface-alt);
    border: 1px solid rgba(0, 0, 0, 0.05);
    border-radius: var(--bv-radius);
    box-shadow: var(--bv-shadow-well);
  }

  .well > :where(:last-child) {
    margin-block-end: 0;
  }

  /* In place of a list with nothing in it: what would be here, and how to
     add the first one. Two rhythm lines above and below, border included. */
  .well-empty {
    padding-block: calc(var(--bv-space-7) - 1px);
    color: var(--bv-color-muted);
    text-align: center;
  }

  .well-empty :where(p) {
    margin-inline: auto;
  }
}


/* ==========================================================================
   Utilities
   ========================================================================== */

@layer bevel.utilities {
  .muted {
    color: var(--bv-color-muted);
  }

  /* A right-aligned paragraph drops the line-length cap, so its text still
     reaches the end of the line. */
  .text-right {
    max-inline-size: none;
    text-align: end;
  }

  /* Wide tables scroll inside their own box instead of the page. */
  .table-scroll {
    overflow-x: auto;
  }

  .table-scroll :where(th, td) {
    white-space: nowrap;
  }

  /* Read by screen readers, never shown: a label the page already makes
     clear, or the words for an icon-only button. */
  .visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* A row's own margin sets the space after it, and its gap the space
     between columns, so a column and the last block in it drop their bottom
     margins; otherwise a column ending in a table, or a column that is a
     well, would add a second line. In this layer so it beats component
     margins. */
  .row > :where(*),
  .row > :where(*) > :where(:last-child) {
    margin-block-end: 0;
  }

  /* In the last layer so it beats every component transition. */
  @media (prefers-reduced-motion: reduce) {
    *,
    ::before,
    ::after {
      transition-duration: 0.01ms;
      animation-duration: 0.01ms;
      animation-iteration-count: 1;
    }
  }
}
