/* Version A "Sun-bleached steppe" — static HTML port of the kit chrome plus the parts added in the 2026-09 design session.
   Reads tokens from ../../styles.css only. Classes marked NEW have no counterpart in the JSX kit or the component set;
   the others are 1:1 ports of Chrome.jsx / components (so a Nunjucks partial can copy them verbatim). See CHANGES.md. */

/* ---- Chrome (port of Chrome.jsx) ---- */
.mo-page{position:relative;min-height:100vh;background:var(--surface-page)}
/* .mo-header, .mo-brand, the bare .mo-nav block, and the bare .mo-lang
   block are removed (2026-09-16): they were a first, unused 1:1 port of
   Chrome.jsx for a page structure this site does not use. header.njk
   puts the class "mo-nav" on the <header> itself and uses mo-nav__brand,
   mo-nav__links, mo-nav__link, mo-lang, mo-lang__item, mo-lang__sep
   (defined in steppe.css); the bare .mo-nav and .mo-lang rules here had
   the same selectors and, loaded after steppe.css, won the cascade for
   shared properties such as justify-content, breaking the header layout
   at wide widths. steppe.css alone now styles the header. */
.mo-main{padding:var(--space-9) var(--gutter-page) 0}
.mo-page-end{display:flex;justify-content:center;padding:var(--space-9) 0 var(--space-7)}
.mo-page-end img{height:72px}
.mo-footer{border-top:1px solid var(--border-hairline);padding:var(--space-8) var(--gutter-page) var(--space-7);display:grid;grid-template-columns:1.2fr 1fr 1fr 1fr;gap:40px}
.mo-footer__col{display:flex;flex-direction:column;gap:10px}
.mo-footer__col a{font-family:var(--font-text);font-size:16px;color:var(--text-body);border:0}
.mo-footer__about{font-size:15px;color:var(--text-muted);max-width:34ch}
.mo-footer__base{grid-column:1 / -1;display:flex;justify-content:space-between;gap:24px;flex-wrap:wrap;padding-top:24px;border-top:1px solid var(--border-hairline);font-family:var(--font-ui);font-size:13px;color:var(--text-faint)}

/* ---- Component ports ---- */
.mo-tag{font-family:var(--font-ui);font-size:var(--text-label);letter-spacing:var(--tracking-label);display:inline-flex;align-items:center;padding:4px 8px 3px;border:1px solid var(--border-hairline);border-radius:var(--radius-sm);white-space:nowrap;color:var(--text-muted)}
.mo-tag--gilt{color:var(--ochre-1);border-color:color-mix(in oklab,var(--ochre-1) 45%,transparent)}
.mo-tag--seal{color:var(--flame-2);border-color:color-mix(in oklab,var(--flame-1) 40%,transparent);background:var(--flame-wash)}
.mo-btn{font-family:var(--font-ui);font-size:var(--text-ui-md);letter-spacing:var(--tracking-ui);line-height:var(--leading-ui);display:inline-flex;align-items:center;gap:var(--space-3);padding:10px 20px;border:1px solid transparent;border-radius:var(--radius-sm);cursor:pointer;text-decoration:none;transition:var(--transition-color)}
.mo-btn--ghost{padding:8px 4px;color:var(--text-link);background:none}
.mo-btn--ghost:hover{color:var(--text-link-hover)}
.mo-btn--secondary{color:var(--text-strong);border-color:var(--border-strong)}
.mo-btn--secondary:hover{background:var(--paper-2);border-color:var(--ink-2)}
.mo-btn--seal{background:var(--flame-1);color:var(--paper-0);border-color:var(--flame-1)}
.mo-btn--seal:hover{background:var(--flame-2);border-color:var(--flame-2);color:var(--paper-0)}
.mo-btn--lg{padding:14px 28px;font-size:1rem}
.mo-heading{display:flex;flex-direction:column;gap:var(--space-4)}
.mo-heading__row{display:flex;width:100%;align-items:baseline;justify-content:space-between;gap:var(--space-6)}
.mo-heading__title{font-size:var(--text-display-3)}
.mo-heading__lede{font-size:var(--text-lede);font-weight:var(--weight-light);color:var(--text-muted);max-width:var(--measure-prose)}
.mo-divider{border:0;border-top:1px solid var(--border-hairline);margin:0}
.mo-divider--rule{border-top:2px solid var(--ink-1)}
.mo-divider--labelled{display:flex;align-items:center;gap:var(--space-5)}
.mo-divider--labelled::after{content:"";flex:1;height:1px;background:var(--border-hairline)}
.mo-divider--ornament{display:flex;align-items:center;gap:var(--space-5);color:var(--rule-ornament);font-family:var(--font-display);font-size:1.25rem;letter-spacing:.5em}
.mo-divider--ornament::before,.mo-divider--ornament::after{content:"";flex:1;height:1px;background:var(--border-hairline)}
.mo-book{display:flex;flex-direction:column;gap:var(--space-5);border:0;color:inherit}
/* Owner feedback 2026-09-22: a cover is never cropped or resized out of
   its own shape. The plate is a fixed 2:3 box with no frame of its own.
   The cover fills the box at its natural aspect ratio ("contain"): its
   width is the box width or its height is the box height. A small cover
   scales up, so all covers have the standard size. The cover sits at the
   bottom and in the horizontal center, so all covers stand on one shelf.
   CSS cannot select the axis from the image ratio, so the img fills the
   box and object-fit:contain draws the cover. A box border or box-shadow
   would then frame the empty box, so the frame is a chain of
   drop-shadow filters. A drop-shadow follows the drawn pixels, so the
   frame follows the real image. The first four filters draw the 1px
   hairline; the last two approximate --shadow-2 and --shadow-3
   (drop-shadow has no spread value). The img is inset by the 1px
   hairline, so the frame stays inside the box, as the old border did. */
