/* =============================================================
   OSDR Casper – Flipper Style Override
   All customisations go here; screen.css is never modified.
   ============================================================= */

/* ── 1. IBM Plex Sans Self-hosted Font ────────────────────── */
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/themes/theme-osdr-casper/assets/fonts/ibm-plex-sans/IBMPlexSans-Regular.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

/* ── 2. Accent Colour (Ghost/Casper CSS variable) ─────────── */
:root {
  --ghost-accent-color: #d00018;
}

/* ── 3. Header – White Background, Fixed Height ───────────── */
.gh-head {
  background: #fff !important;
  border-bottom: 1px solid #e1e1e1;
  min-height: 88px;
  display: flex;
  align-items: center;
}

@media (max-width: 767px) {
  .gh-head {
    min-height: 64px;
  }
}

/* ── 4. Header Inner Layout: Left-Logo | Menu | Actions ───── */
.gh-head-inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 2.4rem;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 4vmin;
}

/* ── 5. Navigation Menu – IBM Plex Sans, Orange ───────────── */
.gh-head-menu {
  font-family: "IBM Plex Sans", Arial, sans-serif !important;
  font-weight: 500;
  font-size: 16px;
}

.gh-head-menu .nav a,
.gh-head-menu a {
  color: #d00018 !important;
  text-decoration: none;
  transition: color 0.15s ease;
}

.gh-head-menu .nav a:hover,
.gh-head-menu a:hover {
  color: #a80013 !important;
}

/* ── 6. Logo Constraints ──────────────────────────────────── */
.gh-head-logo {
  max-height: 52px;
  width: auto;
}

@media (max-width: 767px) {
  .gh-head-logo {
    max-height: 36px;
  }
}

/* ── 7. Header Text/Icon Colours on White Background ─────── */
.gh-head-actions a,
.gh-search-icon {
  color: #171717 !important;
}

/* ── 8. Body Text & Background ───────────────────────────── */
body {
  background: #fff;
  color: #171717;
}

/* ── 9. Accent-coloured Links & Highlights ───────────────── */
a {
  color: #d00018;
}

.kg-bookmark-publisher,
.article-tag {
  color: #d00018;
}

/* ── Homepage: hide the pink/accent hero banner ── */
.site-header-content {
  display: none !important;
}

/* ── Body Typography ── */
.gh-content > p,
.gh-content > ul,
.gh-content > ol,
.gh-content > blockquote {
  font-size: 20px;
  line-height: 1.6;
}

@media (max-width: 767px) {
  .gh-content > p,
  .gh-content > ul,
  .gh-content > ol,
  .gh-content > blockquote {
    font-size: 18px;
    line-height: 1.6;
  }
}

/* ── IBM Plex Sans Medium (500) ── */
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/themes/theme-osdr-casper/assets/fonts/ibm-plex-sans/IBMPlexSans-Medium.woff2") format("woff2");
}

/* ── Comment widget accent ── */
:root {
  --halo-cw-color-primary: #d00018;
  --halo-cw-color-primary-dark: #a80013;
}

/* ── Shiki / code block styling ── */
.gh-content pre,
.gh-content .shiki {
  background: #171717 !important;
  border-radius: 6px;
  font-size: 14px;
  line-height: 1.5;
}

/* ── Hyperlink card ── */
.kg-bookmark-card {
  border: 1px solid #e1e1e1;
  border-radius: 4px;
}

/* ── Mobile full-screen menu overlay ── */
@media (max-width: 767px) {
  .gh-head-open #gh-head {
    background: #fff !important;
  }
  .gh-head-open #gh-head .gh-head-menu {
    background: #fff;
  }
  .gh-head-open #gh-head .nav a {
    font-size: 36px !important;
    font-weight: 700;
    color: #d00018 !important;
    font-family: "IBM Plex Sans", Arial, sans-serif !important;
  }
  .gh-head-open #gh-head .gh-head-actions {
    background: #fff !important;
  }
  .gh-burger:before, .gh-burger:after {
    background-color: #171717 !important;
  }
}

/* ── Flipper-style black multi-column footer ── */
.osdr-footer {
  background: #000;
  color: #a4a4a4;
  margin-top: max(12vmin, 64px);
  padding: 64px 0 48px;
}

