/* =========================================================================
   schizo — a dark, dense, content-first Ghost theme
   Table of contents:
   1. Custom properties (dark default, light override, forced overrides)
   1b. Self-hosted fonts (@font-face: IBM Plex Sans/Sans Arabic/Mono)
   2. Reset
   3. Base typography
   3b. Arabic-specific typography (line-height, tracking, min size)
   4. Layout primitives
   5. Skip link / focus states
   6. Header
   7. Post list (homepage / tag / author)
   8. Pagination
   9. Post layout + table of contents
   10. Content elements (headings, links, hr)
   11. Code blocks + Prism tokens
   12. Tables
   13. Blockquotes
   14. Lists
   15. Figures, footnotes, kbd
   16. Tag chips
   17. Author bio
   18. Error / private pages
   19. Responsive
   20. Reduced motion
   ========================================================================= */

/* ---------------------------------------------------------------------
   1. Custom properties
   --------------------------------------------------------------------- */
:root {
    color-scheme: dark;

    /* Self-hosted IBM Plex (see 1b below). "IBM Plex Sans" and "IBM Plex
       Sans Arabic" are two distinct type families IBM designed to pair
       visually — listing both lets the browser match per-character: Latin
       glyphs resolve against the Latin-subset face, Arabic glyphs fall
       through to the Arabic-subset face, each fetched independently via
       unicode-range. The system-font tail is a last-resort fallback only
       (e.g. font file fails to load), not an active part of the design. */
    --font-sans: "IBM Plex Sans", "IBM Plex Sans Arabic", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", "SFMono-Regular", Consolas, Menlo, "Liberation Mono", monospace;

    --content-width: 68ch;
    --wide-width: 1200px;
    --toc-width: 240px;

    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --space-8: 4.5rem;

    --radius: 3px;

    /* dark palette (default) */
    --color-bg: #0d0d0f;
    --color-bg-raised: #131317;
    --color-bg-inset: #1a1a1f;
    --color-border: #2a2a30;
    --color-border-strong: #3d3d46;
    --color-text: #e8e8ea;
    --color-text-muted: #a8a8b2;
    --color-text-faint: #7d8394;
    --color-accent: #f0a865;
    --color-accent-strong: #ffb87a;
    --color-on-accent: #14100a;
    --color-selection: rgba(240, 168, 101, 0.28);
    --color-danger: #e08080;

    /* Ghost custom-fonts integration (GS051) — aliased onto our own stack */
    --gh-font-heading: var(--font-sans);
    --gh-font-body: var(--font-sans);

    /* Prism token colors, dark */
    --code-comment: #7d8394;
    --code-string: #9bc27c;
    --code-keyword: #7aa2c9;
    --code-function: #d9b36c;
    --code-number: #c98a5e;
    --code-punctuation: #9a9aa5;
    --code-tag: #d18fb0;
    --code-deleted: #e08080;
    --code-inserted: #9bc27c;
}

/* system preference: light, only when the user hasn't forced a theme */
@media (prefers-color-scheme: light) {
    :root {
        color-scheme: light;
        --color-bg: #f7f7f5;
        --color-bg-raised: #eeeeec;
        --color-bg-inset: #e6e6e3;
        --color-border: #dcdcd8;
        --color-border-strong: #c7c7c2;
        --color-text: #16161a;
        --color-text-muted: #5a5a63;
        --color-text-faint: #6b6f7a;
        --color-accent: #a8560c;
        --color-accent-strong: #8a4609;
        --color-on-accent: #fdfaf6;
        --color-selection: rgba(168, 86, 12, 0.18);
        --color-danger: #b3261e;

        --code-comment: #5f6371;
        --code-string: #2f7a3d;
        --code-keyword: #1f5f8b;
        --code-function: #77601a;
        --code-number: #a34e13;
        --code-punctuation: #55555c;
        --code-tag: #99366b;
        --code-deleted: #b3261e;
        --code-inserted: #2f7a3d;
    }
}

