/* Blog listing card */
.blog .inside-article,
.archive .inside-article,
.search .inside-article {
    display: grid !important;
    grid-template-columns: 280px 1fr;
    grid-template-rows: auto auto auto;
    gap: 0 24px;
    padding: 24px;
    margin-bottom: 24px;
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
    transition: box-shadow 0.3s ease, transform 0.2s ease;
    align-items: start;
}

.blog .inside-article:hover,
.archive .inside-article:hover,
.search .inside-article:hover {
    box-shadow: 0 6px 20px rgba(0,0,0,0.12);
    transform: translateY(-2px);
}

/* Featured image left column */
.blog .inside-article > .post-image,
.archive .inside-article > .post-image,
.search .inside-article > .post-image {
    grid-column: 1;
    grid-row: 1 / -1;
    overflow: hidden;
    border-radius: 8px;
    margin: 0;
    padding: 0;
}

.blog .inside-article > .post-image img,
.archive .inside-article > .post-image img,
.search .inside-article > .post-image img {
    width: 280px;
    height: 200px;
    object-fit: cover;
    border-radius: 8px;
    display: block;
    transition: transform 0.3s ease;
}

.blog .inside-article:hover > .post-image img,
.archive .inside-article:hover > .post-image img,
.search .inside-article:hover > .post-image img {
    transform: scale(1.03);
}

/* Right column layout */
.blog .inside-article > header,
.archive .inside-article > header,
.search .inside-article > header {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
    padding: 0;
}

.blog .inside-article > .entry-summary,
.archive .inside-article > .entry-summary,
.search .inside-article > .entry-summary {
    grid-column: 2;
    grid-row: 2;
}

.blog .inside-article > footer,
.archive .inside-article > footer,
.search .inside-article > footer {
    grid-column: 2;
    display: none;
}

.blog .inside-article > .blog-post-date,
.archive .inside-article > .blog-post-date,
.search .inside-article > .blog-post-date {
    grid-column: 2;
    grid-row: 3;
}

/* Title */
.blog .inside-article .entry-title,
.archive .inside-article .entry-title,
.search .inside-article .entry-title {
    font-size: 1.1em;
    line-height: 1.4;
    margin: 0;
    padding: 0;
    font-weight: 700;
}

.blog .inside-article .entry-title a,
.archive .inside-article .entry-title a,
.search .inside-article .entry-title a {
    color: #1a1a1a;
    text-decoration: none;
    transition: color 0.2s ease;
}

/* Make entire card clickable */
.blog .inside-article,
.archive .inside-article,
.search .inside-article {
    position: relative;
    cursor: pointer;
}

.blog .inside-article .entry-title a::after,
.archive .inside-article .entry-title a::after,
.search .inside-article .entry-title a::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
}

.blog .inside-article .entry-title a:hover,
.archive .inside-article .entry-title a:hover,
.search .inside-article .entry-title a:hover {
    color: #1e73be;
}

/* Hide original meta and footer */
.blog .inside-article header .entry-meta,
.archive .inside-article header .entry-meta,
.search .inside-article header .entry-meta {
    display: none;
}

.blog .inside-article footer.entry-meta,
.archive .inside-article footer.entry-meta,
.search .inside-article footer.entry-meta {
    display: none;
}

/* Excerpt */
.blog .inside-article .entry-summary,
.archive .inside-article .entry-summary,
.search .inside-article .entry-summary {
    margin-top: 6px;
}

.blog .inside-article .entry-summary p,
.archive .inside-article .entry-summary p,
.search .inside-article .entry-summary p {
    font-size: 0.85em;
    color: #666;
    line-height: 1.6;
    margin: 0;
}

/* Date at bottom */
.blog .inside-article .blog-post-date,
.archive .inside-article .blog-post-date,
.search .inside-article .blog-post-date {
    font-size: 0.78em;
    color: #aaa;
    margin-top: 10px;
}

/* Category tag */
.blog .inside-article .blog-post-cat,
.archive .inside-article .blog-post-cat,
.search .inside-article .blog-post-cat {
    margin-left: 10px;
    padding: 2px 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    color: #888;
    font-size: 0.95em;
}

/* Page background */
body.blog .site-content,
body.archive .site-content,
body.search .site-content {
    background: #f5f7fa;
}

/* No image fallback */
.blog .inside-article:not(:has(> .post-image)),
.archive .inside-article:not(:has(> .post-image)),
.search .inside-article:not(:has(> .post-image)) {
    grid-template-columns: 1fr;
}