.osdr-footer-inner {
  max-width: 1200px; /* 2026-10-30: align with page content (.inner), was 1400px and hugged the edges */
}

.osdr-footer-columns {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 40px;
  margin-bottom: 48px;
}

.osdr-footer-col-title {
  color: #9a9a9a;
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 16px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.osdr-footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
}

.osdr-footer-links li {
  margin-bottom: 10px;
  padding: 0;
  line-height: 1.5;
}

.osdr-footer-links a {
  color: #a4a4a4;
  font-size: 15px;
  text-decoration: none;
  transition: color 0.15s ease;
}

.osdr-footer-links a:hover {
  color: #d00018;
}

.osdr-footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid #222;
  padding-top: 24px;
  font-size: 13px;
}

.osdr-footer-copyright {
  color: #666;
}

.osdr-footer-powered a {
  color: #666;
  text-decoration: none;
}

.osdr-footer-powered a:hover {
  color: #d00018;
}

@media (max-width: 767px) {
  .osdr-footer-columns {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  .osdr-footer-bottom {
    flex-direction: column;
    gap: 8px;
    text-align: center;
  }
}

/* ── Archive / Categories / Tags pages ── */
.osdr-archive-header {
  padding: max(8vmin, 40px) 0 max(4vmin, 24px);
}

.osdr-archive-title {
  font-size: clamp(2.8rem, 5vw, 4.8rem);
  font-weight: 700;
  color: #171717;
  margin: 0;
}

.osdr-archive-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
  padding: 0 0 max(8vmin, 48px);
}

.osdr-archive-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  border: 1px solid #e1e1e1;
  border-radius: 8px;
  text-decoration: none;
  color: #171717;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.osdr-archive-item:hover {
  border-color: #d00018;
  box-shadow: 0 2px 12px rgba(232, 128, 4, 0.1);
  color: #171717;
}

.osdr-archive-item-name {
  font-size: 17px;
  font-weight: 600;
}

.osdr-archive-item-count {
  font-size: 13px;
  color: #60757e;
}

/* Archives year grouping */
.osdr-archives-wrap {
  padding-bottom: max(8vmin, 48px);
}

.osdr-archive-year {
  margin-bottom: 48px;
}

.osdr-archive-year-title {
  font-size: 2.8rem;
  font-weight: 700;
  color: #171717;
  border-bottom: 2px solid #e1e1e1;
  padding-bottom: 12px;
  margin: 0 0 24px;
}

.osdr-archive-posts {
  list-style: none;
  padding: 0;
  margin: 0;
}

.osdr-archive-posts li {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding: 12px 0;
  border-bottom: 1px solid #f0f0f0;
}

.osdr-archive-post-date {
  font-size: 13px;
  color: #60757e;
  min-width: 60px;
  flex-shrink: 0;
}

.osdr-archive-post-title {
  font-size: 16px;
  color: #171717;
  text-decoration: none;
}

.osdr-archive-post-title:hover {
  color: #d00018;
}

/* ── Phase 4: Hide pagination on homepage (defensive CSS) ── */
/* postFinder.list(1,4) already returns only 4 items so no pagination
   is rendered; this rule is a safety net in case a parent layout ever
   injects .pagination on the home-template page. */
.home-template .pagination {
  display: none !important;
}

/* ── header logo sizing — 2026-10-30: red-block store wordmark, 48px (36px on phones) ── */
.gh-head-logo img {
  height: 48px;
  max-height: none;
  width: auto;
}
@media (max-width: 767px) {
  .gh-head-logo img { height: 36px; }
}

/* ── 2026-06-12: feature card shows the FULL cover image (no crop).
   OSDR covers carry baked-in title text; cover-cropping cuts it off.
   Grid cards keep the uniform ratio box for row alignment. ── */
/* (feature-card image rules superseded by the global no-crop rule below) */

/* ── 2026-06-12: force header logo always visible.
   Casper hides the left-logo on the home template until the page scrolls
   (it normally relies on a big logo in the site-header, which we removed).
   We keep the wordmark in the header at all times, like flipper.net. ── */
