/* Wattulus v3 "Swiss Umber" — drop-in Ghost theme stylesheet. Pair with ghost/README.md. */
@import url("https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600&family=Spline+Sans+Mono:wght@400;500&display=swap");
/* Light is the default for every visitor (Karthi, 2026-10-11); .dark is an
   opt-in alternative toggled by assets/js/wattulus-ui.js, never by
   prefers-color-scheme. --near-white/--near-black are the theme's own soft
   off-white/off-black tones (already used inside .dark below) reused as the
   light page's ground/ink instead of harsh pure white/black, so neither mode
   sits at a stark extreme. Light-mode --text-muted/--text-faint/--accent
   contrast against --bg #F2F2F2 (relative luminance 0.888): muted #666666
   5.13:1, faint #808080 3.53:1 (sub-AA by design, matching dark mode's own
   ~4.0:1 faint tier — a deliberately de-emphasized metadata register, not
   body copy), accent (umber, unchanged) #8A5A44 5.17:1. Both exceed AA
   (4.5:1) except faint, which is intentionally the softer tier. */
:root{--white:#FFFFFF;--black:#0A0A0A;--near-white:#F2F2F2;--near-black:#0E0F10;--grey-050:#FAFAFA;--grey-200:#E0E0E0;--grey-600:#666666;--umber:#8A5A44;--umber-dark:#C6906F;
--bg:var(--near-white);--surface:var(--grey-050);--surface-inverse:var(--black);--ink:var(--near-black);--ink-inverse:var(--white);--text-body:var(--near-black);--text-muted:var(--grey-600);--text-faint:#808080;--line:var(--grey-200);--line-strong:var(--near-black);--accent:var(--umber);--accent-contrast:var(--white);
--font-sans:var(--gh-font-body,"Instrument Sans",system-ui,sans-serif);--font-heading:var(--gh-font-heading,"Instrument Sans",system-ui,sans-serif);--font-mono:"Spline Sans Mono",monospace;--radius:0px;--page-max:1200px;--measure-reading:680px}
/* Dark palette — same values as the previous default (now var() references
   instead of literals); only the trigger (class on <html>, opt-in via
   toggle) changed, not what they resolve to. */
