/* ============================================================================
   GUIDES — shared design system for every page at /guide/<slug>/
   ============================================================================

   WHAT THIS IS
   Every guide is a hardcoded template in templates/guides/ that extends
   templates/guides/base_guide.html. This file is the single place where the
   LOOK of a guide is defined: typography, callouts, tables, command blocks,
   figures, TOC, and the page furniture around them.

   Before this file existed each guide carried its own ~500-line <style> block,
   and the same component was declared 16 times over. Edit here once and every
   guide moves together.

   LOAD ORDER  (all of it is inside <head>, so nothing here blocks a later fix)
     1. tailwind.css, fonts.css, theme/tokens.css, build.css, chrome.css,
        custom.css, legacy.css        <- base.html
     2. THIS FILE                     <- base_guide.html, extra_head block
     3. the guide's own <style>       <- guide_extra_head block, loads last

   Because a guide's own <style> loads after this file, a per-guide rule of
   equal specificity still wins. That is the intended escape hatch: bespoke
   diagrams, scenes and one-off components stay in the guide. Anything that
   two or more guides would want belongs here instead.

   TOKENS
   Colours, radii, shadows and font stacks come from theme/tokens.css. Use the
   variables (--accent, --ink, --surface, --line, --radius, --c-ink-900, ...)
   rather than literals so a theme change reaches guides for free.

   SCOPE
   Everything is scoped to .guide-body, the main column in base_guide.html.
   That keeps guide styling off the sidebar, the nav and the footer.
   ========================================================================== */


/* ---------------------------------------------------------------------------
   1. Anchor offset
   The site nav (NAV.lw-nav) is sticky at top:0 and 98px tall, so a jump target
   must clear more than that or the nav covers the heading you just jumped to.
   7rem = 112px. Scoped with `body` so it wins against any per-guide rule.
   --------------------------------------------------------------------------- */
body .guide-body h2[id],
body .guide-body h3[id],
body .guide-body h4[id] {
    scroll-margin-top: 7rem;
}


/* ---------------------------------------------------------------------------
   2. Prose typography
   --------------------------------------------------------------------------- */
.guide-body p {
    color: var(--ink);
    line-height: 1.75;
    margin-bottom: 1.1rem;
}

.guide-body h2 {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: 1.85rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.25;
    margin-top: 3rem;
    margin-bottom: 1rem;
}

.guide-body h3 {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: 1.35rem;
    font-weight: 600;
    margin-top: 2.25rem;
    margin-bottom: 0.75rem;
}

.guide-body .lead {
    color: var(--ink);
    font-size: 1.2rem;
    line-height: 1.7;
}

.guide-body hr {
    border: none;
    border-top: 1px solid var(--line);
    margin: 2.75rem 0;
}


/* ---------------------------------------------------------------------------
   3. Lists
   .checklist, .hero-meta and .related-list are excluded: they are layout lists
   with their own markers, and inheriting disc + indent from here breaks them.
   .list-plain is the generic opt-out for any other layout list a guide builds
   (card grids, action rows): put it next to the guide's own class and this
   rule leaves the list alone. Without it, this selector's :not() chain
   out-specifies a per-guide `.guide-body .my-grid` reset and the indent wins.
   --------------------------------------------------------------------------- */
.guide-body ol,
.guide-body ul:not(.checklist):not(.hero-meta):not(.related-list):not(.list-plain) {
    margin-bottom: 1.25rem;
    padding-left: 1.5rem;
}

.guide-body ul:not(.checklist):not(.hero-meta):not(.related-list):not(.list-plain) {
    list-style: disc;
}

.guide-body ol {
    list-style: decimal;
}

.guide-body li {
    line-height: 1.7;
    margin-bottom: 0.45rem;
}


/* ---------------------------------------------------------------------------
   4. Links
   --------------------------------------------------------------------------- */
.guide-body a {
    color: var(--accent);
    font-weight: 500;
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
}

.guide-body a:hover {
    color: var(--accent-strong);
    text-decoration-color: var(--accent-strong);
}


/* ---------------------------------------------------------------------------
   5. Inline code
   --------------------------------------------------------------------------- */
.guide-body code {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: 0.35rem;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 0.9em;
    padding: 0.1rem 0.4rem;
}

/* Tailwind Typography (`prose`) decorates inline <code> with literal backticks
   via code::before / code::after. Guides style inline code as a chip, so those
   render as stray characters inside the chip: `HTTPS_PORT`. */
.guide-body code::before,
.guide-body code::after {
    content: none;
}

/* Long unbroken strings in inline code (file paths, keys, URLs) do not wrap by
   default and push the whole page sideways on phones. A single
   /data/coolify/ssh/keys/id.root@host.docker.internal.pub was overflowing a
   390px viewport by 177px. */
