/*
 * LitMemo Blog — Standalone CSS
 * Self-contained — no Tailwind dependency. Serif headings, the SPA's colour tokens.
 */

/* ---- Reset & Base ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/*
 * Colour tokens. Every hex below IS an SPA token from frontend/src/index.css — the `@theme`
 * block for :root, the `.dark` block for html.dark — under the blog's own variable names.
 * DesignTokenParityTest pins each pair, so a value changed on one side only fails the build;
 * change the SPA token and copy it here (the test names the variable and both values).
 *
 * html.dark is set before first paint by the inline <script> at the top of every blog page:
 * the stored `litmemo-theme` choice wins, then the OS preference, and the fallback is dark —
 * the same order as readStoredTheme() in shared/src/lib/theme.ts, which the SPA boots with.
 */
:root {
    color-scheme: light;
    --blog-bg: #faf8f5;          /* background */
    --blog-text: #1a1a1a;        /* foreground */
    --blog-text-muted: #6b6159;  /* muted-foreground */
    --blog-primary: #7d6340;     /* primary */
    --blog-primary-fg: #ffffff;  /* primary-foreground: text on a primary-filled button */
    --blog-border: #9e8e7e;      /* border */
    --blog-card-bg: #ffffff;     /* card */
    --blog-code-bg: #f5f0ea;     /* muted: code, table heads, tag pills, tinted bands */
    --blog-font: "Swei Spring Sugar", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif;
    --blog-font-serif: "Swei Spring Sugar", Georgia, "Noto Serif TC", "PingFang TC", serif;
    --blog-max-width: 1100px;
    --blog-narrow-width: 760px;
}

html.dark {
    color-scheme: dark;
    --blog-bg: #0f0d0a;
    --blog-text: #e8e0d4;
    --blog-text-muted: #978b7b;
    --blog-primary: #c4a574;
    --blog-primary-fg: #0f0d0a;
    --blog-border: #504536;
    --blog-card-bg: #1a1610;
    --blog-code-bg: #241f18;
}

/*
 * Per-language brand face. Each locale renders in its OWN Swei Spring Sugar regional
 * variant, so Japanese kana and Simplified glyphs come from the face that actually has
 * them instead of the Traditional face's substitutes.
 *
 * The family NAMES are not interchangeable: the generator emits "Swei Spring Sugar" (tc),
 * "Swei Spring Sugar SC" and "Swei Spring Sugar JP" as three separate families
 * (scripts/app_font_slices.py FAMILIES). A page that loads the SC stylesheet but asks for
 * the tc family name renders in the system fallback and looks merely "plain" — no error,
 * no console warning.
 *
 * KEEP IN SYNC with BlogViewController.fontFamilyKey, which decides WHICH stylesheet the
 * page links, and with frontend/src/index.css, which carries the identical stacks for the
 * React apps. `<html lang>` is emitted by the Thymeleaf templates from the URL prefix
 * (zh-Hant / ja / en / zh-Hans), so these selectors and that decision share one input.
 *
 * zh-Hant uses the :root stack above (tc), matching appFonts.ts; en uses the same tc stack with the
 * Latin punctuation face in front (the html[lang="en"] block below).
 * System faces trail each stack so text still paints while the slices stream in.
 */
html[lang="ja"] {
    --blog-font: "Swei Spring Sugar JP", "Hiragino Maru Gothic ProN", "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", system-ui, sans-serif;
    --blog-font-serif: "Swei Spring Sugar JP", Georgia, "Hiragino Mincho ProN", "Noto Serif JP", serif;
}

/* English pages: "LM Latin Punctuation" (/fonts/latin-punctuation/latin-punctuation.css, linked only on
   English pages by PublicAppFonts.latinPunctuationStylesheet; U+2018-201F, U+2022, U+2026 only) in front of
   the tc stack, so curly quotes, the bullet and the ellipsis are Latin glyphs. Swei Spring Sugar is a CJK
   face and draws them full-width; CJK pages never name this family, so theirs are unchanged. */
html[lang="en"] {
    --blog-font: "LM Latin Punctuation", "Swei Spring Sugar", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif;
    --blog-font-serif: "LM Latin Punctuation", "Swei Spring Sugar", Georgia, "Noto Serif TC", "PingFang TC", serif;
}

