/* 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 shares the reading typography and adds Inter for its chrome.) */

: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 and Fraunces load on both layouts (layouts/_fonts); Georgia is the fallback. */
  --font-serif: "Newsreader", 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; }

/* Titles speak in Fraunces (the display face) at the homepage's weight. Body headings get
   the same face in the content typography below, shared with the editor canvas. */
.has-serif-title .is-title { 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; }
/* The title and standfirst are shared with the canvas's title and subtitle fields: the
   writer types into the same type the reader gets. The editor side carries its parent so
   it outranks the fields' own box rules further down. */
.gh-article-title,
.editor-canvas .editor-canvas__title {
  font-family: var(--serif); font-weight: 600; color: var(--ink);
  font-size: clamp(3.4rem, 1.36vw + 2.85rem, 4.6rem);
  letter-spacing: -.02em;
  line-height: 1.06;
}
.gh-article-excerpt,
.editor-canvas .editor-canvas__subtitle {
  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) ----
   Every block rule here is shared by the published body (.gh-content) and the editor
   canvas (the .lexxy-editor__content inside .editor-canvas__body): change one, you change
   both, which is how the canvas stays the page. The editor side is two classes deep so it
   beats Lexxy's zero-specificity :where(.lexxy-content) rules on specificity alone — never
   on load order, never with !important. Both bodies render at 2rem, so em-based sizes
   compute identically. Rhythm is margin-top on siblings; Lexxy's margin-bottom is retired
   through its --lexxy-content-margin token in the editor block further down. */
.gh-content { font-size: 1.7rem; letter-spacing: -.01em; margin-top: 4rem; }
.has-serif-body .gh-content,
.editor-canvas__body .lexxy-editor__content { font-family: var(--font-serif); font-size: 2rem; line-height: 1.55; letter-spacing: -.01em; color: var(--ink); }
.gh-content > * + *,
.editor-canvas__body .lexxy-editor__content > * + * { margin-top: 2.8rem; }
/* Lexxy parks a hidden half-line paragraph ahead of a leading image so the caret has
   somewhere to land; it must not push the first real block down. */
.editor-canvas__body .lexxy-editor__content > .provisional-paragraph.hidden + * { margin-top: 0; }
.gh-content > :is(h1, h2, h3, h4, h5, h6),
.editor-canvas__body .lexxy-editor__content :is(h1, h2, h3, h4, h5, h6) {
  margin-top: 5.6rem; font-family: var(--serif); font-weight: 600; line-height: 1.2;
  hyphens: manual; text-wrap: wrap;
}
.gh-content h1, .editor-canvas__body .lexxy-editor__content h1 { font-size: 2.2em; letter-spacing: -.02em; }
.gh-content h2, .editor-canvas__body .lexxy-editor__content h2 { font-size: 1.6em; letter-spacing: -.02em; }
.gh-content h3, .editor-canvas__body .lexxy-editor__content h3 { font-size: 1.3em; letter-spacing: -.017em; }
.gh-content h4, .editor-canvas__body .lexxy-editor__content h4 { font-size: 1.15em; letter-spacing: -.01em; }
/* Only imports carry h5/h6 (the body's headings are h2–h4); body size keeps them legible. */
.gh-content :is(h5, h6), .editor-canvas__body .lexxy-editor__content :is(h5, h6) { font-size: 1em; }
.gh-content a, .editor-canvas__body .lexxy-editor__content a { color: var(--accent-color); text-decoration: underline; }
.gh-content a:hover, .editor-canvas__body .lexxy-editor__content a:hover { opacity: .8; }
.gh-content :is(ul, ol), .editor-canvas__body .lexxy-editor__content :is(ul, ol) { padding-left: 2.8rem; }
/* The item indent and the blockquote's slight inset are what Trix's content stylesheet gave
   the published body for years; they are the site's look now, stated here once for both. */
.gh-content li, .editor-canvas__body .lexxy-editor__content li { margin-left: 1em; }
.gh-content :is(li + li, li :is(ul, ol)),
.editor-canvas__body .lexxy-editor__content :is(li + li, li :is(ul, ol)) { margin-top: .8rem; }
.gh-content blockquote,
.editor-canvas__body .lexxy-editor__content blockquote {
  border-left: 3px solid var(--terracotta);
  margin-left: .3em;
  padding: 0 0 0 2.4rem;
  font-style: italic;
  color: var(--ink-soft);
}
/* A highlight is the colour the writer picked, carried inline as `color: var(--highlight-N)`
   or `background-color: var(--highlight-bg-N)`; the page renders that same variable, so
   Lexxy's nine slots are filled from the palette once, on both surfaces. They sit here and
   not on :root because Lexxy defines its own on :root and a nearer ancestor wins regardless
   of which stylesheet loads first. A <mark> without a pick is just text — no browser yellow. */
