.aside {
    border-left: 3px solid #888;
    padding: 1rem 1.5rem;
    margin: 1.5rem 0;
    background-color: rgba(0, 0, 0, 0.03);
    color: #666;
}

blockquote {
    border-left: 3px solid #888;
    padding: 1rem 1.5rem;
    margin: 1.5rem 0;
    background-color: rgba(0, 0, 0, 0.03);
    color: #666;
}

img.blog-cover-image {
  width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
  border: 1px solid lightgray;
}

img.blog-content-image {
  height: auto;
  display: block;
  margin: 0 auto;
}

/* height-driven so the logo keeps its own aspect ratio; the Honest Cheetah
   lockup is 868x177 (4.90:1), not the 5.41:1 the old fixed size assumed */
img.logo {
  height: 64px;
  width: auto;
  max-width: 100%;
}

img.blog-preview-image {
    max-height: 200px;
    width: 100%;
    object-fit: cover;
    object-position: center;
    border-bottom: 1px solid lightgray;
}

img.about-image {
  max-height: 500px;
  max-width: 500px;
}

img.certification-image {
  max-width: 167px;  
}

div.blog-preview {
    min-height: 340px;
}

:root {
  --text-outline-color: rgba(0, 0, 0, 0.2);
}

/* Duotone icons for the feature cards. Requires a Font Awesome Pro kit for the
   duotone family — see _Layout.cshtml.

   NOTE ON --fa-secondary-opacity: in FA duotone, `.fa-secondary` is the BACKDROP
   shape, not an accent. Setting it to a solid brand colour at opacity 1 paints
   an amber slab behind every glyph — it reads as an unwanted background, not as
   branding. 0.4 (FA's own default) keeps the amber as a tint and lets the icon
   read as an icon. Set it to 0 for monochrome. */
.card-icon {
  font-size: 2.5rem;
  line-height: 1;
  margin-bottom: 0.75rem;
  --fa-primary-color: #1b1b1b;
  --fa-secondary-color: #ffc107;
  --fa-primary-opacity: 1;
  --fa-secondary-opacity: 0.4;
}

.outlined-text {
  /* font-size: 2em; */
  text-shadow: -1px -1px 0 var(--text-outline-color),
    1px -1px 0 var(--text-outline-color), -1px 1px 0 var(--text-outline-color),
    1px 1px 0 var(--text-outline-color);
}

.nav-upper {
  height: 50px;
}

.nav-lower {
  height: 50px;
  margin-top: 50px;
}

slogan {
  font-style: italic;
  font-weight: 400;
}

limited-width {
  max-width: 800px;
}

/* Set the Bootstrap variable, NOT just `html`. Bootstrap 5 applies
   `body { font-family: var(--bs-body-font-family) }`, which overrides anything
   inherited from `html` — so declaring the face on `html` alone silently does
   nothing and the page renders in the system stack. (That is exactly what
   www.benday.com does today: it downloads Acumin Pro and then renders
   system-ui.) Setting the variable makes Bootstrap's own components use it too. */
