/* =========================================================================
   platen
   An ultra-minimal, monospaced Ghost theme for an epistolary blog.

   Two tones only — black ink, white paper. One typeface. One size. Emphasis
   is carried by weight, slant and the underline alone, the way a typewriter
   would manage it. Everything below is in service of those constraints.
   ========================================================================= */

/* ----- Tokens ------------------------------------------------------------- */
:root {
    --ink: #000;
    --paper: #fff;

    /* TT2020 — the theme's typewriter face (self-hosted; see the @font-face
       block below) — backed by a system-monospace fallback for the moment
       before it loads and for any glyph it doesn't carry. */
    --type: "TT2020", ui-monospace, "SFMono-Regular", "SF Mono",
            "Cascadia Mono", "DejaVu Sans Mono", "Roboto Mono", Menlo, Consolas,
            "Liberation Mono", monospace;

    /* The one size every glyph on the page is set in. */
    --size: 1rem;
    --leading: 1.6;

    /* A comfortable measure for monospaced prose. */
    --measure: 68ch;

    /* The unit of vertical rhythm. */
    --line: 1.6rem;

    /* Tracking for runs of capitals — a quiet "letterhead" voice used only on
       the page's metadata furniture (the dateline, the navigation), never on
       prose, where emphasis stays weight, slant and underline. */
    --tracking: 0.1em;

    /* A horizontal line struck from the font's own em-dashes, not drawn as a
       border. Long enough to overrun the measure; the elements that use it
       clip it to their own width. */
    --rule: "————————————————————————————————————————————————————————————————————————————————";
}

/* ----- Typeface ----------------------------------------------------------- */
/* TT2020 — Fredrick Brennan's hyperrealistic emulation of a worn 1960s
   typewriter, self-hosted under assets/fonts/ so the page makes no third-party
   request. Four cuts of the one family, all named "TT2020" below:
       roman + italic      TT2020 Style E — the regular weight
       bold  + bold-italic TT2020 Style B — a true *double-struck* bold, the
                           only way a typewriter ever made heavier type.
   The struck, irregular look of every cut comes from OpenType contextual
   alternates (`calt`) that cycle pseudo-randomly through ~13 variants of each
   glyph, so no two letters land alike — hence `contextual` must stay on
   wherever text is set (see the reset).

   Provenance: assets/fonts/README.md. Licence (SIL OFL): assets/fonts/OFL.txt.

   font-display: swap paints the system-monospace fallback at once, then swaps
   each cut in as it loads — and only the cuts a page uses are ever fetched. */
@font-face {
    font-family: "TT2020";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/tt2020-regular.woff2") format("woff2");
}
@font-face {
    font-family: "TT2020";
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/tt2020-italic.woff2") format("woff2");
}
@font-face {
    font-family: "TT2020";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/tt2020-bold.woff2") format("woff2");
}
@font-face {
    font-family: "TT2020";
    font-style: italic;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/tt2020-bold-italic.woff2") format("woff2");
}

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

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Let an opening quotation mark hang into the margin. */
    hanging-punctuation: first;
}

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--type);
    font-size: var(--size);
    line-height: var(--leading);
    /* Break the rare over-long token (a bare URL, say) rather than let it
       push the column wider than the screen. */
    overflow-wrap: break-word;
    /* No common ligatures — a typewriter strikes each character on its own —
       yet keep *contextual* alternates on: that is the OpenType feature TT2020
       uses to vary each glyph and fake the irregular strike of real type. */
    font-variant-ligatures: no-common-ligatures contextual;
}

/* One typeface, one size — enforced across every text-bearing element so
   that no heading, caption or aside can drift larger or smaller. */
h1, h2, h3, h4, h5, h6,
p, ul, ol, li, dl, dt, dd,
blockquote, figure, figcaption,
table, caption, th, td,
pre, code, kbd, samp, var, tt,
a, em, strong, b, i, u, s, small, big, mark, cite, q, abbr, sub, sup,
address, time, label, input, button, textarea, select, legend {
    font-size: var(--size);
    line-height: var(--leading);
    font-family: var(--type);
}

/* Keep sub/sup from resizing the glyph or disturbing the line. */
sub, sup {
    vertical-align: baseline;
}