.dark{color-scheme:dark;--bg:var(--near-black);--surface:#161718;--surface-inverse:var(--near-white);--ink:var(--near-white);--ink-inverse:var(--near-black);--text-body:var(--near-white);--text-muted:#9BA0A6;--text-faint:#6E7378;--line:#26282A;--line-strong:var(--near-white);--accent:var(--umber-dark);--accent-contrast:var(--near-black)}
/* base */
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text-body);font-family:var(--font-sans);font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}
a{color:var(--ink);transition:color 150ms}
a:hover{color:var(--accent)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
img{max-width:100%}
.only-dark{display:none}
.dark .only-light{display:none}
.dark .only-dark{display:inline-block}
/* mono label */
.w-label{font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-muted)}
.w-label--faint{color:var(--text-faint)}
/* byline */
.w-byline{font-family:var(--font-mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);border:1px solid var(--line);padding:3px 8px}
.w-byline.is-agent{color:var(--accent);border-color:var(--accent)}
/* buttons */
.w-btn{font-family:var(--font-sans);font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;border:1px solid var(--line-strong);background:transparent;color:var(--ink);padding:0 18px;height:40px;cursor:pointer;border-radius:0;transition:color 150ms,background 150ms,border-color 150ms}
.w-btn:hover{color:var(--accent);border-color:var(--accent)}
.w-btn--solid{background:var(--surface-inverse);color:var(--ink-inverse);border-color:var(--surface-inverse)}
.w-btn--solid:hover{background:var(--accent);border-color:var(--accent);color:var(--accent-contrast)}
.w-btn--accent{background:var(--accent);color:var(--accent-contrast);border-color:var(--accent)}
.w-btn--accent:hover{background:var(--ink);border-color:var(--ink);color:var(--ink-inverse)}
.w-btn:disabled{opacity:.4;pointer-events:none}
/* input */
.w-input{font-family:var(--font-sans);font-size:14px;color:var(--ink);background:var(--bg);border:2px solid var(--line);border-radius:0;height:40px;padding:0 12px;transition:border-color 150ms}
.w-input:focus{outline:none;border-color:var(--line-strong)}
.w-input[aria-invalid="true"]{border-color:var(--accent)}
/* header / footer */
.w-header{position:sticky;top:0;z-index:10;background:var(--bg);display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:16px 40px;border-bottom:1px solid var(--line)}
.w-header nav{display:flex;gap:24px;justify-self:center}
.w-header nav a{font-size:12px;font-weight:500;text-transform:uppercase;letter-spacing:.06em;text-decoration:none;white-space:nowrap}
.w-footer{display:flex;justify-content:space-between;padding:20px 40px;border-top:1px solid var(--line);font-family:var(--font-mono);font-size:11px;letter-spacing:.08em;color:var(--text-faint)}
/* essay index row */
.w-essay-row{display:grid;grid-template-columns:72px 1fr 300px auto;gap:24px;align-items:baseline;padding:28px 40px;border-bottom:1px solid var(--line);text-decoration:none;transition:background 150ms}
.w-essay-row:hover{background:var(--surface)}
.w-essay-row .num,.w-essay-row .date{font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;color:var(--text-faint)}
.w-essay-row .title{font-size:19px;font-weight:500;color:var(--ink);transition:color 150ms}
.w-essay-row:hover .title{color:var(--accent)}
.w-essay-row .dek{font-size:14px;line-height:1.5;color:var(--text-muted)}
/* reading view (post template) */
.w-article{max-width:var(--measure-reading);margin:0 auto;padding:96px 24px 88px}
.w-article h1{font-size:30px;font-weight:600;letter-spacing:-.02em;line-height:1.25;margin:0 0 24px;text-wrap:pretty}
.gh-content,.w-prose{font-size:19px;line-height:1.7}
.gh-content p,.w-prose p{margin:0 0 26px;text-wrap:pretty}
.gh-content h2,.w-prose h2{font-size:24px;font-weight:600;letter-spacing:-.02em;margin:48px 0 20px}
.gh-content a,.w-prose a{text-decoration:none;border-bottom:1px solid var(--line-strong)}
.gh-content blockquote{margin:0 0 26px;padding-left:20px;border-left:1px solid var(--line-strong)}
.gh-content pre{font-family:var(--font-mono);font-size:14px;line-height:1.6;background:var(--surface);border:1px solid var(--line);padding:20px;overflow-x:auto}
.gh-content code{font-family:var(--font-mono);font-size:.9em}
.gh-content figcaption{font-family:var(--font-mono);font-size:11px;letter-spacing:.08em;color:var(--text-faint);margin-top:10px}
.gh-content hr{border:0;border-top:1px solid var(--line);margin:48px 0}
/* tables (no prior rule — browser defaults were silently unstyled in either mode) */
.gh-content table{display:block;overflow-x:auto;width:100%;border-collapse:collapse;margin:0 0 26px;font-size:16px}
.gh-content table th,.gh-content table td{border:1px solid var(--line);padding:10px 14px;text-align:left}
.gh-content table th{background:var(--surface);font-weight:600;color:var(--text-body)}
/* newsletter cell (Portal form). The form wraps so Portal's status message
   (a third child alongside the input and button) drops to its own line
   instead of being squeezed into the same row — see #273's reconciliation. */
.w-newsletter{background:var(--surface);padding:40px;display:flex;flex-direction:column;gap:24px}
.w-newsletter form{display:flex;flex-wrap:wrap;gap:0}
.w-newsletter .w-input{flex:1}
.w-newsletter .w-form-status{flex-basis:100%}
@media (max-width:720px){.w-essay-row{grid-template-columns:56px 1fr;grid-auto-rows:auto}.w-essay-row .dek,.w-essay-row .date{grid-column:2}.w-header{padding:12px 20px}}

/* Header at narrow widths: the 1fr/auto/1fr grid above gives the logo and
   nav zero gap once nav's auto column pushes against them (logo ends up
   touching the first nav link), and the Subscribe button gets compressed —
   see #273's mobile-header fix. Below 600px the header stacks into three
   rows in source order (logo, then nav, then the toggle/Subscribe group)
   instead of using CSS `order` to reshuffle a single row — `order` only
   changes visual position, not DOM/tab order, so it would make keyboard
   focus jump between rows out of visual sequence. */
@media (max-width:600px){
.w-header{display:flex;flex-direction:column;align-items:flex-start;row-gap:10px;padding:12px 16px}
.w-header nav{flex-wrap:wrap;gap:10px 20px}
}

