/* nityesh.com — "Chronicles of Nityesh" print-house design. Plain CSS, no framework.
   Paper #f6efe0, ink #2b2620, terracotta accents. Fraunces for display headings,
   Newsreader for reading body, IBM Plex Mono for labels. The homepage + site chrome
   and the interior reader pages all share this one voice. (The author-only writing
   surface further down keeps its own --font-sans/EB-Garamond tokens, loaded by its
   own bare layout.) */

:root {
  /* --- "Chronicles" print-house palette, ported from the homepage redesign mockup.
     These drive the new homepage + site chrome; the interior-page tokens below are
     retuned onto the same paper so article/tag pages inherit it gracefully. --- */
  --paper: #f6efe0;
  --paper-deep: #efe6d2;
  --card: #fbf6ea;
  --ink: #2b2620;
  --ink-soft: #5c5347;
  --line: #d9cdb4;
  --terracotta: #b05c34;
  --terracotta-deep: #96491f;
  --spool-red: #d0402a;
  --tms-green: #2c453a;
  --tms-green-deep: #22362d;
  --wood: #7a5230;
  --wood-deep: #5d3c20;
  --gold: #f3e3b8;
  --serif: "Fraunces", Georgia, serif;
  --body: "Newsreader", Georgia, serif;
  --mono: "IBM Plex Mono", monospace;

  --background-color: var(--paper);
  --accent-color: var(--terracotta-deep);

  --color-primary-text: var(--ink);
  --color-secondary-text: rgba(43, 38, 32, .58);
  --color-muted: #666;
  --color-border: var(--line);

  --font-sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  /* Newsreader is loaded on public pages; the writing layout only loads EB Garamond,
     so it falls through to that. Both surfaces land on a real serif either way. */
  --font-serif: "Newsreader", "EB Garamond", Georgia, Times, serif;
  --font-mono: "IBM Plex Mono", "JetBrains Mono", Menlo, Consolas, Monaco, "Liberation Mono", monospace;

  --container-width: 1320px;
  --content-width: 720px;
  --container-gap: clamp(24px, 5vw, 48px);
}

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

html { font-size: 62.5%; -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  background-color: var(--background-color);
  color: var(--color-primary-text);
  font-family: var(--font-sans);
  font-size: 1.6rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Faint paper grain over the whole site — pointer-events:none so it never blocks a click. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 60;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}

img, picture, svg, video { display: block; height: auto; max-width: 100%; }
iframe { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; }

h1, h2, h3, h4, h5, h6 { line-height: 1.2; overflow-wrap: break-word; }
p { overflow-wrap: break-word; }

a { color: var(--color-primary-text); text-decoration: none; }
a:hover { opacity: .8; }

/* Public reader headings speak in Fraunces (the display face) at the homepage's weight;
   the author editor canvas stays on --font-serif — it lives on the bare writing layout
   that never loads Fraunces, so pointing it here would only fall back to Georgia. */
.has-serif-title .is-title { font-family: var(--serif); font-weight: 600; }
.has-serif-title .gh-content > :is(h1, h2, h3, h4, h5, h6) { font-family: var(--serif); font-weight: 600; }

/* ---- Layout scaffolding ---- */
.gh-viewport { display: flex; flex-direction: column; min-height: 100vh; }
.gh-main { flex-grow: 1; }
.gh-outer { padding: 0 max(4vmin, 20px); }
.gh-inner { margin: 0 auto; max-width: var(--container-width); width: 100%; }

/* ---- Tag archive (a section of the library, in the homepage's voice) ---- */
.tag-archive { max-width: 780px; margin: 0 auto; padding: clamp(4rem, 8vw, 7rem) 0 7rem; }
.tag-archive__head { border-bottom: 1px solid var(--line); padding-bottom: 2.8rem; margin-bottom: 1rem; }
.tag-archive__eyebrow {
  font-family: var(--mono); font-size: 1.2rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--terracotta); display: inline-flex; align-items: center; gap: 14px; margin-bottom: 1.8rem;
}
.tag-archive__eyebrow::after { content: ""; height: 1px; width: 54px; background: var(--terracotta); opacity: .5; }
.tag-archive__title { font-family: var(--serif); font-weight: 600; font-size: clamp(3.4rem, 3.4vw, 4.6rem); letter-spacing: -.02em; line-height: 1.05; }
.tag-archive__lede { font-family: var(--body); font-style: italic; font-size: 2rem; line-height: 1.5; color: var(--ink-soft); margin-top: 1.6rem; max-width: 62rem; white-space: pre-line; }

/* ---- Post rows (the archive list — serif titles, mono dates, hairline rules) ---- */
.gh-feed { display: flex; flex-direction: column; width: 100%; }
.post-list-item {
  align-items: flex-start;
  border-bottom: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 3rem;
  padding: 2.6rem 0;
}
.post-list-item:last-child { border-bottom: none; }
.post-content { flex: 1; min-width: 0; }
.post-title { font-family: var(--serif); font-size: 2.3rem; font-weight: 600; letter-spacing: -.012em; line-height: 1.22; margin-bottom: .9rem; }
.post-title a { color: var(--ink); transition: color .15s ease; }
.post-title a:hover { color: var(--terracotta); opacity: 1; }
.post-excerpt { color: var(--ink-soft); font-size: 1.6rem; line-height: 1.5; margin-bottom: 1.1rem; font-family: var(--body); }
.post-date { font-family: var(--mono); color: var(--ink-soft); font-size: 1.15rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 500; }
.post-image { flex: 0 0 190px; }
.post-image img { border-radius: 4px; height: 130px; object-fit: cover; width: 190px; border: 1px solid var(--line); box-shadow: 0 6px 16px rgba(43, 38, 32, .12); }