/* forced dark, regardless of OS */
:root[data-theme="dark"] {
    color-scheme: dark;
    --color-bg: #0d0d0f;
    --color-bg-raised: #131317;
    --color-bg-inset: #1a1a1f;
    --color-border: #2a2a30;
    --color-border-strong: #3d3d46;
    --color-text: #e8e8ea;
    --color-text-muted: #a8a8b2;
    --color-text-faint: #7d8394;
    --color-accent: #f0a865;
    --color-accent-strong: #ffb87a;
    --color-on-accent: #14100a;
    --color-selection: rgba(240, 168, 101, 0.28);
    --color-danger: #e08080;

    --code-comment: #7d8394;
    --code-string: #9bc27c;
    --code-keyword: #7aa2c9;
    --code-function: #d9b36c;
    --code-number: #c98a5e;
    --code-punctuation: #9a9aa5;
    --code-tag: #d18fb0;
    --code-deleted: #e08080;
    --code-inserted: #9bc27c;
}

/* forced light, regardless of OS */
:root[data-theme="light"] {
    color-scheme: light;
    --color-bg: #f7f7f5;
    --color-bg-raised: #eeeeec;
    --color-bg-inset: #e6e6e3;
    --color-border: #dcdcd8;
    --color-border-strong: #c7c7c2;
    --color-text: #16161a;
    --color-text-muted: #5a5a63;
    --color-text-faint: #6b6f7a;
    --color-accent: #a8560c;
    --color-accent-strong: #8a4609;
    --color-on-accent: #fdfaf6;
    --color-selection: rgba(168, 86, 12, 0.18);
    --color-danger: #b3261e;

    --code-comment: #5f6371;
    --code-string: #2f7a3d;
    --code-keyword: #1f5f8b;
    --code-function: #77601a;
    --code-number: #a34e13;
    --code-punctuation: #55555c;
    --code-tag: #99366b;
    --code-deleted: #b3261e;
    --code-inserted: #2f7a3d;
}

/* ---------------------------------------------------------------------
   1b. Self-hosted fonts — IBM Plex, subset per-family to WOFF2, weights
   400/600 only. unicode-range is what actually splits Latin from Arabic:
   each face only claims the codepoints in its range, so the browser only
   fetches a face once it finds matching text on the page — a Latin-only
   post never triggers the Arabic download, and vice versa. All local,
   zero external requests.
   --------------------------------------------------------------------- */
@font-face {
    font-family: "IBM Plex Sans";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/ibm-plex-sans-latin-400.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+2190-2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "IBM Plex Sans";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/ibm-plex-sans-latin-600.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+2190-2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "IBM Plex Sans Arabic";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/ibm-plex-sans-arabic-400.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200C-200F, U+2010-2011;
}
@font-face {
    font-family: "IBM Plex Sans Arabic";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/ibm-plex-sans-arabic-600.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF, U+200C-200F, U+2010-2011;
}
@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-latin-400.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+2190-2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-latin-600.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+2190-2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------------------------------------------------------------------
   2. Reset
   --------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
img, picture, svg { display: block; max-width: 100%; }
input, button, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; }
ul[class], ol[class] { list-style: none; padding: 0; }

::selection { background: var(--color-selection); }

/* ---------------------------------------------------------------------
   3. Base typography
   --------------------------------------------------------------------- */
body {
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-sans);
    font-size: 17px;
    line-height: 1.7;
    text-rendering: optimizeLegibility;
    /* only 400/600 are ever loaded (see 1b) — don't let the browser fake a
       bolder or oblique weight we didn't ship, it looks worse than 600 */
    font-synthesis: none;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--gh-font-heading);
    line-height: 1.3;
    font-weight: 600;
}

/* ---------------------------------------------------------------------
   3b. Arabic-specific typography
   These are genuine differences from the Latin defaults above, not
   inherited tweaks — Arabic script needs looser leading (taller x-height,
   tashkeel marks above/below the baseline), zero tracking (letter-spacing
   distorts the joined cursive forms), and a larger minimum body size for
   legibility at comparable stroke weight.

   Note on selectors: our dir="auto" markup never produces a literal
   dir="rtl" attribute, so [dir="rtl"] would silently never match here —
   :dir(rtl) is what reads dir="auto"'s *computed* direction. :lang(ar) is
   kept alongside it for content where an author (or Ghost) sets an actual
   lang="ar" attribute, which is a real-language signal :dir() can't see
   (a short RTL-detected quote inside an otherwise-English post, say).
   --------------------------------------------------------------------- */
:lang(ar),
:dir(rtl) {
    letter-spacing: 0 !important;
}
.post-content:lang(ar),
.post-content:dir(rtl) {
    font-size: max(1em, 18px);
    line-height: 1.95;
}
/* headings inherit the tight 1.3 above by default; Arabic headings need
   real clearance so tashkeel (fatha/kasra/damma etc.) above and below the
   letterforms don't get clipped by the next line box */