.guide-body :not(pre) > code {
    overflow-wrap: anywhere;
    word-break: break-word;
}


/* ---------------------------------------------------------------------------
   6. Hero meta — the pill row of facts under the H1
   --------------------------------------------------------------------------- */
.guide-body ul.hero-meta {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.6rem;
    list-style: none;
    margin: 1rem 0 0;
    padding-left: 0;
}

.guide-body ul.hero-meta li {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    color: var(--ink);
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.2;
    margin: 0;
    padding: 0.3rem 0.7rem;
    white-space: nowrap;
}

.guide-body ul.hero-meta li strong {
    color: var(--accent);
    font-weight: 700;
}

/* "Last verified" provenance note.
   This was styled as a compact tinted badge — inline-flex, 1px signal border,
   green wash — on the assumption it held a date. In practice every guide puts
   a full sentence in it (51 to 196 characters), so the badge stretched the
   width of the column and became a green slab with wrapping text.

   It is a footnote about how the guide was checked, so it now reads as one:
   no box, a small check in the signal colour, and the claim in muted text. */
/* Block, not flex. Flex would make the <strong> and the sentence after it two
   separate flex items, so "Last verified:" collapses into its own narrow
   wrapping column. Keeping normal inline flow lets the label and the claim run
   together as one paragraph, with the icon hanging in the left gutter. */
.guide-body .last-verified {
    display: block;
    position: relative;
    margin-top: 1rem;
    padding-left: 1.5rem;
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.6;
}

.guide-body .last-verified::before {
    --ico-verified: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m8.2 12.3 2.6 2.6 5-5.4'/%3E%3C/svg%3E");
    content: "";
    position: absolute;
    left: 0;
    top: 0.3em;                  /* optical align to the first line of text */
    width: 0.95rem;
    height: 0.95rem;
    background: var(--signal);
    -webkit-mask: var(--ico-verified) center / contain no-repeat;
    mask: var(--ico-verified) center / contain no-repeat;
}

.guide-body .last-verified strong {
    color: var(--ink);
    font-weight: 600;
}


/* ---------------------------------------------------------------------------
   6b. Byline — avatar + author, then the published / updated dates
   Markup is the guide_header block in base_guide.html. The avatar replaces the
   old "By " prefix, so the face is the label and the name reads as the value.
   --------------------------------------------------------------------------- */
.guide-body .guide-byline {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 0.75rem;
    font-size: 0.875rem;
    line-height: 1.4;
    color: var(--muted);
}

.guide-body .guide-byline__author {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
    color: var(--ink);
}

.guide-body .guide-byline__avatar {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    margin: 0;                  /* reset the Tailwind `prose` img margin */
    border-radius: var(--radius-pill);
    border: 1px solid var(--line);
    background: var(--surface-2);
    object-fit: cover;
}

.guide-body .guide-byline__sep {
    margin: 0 0.6rem;
    opacity: 0.55;
    user-select: none;
}


/* ---------------------------------------------------------------------------
   7. Breadcrumb (top of the guide header)
   Links are scoped as `.guide-body a.guide-breadcrumb__link` so they
   out-specify the `.guide-body a` rule above. The hub crumb only appears when
   the guide maps to a public hub index (see guides/views._hub_back).
   --------------------------------------------------------------------------- */
.guide-body .guide-breadcrumb {
    margin-bottom: 1.5rem;
}

.guide-body .guide-breadcrumb ol {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.5rem;
    font-size: 0.78rem;
    line-height: 1.3;
}

.guide-body .guide-breadcrumb li {
    display: flex;
    align-items: center;
    margin: 0;
}

.guide-body a.guide-breadcrumb__link {
    color: var(--muted);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.15s ease;
}

.guide-body a.guide-breadcrumb__link:hover {
    color: var(--accent);
    text-decoration: none;
}

.guide-body .guide-breadcrumb__sep {
    color: var(--muted);
    opacity: 0.55;
    user-select: none;
}

.guide-body .guide-breadcrumb__current {
    color: var(--ink);
    font-weight: 600;
}


/* ---------------------------------------------------------------------------
   8. Table of contents
   Two shapes share these rules: a plain <ol> box, and a collapsible
   <details><summary> box. Both use .toc.
   --------------------------------------------------------------------------- */
.guide-body .toc {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    margin: 1.75rem 0;
    padding: 1.1rem 1.4rem 1.2rem;
}

/* Every guide now uses the <details open><summary> shape, so `summary` below is
   the real heading. The h2 selector stays as a safety net for a hand-written
   TOC that skips the disclosure. */
.guide-body .toc h2 {
    color: var(--accent);
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    margin: 0 0 0.7rem;
    text-transform: uppercase;
}

