/* ==========================================================================
   briankrug.com — "The Split"

   A sticky identity rail on the left, content scrolling on the right. The rail
   is the masthead and the navigation at once, which is why interior pages need
   nothing but a heading and a body.

   Fonts are self-hosted. The site proxies its own analytics first-party
   specifically so that no third party sees a reader's request; loading type
   from Google would hand that back for nothing.
   ========================================================================== */

/* --- Fonts ---------------------------------------------------------------
   Source Serif 4, self-hosted. The site proxies its own analytics first-party
   precisely so no third party sees a reader's request; pulling type from Google
   would hand that back for nothing.

   These are VARIABLE fonts, so one upright file covers every weight the theme
   uses — Google serves the same bytes for a 400 and a 600 request, and shipping
   both would have been 223 KB of duplicate. Hence `font-weight: 200 900`
   rather than a file per weight.

   Split latin / latin-ext by unicode-range: latin-ext is only fetched when a
   page actually contains a character that needs it. It usually does here —
   Hébert, Negrón-Lomas, Harutyunyan — but not on every page.

   font-display:swap so text paints in the fallback rather than sitting
   invisible while the file loads. */

@font-face {
    font-family: "Source Serif";
    src: url("../fonts/source-serif-latin.woff2") format("woff2");
    font-weight: 200 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Source Serif";
    src: url("../fonts/source-serif-latin-ext.woff2") format("woff2");
    font-weight: 200 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Source Serif";
    src: url("../fonts/source-serif-italic-latin.woff2") format("woff2");
    font-weight: 200 900;
    font-style: italic;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Source Serif";
    src: url("../fonts/source-serif-italic-latin-ext.woff2") format("woff2");
    font-weight: 200 900;
    font-style: italic;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Tokens --------------------------------------------------------------- */

:root {
    --ink:        #16161a;
    --ink-soft:   #55555e;
    --ink-faint:  #8a8a94;
    --rule:       #e2e2e6;
    --paper:      #ffffff;
    --paper-alt:  #fafaf9;
    --accent:     #7a1f2b;

    /* Ghost 6 lets an admin choose fonts in Settings > Design, and injects
       --gh-font-heading / --gh-font-body when they do. Honouring them means a
       font change in Ghost actually takes effect; the fallback is the theme's
       own Source Serif, which is what ships and what the design assumes. */
    --stack: "Source Serif", "Iowan Old Style", "Palatino Linotype",
             Palatino, Georgia, "Times New Roman", serif;

    --serif:         var(--gh-font-body, var(--stack));
    --serif-heading: var(--gh-font-heading, var(--stack));

    --measure: 34rem;
}

*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--serif);
    font-size: 1.0625rem;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

a { color: inherit; }

img { max-width: 100%; display: block; }

/* The rail precedes the content in source order, so without this a keyboard
   user tabs the whole navigation on every page before reaching anything. */
.skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: .75rem 1rem;
    background: var(--ink);
    color: #fff;
    text-decoration: none;
}

.skip:focus { left: 0; }

/* --- Top bar (mobile only) -----------------------------------------------
   On desktop the rail carries the navigation and this whole bar is hidden;
   see the media query at the end. */

.nav { display: none; }

.nav-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .85rem 1.5rem;
    padding-left:  max(1.5rem, env(safe-area-inset-left));
    padding-right: max(1.5rem, env(safe-area-inset-right));
}

.nav-brand {
    font-weight: 600;
    font-size: 1.05rem;
    text-decoration: none;
}

.nav-links { list-style: none; margin: 0; padding: 0; }