.post-content:lang(ar) h1, .post-content:dir(rtl) h1,
.post-content:lang(ar) h2, .post-content:dir(rtl) h2,
.post-content:lang(ar) h3, .post-content:dir(rtl) h3,
.post-content:lang(ar) h4, .post-content:dir(rtl) h4,
.post-title:lang(ar), .post-title:dir(rtl),
.post-row-title:lang(ar), .post-row-title:dir(rtl) {
    line-height: 1.7;
}
/* code is never Arabic and never RTL, even nested inside Arabic prose —
   hold it to Latin metrics regardless of what ancestor rule just applied.
   (.code-toolbar-header/.copy-code-button already have their own explicit
   font-size, so the inherited Arabic bump above never reaches them — only
   their letter-spacing needs the same explicit override as everything
   else caught by the earlier blanket :lang(ar)/:dir(rtl) rule.) */
.post-content:lang(ar) pre, .post-content:dir(rtl) pre,
.post-content:lang(ar) code, .post-content:dir(rtl) code {
    font-size: revert;
    line-height: 1.55;
    letter-spacing: normal !important;
}
.post-content:lang(ar) .code-toolbar-header, .post-content:dir(rtl) .code-toolbar-header,
.post-content:lang(ar) .copy-code-button, .post-content:dir(rtl) .copy-code-button {
    letter-spacing: normal !important;
}

/* ---------------------------------------------------------------------
   4. Layout primitives
   --------------------------------------------------------------------- */
.wrap {
    max-width: var(--wide-width);
    margin-inline: auto;
    padding-inline: var(--space-5);
}

.site {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.site-main {
    flex: 1;
}

/* ---------------------------------------------------------------------
   5. Skip link / focus states
   --------------------------------------------------------------------- */
.skip-link {
    position: absolute;
    left: var(--space-4);
    top: -3rem;
    z-index: 100;
    background: var(--color-accent);
    color: var(--color-on-accent);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius);
    font-family: var(--font-mono);
    font-size: 0.85rem;
    transition: top 0.15s ease;
}
.skip-link:focus {
    top: var(--space-4);
}

:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}
a:focus-visible, button:focus-visible {
    border-radius: var(--radius);
}

/* ---------------------------------------------------------------------
   6. Header
   --------------------------------------------------------------------- */
.site-header {
    border-bottom: 1px solid var(--color-border);
}

.site-header-inner {
    display: flex;
    align-items: center;
    gap: var(--space-6);
    padding-block: var(--space-4);
    flex-wrap: wrap;
}

.site-title {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
    text-decoration: none;
    white-space: nowrap;
}
.site-title::before {
    content: "~/";
    color: var(--color-text-faint);
}

.site-nav {
    flex: 1;
    min-width: 0;
}
.site-nav .nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-5);
}
.site-nav a {
    text-decoration: none;
    color: var(--color-text-muted);
    font-size: 0.95rem;
    border-bottom: 1px solid transparent;
}
.site-nav a:hover {
    color: var(--color-text);
    border-bottom-color: var(--color-border-strong);
}

.header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.rss-link {
    color: var(--color-text-muted);
    display: inline-flex;
}
.rss-link:hover {
    color: var(--color-text);
}
.rss-link svg {
    width: 18px;
    height: 18px;
}

.secondary-nav .nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}
.secondary-nav a {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--color-text-muted);
    text-decoration: none;
}
.secondary-nav a:hover {
    color: var(--color-text);
}

.theme-toggle {
    display: none; /* hidden until JS confirms it can persist a choice */
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    color: var(--color-text-muted);
}
.has-js .theme-toggle {
    display: inline-flex;
}
.theme-toggle:hover {
    color: var(--color-text);
    border-color: var(--color-border-strong);
}
.theme-toggle svg {
    width: 16px;
    height: 16px;
}
.theme-toggle [data-icon] {
    display: none;
}
.theme-toggle [data-icon="system"] {
    display: block;
}
:root[data-theme="dark"] .theme-toggle [data-icon="system"],
:root[data-theme="light"] .theme-toggle [data-icon="system"] {
    display: none;
}
:root[data-theme="dark"] .theme-toggle [data-icon="dark"],
:root[data-theme="light"] .theme-toggle [data-icon="light"] {
    display: block;
}