.guide-body .toc ol {
    list-style: decimal;
    margin: 0;
    padding-left: 1.3rem;
}

.guide-body .toc li {
    line-height: 1.5;
    margin-bottom: 0.3rem;
}

/* No underline here. A table of contents is a dense stack of links, and the
   2px underline from `.guide-body a` turns it into a block of stripes. The
   hover underline keeps the affordance without the noise. */
.guide-body .toc a {
    font-weight: 600;
    text-decoration: none;
}

.guide-body .toc a:hover {
    text-decoration: underline;
}

/* --- collapsible variant --- */
.guide-body .toc summary {
    align-items: center;
    color: var(--accent);
    cursor: pointer;
    display: flex;
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    list-style: none;
    text-transform: uppercase;
}

.guide-body .toc summary::-webkit-details-marker {
    display: none;
}

.guide-body .toc summary::after {
    content: "+";
    font-size: 1.05rem;
    line-height: 1;
    margin-left: auto;
}

.guide-body .toc details[open] summary {
    margin-bottom: 0.75rem;
}

.guide-body .toc details[open] summary::after {
    content: "\2212";   /* minus */
}


/* ---------------------------------------------------------------------------
   9. Callouts
   One tone variable drives the whole component:
       .callout            neutral / note   (--accent-2)
       .callout--tip       green            (--signal)
       .callout--warn      yellow           (--warn)
       .callout--danger    red              (--danger)
       .callout--lead      roomier padding, for the opening callout

   The box is PAPER, not a tint. Callouts used to be a flat pastel wash across
   the full width, which read as an admin-panel alert and fought the cream page
   for attention. Now the tone appears only as a 3px spine on the left edge and
   in the label — the content sits on the same surface as the rest of the page,
   so the box reads as a considered aside rather than a coloured slab.

   --cwt is the tone pushed toward ink. Several tones (--warn, --signal) are far
   too light to use as text or a thin icon stroke on paper; --cwt keeps the hue
   but earns the contrast.
   --------------------------------------------------------------------------- */
.guide-body .callout {
    --cw: var(--accent-2);
    --cwt: color-mix(in srgb, var(--cw) 62%, var(--ink));
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--cw);
    border-radius: var(--radius);
    margin: 2rem 0;
    padding: 1.3rem 1.6rem;
}

.guide-body .callout--tip    { --cw: var(--signal); }
.guide-body .callout--warn   { --cw: var(--warn); }
.guide-body .callout--danger { --cw: var(--danger); }
.guide-body .callout--lead   { padding: 1.45rem 1.7rem; }

.guide-body .callout-head {
    align-items: center;
    display: flex;
    gap: 0.55rem;
    margin-bottom: 0.8rem;
}

/* No chip. The icon used to sit in a 2.5rem bordered, shadowed, tinted square —
   three nested containers around one glyph. It now sits inline at label size. */
.guide-body .callout-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 1.05rem;
    line-height: 1;
}

/* A kicker, not a heading: small, letterspaced, tone-coloured. Matches the
   label pattern already used by .toc h2, .magnet-label and .pers-label. */
.guide-body .callout-label {
    color: var(--cwt);
    font-family: var(--font-body);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.11em;
    line-height: 1.3;
    text-transform: uppercase;
}

/* --- Drawn callout icons ------------------------------------------------
   The chip used to hold an emoji, which rendered as a different picture on
   every OS and pulled a colour palette we don't control into the callout.
   These are stroked SVGs painted through a CSS mask instead, so the icon
   inherits the callout's own tone (--cw) and stays crisp at any zoom.

   Markup: <span class="callout-ico callout-ico--summary" aria-hidden="true"></span>
   Adding one is a two-line job: define --callout-ico on a new modifier below.
   The art lives here, not in the guides, so every guide moves together.

   The mask only reads the SVG's alpha channel, so the stroke colour inside
   the data URI is irrelevant — `background` below is what you actually see. */
.guide-body [class*="callout-ico--"]::before {
    content: "";
    width: 1.05rem;
    height: 1.05rem;
    background: var(--cwt);
    -webkit-mask: var(--callout-ico) center / contain no-repeat;
    mask: var(--callout-ico) center / contain no-repeat;
}

/* Without mask support the rule above would paint a solid coloured square,
   which is worse than no icon at all. */
@supports not ((-webkit-mask: none) or (mask: none)) {
    .guide-body [class*="callout-ico--"]::before { display: none; }
}

/* Three lines, the last one short — a summary. Used for TL;DR. */
.guide-body .callout-ico--summary {
    --callout-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 7h16'/%3E%3Cpath d='M4 12h16'/%3E%3Cpath d='M4 17h9'/%3E%3C/svg%3E");
}