.is-head-left-logo.home-template .gh-head:not(.is-header-hidden) .gh-head-logo {
  display: flex !important;
  align-items: center;
}
.gh-head-logo {
  font-size: 0; /* hide the text fallback span; we use the image wordmark */
}

/* ── 2026-06-12: self-hosted Charis SIL (OFL) — Charter's open descendant,
   so the magazine serif looks identical on Windows/Mac/Android. ── */
@font-face {
  font-family: "Charis SIL";
  font-style: normal; font-weight: 400; font-display: swap;
  src: url("/themes/theme-osdr-casper/assets/fonts/charis/charis-sil-regular.woff2") format("woff2");
}
@font-face {
  font-family: "Charis SIL";
  font-style: italic; font-weight: 400; font-display: swap;
  src: url("/themes/theme-osdr-casper/assets/fonts/charis/charis-sil-italic.woff2") format("woff2");
}
@font-face {
  font-family: "Charis SIL";
  font-style: normal; font-weight: 700; font-display: swap;
  src: url("/themes/theme-osdr-casper/assets/fonts/charis/charis-sil-bold.woff2") format("woff2");
}
@font-face {
  font-family: "Charis SIL";
  font-style: italic; font-weight: 700; font-display: swap;
  src: url("/themes/theme-osdr-casper/assets/fonts/charis/charis-sil-bolditalic.woff2") format("woff2");
}

/* serif body type to match flipper.net's magazine feel: Charis-led stack for
   prose AND home post-card excerpts (Casper leaves excerpts sans). */
:root {
  --font-serif: "Charis SIL", Charter, Cambria, Georgia, serif;
}
.post-card-excerpt {
  font-family: var(--font-serif);
}

/* ── 2026-10-30: uniform 16:9 cover box, never crop ──
   (replaces the 06-12 "natural proportions" rule, which let a 392x768 GIF stretch a whole row)
   16:9 covers fill the box exactly; other ratios are shown whole and letterboxed on a light tint,
   so baked-in cover text is never cut and every row lines up. ── */
.post-card-image-link {
  aspect-ratio: 16 / 9;
  background: #f3f3f1;
  border-radius: 6px;
}
.post-card-image-link::after {
  display: none !important;
}
.post-card-image,
.post-card-large .post-card-image {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  object-fit: contain !important;
  background: transparent;
}
@media (min-width: 1001px) {
  .post-card-large .post-card-image-link { align-self: start; }
}

/* ── 2026-06-12: unify header layout across home & post pages ──
   Casper pulls the nav left to hug the logo ONLY on the home template
   (margin-left:-40px). Post/other pages lack that rule, so the menu drifts
   to the middle. Replicate the home behaviour on every left-logo page so the
   header looks identical everywhere. We keep Casper's grid (auto 1fr auto)
   and only normalise the menu margins. ── */
.is-head-left-logo .gh-head:not(.is-header-hidden) .gh-head-menu,
.is-head-left-logo.home-template .gh-head:not(.is-header-hidden) .gh-head-menu {
  /* 2026-10-30: was -40px, which pushed "Home" into the red wordmark. The second selector matches
     Casper's own home-only rule (.is-head-left-logo.home-template ... margin-left:-40px), which
     otherwise wins on specificity on the home page. */
  margin-left: 40px;
  margin-right: 64px;
}

/* ── T-012: article SEO lead already uses .article-excerpt; keep anti-copy parity with theme-wing ── */
article.article.copy-protected,
article.post.copy-protected {
  position: relative;
}

/* 0.2.18: only the body is unselectable; the header (title, excerpt, byline) stays copyable */
article.article.copy-protected .gh-content,
article.post.copy-protected .gh-content {
  -webkit-user-select: none;
  user-select: none;
}
article.post.copy-protected .article-header {
  -webkit-user-select: text;
  user-select: text;
}

article.article.copy-protected img,
article.post.copy-protected img {
  -webkit-user-drag: none;
  user-drag: none;
  pointer-events: none;
}