html[lang="zh-Hans"] {
    --blog-font: "Swei Spring Sugar SC", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
    --blog-font-serif: "Swei Spring Sugar SC", Georgia, "Noto Serif SC", "PingFang SC", serif;
}

/* Arabic pages (slice S5): the Arabic faces come from /fonts/arabic/arabic-fonts.css, linked only on
   Arabic pages (PublicAppFonts.arabicStylesheet) and limited to Arabic code points by unicode-range,
   so they lead the tc stack without touching Latin or digits. Sans (Noto Sans Arabic) for the
   interface, Naskh (Noto Naskh Arabic) for the serif / reading role. Arabic gets no letter-spacing
   (tracking breaks its joining) and no slanted text (docs/ui/ar-localization-guide.md). */
html[lang="ar"] {
    --blog-font: "LM Noto Sans Arabic", "Swei Spring Sugar", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif;
    --blog-font-serif: "LM Noto Naskh Arabic", "Swei Spring Sugar", Georgia, "Noto Serif TC", "PingFang TC", serif;
}

html[lang="ar"] body * {
    /* !important: every per-component letter-spacing in this file would otherwise beat it. */
    letter-spacing: normal !important;
}

html[lang="ar"] :is(em, i, cite) {
    font-style: normal;
    font-weight: 700;
}

/* Two-line clamped descriptions. The line box comes from Swei (the Arabic faces cover no space, so
   they never set line metrics) while Arabic glyphs at 115% (arabic-fonts.css size-adjust) descend
   ~0.48em below the baseline; at 1.5–1.6 the clamp's overflow: hidden cut the tails of ي ج ر on the
   last line. 1.8 leaves 0.52em under the baseline. */
html[lang="ar"] :is(.blog-card-desc, .blog-related-card-desc) {
    line-height: 1.8;
}

html { font-size: 16px; }
body {
    font-family: var(--blog-font);
    background: var(--blog-bg);
    color: var(--blog-text);
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--blog-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- Layout ---- */
.blog-layout {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.blog-container {
    max-width: var(--blog-max-width);
    margin: 0 auto;
    padding: 0 1.5rem;
}

.blog-container-narrow {
    max-width: var(--blog-narrow-width);
}

.blog-main { flex: 1; padding: 2.5rem 0 4rem; }

/* The header is the shared SSR top bar: /site-assets/site-topbar.css (fragments/site-topbar.html). */

/* ---- Blog List ---- */
.blog-list-title {
    font-family: var(--blog-font-serif);
    font-size: 2rem;
    font-weight: 700;
    color: var(--blog-primary);
    margin-bottom: 0.5rem;
}

.blog-list-subtitle {
    color: var(--blog-text-muted);
    font-size: 1rem;
    margin-bottom: 2.5rem;
}

/* ---- Topic cluster sections ---- */
.blog-cluster-section { margin-bottom: 4rem; }
.blog-cluster-section:last-of-type { margin-bottom: 1rem; }

.blog-cluster-title {
    font-family: var(--blog-font-serif);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--blog-text);
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.blog-cluster-emoji {
    font-size: 1.5rem;
    line-height: 1;
}

.blog-cluster-desc {
    color: var(--blog-text-muted);
    font-size: 0.9375rem;
    margin-bottom: 1.25rem;
    line-height: 1.6;
}

.blog-post-list { display: flex; flex-direction: column; gap: 1rem; }

.blog-card {
    background: var(--blog-card-bg);
    border: 1px solid var(--blog-border);
    border-radius: 0.75rem;
    transition: border-color 0.2s, box-shadow 0.2s;
}
.blog-card:hover {
    border-color: var(--blog-primary);
    box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}

.blog-card-link { display: block; text-decoration: none !important; color: inherit; }

.blog-card-body { padding: 1.5rem; }

.blog-card-meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.8125rem;
    color: var(--blog-text-muted);
    margin-bottom: 0.5rem;
}

.blog-card-tags { display: flex; gap: 0.375rem; flex-wrap: wrap; }

.blog-tag {
    display: inline-block;
    padding: 0.125rem 0.5rem;
    font-size: 0.75rem;
    border-radius: 999px;
    /* muted, not accent: primary on accent measures 4.27 in the light theme (under AA 4.5 for
       this 12px text); on muted it is 4.97 light / 6.99 dark. */
    background: var(--blog-code-bg);
    color: var(--blog-primary);
}

.blog-card-title {
    font-family: var(--blog-font-serif);
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--blog-text);
    line-height: 1.4;
    margin-bottom: 0.375rem;
}