img, picture, video, canvas, svg, iframe {
    display: block;
    max-width: 100%;
}

/* ----- Links -------------------------------------------------------------- */
/* A drawn underline is a line the platen can't strike, so links don't wear
   one. In prose a link takes a dashed underline. On hover or keyboard focus,
   links are struck solid: (inked the way a hard keypress would leave it).
   Structural links (masthead, nav, titles, footer) are found by position. */
a {
    color: var(--ink);
    text-decoration: none;
}
a:hover,
a:focus-visible {
    background: var(--ink);
    color: var(--paper);
}
.letter__body a {
    text-decoration: underline dashed;
    text-underline-offset: 0.15em;
}

/* Underline survives as an emphasis device (<u>, <ins>), and even then
   as a dashed line — a row of struck hyphens, not a drawn rule. */
u, ins {
    text-decoration: underline dashed;
    text-underline-offset: 0.15em;
}

/* ----- Focus & selection -------------------------------------------------- */
:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
}

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

/* ----- Skip link ---------------------------------------------------------- */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    padding: 0.5rem 1rem;
    background: var(--paper);
    border: 1px solid var(--ink);
    z-index: 100;
}
.skip-link:focus {
    left: 0.75rem;
    top: 0.75rem;
}

/* ----- Page scaffold ------------------------------------------------------ */
.page {
    max-width: var(--measure);
    margin: 0 auto;
    padding: 3rem 1.5rem 4rem;
}

/* ----- Masthead ----------------------------------------------------------- */
.site-head {
    margin-bottom: 4rem;
    text-align: center;
}
.site-head__title {
    margin: 0;
    font-weight: 700;
    /* The masthead is the letterhead — the blog's name typed in tracked
       capitals at the head of every page. */
    text-transform: uppercase;
    letter-spacing: var(--tracking);
}
.site-head__title a {
    text-decoration: none;
}
.site-head__description {
    margin: 0.5rem 0 0;
}
.site-nav {
    margin-top: 1rem;
}
.site-nav__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0 2ch;
    /* The navigation reads as a letterhead's tracked capitals, set apart from
       the body without leaving the one face, one size or one ink. */
    text-transform: uppercase;
    letter-spacing: var(--tracking);
}
.site-nav [aria-current="page"] {
    font-weight: 700;
}

/* ----- The stream of letters ---------------------------------------------- */
.letters {
    margin: 0;
}

/* A typographic pause between consecutive letters. The asterism is decorative
   and inherits the one size, so it never breaks the monospace grid. */
.letter + .letter::before {
    content: "* * *";
    display: block;
    text-align: center;
    margin: 4rem 0;
}

/* ----- A single letter ---------------------------------------------------- */
.letter__head {
    margin-bottom: var(--line);
}
.letter__date {
    /* The dateline, set in the tracked capitals of a letterhead. The negative
       right margin lets the trailing letter-space hang past the measure, so
       the figures still sit flush to the right edge. */
    margin: 0 calc(var(--tracking) * -1) calc(var(--line) / 2) 0;
    text-align: right;
    text-transform: uppercase;
    letter-spacing: var(--tracking);
}
.letter__title {
    margin: 0;
    font-weight: 700;
    text-wrap: balance;
    text-align: center;
}

.letter__title h2::before {
  content: "RE: "
}

.letter__title a {
    text-decoration: none;
}
.letter__salutation {
    margin: 0 0 var(--line);
}

/* The body's own first/last elements shouldn't add stray margins. */
.letter__body > *:first-child,
.page-doc__body > *:first-child {
    margin-top: 0;
}
.letter__body > *:last-child,
.page-doc__body > *:last-child {
    margin-bottom: 0;
}

/* Sign-off: set apart from the body and pushed to the right, the way you
   would sign the foot of a letter. */
.letter__signoff {
    margin-top: calc(var(--line) * 2);
    text-align: right;
}
.letter__signoff p {
    margin: 0;
}
/* A line left blank between the valediction and the name — the space you
   would sign by hand. */
.letter__signoff .letter__signature {
    margin-top: var(--line);
}