.mo-book__plate{aspect-ratio:2 / 3;position:relative;transition:transform var(--duration-base) var(--ease-out);display:grid;place-items:end center}
a.mo-book:hover .mo-book__plate, a.mo-book:focus-visible .mo-book__plate{transform:translateY(-3px)}
.mo-book__plate{--book-frame:drop-shadow(1px 0 0 var(--border-hairline)) drop-shadow(-1px 0 0 var(--border-hairline)) drop-shadow(0 1px 0 var(--border-hairline)) drop-shadow(0 -1px 0 var(--border-hairline))}
.mo-book__plate img{position:absolute;inset:1px;width:calc(100% - 2px);height:calc(100% - 2px);max-width:none;max-height:none;box-sizing:border-box;object-fit:contain;object-position:50% 100%;background:none;border:0;box-shadow:none;filter:var(--book-frame) drop-shadow(0 2px 4px rgba(43,36,28,.05)) drop-shadow(0 8px 10px rgba(43,36,28,.12));transition:filter var(--duration-base) var(--ease-out)}
a.mo-book:hover .mo-book__plate img, a.mo-book:focus-visible .mo-book__plate img{filter:var(--book-frame) drop-shadow(0 4px 8px rgba(43,36,28,.06)) drop-shadow(0 16px 16px rgba(43,36,28,.16))}
.mo-book__text{display:flex;flex-direction:column;gap:var(--space-2)}
.mo-book__title{font-family:var(--font-display);font-size:var(--text-subtitle);font-weight:var(--weight-regular);color:var(--text-strong);line-height:var(--leading-title);transition:var(--transition-color)}
a.mo-book:hover .mo-book__title, a.mo-book:focus-visible .mo-book__title{color:var(--seal-1)}
.mo-book__orig{font-size:var(--text-body-sm);font-style:italic;color:var(--text-muted)}
.mo-book__meta{font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-faint)}
.mo-figure{margin:0;display:flex;flex-direction:column;gap:var(--space-4)}
.mo-figure__plate{aspect-ratio:3 / 4;background:var(--paper-3);overflow:hidden;display:grid;place-items:center;border:var(--border-width-frame) solid var(--paper-0);box-shadow:var(--shadow-2)}
.mo-figure__plate img{width:100%;height:100%;object-fit:cover}
.mo-figure figcaption{font-size:var(--text-caption);color:var(--text-muted)}
.mo-tabs{display:flex;gap:var(--space-7);border-bottom:1px solid var(--border-hairline)}
.mo-tabs a{font-family:var(--font-ui);font-size:var(--text-ui-md);letter-spacing:var(--tracking-ui);color:var(--text-muted);border:0;border-bottom:2px solid transparent;padding:0 0 var(--space-4);margin-bottom:-1px}
.mo-tabs a:hover{color:var(--text-body)}
.mo-tabs a.is-active{color:var(--text-strong);border-bottom-color:var(--seal-1)}
.mo-pagination{display:flex;align-items:center;gap:var(--space-3)}
.mo-pagination a{min-width:32px;height:32px;display:grid;place-items:center;padding:0 8px;font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-body);border:1px solid var(--border-hairline);border-radius:var(--radius-sm)}
.mo-pagination a.is-active{background:var(--ink-1);border-color:var(--ink-1);color:var(--paper-0)}
.mo-pagination a.is-disabled{opacity:.35;pointer-events:none}

/* ---- NEW: Now block (Rule 9) ---- */
/* Owner decision 2026-09-23: one entry with a photo (.mo-now__photo),
   an optional book cover (.mo-now__cover), a title, a short text, and
   an optional link. Design canvas "Now Section Options", layout B: "Now"
   top left, level with the top of the photo; the title, text and link
   sit at the bottom left. With a cover (.mo-now--cover), the cover
   overlaps the lower-left corner of the photo. The phone layout is in
   the max-width:640px block below. */
.mo-now{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--space-8);padding:var(--space-8) 0;border-top:2px solid var(--ink-1);border-bottom:1px solid var(--border-hairline)}
.mo-now__title{font-size:var(--text-display-3);margin:0;line-height:1}
.mo-now--entry{grid-template-columns:minmax(0,1fr) minmax(0,640px);grid-template-areas:"head media" "body media";grid-template-rows:auto 1fr;column-gap:var(--space-10);row-gap:var(--space-8)}
.mo-now--entry.mo-now--compact{grid-template-columns:minmax(0,1fr);grid-template-areas:"head" "body";grid-template-rows:auto auto}
.mo-now__head{grid-area:head}
.mo-now__media{grid-area:media;position:relative}
.mo-now__body{grid-area:body;display:flex;flex-direction:column;gap:var(--space-4);align-items:flex-start}
.mo-now__cover img,.mo-now__photo img{display:block;width:100%;height:100%;object-fit:cover}
.mo-now__cover{aspect-ratio:2 / 3;background:var(--surface-sunken);box-shadow:0 18px 40px rgba(43,36,28,0.18)}
.mo-now__photo{aspect-ratio:7 / 5;background:var(--surface-sunken)}
/* With a cover: the photo takes the right 87.5% of the media column.
   The cover is 31.25% wide and sits at the bottom left; the padding at the
   bottom of the column (a percentage of its width) makes room for the
   part of the cover that hangs below the photo. */
.mo-now--cover .mo-now__media{padding-bottom:15.6%}
.mo-now--cover .mo-now__photo{margin-left:12.5%}
.mo-now--cover .mo-now__cover{position:absolute;left:0;bottom:0;width:31.25%;box-shadow:0 18px 40px rgba(43,36,28,0.25)}
.mo-now__entry-title{margin:0;font-family:var(--font-display);font-size:clamp(2.25rem,4.4vw,3.5rem);line-height:1.05;font-weight:500;color:var(--text-strong)}
.mo-now__text{margin:0;max-width:36em;font-size:var(--text-lede);line-height:1.55;color:var(--text-body)}
.mo-now__link{font-family:var(--font-ui);font-size:var(--text-ui-sm);letter-spacing:var(--tracking-ui)}
/* Owner feedback 2026-09-23: on a desktop, the title, text and link are
   centred on the height of the section, beside the photo. "Now" stays
   top left. The body spans both rows, so it centres on the full height. */
