/* ============================================================================
   SLEUKRITH  ·  សាស្ត្រាស្លឹករឹត
   Khmer typography system v1.0

   Design source: the palm-leaf manuscript itself — incised lines darkened
   with lampblack on a dried leaf that is olive-grey, not cream. Text was cut
   in continuous rows with no word spacing, which is exactly the problem this
   stylesheet exists to solve. Rubric red and brass are the only accents,
   taken from lacquered manuscript edges.

   Values marked [S] are overridable from admin Settings and are injected as
   custom properties on :root at render time.
   ========================================================================== */

/* ── FONTS ─────────────────────────────────────────────────────────────────
   Self-hosted. Do NOT load from Google's CDN — Cambodian mobile networks
   resolve fonts.gstatic.com slowly and Khmer files are large.
   Subset to Khmer + Latin-basic, WOFF2 only, and preload the body face.

   Noto Serif Khmer is the recommendation for article text. It is the only
   widely available Khmer serif with correctly positioned coeng (subscript)
   consonants across weights, and it has a variable axis so bold costs no
   extra download. Kantumruy Pro handles the interface: a genuinely modern
   Khmer sans, not a Latin face with Khmer bolted on.
   Moul appears exactly once, in the wordmark. It is a ceremonial face —
   at body size it is unreadable, and using it twice cheapens it.
   ------------------------------------------------------------------------ */

@font-face {
  font-family: 'Noto Serif Khmer';
  src: url('/fonts/NotoSerifKhmer-Variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+1780-17FF, U+19E0-19FF, U+200B;
}
@font-face {
  font-family: 'Kantumruy Pro';
  src: url('/fonts/KantumruyPro-Variable.woff2') format('woff2-variations');
  font-weight: 100 700;
  font-display: swap;
  unicode-range: U+1780-17FF, U+200B;
}
@font-face {
  font-family: 'Moul';
  src: url('/fonts/Moul-Regular.woff2') format('woff2');
  font-weight: 400;
  font-display: block;          /* wordmark: no flash of fallback */
  unicode-range: U+1780-17FF;
}
@font-face {
  font-family: 'Source Serif 4';
  src: url('/fonts/SourceSerif4-Variable.woff2') format('woff2-variations');
  font-weight: 200 900;
  font-display: swap;
  unicode-range: U+0000-024F, U+2000-206F;
}
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-Variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0000-024F, U+2000-206F;
}

/* ── TOKENS ─────────────────────────────────────────────────────────────── */

:root {
  /* palette — leaf and lampblack */
  --ink:        #191712;   /* [S] soot, never pure black                    */
  --ink-soft:   #4A453B;
  --ink-faint:  #857E70;
  --leaf:       #F7F5EE;   /* [S] page — warm-neutral, slightly green       */
  --leaf-sunk:  #EFEBE0;   /* recessed panels                               */
  --rule:       #D8D3C2;   /* [S] hairline, the ruled guide line            */
  --rubric:     #8C2318;   /* [S] manuscript red — links, errors, emphasis  */
  --brass:      #A8842C;   /* [S] paid / premium marker only                */

  /* type families */
  --f-km-body:  'Noto Serif Khmer', 'Khmer OS Battambang', serif;      /* [S] */
  --f-km-ui:    'Kantumruy Pro', 'Noto Sans Khmer', sans-serif;        /* [S] */
  --f-km-disp:  'Moul', 'Noto Serif Khmer', serif;                     /* [S] */
  --f-la-body:  'Source Serif 4', Georgia, serif;                      /* [S] */
  --f-la-ui:    'Inter', system-ui, -apple-system, sans-serif;         /* [S] */

  /* metrics
     Khmer sits optically smaller than Latin at the same px, and its
     vowel signs stack above while coeng stack below. Both facts drive
     the two numbers below — they are the whole system. */
  --size-body:    18px;    /* [S] Latin body                                */
  --km-scale:     1.10;    /* [S] Khmer multiplier: 1.06–1.14               */
  --lh-latin:     1.65;    /* [S]                                            */
  --lh-khmer:     2.00;    /* [S] below ~1.85 the subscripts collide        */
  --measure-km:   34em;    /* [S] Khmer line length                          */
  --measure-la:   38em;

  --space:        1.45em;  /* paragraph rhythm                               */
}