.blog-card-desc {
    font-size: 0.9375rem;
    color: var(--blog-text-muted);
    line-height: 1.6;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ---- Empty State ---- */
.blog-empty {
    text-align: center;
    padding: 4rem 0;
    color: var(--blog-text-muted);
    font-size: 1.125rem;
}

/* ---- Pagination ---- */
.blog-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 3rem;
    font-size: 0.9375rem;
}

.blog-page-link {
    color: var(--blog-primary);
    font-weight: 500;
}

.blog-page-info { color: var(--blog-text-muted); }

/* ---- Single Article ---- */
.blog-breadcrumb {
    font-size: 0.8125rem;
    color: var(--blog-text-muted);
    margin-bottom: 2rem;
}
.blog-breadcrumb a { color: var(--blog-primary); }
.blog-breadcrumb-sep { margin: 0 0.5rem; }

.blog-article-header { margin-bottom: 2.5rem; }

.blog-article-title {
    font-family: var(--blog-font-serif);
    font-size: 2rem;
    font-weight: 700;
    color: var(--blog-text);
    line-height: 1.35;
    margin-bottom: 0.75rem;
}

.blog-article-meta {
    font-size: 0.875rem;
    color: var(--blog-text-muted);
    margin-bottom: 0.75rem;
}

.blog-article-tags { display: flex; gap: 0.375rem; flex-wrap: wrap; }

/* ---- Markdown Content ---- */
.blog-content {
    font-size: 1.0625rem;
    line-height: 1.85;
    color: var(--blog-text);
}

.blog-content h1,
.blog-content h2,
.blog-content h3,
.blog-content h4,
.blog-content h5,
.blog-content h6 {
    font-family: var(--blog-font-serif);
    font-weight: 600;
    color: var(--blog-text);
    margin-top: 2em;
    margin-bottom: 0.75em;
    line-height: 1.3;
}

.blog-content h1 { font-size: 1.75rem; }
.blog-content h2 { font-size: 1.5rem; border-bottom: 1px solid var(--blog-border); padding-bottom: 0.3em; }
.blog-content h3 { font-size: 1.25rem; }
.blog-content h4 { font-size: 1.125rem; }

.blog-content p { margin-bottom: 1.25em; }

.blog-content a {
    color: var(--blog-primary);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.blog-content strong { font-weight: 600; }

.blog-content blockquote {
    border-inline-start: 3px solid var(--blog-primary);
    padding: 0.75em 1.25em;
    margin: 1.5em 0;
    background: var(--blog-code-bg);
    color: var(--blog-text-muted);
    /* Square on the start edge (where the rule is), rounded on the end edge. */
    border-start-start-radius: 0;
    border-start-end-radius: 0.375rem;
    border-end-end-radius: 0.375rem;
    border-end-start-radius: 0;
}
.blog-content blockquote p:last-child { margin-bottom: 0; }

.blog-content ul,
.blog-content ol {
    padding-inline-start: 1.5em;
    margin-bottom: 1.25em;
}
.blog-content li { margin-bottom: 0.3em; }

.blog-content code {
    font-family: "SF Mono", "Fira Code", "Consolas", monospace;
    font-size: 0.875em;
    background: var(--blog-code-bg);
    padding: 0.15em 0.4em;
    border-radius: 0.25rem;
}

.blog-content pre {
    /* Same muted surface as inline code, boxed by the border token — legible on both themes
       without a third, editor-style palette. */
    background: var(--blog-code-bg);
    color: var(--blog-text);
    border: 1px solid var(--blog-border);
    border-radius: 0.5rem;
    padding: 1.25rem;
    overflow-x: auto;
    margin: 1.5em 0;
    font-size: 0.875rem;
    line-height: 1.6;
}
.blog-content pre code {
    background: none;
    padding: 0;
    font-size: inherit;
    color: inherit;
}

/* Wrap tables in a horizontal scroll container on mobile */
.blog-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 1.5em 0;
    font-size: 0.9375rem;
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.blog-content th,
.blog-content td {
    border: 1px solid var(--blog-border);
    padding: 0.625rem 0.875rem;
    text-align: start;
    white-space: nowrap;
}
.blog-content th {
    background: var(--blog-code-bg);
    font-weight: 600;
}

.blog-content img {
    max-width: 100%;
    height: auto;
    border-radius: 0.5rem;
    margin: 1.5em 0;
}

/* Figures. The caption is real text rather than pixels baked into the image: it is
   selectable, translated with the rest of the row, and read out by a screen reader.
   The card matters most for screenshots — they arrive with their own near-white
   background, which would otherwise dissolve into the cream page with no edge. */
.blog-content figure {
    margin: 1.75em 0;
    background: var(--blog-card-bg);
    border: 1px solid var(--blog-border);
    border-radius: 0.75rem;
    padding: 0.875rem;
}

.blog-content figure img {
    margin: 0;
    border-radius: 0.375rem;
    display: block;
    width: 100%;
}

.blog-content figcaption {
    margin-top: 0.7em;
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--blog-text-muted);
    text-align: center;
}