@media (min-width:1001px){
  .mo-now--entry .mo-now__body{grid-row:1 / span 2;align-self:center}
}
@media (max-width:1000px){
  /* Now on a phone or tablet (layout C): one column. It switches at
     1000px, the same width as the rest of the page. The photo is full width at
     3:2. With a cover, the cover overlaps the bottom edge of the photo. */
  .mo-now--entry{grid-template-columns:minmax(0,1fr);grid-template-areas:"head" "media" "body";grid-template-rows:auto auto auto;row-gap:var(--space-5)}
  .mo-now--entry .mo-now__media{width:100%;max-width:640px}
  .mo-now--entry .mo-now__photo{aspect-ratio:3 / 2}
  .mo-now--cover .mo-now__media{padding-bottom:0}
  .mo-now--cover .mo-now__photo{margin-left:0}
  .mo-now--cover .mo-now__cover{position:relative;left:auto;bottom:auto;width:42%;max-width:240px;margin:-25% 0 0 var(--space-5)}
}
/* ---- Owner feedback 2026-09-16: Home Now block touched the viewport
   edges. Home sets ownGutter: true (src/pages/home.njk), so <main> gets
   no .mo-main class and .mo-now, a direct child of <main>, gets no
   horizontal padding. The News and Events page also renders .mo-now,
   but <main> there keeps .mo-main, which already carries
   var(--gutter-page) (line 16 above); scoping this rule to
   `main:not(.mo-main)` adds the gutter only where nothing else gives
   it, so News and Events never gets double padding. About no longer
   renders .mo-now (removed 2026-09-16). Owner feedback 2026-09-22: the
   rules crossed the margin rail, so the gutter is a margin, not a
   padding, and the rules span only the width between the margins. ---- */
main:not(.mo-main) > .mo-now{margin-inline:var(--gutter-page)}
.mo-now--compact{gap:var(--space-4);padding:var(--space-5) 0 var(--space-6);border-top-width:1px}
.mo-now--compact .mo-now__entry-title{font-size:var(--text-title)}
.mo-now--compact .mo-now__text{font-size:var(--text-body-md)}

/* ---- NEW: News and Events index ---- */
.mo-news{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:var(--space-10);align-items:start;margin-top:var(--space-8)}
.mo-upcoming{display:grid;grid-template-columns:180px minmax(0,1fr);gap:var(--space-8);padding:var(--space-7) 0 var(--space-8);border-top:2px solid var(--ink-1)}
.mo-upcoming__date{font-family:var(--font-display);font-size:var(--text-display-3);line-height:1;color:var(--text-strong)}
.mo-upcoming__date small{display:block;font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--ochre-1);margin-top:var(--space-3);letter-spacing:var(--tracking-ui)}
.mo-upcoming__body{display:flex;flex-direction:column;gap:var(--space-4);align-items:flex-start}
.mo-upcoming__title{font-size:var(--text-title);line-height:var(--leading-title)}
.mo-upcoming__title a{color:inherit;border:0}
.mo-upcoming__title a:hover{color:var(--flame-1)}
.mo-news-list{list-style:none;margin:0;padding:0}
.mo-news-item{display:grid;grid-template-columns:180px minmax(0,1fr);gap:var(--space-8);padding:var(--space-6) 0;border-top:1px solid var(--border-hairline)}
.mo-news-item__when{display:flex;flex-direction:column;gap:var(--space-3);align-items:flex-start;font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-muted)}
.mo-news-item__when time{color:var(--text-body)}
.mo-news-item__title{font-size:var(--text-title);line-height:var(--leading-title)}
.mo-news-item__title a{color:var(--text-strong);border:0}
.mo-news-item__title a:hover{color:var(--flame-1)}
.mo-news-item__summary{margin-top:var(--space-3);color:var(--text-muted);font-size:var(--text-body-lg);max-width:var(--measure-prose);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
.mo-news-year{font-family:var(--font-ui);font-size:var(--text-label);letter-spacing:var(--tracking-label);color:var(--text-faint);padding:var(--space-8) 0 var(--space-4)}
.mo-news-aside{display:flex;flex-direction:column;gap:var(--space-6);position:sticky;top:var(--mo-sticky-top)}

/* ---- NEW: News post ---- */
.mo-post{display:grid;grid-template-columns:180px minmax(0,66ch) minmax(120px,1fr);gap:56px}
.mo-post__rail{display:flex;flex-direction:column;gap:18px;position:sticky;top:var(--mo-sticky-top);align-self:start}
.mo-post__rail a{font-family:var(--font-ui);font-size:13px;border:0}
.mo-post__rail time{font-family:var(--font-display);font-size:20px;color:var(--text-strong)}
.mo-post__body{display:flex;flex-direction:column;gap:var(--space-8)}
.mo-post__head{display:flex;flex-direction:column;gap:14px}
.mo-post__title{font-size:var(--text-display-2);line-height:var(--leading-tight)}
.mo-post__text{display:flex;flex-direction:column;gap:var(--space-6);font-size:var(--text-body-lg)}
.mo-post__text a{word-break:break-all}

/* ---- NEW: Works ---- */
.mo-works-index{list-style:none;margin:0;padding:0}
.mo-works-index li{display:grid;grid-template-columns:minmax(0,1fr) 260px;gap:var(--space-8);align-items:center;padding:var(--space-7) 0;border-bottom:1px solid var(--border-hairline)}
.mo-works-index__title{font-size:var(--text-display-3);line-height:var(--leading-title)}
.mo-works-index__title a{color:var(--text-strong);border:0}
.mo-works-index__title a:hover{color:var(--flame-1)}
.mo-works-index__count{font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-faint);margin-top:var(--space-2)}
.mo-works-index__lede{margin-top:var(--space-4);color:var(--text-muted);font-size:var(--text-body-lg);max-width:52ch}
.mo-works-index__strip{display:flex;gap:10px;justify-content:flex-end}
.mo-works-index__strip img,.mo-works-index__strip span{width:64px;height:96px;object-fit:cover;border:1px solid var(--border-hairline);box-shadow:var(--shadow-1)}
.mo-works-index__strip span{display:grid;place-items:center;background:var(--sand-2);font-family:var(--font-display);font-style:italic;font-size:11px;text-align:center;padding:6px;color:var(--text-muted);line-height:1.2}
.mo-book-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:40px 32px;margin-top:var(--space-8)}
/* No-cover fallback: the title set in the display face on a toned panel. The panel is a plate, not a placeholder. */
.mo-book__panel{width:100%;height:100%;box-sizing:border-box;background:var(--sand-2);border:1px solid var(--border-hairline);display:flex;flex-direction:column;justify-content:space-between;padding:18% 12% 12%;text-align:center;box-shadow:inset 0 0 0 1px var(--sand-3),var(--shadow-2);transition:box-shadow var(--duration-base) var(--ease-out)}
a.mo-book:hover .mo-book__panel, a.mo-book:focus-visible .mo-book__panel{box-shadow:inset 0 0 0 1px var(--sand-3),var(--shadow-3)}
.mo-book__panel-title{font-family:var(--font-display);font-style:italic;font-size:clamp(1.25rem,1.6vw,1.625rem);line-height:1.2;color:var(--text-strong);text-wrap:balance}
.mo-book__panel-title::before{content:"";display:block;width:24px;height:1px;background:var(--ochre-2);margin:0 auto var(--space-5)}
.mo-book__panel-foot{font-family:var(--font-ui);font-size:var(--text-label);letter-spacing:var(--tracking-label);color:var(--text-muted)}
.mo-calli-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-8) var(--space-7);margin-top:var(--space-8)}
/* Owner feedback 2026-09-22: the same one-shelf rule and the same
   standard-size "contain" fit as .mo-book__plate. The 4:3 plate is a box
   with no frame of its own. The piece scales up or down at its natural
   aspect ratio until its width or its height is the box width or height.
   It sits at the bottom and in the center. The 6px paper frame is a
   chain of drop-shadow filters, so the frame follows the real image. The
   img is inset by the frame width, so the frame stays inside the box.
   Scoped to the calligraphy grid, so the other .mo-figure__plate uses
   (poem, now, photo grid) do not change. */