@media (prefers-color-scheme: dark) {
  :root[data-theme='auto'], :root[data-theme='dark'] {
    --ink:       #EDEAE0;
    --ink-soft:  #B3ADA0;
    --ink-faint: #7E786C;
    --leaf:      #14130F;
    --leaf-sunk: #1D1B16;
    --rule:      #33302A;
    --rubric:    #D4695B;   /* lifted for contrast on dark                   */
    --brass:     #C9A448;
  }
}

/* ── BASE ──────────────────────────────────────────────────────────────── */

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--leaf);
  color: var(--ink);
  font-family: var(--f-la-ui), var(--f-km-ui);
  font-size: var(--size-body);
  line-height: var(--lh-latin);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Language switching is done with the lang attribute, not a class.
   Set lang="km" on <html> for the interface and on the article element
   for content — they are independent, which is the whole point of a
   Khmer-content / bilingual-interface platform. */

:lang(km) {
  font-family: var(--f-km-ui), var(--f-la-ui);
  line-height: var(--lh-khmer);
}

/* ── THE FOUR KHMER RULES ──────────────────────────────────────────────────
   These four exist because breaking any one of them is what makes most
   Khmer websites unpleasant to read. They are not stylistic preferences.
   ------------------------------------------------------------------------ */

:lang(km) {
  /* 1 — never track Khmer. Letter-spacing detaches vowel signs from their
         base consonant and the word visually falls apart. */
  letter-spacing: 0 !important;

  /* 2 — never justify. Khmer has no inter-word spaces, so the browser
         stretches inside clusters and rivers open up everywhere. */
  text-align: start;

  /* 3 — break only at ZWSP (U+200B). `word-break: break-all` will split a
         consonant from its subscript and render literal garbage. */
  word-break: normal;
  overflow-wrap: normal;
  line-break: strict;

  /* 4 — no faux styling. Khmer has no true italic, and synthesised bold
         thickens the coeng into a blob. Load real weights instead. */
  font-synthesis: none;
  font-style: normal;
}

:lang(km) em,
:lang(km) i {
  font-style: normal;
  color: var(--rubric);        /* emphasis by rubrication, as in manuscripts */
}

:lang(km) strong,
:lang(km) b { font-weight: 700; }

/* ── READING SURFACE ───────────────────────────────────────────────────── */

.article {
  max-width: var(--measure-la);
  margin-inline: auto;
  padding-inline: 1.5rem;
}

.article:lang(km) {
  max-width: var(--measure-km);
  font-family: var(--f-km-body), var(--f-la-body);
  font-size: calc(var(--size-body) * var(--km-scale));
  line-height: var(--lh-khmer);
}

.article p {
  margin: 0 0 var(--space);
  hanging-punctuation: first;
}

.article:lang(km) p { margin-bottom: calc(var(--space) * 1.05); }

/* Khmer headings need tighter leading than body — the same 2.0 that keeps
   body text legible makes a two-line headline look unbound. */
.article h2,
.article h3 {
  font-family: var(--f-la-body);
  font-weight: 600;
  margin: 2.2em 0 0.7em;
  line-height: 1.3;
}
.article h2:lang(km),
.article h3:lang(km) {
  font-family: var(--f-km-body);
  line-height: 1.55;
  font-weight: 700;
}
.article h2 { font-size: 1.45em; }
.article h3 { font-size: 1.18em; }

.article a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--rubric);
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}
.article a:hover { color: var(--rubric); }

/* Khmer underlines collide with subscript consonants. Offset further and
   thin the line, or the descenders sit on top of it. */
.article:lang(km) a {
  text-underline-offset: 0.42em;
  text-decoration-thickness: 1px;
}