/* Circled check — what you'll have once the guide is done. */
.guide-body .callout-ico--outcome {
    --callout-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m8.2 12.3 2.6 2.6 5-5.4'/%3E%3C/svg%3E");
}

/* Triangle with a mark — the thing to not trip over. For .callout--warn. */
.guide-body .callout-ico--warn {
    --callout-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3'/%3E%3Cpath d='M12 9v4'/%3E%3Cpath d='M12 17h.01'/%3E%3C/svg%3E");
}

/* Lightbulb — a tip worth keeping. For .callout--tip. */
.guide-body .callout-ico--tip {
    --callout-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5'/%3E%3Cpath d='M9 18h6'/%3E%3Cpath d='M10 22h4'/%3E%3C/svg%3E");
}

.guide-body .callout p { margin-bottom: 0.8rem; }
.guide-body .callout p:last-child { margin-bottom: 0; }

/* --- "What you'll have at the end" --------------------------------------
   This box lists results, so its bullets are checks. Indigo rather than the
   default violet: violet at 62% over cream went muddy, and the brand accent
   suits a promise about the finished state.

   :has() keeps this to the one box without touching the markup. Where it is
   unsupported the box simply keeps the default tone and disc bullets. */
.guide-body .callout:has(.callout-ico--outcome) { --cw: var(--accent); }

/* The two :not() selectors are here to win a specificity fight, not to exclude anything
   meaningful. The generic prose rule near the top of this file carries three :not()s, so
   it scores four classes and beat the three-class selector this used to be -- which left a
   disc bullet sitting underneath the check in every outcome callout on the site.
   .checklist is deliberately NOT excluded: lists that already carry that class get no
   resets at all from the generic rule and still need these. */
.guide-body .callout:has(.callout-ico--outcome) ul:not(.hero-meta):not(.related-list) {
    list-style: none;
    margin: 0;
    padding-left: 0;
}

.guide-body .callout:has(.callout-ico--outcome) li {
    position: relative;
    margin-bottom: 0.5rem;
    padding-left: 1.65rem;
}

.guide-body .callout:has(.callout-ico--outcome) li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.42em;
    width: 0.95rem;
    height: 0.95rem;
    background: var(--cwt);
    -webkit-mask: var(--ico-check) center / contain no-repeat;
    mask: var(--ico-check) center / contain no-repeat;
    --ico-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5 9 17.5 20 6.5'/%3E%3C/svg%3E");
}


/* ---------------------------------------------------------------------------
   10. Tables
   Wrap every table in .guide-table-wrap so a wide table scrolls itself instead
   of pushing the page sideways on mobile.
   --------------------------------------------------------------------------- */
.guide-body .guide-table-wrap {
    margin: 1.5rem 0 2rem;
    overflow-x: auto;
}

.guide-body table {
    background: var(--surface);
    border: 1px solid var(--line);
    border-collapse: separate;
    border-radius: var(--radius);
    border-spacing: 0;
    box-shadow: var(--shadow-sm);
    font-size: 0.93rem;
    overflow: hidden;
    width: 100%;
}

.guide-body thead th {
    background: var(--surface-ink);
    color: var(--c-paper);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 0.75rem 0.9rem;
    text-align: left;
    text-transform: uppercase;
}

.guide-body tbody td {
    border-top: 1px solid var(--line);
    line-height: 1.55;
    padding: 0.75rem 0.9rem;
    vertical-align: top;
}

.guide-body tbody tr:first-child td { border-top: none; }
.guide-body tbody tr:nth-child(even) td { background: var(--surface-2); }
.guide-body tbody td strong { color: var(--ink); }
.guide-body tbody td code { font-size: 0.85em; }


/* ---------------------------------------------------------------------------
   11. Figures, images and video
   --------------------------------------------------------------------------- */
.guide-body figure.guide-image {
    margin: 1.75rem 0 2rem;
}

.guide-body figure.guide-image img {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    display: block;
    height: auto;
    width: 100%;
}

.guide-body figure.guide-image figcaption {
    color: var(--muted);
    font-size: 0.875rem;
    font-style: italic;
    margin-top: 0.75rem;
    text-align: center;
}

/* Square/portrait screenshots would otherwise blow up to full column width. */
.guide-body figure.guide-image--square img {
    margin: 0 auto;
    max-width: 560px;
}


/* Two-up screenshot comparison. */
.guide-body .img-grid {
    align-items: start;
    display: grid;
    gap: 1.1rem;
    grid-template-columns: repeat(2, 1fr);
    margin: 1.75rem 0 2rem;
}

.guide-body .img-grid figure { margin: 0; }

.guide-body .img-grid img {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    display: block;
    height: auto;
    width: 100%;
}

.guide-body .img-grid figcaption {
    color: var(--muted);
    font-size: 0.8rem;
    line-height: 1.45;
    margin-top: 0.5rem;
    text-align: center;
}