.nav-toggle {
    display: none;
    position: relative;
    z-index: 60;
    width: 44px;                 /* the iOS minimum touch target */
    height: 44px;
    margin-right: -10px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.nav-toggle span {
    position: absolute;
    left: 11px;
    width: 22px;
    height: 1.5px;
    background: var(--ink);
    transition: transform .25s ease, opacity .2s ease;
}

.nav-toggle span:nth-child(1) { top: 16px; }
.nav-toggle span:nth-child(2) { top: 21.5px; }
.nav-toggle span:nth-child(3) { top: 27px; }

body.nav-open .nav-toggle span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
body.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

/* --- Layout --------------------------------------------------------------- */

.layout {
    display: grid;
    grid-template-columns: minmax(17rem, 21rem) minmax(0, 1fr);
    gap: 5rem;
    max-width: 76rem;
    margin: 0 auto;
    padding: 0 3rem;
    padding-left:  max(3rem, env(safe-area-inset-left));
    padding-right: max(3rem, env(safe-area-inset-right));
}

/* --- The rail ------------------------------------------------------------- */

.rail {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    display: flex;
    flex-direction: column;
    padding: 4.5rem 0 2.5rem;
}

.portrait-link { display: block; width: 148px; margin-bottom: 1.75rem; }

.portrait {
    width: 148px;
    height: 148px;
    border-radius: 50%;
    object-fit: cover;
    /* The source photo is a 3:4 portrait with the face high in the frame; a
       centred square crop would cut the top of his head. Tuned to this image —
       revisit if the photo is replaced. */
    object-position: 50% 24%;
    background: var(--paper-alt);
}

.rail-name {
    font-family: var(--serif-heading);
    font-size: 2.5rem;
    font-weight: 400;
    line-height: 1.02;
    letter-spacing: -.015em;
    margin: 0 0 1rem;
    /* Originally capped at 6ch so the name broke onto two lines. Brian prefers
       it on one, and "Brian Krug" at this size is well inside the rail. */
    text-wrap: nowrap;
}

.rail-name a { text-decoration: none; }

.tagline {
    margin: 0 0 2.25rem;
    font-size: .95rem;
    line-height: 1.55;
    color: var(--ink-soft);
    /* 19rem, not 18: the location line sets at 289.8px, and at 18rem it had
       288px to sit in, so it wrapped and left the state stranded on its own
       line. The rail column is 21rem here, so this still clears it. */
    max-width: 19rem;
}

.tagline em {
    display: block;
    font-style: normal;
    font-size: .72rem;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-top: .5rem;
    /* If a longer location is ever set in Settings > Design, break it into two
       balanced lines rather than dropping one last word by itself. */
    text-wrap: balance;
}

.rail-nav {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--rule);
}

.rail-nav a {
    display: block;
    text-decoration: none;
    padding: .72rem 0;
    font-size: 1rem;
    color: var(--ink-soft);
    border-bottom: 1px solid var(--rule);
    transition: color .15s, padding-left .15s;
}

.rail-nav a:hover { color: var(--ink); padding-left: .4rem; }
.rail-nav a[aria-current="page"] { color: var(--ink); font-weight: 600; }

/* margin-top:auto pins the icons to the bottom of the sticky rail without a
   height calculation. */
.rail .social { justify-content: flex-start; gap: .4rem; margin: auto 0 0; }
.rail .social a { width: 34px; height: 34px; }
.rail .social svg { width: 17px; height: 17px; }

/* --- Social icons --------------------------------------------------------- */

.social {
    display: flex;
    justify-content: center;
    gap: 1.5rem;
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
}

.social a {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    color: var(--ink-soft);
    transition: color .15s;
}

.social a:hover { color: var(--ink); }
.social svg { width: 19px; height: 19px; fill: currentColor; }

/* --- The content column --------------------------------------------------- */

.stream { padding: 4.5rem 0 0; min-width: 0; }

.blurb { max-width: var(--measure); }

.blurb p {
    font-size: 1.22rem;
    line-height: 1.62;
    margin: 0 0 1.25rem;
}

/* Ghost wraps every paragraph after the first identically, so the size step
   down has to come from position rather than a class. */
.blurb p ~ p {
    font-size: 1.06rem;
    color: var(--ink-soft);
}

.more {
    display: inline-block;
    text-decoration: none;
    font-size: .78rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--accent);
    border-bottom: 1px solid currentColor;
    padding-bottom: 1px;
}

.more:hover { color: var(--ink); }

/* --- Feeds ---------------------------------------------------------------- */

.section { padding-top: 3.75rem; }

.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: .5rem;
    /* Must match .entry's cap or the "All news" link strands itself far to the
       right of the column it heads. */
    max-width: var(--measure);
}

.section-head h2 {
    margin: 0;
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.section-head a {
    font-size: .74rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--ink-faint);
    white-space: nowrap;
}