/* Mobile */
@media (max-width: 768px) {
    .blog .inside-article,
    .archive .inside-article,
    .search .inside-article {
        grid-template-columns: 1fr;
        grid-template-rows: auto;
        padding: 16px;
    }
    .blog .inside-article > .post-image,
    .archive .inside-article > .post-image,
    .search .inside-article > .post-image {
        grid-column: 1;
        grid-row: auto;
        margin-bottom: 14px;
    }
    .blog .inside-article > .post-image img,
    .archive .inside-article > .post-image img,
    .search .inside-article > .post-image img {
        width: 100%;
        height: auto;
        max-height: 220px;
    }
    .blog .inside-article > header,
    .archive .inside-article > header,
    .search .inside-article > header {
        grid-column: 1;
        grid-row: auto;
    }
    .blog .inside-article > .entry-summary,
    .archive .inside-article > .entry-summary,
    .search .inside-article > .entry-summary {
        grid-column: 1;
        grid-row: auto;
    }
    .blog .inside-article > .blog-post-date,
    .archive .inside-article > .blog-post-date,
    .search .inside-article > .blog-post-date {
        grid-column: 1;
        grid-row: auto;
    }
}



/* Logo size */
.site-logo img,
.custom-logo {
    max-height: 50px;
    width: auto;
}

/* Site title gradient */
.site-branding .main-title a {
    background: linear-gradient(90deg, #00d4ff, #7b2ff7);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    font-weight: 700;
}

/* Hide site description, keep title */
.site-branding .site-description {
    display: none;
}

/* Hide archive/category page header */
.archive .page-header,
.category .page-header {
    display: none;
}

/* Hide featured image on single post/page */
.single .post-image, .single .featured-image,
.page .post-image, .page .featured-image {
    display: none;
}

/* Remove author link styling */
.entry-meta .byline a,
.entry-meta .author a {
    pointer-events: none;
    color: inherit;
    text-decoration: none;
}

/* No sidebar - full width content */
#right-sidebar, .sidebar {
    display: none !important;
}
.content-area {
    width: 100% !important;
    max-width: 100% !important;
}
.site-content .content-area {
    float: none !important;
}

/* Wide tables scroll inside themselves instead of widening the page.
   Yandex flagged the site as not mobile-friendly on 2026-07-31. Measured
   2026-09-02: article tables render 530px wide inside a 375px viewport and
   push the whole document to 560px, so every article with a comparison table
   needs sideways scrolling to read. Code blocks were already fine -- their
   <pre> already carries overflow-x:auto -- so this is the whole fix.
   Scoped to narrow viewports: desktop table rendering is unaffected. */