.guide-body .img-grid figcaption strong { color: var(--ink); }

/* Responsive 16:9 iframe holder. */
.guide-body .video-embed {
    background: var(--c-ink-900);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin: 1.75rem 0 2rem;
    overflow: hidden;
    padding-bottom: 56.25%;
    position: relative;
    width: 100%;
}

.guide-body .video-embed iframe {
    border: 0;
    height: 100%;
    inset: 0;
    position: absolute;
    width: 100%;
}


/* ---------------------------------------------------------------------------
   12. Command and output blocks
   Three treatments, because which one you use tells the reader what to DO with
   the block (see the guides skill, references/beginner-floor.md R3):

       .prompt-block   you run this           dark terminal + copy button
       .file-block     you save this to disk  dark terminal + path bar + copy
       .out-block      you get this back      light inset panel, NO copy button

   The copy button is injected by base_guide.html's script, which only walks
   .prompt-block — so .out-block staying uncopyable is automatic rather than
   something each guide has to remember.
   --------------------------------------------------------------------------- */
.guide-body .prompt-block {
    background: var(--c-ink-900);
    border: 1px solid var(--c-ink-700);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    color: var(--c-ink-300);
    font-family: var(--font-mono);
    font-size: 0.88rem;
    line-height: 1.65;
    margin: 1.25rem 0 1.5rem;
    overflow-x: auto;
    padding: 1.5rem 1.75rem;
    white-space: pre-wrap;
    word-wrap: break-word;
}

/* --- file block: a path bar welded to the top of a terminal pane --- */
.guide-body .file-block { margin: 0 0 1.35rem; }

.guide-body .file-block__path {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    background: var(--c-ink-800);
    color: var(--c-ink-400);
    border: 1px solid var(--c-ink-700);
    border-bottom: 0;
    border-radius: var(--radius) var(--radius) 0 0;
    padding: 0.5rem 1.1rem;
    font-family: var(--font-mono);
    font-size: 0.78rem;
    word-break: break-all;
}

.guide-body .file-block__path::before {
    content: "";
    flex: 0 0 auto;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 2px;
    background: var(--accent);
}

/* The copy-button JS wraps the <pre> in .prompt-wrapper, so target both the
   wrapped and unwrapped shapes to keep the pane welded to its path bar. */
.guide-body .file-block .prompt-wrapper { margin: 0; }

.guide-body .file-block .prompt-block {
    margin: 0;
    border-radius: 0 0 var(--radius) var(--radius);
}

/* --- output block --- */
.guide-body .out-block {
    background: var(--surface-2);
    color: var(--ink);
    border: 1px solid var(--line);
    border-left: 3px solid var(--muted);
    border-radius: var(--radius-sm);
    padding: 0.9rem 1.15rem;
    margin: 0 0 1.35rem;
    font-family: var(--font-mono);
    font-size: 0.84rem;
    line-height: 1.6;
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-x: auto;
}

.guide-body .out-block__label {
    display: block;
    font-family: var(--font-body);
    font-size: 0.67rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--muted);
    margin-bottom: 0.45rem;
}

/* --- source-code block: never wrap, scroll instead, and cap the height --- */
.guide-body .prompt-block.prompt-code {
    -webkit-overflow-scrolling: touch;
    max-height: 30rem;
    overflow: auto;
    tab-size: 4;
    white-space: pre;
    word-wrap: normal;
}

.guide-body .prompt-code {
    scrollbar-color: var(--c-ink-700) var(--c-ink-900);
    scrollbar-width: thin;
}

.guide-body .prompt-code::-webkit-scrollbar { height: 10px; width: 10px; }
.guide-body .prompt-code::-webkit-scrollbar-track { background: var(--c-ink-900); }

.guide-body .prompt-code::-webkit-scrollbar-thumb {
    background: var(--c-ink-700);
    border: 2px solid var(--c-ink-900);
    border-radius: 6px;
}

.guide-body .prompt-code::-webkit-scrollbar-thumb:hover { background: var(--c-ink-600); }

/* Lets the wrapper own the border/radius so a capped code pane clips cleanly. */
.guide-body .prompt-wrapper--code {
    border: 1px solid var(--c-ink-700);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin: 1.25rem 0 1.5rem;
    overflow: hidden;
}

.guide-body .prompt-wrapper--code .prompt-code {
    border: none;
    border-radius: 0;
    box-shadow: none;
    margin: 0;
}

/* --- copy-to-clipboard button (injected by base_guide.html) --- */
.prompt-wrapper {
    position: relative;
}

.prompt-copy {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    background: var(--accent);
    color: #fff;
    border: 1px solid transparent;
    border-radius: 0.4rem;
    padding: 0.35rem 0.75rem;
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    line-height: 1;
    transition: transform 0.1s ease, background 0.15s ease;
    z-index: 1;
}