/* ---- Post page ---- */
.gh-article { padding-bottom: 6rem; }
.gh-canvas { max-width: var(--content-width); margin-left: auto; margin-right: auto; padding: 0 20px; }
.gh-article-header { margin-top: 6rem; }
/* Primary tag as a mono eyebrow — same detail as the homepage .sec-label. */
.gh-article-tag {
  font-family: var(--mono);
  color: var(--terracotta);
  font-size: 1.2rem;
  font-weight: 500;
  letter-spacing: .2em;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  text-transform: uppercase;
}
.gh-article-tag::after { content: ""; height: 1px; width: 54px; background: var(--terracotta); opacity: .5; }
.gh-article-tag:hover { color: var(--terracotta-deep); opacity: 1; }
.gh-article-title {
  font-size: clamp(3.4rem, 1.36vw + 2.85rem, 4.6rem);
  letter-spacing: -.02em;
  line-height: 1.06;
}
.gh-article-excerpt {
  font-size: clamp(1.8rem, .3vw + 1.7rem, 2.1rem);
  line-height: 1.45;
  margin-top: 16px;
  color: var(--ink-soft);
  font-family: var(--body);
  font-style: italic;
}
.gh-article-meta { align-items: center; display: flex; gap: 12px; margin-top: 30px; }
.gh-article-author-image img {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  background: #e6e6e6;
  border: 2px solid #fffdf6;
  box-shadow: 0 2px 6px rgba(43, 38, 32, .14);
}
.gh-article-meta-wrapper { display: flex; flex-direction: column; gap: 4px; }
.gh-article-author-name { font-family: var(--body); font-size: 1.6rem; font-weight: 600; color: var(--ink); }
.gh-article-meta-content { font-family: var(--mono); color: var(--ink-soft); font-size: 1.15rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; }
.gh-article-meta-content .bull { opacity: .55; }
/* Feature image gets the soft matted-card treatment from the homepage. */
.gh-article-image { max-width: 1040px; margin: 4.5rem auto 0; padding: 0 20px; }
.gh-article-image img { width: 100%; border-radius: 6px; border: 6px solid #fffdf6; box-shadow: 0 14px 34px rgba(43, 38, 32, .16), 0 2px 6px rgba(43, 38, 32, .10); }
.gh-article-image figcaption { text-align: center; font-family: var(--body); font-style: italic; font-size: 1.5rem; color: var(--ink-soft); margin-top: 1.4rem; }

/* ---- Content typography (rich-text body) ---- */
.gh-content { font-size: 1.7rem; letter-spacing: -.01em; margin-top: 4rem; }
.has-serif-body .gh-content { font-family: var(--font-serif); font-size: 2rem; line-height: 1.55; }
.gh-content > * + * { margin-top: 2.8rem; }
/* Heading + link typography is shared by the published body (.gh-content) and the
   editor canvas (.editor-canvas__body) so the two surfaces can't drift. Both bodies
   render at 2rem, so the em-based sizes compute identically; the descendant editor
   selectors (specificity 0,1,1) beat Lexxy's zero-specificity :where(.lexxy-content). */
.gh-content > :is(h1, h2, h3, h4, h5, h6),
.editor-canvas__body :is(h1, h2, h3, h4, h5, h6) { margin-top: 5.6rem; font-family: var(--font-serif); line-height: 1.2; }
.gh-content h1, .editor-canvas__body h1 { font-size: 2.2em; letter-spacing: -.02em; }
.gh-content h2, .editor-canvas__body h2 { font-size: 1.6em; letter-spacing: -.02em; }
.gh-content h3, .editor-canvas__body h3 { font-size: 1.3em; letter-spacing: -.017em; }
.gh-content h4, .editor-canvas__body h4 { font-size: 1.15em; letter-spacing: -.01em; }
.gh-content a, .editor-canvas__body a { color: var(--accent-color); text-decoration: underline; }
.gh-content a:hover, .editor-canvas__body a:hover { opacity: .8; }
.gh-content :is(ul, ol) { padding-left: 2.8rem; }
.gh-content :is(li + li, li :is(ul, ol)) { margin-top: .8rem; }
.gh-content blockquote,
.editor-canvas__body blockquote {
  border-left: 3px solid var(--terracotta);
  padding-left: 2.4rem;
  font-style: italic;
  color: var(--ink-soft);
}
.gh-content img { margin-left: auto; margin-right: auto; border-radius: 4px; }
.gh-content figure { margin-top: 4rem; margin-bottom: 4rem; }
.gh-content figcaption {
  text-align: center;
  font-size: 1.5rem;
  font-family: var(--body);
  font-style: italic;
  color: var(--ink-soft);
  margin-top: 1.2rem;
}
/* A fleuron instead of a bare rule — the print detail that runs through the masthead & footer. */
.gh-content hr {
  border: 0; height: auto; margin: 5.2rem 0; text-align: center;
  font-family: var(--serif); color: var(--terracotta); line-height: 1;
}
.gh-content hr::before { content: "❦"; font-size: 1.7rem; }

/* ---- Koenig cards ---- */
.kg-card { margin-top: 4rem; margin-bottom: 4rem; }

/* image + caption */
.kg-image-card img { margin-inline: auto; }
.kg-width-wide img { max-width: min(85vw, 1040px); }
.kg-width-full img { max-width: 100%; }

/* gallery */
.kg-gallery-container { display: flex; flex-direction: column; gap: 10px; margin-inline: auto; }
.kg-gallery-row { display: flex; gap: 10px; }
.kg-gallery-image { flex: 1 1 0; }
.kg-gallery-image img { width: 100%; height: 100%; object-fit: cover; border-radius: 3px; margin: 0; }

/* bookmark */
.kg-bookmark-card a.kg-bookmark-container {
  display: flex;
  min-height: 148px;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--background-color);
  color: var(--color-primary-text);
  text-decoration: none;
  font-family: var(--font-sans);
}
.kg-bookmark-content { flex: 1 1 0; display: flex; flex-direction: column; justify-content: flex-start; padding: 1.6rem 2rem; }
.kg-bookmark-title { font-size: 1.5rem; font-weight: 600; }
.kg-bookmark-description { font-size: 1.4rem; margin-top: .4rem; color: var(--color-secondary-text); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.kg-bookmark-metadata { display: flex; align-items: center; gap: .6rem; margin-top: auto; padding-top: 1.4rem; font-size: 1.3rem; }
.kg-bookmark-icon { width: 20px; height: 20px; margin: 0; }
.kg-bookmark-thumbnail { position: relative; flex: 0 0 30%; }
.kg-bookmark-thumbnail img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; margin: 0; }

/* callout */
.kg-callout-card { display: flex; gap: 1rem; padding: 1.6rem 2rem; border-radius: 4px; font-family: var(--font-sans); font-size: 1.6rem; }
.kg-callout-card-grey { background: rgba(0, 0, 0, .05); }
.kg-callout-emoji { font-size: 1.8rem; }

/* button */
.kg-button-card { display: flex; }
.kg-button-card.kg-align-center { justify-content: center; }
.kg-btn {
  display: inline-flex;
  align-items: center;
  border-radius: 100px;
  padding: .8em 1.6em;
  font-size: 1.5rem;
  font-weight: 600;
  font-family: var(--font-sans);
  line-height: 1.2;
}
.kg-btn-accent { background-color: var(--accent-color); color: #fff; }
.kg-btn-accent:hover { opacity: .9; }

/* toggle */
.kg-toggle-card { border-bottom: 1px solid var(--color-border); padding: 1.6rem 0; }
.kg-toggle-heading { display: flex; justify-content: space-between; align-items: center; cursor: pointer; }
.kg-toggle-heading-text { font-size: 2rem; font-weight: 600; font-family: var(--font-serif); }
.kg-toggle-card-icon { background: none; border: 0; cursor: pointer; width: 24px; height: 24px; padding: 0; }
.kg-toggle-card-icon svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.5; }
.kg-toggle-content { margin-top: 1.2rem; }
.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 svg { transform: rotate(180deg); }

/* code */
.gh-content pre {
  background: var(--paper-deep);
  color: var(--color-primary-text);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 1.5rem;
  line-height: 1.5;
  overflow: auto;
  padding: 16px 20px;
}
.gh-content pre code { background: none; padding: 0; font-size: inherit; color: inherit; }
.gh-content :not(pre) > code {
  background: rgba(0, 0, 0, .05);
  border-radius: .25em;
  font-family: var(--font-mono);
  font-size: .85em;
  padding: .15em .4em;
}

/* embeds */
.kg-embed-card { display: flex; flex-direction: column; align-items: center; }
.kg-embed-card iframe { margin-inline: auto; }
.twitter-tweet { margin-inline: auto !important; }

/* ---- 404 ---- */
.gh-error { text-align: center; padding: 10rem 20px; }
.gh-error .error-code { font-family: var(--serif); font-size: clamp(7rem, 14vw, 11rem); font-weight: 600; color: var(--terracotta); line-height: 1; letter-spacing: -.02em; }
.gh-error .error-message { font-family: var(--body); font-style: italic; font-size: 2.2rem; color: var(--ink-soft); margin-top: 1rem; }
.gh-error a { display: inline-block; margin-top: 3rem; font-family: var(--mono); font-size: 1.2rem; letter-spacing: .14em; text-transform: uppercase; color: var(--terracotta); text-decoration: none; border-bottom: 1px solid currentColor; padding-bottom: 3px; }
.gh-error a:hover { color: var(--terracotta-deep); opacity: 1; }
.gh-error button { display: inline-block; margin-top: 3rem; font-family: var(--mono); font-size: 1.2rem; letter-spacing: .14em; text-transform: uppercase; color: var(--terracotta); background: none; border: none; border-bottom: 1px solid currentColor; padding: 0 0 3px; cursor: pointer; }
.gh-error button:hover { color: var(--terracotta-deep); }

/* ---- Responsive ---- */
@media (max-width: 700px) {
  .post-list-item { flex-direction: column; gap: 1.5rem; padding: 2.2rem 0; }
  .post-content { width: 100%; }
  .post-title { font-size: 2rem; }
  .post-image { flex: none; width: 100%; }
  .post-image img { width: 100%; height: 200px; }
  .tag-archive__lede { font-size: 1.8rem; }
  .has-serif-body .gh-content { font-size: 1.8rem; }
}

/* =========================================================================
   HOMEPAGE + SITE CHROME — "Chronicles of Nityesh" print-house redesign.
   Ported from ~/work/nityesh-com-redesign/mockup/index.html. The masthead, footer
   and reveal rules are site-wide (class-scoped, safe on every page); everything
   under `.home-template` is homepage-only so bare `section`/`h2`/`a` rules can't
   leak onto article and tag pages.
   ========================================================================= */
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 40px; }
.mono { font-family: var(--mono); }

/* ---- Print masthead (site-wide) — a trim newspaper flag: wordmark and nav share
   one band under a single hairline. The kicker that used to sit above the wordmark
   now closes the page in the footer. ---- */