.section-head a:hover { color: var(--ink); }

.entry {
    display: block;
    text-decoration: none;
    padding: 1.4rem 0;
    border-top: 1px solid var(--rule);
    max-width: var(--measure);
}

.entry:hover .entry-title { color: var(--accent); }

.entry-date {
    font-size: .72rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: .4rem;
}

.entry-title {
    font-family: var(--serif-heading);
    margin: 0;
    font-size: 1.15rem;
    font-weight: 400;
    line-height: 1.42;
    transition: color .15s;
}

.entry-meta {
    margin: .35rem 0 0;
    font-size: .88rem;
    font-style: italic;
    color: var(--ink-soft);
}

/* Hidden by main.js when a feed holds more entries than data-show allows. */
.entry[hidden] { display: none; }

.empty { color: var(--ink-faint); font-style: italic; }

/* --- Page and post headers ------------------------------------------------ */

.page-head { max-width: var(--measure); margin-bottom: .5rem; }

.page-head h1 {
    font-family: var(--serif-heading);
    font-size: 2.1rem;
    font-weight: 400;
    line-height: 1.12;
    letter-spacing: -.015em;
    margin: 0 0 .75rem;
}

.page-intro {
    margin: 0 0 1.5rem;
    font-size: 1.08rem;
    color: var(--ink-soft);
    max-width: var(--measure);
}

.single { max-width: var(--measure); }

.single-head { margin-bottom: 2rem; }

.single-meta {
    font-size: .72rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: .5rem;
}

.single-head h1 {
    font-family: var(--serif-heading);
    font-size: 2.1rem;
    font-weight: 400;
    line-height: 1.15;
    letter-spacing: -.015em;
    margin: 0;
}

.single-standfirst {
    margin: .85rem 0 0;
    font-size: 1.15rem;
    line-height: 1.55;
    color: var(--ink-soft);
}

.single-figure { margin: 0 0 2rem; }

.single-figure figcaption {
    margin-top: .5rem;
    font-size: .85rem;
    font-style: italic;
    color: var(--ink-faint);
}

.single-foot { margin-top: 3rem; }

/* --- Prose: the Ghost editor's output ------------------------------------- */

.prose > * { max-width: var(--measure); }

.prose p { margin: 0 0 1.25rem; }

.prose h2 {
    font-family: var(--serif-heading);
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1.3;
    margin: 2.75rem 0 .85rem;
}

.prose h3 {
    font-family: var(--serif-heading);
    font-size: 1.1rem;
    font-weight: 600;
    margin: 2rem 0 .6rem;
}

.prose a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
.prose a:hover { color: var(--ink); }

.prose ul, .prose ol { margin: 0 0 1.25rem; padding-left: 1.25rem; }
.prose li { margin-bottom: .4rem; }

.prose blockquote {
    margin: 0 0 1.25rem;
    padding-left: 1.25rem;
    border-left: 2px solid var(--rule);
    color: var(--ink-soft);
    font-style: italic;
}

.prose img { margin: 0 0 1.25rem; }

.prose figure { margin: 0 0 1.75rem; }

.prose figcaption {
    margin-top: .5rem;
    font-size: .85rem;
    font-style: italic;
    color: var(--ink-faint);
}

.prose hr { border: 0; border-top: 1px solid var(--rule); margin: 2.5rem 0; }

/* Wide content must scroll inside its own box rather than pushing the page
   sideways. */
.prose table { width: 100%; border-collapse: collapse; font-size: .95rem; }
.prose th, .prose td { text-align: left; padding: .5rem .75rem .5rem 0; border-bottom: 1px solid var(--rule); }

.prose pre {
    overflow-x: auto;
    background: var(--paper-alt);
    border: 1px solid var(--rule);
    padding: 1rem;
    font-size: .85rem;
}

/* --- CV ------------------------------------------------------------------
   A CV needs more width than an essay: entries are date + description pairs
   that wrap badly at 34rem. */

.single--cv { max-width: 46rem; }
.prose--cv > * { max-width: 46rem; }