.prompt-copy:hover { transform: translateY(-1px); }
.prompt-copy:active { transform: translateY(0); }

.prompt-copy.is-copied {
    background: var(--signal);
    color: var(--c-ink);
}

/* Reserve right padding inside the pane so the button never overlaps text. */
.guide-body .prompt-wrapper .prompt-block {
    padding-right: 5rem;
}


/* ---------------------------------------------------------------------------
   13. FAQ and author note
   --------------------------------------------------------------------------- */
.guide-body .faq h3 {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.35;
    margin-top: 2.5rem;
    margin-bottom: 0.7rem;
}

.guide-body .faq h3:first-of-type { margin-top: 1.25rem; }
.guide-body .faq p { margin-bottom: 0.6rem; }

/* Photo-left author strip: Hasan's cutout stands on a single bottom rule
   (no card background), the guide's closing line sits in a speech bubble to
   his right, bio below it. Markup is templates/guides/_author_box.html —
   pass `closing` (+ optional `verified`) via {% include ... with ... %}. */
.guide-body .guide-author {
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: flex-end;
    gap: 1.75rem;
    line-height: 1.6;
    margin: 4rem 0 0;          /* top room for the head overlap */
    padding: 0 1.75rem;
}

.guide-body .guide-author__figure {
    flex: 0 0 190px;
    margin: -2.25rem 0 0;      /* the head breaks the card's top edge */
}

.guide-body .guide-author__figure img {
    display: block;
    width: 100%;
    height: auto;
    margin: 0;                 /* reset the Tailwind `prose` img margin */
}

.guide-body .guide-author__text {
    align-self: stretch;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 1.4rem 0;
}

.guide-body .guide-author__bubble {
    position: relative;
    align-self: flex-start;
    background: var(--surface);
    border: 1.5px solid var(--ink);
    border-radius: var(--radius);
    box-shadow: 2.5px 2.5px 0 color-mix(in srgb, var(--ink) 85%, transparent);
    color: var(--ink);
    font-family: var(--font-display);
    font-size: 1.02rem;
    font-weight: 700;
    margin: 0 0 1rem;
    padding: 0.55rem 0.95rem;
}

.guide-body .guide-author__bubble::after {
    content: "";
    position: absolute;
    left: -8px;
    top: 50%;
    transform: translateY(-50%) rotate(45deg);
    width: 12px;
    height: 12px;
    background: var(--surface);
    border-left: 1.5px solid var(--ink);
    border-bottom: 1.5px solid var(--ink);
}

.guide-body .guide-author__bio {
    color: var(--ink);
    font-size: 0.95rem;
    margin: 0;
}

@media (max-width: 640px) {
    .guide-body .guide-author {
        flex-direction: column;
        align-items: center;
        gap: 0;
        padding: 0 1.25rem;
        text-align: center;
    }

    .guide-body .guide-author__figure { flex-basis: auto; width: 170px; }

    .guide-body .guide-author__text { align-items: center; padding-top: 0; }

    .guide-body .guide-author__bubble { align-self: center; }

    .guide-body .guide-author__bubble::after {
        left: 2.2rem;
        top: -8px;
        transform: rotate(45deg);
        border: none;
        border-left: 1.5px solid var(--ink);
        border-top: 1.5px solid var(--ink);
    }
}


/* ---------------------------------------------------------------------------
   14. Inline lead-magnet card
   --------------------------------------------------------------------------- */
.guide-body .magnet-card {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface));
    border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin: 2rem 0;
    padding: 1.5rem 1.75rem;
}

.guide-body .magnet-card .magnet-label {
    color: var(--accent);
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    margin-bottom: 0.5rem;
    text-transform: uppercase;
}

.guide-body .magnet-card .magnet-title {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0 0 0.6rem;
}

.guide-body .magnet-card ul { margin-bottom: 1rem; }

.guide-body .magnet-btn {
    background: var(--accent);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    color: #fff;
    display: inline-block;
    font-size: 0.9rem;
    font-weight: 700;
    margin-top: 0.4rem;
    padding: 0.6rem 1.2rem;
    text-decoration: none;
}

.guide-body .magnet-btn:hover {
    color: #fff;
    filter: brightness(1.08);
    text-decoration: none;
}


/* ---------------------------------------------------------------------------
   15. Personalisation widget
   The card where a reader types their domain/host, and .pdt-var spans in the
   command blocks that get rewritten with it (see the per-guide script).
   --------------------------------------------------------------------------- */
.guide-body .pers-card {
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin: 1.75rem 0;
    padding: 1.25rem 1.5rem;
}

.guide-body .pers-card .pers-label {
    color: var(--signal);
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    margin-bottom: 0.5rem;
    text-transform: uppercase;
}