@media (max-width: 768px) {
  .entry-content table {
    display: block;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* Comparison tables become one card per row on phones.
   The sideways-scroll fix above keeps the page from overflowing, but reading a
   six-column table by dragging it is still poor: the heading row scrolls out of
   view and nothing signals that more columns exist. Below 600px each row is
   stacked instead, with the column name (supplied by tf_stack_tables() as
   data-label) sitting beside its value. Only tables with three or more columns
   get the tf-stack class. */
@media (max-width: 600px) {
  .entry-content table.tf-stack,
  .entry-content table.tf-stack tbody,
  .entry-content table.tf-stack tr {
    display: block;
    width: 100%;
  }
  .entry-content table.tf-stack thead {
    /* Headings move into each cell, so the row itself is redundant. Clipped
       rather than display:none so it still reaches screen readers. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .entry-content table.tf-stack tr {
    margin: 0 0 16px;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    overflow: hidden;
    background: #fff;
  }
  .entry-content table.tf-stack td {
    display: flex;
    gap: 12px;
    align-items: baseline;
    padding: 9px 12px;
    border: 0;
    border-bottom: 1px solid #eef2f7;
    text-align: left;
  }
  .entry-content table.tf-stack tr td:last-child {
    border-bottom: 0;
  }
  .entry-content table.tf-stack td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 36%;
    min-width: 0;
    font-weight: 600;
    color: #475569;
    overflow-wrap: break-word;
  }
  /* The first cell is the row's subject (the provider, the model): give it the
     weight of a card title instead of a label/value pair. */
  .entry-content table.tf-stack td:first-child {
    background: #f8fafc;
    font-weight: 700;
  }
  .entry-content table.tf-stack td:first-child::before {
    display: none;
  }
}

/* Narrow screens: render a labelled table as cards, one per row.
   Sideways scrolling fixed the overflow but not the reading -- these tables
   carry up to 1166px of content, so following one row meant dragging three
   screen-widths with the column heading scrolled out of sight. Each row
   becomes a card: first cell as its title, the rest as label/value pairs.
   Only tables the PHP filter labelled (3+ columns) get this; two-column
   tables already fit and stay as they are. */
@media (max-width: 768px) {
  .entry-content table.tf-stack,
  .entry-content table.tf-stack tbody,
  .entry-content table.tf-stack tr {
    display: block;
    width: 100%;
    overflow: visible;   /* no scroll container once rows are stacked */
  }

  .entry-content table.tf-stack thead {
    /* Headings move into each cell via data-label, but stay reachable to
       screen readers and to anything parsing the table. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .entry-content table.tf-stack tr {
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    margin: 0 0 14px;
    padding: 0;
    overflow: hidden;
  }

  .entry-content table.tf-stack td {
    display: grid;
    grid-template-columns: 38% 1fr;
    gap: 10px;
    align-items: start;
    width: auto;
    border: 0;
    border-top: 1px solid #f1f5f9;
    padding: 9px 12px;
    text-align: left;
  }

  .entry-content table.tf-stack td::before {
    content: attr(data-label);
    font-weight: 600;
    color: #475569;
    overflow-wrap: anywhere;
  }

  /* The first cell is the row's subject, so it reads better as a card title
     than as another label/value pair. */
  .entry-content table.tf-stack td:first-child {
    display: block;
    background: #f8fafc;
    border-top: 0;
    font-weight: 700;
    padding: 10px 12px;
  }
  .entry-content table.tf-stack td:first-child::before {
    content: none;
  }

  /* Cells hold code samples and long vendor strings; let them wrap rather
     than reintroduce the overflow this is meant to remove. */
  .entry-content table.tf-stack td,
  .entry-content table.tf-stack td code {
    overflow-wrap: anywhere;
  }
}

/* Value wrapper for stacked tables. grid makes every child of the <td> its own
   grid item, so a cell containing an emoji image plus text was splitting into
   two cells and dropping the text to the next line. tf_stack_tables() now wraps
   the value so grid sees only ::before and this span. The first column is the
   card heading and takes no label, so its wrapper stays transparent. */
@media (max-width: 600px) {
  .entry-content table.tf-stack td > .tf-v { display: block; min-width: 0; }
  .entry-content table.tf-stack td:first-child > .tf-v { display: contents; }
}

/* Code blocks wrap on phones instead of scrolling sideways.
   Measured 2026-09-03 at 375px: a <pre> is 315px wide and its content runs to
   404-560px, so every code block on an article needed a sideways drag and the
   visible portion cut off mid-string -- on a page whose whole point is the
   exact error text, the identifying part of the message was the part you could
   not see. Wrapping keeps newlines (pre-wrap) and breaks the long unbroken
   runs that URLs and JSON produce. Desktop keeps the scroll container. */
@media (max-width: 600px) {
  .entry-content pre {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    word-break: break-word;
    /* One notch smaller buys ~6 characters a line without hurting legibility. */
    font-size: 0.82em;
    line-height: 1.55;
  }
  .entry-content pre code {
    white-space: inherit;
    overflow-wrap: inherit;
    word-break: inherit;
  }
  /* Inline code in running text: break rather than push the paragraph wide. */
  .entry-content p > code,
  .entry-content li > code,
  .entry-content td code {
    overflow-wrap: anywhere;
  }
}

/* 列表卡片的分类标签:blog-post-cat 永不断行,有更新日期时另起一行。
   它是个带 padding 和边框的 <span>,默认是 inline —— 行尾放不下时会从词中间
   断开,药丸边框被切成两半("AI" 留在上行,"Tools" 掉到下行)。有 Updated
   日期时这一行显著变长,手机上必然触发。 */
.blog .inside-article .blog-post-cat,
.archive .inside-article .blog-post-cat,
.search .inside-article .blog-post-cat {
    display: inline-block;
    white-space: nowrap;
    vertical-align: middle;
}

/* 有 Updated 时把标签放到独立一行。:has() 判断兄弟节点里有没有更新日期,
   不需要改 PHP;老浏览器不支持就退回上面的 inline-block —— 依然不会断裂,
   只是不换行,是可接受的降级。 */
@media (max-width: 768px) {
    .blog .inside-article .blog-post-date:has(.blog-post-updated) .blog-post-cat,
    .archive .inside-article .blog-post-date:has(.blog-post-updated) .blog-post-cat,
    .search .inside-article .blog-post-date:has(.blog-post-updated) .blog-post-cat {
        display: block;
        width: fit-content;
        margin-left: 0;
        margin-top: 9px;
    }
}

/* --- Sticky footer -------------------------------------------------------
   Short pages -- a single tool, the panel with three cards -- left the footer
   floating in the middle of the screen with blank space beneath it, because
   body is a plain block and nothing stretches to the viewport height.

   Only the header, #page and .site-footer sit in normal flow here; the
   skip-link and the tracking iframe are absolutely positioned and so are not
   flex items. That makes a flex column on body safe. #page absorbs the slack.
   --------------------------------------------------------------------- */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
body > #page {
  flex: 1 0 auto;
}
body > .site-footer {
  flex: 0 0 auto;
}