/* ----- Long-form content -------------------------------------------------- */
p {
    margin: 0 0 var(--line);
    /* Tidy the ragged-right edge — no lone word stranded on the last line. */
    text-wrap: pretty;
}

/* Headings inside a letter or page: distinguished by weight, never by size. */
.letter__body :is(h1, h2, h3, h4, h5, h6),
.page-doc__body :is(h1, h2, h3, h4, h5, h6) {
    margin: calc(var(--line) * 1.5) 0 var(--line);
    font-weight: 700;
    text-wrap: balance;
}

strong, b {
    font-weight: 700;
}
em, i, cite {
    font-style: italic;
}
small {
    font-weight: 700; /* keep it readable rather than shrinking it */
}

/* Lists — a typewriter dash for bullets, plain numerals for ordered ones.
   Markers are kept (not removed) so screen readers still announce a list. */
ul, ol {
    margin: 0 0 var(--line);
    padding-left: 3ch;
}
li {
    margin: 0 0 calc(var(--line) / 4);
    text-wrap: pretty;
}
li > ul,
li > ol {
    margin: calc(var(--line) / 4) 0 0;
}
ul {
    list-style-type: square;   /* fallback for older browsers */
    list-style-type: "\2013\00a0\00a0"; /* en dash + spaces, modern browsers */
}
ol {
    list-style-type: decimal;
}

/* Definition lists. */
dl { margin: 0 0 var(--line); }
dt { font-weight: 700; }
dd { margin: 0 0 calc(var(--line) / 2) 3ch; }

/* Blockquotes — set off the way a long quotation is typed: indented on both
   sides, with no rule drawn down the edge. */
blockquote {
    margin: var(--line) 3ch;
    padding: 0;
}
blockquote > *:last-child {
    margin-bottom: 0;
}
blockquote cite {
    font-style: normal;
}

/* Code — already monospaced, so simply boxed in ink. */
code, kbd, samp {
    font-family: var(--type);
}
:not(pre) > code {
    /* No box: on an all-typewriter page, inline code already reads as itself. */
    padding: 0;
}
kbd {
    /* A key, the plain-text way — bracketed, [Enter], not boxed. */
    padding: 0;
}
kbd::before { content: "["; }
kbd::after  { content: "]"; }
pre {
    margin: 0 0 var(--line);
    border: 0;
    padding: 0;
    overflow-x: auto;
    white-space: pre;
}
/* A code block is framed above and below by a struck rule, not boxed. */
pre::before,
pre::after {
    content: var(--rule);
    display: block;
    overflow: hidden;
    white-space: nowrap;
}
pre::before { margin-bottom: calc(var(--line) / 2); }
pre::after  { margin-top: calc(var(--line) / 2); }
pre code {
    padding: 0;
    border: 0;
}

/* Highlighted text — struck over in solid ink rather than boxed or washed
   with colour. */
mark {
    background: var(--ink);
    color: var(--paper);
    padding: 0 0.3ch;
    /* The ink ground is the highlight, so make sure it survives printing. */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
}

abbr[title] {
    text-decoration: underline dotted;
    cursor: help;
}

/* Horizontal rule — struck from em-dashes and clipped to the column, not
   drawn as a border. */
hr {
    margin: calc(var(--line) * 1.5) 0;
    border: 0;
    overflow: hidden;
    white-space: nowrap;
    color: var(--ink);
}
hr::before {
    content: var(--rule);
}

/* Tables — ruled in ink, never shaded. */
table {
    width: 100%;
    margin: 0 0 var(--line);
    border-collapse: collapse;
}
caption {
    text-align: left;
    font-style: italic;
    margin-bottom: calc(var(--line) / 2);
}
th, td {
    padding: 0.3rem 0.6rem;
    text-align: left;
    vertical-align: top;
}
/* No drawn grid: the header is set off by weight and a struck-dash rule, and
   the columns are left to align themselves. */
th {
    font-weight: 700;
    border-bottom: 1px dashed var(--ink);
}

/* Figures. */
figure {
    margin: var(--line) 0;
}
figcaption {
    margin-top: calc(var(--line) / 2);
    font-style: italic;
}

/* ----- Ghost editor cards ------------------------------------------------- */
/* card_assets is off, so the few cards a letter might use are styled here and
   pulled back into the same monochrome palette. */

