/* =============================================================
   ARTICLE CONTENT - the single source of truth for article body
   styling, shared by THREE surfaces that must agree exactly:

     1. the editing surface  (.ql-editor, inside the editor)
     2. the preview overlay  (#preview-content in the editor)
     3. the published page   (blog/show, news/show)

   Before this file existed each surface carried its own inline
   copy, and they drifted -- which is why "Preview" never quite
   matched what readers saw.

   IMPORTANT: these rules style HTML generated BY the editor, so
   they cannot be expressed as Tailwind utilities -- there is no
   markup to attach classes to. Keep this as plain CSS.

   The same HTML is served verbatim to the mobile apps via the
   API (content ships unmodified from the DB column), so changing
   the markup these selectors target is an API-visible change.
   ============================================================= */

/* Article Body */
.article-body {
    font-size: 1.125rem;
    line-height: 1.7;
    color: var(--text-main) !important;
    font-family: 'Raleway', 'Google Sans', sans-serif;
    overflow-wrap: anywhere;
    word-wrap: break-word;
}

/* Force all text elements in article to use theme color (overrides WYSIWYG inline styles).
 *
 * :not() guards on code, because a code block sets its own dark background and
 * light foreground. Without them this rule repainted the code text to the page
 * text colour on top of that background -- dark on dark in the light theme --
 * and did the same to every syntax-highlight span inside. Quill's legacy code
 * blocks are made of <div>s, so they were hit hardest. */
.article-body p:not(.ql-code-block),
.article-body span:not(.hljs *),
.article-body div:not(.ql-code-block):not(.ql-code-block-container):not(.hewa-code-block),
.article-body li,
.article-body td,
.article-body th,
.article-body blockquote,
.article-body strong,
.article-body em,
.article-body a {
    color: var(--text-main) !important;
}

/* Nothing inside a code block takes the page text colour. */
.article-body pre,
.article-body pre *,
.article-body code,
.article-body .ql-code-block-container,
.article-body .ql-code-block-container * {
    color: inherit !important;
}

/* --- Tables ---------------------------------------------------- */
/* display:block is what makes a table scroll horizontally on a phone. The cost
 * is that the table no longer shrink-wraps its content, so it always fills the
 * column -- which is what we want here. A wrapper element would be cleaner but
 * would change the stored markup, and that markup goes to the mobile apps
 * verbatim. */
.article-body table {
    display: block;
    width: 100% !important;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 28px 0;
    border-collapse: collapse;
    border-spacing: 0;
    font-size: 0.95rem;
    /* A visible edge to the scroll area, so a table that runs off the side
       reads as scrollable rather than clipped. */
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 12px;
}

.dark .article-body table {
    border-color: rgba(255, 255, 255, 0.1);
}

.article-body table th,
.article-body table td {
    min-width: 120px;
    padding: 12px 16px;
    border: none;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
    border-right: 1px solid rgba(0, 0, 0, 0.07);
    text-align: left;
    vertical-align: top;
}

.article-body table th:last-child,
.article-body table td:last-child {
    border-right: none;
}

.article-body table tr:last-child td {
    border-bottom: none;
}