.site-footer {
    border-top: 1px solid var(--color-border);
}
.site-footer-inner {
    padding-block: var(--space-5);
}
.site-footer-note {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--color-text-faint);
}

/* ---------------------------------------------------------------------
   7. Post list
   --------------------------------------------------------------------- */
.post-list {
    max-width: var(--wide-width);
    margin-inline: auto;
    padding-inline: var(--space-5);
}

.post-row {
    border-bottom: 1px solid var(--color-border);
    padding-block: var(--space-6);
    position: relative;
}
.post-row:first-child {
    padding-top: var(--space-7);
}

.post-row-meta {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--color-text-faint);
    display: flex;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
}
.post-row-meta time {
    color: var(--color-text-faint);
}

.post-row-title {
    font-size: 1.35rem;
    margin-bottom: var(--space-2);
}
.post-row-title a {
    text-decoration: none;
}
.post-row-title a::after {
    /* stretched link: whole row is clickable via the title link,
       tag chips stay independently clickable via z-index below */
    content: "";
    position: absolute;
    inset: 0;
}
.post-row:hover .post-row-title a {
    color: var(--color-accent);
}

.post-row-excerpt {
    color: var(--color-text-muted);
    max-width: 62ch;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-bottom: var(--space-3);
}

.post-row-tags {
    position: relative;
    z-index: 1;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.empty-state {
    padding-block: var(--space-8);
    text-align: center;
    color: var(--color-text-muted);
}
.empty-state h2 {
    font-size: 1.1rem;
    margin-bottom: var(--space-2);
    color: var(--color-text);
}

/* ---------------------------------------------------------------------
   8. Pagination
   --------------------------------------------------------------------- */
.pagination {
    max-width: var(--wide-width);
    margin-inline: auto;
    padding: var(--space-6) var(--space-5) var(--space-8);
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-family: var(--font-mono);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}
.pagination a {
    text-decoration: none;
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--space-2) var(--space-4);
}
.pagination a:hover {
    border-color: var(--color-border-strong);
    color: var(--color-accent);
}
.pagination .page-status {
    color: var(--color-text-faint);
}
.pagination .pagination-spacer {
    visibility: hidden;
}

/* ---------------------------------------------------------------------
   9. Post layout + table of contents
   --------------------------------------------------------------------- */
.post {
    padding-block: var(--space-7) var(--space-8);
}

.post-header {
    max-width: var(--content-width);
    margin-inline: auto;
    padding-inline: var(--space-5);
    margin-bottom: var(--space-6);
}

.post-meta {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    color: var(--color-text-faint);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.post-title {
    font-size: 2rem;
    line-height: 1.2;
    margin-bottom: var(--space-4);
}

.post-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.post-feature-image {
    max-width: var(--content-width);
    margin: 0 auto var(--space-6);
    padding-inline: var(--space-5);
}
.post-feature-image img {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    width: 100%;
    height: auto;
}

.post-layout {
    display: grid;
    grid-template-columns: 1fr;
    padding-inline: var(--space-5);
    max-width: calc(var(--content-width) + var(--space-5) * 2);
    margin-inline: auto;
}

.post-toc {
    display: none;
    margin-bottom: var(--space-6);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg-raised);
}
.has-toc .post-toc {
    display: block;
}
/* RTL: applies at every width, not just the desktop grid breakpoint, so the
   mobile collapsed <details> list also right-aligns its Arabic heading
   links instead of inheriting the page's default LTR alignment. The grid
   column swap (relevant only once the TOC is a sticky side column) stays
   scoped to the desktop media query further down. */
.post-layout:has(.post-content:dir(rtl)) .post-toc {
    direction: rtl;
}
.post-toc-summary {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    font-weight: 600;
    padding: var(--space-3) var(--space-4);
    color: var(--color-text-muted);
}
.post-toc nav {
    padding: 0 var(--space-4) var(--space-4);
}
.post-toc ul {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.post-toc a {
    display: block;
    font-size: 0.85rem;
    text-decoration: none;
    color: var(--color-text-muted);
    border-inline-start: 2px solid transparent;
    padding-inline-start: var(--space-3);
    line-height: 1.4;
}
.post-toc a[data-depth="3"] {
    padding-inline-start: var(--space-5);
    font-size: 0.8rem;
}
.post-toc a:hover {
    color: var(--color-text);
}
.post-toc a.is-active {
    color: var(--color-accent);
    border-inline-start-color: var(--color-accent);
}

.post-content {
    max-width: var(--content-width);
    margin-inline: auto;
}

.post-footer {
    max-width: var(--content-width);
    margin: var(--space-7) auto 0;
    padding-inline: var(--space-5);
}

.post-nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
    border-top: 1px solid var(--color-border);
    padding-top: var(--space-6);
    margin-top: var(--space-6);
}
.post-nav-link {
    text-decoration: none;
    display: block;
}
.post-nav-link.next {
    text-align: right;
}
.post-nav-direction {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--color-text-faint);
    display: block;
    margin-bottom: var(--space-1);
}
.post-nav-title {
    color: var(--color-text);
}
.post-nav-link:hover .post-nav-title {
    color: var(--color-accent);
}