.cv-links {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin: 1.25rem 0 0;
    font-size: .78rem;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.cv-links a { color: var(--ink-faint); text-decoration: none; border-bottom: 1px solid var(--rule); }
.cv-links a:hover { color: var(--ink); border-bottom-color: currentColor; }

.prose--cv h2 {
    font-size: .82rem;
    font-weight: 600;
    letter-spacing: .19em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--ink);
    padding-bottom: .4rem;
    margin: 3rem 0 1rem;
}

.prose--cv ul { list-style: none; padding-left: 0; }

.prose--cv li {
    padding: .55rem 0;
    border-bottom: 1px solid var(--rule);
    margin-bottom: 0;
}

/* --- Pagination and footer ------------------------------------------------ */

.pagination {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    max-width: var(--measure);
    margin-top: 2.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--rule);
    font-size: .8rem;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.pagination a { color: var(--ink-faint); text-decoration: none; }
.pagination a:hover { color: var(--ink); }
.pagination .page-next { margin-left: auto; }

.foot {
    border-top: 1px solid var(--rule);
    margin-top: 4rem;
    padding: 2.5rem 0 calc(2.5rem + env(safe-area-inset-bottom));
    text-align: left;
    color: var(--ink-faint);
    font-size: .85rem;
}

.foot p { margin: 0; }

/* The rail already carries the icons on desktop. */
.foot .social { display: none; }

/* --- Mobile --------------------------------------------------------------
   The rail stops being a rail and becomes a centred header block; the top bar
   and hamburger take over navigation. */

@media (max-width: 60rem) {

    .nav {
        display: block;
        position: sticky;
        top: 0;
        z-index: 50;
        background: rgba(255, 255, 255, .92);
        -webkit-backdrop-filter: saturate(180%) blur(12px);
        backdrop-filter: saturate(180%) blur(12px);
        border-bottom: 1px solid var(--rule);
        /* The Dynamic Island and the notch both live in safe-area-inset-top.
           Padding the sticky bar by it keeps the hamburger clear of the island
           in landscape and of the status bar in portrait. Requires
           viewport-fit=cover on the meta tag, or this resolves to 0. */
        padding-top: env(safe-area-inset-top);
    }

    .nav-toggle { display: block; }

    /* The drawer stays in the DOM and is hidden with opacity + visibility
       rather than display:none. `display` cannot be transitioned, so the menu
       would snap in and out; this way both directions animate from one set of
       rules. visibility:hidden also keeps the links out of the tab order while
       closed, which display:none did for free and opacity alone does not. */
    .nav-links {
        position: fixed;
        inset: 0;
        /* 100dvh, not 100vh: on iOS Safari 100vh is the height with the browser
           chrome retracted, so a 100vh drawer is taller than the visible
           viewport and its lower items sit under the toolbar. */
        height: 100dvh;
        z-index: 55;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        background: var(--paper);
        /* Symmetric, so justify-content:center lands optically centred. */
        padding: calc(env(safe-area-inset-top) + 3.5rem) 1.5rem
                 calc(env(safe-area-inset-bottom) + 3.5rem);
        opacity: 0;
        visibility: hidden;
        transition: opacity .26s ease, visibility .26s ease;
    }

    .nav-links.is-open { opacity: 1; visibility: visible; }

    .nav-links li { width: 100%; }

    .nav-links a {
        /* display:block is load-bearing: inline links would not lay out the
           padding, and the tap target would be the text alone. */
        display: block;
        text-align: center;
        font-size: 1.5rem;
        color: var(--ink);
        text-decoration: none;
        padding: .85rem 0;
        opacity: 0;
        transform: translateY(9px);
        transition: opacity .34s cubic-bezier(.2, .7, .3, 1),
                    transform .34s cubic-bezier(.2, .7, .3, 1),
                    color .15s;
    }

    /* Current page reads as weight, not as a rule — a full-width underline
       beneath one centred item looks like a mistake. */
    .nav-links a[aria-current="page"] { font-weight: 600; }

    .nav-links.is-open a { opacity: 1; transform: none; }

    /* Stagger applied only under .is-open, so closing runs with no delay:
       items rise in one after another, then leave together and quickly. */
    .nav-links.is-open li:nth-child(1) a { transition-delay: .04s; }
    .nav-links.is-open li:nth-child(2) a { transition-delay: .08s; }
    .nav-links.is-open li:nth-child(3) a { transition-delay: .12s; }
    .nav-links.is-open li:nth-child(4) a { transition-delay: .16s; }
    .nav-links.is-open li:nth-child(5) a { transition-delay: .20s; }
    .nav-links.is-open li:nth-child(6) a { transition-delay: .24s; }
    .nav-links.is-open li:nth-child(7) a { transition-delay: .28s; }

    body.nav-open { overflow: hidden; }

    .layout {
        grid-template-columns: 1fr;
        gap: 0;
        padding: 0 1.5rem;
        padding-left:  max(1.5rem, env(safe-area-inset-left));
        padding-right: max(1.5rem, env(safe-area-inset-right));
    }

    .rail {
        position: static;
        height: auto;
        padding: 2.75rem 0 0;
        text-align: center;
        align-items: center;
    }

    .portrait-link { width: 128px; }
    .portrait { width: 128px; height: 128px; }
    .rail-name { font-size: 2.2rem; }
    .tagline { max-width: 22rem; margin-bottom: 1.5rem; }
    .rail-nav { display: none; }          /* the hamburger owns navigation now */
    .rail .social { justify-content: center; margin: 0; }

    .stream { padding-top: 2.5rem; }
    .blurb p { font-size: 1.1rem; }
    .entry, .section-head, .page-head, .single, .single--cv,
    .prose > *, .prose--cv > *, .pagination, .contact-list,
    .prose .kg-width-wide { max-width: none; }

    .foot { text-align: center; }
    .foot .social { display: flex; }
}