.gh-content,
.editor-canvas__body lexxy-editor {
  --highlight-1: var(--terracotta);
  --highlight-2: var(--terracotta-deep);
  --highlight-3: var(--spool-red);
  --highlight-4: var(--wood);
  --highlight-5: var(--wood-deep);
  --highlight-6: var(--tms-green);
  --highlight-7: var(--tms-green-deep);
  --highlight-8: var(--ink-soft);
  --highlight-9: var(--ink);
  --highlight-bg-1: var(--gold);
  --highlight-bg-2: color-mix(in srgb, var(--terracotta) 18%, transparent);
  --highlight-bg-3: color-mix(in srgb, var(--spool-red) 16%, transparent);
  --highlight-bg-4: color-mix(in srgb, var(--wood) 18%, transparent);
  --highlight-bg-5: color-mix(in srgb, var(--tms-green) 16%, transparent);
  --highlight-bg-6: var(--paper-deep);
  --highlight-bg-7: var(--line);
  --highlight-bg-8: color-mix(in srgb, var(--terracotta-deep) 14%, transparent);
  --highlight-bg-9: color-mix(in srgb, var(--ink) 8%, transparent);
}
.gh-content mark, .editor-canvas__body .lexxy-editor__content mark { background-color: transparent; color: inherit; }
.gh-content img,
.editor-canvas__body .lexxy-editor__content img { margin-left: auto; margin-right: auto; border-radius: 4px; max-block-size: none; }
.gh-content figure,
.editor-canvas__body .lexxy-editor__content figure { margin-top: 4rem; margin-bottom: 4rem; }
.gh-content figcaption,
.editor-canvas__body .lexxy-editor__content figcaption {
  text-align: center;
  font-size: 1.5rem;
  font-family: var(--body);
  font-style: italic;
  color: var(--ink-soft);
  margin-top: 1.2rem;
}
/* The canvas paints an image as Lexxy's .attachment figure with a textarea for the caption.
   Strip the gem's padding so the figure is the figure, and let the caption's field inherit
   the caption's look. */
.editor-canvas__body .lexxy-editor__content :is(.attachment, .attachment__caption) { padding: 0; border-radius: 0; }
.editor-canvas__body .lexxy-editor__content .attachment__caption textarea { padding: 0; text-align: inherit; font-style: inherit; }
/* A fleuron instead of a bare rule — the print detail that runs through the masthead & footer.
   In the canvas the rule sits inside Lexxy's .horizontal-divider figure, which takes the
   margins so the rule can't collapse them twice. */
.gh-content hr,
.editor-canvas__body .lexxy-editor__content .horizontal-divider { margin: 5.2rem 0; padding: 0; }
.gh-content hr,
.editor-canvas__body .lexxy-editor__content hr {
  border: 0; height: auto; width: auto; text-align: center;
  font-family: var(--serif); color: var(--terracotta); line-height: 1;
}
.editor-canvas__body .lexxy-editor__content .horizontal-divider hr { margin: 0; }
.gh-content hr::before, .editor-canvas__body .lexxy-editor__content hr::before { content: "❦"; font-size: 1.7rem; }

/* ---- Tables ---- */
/* Numbers are why a table is in a post at all, so they get the alignment and the tabular
   figures; the hairline rules are the Ghost content rhythm, not a grid. A table wider than
   the measure scrolls rather than squeezing its columns — the wrapper is the browser's, on
   the table itself, so no card or markup has to arrange it. Lexxy already wraps its table
   in a scrolling div, so on the canvas that div is the scrolling box and the table inside
   is just the table. */
.gh-content table,
.editor-canvas__body .lexxy-editor__content .lexxy-content__table-wrapper { display: block; overflow-x: auto; margin: 3.2rem 0; }
.gh-content table,
.editor-canvas__body .lexxy-editor__content table {
  width: 100%; border-collapse: collapse;
  font-size: .82em; line-height: 1.45;
}
.editor-canvas__body .lexxy-editor__content table { margin: 0; }
.gh-content th, .gh-content td,
.editor-canvas__body .lexxy-editor__content th, .editor-canvas__body .lexxy-editor__content td {
  padding: .7em 1.1em; text-align: left; vertical-align: top;
  border: 0; border-bottom: 1px solid var(--line);
  min-width: 0; max-width: none;
}
.gh-content th,
.editor-canvas__body .lexxy-editor__content th {
  font-weight: 600; white-space: nowrap; background: none;
  border-bottom-width: 2px; color: var(--ink-soft);
}
.gh-content :is(td + td, th + th),
.editor-canvas__body .lexxy-editor__content :is(td + td, th + th) { text-align: right; font-variant-numeric: tabular-nums; }
.gh-content tr:last-child td,
.editor-canvas__body .lexxy-editor__content tr:last-child td { border-bottom: 0; }
.gh-content caption,
.editor-canvas__body .lexxy-editor__content caption { caption-side: bottom; padding-top: 1rem; font-size: .95em; color: var(--ink-soft); text-align: left; }