.article blockquote {
  margin: 2em 0;
  padding-inline-start: 1.4em;
  border-inline-start: 2px solid var(--rubric);
  color: var(--ink-soft);
}

.article img,
.article figure { margin: 2.4em 0; max-width: 100%; height: auto; }

.article figcaption {
  font-family: var(--f-la-ui);
  font-size: 0.82em;
  line-height: 1.5;
  color: var(--ink-faint);
  margin-top: 0.7em;
}
.article figcaption:lang(km) {
  font-family: var(--f-km-ui);
  line-height: 1.8;
}

/* ── THE RULED LINE ────────────────────────────────────────────────────────
   Signature element. A sastra leaf is scored with a guide line and pierced
   with two binding holes. The section divider reproduces that: a hairline
   rule interrupted by two small circles. It is the only ornament on the
   page, and it carries meaning rather than decoration.
   ------------------------------------------------------------------------ */

.leaf-rule {
  border: 0;
  height: 1px;
  background: var(--rule);
  margin: 3.4em auto;
  max-width: var(--measure-km);
  position: relative;
  overflow: visible;
}
.leaf-rule::before,
.leaf-rule::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--leaf);
  border: 1px solid var(--rule);
  transform: translateY(-50%);
}
.leaf-rule::before { left: 32%; }
.leaf-rule::after  { left: 68%; }

/* ── WORDMARK ──────────────────────────────────────────────────────────── */

.wordmark {
  font-family: var(--f-km-disp);
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--ink);
}

/* ── UTILITY TYPE ──────────────────────────────────────────────────────── */

.meta {
  font-family: var(--f-la-ui);
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.meta:lang(km) {
  font-family: var(--f-km-ui);
  font-size: 0.86rem;
  letter-spacing: 0;          /* rule 1 applies to labels too */
  text-transform: none;       /* Khmer has no case             */
  line-height: 1.7;
}

.paid-mark {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--f-la-ui);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brass);
  border: 1px solid currentColor;
  border-radius: 2px;
  padding: 0.15em 0.5em;
}

/* Khmer numerals for dates — ០១២៣៤៥៦៧៨៩ — set from Settings. */
.khmer-numerals { font-feature-settings: 'lnum' 0; }

/* ── EDITOR ────────────────────────────────────────────────────────────────
   The composing surface must match the published surface exactly, or the
   writer is editing a document they have never seen.
   ------------------------------------------------------------------------ */

.editor[contenteditable] {
  font-family: var(--f-km-body), var(--f-la-body);
  font-size: calc(var(--size-body) * var(--km-scale));
  line-height: var(--lh-khmer);
  max-width: var(--measure-km);
  margin-inline: auto;
  outline: none;
  caret-color: var(--rubric);
}
.editor[contenteditable]:empty::before {
  content: attr(data-placeholder);
  color: var(--ink-faint);
  pointer-events: none;
}

/* Toggle in the editor toolbar: reveals where the ZWSP word breaks fall,
   so the writer can fix bad segmentation before publishing. */
.show-breaks .editor { --break-dot: var(--ink-faint); }
.show-breaks .editor::highlight(zwsp) { background: var(--leaf-sunk); }

/* ── PAYWALL ───────────────────────────────────────────────────────────── */

.paywall-fade {
  position: relative;
  max-height: 22em;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
}

/* ── RESPONSIVE ────────────────────────────────────────────────────────────
   Khmer at 16px on a phone is genuinely hard to read; hold the size and
   give up the margins instead. */

@media (max-width: 640px) {
  :root { --size-body: 17px; --km-scale: 1.14; --lh-khmer: 1.95; }
  .article { padding-inline: 1.15rem; }
}

@media print {
  :root { --leaf: #fff; --ink: #000; }
  .leaf-rule, nav, .paywall-fade { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ── FOCUS ─────────────────────────────────────────────────────────────── */

:focus-visible {
  outline: 2px solid var(--rubric);
  outline-offset: 3px;
  border-radius: 2px;
}