article.article.copy-protected::after,
article.post.copy-protected::after {
  content: "";
  position: absolute;
  /* 2026-10-30 (0.2.5): owner asked the watermark to stay inside the text column.
     Same width formula as Casper's .gh-canvas main column: min(720px, 100% - 2 * gap). */
  top: 0;
  bottom: 0;
  left: 50%;
  width: min(720px, calc(100% - 2 * max(4vmin, 20px)));
  width: var(--osdr-main, min(720px, calc(100% - 2 * max(4vmin, 20px)))); /* 0.2.15: follows the article column */
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 2;
  opacity: 0.1;
  /* 2026-10-30: density cut by one third (owner decision): stripe period 168px -> 252px,
     logo rows 260px -> 390px (the -sparse tile carries the extra transparent padding). */
  background-image: repeating-linear-gradient(
      -32deg,
      transparent 0,
      transparent 126px,
      rgba(208, 0, 24, 0.045) 126px,
      rgba(208, 0, 24, 0.045) 128px,
      transparent 128px,
      transparent 252px
    ),
    url("../images/osdr-watermark-logo-col.png");
  /* 0.2.7: owner wants the watermark to cover the full text width. The -col tile is the logo
     cropped tight (380x206); at 100% of a 720px column the logo spans ~660px and rows repeat
     every 390px, same density as before. */
  background-size: 560px 240px, 100% auto;
  background-position: 0 0, center top;
  background-repeat: repeat, repeat-y;
}

.copy-protect-toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  z-index: 9999;
  padding: 10px 16px;
  border-radius: 999px;
  background: rgba(23, 23, 23, 0.92);
  color: #fff;
  font-size: 14px;
  line-height: 1.4;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
}

.copy-protect-toast[hidden] {
  display: none !important;
}

/* =============================================================
   2026-10-30 tuning pass (see 06-博客主题调教-pre站/CHANGELOG.md)
   ============================================================= */

/* ── Footer: brand blurb column + tablet layout ── */
.osdr-footer-about p {
  margin: 16px 0 0;
  max-width: 300px;
  font-size: 14px;
  line-height: 1.6;
  color: #8a8a8a;
}
.osdr-footer-logo {
  display: block;
  border-radius: 10px;
}
@media (min-width: 768px) and (max-width: 1023px) {
  .osdr-footer-columns { grid-template-columns: 1fr 1fr; }
}