/* ---- Koenig cards ---- */
.kg-card { margin-top: 4rem; margin-bottom: 4rem; }
/* An HTML card is the author's own markup, so the theme gives it the shared card rhythm
   and then gets out of the way — every other rule here would be a rule to fight. */

/* 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; }
/* An editor gallery keeps each image inside its attachment element; let the row see through it. */
.kg-gallery-row > action-text-attachment { display: contents; }
.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 — the box only; colouring is its own concern. The canvas paints a block as a bare
   <code data-language> and stores it as the <pre><code> the page shows, so the two
   selectors name the same thing. */
.gh-content pre,
.editor-canvas__body .lexxy-editor__content code[data-language] {
  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,
.editor-canvas__body .lexxy-editor__content code:not([data-language]) {
  background: rgba(0, 0, 0, .05);
  border-radius: .25em;
  font-family: var(--font-mono);
  font-size: .85em;
  padding: .15em .4em;
  color: inherit;
}

/* Code colour. Rouge paints the published block (CodeHighlighting, class-based tokens);
   Prism paints the editor canvas. One palette for both: the Rouge classes below and the
   Lexxy token variables further down point at the same ink/terracotta/wood/green tokens,
   so the writer sees what readers will. Keywords terracotta, strings green, numbers and
   constants wood, comments soft ink, names plain ink. */
.gh-content pre.highlight { position: relative; }
.highlight .k, .highlight .kd, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kt, .highlight .kc, .highlight .ow, .highlight .na { color: var(--terracotta-deep); }
.highlight .s, .highlight .s1, .highlight .s2, .highlight .sb, .highlight .sh, .highlight .si, .highlight .sx, .highlight .sr, .highlight .sc, .highlight .sd, .highlight .se, .highlight .nb { color: var(--tms-green); }
.highlight .ss, .highlight .dl { color: var(--tms-green-deep); }
.highlight .m, .highlight .mi, .highlight .mf, .highlight .mh, .highlight .mo, .highlight .mb, .highlight .no, .highlight .nt, .highlight .cp { color: var(--wood); }
.highlight .nf, .highlight .nc, .highlight .nn, .highlight .fm { color: var(--wood-deep); }
.highlight .c, .highlight .c1, .highlight .cm, .highlight .cs { color: var(--ink-soft); font-style: italic; }
.highlight .o, .highlight .p { color: var(--ink-soft); }
.highlight .gi { color: var(--tms-green); } .highlight .gd { color: var(--spool-red); }
.highlight .err { color: var(--spool-red); }
/* The label and the copy button sit in the block's top-right corner, in the mono the
   labels elsewhere use. The button hides until the clipboard controller confirms the API. */
.highlight__tools {
  position: absolute; top: .6rem; right: 1rem; display: flex; align-items: center; gap: .8rem;
  font-family: var(--font-mono); font-size: 1.1rem; line-height: 1; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft); white-space: normal;
}
.highlight__language { opacity: .7; }
.highlight__copy { display: none; font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; background: var(--paper); border: 1px solid var(--line); border-radius: 4px; padding: .4rem .7rem; cursor: pointer; }
.highlight--copyable .highlight__copy { display: inline-block; }
.highlight__copy:hover { color: var(--ink); border-color: var(--ink-soft); }

/* 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,
  .editor-canvas__body .lexxy-editor__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; }

/* The preview strip: the same near-black sticker, stretched across the top of a page
   that only the signed-in writer can reach. Fixed, so it stays in view however far he
   reads; the body makes room for it. Phone swaps the page for a 390px frame of itself
   on a dark table — a real viewport that wide, because the responsive rules are media
   queries and a narrowed wrapper would lie. */