.mo-calli-grid .mo-figure__plate{aspect-ratio:4 / 3;position:relative;overflow:visible;place-items:end center;background:none;border:0;box-shadow:none}
.mo-calli-grid .mo-figure__plate img{--f:var(--border-width-frame);position:absolute;inset:var(--f);width:calc(100% - 2 * var(--f));height:calc(100% - 2 * var(--f));max-width:none;max-height:none;box-sizing:border-box;object-fit:contain;object-position:50% 100%;background:none;border:0;box-shadow:none;filter:drop-shadow(var(--f) 0 0 var(--paper-0)) drop-shadow(calc(-1 * var(--f)) 0 0 var(--paper-0)) drop-shadow(0 var(--f) 0 var(--paper-0)) drop-shadow(0 calc(-1 * var(--f)) 0 var(--paper-0)) drop-shadow(0 2px 4px rgba(43,36,28,.05)) drop-shadow(0 8px 10px rgba(43,36,28,.12))}
.mo-essays{list-style:none;margin:var(--space-8) 0 0;padding:0;border-top:2px solid var(--ink-1);max-width:66ch}
.mo-essays li{display:flex;flex-direction:column;gap:var(--space-3);align-items:flex-start;padding:var(--space-6) 0;border-bottom:1px solid var(--border-hairline)}
.mo-essays__title{font-size:var(--text-title);line-height:var(--leading-title)}
.mo-essays__title a{color:var(--text-strong);border:0}
.mo-essays__title a:hover{color:var(--flame-1)}
.mo-essays__meta{display:flex;gap:var(--space-3);align-items:center;font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-faint)}

/* ---- Mock-only: labels a page fragment in a composite mockup. Not for the build. ---- */
.mock-note{font-family:var(--font-ui);font-size:12px;letter-spacing:.08em;color:var(--sky-1);background:var(--sky-wash);padding:8px var(--gutter-page);border-top:1px dashed var(--sky-2);border-bottom:1px dashed var(--sky-2)}

/* Calligraphy of the day beside the poem (design-system),
   Steppe styling: the existing .mo-figure / .mo-figure__plate frame.
   Layout (owner feedback 2026-09-18): the band is a wrapping flex row.
   The poem article takes the width of its longest verse line, so no
   line of poetry wraps (white-space:pre on the verse; the earlier
   pre-wrap and the --measure-poem cap wrapped long lines). The
   calligraphy figure takes all the space that remains beside the poem
   and grows with it. When less than 280px remains, the figure wraps to
   its own row below the poem and takes the full width. The media rule
   at max-width:1000px no longer needs a one-column override. A verse
   wider than the page does not wrap: js/verse-fit.js shrinks its font
   size to fit (owner feedback 2026-09-23). The stack scrolls only below
   the script's minimum size, or with no script.
   The plate keeps the 16:10 aspect ratio, so a wider figure is also a
   taller figure and fills the freed space. */
.mo-poem-band{display:flex;flex-wrap:wrap;gap:var(--space-8);align-items:flex-start}
.mo-poem-band .mo-poem{flex:0 0 auto;max-width:100%;min-width:0}
.mo-poem-band .mo-poem__stack{overflow-x:auto;max-width:100%}
.mo-poem-band .mo-poem__verse{white-space:pre;max-width:none}
.mo-poem-band .mo-poem__title,.mo-poem-band .mo-poem__subtitle,.mo-poem-band .mo-poem__credit{max-width:var(--measure-poem)}
/* The calligraphy column repeats the poem column's own header: the same
   .mo-label, on the same line, and the plate starts on the line the poem
   title starts on. The gap is --space-6, the gap .mo-poem sets between
   its label and its title. */
.mo-poem-band__calligraphy{flex:1 1 280px;min-width:min(280px,100%);display:flex;flex-direction:column;gap:var(--space-6)}
.mo-poem-band .mo-figure__plate{aspect-ratio:16/10}