/* page scaffolding (Ghost templates) */
.w-logo{display:flex;align-items:center;text-decoration:none}
.w-header-right{display:flex;justify-content:flex-end;align-items:center;gap:18px}
.w-header-right .w-btn{height:32px;font-size:11px;display:inline-flex;align-items:center;justify-content:center;text-decoration:none}
.w-hero{display:grid;grid-template-columns:2fr 1fr;border-bottom:1px solid var(--line)}
.w-hero-main{padding:72px 40px 64px;border-right:1px solid var(--line)}
.w-hero-main h1{font-size:34px;font-weight:600;line-height:1.15;letter-spacing:-.02em;margin:0;max-width:560px;text-wrap:pretty}
.w-hero-side{padding:72px 40px 64px;display:flex;flex-direction:column;justify-content:flex-end;gap:16px}
.w-hero-side p{margin:0;color:var(--text-muted)}
.w-utility-band{display:grid;grid-template-columns:1fr 1fr 1fr}
.w-utility-cell{padding:40px;border-right:1px solid var(--line)}
.w-utility-cell p{margin:0 0 14px}
.w-utility-cell a{text-decoration:none;border-bottom:1px solid var(--line-strong)}
.w-newsletter-pitch{font-size:17px;line-height:1.4;margin:0}
.w-archive-head{display:flex;flex-direction:column;gap:14px;padding:56px 40px 48px;border-bottom:1px solid var(--line)}
.w-archive-head h1{font-size:34px;font-weight:600;letter-spacing:-.02em;margin:0}
.w-post-meta{display:flex;align-items:baseline;gap:16px;margin-bottom:32px;font-family:var(--font-mono);font-size:12px;letter-spacing:.08em;color:var(--text-faint)}
.w-post-meta .num{color:var(--ink)}
.w-post-meta .tag{margin-left:auto;text-decoration:none;color:var(--text-faint);border-bottom:1px solid var(--line);text-transform:uppercase}
.w-post-byline{display:flex;align-items:center;gap:12px;padding-bottom:40px;border-bottom:1px solid var(--line);margin-bottom:48px}
.w-post-byline .w-byline{text-decoration:none}
.w-post-byline .review-note{font-size:13px;color:var(--text-faint)}
.w-prevnext{border-top:1px solid var(--line);display:flex}
.w-prevnext a{flex:1;display:flex;flex-direction:column;gap:8px;padding:40px;text-decoration:none}
.w-prevnext a+a{border-left:1px solid var(--line)}
.w-prevnext .title{font-size:17px;font-weight:500;color:var(--ink)}
@media (max-width:720px){.w-hero,.w-utility-band{grid-template-columns:1fr}.w-hero-main{border-right:0;border-bottom:1px solid var(--line)}}

/* Koenig card widths. Ghost emits these on wide and full-bleed cards; without
   them the editor's layout choice silently does nothing. Square corners and
   hairlines are kept — the width changes, the design language does not. */
.kg-width-wide{max-width:min(100%,960px);margin-left:auto;margin-right:auto}
.kg-width-full{max-width:100%;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);width:100vw}
.kg-width-full img,.kg-width-wide img{width:100%;height:auto;border-radius:var(--radius)}
figure.kg-card{margin:2rem 0}
figcaption{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);text-align:center;margin-top:.6rem}

/* Custom fonts. Ghost injects --gh-font-heading / --gh-font-body through
   {{ghost_head}} when an admin picks fonts. Consuming them with the Swiss
   Umber faces as fallback means the setting takes effect instead of being
   silently overridden — and the theme still looks like itself if unset. */
h1,h2,h3,h4,.w-hero h1{font-family:var(--font-heading)}

/* Form feedback. Portal's vanilla-JS handler adds/removes the classes
   loading/success/error directly on the <form data-members-form> element
   (confirmed against the actual portal@~2.71 bundle Ghost 6.69 serves —
   it only READS data-members-form to select which forms to wire up, it
   never writes a state into the attribute's value); the reader otherwise
   clicks GO and sees nothing happen. role=status announces the change
   without stealing focus. */
.w-form-status{margin:.5rem 0 0;font-family:var(--font-mono);font-size:11px;color:var(--text-faint)}
.w-form-status span{display:none}
form.loading .on-loading,
form.success .on-success,
form.error .on-error{display:inline}
form.success .on-success{color:var(--accent)}
form.error .on-error{color:var(--accent)}
/* Theme toggle: an icon button in the label register, not a text link. */
.w-theme-toggle{display:inline-flex;align-items:center;justify-content:center;background:none;border:0;padding:8px;margin:-8px;cursor:pointer;color:var(--text-faint);transition:color 150ms}
.w-theme-toggle:hover{color:var(--accent)}
.w-theme-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