body:has(.preview-strip) { padding-top: 40px; }
.preview-strip {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20; height: 40px;
  display: flex; align-items: center; justify-content: center; gap: 20px;
  color: var(--paper); background: var(--ink);
  font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  box-shadow: 0 2px 6px rgba(43, 38, 32, .28);
}
.preview-strip__devices { display: inline-flex; border: 1px solid rgba(246, 239, 224, .35); border-radius: 6px; overflow: hidden; }
.preview-strip__device {
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit;
  background: none; border: 0; padding: 5px 11px; cursor: pointer;
}
.preview-strip__device[aria-pressed="true"] { color: var(--ink); background: var(--paper); cursor: default; }
.preview-strip a.preview-strip__edit { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.preview-frame { display: none; }
html.preview-phone, html.preview-phone body { background: #3a342d; }
/* The strip and the frame are yielded into the viewport with the page; hide their siblings, not their parent. */
html.preview-phone .gh-viewport > :not(:has(.preview-frame)) { display: none; }
html.preview-phone .preview-frame {
  display: block; width: 390px; height: calc(100vh - 88px); margin: 24px auto 0;
  border: 0; border-radius: 22px; background: var(--paper);
  box-shadow: 0 0 0 8px #14110e, 0 24px 60px rgba(0, 0, 0, .5);
}

/* ---- 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;
  /* Every grey here clears WCAG AA (4.5:1) on both --w-surface and --w-panel: faint is
     4.57 / 4.81, muted 5.80 / 6.10. Faint was #8b8d90 — 3.11 / 3.27, a fail it carried
     across fifteen uses, most of them the dashboard's dates, slugs and URLs. */
  --w-faint: #6f7175;
  --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;
  /* Darkened from #1f7a3d, which read 4.22:1 as the Published pill's text on its own
     13%-green tint. 4.82 there now, 5.73 as plain text on the surface. */
  --w-ok: #1c7038;
  --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; }
/* The token, not a grey of its own: #6b6d70 read 4.24:1 on the pill's own tint. */
.status--draft { color: var(--w-muted); 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); }
/* The token, not faint: the count sits on its own 5% tint, where faint reads 4.10:1. */
.dash-tab__count { font-size: 1.15rem; font-weight: 600; color: var(--w-muted); 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; }

/* Which post this is, once the canvas title has gone under the bar. It takes the slack
   between the two sides rather than being centred absolutely, so it can never sit on top
   of the controls at either end — it gives way to them instead. */