@media (max-width:1000px){
  .mo-news,.mo-post{grid-template-columns:1fr}
  .mo-post__rail{position:static}
  .mo-news-aside{position:static}
  .mo-book-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .mo-calli-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .mo-footer{grid-template-columns:1fr 1fr}
  .mo-works-index li{grid-template-columns:1fr}
  .mo-works-index__strip{justify-content:flex-start}
}
@media (max-width:640px){
  .mo-upcoming,.mo-news-item{grid-template-columns:1fr;gap:var(--space-4)}
  .mo-book-grid,.mo-calli-grid,.mo-footer{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* ---- Implementer addition, 2026-09-15: Home hero, the daily poem block,
   the poem page, honours, press, the photo grid, contact forms, the About
   and Contact heroes. Ported from Home.jsx, Poem.jsx, Biography.jsx,
   Contact.jsx and the PoemBlock, SectionHeading, Figure, Input, Checkbox
   component sources (inline styles there; class rules here so the
   Nunjucks partials in src/_includes/steppe/ can use plain class names).
   No new stylesheet file: this file already holds the page-level parts,
   the same role css/flame/flame-pages.css holds for Flame. ---- */

/* Every top-level section here relies on the surrounding page for the
   left/right gutter, the same way .mo-now above does not set
   its own horizontal padding. .mo-gutter is the one exception: the
   Home hero and the poem block are not wrapped by .mo-main (see
   news.html / works-index.html), so they carry the gutter themselves. */
.mo-gutter{padding-inline:var(--gutter-page)}

/* ---- Hero (Home.jsx, section 1). design-system
   moves the photograph to the first grid column and the text to the
   second, and raises the minimum height to 735px. Owner feedback
   2026-09-16: the photo was too wide next to the text; the columns
   now hold a fixed 2:1 ratio (about two thirds photo, one third text)
   instead of the photo filling all the leftover space. ---- */
/* Owner feedback 2026-09-22: on desktop the photo spans the full width
   between the margins, with a top margin equal to the side margin. The
   text sits on the photo: the role label in a box at the top left, the
   poem in a box at the bottom right. The two columns and their
   height balance (2026-09-16) are gone. Owner feedback 2026-09-22: the
   top margin is half the gutter, and the photo fills the window below
   the header with the same half-gutter gap under it. js/hero-fit.js
   sets --nav-h to the header height. The photo is never taller than
   it is wide, and never shorter than 26rem. */
.mo-hero{position:relative;margin:calc(var(--gutter-page) / 2) var(--gutter-page) 0;--hero-box:color-mix(in srgb,var(--surface-page) 70%,transparent)}
.mo-hero__content{position:absolute;inset:0;padding:var(--space-7);display:flex;flex-direction:column;justify-content:space-between;align-items:flex-start;gap:var(--space-6)}
.mo-hero__native{font-family:var(--font-display);font-style:italic;font-size:var(--text-subtitle);color:var(--text-muted)}
.mo-hero__tags{display:flex;gap:8px;flex-wrap:wrap}
.mo-hero__figure{position:relative;overflow:hidden;width:100%;height:max(26rem,min(calc(100vh - var(--nav-h,90px) - var(--gutter-page)),calc(100vw - 2 * var(--gutter-page))));background:var(--sand-2)}
.mo-hero__figure img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Owner instruction 2026-09-23: the hero is a full-body portrait. Crop the
   bottom edge only, never the top; crop the side edges equally. On a phone,
   the tall box cuts much of each side, so move the crop to the left, where
   the poet stands. Owner instruction 2026-09-28: the photo is now wider
   (aduu-steppe-wide-2304.webp). The poet stands at 33% of its width, so
   the phone crop is 33%. */
.mo-hero__figure img{object-position:center top}
@media (max-width:640px){
  .mo-hero__figure img{object-position:33% top}
}

/* ---- PoemBlock, Home daily poem (PoemBlock.jsx) ---- */
.mo-poem-wrap{padding:var(--section-gap) var(--gutter-page)}
.mo-poem{display:flex;flex-direction:column;gap:var(--space-6)}
/* Owner request 2026-09-23: the "Poem of the day" line holds the label
   on the left and the МОН / ENG switch (.mo-lang, css/steppe/steppe.css)
   on the right. The switch items are buttons here, not links. */
.mo-poem__head{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-4)}
.mo-poem__lang .mo-lang__item{background:none;border-top:0;border-left:0;border-right:0;padding:0;cursor:pointer}
.mo-poem__lang .mo-lang__item[disabled]{cursor:default;opacity:0.5}
.mo-poem__lang .mo-lang__item[disabled]:hover{color:var(--text-faint)}
.mo-poem__title{font-family:var(--font-display);font-size:var(--text-display-3);font-style:italic;color:var(--text-strong)}
.mo-poem__subtitle{font-family:var(--font-display);font-size:var(--text-subtitle);font-style:italic;color:var(--text-muted);margin-top:4px}
.mo-poem__stack{display:grid}
.mo-poem__pane{grid-area:1/1;opacity:0;visibility:hidden;transition:opacity var(--duration-veil) var(--ease-in-out),visibility 0s linear var(--duration-veil)}
.mo-poem__pane.is-on{opacity:1;visibility:visible;transition:opacity var(--duration-exchange) var(--ease-in-out) 500ms,visibility 0s linear 0s}
.mo-poem__verse{font-family:var(--font-text);font-size:var(--text-lede);font-weight:var(--weight-light);line-height:var(--leading-poem);color:var(--text-strong);max-width:var(--measure-poem);white-space:pre-wrap;margin:0}
.mo-poem__toggle{align-self:flex-start;font-family:var(--font-ui);font-size:var(--text-ui-sm);letter-spacing:var(--tracking-ui);color:var(--text-link);background:none;border:0;border-bottom:1px solid var(--border-hairline);padding:0;cursor:pointer;transition:var(--transition-color)}
.mo-poem__toggle:hover{color:var(--text-link-hover);border-bottom-color:var(--text-link-hover)}
.mo-poem__toggle[disabled]{opacity:.5;cursor:default}
.mo-poem__credit{font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-muted)}
/* The "Read more" link is a flex child of .mo-poem; without this it
   stretches to the full column width. */
[data-mf-poem-link]{align-self:flex-start}