.guide-body .pers-card .pers-title {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 700;
    margin: 0 0 0.4rem;
}

.guide-body .pers-card .pers-help {
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1.55;
    margin: 0 0 0.85rem;
}

.guide-body .pers-card .pers-input-row {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem;
}

.guide-body .pers-card .pers-field {
    display: block;
    margin: 0.65rem 0 0;
}

.guide-body .pers-card .pers-field-label {
    color: var(--muted);
    display: block;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    margin-bottom: 0.3rem;
    text-transform: uppercase;
}

.guide-body .pers-card input[type="text"] {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    color: var(--ink);
    flex: 1 1 240px;
    font-family: var(--font-mono);
    font-size: 0.92rem;
    line-height: 1.3;
    min-width: 0;
    padding: 0.55rem 0.75rem;
}

.guide-body .pers-card input[type="text"]::placeholder { color: var(--muted); }

.guide-body .pers-card input[type="text"]:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
    outline: none;
}

.guide-body .pers-card .pers-reset {
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    color: var(--muted);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    line-height: 1;
    padding: 0.5rem 0.85rem;
    transition: color 0.15s, border-color 0.15s;
}

.guide-body .pers-card .pers-reset:hover {
    border-color: var(--danger);
    color: var(--danger);
}

.guide-body .pers-card .pers-status {
    color: var(--muted);
    font-size: 0.78rem;
    line-height: 1.45;
    margin: 0.85rem 0 0;
}

.guide-body .pers-card .pers-status.is-active {
    color: var(--signal);
    font-weight: 600;
}

.guide-body .pdt-var {
    background: inherit;
    color: inherit;
    font: inherit;
    transition: background-color 0.2s, padding 0.2s;
}

.guide-body .pdt-var.is-customized {
    background: rgba(99, 102, 241, 0.16);
    border-radius: 3px;
    padding: 0 0.18em;
}

/* On the dark terminal the light tint above is invisible — go brighter. */
.guide-body .prompt-block .pdt-var.is-customized {
    background: rgba(99, 102, 241, 0.32);
    color: var(--c-paper);
}


/* ---------------------------------------------------------------------------
   16. Prev / next guide navigation
   Two shapes exist. .guide-postnav is the current one, rendered by the
   guide_post_nav template tag (guides/_post_nav.html) with thumbnails.
   .guide-nav is the older hand-written pair of text cards, still used by
   several guides.
   --------------------------------------------------------------------------- */
.guide-body .guide-postnav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin: 2.5rem 0 1.5rem;
}

@media (max-width: 640px) {
    .guide-body .guide-postnav { grid-template-columns: 1fr; }
}

.guide-body a.guide-postnav__card {
    display: flex;
    align-items: stretch;
    gap: 0;
    min-width: 0;
    min-height: 92px;
    padding: 0;
    overflow: hidden;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--ink);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.guide-body a.guide-postnav__card:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-sm);
    transform: translateY(-2px);
    text-decoration: none;
}

.guide-body .guide-postnav__card--next { text-align: right; }

.guide-body .guide-postnav__thumb {
    flex: 0 0 auto;
    width: 150px;
    align-self: stretch;
    overflow: hidden;
    background: var(--surface-2);
}

@media (max-width: 480px) {
    .guide-body .guide-postnav__thumb { width: 108px; }
}

.guide-body .guide-postnav__thumb img {
    margin: 0;              /* reset the Tailwind `prose` 2em img margin */
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.guide-body .guide-postnav__text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.3rem;
    min-width: 0;
    flex: 1 1 auto;
    padding: 0.8rem 1rem;
}

.guide-body .guide-postnav__card--next .guide-postnav__text {
    align-items: flex-end;
}

.guide-body .guide-postnav__label {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--muted);
    transition: color 0.15s ease;
}

.guide-body a.guide-postnav__card:hover .guide-postnav__label { color: var(--accent); }

.guide-body .guide-postnav__title {
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--ink);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.guide-body .guide-postnav__arrow { display: inline-block; transition: transform 0.15s ease; }
.guide-body a.guide-postnav__card--prev:hover .guide-postnav__arrow { transform: translateX(-3px); }
.guide-body a.guide-postnav__card--next:hover .guide-postnav__arrow { transform: translateX(3px); }

.guide-body .guide-postnav__spacer { display: none; }
@media (min-width: 641px) {
    .guide-body .guide-postnav__spacer { display: block; }
}

/* --- older text-only prev/next pair --- */
.guide-body .guide-nav {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr 1fr;
    margin: 2.5rem 0 1.5rem;
}

@media (max-width: 640px) {
    .guide-body .guide-nav { grid-template-columns: 1fr; }
}