/* Diagrams are drawn on the page's own background and carry no edge of their own,
   so a card around them would frame empty space. */
.blog-content figure.diagram {
    background: none;
    border: 0;
    padding: 0;
}

.blog-content hr {
    border: none;
    border-top: 1px solid var(--blog-border);
    margin: 2em 0;
}

/* ---- Related Posts ---- */
/* ---- FAQ ---- */
.blog-faq {
    margin-top: 3rem;
    padding-top: 2rem;
    border-top: 1px solid var(--blog-border);
}
.blog-faq-title {
    font-family: var(--blog-font-serif);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--blog-text);
    margin-bottom: 1.25rem;
}
.blog-faq-item {
    border: 1px solid var(--blog-border);
    border-radius: 0.75rem;
    background: var(--blog-card-bg);
    margin-bottom: 0.75rem;
    overflow: hidden;
}
.blog-faq-question {
    font-family: var(--blog-font-serif);
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--blog-text);
    padding: 1rem 1.25rem;
    cursor: pointer;
    list-style: none;
    position: relative;
    padding-inline-end: 2.75rem;
    transition: color 0.2s;
}
.blog-faq-question:hover { color: var(--blog-primary); }
/* Hide the default disclosure triangle (incl. Safari/WebKit) and draw our own +/− */
.blog-faq-question::-webkit-details-marker { display: none; }
.blog-faq-question::after {
    content: "+";
    position: absolute;
    inset-inline-end: 1.25rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1.375rem;
    font-weight: 400;
    color: var(--blog-primary);
    line-height: 1;
}
.blog-faq-item[open] .blog-faq-question::after { content: "\2212"; } /* minus sign */
.blog-faq-answer {
    padding: 0 1.25rem 1.125rem;
    color: var(--blog-text-muted);
    font-size: 0.9375rem;
    line-height: 1.7;
    white-space: pre-wrap;
}

/* ---- In-content CTA (mid-article band) ----
   Injected server-side before the 2nd <h2> (~30% depth). Deliberately ONE line + a small
   button on a tinted band — no card, no border box, no note line. The card surface is
   reserved for .blog-cta below so a reader who is only a third of the way in never gets
   the "the article ended" signal. Measured reason for existing at all: .blog-cta sits at
   ~87% page height and only 20–28% of blog sessions reach 90% depth. */
.blog-cta-inline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    margin: 2rem 0;
    padding: 0.875rem 1.125rem;
    border-inline-start: 3px solid var(--blog-primary);
    border-radius: 0.5rem;
    background: var(--blog-code-bg);
}
.blog-cta-inline-text {
    font-size: 0.9375rem;
    line-height: 1.6;
    font-weight: 600;
    /* --blog-text, NOT --blog-text-muted: this is the one line that asks the reader to act,
       and muted on this tint sits at 5.33 light / 4.90 dark — passing, but with no headroom
       for the band's 15px weight-600 copy. */
    color: var(--blog-text);
}
/* (0,2,0) so it beats .blog-content a (0,1,1) — this band renders INSIDE .blog-content,
   which underlines and re-colours every anchor. */
.blog-cta-inline .blog-cta-inline-button {
    flex: none;
    display: inline-block;
    background: var(--blog-primary);
    color: var(--blog-primary-fg) !important;
    padding: 0.4375rem 1rem;
    border-radius: 0.375rem;
    font-weight: 600;
    font-size: 0.875rem;
    white-space: nowrap;
    text-decoration: none;
}
.blog-cta-inline .blog-cta-inline-button:hover { filter: brightness(0.9); text-decoration: none; }