/* ---- Poem page (Poem.jsx), verse macro, meta band, audio ---- */
.mo-poem-page{max-width:var(--measure-prose);margin:0 auto;padding:var(--section-gap) var(--gutter-page) 0;display:flex;flex-direction:column;gap:var(--space-8)}
.mo-poem-page__back{font-family:var(--font-ui);font-size:var(--text-ui-sm);align-self:center;color:var(--text-muted)}
.mo-poem-page__head{text-align:center;display:flex;flex-direction:column;align-items:center;gap:12px}
.mo-poem-page__title{font-size:var(--text-display-2);line-height:var(--leading-tight);font-style:italic}
.mo-poem-page__orig{font-family:var(--font-display);font-style:italic;font-size:var(--text-subtitle);color:var(--text-muted)}
.mo-poem-page__note{font-size:var(--text-caption);color:var(--text-muted);text-align:center;max-width:52ch;margin:0 auto}
.mo-verse{font-family:var(--font-text);font-size:var(--text-lede);font-weight:var(--weight-light);line-height:var(--leading-poem);max-width:var(--measure-poem);white-space:pre-wrap;color:var(--text-strong);margin:0 auto}
.mo-meta-band{display:flex;justify-content:center;gap:var(--space-8);flex-wrap:wrap;padding:var(--space-5) 0;border-top:1px solid var(--border-hairline);border-bottom:1px solid var(--border-hairline)}
.mo-meta-band__item{display:flex;flex-direction:column;gap:6px;align-items:center;font-size:var(--text-body-sm)}
.mo-meta-band__item em{font-family:var(--font-display);font-style:italic;font-size:1.0625rem;color:var(--text-strong)}

/* ---- Honours (Biography.jsx honours column) ---- */
.mo-honours{list-style:none;margin:0;padding:0}
.mo-honours li{display:grid;grid-template-columns:56px 1fr;gap:var(--space-5);padding:16px 0;border-top:1px solid var(--border-hairline)}
.mo-honours li:last-child{border-bottom:1px solid var(--border-hairline)}
.mo-honours b{font-family:var(--font-ui);font-size:var(--text-ui-sm);font-weight:400;color:var(--ochre-1);padding-top:3px}
.mo-honours strong{display:block;font-family:var(--font-display);font-weight:var(--weight-regular);font-size:1.1875rem;color:var(--text-strong)}
.mo-honours span{display:block;font-size:14px;color:var(--text-muted);margin-top:2px}

/* ---- Press and scholarship. No component in the kit for this; the row
   pattern follows .mo-honours and .mo-details, the same choice
   css/flame/flame-pages.css made for .mf-press-list. ---- */
.mo-press-list{list-style:none;margin:0;padding:0}
.mo-press-list__item{display:flex;flex-direction:column;gap:4px;padding:14px 0;border-top:1px solid var(--border-hairline);font-size:var(--text-body-sm);color:var(--text-body)}
/* Owner feedback 2026-09-22: a citation can hold a long bare URL (one
   press item in content/about/press.json has two). The URL has no
   break point, so on a phone it made the About page 605px wide.
   overflow-wrap:anywhere lets the URL break at any character. */
.mo-press-list__item{overflow-wrap:anywhere}
.mo-press-list__item:last-child{border-bottom:1px solid var(--border-hairline)}
.mo-press-list__link{font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-muted);word-break:break-all}

/* ---- Photo grid (Biography.jsx closing figure row); each tile reuses
   .mo-figure / .mo-figure__plate above, at the 3:2 ratio Figure.jsx
   passes for these photographs. ---- */
/* Owner feedback 2026-09-22: one section gap above and below sets the
   photos apart from the text around them. */
.mo-photo-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-7);margin-block:var(--section-gap)}
/* Review of PR #34, 2026-09-25: a gallery photo is never cropped. The
   same one-shelf rule and "contain" fit as .mo-calli-grid (owner
   feedback 2026-09-22). The 3:2 plate is a box with no frame of its own.
   The photo scales up or down at its natural aspect ratio until its width
   or its height is the box width or height. It sits at the bottom and in
   the center. The 6px paper frame is a chain of drop-shadow filters, so
   the frame follows the real photo. The img is inset by the frame width,
   so the frame stays inside the box. */
.mo-photo-grid .mo-figure__plate{position:relative;overflow:visible;place-items:end center;background:none;border:0;box-shadow:none}
.mo-photo-grid .mo-figure__plate img{--f:var(--border-width-frame);position:absolute;inset:var(--f);width:calc(100% - 2 * var(--f));height:calc(100% - 2 * var(--f));max-width:none;max-height:none;box-sizing:border-box;object-fit:contain;object-position:50% 100%;background:none;border:0;box-shadow:none;filter:drop-shadow(var(--f) 0 0 var(--paper-0)) drop-shadow(calc(-1 * var(--f)) 0 0 var(--paper-0)) drop-shadow(0 var(--f) 0 var(--paper-0)) drop-shadow(0 calc(-1 * var(--f)) 0 var(--paper-0)) drop-shadow(0 2px 4px rgba(43,36,28,.05)) drop-shadow(0 8px 10px rgba(43,36,28,.12))}

/* ---- Contact forms (Input.jsx, Checkbox.jsx, Contact.jsx) ---- */
.mo-form{display:flex;flex-direction:column;gap:var(--space-6)}
/* Owner feedback 2026-09-23: one heading style for both contact forms
   (the style the signup heading had inline before). */
.mo-form__title{font-size:var(--text-subtitle);text-transform:none;letter-spacing:0}
.mo-form__row{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-6)}
.mo-form__actions{display:flex;align-items:center;gap:var(--space-5);flex-wrap:wrap}
.mo-field{display:flex;flex-direction:column;gap:6px}
.mo-field__label{font-family:var(--font-ui);font-size:var(--text-label);letter-spacing:var(--tracking-label);color:var(--text-muted)}
.mo-input,.mo-textarea{font-family:var(--font-text);font-size:var(--text-body-md);line-height:var(--leading-body);color:var(--text-strong);background:var(--surface-raised);border:1px solid var(--border-hairline);border-radius:var(--radius-sm);padding:9px 12px;width:100%;transition:var(--transition-color)}
.mo-input:hover,.mo-textarea:hover{border-color:var(--border-strong)}
.mo-input:focus,.mo-textarea:focus{outline:none;border-color:var(--earth-2);box-shadow:var(--shadow-inset-hairline)}
.mo-textarea{resize:vertical;min-height:160px}