.author-bio {
    display: flex;
    gap: var(--space-4);
    align-items: flex-start;
    border-top: 1px solid var(--color-border);
    padding-top: var(--space-6);
    margin-top: var(--space-6);
}
.author-bio img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    flex-shrink: 0;
}
.author-bio-name {
    font-weight: 600;
    margin-bottom: var(--space-1);
}
.author-bio-desc {
    color: var(--color-text-muted);
    font-size: 0.95rem;
}

/* ---------------------------------------------------------------------
   10. Content elements
   --------------------------------------------------------------------- */
.post-content h1,
.post-content h2,
.post-content h3,
.post-content h4 {
    margin-top: var(--space-7);
    margin-bottom: var(--space-4);
    scroll-margin-top: var(--space-6);
}
.post-content h2 { font-size: 1.5rem; }
.post-content h3 { font-size: 1.25rem; }
.post-content h4 { font-size: 1.05rem; }

.post-content p,
.post-content ul,
.post-content ol,
.post-content table,
.post-content figure,
.post-content blockquote,
.post-content .kg-card {
    margin-bottom: var(--space-5);
}

.post-content a {
    color: var(--color-accent);
    text-decoration-color: var(--color-border-strong);
    text-underline-offset: 0.15em;
}
.post-content a:hover {
    text-decoration-color: var(--color-accent);
}

.post-content hr {
    border: 0;
    border-top: 1px solid var(--color-border);
    margin-block: var(--space-7);
}

/* ---------------------------------------------------------------------
   11. Code blocks + Prism tokens
   --------------------------------------------------------------------- */
.post-content code {
    font-family: var(--font-mono);
    font-size: 0.85em;
}

.post-content :not(pre) > code {
    background: var(--color-bg-inset);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.1em 0.4em;
    /* code is never RTL, even mid-sentence in Arabic prose. direction alone
       has no effect on an inline box unless unicode-bidi also isolates it. */
    direction: ltr;
    unicode-bidi: isolate;
    text-align: left;
}

.post-content .kg-code-card {
    position: relative;
}

.code-toolbar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--color-bg-inset);
    border: 1px solid var(--color-border);
    border-bottom: 0;
    border-radius: var(--radius) var(--radius) 0 0;
    padding: var(--space-2) var(--space-4);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--color-text-faint);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    /* language label stays left, copy button stays right, regardless of
       the ambient content direction — this chrome belongs to the code
       block, which is always LTR */
    direction: ltr;
}

.copy-code-button {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.15em 0.6em;
    text-transform: none;
    letter-spacing: normal;
}
.copy-code-button:hover {
    color: var(--color-text);
    border-color: var(--color-border-strong);
}
.copy-code-button[data-copied="true"] {
    color: var(--color-accent);
    border-color: var(--color-accent);
}

.post-content pre {
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--space-4);
    overflow-x: auto;
    line-height: 1.55;
    /* code is never RTL, even inside Arabic prose */
    direction: ltr;
    unicode-bidi: isolate;
    text-align: left;
}
.code-toolbar-header + pre {
    border-radius: 0 0 var(--radius) var(--radius);
}
.post-content pre code {
    background: none;
    border: 0;
    padding: 0;
    white-space: pre;
    direction: ltr;
    text-align: left;
}

.token.comment,
.token.prolog,
.token.doctype,
.token.cdata { color: var(--code-comment); font-style: normal; }
.token.string,
.token.attr-value,
.token.char { color: var(--code-string); }
.token.keyword,
.token.selector,
.token.builtin { color: var(--code-keyword); }
.token.function,
.token.class-name { color: var(--code-function); }
.token.number,
.token.boolean,
.token.constant { color: var(--code-number); }
.token.punctuation,
.token.operator { color: var(--code-punctuation); }
.token.tag,
.token.attr-name,
.token.property { color: var(--code-tag); }
.token.deleted { color: var(--code-deleted); }
.token.inserted { color: var(--code-inserted); }
.token.important,
.token.bold { font-weight: 600; }