/* ── Home: category shortcuts + pagination ── */
.osdr-home-cats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  padding: max(5vmin, 32px) 0 max(4vmin, 24px);
  font-family: "IBM Plex Sans", Arial, sans-serif;
}
.osdr-home-cat {
  padding: 6px 14px;
  border: 1px solid #e1e1e1;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  color: #171717;
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.osdr-home-cat:hover { border-color: #d00018; color: #d00018; }
.osdr-home-cat.is-active { background: #171717; border-color: #171717; color: #fff; }

.osdr-pagination {
  display: grid;
  grid-template-columns: 1fr auto 1fr; /* keeps "Page x of y" centred with or without a prev link */
  align-items: center;
  gap: 16px;
  margin: max(6vmin, 40px) 0 0;
  padding-top: 24px;
  border-top: 1px solid #e1e1e1;
  font-family: "IBM Plex Sans", Arial, sans-serif;
  font-size: 15px;
}
.osdr-pagination a { color: #d00018; font-weight: 500; text-decoration: none; }
.osdr-page-prev { grid-column: 1; justify-self: start; }
.osdr-page-info { grid-column: 2; color: #60757e; }
.osdr-page-next { grid-column: 3; justify-self: end; }

/* ── Cards: tidy excerpt + meta ── */
.post-card-excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-card-meta { font-size: 13px; color: #60757e; }

/* ── Category / tag header ── */
.osdr-term-header { padding-bottom: max(3vmin, 16px); }
.osdr-term-kicker {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #d00018;
}
.osdr-term-desc { margin: 16px 0 0; max-width: 720px; font-size: 18px; line-height: 1.55; color: #3d3d3d; }
.osdr-term-count { margin: 12px 0 0; font-size: 14px; color: #60757e; }

/* ── Article byline: brand avatar ── */
/* 0.2.10: Casper's .author-avatar wrapper is 56px with a grey fill and a white 2px ring; a 48px
   image inside it sat top-left and left a grey crescent. The wrapper now carries the size, ring
   and white fill; the (pre-centred) icon fills it edge to edge. */
.article-byline .author-avatar {
  width: 52px;
  height: 52px;
  margin: 0;
  border: 1px solid #e1e1e1;
  background: #fff;
  overflow: hidden;
}
.article-byline .author-profile-image {
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 50%;
  background: #fff;
  object-fit: cover;
}

/* ── Article tables: scroll sideways instead of being cut off ── */
.gh-content .tableWrapper,
.gh-content > table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.gh-content table {
  font-family: "IBM Plex Sans", Arial, sans-serif;
  font-size: 16px;
}
.gh-content table td,
.gh-content table th { white-space: normal; min-width: 96px; }

/* ── Neutralise styles pasted in from Word / web pages ──
   Halo keeps inline font-family / font-size / white backgrounds from pasted text (07-27 finding).
   Fonts and sizes fall back to the theme; author-chosen text colours are intentionally kept. */
.gh-content [style*="font-family"] { font-family: inherit !important; }
.gh-content span[style*="font-size"],
.gh-content p[style*="font-size"],
.gh-content li[style*="font-size"] { font-size: inherit !important; }
.gh-content span[style*="background"],
.gh-content p[style*="background"] { background: transparent !important; }

/* ── Article images: never wider than the column ── */
.gh-content img { max-width: 100%; height: auto; }

/* ── Search widget (PluginSearchWidget 1.7): brand red instead of the plugin's default green ── */
:root {
  --halo-search-widget-primary-color: #d00018;
  --halo-search-widget-base-font-family: "IBM Plex Sans", Arial, sans-serif;
}

/* ── 2026-10-30 (0.2.4): uniform in-article images (owner request: same size within an article) ──
   Every standalone image sits in the same full-column frame. post.html tags each image by its
   ORIGINAL width (Halo stores it in the width attribute):
     >= 480px  -> .osdr-img-fill  : fills the frame width
     <  480px  -> .osdr-img-small : natural size, centred (upscaling small screenshots blurs them)
   Height is capped so tall phone screenshots / portrait photos do not take a whole screen;
   click (on the frame) opens the full-size image. */
.gh-content figure:has(> img),
.gh-content p:has(> img:only-child) {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  margin: 1.8em 0;
  padding: 10px;
  background: #f6f6f4;
  border-radius: 8px;
  cursor: zoom-in;
  box-sizing: border-box;
}
.gh-content figure > img,
.gh-content p > img:only-child {
  display: block;
  max-width: 100% !important;
  height: auto !important;
  max-height: min(560px, 70vh);
  object-fit: contain;
  border-radius: 4px;
  margin: 0 auto;
}
.gh-content img.osdr-img-fill { width: 100% !important; }
.gh-content img.osdr-img-small { width: auto !important; }

/* full-size viewer */
.osdr-lightbox {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(10, 10, 10, 0.88);
  cursor: zoom-out;
}
.osdr-lightbox img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

/* ── 2026-10-30 (0.2.5): card titles/excerpts line up across a row ──
   Titles longer than three lines are clamped; excerpts always occupy two lines; the date sits
   at the bottom so every card in a row ends on the same line. Content was also edited so titles
   stay within ~2 lines and excerpts within ~2 lines (content/patches/posts-length-20261030.json). */
.post-card-content { display: flex; flex-direction: column; flex-grow: 1; }
.post-card-content-link { flex-grow: 1; }
.post-card:not(.post-card-large) .post-card-title {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-card:not(.post-card-large) .post-card-excerpt {
  -webkit-line-clamp: 2;
  min-height: calc(2 * 1.5em);
}
.post-card-meta { margin-top: auto; padding-top: 12px; }
/* 0.2.6: in the 3-column grid a 26px title fits ~22 chars per line, so 50-56 char titles took
   3 lines next to 2-line neighbours. 22px fits ~28 chars, i.e. every normalised title in 2 lines;
   the 2-line min-height keeps excerpts starting at the same height across a row. */
@media (min-width: 768px) {
  .post-card:not(.post-card-large) .post-card-title {
    font-size: 22px;
    line-height: 1.2;
    min-height: 2.4em;
  }
}

/* ── 0.2.7: the post cover may not be wider than the text (owner request).
   Casper places .article-image on the wide grid track (720px + 2 x 240px); pin it to the text column. ── */
.article-image,
.image-wide .article-image,
.image-full .article-image,
.image-left-logo .article-image {
  grid-column: main-start / main-end !important;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}
.article-image img {
  width: 100%;
  max-width: 100%;
  height: auto;
  border-radius: 6px;
}

/* ── 0.2.8: the lead (first, large) card has room to spare — show the whole hand-written excerpt
   (owner: "as much as possible, but not overdone"): no 2/3-line clamp, slightly larger type,
   hard cap of 7 lines for unusually long excerpts; text block centred next to the cover and the
   date follows the excerpt instead of being pushed to the bottom. ── */
.post-card-large .post-card-excerpt {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 7;
  overflow: hidden;
  min-height: 0;
  font-size: 19px;
  line-height: 1.6;
  margin-top: 16px;
}
@media (min-width: 1001px) {
  .post-card-large .post-card-content { justify-content: center; }
  .post-card-large .post-card-content-link { flex-grow: 0; }
  .post-card-large .post-card-meta { margin-top: 20px; }
}
@media (max-width: 1000px) {
  .post-card-large .post-card-excerpt { -webkit-line-clamp: 5; font-size: 17px; }
}

/* ── 0.2.9: view counts (byline + cards) ── */
.byline-views,
.post-card-meta-views { white-space: nowrap; }
.post-card-meta-views .bull { margin: 0 4px; }
.post-card-meta { display: flex; align-items: center; flex-wrap: wrap; }

/* ── 0.2.12: mobile polish ──
   Casper already draws a 2px dot before every card-meta item after the first, so the extra
   bullet in the views span doubled it; its 6px inner gap also spread "140  views". */
.post-card-meta-views .bull { display: none; }
.post-card-meta > .post-card-meta-views { gap: 0.3em; } /* "views" is a bare text node: gap, not a sibling margin */
/* category chips: one swipeable row on phones instead of four wrapped rows above the first post */
@media (max-width: 767px) {
  .osdr-home-cats {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    margin: 0 calc(-1 * max(4vmin, 20px));
    padding-left: max(4vmin, 20px);
    padding-right: max(4vmin, 20px);
  }
  .osdr-home-cats::-webkit-scrollbar { display: none; }
  .osdr-home-cat { flex: 0 0 auto; font-size: 13px; padding: 5px 12px; }
}

/* ── 0.2.15 (owner: "make the article as wide as the nav bar"): on desktop the article column uses
   the same formula as the header content box — min(1200px, 100% - 2*gap) minus the header's 4vmin
   padding on each side — so text, cover, image frames and watermark line up with the logo and the
   search icon at every window width. Phones keep Casper's full-width column. ── */
@media (min-width: 768px) {
  :root { --osdr-main: calc(min(1200px, 100% - 2 * max(4vmin, 20px)) - 8vmin); }
  .gh-canvas { --main: calc(min(1200px, 100% - var(--gap) * 2) - 8vmin); }
}

/* ── 0.2.16 (owner: "tables should adapt to the window") ──
   The editor bakes fixed widths into every table (<table style="width:790px">, <col style="width:196px">),
   so tables kept the size of the author's editor window. Override them: full column width,
   auto layout, columns sized by content; long tokens (file names, SKUs) may break anywhere so a
   table never forces sideways scrolling. The wrapper keeps overflow-x as a last resort. */
.gh-content table {
  display: table !important;
  width: 100% !important;
  max-width: 100%;
  table-layout: auto !important;
}
.gh-content table col { width: auto !important; }
.gh-content table td,
.gh-content table th {
  min-width: 0 !important;
  width: auto !important;
  overflow-wrap: break-word; /* 0.2.17: was "anywhere" — it split words mid-way on phones ("Proces|sor") */
  word-break: normal;
}
.gh-content .tableWrapper { overflow-x: auto; max-width: 100%; }
@media (max-width: 767px) {
  /* phones: smaller type and padding so most tables fit; wide spec tables (5+ columns) scroll
     sideways a little inside their wrapper instead of breaking words */
  .gh-content table { font-size: 13px; line-height: 1.35; }
  .gh-content table td, .gh-content table th { padding: 5px 6px; }
}

/* 0.2.22: visually hidden but readable by crawlers and screen readers */
.osdr-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