.editor-bar__title {
  flex: 1 1 auto; min-width: 0; text-align: center;
  font-family: var(--font-sans); font-size: 1.4rem; font-weight: 500; color: var(--w-muted);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
/* The observer hides it on scroll; :empty hides it while the post is untitled, so nothing
   anywhere has to remember whether there is a title yet. Both need saying, or the display
   above would keep an empty box on the bar. */
.editor-bar__title[hidden],
.editor-bar__title:empty { display: none; }

/* How much of it there is. Tabular figures so a climbing count doesn't shuffle the words
   beside it on every other keystroke. */
.editor-bar__count {
  font-family: var(--font-sans); font-size: 1.3rem; font-weight: 500; color: var(--w-faint);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* The bar's job at this width is the save state and the ship button; a number the writer
   can scroll to the foot of the canvas for is what gives way first. */
@media (max-width: 680px) { .editor-bar__count { display: none; } }

.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"],
.autosave-status[data-state="signedout"],
.autosave-status[data-state="stale"] { 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);
}

/* The browser's own copy of the body, offered back after a save that never landed. One
   line above the body, in the colour of the failure it follows; the two verbs are links,
   not buttons, so the bar stays a sentence. */
.draft-notice {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem; margin: 0 0 1.6rem;
  font-family: var(--font-sans); font-size: 1.3rem; font-weight: 500; color: var(--w-danger);
}
.draft-notice[hidden] { display: none; }
.draft-notice__action {
  background: none; border: 0; padding: 0; font: inherit; color: var(--w-ink);
  text-decoration: underline; cursor: pointer;
}

/* 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. */
/* position: relative so the TK gutter measures against the canvas rather than the page. */
.editor-canvas { position: relative; max-width: 76rem; margin: 0 auto; padding: 5rem clamp(20px, 4vw, 40px) 12rem; }

/* The writer's own notes-to-self, marked in the margin. Their own layer over the canvas
   and never inside the prose: Lexical owns every node in its content element and would
   either discard a marker or take it into the document. */
.editor-canvas__gutter { position: absolute; inset: 0; pointer-events: none; }
.tk-marker {
  position: absolute; right: -3.4rem;
  font-family: var(--font-sans); font-size: 1.1rem; font-weight: 600; letter-spacing: .05em;
  color: var(--w-accent-ink); background: rgba(180, 83, 9, .12);
  border-radius: 4px; padding: .1rem .45rem;
}
/* Past the measure while there is room outside it, and back against the canvas edge when
   there isn't — a marker off the side of the screen marks nothing. */
@media (max-width: 860px) { .tk-marker { right: 0; } }
/* Type and colour come from the public title/standfirst rules they share (see
   .gh-article-title); only the box is decided here. */
.editor-canvas__title,
.editor-canvas__subtitle {
  display: block; width: 100%; border: 0; background: none; padding: 0;
  resize: none; overflow: hidden; white-space: pre-wrap;
}
.editor-canvas__subtitle { margin-bottom: 1.4rem; }

/* 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. The prose itself is styled by the content typography
   rules it shares with .gh-content (above); this wrapper carries the same measure so the
   toolbar, which inherits from it, is sized against the body type. */
.editor-canvas__body {
  /* Positioned so the bubbles and the slash menu can be placed against the words they
     belong to without leaving the canvas — they are its absolute children. */
  position: relative;
  font-family: var(--font-serif); font-size: 2rem; line-height: 1.55;
  letter-spacing: -.01em; color: var(--ink);
  /* The box the selection bubbles are positioned inside, so they scroll with the words
     they point at rather than being pinned to the viewport. */
  position: relative;
}
/* The gem is themed through its own --lexxy-* tokens, in one block, from the site palette —
   nothing reaches into its stylesheet. The canvas stays transparent on the paper. The
   content-margin token is retired (zero), not retuned: Lexxy's naked rems compute small at
   html{font-size:62.5%}, and the shared rules own the block rhythm with margin-top. */
.editor-canvas__body lexxy-editor {
  display: block; min-height: 46vh;
  --lexxy-color-canvas: transparent;
  --lexxy-color-ink: var(--ink);
  --lexxy-color-ink-medium: var(--ink-soft);
  --lexxy-color-ink-light: color-mix(in srgb, var(--ink-soft) 50%, var(--paper));
  --lexxy-color-ink-lighter: var(--line);
  --lexxy-color-ink-lightest: var(--paper-deep);
  --lexxy-color-ink-inverted: var(--paper);
  --lexxy-color-accent-dark: var(--accent-color);
  --lexxy-color-accent-medium: var(--terracotta);
  --lexxy-color-accent-light: var(--gold);
  --lexxy-color-accent-lightest: rgba(180, 83, 9, .13);
  --lexxy-color-text: var(--ink);
  --lexxy-color-text-subtle: var(--ink-soft);
  --lexxy-color-link: var(--accent-color);
  --lexxy-color-selected: rgba(180, 83, 9, .13);
  --lexxy-color-selected-hover: rgba(180, 83, 9, .22);
  --lexxy-color-selected-dark: var(--terracotta);
  --lexxy-color-code-bg: var(--paper-deep);
  --lexxy-color-table-header-bg: transparent;
  --lexxy-color-table-cell-border: var(--line);
  --lexxy-font-base: var(--font-sans);
  --lexxy-font-mono: var(--font-mono);
  --lexxy-text-small: 1.3rem;
  --lexxy-content-margin: 0;
  --lexxy-focus-ring-color: var(--terracotta);
  --lexxy-radius: 6px;
  --lexxy-shadow: var(--w-shadow);
  --lexxy-editor-padding: 0;
  border: 0; border-radius: 0; background: none;
}

/* The toolbar is chrome, not prose: it steps out of the canvas serif into the UI sans at
   14px, which is also what sizes Lexxy's buttons (2lh of it — 62px when it inherited the
   20px serif, which is why eleven tools overflowed a 680px measure). Everything below is
   scoped to <lexxy-toolbar>, one specificity step above the gem's :where() rules, so it
   wins on weight rather than load order. No !important. The canvas's own tokens on
   lexxy-editor above are untouched. */
.editor-canvas__body lexxy-toolbar {
  --lexxy-toolbar-button-size: 3.4rem;
  --lexxy-toolbar-icon-size: 1.6rem;
  --lexxy-toolbar-spacing: .6rem;
  font-family: var(--font-sans); font-size: 1.4rem; line-height: 1.4; letter-spacing: 0;
  flex-wrap: nowrap; border-block-end-color: var(--w-line);
  /* Two thousand words in, the toolbar used to be a thousand pixels above the caret. It
     rides under the bar instead: 6rem is the bar's height, and the bar's z-index is 20, so
     15 puts the toolbar over the prose and under the bar. Sticky makes it a stacking
     context, which is what carries its dropdown panels over the prose with it. It needs an
     opaque back — the canvas is transparent so the prose sits on the paper — and that back
     is the page's own colour, not the panel's: anything else is a band the eye tracks. */
  position: sticky; top: 6rem; z-index: 15; background: var(--background-color);
}
/* Our icons are strokes, the gem's are fills; its rule paints every toolbar svg with a
   fill, so say otherwise for ours (the filled dots set their own fill inline). */
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-button svg {
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-button:hover:not([aria-disabled="true"]) { background-color: rgba(0, 0, 0, .05); }
/* A gap, not a rule, after the text-style menu: the gem draws its group rule and its
   chevron with the same ::after, so a trigger can't wear both. */
.editor-canvas__body lexxy-toolbar > .lexxy-editor__toolbar-dropdown:has(> [name=format]) { margin-inline-end: .6rem; }
/* Lexxy draws the dropdown caret at .3ch square, which renders as a dot — the text-style
   and colour buttons stop reading as menus. The caret is a rotated corner, so growing it
   drops its visual centre; pull it back up. */
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-button--chevron:after {
  block-size: .65ch; inline-size: .65ch; margin-block-start: -.2ch;
}

/* The canvas's code block reads as the published one: same paper-deep box, and Prism's
   token variables pointed at the Rouge palette above. */
.editor-canvas__body code[data-language] {
  background: var(--paper-deep); border: 1px solid var(--line); border-radius: 6px;
  font-family: var(--font-mono); font-size: 1.5rem; line-height: 1.5; padding: 16px 20px;
}
.editor-canvas__body lexxy-editor {
  --lexxy-color-code-token-att: var(--terracotta-deep);
  --lexxy-color-code-token-selector: var(--tms-green);
  --lexxy-color-code-token-property: var(--wood);
  --lexxy-color-code-token-function: var(--wood-deep);
  --lexxy-color-code-token-comment: var(--ink-soft);
  --lexxy-color-code-token-operator: var(--ink-soft);
  --lexxy-color-code-token-punctuation: var(--ink-soft);
  --lexxy-color-code-token-variable: var(--ink);
}

/* 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;
}

/* Panels. The gem paints them with --lexxy-color-canvas, which the editor sets to
   transparent so the prose sits on the page — so every menu let the prose bleed through.
   Redefine that one token on the panel itself: the panel and what's in it turn opaque,
   the canvas never sees the change. Our border and shadow, not the gem's blue 2px. */
.editor-canvas__body lexxy-toolbar [data-dropdown-panel] {
  --lexxy-color-canvas: var(--w-panel);
  border: 1px solid var(--w-line-strong); border-radius: 8px; box-shadow: var(--w-shadow);
  color: var(--w-ink);
}
.toolbar-panel__label { padding: .2rem .6rem 0; font-size: 1.3rem; font-weight: 500; color: var(--w-muted); }

/* Text styles: each item is a preview of the style it applies — the label set in the
   heading's own face and size — so the gem's H2/H3/H4 glyphs are redundant. Lexxy
   generates the heading items (labels_controller names them from the toolbar markup);
   the data-heading it stamps on each is what sizes them. The gem collapses this list to
   an unlabelled icon grid once the toolbar overflows; on a phone the labels are the whole
   point, so keep the list. */
.editor-canvas__body lexxy-toolbar .toolbar-styles { min-inline-size: 18rem; padding: .4rem; }
.editor-canvas__body lexxy-toolbar .toolbar-styles button { padding: .6rem 1rem; border-radius: 6px; }
.editor-canvas__body lexxy-toolbar .toolbar-styles button svg { display: none; }
.editor-canvas__body lexxy-toolbar .toolbar-styles button span { font-family: var(--font-serif); font-size: 1.6rem; line-height: 1.2; color: var(--w-ink); }
.editor-canvas__body lexxy-toolbar .toolbar-styles .lexxy-heading-button span { font-weight: 600; letter-spacing: -.015em; }
.editor-canvas__body lexxy-toolbar .toolbar-styles [data-heading="h2"] span { font-size: 2.3rem; }
.editor-canvas__body lexxy-toolbar .toolbar-styles [data-heading="h3"] span { font-size: 1.9rem; }
.editor-canvas__body lexxy-toolbar .toolbar-styles [data-heading="h4"] span { font-size: 1.65rem; }
.editor-canvas__body lexxy-toolbar[overflowing] .toolbar-styles:not([hidden]) { display: flex; }
.editor-canvas__body lexxy-toolbar[overflowing] .toolbar-styles button span { display: inline; }

/* The link dialog hangs off its button at a readable width, instead of spanning the
   toolbar. Once the toolbar overflows (a phone) there's no room beside anything, so it
   goes back to the gem's full-width placement. */
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-dropdown--link { position: relative; }
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-dropdown--link [data-dropdown-panel] {
  inset-inline-start: 0; inset-inline-end: auto; inline-size: 36rem; padding: .6rem;
}
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-dropdown--link [data-dropdown-panel] button { inline-size: auto; padding-inline: 1.4rem; font-weight: 500; }
.editor-canvas__body lexxy-toolbar[overflowing] .lexxy-editor__toolbar-dropdown--link { position: static; }
.editor-canvas__body lexxy-toolbar[overflowing] .lexxy-editor__toolbar-dropdown--link [data-dropdown-panel] {
  inset-inline: var(--lexxy-toolbar-spacing); inline-size: auto;
}
/* The palette hangs off the right end of the bar, so it grows leftward, over the bar,
   rather than past the measure's edge. On a phone the gem's full-width placement stands. */
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-dropdown--highlight [data-dropdown-panel] { padding: .6rem; }
.editor-canvas__body lexxy-toolbar:not([overflowing]) .lexxy-editor__toolbar-dropdown--highlight [data-dropdown-panel] {
  inset-inline-start: auto; inset-inline-end: 0;
}
.editor-canvas__body lexxy-toolbar .lexxy-editor__toolbar-dropdown-reset { padding: .5rem 1rem; font-size: 1.3rem; font-weight: 500; }

/* The bubbles that come to the caret. Chrome again, so out of the canvas serif and into
   the panel's own paper — the same border, radius and shadow the toolbar's menus wear, so
   everything that floats over the prose reads as one family. z-index 14 is deliberate:
   over the body, under the sticky toolbar, so a bubble that ends up beside the chrome
   goes behind it rather than through it. */
.selection-bubble {
  position: absolute; top: 0; left: 0; z-index: 14;
  display: flex; align-items: center; gap: .2rem;
  padding: .4rem; border: 1px solid var(--w-line-strong); border-radius: 8px;
  background: var(--w-panel); box-shadow: var(--w-shadow);
  font-family: var(--font-sans); font-size: 1.4rem; line-height: 1; letter-spacing: 0;
  color: var(--w-ink);
}
.selection-bubble[hidden] { display: none; }
.selection-bubble__button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 3rem; height: 3rem; padding: 0; border: 0; border-radius: 6px;
  background: none; color: inherit; cursor: pointer;
}
.selection-bubble__button svg {
  width: 1.6rem; height: 1.6rem;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.selection-bubble__button:hover { background: rgba(0, 0, 0, .05); }
.selection-bubble__button[aria-pressed="true"] { background: rgba(0, 0, 0, .08); color: var(--w-accent-ink); }
.selection-bubble__label { font-size: 1.3rem; font-weight: 600; letter-spacing: -.01em; }
.selection-bubble__rule { width: 1px; height: 1.8rem; margin: 0 .4rem; background: var(--w-line-strong); }
/* The address is the label, not a control: it can be read, and it stays on one line so
   the bubble keeps the shape of a bar. */
.selection-bubble__href {
  padding: 0 .6rem; font-family: var(--font-mono); font-size: 1.25rem;
  color: var(--w-muted); white-space: nowrap;
}
.selection-bubble__action {
  height: 3rem; padding: 0 .9rem; border: 0; border-radius: 6px;
  background: none; font: inherit; font-weight: 500; color: inherit; cursor: pointer;
}
.selection-bubble__action:hover { background: rgba(0, 0, 0, .05); }
/* The slash menu. It is the toolbar's panels in another place — the same opaque paper,
   border, shadow and UI sans — because it is the same set of tools, offered at the point
   in the prose where the block will land. Placed by the controller against the
   paragraph's own rect; the canvas body is what it is placed inside. The selected row is
   the editor's own selection colour, so keyboard and mouse agree with the prose. */
.slash-menu {
  position: absolute; z-index: 30; margin: 0; padding: .5rem; list-style: none;
  inline-size: min(30rem, calc(100vw - 4rem)); max-block-size: 32rem; overflow-y: auto;
  background: var(--w-panel); border: 1px solid var(--w-line-strong); border-radius: 8px;
  box-shadow: var(--w-shadow);
  font-family: var(--font-sans); font-size: 1.4rem; line-height: 1.35;
  letter-spacing: 0; color: var(--w-ink);
}
.slash-menu[hidden] { display: none; }
.slash-menu__item { padding: .6rem .8rem; border-radius: 6px; cursor: pointer; }
.slash-menu__item[hidden] { display: none; }
.slash-menu__item:hover { background: rgba(0, 0, 0, .05); }
.slash-menu__item[aria-selected="true"] { background: rgba(180, 83, 9, .13); }
.slash-menu__label { display: block; font-weight: 500; }
.slash-menu__hint { display: block; margin-block-start: .1rem; font-size: 1.2rem; color: var(--w-muted); }

/* Embeds, seen from the editor. A YouTube frame plays here exactly as it will on the
   published page, in the same .kg-embed-card figure under the same rules. 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 .lexxy-editor__content 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 .lexxy-editor__content 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 .lexxy-editor__content blockquote.twitter-tweet a { word-break: break-all; }

/* An HTML card, seen from the editor: the real card in a sandboxed frame of its own
   document (Writing::HtmlCardsController#show), sized to its content by the message
   that document posts. Pointer events stay off so a click lands on the attachment and
   selects it — the card is one opaque block here, select or delete, nothing inside it
   is the writer's to press. */
.editor-canvas__body action-text-attachment:has(> .html-card-frame) { display: block; margin: 2.4rem 0; }
.editor-canvas__body .html-card-frame { display: block; width: 100%; height: 16rem; border: 0; pointer-events: none; }

/* The card's own document, as the frame above loads it: the published typography with
   none of the page around it, flush to the frame so the reported height is the card's. */
body.html-card { margin: 0; background: transparent; }
body.html-card .gh-content, body.html-card .kg-card { margin: 0; }

/* The card composer: tooling, not page, so it steps out of the canvas serif and stays
   quiet — a folded line under the prose that only becomes a form when it's wanted. */
.card-composer { margin-top: 2.4rem; font-family: var(--font-sans); font-size: 1.3rem; }
.card-composer__summary {
  padding: .4rem 0; width: fit-content; cursor: pointer;
  font-size: 1.15rem; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--w-faint);
}
.card-composer__summary:hover { color: var(--w-muted); }
.card-composer__source {
  display: block; width: 100%; margin: .8rem 0; padding: 1rem 1.2rem;
  border: 1px solid var(--w-line-strong); border-radius: 8px; background: var(--w-panel);
  font-family: var(--font-mono); font-size: 1.25rem; line-height: 1.5; color: var(--w-ink);
  resize: vertical;
}
.card-composer__foot { display: flex; align-items: center; flex-wrap: wrap; gap: .8rem 1.2rem; }
.card-composer__hint { margin: 0; color: var(--w-faint); }

/* ---- 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%);
  /* Visibility waits out the slide on the way closed and flips at once on the way open.
     Transitioning it in both directions left the panel un-focusable for the first frames
     of an opening, and a panel that can't take focus is a panel the keyboard can't use. */
  transition: transform .26s cubic-bezier(.4, 0, .2, 1), visibility 0s linear .26s;
}
.settings-panel.is-open {
  transform: translateX(0); visibility: visible;
  transition: transform .26s cubic-bezier(.4, 0, .2, 1), visibility 0s;
}
.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 0s linear .16s;
}
.publish-popover.is-open {
  visibility: visible; opacity: 1; transform: translateY(0);
  transition: opacity .16s ease, transform .16s ease, visibility 0s;
}
.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); }