/* Someone who has asked the OS for less motion gets the menu immediately, with
   no slide and no stagger. */
@media (prefers-reduced-motion: reduce) {
    .nav-links,
    .nav-links a,
    .nav-toggle span { transition-duration: .01ms; }
    .nav-links.is-open li a { transition-delay: 0s; }
    .nav-links a { transform: none; }
}

/* ==========================================================================
   Koenig — the Ghost editor's cards.

   Not optional. Ghost's theme validator requires these classes, and without
   them a bookmark, gallery, callout or toggle card that Brian inserts renders
   as unstyled markup. Everything the editor can produce has to have a home
   here, because the whole point of the build is that he never edits a template.
   ========================================================================== */

/* Width variants. `.prose > *` caps children at the reading measure, so these
   have to break out of it deliberately. */

.prose .kg-width-wide {
    max-width: 46rem;
}

.prose .kg-width-full {
    max-width: none;
    width: 100%;
}

.kg-image { margin: 0 auto; }

.kg-card { margin: 0 0 1.75rem; }

/* --- Image and gallery cards --------------------------------------------- */

.kg-image-card figcaption,
.kg-gallery-card figcaption,
.kg-embed-card figcaption,
.kg-video-card figcaption,
.kg-audio-card figcaption {
    margin-top: .5rem;
    font-size: .85rem;
    font-style: italic;
    color: var(--ink-faint);
    text-align: center;
}

.kg-gallery-card,
.kg-gallery-container { position: relative; display: flex; flex-direction: column; }

.kg-gallery-row { display: flex; flex-direction: row; justify-content: center; }

.kg-gallery-image img { display: block; width: 100%; height: 100%; margin: 0; }

.kg-gallery-row:not(:first-of-type) { margin: .5rem 0 0; }
.kg-gallery-image:not(:first-of-type) { margin: 0 0 0 .5rem; }

/* --- Bookmark card -------------------------------------------------------- */

.kg-bookmark-card { width: 100%; }

.kg-bookmark-container {
    display: flex;
    min-height: 6rem;
    color: inherit;
    text-decoration: none;
    border: 1px solid var(--rule);
    background: var(--paper);
}

.kg-bookmark-container:hover { border-color: var(--ink-faint); }

.kg-bookmark-content {
    flex-basis: 0;
    flex-grow: 1;
    padding: 1.1rem;
    overflow: hidden;
}

.kg-bookmark-title { font-weight: 600; line-height: 1.35; }
.kg-bookmark-description {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: .35rem;
    font-size: .92rem;
    color: var(--ink-soft);
}

.kg-bookmark-metadata {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    margin-top: .75rem;
    font-size: .82rem;
    color: var(--ink-faint);
}