/* ---- About biography and honours grid (Biography.jsx, section 2) ---- */
.mo-bio-grid{display:grid;grid-template-columns:minmax(0,66ch) 1fr;gap:var(--space-9);align-items:stretch}
/* Honours column: absolute box, so the biography sets the row height;
   the list scrolls inside (owner feedback 2026-09-16) */
.mo-bio-side{position:relative;min-height:0}
.mo-bio-side__box{position:absolute;inset:0;display:flex;flex-direction:column}
.mo-bio-side__scroll{flex:1 1 auto;min-height:0;overflow-y:auto;scrollbar-width:thin}
.mo-bio-text{display:flex;flex-direction:column;gap:var(--space-6);font-size:var(--text-body-lg)}

/* ---- Contact body (Contact.jsx main grid) ---- */
/* Owner feedback 2026-09-23: the two columns share the width equally. */
.mo-contact-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--space-10);align-items:start}
/* Each column is a stack: the right column holds the contact details
   and, below them, the sign-up form (owner feedback 2026-09-18). The
   gap is the same --space-7 the Flame .mf-stack utility uses. */
.mo-contact-grid > div{display:flex;flex-direction:column;gap:var(--space-7)}
.mo-details{display:flex;flex-direction:column}
/* Owner feedback 2026-09-23: the link underline stops at the end of the text. */
.mo-details div > a{justify-self:start}
.mo-details div{display:grid;grid-template-columns:140px 1fr;gap:var(--space-5);padding:14px 0;border-top:1px solid var(--border-hairline);font-size:var(--text-body-md);white-space:pre-line}

@media (max-width:1000px){
  .mo-hero,.mo-bio-grid,.mo-contact-grid{grid-template-columns:1fr}
  .mo-bio-side__box{position:static}
  .mo-bio-side__scroll{overflow:visible}
  /* Owner feedback 2026-09-22: the poem did not shrink on phones. A 1fr
     column grows to the min-content width of the nowrap poem lines, so
     js/hero-fit.js measured a box wider than the screen. minmax(0,1fr)
     keeps the column at the screen width. */
  .mo-hero{min-height:0;margin:0;grid-template-columns:minmax(0,1fr)}
  /* Owner report 2026-09-16: the photo vanished on phones. A stretched grid
     item with only an absolute child has no height on iOS Safari, so the
     image flows in the normal way here and carries the 4/3 ratio itself. */
  .mo-hero__figure{min-height:0;height:auto;align-self:start}
  .mo-hero__figure img{position:static;display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover}
  /* Below 1000px the text stays under the photo, not on it. */
  .mo-hero__content{position:static;padding:var(--space-8) var(--gutter-page)}
  /* Owner feedback 2026-09-22: on phones the hero fills the window below
     the header. The photo takes the height that the poem does not use,
     and is never shorter than 16rem. The figure has a height from the
     flex layout, so the image can be absolute again. The role label sits
     on the photo at the top left, in the same box as on desktop. Its
     positioned ancestor is .mo-hero, because .mo-hero__content is static
     here. The poem stays under the photo. */
  .mo-hero{display:flex;flex-direction:column;min-height:calc(100vh - var(--nav-h,64px));min-height:calc(100svh - var(--nav-h,64px))}
  .mo-hero__figure{flex:1 1 auto;min-height:16rem;position:relative}
  .mo-hero__figure img{position:absolute;inset:0;height:100%;aspect-ratio:auto}
  .mo-hero__content{padding:var(--space-6) var(--gutter-page)}
  .mo-hero__content > .mo-label{position:absolute;top:var(--gutter-page);left:var(--gutter-page);max-width:calc(100% - 2 * var(--gutter-page));box-sizing:border-box;background-color:var(--hero-box);padding:var(--space-3) var(--space-5)}
  .mo-photo-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .mo-form__row{grid-template-columns:1fr}
  .mo-details div{grid-template-columns:1fr}
  .mo-photo-grid{grid-template-columns:1fr}
}

/* ---- Implementer addition, 2026-09-15: Home "Selected works", the
   gallery strip, and the News and Events strip
   (src/_includes/steppe/{books,gallery,news-strip}.njk). These three
   sections are not wrapped by a `.mo-main`-classed <main> (steppe/base.njk
   gives <main> no class), so each carries its own gutter padding, the
   same choice .mo-hero and .mo-poem-wrap above make. No counterpart in
   the kit or in the Works and News classes above: `.mo-home-section` is
   a plain section wrapper, and `.mo-facts` is a compact date-and-link
   list for the 3-item News strip, smaller than `.mo-news-list`, which
   is built for the full ledger. ---- */
.mo-home-section{padding:var(--section-gap) var(--gutter-page);display:flex;flex-direction:column;gap:var(--space-7)}
.mo-facts{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-4)}
.mo-facts li{display:flex;gap:var(--space-5);align-items:baseline;padding:var(--space-4) 0;border-top:1px solid var(--border-hairline)}
.mo-facts b{font-family:var(--font-ui);font-size:var(--text-ui-sm);color:var(--text-faint);min-width:110px}
.mo-facts a{color:var(--text-strong);border:0}
.mo-facts a:hover{color:var(--flame-1)}

/* ---- Owner feedback 2026-09-16: Works entry page. The book, calligraphy
   and essay thumbnails were far too small, and only the title text was a
   link. Each row is now one link, .mo-works-index__row (works.njk wraps
   the whole li in one <a>, so h2 no longer holds its own inner <a>).
   These rules are appended, not merged into the .mo-works-index block
   above: this file loads after steppe.css, and later rules for the same
   selector win the cascade, so widening the strip images here overrides
   the smaller size set above without rewriting that block. ---- */
.mo-works-index li{display:block;padding:0}
.mo-works-index__row{display:grid;grid-template-columns:minmax(0,1fr) minmax(320px,42%);gap:var(--space-8);align-items:center;padding:var(--space-7) 0;color:inherit;border:0}
.mo-works-index__row:hover .mo-works-index__title{color:var(--flame-1)}
.mo-works-index__strip{gap:16px}
.mo-works-index__strip img,.mo-works-index__strip span{width:auto;min-width:0;flex:1 1 0;height:280px;object-fit:cover}
/* Owner feedback 2026-09-22: a strip image is never cropped. It keeps
   its natural aspect ratio, the old strip height is its maximum height,
   and all items stand on one shelf at the bottom of the strip. The text
   placeholders (span) keep their fixed height. */