/* Width options are reined back into the measure for a consistent column. */
.kg-width-wide,
.kg-width-full {
    max-width: 100%;
}

/* Image & gallery cards. */
.kg-image-card,
.kg-gallery-card {
    margin: var(--line) 0;
}
.kg-image {
    margin-left: auto;
    margin-right: auto;
}
.kg-gallery-container {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.kg-gallery-row {
    display: flex;
    gap: 0.6rem;
}
.kg-gallery-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Embed, video & audio cards. */
.kg-embed-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: var(--line) 0;
}
.kg-video-card,
.kg-audio-card {
    margin: var(--line) 0;
}

/* Bookmark card — a plain ruled box, all type in ink. */
.kg-bookmark-card {
    margin: var(--line) 0;
}
.kg-bookmark-container {
    display: flex;
    align-items: stretch;
    text-decoration: none;
    border: 1px solid var(--ink);
}
.kg-bookmark-content {
    flex: 1 1 auto;
    padding: 1rem;
    overflow: hidden;
}
.kg-bookmark-title,
.kg-bookmark-description,
.kg-bookmark-metadata,
.kg-bookmark-author,
.kg-bookmark-publisher {
    color: var(--ink);
}
.kg-bookmark-title { font-weight: 700; }
.kg-bookmark-thumbnail img {
    height: 100%;
    object-fit: cover;
}
.kg-bookmark-icon {
    width: 1em;
    height: 1em;
    vertical-align: text-bottom;
    display: inline-block;
}

/* Callout card — boxed in ink, not filled with colour. */
.kg-callout-card {
    margin: var(--line) 0;
    padding: 1rem;
    border: 1px solid var(--ink);
    background: var(--paper) !important;
    display: flex;
    gap: 1ch;
}
.kg-callout-text { color: var(--ink); }
.kg-callout-emoji { font-style: normal; }

/* Button card. */
.kg-button-card {
    margin: var(--line) 0;
}
.kg-btn {
    display: inline-block;
    padding: 0.4rem 1ch;
    border: 1px solid var(--ink);
    color: var(--ink) !important;
    background: var(--paper) !important;
    text-decoration: none;
}
.kg-btn:hover,
.kg-btn:focus {
    text-decoration: underline;
}

/* Toggle card — shown open, since the theme ships no JavaScript. */
.kg-toggle-card .kg-toggle-content {
    display: block !important;
    height: auto !important;
}
.kg-toggle-heading { font-weight: 700; }

/* File & product cards. */
.kg-file-card a,
.kg-product-card {
    display: block;
    padding: 1rem;
    border: 1px solid var(--ink);
    color: var(--ink);
    text-decoration: none;
    margin: var(--line) 0;
}

/* ----- Complete monochrome coverage for every Ghost card ------------------
   With card_assets off, each Koenig card is normalised here so nothing can
   introduce colour, grey or a second size. The exotic cards (audio/video
   players, product, NFT, before/after) are unlikely in a letter, but they're
   covered so the palette holds no matter what gets pasted in. */

/* Callout colour variants → one boxed-in-ink treatment. */
.kg-callout-card-grey,
.kg-callout-card-white,
.kg-callout-card-blue,
.kg-callout-card-green,
.kg-callout-card-yellow,
.kg-callout-card-red,
.kg-callout-card-pink,
.kg-callout-card-purple,
.kg-callout-card-accent {
    background: var(--paper) !important;
    border: 1px solid var(--ink);
}

/* Button alignment and accent buttons. */
.kg-button-card.kg-align-left { display: flex; justify-content: flex-start; }
.kg-button-card.kg-align-center { display: flex; justify-content: center; }
.kg-btn-accent,
.kg-product-card-btn-accent {
    background: var(--paper) !important;
    color: var(--ink) !important;
    border: 1px solid var(--ink);
}

/* Toggle extras. */
.kg-toggle-heading-text { font-weight: 700; }
.kg-toggle-card-icon { width: 1em; height: 1em; }

/* An alternative blockquote style. */
.kg-blockquote-alt { font-style: italic; }