/* ---------------------------------------------------------------------
   12. Tables
   --------------------------------------------------------------------- */
.post-content .kg-table-card,
.post-content table.gh-table-wrap {
    overflow-x: auto;
}
.post-content table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--font-mono);
    font-size: 0.85rem;
    display: block;
    overflow-x: auto;
    white-space: nowrap;
}
.post-content th,
.post-content td {
    border: 1px solid var(--color-border);
    padding: var(--space-2) var(--space-3);
    text-align: start;
    white-space: normal;
}
.post-content th {
    background: var(--color-bg-inset);
    font-weight: 600;
    white-space: nowrap;
}
.post-content tbody tr:nth-child(even) {
    background: color-mix(in srgb, var(--color-bg-raised) 60%, transparent);
}

/* Numeric columns: authors mark these with class="num" on th/td (Ghost has
   no native "numeric column" concept). Numerals stay LTR and right-aligned
   regardless of the table's own direction, so magnitudes/decimals still
   line up — the standard convention even in RTL-language interfaces. */
.post-content th.num,
.post-content td.num {
    direction: ltr;
    unicode-bidi: isolate;
    text-align: right;
}

/* ---------------------------------------------------------------------
   13. Blockquotes
   --------------------------------------------------------------------- */
.post-content blockquote {
    border-inline-start: 3px solid var(--color-border-strong);
    padding-inline-start: var(--space-5);
    color: var(--color-text-muted);
    font-style: normal;
}
.post-content blockquote p:last-child {
    margin-bottom: 0;
}

/* ---------------------------------------------------------------------
   14. Lists
   --------------------------------------------------------------------- */
.post-content ul,
.post-content ol {
    padding-inline-start: 1.4em;
}
.post-content ul { list-style: disc; }
.post-content ul ul { list-style: circle; }
.post-content ul ul ul { list-style: square; }
.post-content ol { list-style: decimal; }
.post-content ol ol { list-style: lower-alpha; }
.post-content ol ol ol { list-style: lower-roman; }
.post-content li > ul,
.post-content li > ol {
    margin-top: var(--space-2);
    margin-bottom: 0;
}
.post-content li + li {
    margin-top: var(--space-2);
}

/* ---------------------------------------------------------------------
   15. Figures, footnotes, kbd
   --------------------------------------------------------------------- */
.post-content figure img,
.post-content figure video {
    border-radius: var(--radius);
    width: 100%;
    height: auto;
}

/* Koenig editor width options: break the normal content column.
   left/transform here are intentionally physical, not logical — this is a
   viewport-centering hack (center via left:50%+translateX(-50%)), not a
   content-direction concern. inset-inline-start would flip to "right" under
   RTL while translateX(-50%) stays a fixed physical offset, breaking the
   centering. Wide/full images center the same way regardless of language. */
.post-content .kg-width-wide {
    width: 100vw;
    max-width: 1000px;
    position: relative;
    left: 50%;
    transform: translateX(-50%);
}
.post-content .kg-width-full {
    width: 100vw;
    max-width: 100vw;
    position: relative;
    left: 50%;
    transform: translateX(-50%);
}
.post-content .kg-width-full img,
.post-content .kg-width-full video {
    border-radius: 0;
}
.post-content figcaption {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--color-text-faint);
    margin-top: var(--space-2);
    text-align: center;
}

.footnotes {
    margin-top: var(--space-7);
    padding-top: var(--space-5);
    border-top: 1px solid var(--color-border);
    font-size: 0.9rem;
    color: var(--color-text-muted);
}
.footnotes ol {
    padding-inline-start: 1.4em;
}
.footnotes li {
    margin-bottom: var(--space-2);
}
.footnote-ref {
    font-size: 0.75em;
    vertical-align: super;
}

kbd {
    font-family: var(--font-mono);
    font-size: 0.85em;
    background: var(--color-bg-inset);
    border: 1px solid var(--color-border-strong);
    border-bottom-width: 2px;
    border-radius: var(--radius);
    padding: 0.05em 0.45em;
}

/* ---------------------------------------------------------------------
   16. Tag chips
   --------------------------------------------------------------------- */