.masthead-print { border-bottom: 1px solid var(--line); }
.mast-band { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; padding-top: 22px; padding-bottom: 18px; }
.wordmark {
  font-family: var(--serif); font-weight: 600; font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.1; letter-spacing: -.02em; color: var(--ink);
}
.wordmark a { color: inherit; }
.wordmark a:hover { opacity: 1; color: var(--terracotta-deep); }
.wordmark em { font-style: italic; font-weight: 500; color: var(--terracotta); }
.mast-nav {
  display: flex; align-items: baseline; gap: 26px; flex-shrink: 0;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase;
}
.mast-nav a { text-decoration: none; color: var(--ink-soft); }
.mast-nav a:hover { color: var(--terracotta); opacity: 1; }
/* Subscribe is an action, not a place — so it wears a button, not a nav link. */
.mast-subscribe {
  color: var(--terracotta-deep); border: 1px solid #cdb694; border-radius: 99px;
  padding: 7px 16px; transition: border-color .2s ease, background .2s ease;
}
.mast-subscribe:hover { color: var(--terracotta-deep); border-color: var(--terracotta); background: rgba(176, 92, 52, .07); }

/* The writer's shortcut from a published page into its editor. Floats clear of
   the article so the reading design stays untouched; its looks come from
   .admin-link below, like every other back-office control. */
.edit-pill { position: fixed; right: 22px; bottom: 22px; z-index: 10; }

/* Back-office chrome, deliberately outside the reader's design language. The
   page is paper and terracotta; an admin control is a near-black sticker with
   square-ish corners, so the writer never mistakes a control only he can see for
   something a visitor is being shown. Scoped under .gh-viewport to outrank
   `.home-template a { color: inherit }` on the homepage. */
.gh-viewport a.admin-link {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  color: var(--paper); background: var(--ink); border: 1px solid var(--ink); border-radius: 6px;
  padding: 6px 12px; text-decoration: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 2px 6px rgba(43, 38, 32, .28);
  transition: background .2s ease, border-color .2s ease;
}
.gh-viewport a.admin-link::before { content: "\270E"; font-size: 13px; letter-spacing: 0; }
.gh-viewport a.admin-link:hover { color: var(--paper); background: var(--terracotta-deep); border-color: var(--terracotta-deep); opacity: 1; }

/* ---- Site footer (site-wide) ---- */
.site-footer { border-top: 1px solid var(--line); padding: 34px 0 44px; margin-top: auto; }
.site-footer .wrap { display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap; }
.site-footer .mono { font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.site-footer .foot-kicker { flex-basis: 100%; letter-spacing: .28em; color: var(--terracotta-deep); margin-bottom: 4px; }
.site-footer a { text-decoration: none; }
.site-footer a:hover { color: var(--terracotta); opacity: 1; }
.site-footer .links { display: flex; gap: 22px; }

/* ---- Reveal animation (progressive enhancement; hidden state only once JS adds .reveal-ready) ---- */
.reveal-ready .rise { opacity: 0; transform: translateY(24px); transition: opacity .7s ease, transform .7s cubic-bezier(.2, .7, .3, 1); }
.reveal-ready .rise.in { opacity: 1; transform: none; }
.reveal-ready .hero .rise { transition-delay: calc(var(--d, 0) * .12s); }

/* ---- Homepage base ---- */
.home-template { font-family: var(--body); font-size: 19px; line-height: 1.6; }
.home-template a { color: inherit; }
.home-template a:hover { opacity: 1; }
.home-template section { padding: 86px 0; }
.home-template .sec-label { font-family: var(--mono); font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--terracotta); margin-bottom: 16px; display: flex; align-items: center; gap: 14px; }
.home-template .sec-label::after { content: ""; height: 1px; width: 64px; background: var(--terracotta); opacity: .5; }
.home-template h2 { font-family: var(--serif); font-weight: 600; font-size: clamp(32px, 3.4vw, 48px); letter-spacing: -.015em; line-height: 1.1; margin-bottom: 14px; }
.home-template .sec-lede { font-style: italic; font-size: 21px; color: var(--ink-soft); max-width: 620px; }