/* File card internals. */
.kg-file-card-container { display: flex; border: 1px solid var(--ink); }
.kg-file-card-contents { padding: 1rem; }
.kg-file-card-title { font-weight: 700; }
.kg-file-card-caption,
.kg-file-card-filename,
.kg-file-card-filesize { color: var(--ink); }
.kg-file-card-medium,
.kg-file-card-small { display: block; }

/* Product card. */
.kg-product-card-container { border: 1px solid var(--ink); padding: 1rem; }
.kg-product-card-title-container,
.kg-product-card-title { font-weight: 700; }
.kg-product-card-description,
.kg-product-card-rating,
.kg-product-card-rating-star { color: var(--ink); }
.kg-product-card-rating-active { font-weight: 700; }
.kg-product-card-image { max-width: 100%; }
.kg-product-card-button { border: 1px solid var(--ink); }

/* NFT card. */
.kg-nft-card { border: 1px solid var(--ink); }
.kg-nft-card-container { display: block; }
.kg-nft-image { max-width: 100%; }
.kg-nft-header,
.kg-nft-title { font-weight: 700; }
.kg-nft-metadata,
.kg-nft-creator,
.kg-nft-description { color: var(--ink); }
.kg-nft-opensea-logo { display: none; }

/* Before/after comparison card. */
.kg-before-after-card,
.kg-before-after-card-image-before,
.kg-before-after-card-image-after { max-width: 100%; }

/* Audio & video player cards — styled in ink (the theme ships no player JS). */
.kg-audio-player-container,
.kg-video-player-container,
.kg-video-container { border: 1px solid var(--ink); }
.kg-video-player { max-width: 100%; }
.kg-audio-title,
.kg-audio-time,
.kg-video-time { font-weight: 700; }
.kg-audio-thumbnail,
.kg-audio-thumbnail.placeholder {
    width: 4rem;
    height: 4rem;
    border: 1px solid var(--ink);
}
.kg-audio-current-time,
.kg-audio-duration,
.kg-audio-playback-rate,
.kg-video-current-time,
.kg-video-duration,
.kg-video-playback-rate { color: var(--ink); }
.kg-audio-seek-slider,
.kg-audio-volume-slider,
.kg-video-seek-slider,
.kg-video-volume-slider { accent-color: var(--ink); }
.kg-audio-play-icon,
.kg-audio-pause-icon,
.kg-audio-mute-icon,
.kg-audio-unmute-icon,
.kg-video-large-play-icon,
.kg-video-play-icon,
.kg-video-pause-icon,
.kg-video-mute-icon,
.kg-video-unmute-icon { fill: var(--ink); color: var(--ink); }
.kg-video-overlay { background: transparent; }
.kg-video-hide { display: none; }

/* ----- Static pages (About, Colophon, …) ---------------------------------- */
.page-doc__title {
    margin: 0 0 var(--line);
    font-weight: 700;
    text-wrap: balance;
    text-align: center;
}

/* ----- Error page --------------------------------------------------------- */
.error {
    text-align: center;
}
.error__code {
    font-weight: 700;
}

/* ----- Footer ------------------------------------------------------------- */
.site-foot {
    margin-top: 5rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--line) 1ch;
}
/* The rule above the footer is struck, full width, on its own wrapped row. */
.site-foot::before {
    content: var(--rule);
    flex: 0 0 100%;
    overflow: hidden;
    white-space: nowrap;
}
.site-foot p {
    margin: 0;
}

/* ----- Empty state -------------------------------------------------------- */
.letters__empty {
    font-style: italic;
}

/* ----- Small screens ------------------------------------------------------ */
@media (max-width: 38rem) {
    .page {
        padding: 1.5rem 1rem 2.5rem;
    }
    .site-head {
        margin-bottom: 2.5rem;
    }
    .letter + .letter::before {
        margin: 2.5rem 0;
    }
}

/* ----- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}

/* ----- Print: it is, after all, a letter. --------------------------------- */
@media print {
    :root {
        --measure: 100%;
    }
    .skip-link,
    .site-nav,
    .site-foot {
        display: none;
    }
    .page {
        max-width: none;
        padding: 0;
    }
    a {
        text-decoration: none;
    }
    .letter + .letter {
        page-break-before: always;
    }
    .letter + .letter::before {
        content: none;
    }
}