.tag-chip {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.1em 0.5em;
    text-decoration: none;
    white-space: nowrap;
}
.tag-chip:hover {
    color: var(--color-accent);
    border-color: var(--color-accent);
}

.archive-header {
    max-width: var(--wide-width);
    margin-inline: auto;
    padding: var(--space-7) var(--space-5) var(--space-5);
}
.archive-header h1 {
    font-size: 1.6rem;
    margin-bottom: var(--space-2);
}
.archive-header p {
    color: var(--color-text-muted);
    max-width: 60ch;
}

/* ---------------------------------------------------------------------
   17. Author bio (author.hbs archive)
   --------------------------------------------------------------------- */
.author-archive-header {
    display: flex;
    gap: var(--space-4);
    align-items: center;
}
.author-archive-header img {
    width: 64px;
    height: 64px;
    border-radius: 50%;
}

/* ---------------------------------------------------------------------
   18. Error / private pages
   --------------------------------------------------------------------- */
.error-page {
    max-width: 60ch;
    margin: var(--space-8) auto;
    padding-inline: var(--space-5);
    text-align: center;
}
.error-code {
    font-family: var(--font-mono);
    font-size: 3.5rem;
    color: var(--color-text-faint);
    margin-bottom: var(--space-4);
}
.error-page h1 {
    font-size: 1.5rem;
    margin-bottom: var(--space-3);
}
.error-message {
    color: var(--color-text-muted);
    margin-bottom: var(--space-5);
}
.error-page a {
    color: var(--color-accent);
}

.private-form {
    max-width: 40ch;
    margin: var(--space-8) auto;
    padding-inline: var(--space-5);
}
.private-form input[type="password"] {
    width: 100%;
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--space-3);
    color: var(--color-text);
    margin-block: var(--space-4);
}
.private-form button {
    background: var(--color-accent);
    color: var(--color-on-accent);
    border-radius: var(--radius);
    padding: var(--space-2) var(--space-5);
    font-weight: 600;
}
.private-form .error {
    color: var(--color-danger);
    font-size: 0.9rem;
}

/* ---------------------------------------------------------------------
   19. Responsive
   --------------------------------------------------------------------- */
@media (min-width: 1200px) {
    .post-layout {
        max-width: var(--wide-width);
        grid-template-columns:
            1fr
            min(var(--content-width), calc(100% - var(--toc-width) - var(--space-7) - var(--space-5) * 2))
            var(--toc-width)
            1fr;
        column-gap: var(--space-7);
        align-items: start;
    }
    .post-content { grid-column: 2; }
    .post-toc {
        grid-column: 3;
        grid-row: 1;
        position: sticky;
        top: var(--space-6);
        margin-bottom: 0;
        max-height: calc(100vh - var(--space-7));
        overflow-y: auto;
    }
    .post-toc:not([open]) > nav {
        display: block !important;
    }
    .post-toc-summary {
        pointer-events: none;
    }
    .post-toc-summary::marker,
    .post-toc-summary::-webkit-details-marker {
        display: none;
    }

    /* RTL, desktop only: swapping just the grid-column index isn't enough
       on its own — column 2 and column 3 are different widths (content-width
       vs the narrow toc-width track), so the track sizes have to swap too,
       or content gets squeezed into the narrow track. Redefining
       grid-template-columns handles that; the grid-column reassignment
       below then places each item in its new track. (.post-toc's own
       direction:rtl is set unconditionally further up, not repeated here.) */
    .post-layout:has(.post-content:dir(rtl)) {
        grid-template-columns:
            1fr
            var(--toc-width)
            min(var(--content-width), calc(100% - var(--toc-width) - var(--space-7) - var(--space-5) * 2))
            1fr;
    }
    .post-layout:has(.post-content:dir(rtl)) .post-content {
        grid-column: 3;
    }
    .post-layout:has(.post-content:dir(rtl)) .post-toc {
        grid-column: 2;
        grid-row: 1;
    }
}

@media (max-width: 640px) {
    body { font-size: 16px; }
    .post-title { font-size: 1.6rem; }
    .site-header-inner { gap: var(--space-4); }
    .post-nav { grid-template-columns: 1fr; }
    .post-nav-link.next { text-align: left; }
    .author-bio { flex-direction: column; }
}

/* ---------------------------------------------------------------------
   20. Reduced motion
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    * {
        transition-duration: 0.001ms !important;
        animation-duration: 0.001ms !important;
    }
}