.kg-bookmark-icon { width: 18px; height: 18px; margin-right: .5rem; }
.kg-bookmark-author::after { content: "•"; margin: 0 .4rem; }
.kg-bookmark-publisher {
    overflow: hidden;
    max-width: 240px;
    line-height: 1.4;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kg-bookmark-thumbnail {
    position: relative;
    flex-grow: 1;
    min-width: 33%;
}

.kg-bookmark-thumbnail img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* --- Callout, toggle, button, header, product, NFT ------------------------ */

.kg-callout-card {
    display: flex;
    gap: .75rem;
    padding: 1rem 1.15rem;
    background: var(--paper-alt);
    border-left: 2px solid var(--rule);
}

.kg-callout-card-accent { background: var(--paper-alt); }
.kg-callout-emoji { font-size: 1.1rem; line-height: 1.4; }
.kg-callout-text { font-size: .98rem; }

.kg-toggle-card { border-bottom: 1px solid var(--rule); padding: 1rem 0; }
.kg-toggle-heading { display: flex; justify-content: space-between; align-items: center; cursor: pointer; }
.kg-toggle-heading-text { font-weight: 600; font-size: 1.05rem; }
.kg-toggle-card-icon { width: 14px; height: 14px; transition: transform .2s; }
.kg-toggle-card[data-kg-toggle-state="close"] .kg-toggle-content { display: none; }
.kg-toggle-card[data-kg-toggle-state="open"] .kg-toggle-card-icon { transform: rotate(180deg); }
.kg-toggle-content { margin-top: .75rem; color: var(--ink-soft); }

.kg-button-card { display: flex; }
.kg-button-card.kg-align-center { justify-content: center; }
.kg-btn {
    display: inline-block;
    padding: .7rem 1.4rem;
    background: var(--ink);
    color: #fff;
    text-decoration: none;
    font-size: .9rem;
    letter-spacing: .04em;
}
.kg-btn:hover { background: var(--accent); }
.kg-btn-accent { background: var(--accent); }

.kg-header-card { padding: 2.5rem 1.5rem; text-align: center; }
.kg-header-card-header { font-size: 1.8rem; font-weight: 400; margin: 0 0 .5rem; }
.kg-header-card-subheader { color: var(--ink-soft); margin: 0; }

.kg-product-card-container { border: 1px solid var(--rule); padding: 1.25rem; }
.kg-product-card-title { font-weight: 600; margin: 0 0 .5rem; }
.kg-product-card-rating { color: var(--accent); }

.kg-nft-card { border: 1px solid var(--rule); }

/* --- Embeds and media ----------------------------------------------------- */

.kg-embed-card { display: flex; flex-direction: column; align-items: center; width: 100%; }
.kg-embed-card iframe { max-width: 100%; }

.kg-video-card, .kg-audio-card { border: 1px solid var(--rule); }
.kg-file-card-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    border: 1px solid var(--rule);
    padding: 1rem;
    text-decoration: none;
    color: inherit;
}
.kg-file-card-title { font-weight: 600; }
.kg-file-card-caption { font-size: .88rem; color: var(--ink-soft); }
.kg-file-card-metadata { font-size: .82rem; color: var(--ink-faint); }

/* Signup and members cards: this site has no memberships, but the editor can
   still insert them, and unstyled is worse than plain. */
.kg-signup-card { border: 1px solid var(--rule); padding: 1.5rem; }
.kg-signup-card-heading { margin: 0 0 .5rem; font-size: 1.3rem; font-weight: 400; }
.kg-signup-card-subheading { margin: 0 0 1rem; color: var(--ink-soft); }

/* --- Contact page --------------------------------------------------------- */

.contact-list {
    max-width: var(--measure);
    margin: 2.5rem 0 0;
    padding-top: 1.5rem;
    border-top: 1px solid var(--rule);
}

.contact-list dt {
    font-size: .72rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-top: 1.25rem;
}

.contact-list dt:first-child { margin-top: 0; }

.contact-list dd { margin: .25rem 0 0; font-size: 1.05rem; }
.contact-list dd a { color: var(--accent); text-underline-offset: 2px; }
.contact-list dd a:hover { color: var(--ink); }