/* ---- End-of-article CTA ----
   The only forward-pointing link on a post page; everything else (related posts,
   back-to-list, footer) points sideways or out. Sits above .blog-related so
   "try it" is offered before "read another article". */
.blog-cta {
    margin-top: 3rem;
    padding: 1.75rem 1.5rem;
    border: 1px solid var(--blog-border);
    border-radius: 0.75rem;
    /* Solid card surface, NOT a tinted gradient: the muted 15px desc and 13px note need the
       card's full contrast (6.04 light / 5.40 dark), and a gradient stop on the muted tint
       would take that headroom away. Same surface token as .blog-related-card. */
    background: var(--blog-card-bg);
    text-align: center;
}
.blog-cta-title {
    font-family: var(--blog-font-serif);
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--blog-text);
    margin-bottom: 0.625rem;
}
.blog-cta-desc {
    font-size: 0.9375rem;
    line-height: 1.7;
    color: var(--blog-text-muted);
    max-width: 34em;
    margin: 0 auto 1.25rem;
}
.blog-cta-button {
    display: inline-block;
    background: var(--blog-primary);
    color: var(--blog-primary-fg) !important;
    padding: 0.625rem 1.75rem;
    border-radius: 0.375rem;
    font-weight: 600;
    font-size: 1rem;
}
.blog-cta-button:hover { filter: brightness(0.9); text-decoration: none; }
.blog-cta-note {
    margin-top: 0.75rem;
    font-size: 0.8125rem;
    color: var(--blog-text-muted);
}

.blog-related {
    margin-top: 3rem;
    padding-top: 2rem;
    border-top: 1px solid var(--blog-border);
}
.blog-related-title {
    font-family: var(--blog-font-serif);
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--blog-text);
    margin-bottom: 1.25rem;
}
.blog-related-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}
@media (min-width: 640px) {
    .blog-related-grid { grid-template-columns: repeat(3, 1fr); }
}
.blog-related-card {
    display: block;
    padding: 1.25rem;
    border: 1px solid var(--blog-border);
    border-radius: 0.75rem;
    background: var(--blog-card-bg);
    text-decoration: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}
.blog-related-card:hover {
    border-color: var(--blog-primary);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.blog-related-card-title {
    font-family: var(--blog-font-serif);
    font-size: 1rem;
    font-weight: 700;
    color: var(--blog-text);
    margin-bottom: 0.5rem;
    line-height: 1.4;
}
.blog-related-card-desc {
    font-size: 0.8125rem;
    color: var(--blog-text-muted);
    line-height: 1.5;
    margin-bottom: 0.75rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.blog-related-card-link {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--blog-primary);
}

/* ---- Product exit (blog → /templates/* and /features/*) ----
   Injected server-side at ~65–70% depth, INSIDE .blog-content. This is the old
   bottom-of-page「相關功能」card grid, promoted: it used to render at 95.2% of page
   height while only 20–28% of sessions reach 90% depth.

   Not a card grid any more. Three surfaces on one article already read as "the end"
   (.blog-cta, 推薦閱讀, and previously this) and two of them are still below; a reader
   two thirds in must not get that signal a third time, one screen early. So: a bordered
   list of full-width rows, visually closer to the .blog-cta-inline band than to
   .blog-related-card. */
.blog-product-exit {
    margin: 2.5rem 0;
    padding: 1.25rem;
    border: 1px solid var(--blog-border);
    border-radius: 0.75rem;
    background: var(--blog-card-bg);
}
.blog-product-exit-title {
    font-family: var(--blog-font-serif);
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--blog-text);
    margin: 0 0 0.875rem;
    /* .blog-content h2 gives every heading a bottom rule + 2em top margin. This one is
       chrome, not a section of the article, so both are cancelled here. */
    border-bottom: none;
    padding-bottom: 0;
}
.blog-product-exit-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
/* Grid, not flex, and the reason is the 320px column. The tag is a fixed-width pill and the
   arrow is fixed too, so on a phone a flex row left the name ~95px and broke it mid-word
   ("Worldbuildi / ng Sheet"). Grid AREAS let the narrow layout drop the tag onto its own line
   while the pill keeps its pill size (justify-self), which flex-basis:100% cannot do — it would
   stretch the pill's background across the row.
   (0,2,0) so it beats .blog-content a (0,1,1) — this block renders inside .blog-content,
   which underlines and re-colours every anchor. */
