/*
 * PK Design layer for Flair
 * =========================
 *
 * Loaded AFTER Flair's app.css, so it wins the cascade at equal specificity.
 *
 * WHY THIS IS A SEPARATE FILE RATHER THAN EDITS TO FLAIR'S SOURCE
 * Flair builds its CSS with Tailwind + Vite, but the commercial distribution
 * ships without theme.js (the prebuild step), so `npm run build` cannot run.
 * Layering on top avoids depending on a toolchain we don't have, and it means a
 * future Flair update is a re-apply of a few template edits rather than a merge
 * of a rebuilt bundle.
 *
 * STRUCTURE
 *   1. Fonts        self-hosted IBM Plex, no CDN
 *   2. Adapter      Flair's CSS variables → PK tokens
 *   3. Wordmark     the one place the system uses weight 700
 *   4. Structure    the changes a variable map cannot reach
 */

/* ================================================================== *
 * 1 · Fonts — self-hosted, Latin subset
 *
 * Flair loads its faces from Google Fonts. Self-hosting removes a third-party
 * request on every page load and a single point of failure for the whole
 * typographic system.
 * ================================================================== */

@font-face { font-family:'IBM Plex Sans'; font-style:normal; font-weight:300; font-display:swap;
  src:url('../fonts/IBMPlexSans-Light-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Sans'; font-style:normal; font-weight:400; font-display:swap;
  src:url('../fonts/IBMPlexSans-Regular-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Sans'; font-style:normal; font-weight:500; font-display:swap;
  src:url('../fonts/IBMPlexSans-Medium-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Sans'; font-style:normal; font-weight:600; font-display:swap;
  src:url('../fonts/IBMPlexSans-SemiBold-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Sans'; font-style:normal; font-weight:700; font-display:swap;
  src:url('../fonts/IBMPlexSans-Bold-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Sans'; font-style:italic; font-weight:400; font-display:swap;
  src:url('../fonts/IBMPlexSans-Italic-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Sans'; font-style:italic; font-weight:700; font-display:swap;
  src:url('../fonts/IBMPlexSans-BoldItalic-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Mono'; font-style:normal; font-weight:400; font-display:swap;
  src:url('../fonts/IBMPlexMono-Regular-Latin1.woff2') format('woff2'); }
@font-face { font-family:'IBM Plex Serif'; font-style:italic; font-weight:400; font-display:swap;
  src:url('../fonts/IBMPlexSerif-Italic-Latin1.woff2') format('woff2'); }

/* ================================================================== *
 * 2 · Adapter — see pk-scheme.css
 *
 * The Flair-variable mapping and the colour-scheme branches live in the
 * GENERATED pk-scheme.css, because both have to mirror Flair's own selectors
 * exactly ([data-color-scheme=dark]:root, specificity 0,2,0) and carry values
 * from the build. Only the font stack stays here, since it is a decision.
 * ================================================================== */

/*
 * Flair's fonts partial writes --font-headings on `body` via an inline <style>.
 * A :root rule loses to it, so this matches body too — and this file is linked
 * after that block, so order decides.
 */
body {
  --font-headings: 'IBM Plex Sans', -apple-system, system-ui, sans-serif;
  --font-body:     'IBM Plex Sans', -apple-system, system-ui, sans-serif;
  --font-system:   'IBM Plex Sans', -apple-system, system-ui, sans-serif;
}

/* ================================================================== *
 * 3 · The wordmark
 *
 * PrabhuKaliaperumal as one word in two weights: given name bold, family name
 * light. The contrast does work rather than decorating — it puts the person
 * forward and lets the surname recede.
 *
 * The only place the system uses 700. Running text never does.
 * ================================================================== */

[data-text-logo] {
  letter-spacing: -0.015em;
  font-family: var(--font-headings);
}

/* Flair sets font-bold in the markup, so the light half must outrank a utility. */
[data-text-logo] .pk-wm-given  { font-weight: 700 !important; }
[data-text-logo] .pk-wm-family { font-weight: 300 !important; }

/* 300 goes spindly at small sizes; hold at 400 until there is room for it. */
@media (max-width: 719px) {
  [data-text-logo] .pk-wm-family { font-weight: 400 !important; }
}

/* ================================================================== *
 * 4 · Structure — what a variable map cannot reach
 *
 * Everything above is surface. These are the register's actual claims, and
 * they need to outrank Tailwind utilities baked into the templates.
 * ================================================================== */

/*
 * The article title. Flair sets text-4xl/5xl at font-bold; the Recognition
 * register wants 31px at weight 400 with silence doing the work.
 *
 * "True, isn't it?" never follows emphasis — a large bold headline says THIS IS
 * IMPORTANT and invites resistance. A small one alone on the page says it
 * doesn't need to shout.
 */
[data-post-hero] h1,
article header h1,
.gh-article-title {
  font-size: var(--md-sys-typescale-display-large-size) !important;
  line-height: var(--md-sys-typescale-display-large-line-height) !important;
  font-weight: 400 !important;
  letter-spacing: -0.01em;
  max-width: 22ch;
  text-wrap: balance;
}

@media (min-width: 1024px) {
  [data-post-hero] h1,
  article header h1 {
    font-size: var(--md-sys-typescale-display-large-size) !important;
  }
}

/* Long-form reading: PK measure and rhythm rather than Tailwind prose defaults. */
.ghost-content.prose,
.prose-theme {
  font-size: var(--pk-reading-size);
  line-height: var(--pk-reading-line);
}

.prose :where(h2):not(:where([class~='not-prose'] *)) {
  font-size: var(--md-sys-typescale-headline-medium-size);
  line-height: var(--md-sys-typescale-headline-medium-line-height);
  font-weight: 500;
  letter-spacing: 0;
}

.prose :where(h3):not(:where([class~='not-prose'] *)) {
  font-size: var(--md-sys-typescale-headline-small-size);
  font-weight: 500;
}

/*
 * Pull quote. The accent is legitimate here because a quote marks the turn in
 * the argument — which is consequence, not mechanism.
 */
.prose :where(blockquote):not(:where([class~='not-prose'] *)) {
  border-left-width: 2px;
  border-left-color: var(--md-sys-color-primary);
  font-family: 'IBM Plex Serif', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  quotes: none;
}

.prose :where(blockquote p:first-of-type)::before,
.prose :where(blockquote p:last-of-type)::after { content: none; }

/* Data, figures and metadata sit in the mono — and numbers line up. */
.prose :where(code, pre):not(:where([class~='not-prose'] *)),
time, table {
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-variant-numeric: tabular-nums;
}

.prose :where(figcaption):not(:where([class~='not-prose'] *)) {
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  color: var(--md-sys-color-outline);
}

/*
 * Corner radius — ONE knob.
 *
 * Flair derives every corner from --radius:
 *   xs = radius - 4px    sm = radius - 2px    md = radius + 2px
 *   lg = radius + 4px    xl = radius + 8px
 *
 * So this single value moves the nav pill, cards, images and buttons together.
 * 20px is Flair's own default — the rounded look.
 *
 * I had this at 3px on a system argument (print register, paper-flat surfaces).
 * Overruled deliberately: the rounded nav and image corners are wanted. Worth
 * recording as a decision rather than a drift, because it is the one place the
 * theme's own character was kept over the system's.
 *
 * To flatten later, change this number — nothing else.
 */
:root {
  --radius: 20px;
}

/* Buttons and CTAs carry the accent, and the accent is rare by design. */
[data-cta] a,
.gh-button,
button[type='submit'] {
  letter-spacing: 0.06em;
}

/* ================================================================== *
 * 5 · Expressive titles
 *
 * A title can mark which of its words carry the claim:
 *
 *     You *Can't* _Manage_ Experience
 *
 * This passes the system's typographic rule — it operates on the ARGUMENT
 * (which words are doing the arguing) rather than on the word (illustrating
 * what a word means, which is a pun). Emphasis marks the negation and the
 * object; italic holds the contested term at arm's length.
 *
 * Declared per post in code injection, so the real Ghost title stays clean for
 * search, RSS, email and social. See assets/js/pk.js for authoring.
 *
 * Rarely. On every post it becomes a mannerism.
 * ================================================================== */

.pk-em-b {
  /* 600 rather than 700: the title is already the largest thing on the page,
     and the emphasis only has to separate from 400, not shout. */
  font-weight: 600;
}

.pk-em-i {
  font-style: italic;
  /* Plex Sans has a true italic with its own letterforms, so the shift reads
     as a change of voice rather than as slanted upright type. */
  font-synthesis: none;
}

/* Both at once, for a word that is the claim AND contested. */
.pk-em-b.pk-em-i,
.pk-em-b .pk-em-i,
.pk-em-i .pk-em-b {
  font-weight: 600;
  font-style: italic;
}