.article-body table th {
    background: rgba(15, 23, 42, 0.05);
    font-weight: 700;
    font-size: 0.85rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* Zebra striping. Readers lose their row on a wide table without it, which is
   exactly when the table is scrolling sideways. */
.article-body table tbody tr:nth-child(even) td {
    background: rgba(15, 23, 42, 0.02);
}

.dark .article-body table th,
.dark .article-body table td {
    border-color: rgba(255, 255, 255, 0.1);
}

.dark .article-body table th {
    background: rgba(255, 255, 255, 0.07);
}

.dark .article-body table tbody tr:nth-child(even) td {
    background: rgba(255, 255, 255, 0.03);
}

/* TipTap emits <colgroup> with inline min-widths for its column resizer. Those
   are an editing concern; letting them through would pin published column
   widths to whatever the writer's screen happened to be. */
.article-body table colgroup col {
    width: auto !important;
    min-width: 0 !important;
}

@media (max-width: 640px) {
    .article-body table {
        font-size: 0.85rem;
    }

    .article-body table th,
    .article-body table td {
        min-width: 100px;
        padding: 10px 12px;
    }
}

.article-body a { 
    color: var(--primary, #7C6CEF) !important; 
    text-decoration: underline;
}

/* =========================================================================
   Headings - the single scale, for every surface an article appears on.
   =========================================================================

   There were three scales before this, and which one you saw depended on where
   you were standing:

     .ql-editor h1/h2/h3   2 / 1.5 / 1.25rem     (hewa-editor.css, Quill only)
     .ProseMirror          nothing at all        (TipTap fell to UA defaults)
     .article-body h2,h3,h4   all 1.75rem        (published page)

   So H2 and H3 were indistinguishable once published, H1 was never styled at
   all, and the editor disagreed with the result in a way that changed again if
   the EDITOR_ENGINE was flipped. That is what "headings behave differently for
   different people" was.

   All three selectors are listed together deliberately. Splitting them is how
   they drifted, and WYSIWYG means the editing surface and the published page
   have to be styled by the same rule, not by two rules someone keeps in sync.

   h2 stays at 1.75rem so the archive - which leans on H2 - does not reflow. */
.article-body h1,
.ql-editor h1,
.ProseMirror h1 {
    font-size: 2.25rem;
    font-weight: 700;
    line-height: 1.2;
    margin-top: 48px;
    margin-bottom: 18px;
    color: var(--text-main) !important;
}

.article-body h2,
.ql-editor h2,
.ProseMirror h2 {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.25;
    margin-top: 40px;
    margin-bottom: 16px;
    color: var(--text-main) !important;
}

.article-body h3,
.ql-editor h3,
.ProseMirror h3 {
    font-size: 1.375rem;
    font-weight: 600;
    line-height: 1.3;
    margin-top: 32px;
    margin-bottom: 12px;
    color: var(--text-main) !important;
}

.article-body h4,
.ql-editor h4,
.ProseMirror h4 {
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.35;
    margin-top: 28px;
    margin-bottom: 10px;
    color: var(--text-main) !important;
}

/* The first heading in a body should not push the whole article down. */
.article-body > :first-child,
.ql-editor > :first-child,
.ProseMirror > :first-child {
    margin-top: 0;
}
/* =========================================================================
   Lists - markers restored, on every surface.
   =========================================================================

   Tailwind's preflight resets `ul, ol { list-style: none; margin: 0;
   padding: 0 }`, and it is loaded on both the editor and the published page.
   Nothing put the markers back: .article-body ul set a padding but never a
   list-style-type, and there was no ol rule at all - so bulleted and numbered
   lists were indistinguishable from plain paragraphs while writing, and stayed
   that way once published.

   list-style-type is set explicitly rather than relying on the browser
   default, because the default is what preflight just removed. */
.article-body ul,
.ql-editor ul,
.ProseMirror ul {
    list-style: disc outside;
    margin-bottom: 24px;
    padding-left: 24px;
}

.article-body ol,
.ql-editor ol,
.ProseMirror ol {
    list-style: decimal outside;
    margin-bottom: 24px;
    padding-left: 24px;
}

/* Nested levels need their own marker, or a sub-list is a second column of
   identical bullets with no visible hierarchy. */
.article-body ul ul,
.ql-editor ul ul,
.ProseMirror ul ul {
    list-style-type: circle;
    margin-bottom: 0;
}

.article-body ol ol,
.ql-editor ol ol,
.ProseMirror ol ol {
    list-style-type: lower-alpha;
    margin-bottom: 0;
}

.article-body li,
.ql-editor li,
.ProseMirror li {
    margin-bottom: 10px;
    color: var(--text-main) !important;
}

/* A paragraph inside a list item is how both editors wrap list content; without
   this it inherits the paragraph margin and the list falls apart vertically. */
.article-body li > p,
.ql-editor li > p,
.ProseMirror li > p {
    margin: 0;
}

.article-body img {
    max-width: 100% !important;
    height: auto !important;
    border-radius: 16px;
    margin: 30px 0;
    display: block;
}
.article-body .ad-banner-wrapper img,
.article-body .merch-mini-card img {
    margin: 0 !important;
    max-width: 100% !important;
    height: 100% !important;
    max-height: 100% !important;
    display: block !important;
    border-radius: 0 !important;
    transform: none !important;
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    width: 100% !important;
}

/* Force correct title dimensions and reset global article-body overrides */
.article-body .merch-mini-card .merch-mini-title {
    margin: 0 !important;
    padding: 0 !important;
    font-size: 1.125rem !important;
    font-weight: 900 !important;
    line-height: 1.3 !important;
    color: #18181b !important;
    font-family: 'Outfit', 'Google Sans', sans-serif !important;
}
.dark .article-body .merch-mini-card .merch-mini-title {
    color: #ffffff !important;
}

/* Ensure text and icon colors inside the mini-card buttons are white (contrast against red bg) */
.article-body .merch-mini-card .merch-mini-btn,
.article-body .merch-mini-card .merch-mini-btn span,
.article-body .merch-mini-card .merch-mini-btn i {
    color: #ffffff !important;
}




/* Embedded Videos
   The !important flags and the wrapper overrides below are not defensive
   noise: Quill writes inline width/left/position onto embeds and their
   wrapping paragraph, which pushed videos off-centre and out of the column.
   These came from the news page, where the problem was noticed first, and
   now apply everywhere so one content type is not quietly worse than
   the other. */
.article-body iframe {
    width: 100% !important;
    max-width: 100% !important;
    aspect-ratio: 16/9;
    height: auto !important;
    border-radius: 20px !important;
    box-shadow: 0 10px 40px rgba(0,0,0,0.1);
    margin: 40px auto !important;
    display: block !important;
    left: auto !important;
    position: relative !important;
}

/* Override any wrapper container the editor introduced around the embed. */
.article-body div:has(> iframe),
.article-body p:has(> iframe) {
    width: 100% !important;
    max-width: 100% !important;
    text-align: center;
    margin: 40px 0 !important;
}

/* Figure and Caption Support */
.article-body figure {
    margin: 40px 0;
    text-align: center;
}

.article-body figure img,
.article-body figure iframe {
    margin: 0 auto;
    display: block;
}

/* A caption has to read as a caption.
 *
 * Designed as an editorial sidebar: a vertical bar on the left, italicized grey text,
 * cleanly aligned under figures, images, and equations. */
.article-body figcaption,
.article-body .caption-true,
.article-body [data-caption="true"] {
    display: block;
    max-width: 95%;
    margin: 10px 0 24px 0;
    padding: 4px 0 4px 12px;
    background: transparent !important;
    border: none;
    border-left: 3px solid var(--primary, #7C6CEF);
    border-radius: 0;
    font-size: 0.88rem !important;
    font-style: italic !important;
    color: #64748b !important;
    text-align: left !important;
    line-height: 1.6;
    letter-spacing: 0.01em;
}

.dark .article-body figcaption,
.dark .article-body .caption-true,
.dark .article-body [data-caption="true"] {
    background: transparent !important;
    border-left-color: var(--primary, #9f91ff);
    color: #9ca3af !important;
}

/* The explicit caption classes sit on a paragraph that follows the image
   directly, so ensure spacing remains crisp without overlapping. */
.article-body .caption-true,
.article-body [data-caption="true"] {
    margin-top: 8px;
    margin-bottom: 24px;
}

/* Positional caption guessing.
   These infer a caption from a paragraph merely sitting next to an image, video,
   or equation in surfaces opted into auto-captions. */
.article-body--auto-captions p:has(+ img),
.article-body--auto-captions img + p:first-of-type,
.article-body--auto-captions iframe + p:first-of-type {
    display: block;
    max-width: 95%;
    margin: 8px 0 26px 0;
    padding: 4px 0 4px 12px;
    background: transparent !important;
    border: none;
    border-left: 3px solid var(--primary, #7C6CEF);
    border-radius: 0;
    font-size: 0.88rem !important;
    font-style: italic !important;
    color: #64748b !important;
    text-align: left !important;
    line-height: 1.6;
}

.dark .article-body--auto-captions p:has(+ img),
.dark .article-body--auto-captions img + p:first-of-type,
.dark .article-body--auto-captions iframe + p:first-of-type {
    background: transparent !important;
    border-left-color: var(--primary, #9f91ff);
    color: #9ca3af !important;
}

/* Quill small text caption styling */
.article-body em.ql-size-small,
.article-body p em.ql-size-small,
.article-body .ql-size-small {
    display: block;
    max-width: 95%;
    margin: 8px 0 26px 0;
    padding: 4px 0 4px 12px;
    background: transparent !important;
    border: none;
    border-left: 3px solid var(--primary, #7C6CEF);
    border-radius: 0;
    font-size: 0.88rem !important;
    font-style: italic !important;
    color: #64748b !important;
    text-align: left !important;
    line-height: 1.6;
}
.dark .article-body em.ql-size-small,
.dark .article-body p em.ql-size-small,
.dark .article-body .ql-size-small {
    background: transparent !important;
    border-left-color: var(--primary, #9f91ff);
    color: #9ca3af !important;
}

/* Blockquote styling - matches editor preview */
.article-body blockquote {
    border-left: 4px solid #7c3aed;
    padding: 16px 24px;
    margin: 30px 0;
    background: rgba(124, 58, 237, 0.05);
    border-radius: 0 12px 12px 0;
    font-style: italic;
    font-size: 1.1rem;
    color: #64748b;
    quotes: none;
}

/* Quill Alignment Classes for published articles */
.article-body .ql-align-center { text-align: center !important; }
.article-body .ql-align-right { text-align: right !important; }
.article-body .ql-align-justify { text-align: justify !important; }

/* Centered blockquotes from Quill */
.article-body blockquote.ql-align-center {
    border-left: none;
    border-radius: 12px;
    text-align: center;
    padding: 24px 32px;
    position: relative;
}

.article-body blockquote.ql-align-center::before {
    content: '"';
    font-size: 4rem;
    color: #7c3aed;
    opacity: 0.2;
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    line-height: 1;
}

.article-body blockquote:not(.ql-align-center)::before {
    content: '"';
    font-size: 3rem;
    color: #7c3aed;
    opacity: 0.3;
    float: left;
    margin-right: 12px;
    line-height: 1;
    margin-top: -5px;
}

/* --- LaTeX equations ----------------------------------------- */
/* Stored as an <img> with the source in data-latex, so it renders
   identically here, in the editor, and in the mobile apps without
   any of them needing a maths library. */
.article-body img.hewa-math {
    display: inline-block;
    vertical-align: middle;
    margin: 0 2px;
    max-width: 100%;
}

/* Equations are black glyphs on transparent, which is invisible on a dark
 * page -- the reported "black on black". The colour is baked into the stored
 * data URI, so it cannot be re-themed at render time; inverting the image can.
 * Inversion leaves the alpha channel alone, so the transparent background
 * stays transparent and only the glyphs go from black to white.
 *
 * This deliberately fixes ALREADY-PUBLISHED equations too. Anything keyed on
 * how new equations are generated would have left every existing article
 * unreadable in dark mode. */
.dark .article-body img.hewa-math {
    filter: invert(1);
}

@media (prefers-color-scheme: dark) {
    .article-body img.hewa-math {
        filter: invert(1);
    }

    /* An explicit light theme must win over the media query. */
    .light .article-body img.hewa-math,
    [data-theme="light"] .article-body img.hewa-math {
        filter: none;
    }
}

.article-body img.hewa-math.is-block,
.article-body img.hewa-math[data-display="block"] {
    display: block;
    margin: 28px auto;
    /* Long equations scroll rather than overflowing the column. */
    max-width: 100%;
}


/* A captioned video: the figure/figcaption rules above already cover the
   caption itself, this only sizes the embed inside a figure. */
.article-body figure iframe {
    aspect-ratio: 16 / 9;
    height: auto;
}

/* --- Code blocks --------------------------------------------- */
/* A dark, monospaced block with a copy button, the way a chat
   interface presents code. The button is added at read time by
   public/js/code-copy.js (and by a node view in the editor) -- it
   is deliberately NOT in the stored markup, which stays a bare
   <pre class="ql-syntax"> for the mobile apps. */
/* One panel, not a stack of pieces.
 *
 * The wrapper owns the background, the rounding and the clipping; the <pre>
 * inside is transparent and only scrolls. Previously both carried a background
 * and the wrapper had neither radius nor overflow, so a long line scrolled out
 * past the rounded corners and the whole thing read as a bare black box sitting
 * behind the text. */
.hewa-code-block {
    position: relative;
    margin: 28px 0;
    background: #1e1f22;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    overflow: hidden;
}

/* The bar that makes it look like a code panel rather than a dark rectangle:
   language on the left, copy on the right. Added at read time by
   code-copy.js, never stored. */
.hewa-code-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px 8px 16px;
    background: rgba(255, 255, 255, 0.04);
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.hewa-code-lang {
    font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #8b93a7;
}

.article-body pre.ql-syntax,
.hewa-code-block pre.ql-syntax,
.hewa-code-block pre {
    margin: 0;
    padding: 16px 20px;
    background: transparent;
    color: #e6e6e6;
    border: none;
    border-radius: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 0.88rem;
    line-height: 1.6;
    white-space: pre;
    tab-size: 4;
}

/* A bare <pre> that code-copy.js has not wrapped yet -- during page load, or
   in a context where the script is absent. It still has to look right on its
   own rather than flashing as an unstyled block. */
.article-body pre.ql-syntax {
    background: #1e1f22;
    border-radius: 14px;
}

.hewa-code-block pre.ql-syntax {
    background: transparent;
}

/* --- Legacy Quill code blocks --------------------------------- */
/* Quill wrote one <div class="ql-code-block"> PER LINE inside a container,
   rather than a single <pre>. Articles published before the TipTap migration
   still carry that markup, and with no rules for it each line rendered as a
   separate full-width block with its own spacing -- the "not one block"
   problem. This makes the container the panel and the lines its rows. */
.article-body .ql-code-block-container {
    margin: 28px 0;
    padding: 16px 20px;
    background: #1e1f22;
    color: #e6e6e6;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
    font-size: 0.88rem;
    line-height: 1.6;
    tab-size: 4;
}

/* Wrapped by code-copy.js: the container becomes the scroll area only. */
.hewa-code-block .ql-code-block-container {
    margin: 0;
    background: transparent;
    border: none;
    border-radius: 0;
}

.article-body .ql-code-block {
    margin: 0;
    padding: 0;
    background: transparent;
    white-space: pre;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
}

.hewa-code-copy {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex-shrink: 0;
    padding: 4px 10px;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.06);
    color: #cbd5e1;
    font-size: 0.72rem;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

/* Always visible now that it lives in the header rather than floating over
   the first line of code. Hiding it until hover meant it did not exist at all
   on touch, which is most readers. */
.hewa-code-copy:hover {
    background: rgba(255, 255, 255, 0.16);
    color: #fff;
}

.hewa-code-copy.is-copied {
    background: #16a34a;
    border-color: #16a34a;
    color: #fff;
}

@media (max-width: 640px) {
    .article-body pre.ql-syntax,
    .hewa-code-block pre,
    .article-body .ql-code-block-container {
        padding: 14px;
        font-size: 0.8rem;
    }
}