.mo-works-index__strip{align-items:flex-end}
.mo-works-index__strip img{flex:0 1 auto;height:auto;max-height:280px;max-width:100%;box-sizing:border-box;object-fit:fill}
@media (max-width:1000px){
  .mo-works-index__row{grid-template-columns:1fr}
  .mo-works-index__strip{justify-content:flex-start}
  .mo-works-index__strip img,.mo-works-index__strip span{height:220px}
  .mo-works-index__strip img{height:auto;max-height:220px}
}
@media (max-width:640px){
  .mo-works-index__strip img,.mo-works-index__strip span{height:160px}
  .mo-works-index__strip img{height:auto;max-height:160px}
}

/* ---- Owner feedback 2026-09-16: Hero honours tags. A long award name in
   .mo-hero__tags kept .mo-tag's shared white-space:nowrap and overflowed
   past the text column instead of wrapping. Scoped to the hero so
   .mo-tag stays nowrap everywhere else (kind labels, essay tags). ---- */
.mo-hero__tags .mo-tag{white-space:normal;text-align:left}

/* ---- Owner instruction 2026-09-16: copy design-system
   Home.jsx's hero literally. That export's hero heading is the poem
   itself (fontSize 70, italic), not the poet's name, so .mo-hero__poem
   gives the poem that same display-italic-serif size. The clamp keeps
   the export's 70px ceiling but shrinks on narrow screens, the same
   pattern --text-display-1 (tokens/typography.css) already uses.
   Owner feedback 2026-09-22: the ceiling is now 2.5rem (40px), the size
   of the brand word in the header. ---- */
.mo-hero__poem{margin:0;width:100%;max-width:100%;font-family:var(--font-display);font-style:italic;font-weight:400;font-size:clamp(2.25rem,5vw,2.5rem);line-height:var(--leading-tight);color:var(--text-strong)}
/* Owner instruction 2026-09-16: a poem line must never wrap. Each line
   is one nowrap block; js/hero-fit.js sets the font size of .mo-hero__poem
   so the widest line fits the box width (ceiling 40px). ---- */
.mo-hero__line{display:block;white-space:nowrap}
/* Owner feedback 2026-09-22: above 1000px the label and the poem sit on
   the photo in semi-transparent boxes of the page color (70% opacity).
   The poem box takes the width of its widest line, up to one third of
   the photo; past that, js/hero-fit.js shrinks the poem so the box does
   not cover the portrait.
   Owner instruction 2026-09-23 (second): the label moves to the lower
   left corner and the poem box to the lower right corner, bottom edges
   level. The auto left margin keeps the poem at the right when role_mn
   is empty and the page has no label. */
@media (min-width:1001px){
  .mo-hero__content{flex-direction:row;align-items:flex-end}
  .mo-hero__content > .mo-label{background-color:var(--hero-box);padding:var(--space-3) var(--space-5)}
  .mo-hero__poem{align-self:flex-end;margin-left:auto;width:auto;max-width:33.333%;box-sizing:border-box;background-color:var(--hero-box);padding:var(--space-6) var(--space-7)}
}

/* Home Books grid (owner request 2026-09-19). The section writes four
   books. The grid is 4 across above 1000px and 2 across below 640px, so
   all four books show and every row is full. Between those two widths
   the grid is 3 across, so the fourth book is hidden there. The Works
   Books page keeps the plain .mo-book-grid and is not changed. */
@media (max-width:1000px) and (min-width:641px){
  .mo-book-grid--home > :nth-child(4){display:none}
}

/* Owner feedback 2026-09-22: a 1px hairline rule between each two Home
   sections, on phones and on desktop. The rule is the same one as the
   .mo-now bottom border above Books, inset by the page gutters. The
   pairs next to .mo-now get no rule, because .mo-now already draws a
   line on its top and bottom edges. Above 1000px the poem section
   starts at the bottom edge of the hero photo, so the rule there moves
   down half a gutter and does not touch the photo. */
.mo-hero + .mo-poem-wrap,.mo-home-section + .mo-home-section{position:relative}
.mo-hero + .mo-poem-wrap::before,.mo-home-section + .mo-home-section::before{content:"";position:absolute;top:0;left:var(--gutter-page);right:var(--gutter-page);border-top:1px solid var(--border-hairline)}
@media (min-width:1001px){
  .mo-hero + .mo-poem-wrap::before{top:calc(var(--gutter-page) / 2)}
}
/* On phones each side of a rule is --space-8 (48px), not the full
   --section-gap. The --section-gap token does not change. */
@media (max-width:640px){
  .mo-poem-wrap,.mo-home-section{padding-block:var(--space-8)}
}

/* Owner feedback 2026-09-22: helper classes for the page templates.
   .mo-page-head__rule is the rule under a page heading. .mo-now--plain
   is a .mo-now with no top line and no top padding. */
.mo-page-head__rule{margin:var(--space-8) 0}
.mo-now--plain{border-top:0;padding-top:0}
/* The News Now heading is an h2. Reset the h2 margins, weight, and
   line height, so it looks the same as a .mo-label span. */
.mo-now--plain h2.mo-label{margin:0;font-weight:inherit;line-height:inherit}
/* Owner feedback 2026-09-22: on a Works subpage the back link to Works
   sits above the page heading, in the style of the News "Latest"
   header (.mo-divider--labelled). */
.mo-page-back{margin-bottom:var(--space-6)}
/* Owner feedback 2026-09-22: below 1000px the role label on the hero
   photo stays on one line. js/hero-fit.js sets its font size so the
   line fits the box. The label text is editable in the admin, so a
   fixed CSS size cannot fit every text. */
@media (max-width:1000px){
  .mo-hero__content > .mo-label{white-space:nowrap}
}

/* Owner instruction 2026-09-23: no text is forced to all capitals, in
   Mongolian or in English. Each label shows the letter case that the
   editor saved. Do not add text-transform:uppercase to site styles. */