.blog-product-exit .blog-product-exit-link {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "tag name arrow";
    align-items: center;
    column-gap: 0.5rem;
    row-gap: 0.25rem;
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--blog-border);
    border-radius: 0.5rem;
    background: var(--blog-bg);
    text-decoration: none;
    color: var(--blog-text);
    transition: border-color 0.2s, background 0.2s;
}
@media (max-width: 430px) {
    /* Covers the whole 320–428 RWD band. Arrow spans both rows so it stays pinned right. */
    .blog-product-exit .blog-product-exit-link {
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "tag  arrow"
            "name arrow";
    }
}
.blog-product-exit .blog-product-exit-link:hover {
    border-color: var(--blog-primary);
    background: var(--blog-code-bg);
    text-decoration: none;
}
/* Templates lead on click data (28 days: 68 clicks / 1,324 impressions, against
   /features/*'s 9 / 365), so they lead in the DOM AND carry the filled tag. Features get
   the outline treatment — the two are not presented as equals. */
.blog-product-exit-template .blog-product-exit-tag {
    color: var(--blog-primary-fg);
    background: var(--blog-primary);
}
.blog-product-exit-tag {
    grid-area: tag;
    justify-self: start;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--blog-primary);
    background: var(--blog-code-bg);
    border-radius: 0.375rem;
    padding: 0.125rem 0.5rem;
}
.blog-product-exit-name {
    grid-area: name;
    /* min-width:0 lets the grid item go below its content width, so the text wraps instead of
       forcing the row wider than the viewport. No ellipsis: a wrapped template name is
       readable, a cut one is not — and at 320px the four-language titles do wrap. */
    min-width: 0;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.4;
    overflow-wrap: break-word;
}
.blog-product-exit-arrow {
    grid-area: arrow;
    color: var(--blog-primary);
    font-size: 0.9375rem;
}
/* The arrow points toward the reading direction's end; a grid item, so the transform applies. */
[dir="rtl"] .blog-product-exit-arrow { transform: scaleX(-1); }

/* ---- Back Link ---- */
.blog-back {
    margin-top: 3rem;
    padding-top: 2rem;
    border-top: 1px solid var(--blog-border);
}

.blog-back-link {
    color: var(--blog-primary);
    font-size: 0.9375rem;
    font-weight: 500;
}

/* ---- Responsive ---- */
@media (max-width: 640px) {
    .blog-container { padding: 0 1rem; }
    .blog-list-title { font-size: 1.5rem; }
    .blog-list-subtitle { font-size: 0.875rem; margin-bottom: 1.5rem; }
    .blog-cluster-section { margin-bottom: 2.5rem; }
    .blog-cluster-title { font-size: 1.25rem; }
    .blog-cluster-desc { font-size: 0.875rem; margin-bottom: 0.875rem; }
    .blog-article-title { font-size: 1.375rem; }
    .blog-card-body { padding: 1rem; }
    .blog-card-title { font-size: 1.1rem; }
    .blog-content { font-size: 1rem; }
    .blog-content h2 { font-size: 1.25rem; }
    .blog-content h3 { font-size: 1.125rem; }
    .blog-content pre { padding: 0.875rem; font-size: 0.8125rem; }
    .blog-content blockquote { padding: 0.5em 0.75em; }
    .blog-content th,
    .blog-content td { padding: 0.5rem 0.625rem; font-size: 0.8125rem; }
    .blog-faq-title { font-size: 1.25rem; }
    .blog-faq-question { font-size: 1rem; padding: 0.875rem 1rem; padding-inline-end: 2.5rem; }
    .blog-faq-answer { padding: 0 1rem 1rem; font-size: 0.875rem; }

    /* In-content band: stack, so the label never squeezes the button to one word per line. */
    .blog-cta-inline { flex-direction: column; align-items: stretch; gap: 0.75rem; padding: 0.875rem 1rem; }
    .blog-cta-inline-text { font-size: 0.875rem; }
    .blog-cta-inline .blog-cta-inline-button { text-align: center; padding: 0.5625rem 1rem; }

    /* CTA card: tighter on small screens */
    .blog-cta { padding: 1.5rem 1.125rem; }
    .blog-cta-title { font-size: 1.125rem; }
    .blog-cta-desc { font-size: 0.875rem; }
    .blog-cta-button { display: block; padding: 0.6875rem 1rem; }
}

}