/* ---- Intro (frontispiece) ---- */
.hero { padding: 84px 0 76px; position: relative; overflow: hidden; }
.hero-grid { display: grid; grid-template-columns: 360px 1fr; gap: 84px; align-items: start; position: relative; z-index: 1; max-width: 1040px; margin: 0 auto; }
.portrait { position: relative; text-align: center; }
.portrait .photo {
  width: 300px; height: 340px; object-fit: cover; object-position: top; display: block; margin: 0 auto;
  border-radius: 160px 160px 8px 8px;
  border: 9px solid #fffdf6;
  box-shadow: 0 14px 30px rgba(43, 38, 32, .18), 0 2px 6px rgba(43, 38, 32, .12);
}
.portrait figcaption { margin-top: 16px; font-family: var(--body); font-style: italic; font-size: 15.5px; color: var(--ink-soft); }
.hero-copy { max-width: 620px; font-size: 21.5px; color: #3d362d; padding-top: 8px; }
.hero-copy b { color: var(--ink); font-weight: 600; }
.hero-copy p + p { margin-top: 22px; }
.hero-copy .lead::first-letter { font-family: var(--serif); font-weight: 600; color: var(--terracotta); float: left; font-size: 86px; line-height: .78; padding: 8px 14px 0 0; }
.hero-copy .truth { font-style: italic; color: var(--terracotta); }
.thesis-btn {
  display: inline-block; margin-top: 34px; text-decoration: none;
  font-family: var(--serif); font-variant: small-caps; letter-spacing: .14em; font-size: 17px; font-weight: 600;
  color: var(--terracotta-deep); border: 1.5px solid #cdb694; border-radius: 99px; padding: 10px 30px;
  transition: border-color .2s, background .2s;
}
.thesis-btn:hover { border-color: var(--terracotta); background: rgba(176, 92, 52, .06); opacity: 1; }

/* ---- Fresh off the press (the latest three — a quiet ledger list) ---- */
.home-template #press { padding-bottom: 34px; }
.press-list { margin-top: 30px; border-top: 1px solid var(--line); max-width: 880px; }
.press-item { display: flex; gap: 36px; align-items: baseline; padding: 24px 0; border-bottom: 1px solid var(--line); }
.press-date { flex: 0 0 112px; font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.press-body { min-width: 0; }
.press-title { font-family: var(--serif); font-weight: 600; font-size: 23px; letter-spacing: -.012em; line-height: 1.25; }
.press-title a:hover { color: var(--terracotta); opacity: 1; }
.press-excerpt { margin-top: 6px; color: var(--ink-soft); font-size: 17px; line-height: 1.5; max-width: 640px; }

/* ---- The software shelf (one card per shipped product, newest first) ---- */
.home-template #apps { background: linear-gradient(180deg, var(--paper) 0%, var(--paper-deep) 18%, var(--paper-deep) 82%, var(--paper) 100%); }
.machines { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; margin-top: 56px; }
.machine {
  display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 20px 20px;
  transition: transform .28s cubic-bezier(.2, .9, .3, 1.2), border-color .28s ease, box-shadow .28s ease;
}
.machine:hover { transform: translateY(-4px); border-color: #c8a98a; box-shadow: 0 18px 40px -22px rgba(43, 38, 32, .4); }
.machine-title { font-family: var(--serif); font-weight: 600; font-size: 24px; letter-spacing: -.01em; margin: 14px 0 8px; line-height: 1.15; }
.machine-title a:hover { color: var(--terracotta); opacity: 1; }
.machine-blurb { font-size: 16.5px; color: var(--ink-soft); line-height: 1.5; flex: 1; }

/* Each card wears the top of its own landing page — a screenshot, not a re-enactment. */
.machine-shot { display: block; margin: 0 -8px; border-radius: 9px; border: 1px solid #e0d5bc; overflow: hidden; background: var(--paper-deep); }
.machine-shot img { display: block; width: 100%; height: auto; }
.machine-shot:hover { opacity: 1; }
.machine-shipped { margin-top: 14px; font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }

/* Postage stamp — drawn for the postcards originally; the subscribe letter still wears one. */
.stamp {
  position: absolute; top: 14px; right: 14px; width: 64px; height: 76px; z-index: 5;
  background: #fffdf4; padding: 5px; transform: rotate(2deg);
  -webkit-mask-image: radial-gradient(circle at 4px 4px, transparent 3px, black 3.4px);
  -webkit-mask-size: 10.66px 10.85px; -webkit-mask-position: -1.3px -1.4px;
  mask-image: radial-gradient(circle at 4px 4px, transparent 3px, black 3.4px);
  mask-size: 10.66px 10.85px; mask-position: -1.3px -1.4px;
  box-shadow: 0 1px 3px rgba(43, 38, 32, .25);
}
.stamp-inner { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; border: 1px solid rgba(43, 38, 32, .25); }
.stamp-inner .mono { font-size: 7px; letter-spacing: .08em; text-transform: uppercase; }


/* ---- Margin doodles (one per exhibit — pencil notes in the notebook's margin) ---- */
.home-template section { position: relative; }
.doodle { position: absolute; color: var(--ink-soft); opacity: .3; pointer-events: none; user-select: none; }
.doodle svg { width: 100%; height: 100%; display: block; }
.doodle-hero { width: 130px; right: 70px; top: 64px; transform: rotate(-9deg); }
.doodle-press { width: 100px; right: 110px; top: 150px; transform: rotate(6deg); }
.doodle-apps { width: 104px; right: 84px; top: 56px; transform: rotate(-7deg); }
.doodle-library { width: 108px; right: 90px; top: 78px; transform: rotate(5deg); }
.doodle-subscribe { width: 104px; left: 48px; top: 44px; transform: rotate(-12deg); }
@media (max-width: 1200px) { .doodle { display: none; } }

/* Item-level marginalia: the latest-writing items each get their own small mark.
   The press marks key off list position, not the post — posts rotate through, the
   margins stay drawn. */
.doodle-mini { position: absolute; color: var(--ink-soft); opacity: .28; pointer-events: none; user-select: none; }
.doodle-mini svg { width: 100%; height: 100%; display: block; }
.press-item { position: relative; }
.press-mini { width: 54px; right: -150px; top: 50%; transform: translateY(-50%) rotate(-7deg); }
.press-mini-1 { transform: translateY(-50%) rotate(9deg); }
.press-mini-2 { transform: translateY(-50%) rotate(-4deg); }
@media (max-width: 1200px) { .press-mini { display: none; } }

/* ---- Bookshelf (the library) ---- */
.home-template #library .shelf-scene { margin-top: 70px; }
.shelf-books { display: flex; align-items: flex-end; justify-content: center; gap: 7px; padding: 0 60px; min-height: 250px; }
.book {
  position: relative; display: flex; align-items: center; justify-content: center;
  text-decoration: none; border-radius: 2px 3px 3px 2px;
  box-shadow: inset -5px 0 9px rgba(0, 0, 0, .28), inset 2px 0 4px rgba(255, 255, 255, .22), 2px 0 5px rgba(43, 38, 32, .28);
  transition: transform .3s ease; transform-origin: bottom center;
}
.book:hover { transform: translateY(-14px); opacity: 1; }
.book .spine-title { writing-mode: vertical-rl; font-family: var(--serif); font-weight: 700; letter-spacing: .04em; display: flex; align-items: center; gap: 10px; max-height: calc(100% - 44px); overflow: hidden; }
/* Dark spines get a faint press-in shadow; light spines read best with none at all. */
.shelf-books .b-ml .spine-title, .shelf-books .b-comm .spine-title, .shelf-books .b-boot .spine-title, .shelf-books .b-era .spine-title { text-shadow: 0 1px 1px rgba(0, 0, 0, .3); }
.book .count { position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%); font-family: var(--mono); font-size: 10px; opacity: .85; writing-mode: horizontal-tb; }
.book .bands::before, .book .bands::after { content: ""; position: absolute; left: 6px; right: 6px; height: 2px; background: currentColor; opacity: .4; }
.book .bands::before { top: 14px; }
.book .bands::after { bottom: 34px; }
/* Spine ink is scoped under .shelf-books so it outranks `.home-template a { color: inherit }`
   — bare .b-* classes silently lose that fight and every spine falls back to page ink. */
.shelf-books .b-ml { width: 118px; height: 252px; background: linear-gradient(90deg, #6b503a, #59402c 60%, #48311f); color: #f4ead2; font-size: 16px; }
.shelf-books .b-writing { width: 70px; height: 228px; background: linear-gradient(90deg, #c99a4e, #a97f35 60%, #8a6428); color: #211708; font-size: 16.5px; }
.shelf-books .b-comm { width: 90px; height: 248px; background: linear-gradient(90deg, #315142, #2a4437 60%, #223629); color: #f3ecd6; font-size: 17.5px; }
.shelf-books .b-boot { width: 76px; height: 236px; background: linear-gradient(90deg, #bd6b3e, #a9552a 60%, #8f441d); color: #fff7e8; font-size: 16.5px; }
.shelf-books .b-agi { width: 76px; height: 220px; background: linear-gradient(90deg, #f7efdb, #eadfc2 60%, #d9caa4); color: #33291c; font-size: 16px; transform: rotate(6deg) translateY(2px); transform-origin: bottom right; margin-left: -2px; }
.shelf-books .b-agi:hover { transform: rotate(0) translateY(-10px); }
.b-agi .ribbon { position: absolute; top: -14px; left: 50%; transform: translateX(-50%); width: 8px; height: 26px; background: var(--spool-red); clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 82%, 0 100%); }
/* Sensible default spine for a future sixth era (unknown slug). */
.shelf-books .b-era { width: 80px; height: 240px; background: linear-gradient(90deg, var(--wood), var(--wood-deep) 60%, #48311f); color: #f4ead2; font-size: 16px; }
.plant { align-self: flex-end; margin-left: 26px; position: relative; width: 56px; height: 74px; }
.plant .pot { position: absolute; bottom: 0; left: 8px; width: 40px; height: 30px; background: linear-gradient(180deg, #c96636, #a04c20); clip-path: polygon(6% 0, 94% 0, 80% 100%, 20% 100%); }
.plant .leaf { position: absolute; bottom: 24px; width: 9px; height: 44px; background: #4c6b50; border-radius: 50% 50% 0 0; }
.plant .leaf:nth-child(2) { left: 16px; transform: rotate(-18deg); }
.plant .leaf:nth-child(3) { left: 26px; height: 52px; transform: rotate(2deg); background: #3d5943; }
.plant .leaf:nth-child(4) { left: 34px; transform: rotate(20deg); }
.shelf-board {
  height: 20px; margin-top: -2px; border-radius: 3px;
  background: linear-gradient(180deg, #8a5a33 0%, #6e4525 55%, #5d3c20 100%);
  box-shadow: 0 10px 22px rgba(70, 45, 20, .35), inset 0 1px 0 rgba(255, 255, 255, .25);
  position: relative;
}
.shelf-board::after { content: ""; position: absolute; left: 24px; right: 24px; bottom: -14px; height: 14px; background: linear-gradient(180deg, rgba(70, 45, 20, .28), transparent); filter: blur(4px); }

/* ---- Subscribe ---- */
.home-template #subscribe .letter {
  max-width: 820px; margin: 26px auto 0; background: var(--card); position: relative;
  border: 1px solid var(--line); padding: 56px 64px 50px; transform: rotate(-.5deg);
  box-shadow: 0 2px 4px rgba(43, 38, 32, .08), 0 18px 40px rgba(43, 38, 32, .16);
}
.home-template #subscribe .letter::before {
  content: ""; position: absolute; inset: 10px; pointer-events: none; border: 5px solid transparent;
  border-image: repeating-linear-gradient(45deg, var(--spool-red) 0 12px, transparent 12px 22px, var(--tms-green) 22px 34px, transparent 34px 44px) 5;
  opacity: .55;
}
.home-template #subscribe .letter .stamp { top: 26px; right: 28px; }
.home-template #subscribe h2 { margin-bottom: 18px; }
.home-template #subscribe .letter p { color: var(--ink-soft); font-size: 20px; max-width: 560px; }
.home-template #subscribe .letter p b { color: var(--ink); }
.sub-form { display: flex; gap: 0; margin-top: 34px; max-width: 520px; }
.sub-form input { flex: 1; font-family: var(--mono); font-size: 14px; padding: 15px 18px; border: 1.5px solid var(--ink); border-right: 0; background: #fffdf6; color: var(--ink); outline: none; }
.sub-form input::placeholder { color: #a3947c; }
.sub-form button { font-family: var(--mono); font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; background: var(--ink); color: var(--gold); border: 1.5px solid var(--ink); padding: 15px 26px; cursor: pointer; transition: background .2s; }
.sub-form button:hover { background: var(--terracotta-deep); border-color: var(--terracotta-deep); color: #fff; opacity: 1; }
.sub-fine { margin-top: 16px; font-family: var(--mono); font-size: 11px; letter-spacing: .08em; color: var(--ink-soft); text-transform: uppercase; }
.sub-error { color: var(--terracotta-deep); }
.sub-confirm { margin-top: 34px; font-family: var(--mono); font-size: 14px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--terracotta-deep); }

/* ---- Homepage responsive ---- */
@media (max-width: 960px) {
  .hero-grid { grid-template-columns: 1fr; gap: 48px; }
  .machines { grid-template-columns: 1fr; max-width: 560px; margin-left: auto; margin-right: auto; }
}
@media (max-width: 520px) {
  .wrap { padding: 0 22px; }
  .home-template { font-size: 17px; }
  .mast-band { flex-direction: column; align-items: flex-start; gap: 14px; padding-top: 18px; padding-bottom: 16px; }
  .mast-nav { gap: 18px; letter-spacing: .14em; }
  .mast-subscribe { padding: 6px 13px; }
  .hero { padding: 52px 0 40px; }
  .portrait .photo { width: 240px; height: 276px; border-radius: 130px 130px 8px 8px; }
  .hero-copy .lead::first-letter { font-size: 64px; }
  .home-template section { padding: 60px 0; }
  .shelf-books { padding: 0 8px; gap: 5px; transform: scale(.72); transform-origin: bottom center; min-height: 190px; }
  .plant { margin-left: 10px; }
  .home-template #subscribe .letter { padding: 40px 26px 36px; }
  .home-template #subscribe .letter .stamp { display: none; }
  .sub-form { flex-direction: column; }
  .sub-form input { border-right: 1.5px solid var(--ink); border-bottom: 0; }
  .press-item { flex-direction: column; gap: 4px; }
  .press-date { flex: none; }
}

/* =========================================================================
   Writing surface (author-only, behind sign-in). A focused, Ghost-caliber
   workbench hand-built in plain CSS — cream + Garamond typographic continuity
   with the public site, white panels for depth, one accent for intent. It
   lives on its own bare `writing` layout; the shared tokens below cascade to
   every author view (and the public-layout sign-in card via `.auth`).
   ========================================================================= */
.writing-app,
.auth {
  --w-surface: #fbf7ec;
  --w-panel: #fffdf8;
  --w-ink: #14171a;
  --w-muted: #5f6165;
  --w-faint: #8b8d90;
  --w-line: rgba(0, 0, 0, .09);
  --w-line-strong: rgba(0, 0, 0, .17);
  --w-accent: var(--accent-color);
  --w-accent-ink: #9a460a;
  --w-danger: #b00020;
  --w-ok: #1f7a3d;
  --w-radius: 12px;
  --w-shadow: 0 1px 2px rgba(0, 0, 0, .05), 0 10px 30px rgba(0, 0, 0, .07);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---- Buttons (the one control system for the whole surface) ---- */
.w-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  font-family: var(--font-sans); font-size: 1.4rem; font-weight: 500; line-height: 1;
  letter-spacing: -.005em; white-space: nowrap; cursor: pointer;
  padding: .85rem 1.4rem; border-radius: 8px; border: 1px solid transparent;
  background: transparent; color: var(--w-ink);
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease, color .15s ease;
}
.w-btn:hover { opacity: 1; }
.w-btn svg { flex-shrink: 0; }
.w-btn--primary { background: var(--w-accent); color: #fff; font-weight: 600; box-shadow: 0 1px 2px rgba(0, 0, 0, .14); }
.w-btn--primary:hover { background: var(--w-accent-ink); color: #fff; }
.w-btn--ghost { background: var(--w-panel); border-color: var(--w-line-strong); }
.w-btn--ghost:hover { background: #f2ecdd; }
.w-btn--danger { background: var(--w-panel); color: var(--w-danger); border-color: rgba(176, 0, 32, .32); }
.w-btn--danger:hover { background: #fdecef; }
.w-btn--sm { font-size: 1.3rem; padding: .6rem 1rem; }
.w-btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }
.w-btn--primary:disabled:hover { background: var(--w-accent); }
.w-btn--block { width: 100%; padding: 1.1rem; font-size: 1.5rem; }
.w-inline { display: inline; margin: 0; }

/* ---- Dropdowns. Every menu on this surface is a native <details>; this is the panel
   its <summary> drops. Right-aligned because they all hang off a right-hand control. ---- */
.w-menu {
  position: absolute; top: calc(100% + .6rem); right: 0; z-index: 30;
  min-width: 17rem; display: flex; flex-direction: column; padding: .5rem;
  background: var(--w-panel); border: 1px solid var(--w-line-strong);
  border-radius: var(--w-radius); box-shadow: var(--w-shadow);
}
.w-menu a,
.w-menu button {
  appearance: none; background: none; border: 0; width: 100%; text-align: left; cursor: pointer;
  font-family: var(--font-sans); font-size: 1.4rem; font-weight: 500; line-height: 1;
  color: var(--w-ink); white-space: nowrap; padding: .8rem .9rem; border-radius: 6px;
}
.w-menu a:hover,
.w-menu button:hover { background: rgba(0, 0, 0, .06); color: var(--w-ink); opacity: 1; }

/* ---- Split button: one primary action fused to a caret that drops its rarer siblings.
   Same primary fill throughout, a hairline of the button's own border between them. ---- */
.w-split { display: inline-flex; }
.w-split__main { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.w-split__more { position: relative; display: inline-flex; }
.w-split__caret {
  padding-left: .9rem; padding-right: .9rem; list-style: none;
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  border-left-color: rgba(255, 255, 255, .38);
}
.w-split__caret::-webkit-details-marker { display: none; }
.w-split__more[open] .w-split__caret { background: var(--w-accent-ink); }

/* ---- Shared form fields ---- */
.field { display: flex; flex-direction: column; gap: .55rem; }
.field > label,
.field__label,
.stacked-form label,
.schedule-form > label {
  font-family: var(--font-sans); font-size: 1.3rem; font-weight: 600;
  color: var(--w-muted); letter-spacing: .005em;
}
.field__hint { font-size: 1.2rem; color: var(--w-faint); font-weight: 400; }
.field input[type="text"], .field input[type="email"], .field input[type="url"],
.field input[type="password"], .field textarea,
.stacked-form input[type="text"], .stacked-form input[type="email"],
.stacked-form input[type="password"], .stacked-form textarea,
.schedule-form input[type="datetime-local"] {
  width: 100%; padding: .85rem 1.1rem; font: inherit; font-size: 1.45rem;
  color: var(--w-ink); background: var(--w-panel);
  border: 1px solid var(--w-line-strong); border-radius: 8px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field input:focus, .field textarea:focus,
.stacked-form input:focus, .stacked-form textarea:focus,
.schedule-form input:focus {
  outline: none; border-color: var(--w-accent); box-shadow: 0 0 0 3px rgba(180, 83, 9, .13);
}
.field textarea, .stacked-form textarea { resize: vertical; line-height: 1.5; }
.field input[type="file"] { font-size: 1.3rem; color: var(--w-muted); }
.field code, .stacked-form code { font-family: var(--font-mono); font-size: .88em; background: rgba(0, 0, 0, .05); padding: .1em .4em; border-radius: 4px; }

/* Live slug availability — the frame the editor points at the slug's own URL. Same dot as
   the status pills, shrunk to hint size; the height is held so the field never jumps. */
.slug-status { display: block; min-height: 1.7rem; }
.slug-status span {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-sans); font-size: 1.2rem; font-weight: 600; letter-spacing: .01em;
}
.slug-status span::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.slug-status [data-state="available"] { color: var(--w-ok); }
.slug-status [data-state="taken"],
.slug-status [data-state="reserved"] { color: var(--w-danger); }

.errors {
  list-style: none; margin: 1.6rem auto; max-width: 72rem; padding: 1.2rem 1.6rem;
  background: #fdecef; border: 1px solid rgba(176, 0, 32, .25); border-radius: 8px;
  color: var(--w-danger); font-size: 1.4rem;
}
.errors li + li { margin-top: .4rem; }

/* ---- Status pills (dashboard rows + publish popover) ---- */
.status {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-sans); font-size: 1.15rem; font-weight: 600;
  letter-spacing: .03em; text-transform: uppercase;
  padding: .35rem .75rem; border-radius: 6px; white-space: nowrap;
}
.status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status--draft { color: #6b6d70; background: rgba(0, 0, 0, .06); }
.status--scheduled { color: #8a5300; background: rgba(180, 83, 9, .13); }
.status--published { color: var(--w-ok); background: rgba(31, 122, 61, .13); }

/* =========================================================================
   Dashboard — the writing index
   ========================================================================= */
.writing-dash,
.form-page { max-width: 90rem; margin: 0 auto; padding: 4.4rem max(4vmin, 20px) 8rem; }

.dash-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem; flex-wrap: wrap; margin-bottom: 2.6rem; }
.dash-eyebrow { display: block; font-size: 1.2rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--w-accent); margin-bottom: .5rem; }
.dash-head__brand h1 { font-family: var(--font-serif); font-size: clamp(3.4rem, 4vw, 4.2rem); font-weight: 600; letter-spacing: -.015em; }
.dash-head__actions { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }

/* The account menu: a quiet round gear pinned to the bottom-left corner of the viewport,
   floating over the list on a soft shadow. Its panel is the shared .w-menu, flipped to
   open upward and align left — there's nothing below or to the left of it. */
.dash-menu { position: fixed; left: 22px; bottom: 22px; z-index: 10; }
.dash-menu__button {
  padding: .85rem; border-radius: 50%; color: var(--w-muted); list-style: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 6px 16px rgba(0, 0, 0, .10);
}
.dash-menu__button::-webkit-details-marker { display: none; }
.dash-menu__button:hover,
.dash-menu[open] .dash-menu__button { color: var(--w-ink); }
.dash-menu .w-menu { top: auto; bottom: calc(100% + .6rem); right: auto; left: 0; }

.dash-tabs { display: flex; align-items: center; gap: .2rem; flex-wrap: wrap; border-bottom: 1px solid var(--w-line); margin-bottom: 1rem; }
.dash-tab {
  appearance: none; background: none; border: 0; border-bottom: 2px solid transparent;
  margin-bottom: -1px; cursor: pointer; display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--font-sans); font-size: 1.45rem; font-weight: 500; color: var(--w-muted);
  padding: .9rem 1.1rem; transition: color .15s ease, border-color .15s ease;
}
.dash-tab:hover { color: var(--w-ink); }
.dash-tab[aria-pressed="true"] { color: var(--w-ink); border-bottom-color: var(--w-accent); }
.dash-tab__count { font-size: 1.15rem; font-weight: 600; color: var(--w-faint); background: rgba(0, 0, 0, .05); border-radius: 20px; padding: .15rem .6rem; min-width: 2.1rem; text-align: center; }
.dash-tab[aria-pressed="true"] .dash-tab__count { color: var(--w-accent); background: rgba(180, 83, 9, .12); }

/* Filter-as-you-type. Full width under the tabs, because the list it narrows is that
   wide; borderless until focus so it reads as part of the list, not a form. */
.dash-filter { position: relative; display: flex; align-items: center; }
.dash-filter__icon { position: absolute; left: 1rem; color: var(--w-faint); pointer-events: none; }
.dash-filter__field {
  width: 100%; appearance: none; background: none; border: 0; border-radius: 0;
  border-bottom: 1px solid transparent; padding: .9rem 1rem .9rem 3.3rem;
  font-family: var(--font-sans); font-size: 1.45rem; color: var(--w-ink);
}
.dash-filter__field::placeholder { color: var(--w-faint); }
.dash-filter__field:focus { outline: none; border-bottom-color: var(--w-line); }
.dash-filter__field::-webkit-search-cancel-button { appearance: none; }

.dash-list { list-style: none; padding: 0; margin: 0; }
.dash-row { display: flex; align-items: center; justify-content: space-between; gap: 1.6rem; padding: 1.5rem .6rem; border-bottom: 1px solid var(--w-line); }
.dash-row[hidden] { display: none; }
.dash-row:hover { background: rgba(0, 0, 0, .018); }
.dash-row__link { display: flex; align-items: baseline; gap: 1rem 1.4rem; flex-wrap: wrap; flex: 1; min-width: 0; }
.dash-row__title { font-family: var(--font-serif); font-size: 1.85rem; font-weight: 500; letter-spacing: -.005em; color: var(--w-ink); }
/* On tags the whole row is one edit target, so the Edit button lights the name too. */
.dash-row__link:hover .dash-row__title,
.dash-list--tags .dash-row:hover .dash-row__title { color: var(--w-accent); }
.dash-row__slug { font-size: 1.3rem; color: var(--w-faint); }
/* The post row's second line — URL, then when it went (or goes) live, then the tags.
   A full basis inside the link's existing wrap is what drops it onto its own line, so
   the rows on Tags / Subscribers / Connect keep the single-line shape they share. */
.dash-row__meta { flex-basis: 100%; display: flex; align-items: baseline; gap: .5rem .8rem; flex-wrap: wrap; }
.dash-row__url, .dash-row__when { font-family: var(--font-mono); font-size: 1.2rem; color: var(--w-faint); }
.dash-row__tags { display: inline-flex; gap: .5rem; flex-wrap: wrap; }
.chip { font-size: 1.15rem; font-weight: 500; color: var(--w-muted); background: rgba(0, 0, 0, .055); border-radius: 20px; padding: .25rem .8rem; letter-spacing: .01em; }
.dash-row__side { display: flex; align-items: center; gap: 1.4rem; flex-shrink: 0; }
.dash-row__date { font-size: 1.3rem; color: var(--w-faint); font-variant-numeric: tabular-nums; white-space: nowrap; }

.dash-note { margin-top: 1.6rem; font-size: 1.35rem; color: var(--w-faint); }

.dash-empty, .dash-blank { text-align: center; color: var(--w-muted); padding: 6rem 2rem; }
.dash-blank { display: flex; flex-direction: column; align-items: center; gap: 1.8rem; }
.dash-blank p { font-size: 1.8rem; font-family: var(--font-serif); }

/* =========================================================================
   Connect — the "give an AI assistant the keys" page
   ========================================================================= */
.connect-lede { font-size: 1.55rem; line-height: 1.55; color: var(--w-muted); max-width: 64rem; margin-bottom: 3rem; }
.connect-lede code { font-family: var(--font-mono); font-size: .86em; background: rgba(0, 0, 0, .05); padding: .1em .4em; border-radius: 4px; }

.connect-section { margin-top: 4rem; padding-top: 3rem; border-top: 1px solid var(--w-line); }
.connect-section > h2 { font-family: var(--font-serif); font-size: 2.4rem; font-weight: 600; letter-spacing: -.01em; margin-bottom: .5rem; }
.connect-section__intro { font-size: 1.4rem; line-height: 1.5; color: var(--w-muted); max-width: 62rem; margin-bottom: 1.6rem; }

.connect-token { margin-bottom: 2.6rem; }
.connect-token > label { display: block; font-family: var(--font-sans); font-size: 1.3rem; font-weight: 600; color: var(--w-ok); margin-bottom: .7rem; }

.connect-code { position: relative; margin-bottom: 1.2rem; }
.connect-code pre {
  margin: 0; padding: 1.5rem 6rem 1.5rem 1.6rem;
  background: var(--w-ink); color: #f4efe4; border-radius: var(--w-radius);
  font-family: var(--font-mono); font-size: 1.3rem; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
}
.connect-code__copy { position: absolute; top: 1.1rem; right: 1.1rem; background: var(--w-panel); }

.connect-field { margin-bottom: 1.4rem; }
.connect-field > label { display: block; font-family: var(--font-sans); font-size: 1.2rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--w-faint); margin-bottom: .5rem; }
.connect-field__row { display: flex; align-items: stretch; gap: .8rem; }
.connect-field__row code {
  flex: 1; min-width: 0; display: flex; align-items: center;
  font-family: var(--font-mono); font-size: 1.35rem; color: var(--w-ink);
  background: var(--w-panel); border: 1px solid var(--w-line-strong); border-radius: 8px;
  padding: .7rem 1.1rem; overflow-x: auto; white-space: nowrap;
}

.connect-token-form { margin-bottom: 2.4rem; }

.connect-details { margin-top: 1.8rem; }
.connect-details > summary { cursor: pointer; font-size: 1.35rem; font-weight: 500; color: var(--w-faint); }
.connect-details > summary:hover { color: var(--w-ink); }
.connect-details[open] > summary { margin-bottom: 1.4rem; }

/* =========================================================================
   Editor — the distraction-free canvas
   ========================================================================= */
.editor-shell { position: relative; min-height: 100vh; }

.editor-bar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 1.2rem;
  height: 6rem; padding: 0 max(3vmin, 14px);
  background: rgba(248, 244, 233, .88); backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--w-line);
}
.editor-bar__side { display: flex; align-items: center; gap: .8rem; min-width: 0; }
.editor-bar__side--end { justify-content: flex-end; }
/* Only a turbo_stream target: the mint has to aim at something, and this is it. It must
   not become a layout box in the process, hence display:contents — the buttons inside
   stay direct flex children of the bar. */
.editor-bar__actions { display: contents; }
.editor-bar__back { display: inline-flex; align-items: center; gap: .5rem; font-size: 1.4rem; font-weight: 500; color: var(--w-muted); }
.editor-bar__back:hover { color: var(--w-ink); opacity: 1; }
.editor-bar__publish svg { opacity: .75; }

.autosave-status {
  display: inline-flex; align-items: center; min-height: 1.4em;
  font-size: 1.3rem; font-weight: 500; color: var(--w-faint);
  padding-left: 1rem; border-left: 1px solid var(--w-line);
}
.autosave-status:empty { padding-left: 0; border-left: 0; }
.autosave-status[data-state="saved"] { color: var(--w-ok); }
.autosave-status[data-state="unsaved"] { color: var(--w-muted); }
.autosave-status[data-state="error"],
.autosave-status[data-state="refused"] { color: var(--w-danger); }
/* The idle line on a live post. It is a warning, not a reassurance, so it wears the
   LIVE pill's dot rather than the pill's confidence. */
.autosave-status[data-state="live"] { color: var(--w-muted); gap: .5rem; }
.autosave-status[data-state="live"]::before {
  content: ""; width: .7rem; height: .7rem; border-radius: 50%; background: var(--w-ok);
}

/* Match the published measure: max-width + horizontal padding land the contenteditable
   at ~680px (the live .gh-content width) on any desktop viewport. Padding tracks viewport
   WIDTH (clamp/vw), not vmin — vmin tied the column to window height and narrowed it on
   tall screens. Lexxy's own content padding is zeroed below so text starts at the title's
   left edge and the wrapper width IS the writing measure. */
.editor-canvas { max-width: 76rem; margin: 0 auto; padding: 5rem clamp(20px, 4vw, 40px) 12rem; }
.editor-canvas__title,
.editor-canvas__subtitle {
  display: block; width: 100%; border: 0; background: none; padding: 0;
  resize: none; overflow: hidden; white-space: pre-wrap;
  font-family: var(--font-serif); color: var(--w-ink);
}
.editor-canvas__title {
  margin-bottom: 1.2rem; font-size: clamp(3.4rem, 4.6vw, 4.6rem); font-weight: 600;
  line-height: 1.1; letter-spacing: -.022em;
}
.editor-canvas__subtitle {
  margin-bottom: 1.4rem; font-size: clamp(1.7rem, .23vw + 1.61rem, 1.9rem);
  line-height: 1.45; letter-spacing: -.018em; color: var(--w-muted);
}

/* The URL, under the subtitle: quiet enough to ignore while writing, legible enough to
   check. The dotted underline is the whole affordance — it says "this part is yours"
   without a box or a label, and goes solid when it has the caret. */
.url-line {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 1.4rem;
  margin-bottom: 2.8rem;
  font-family: var(--font-mono); font-size: 1.3rem; color: var(--w-faint);
}
.url-line__url { display: inline-flex; align-items: baseline; max-width: 100%; }
.url-line__slug {
  padding: 0 .1rem; border: 0; border-bottom: 1px dotted var(--w-muted); border-radius: 0;
  background: none; font: inherit; color: var(--w-ink); cursor: text;
  /* Sized by its content, so the trailing slash sits against the slug rather than at the
     end of a box (browsers without it fall back to the input's default width). */
  field-sizing: content; min-width: 6ch; max-width: 100%;
}
.url-line__slug:focus { outline: none; border-bottom: 1px solid var(--w-ink); }
.url-line__slug::placeholder { color: var(--w-faint); }
/* The live-URL warning is for the moment of editing, not a banner to live with. */
.url-line__hint {
  flex-basis: 100%; display: none; margin: .4rem 0 0;
  font-family: var(--font-sans); font-size: 1.2rem; font-weight: 500; color: var(--w-danger);
}
.url-line:focus-within .url-line__hint { display: block; }
/* The three canvas placeholders read as one hint, so they share one colour. Lexxy paints
   the body's from its `placeholder` attribute at two-thirds ink; opacity: 1 hands the
   tone back to the colour (and undoes Firefox's own ::placeholder fade while it's here). */
.editor-canvas__title::placeholder,
.editor-canvas__subtitle::placeholder,
.editor-canvas__body .lexxy-editor__content::before { color: rgba(0, 0, 0, .24); opacity: 1; }
.editor-canvas__title:focus,
.editor-canvas__subtitle:focus { outline: none; }

/* The Lexxy editor is the star: match the public serif body so the writer sees what
   readers will. Theme the gem via its own --lexxy-* tokens (transparent canvas, our ink
   and accent), drop the boxed card chrome, and zero its content padding so the text sits
   directly on the cream page at the published measure. */
.editor-canvas__body {
  font-family: var(--font-serif); font-size: 2rem; line-height: 1.55;
  letter-spacing: -.01em; color: var(--w-ink);
}
.editor-canvas__body lexxy-editor {
  display: block; min-height: 46vh;
  --lexxy-color-canvas: transparent;
  --lexxy-color-ink: var(--w-ink);
  --lexxy-color-link: var(--accent-color);
  --lexxy-color-accent-dark: var(--accent-color);
  --lexxy-color-selected: rgba(180, 83, 9, .13);
  --lexxy-editor-padding: 0;
  border: 0; border-radius: 0; background: none;
}

/* Lexxy draws the dropdown caret at .3ch square, which at our toolbar size renders as a
   dot — the text-style and highlight buttons stop reading as menus. One step above the
   gem's own rule, so it wins on specificity rather than on load order. No !important. */
.editor-canvas__body lexxy-editor .lexxy-editor__toolbar-button--chevron:after {
  /* The caret is a rotated corner, so growing it drops its visual centre — pull it back. */
  block-size: .65ch; inline-size: .65ch; margin-block-start: -.2ch;
}

/* Embeds, seen from the editor. A YouTube frame plays here exactly as it will on the
   published page. A tweet can't: the live page swaps the blockquote for the real thing
   once Twitter's widget script loads (tweets_controller), and no widget runs on the
   writer's canvas. So dress the blockquote as a card that says what it is and where it
   goes, rather than leaving it looking like a stray pull-quote. */
.editor-canvas__body .kg-embed-card { margin: 2.4rem 0; }
.editor-canvas__body .kg-embed-card iframe { max-width: 100%; border-radius: 8px; }
.editor-canvas__body blockquote.twitter-tweet {
  width: 100%; margin: 0; padding: 1.4rem 1.6rem; border: 1px solid var(--w-line-strong);
  border-radius: 10px; background: var(--w-panel);
  font-family: var(--font-sans); font-size: 1.45rem; line-height: 1.5; font-style: normal;
}
.editor-canvas__body blockquote.twitter-tweet::before {
  content: "Tweet — renders on the published page"; display: block; margin-bottom: .6rem;
  font-size: 1.15rem; font-weight: 600; font-style: normal;
  letter-spacing: .07em; text-transform: uppercase; color: var(--w-muted);
}
.editor-canvas__body blockquote.twitter-tweet a { word-break: break-all; }

/* ---- Overlays: shared scrim, settings slide-over, publish popover ---- */
.editor-shell__scrim {
  position: fixed; inset: 0; z-index: 40; background: rgba(20, 18, 14, .3);
  opacity: 0; visibility: hidden; transition: opacity .2s ease, visibility .2s ease;
}
.editor-shell__scrim.is-open { opacity: 1; visibility: visible; }

.settings-panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 50; width: min(42rem, 94vw);
  display: flex; flex-direction: column; background: var(--w-panel);
  box-shadow: -14px 0 44px rgba(0, 0, 0, .14); visibility: hidden;
  transform: translateX(100%); transition: transform .26s cubic-bezier(.4, 0, .2, 1), visibility .26s;
}
.settings-panel.is-open { transform: translateX(0); visibility: visible; }
.settings-panel__head, .publish-popover__head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.6rem 2rem; border-bottom: 1px solid var(--w-line); flex-shrink: 0;
}
/* The panel carries its own copy of the save status, so the heading takes the slack and
   status + close sit together on the right. */
.settings-panel__head h2 { font-family: var(--font-sans); font-size: 1.6rem; font-weight: 600; margin-right: auto; }
.settings-panel__head .autosave-status { padding-left: 0; border-left: 0; }
.settings-panel__body { flex: 1; overflow-y: auto; padding: 2rem; display: flex; flex-direction: column; gap: 1.7rem; }
.settings-panel__rule { border: 0; border-top: 1px solid var(--w-line); margin: .2rem 0; }

.panel-close { display: inline-flex; padding: .6rem; border: 0; background: none; border-radius: 6px; cursor: pointer; color: var(--w-muted); }
.panel-close:hover { background: rgba(0, 0, 0, .06); color: var(--w-ink); }

.publish-popover {
  position: fixed; top: 6.8rem; right: max(3vmin, 14px); z-index: 50; width: min(36rem, 94vw);
  background: var(--w-panel); border: 1px solid var(--w-line); border-radius: var(--w-radius);
  box-shadow: var(--w-shadow); visibility: hidden; opacity: 0; transform: translateY(-8px);
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
.publish-popover.is-open { visibility: visible; opacity: 1; transform: translateY(0); }
.publish-popover__head { padding: 1.2rem 1.6rem; }
.publish-popover__head h2 { font-family: var(--font-sans); font-size: 1.5rem; font-weight: 600; }
.publish-popover__body { padding: 1.6rem; display: flex; flex-direction: column; gap: 1.3rem; }
.publish-state { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; font-size: 1.4rem; color: var(--w-muted); }
.publish-state a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.publish-state a:hover { color: var(--w-ink); }
.publish-actions { display: flex; gap: .8rem; flex-wrap: wrap; }
.schedule-form { display: flex; flex-direction: column; gap: .9rem; }
/* The one thing standing between a reflex click and nityesh.com/untitled/. No display of
   its own, so the hidden attribute stays the last word on whether it shows. */
.publish-note { font-size: 1.35rem; line-height: 1.45; color: var(--w-accent-ink); }
/* A refused publish time. Same line, said in the colour of a no. */
.publish-note--refused { color: var(--w-danger); }

/* ---- Tags (existing checkboxes + the deliberate mint control) ---- */
.tag-checkboxes { display: flex; flex-wrap: wrap; gap: .6rem; }
.tag-choice {
  display: inline-flex; align-items: center; gap: .5rem; cursor: pointer;
  font-size: 1.35rem; font-weight: 500; color: var(--w-ink);
  background: var(--w-surface); border: 1px solid var(--w-line); border-radius: 20px; padding: .4rem .9rem;
}
.tag-choice:hover { border-color: var(--w-line-strong); }
.tag-choice:has(:checked) { color: var(--w-accent-ink); background: rgba(180, 83, 9, .1); border-color: rgba(180, 83, 9, .4); }
.tag-choice input { accent-color: var(--w-accent); }
.tag-mint { display: flex; gap: .6rem; margin-top: .8rem; }
.tag-mint__input { flex: 1; }

.feature-image-preview { margin-top: .8rem; max-width: 100%; border-radius: 8px; border: 1px solid var(--w-line); }

/* ---- HTML page editor: a hand-authored document is edited as source, not prose, so the
   body field is a tall monospace textarea that never wraps or autocorrects — wrapping
   would lie about the lines the author is reading. Publishing hangs off a panel below the
   form; there's no sticky editor bar here to anchor the popover to. ---- */
.field textarea.html-source {
  font-family: var(--font-mono); font-size: 1.3rem; line-height: 1.55;
  min-height: 58vh; white-space: pre; overflow-wrap: normal; tab-size: 2;
}
.editor-panel {
  margin-top: 2.6rem; background: var(--w-panel); border: 1px solid var(--w-line);
  border-radius: var(--w-radius); box-shadow: var(--w-shadow);
}
.editor-panel > h2 { font-family: var(--font-sans); font-size: 1.5rem; font-weight: 600; padding: 1.2rem 1.6rem; border-bottom: 1px solid var(--w-line); }
.editor-panel__danger { margin-top: 2.6rem; }

/* =========================================================================
   Form page (tag editor) + auth card
   ========================================================================= */
.form-page__head { display: flex; align-items: center; gap: 1.6rem; margin-bottom: 2.4rem; flex-wrap: wrap; }
.form-page__head h1 { font-family: var(--font-serif); font-size: 3.2rem; font-weight: 600; margin-right: auto; }
.stacked-form {
  display: flex; flex-direction: column; gap: 1.8rem; padding: 2.6rem;
  background: var(--w-panel); border: 1px solid var(--w-line);
  border-radius: var(--w-radius); box-shadow: var(--w-shadow);
}
.stacked-form small { display: block; }

.auth { display: flex; align-items: center; justify-content: center; min-height: 56vh; padding: 6rem 20px; }
.auth__card {
  width: 100%; max-width: 40rem; padding: 3.4rem;
  background: var(--w-panel); border: 1px solid var(--w-line); border-radius: 16px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .05), 0 14px 40px rgba(0, 0, 0, .09);
}
.auth__card h1 { font-family: var(--serif); font-size: 3.2rem; font-weight: 600; color: var(--ink); }
.auth__sub { font-family: var(--body); font-style: italic; color: var(--ink-soft); font-size: 1.55rem; margin: .5rem 0 2.4rem; }
.auth__error { background: #fdecef; border: 1px solid rgba(176, 0, 32, .25); color: var(--w-danger); padding: .9rem 1.2rem; border-radius: 8px; font-size: 1.35rem; margin-bottom: 1.6rem; }
.auth .stacked-form { background: none; border: 0; padding: 0; box-shadow: none; gap: 1.6rem; }
.auth .stacked-form label { font-family: var(--mono); font-size: 1.2rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.oauth-consent { display: flex; flex-direction: column; gap: 1rem; margin-top: 2.4rem; }
.oauth-consent .w-inline { display: block; margin: 0; }

/* ---- Responsive ---- */
@media (max-width: 640px) {
  /* The status line carries a sentence on a live post, so on a phone it has to give way
     rather than shove the publish controls off the bar. (The rest of the phone editor
     chrome — icon-only Settings, a chevron back link — is its own piece of work.) */
  .editor-bar__back { flex: none; }
  .editor-bar .autosave-status {
    display: block; min-width: 0;
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  }
  .editor-bar .autosave-status::before { display: inline-block; vertical-align: middle; margin-right: .5rem; }

  .settings-panel { width: 100vw; }
  .publish-popover { left: max(3vmin, 14px); right: max(3vmin, 14px); width: auto; }
  .editor-canvas { padding-top: 3rem; }
  .dash-row { align-items: flex-start; }
  /* The corner gear floats over the page; give the dashboard a foot as tall as the
     control (button plus its inset) so it can never sit on the last row's actions. */
  .writing-dash { padding-bottom: 14rem; }
}

/* 600px, not the 640 above: it is the same threshold the dashboard controller uses to
   decide whether focusing the filter box would pop a phone keyboard. Six wrapped tabs
   cost three rows of a phone screen before the first post; one scrolling strip costs
   one, and swiping it is the gesture the row of them already looks like. */
@media (max-width: 600px) {
  .dash-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .dash-tabs::-webkit-scrollbar { display: none; }
  .dash-tab { flex: 0 0 auto; }

  /* The pill and "Edited 16 Aug 2026" can't share 390px with a serif headline and a URL,
     and the headline is what he is scanning for. Stack them: title, URL, then state. */
  .writing-dash .dash-row { flex-direction: column; gap: .8rem; }
  .writing-dash .dash-row__side { gap: 1rem; }
}