.guide-body .guide-nav a {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    color: var(--ink);
    display: block;
    font-weight: 500;
    padding: 1rem 1.15rem;
    text-decoration: none;
    transition: transform 0.1s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.guide-body .guide-nav a:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow);
    transform: translateY(-1px);
}

.guide-body .guide-nav a .guide-nav-label {
    color: var(--accent);
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    margin-bottom: 0.25rem;
    text-transform: uppercase;
}

.guide-body .guide-nav a .guide-nav-title {
    display: block;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.35;
}

.guide-body .guide-nav .guide-nav--next { text-align: right; }


/* ---------------------------------------------------------------------------
   16b. Related links
   Was a bulleted list of "EMOJI <underlined link>: description", which read as
   raw HTML rather than a component — three colours and an underline per row.
   Now full-width rows: the whole row is the target, the title carries the
   weight, the description sits back in muted text, and a chevron slides in on
   hover. Rows carrying more than one link keep prose styling (.related-note).
   --------------------------------------------------------------------------- */
.guide-body .related-list {
    list-style: none;
    margin: 1.25rem 0 2rem;
    padding: 0;
    border-top: 1px solid var(--line);
}

.guide-body .related-list li {
    margin: 0;
}

.guide-body a.related-item,
.guide-body .related-note {
    display: block;
    position: relative;
    padding: 0.85rem 2.25rem 0.85rem 0.15rem;
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    font-size: 0.95rem;
    line-height: 1.55;
    text-decoration: none;
    transition: background-color 0.15s ease, padding-left 0.15s ease;
}

.guide-body a.related-item:hover {
    background: var(--surface-2);
    padding-left: 0.7rem;
    text-decoration: none;
}

.guide-body .related-item__title {
    color: var(--ink);
    font-weight: 600;
}

.guide-body a.related-item:hover .related-item__title {
    color: var(--accent);
}

/* Separator lives here, not in the markup, so a row with no description
   doesn't render a dangling dash. */
.guide-body .related-item__desc::before {
    content: " — ";
}

.guide-body a.related-item::after {
    --ico-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E");
    content: "";
    position: absolute;
    right: 0.7rem;
    top: 50%;
    width: 0.8rem;
    height: 0.8rem;
    background: var(--accent);
    -webkit-mask: var(--ico-chevron) center / contain no-repeat;
    mask: var(--ico-chevron) center / contain no-repeat;
    opacity: 0;
    transform: translate(-4px, -50%);
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.guide-body a.related-item:hover::after {
    opacity: 1;
    transform: translate(0, -50%);
}


/* ---------------------------------------------------------------------------
   16c. Course CTA
   The one commercial block in a guide. It used to be a .callout--tip holding a
   rocket emoji and an underlined text link, so the page's conversion point was
   indistinguishable from an advice box and its action didn't look clickable.

   It is now its own component: a bar with the pitch on the left and a real
   button on the right. Deliberately the only place in the guide body with a
   filled accent button, so nothing else competes with it.
   --------------------------------------------------------------------------- */
.guide-body .guide-cta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem 1.5rem;
    margin: 2.25rem 0;
    padding: 1.4rem 1.6rem;
    background: color-mix(in srgb, var(--accent) 5%, var(--surface));
    border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line));
    border-radius: var(--radius);
}

.guide-body .guide-cta__eyebrow {
    margin: 0 0 0.3rem;
    color: var(--accent);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.11em;
    line-height: 1.3;
    text-transform: uppercase;
}

.guide-body .guide-cta__title {
    margin: 0;
    color: var(--ink);
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.3;
}

/* Optional supporting line — price, access terms. */
.guide-body .guide-cta__note {
    margin: 0.3rem 0 0;
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.4;
}

.guide-body a.guide-cta__btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.7rem 1.3rem;
    background: var(--accent);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    color: #fff;
    font-size: 0.92rem;
    font-weight: 700;
    text-decoration: none;
    transition: background-color 0.15s ease, transform 0.15s ease;
}

.guide-body a.guide-cta__btn::after {
    content: "\2192";           /* arrow lives here so the label stays plain text */
    transition: transform 0.15s ease;
}

.guide-body a.guide-cta__btn:hover {
    background: var(--accent-strong);
    color: #fff;
    text-decoration: none;
    transform: translateY(-1px);
}

.guide-body a.guide-cta__btn:hover::after {
    transform: translateX(3px);
}


/* ---------------------------------------------------------------------------
   17. Community CTA
   The button is a primary button but lives inside .guide-body, whose
   `.guide-body a` colour would otherwise repaint its label (indigo on indigo
   = invisible). Keep the label white, including on hover.
   --------------------------------------------------------------------------- */
.guide-community .lw-btn--primary,
.guide-community .lw-btn--primary:hover { color: #fff; }