:root {
  --bs-body-font-family: "acumin-pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

html {
  font-size: 14px;
  font-family: var(--bs-body-font-family);
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus,
.btn:active:focus,
.btn-link.nav-link:focus,
.form-control:focus,
.form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

html {
  position: relative;
  min-height: 100%;
}

body {
  margin-bottom: 60px;
}

.form-floating > .form-control-plaintext::placeholder,
.form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder,
.form-floating > .form-control:focus::placeholder {
  text-align: start;
}

table.md-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1.5rem;
}

table.md-table th,
table.md-table td {
  padding: 0.6rem 1rem;
  border: 1px solid #dee2e6;
  text-align: left;
}

table.md-table thead th {
  background-color: #f1f3f5;
  font-weight: 600;
}

table.md-table tbody tr:nth-child(even) {
  background-color: #f8f9fa;
}

/* Brand wordmark beside the logo mark. The mark carries no lettering, so the
   text is what actually names the site in the header. */
.wordmark {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #1b1b1b;
  white-space: nowrap;
}

/* Third-party platform marks on the product cards. Deliberately NOT amber
   duotone like .card-icon — those say "what Honest Cheetah does", these say
   "which platform this runs on". Keeping someone else's logo in our brand
   colour would misread as ours. */
.platform-icon {
  color: #1b1b1b;
  margin-right: 0.45rem;
}

/* Page hero — the benday.com treatment, reusable across pages.

   Three stacked background layers, top to bottom:
     1. a dark scrim, so white text stays legible over ANY photo
     2. the page's own photo, passed in as --hero-image
     3. the brand gradient, shown when the photo is missing or fails to load

   A page sets only its own image:
     <div class="p-5 mb-4 rounded-3 page-hero"
          style="--hero-image: url('/images/hero-github.png');">

   Omit --hero-image and the hero degrades cleanly to the brand gradient, so a
   page is never broken-looking just because its photo hasn't been made yet.

   Photos live in wwwroot/images/ (site chrome, ships with the app). Sizing:
   the hero box maxes at 1296x523 CSS px, so 2x DPR wants ~2600x1100.

   CROPPING: `cover` crops very differently per breakpoint. Desktop shows the
   full width; mobile is PORTRAIT and keeps only a narrow centre strip. Prefer
   atmospheric images. If a photo DOES have a focal subject off-centre, pull it
   back into the mobile strip with --hero-position (x only; desktop shows the
   full width so it is unaffected):
     style="--hero-image: url('...'); --hero-position: 70% center;"

   CONTRAST: a bright or busy photo can drop text below WCAG AA even though the
   average looks fine — measure the WORST patch behind the text, not the mean.
   Darken just that page with --hero-scrim-top / --hero-scrim-bottom (defaults
   0.55 / 0.30), and drop `text-opacity-75` from the lead paragraph:
     style="--hero-image: url('...'); --hero-scrim-top: .65; --hero-scrim-bottom: .45;" */
.page-hero {
  background-image:
    linear-gradient(
      rgba(0, 0, 0, var(--hero-scrim-top, 0.55)),
      rgba(0, 0, 0, var(--hero-scrim-bottom, 0.30))),
    var(--hero-image, none),
    linear-gradient(135deg, #1b1b1b 0%, #3a3a3a 55%, #8a6d0b 100%);
  background-size: cover;
  background-position: var(--hero-position, center);
  background-repeat: no-repeat;
}

/* The logo mark is ~4.9:1, so at 64px tall it's ~314px wide. Add the wordmark
   beside it and the pair overflows a 375px phone viewport — the brand name gets
   clipped mid-word. Scale both down on small screens. */
@media (max-width: 575.98px) {
  img.logo {
    height: 36px;
  }

  .wordmark {
    font-size: 1.1rem;
  }
}

/* Duotone icon inline before a section heading. Same brand colours as
   .card-icon (black linework, amber fill) but sized relative to the heading
   and baseline-aligned, rather than a block above the text. */
.heading-icon {
  font-size: 0.85em;
  margin-right: 0.5rem;
  --fa-primary-color: #1b1b1b;
  --fa-secondary-color: #ffc107;
  --fa-primary-opacity: 1;
  --fa-secondary-opacity: 0.4;
}

/* Tall screenshots — collapsed by default, full size on click.

   Most product screenshots are full-page captures, and several are 2x taller
   than they are wide. Rendered at column width they push the next paragraph
   two or three screens down. This treatment shows a preview and lets the
   reader opt into the whole thing.

   Markup is the existing figure pattern, untouched:
     <figure class="figure mb-4">
       <img src="..." class="figure-img img-fluid rounded shadow-sm border" alt="...">
       <figcaption class="figure-caption">...</figcaption>
     </figure>

   js/site.js decides per figure once the image has loaded, wraps the img in
   a .figure-clip-frame and adds the toggle button. Without JS nothing here
   applies and the figure renders exactly as before. Author controls, all on
   the <figure>:

     (none)          auto — collapse only if the rendered image is markedly
                     taller than the collapsed height (see site.js)
     figure-clip     always collapse, CROP mode: top of the image, faded out
                     at the bottom, "Show full screenshot" to expand
     figure-zoom     always collapse, SCALE mode: the whole image shrunk to
                     fit the collapsed height (so it goes narrow and centred),
                     "Enlarge" to show it at full width
     figure-noclip   never collapse
     --clip-height   override the collapsed height for one figure:
                     <figure class="figure figure-clip" style="--clip-height: 20rem;">

   The class names below are the JS contract; keep them in sync with site.js. */
.figure-clip,
.figure-zoom {
  --clip-height: min(30rem, 65vh);
}

.figure-clip-frame {
  position: relative;
  margin-bottom: 0.5rem; /* takes over .figure-img's bottom margin */
  cursor: zoom-in;
}

.figure-clip-frame .figure-img {
  display: block;
  margin-bottom: 0;
}

/* CROP mode: fixed-height window onto the top of the image, fading to the page
   background so the cut looks deliberate rather than broken. */
.figure-clip .figure-clip-frame {
  max-height: var(--clip-height);
  /* clip, not hidden: a hidden overflow box is still a scroll container, so
     focusing the toggle or find-in-page can silently scroll the image inside
     the frame and drag the fade with it. clip can't scroll. hidden stays as
     the fallback for anything too old to know clip. */
  overflow: hidden;
  overflow: clip;
  border-radius: var(--bs-border-radius);
}

.figure-clip .figure-clip-frame::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 7rem;
  background: linear-gradient(rgba(255, 255, 255, 0), var(--bs-body-bg) 85%);
  pointer-events: none;
}

/* SCALE mode: the whole image, shrunk to the collapsed height. img-fluid keeps
   max-width: 100%, so a landscape image is unaffected and a tall one narrows.
   Bootstrap's .figure is inline-block and would shrink-wrap the narrowed
   image, leaving it stuck at the left; block keeps the frame full width so
   the image centres and the caption spans the column. */
.figure-zoom {
  display: block;
}

.figure-zoom .figure-clip-frame .figure-img {
  max-height: var(--clip-height);
  width: auto;
  margin-left: auto;
  margin-right: auto;
}

/* The toggle floats over the bottom of the preview. */
.figure-clip-toggle {
  position: absolute;
  left: 50%;
  bottom: 1rem;
  transform: translateX(-50%);
  z-index: 1;
  white-space: nowrap;
}

/* Expanded. The frame stops clipping; the toggle becomes sticky so "Collapse"
   rides along the bottom of the viewport while the reader scrolls through a
   three-screen screenshot instead of waiting for them at the far end. */
.is-open .figure-clip-frame {
  max-height: none;
  overflow: visible;
  cursor: zoom-out;
}

.is-open .figure-clip-frame::after {
  display: none;
}

.figure-zoom.is-open .figure-clip-frame .figure-img {
  max-height: none;
  width: 100%;
}

.is-open .figure-clip-toggle {
  position: sticky;
  display: table; /* shrink-wrap so the sticky box is only as wide as the pill */
  left: auto;
  bottom: 1rem;
  margin: -2.75rem auto 0; /* pull it up over the bottom edge of the image */
  transform: none;
}