/* A link at the foot of the settings panel, weighted as a link and not as a control —
   the panel's real controls are the fields above it and Delete below. */
.settings-panel__aside { display: flex; align-items: baseline; gap: .7rem; font-family: var(--font-sans); font-size: 1.3rem; color: var(--w-muted); }
.panel-link { background: none; border: 0; padding: 0; font: inherit; color: var(--w-ink); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.panel-link:hover { color: var(--w-accent-ink); }

/* ---- The shortcut sheet: a real <dialog>, so the browser owns the backdrop, the Escape
   key and the focus trap. Sized to the table rather than the viewport — it is a thing to
   glance at, not a page to read. ---- */
.shortcut-sheet {
  /* The site's reset zeroes every margin, which takes the centring a modal <dialog>
     gets from the UA stylesheet with it. Put it back. */
  width: min(46rem, 92vw); max-height: 82vh; margin: auto; padding: 0; overflow: auto;
  border: 1px solid var(--w-line); border-radius: var(--w-radius);
  background: var(--w-panel); color: var(--w-ink); box-shadow: var(--w-shadow);
  font-family: var(--font-sans);
}
.shortcut-sheet::backdrop { background: rgba(20, 18, 14, .3); }
.shortcut-sheet__head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.4rem 1.8rem; border-bottom: 1px solid var(--w-line);
  position: sticky; top: 0; background: var(--w-panel);
}
.shortcut-sheet__head h2 { font-size: 1.5rem; font-weight: 600; }
.shortcut-sheet__table { width: 100%; border-collapse: collapse; font-size: 1.35rem; }
.shortcut-sheet__table th {
  text-align: left; font-size: 1.15rem; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--w-faint); padding: 1.2rem 1.8rem .5rem;
}
.shortcut-sheet__table td { padding: .6rem 1.8rem; border-top: 1px solid var(--w-line); vertical-align: baseline; }
.shortcut-sheet__table td:first-child { width: 1%; white-space: nowrap; }
.shortcut-sheet__table tr:first-child td { border-top: 0; }
.shortcut-sheet__foot { padding: 1.2rem 1.8rem 1.6rem; font-size: 1.25rem; color: var(--w-muted); }

/* The keys themselves, in the two places the workbench prints them. Named rather than
   scoped to `.writing-app`, which would reach into the canvas and restyle a <kbd> the
   writer typed — the editor's prose has to look like the published page. */
.shortcut-sheet kbd,
.settings-panel__aside kbd {
  display: inline-block; padding: .2rem .55rem; min-width: 2.2rem; text-align: center;
  font-family: var(--font-sans); font-size: 1.25rem; font-weight: 600; line-height: 1.4;
  color: var(--w-ink); background: var(--w-surface);
  border: 1px solid var(--w-line-strong); border-bottom-width: 2px; border-radius: 6px;
}

/* ---- 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; }
  /* A phone bar has room for the state of the work or the name of it, not both, and the
     writer is one flick from the title itself. (Phone editor chrome proper is 5.6.) */
  .editor-bar__title { display: 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; }
}
