/* ════════════════════════════════════════════════════════════════════════════
   כרך — KEREKH · platform design system
   Implements DESIGN-SPEC.md §2 (tokens) + §3 (component vocabulary).
   Fonts: SIL OFL 1.1 — Frank Ruhl Libre, Heebo, Miriam Libre. Self-hosted,
   subset by unicode-range, zero external requests at runtime.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── faces ───────────────────────────────────────────────────────────────── */
@font-face{
  font-family:"Frank Ruhl Libre"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url(../fonts/FrankRuhlLibre-he.woff2) format("woff2");
  unicode-range:U+0307-0308,U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F;
}
@font-face{
  font-family:"Frank Ruhl Libre"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url(../fonts/FrankRuhlLibre-lat.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Heebo"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url(../fonts/Heebo-he.woff2) format("woff2");
  unicode-range:U+0307-0308,U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F;
}
@font-face{
  font-family:"Heebo"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url(../fonts/Heebo-lat.woff2) format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/* Miriam Libre ships HEBREW ONLY — the wordmark is כרך alone (spec §1c/§2f:
   never "Kerekh AI", never a Latin lockup), and dropping the 15KB Latin file
   is what keeps all faces inside the ≤120KB budget of §2f delivery rule 2. */
@font-face{
  font-family:"Miriam Libre"; font-style:normal; font-weight:700; font-display:swap;
  src:url(../fonts/MiriamLibre700-he.woff2) format("woff2");
  unicode-range:U+0307-0308,U+0590-05FF,U+200C-2010,U+20AA,U+25CC,U+FB1D-FB4F;
}

/* ── tokens · light (default) ────────────────────────────────────────────── */
/* SKIN 2 — "the bindery" (2026-08-01). The room is no longer pale bone: it is
   a saturated tobacco board, the colour of the chipboard a book is bound over.
   The reader's warm tan (#EBE1CD, verbatim) now sits ON that board as a LIGHTER
   sheet — so the §1a law ("paper appears exactly where a book exists") reads at
   1.36:1 of lift instead of the old bone-on-bone whisper. Every value below is
   computed, not eyeballed; the ratios live in DESIGN-SPEC §2d's successor table
   and in the commit message. */
:root{
  --field:      #D5C19C;   /* the board — tobacco/kraft, ink 10.60:1          */
  --field-2:    #E2D3B4;   /* raised: header, condensed bar                   */
  --field-3:    #C2AC84;   /* recessed: footer colophon, wells                */

  --paper:      #EBE1CD;   /* the reader's paper, verbatim — a LIT sheet here */
  --paper-2:    #F3ECDD;
  --paper-edge: #C3AF8B;

  --ink:        #16120C;   /* 10.60:1 on --field                              */
  --ink-soft:   #463A24;   /*  6.31:1 on --field                              */
  --muted:      #57492F;   /*  4.98:1 on --field — AA at any size             */

  /* ink ON a paper object — was hard-coded per-rule in pages.css, now tokens
     so a re-skin cannot leave stale greys behind on the tan. */
  --ink-paper:       #15130F;  /* 14.30:1 on --paper                          */
  --ink-paper-soft:  #3E3524;  /*  9.30:1 on --paper                          */
  --ink-paper-muted: #5C4E33;  /*  6.24:1 on --paper                          */
  --ink-paper-faint: #6A5B3D;  /*  5.09:1 on --paper                          */

  --line:       #B49A6E;
  --line-soft:  #C6B08A;

  --proof:      #7E2718;   /* 5.45:1 on field · deeper, richer oxblood        */
  /* --proof lightens in dark mode, but paper objects DON'T invert (§2c law 3),
     so a --proof stamp printed on a paper object needs its own token or it
     becomes a 2:1 smear on tan in dark mode. This was a live bug in skin 1. */
  --proof-on-paper: #7E2718;  /* 7.39:1 on --paper · 6.78:1 on dark --paper   */

  --display:"Miriam Libre","Frank Ruhl Libre","Arial Hebrew","Noto Sans Hebrew",ui-sans-serif,-apple-system,sans-serif;
  --serif:"Frank Ruhl Libre","Noto Serif Hebrew","Arial Hebrew","Frank Ruehl CLM",Georgia,serif;
  --sans:"Heebo","Assistant","Arial Hebrew","Noto Sans Hebrew",ui-sans-serif,-apple-system,Arial,sans-serif;

  --t-micro:.6875rem;
  --t-caption:.8125rem;
  --t-ui:.875rem;
  --t-body:1.0625rem;
  --t-lead:1.1875rem;
  --t-h3:1.3125rem;
  --t-h2:clamp(1.5rem,4.5vw,2rem);
  --t-h1:clamp(2rem,7vw,3.25rem);
  --t-hero:clamp(2.6rem,10.5vw,5.5rem);

  --s1:.25rem; --s2:.5rem; --s3:.75rem; --s4:1.25rem;
  --s5:2rem;   --s6:3.25rem; --s7:5.25rem; --s8:8.5rem;

  --measure:34em;
  --measure-lead:26em;
  --frame:68rem;

  --dur-fast:140ms;
  --dur:240ms;
  --dur-turn:380ms;
  --ease:cubic-bezier(.2,.7,.2,1);

  --lift:0 1px 0 var(--paper-edge), 0 16px 28px -20px rgba(28,18,6,.55);
  /* the same sheet, picked up — hover only. Not a second shadow style: it is
     --lift with the sheet lifted off the board a few millimetres. */
  --lift-2:0 1px 0 var(--paper-edge), 0 26px 44px -24px rgba(28,18,6,.62);
  --radius:0;
}

/* ── tokens · dark — the press floor at night ────────────────────────────── */
/* The board drops to burnt espresso; the sheets stay lit (§2c law 3). */
@media (prefers-color-scheme:dark){ :root[data-theme="auto"]{
  --field:#14100A; --field-2:#1F1911; --field-3:#0C0906;
  --ink:#F2E8D4; --ink-soft:#CBBB9B; --muted:#9C8C6D;
  --line:#3B3225; --line-soft:#2A2318;
  --proof:#E27A55; --proof-on-paper:#7E2718;
  --paper:#E4D8BC; --paper-2:#EFE5CE; --paper-edge:#B9A780;
  --lift:0 1px 0 rgba(0,0,0,.5), 0 18px 34px -22px rgba(0,0,0,.95);
  --lift-2:0 1px 0 rgba(0,0,0,.5), 0 28px 48px -26px rgba(0,0,0,1);
}}
:root[data-theme="dark"]{
  --field:#14100A; --field-2:#1F1911; --field-3:#0C0906;
  --ink:#F2E8D4; --ink-soft:#CBBB9B; --muted:#9C8C6D;
  --line:#3B3225; --line-soft:#2A2318;
  --proof:#E27A55; --proof-on-paper:#7E2718;
  --paper:#E4D8BC; --paper-2:#EFE5CE; --paper-edge:#B9A780;
  --lift:0 1px 0 rgba(0,0,0,.5), 0 18px 34px -22px rgba(0,0,0,.95);
  --lift-2:0 1px 0 rgba(0,0,0,.5), 0 28px 48px -26px rgba(0,0,0,1);
}

/* ── reset & ground ──────────────────────────────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box }
html{ -webkit-text-size-adjust:100% }
body{
  margin:0; background:var(--field); color:var(--ink);
  font-family:var(--serif); font-size:var(--t-body); line-height:1.75;
  font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,p,ul,ol,figure,blockquote{ margin:0 }
ul,ol{ padding-inline-start:1.35em }
img{ max-width:100% }
button,input,textarea,select{ font:inherit; color:inherit }
a{ color:inherit; text-decoration:none }
a.link{ border-block-end:1px solid var(--line); transition:border-color var(--dur-fast) var(--ease) }
a.link:hover{ border-block-end-color:var(--ink) }

:focus-visible{ outline:1.5px solid var(--ink); outline-offset:2px }

::selection{ background:var(--paper-edge); color:var(--ink-paper) }

/* numerals & bidi — §2e.2, §2e.3 */
.num,time,.folio,.meta{ font-variant-numeric:tabular-nums }
.ltr{ direction:ltr; unicode-bidi:isolate; display:inline-block }

/* ── page frame — the trim edge of a press sheet (§4 global chrome) ───────── */
.frame{
  max-width:var(--frame); margin-inline:auto;
  padding-inline:clamp(1.15rem,5vw,2.5rem);
  position:relative;
}
/* The trim edge is painted as a background, NOT as ::before/::after — a frame
   may also be a .trim block, and the trim marks own those two pseudo-elements.
   Both edges are symmetric, so there is no direction to get wrong. */
@media (min-width:900px){
  .frame{
    background-image:
      linear-gradient(var(--line-soft),var(--line-soft)),
      linear-gradient(var(--line-soft),var(--line-soft));
    background-size:1px 100%, 1px 100%;
    background-position:left top, right top;
    background-repeat:no-repeat;
  }
}

/* ── header ──────────────────────────────────────────────────────────────── */
.site-head{ border-block-end:1px solid var(--line-soft); background:var(--field) }
.site-head .frame{ display:flex; align-items:center; gap:var(--s4);
  min-height:64px; justify-content:space-between }
.wordmark{ font-family:var(--display); font-weight:700; font-size:1.05rem;
  letter-spacing:-.01em; line-height:1; display:inline-block }
.wordmark .rule{ display:block; width:2.2rem; height:1.5px; background:var(--ink); margin-block-start:.4rem }
.site-nav{ display:flex; gap:clamp(.8rem,3vw,1.4rem); font-family:var(--sans);
  font-size:var(--t-micro); letter-spacing:.06em; color:var(--ink-soft); font-weight:500 }
/* 44px tap target on a phone without growing the 64px header (§2d targets) */
.site-nav a{ padding-block:.9rem; display:inline-flex; align-items:center;
  min-height:44px; position:relative }
.site-nav a:hover{ color:var(--ink) }
/* hover EXTENDS a rule — the one hover idiom the spec sanctions (§6). It is a
   scaleX on a hairline, so nothing reflows. transform-origin has no logical
   keyword, hence the explicit dir pair rather than a physical default. */
.site-nav a::after{
  content:""; position:absolute; inset-inline:0; inset-block-end:.55rem; height:1px;
  background:var(--ink); transform:scaleX(0); transform-origin:100% 50%;
  transition:transform var(--dur) var(--ease);
}
[dir="ltr"] .site-nav a::after{ transform-origin:0 50% }
.site-nav a:hover::after{ transform:scaleX(1) }
.site-nav a[aria-current="page"]{ color:var(--ink); border-block-end:1.5px solid var(--ink) }
.site-nav a[aria-current="page"]::after{ display:none }

/* condensed bar past 80vh */
.condensed{
  position:fixed; inset-block-start:0; inset-inline:0; height:44px; z-index:40;
  background:var(--field-2); border-block-end:1px solid var(--line);
  display:flex; align-items:center; justify-content:space-between;
  padding-inline:clamp(1.15rem,5vw,2.5rem);
  transform:translateY(-100%); transition:transform var(--dur) var(--ease);
}
.condensed.on{ transform:none }
.condensed .wordmark{ font-size:.95rem }
.condensed .wordmark .rule{ display:none }
/* the bar is exactly 44px; the button fills it rather than overflowing it */
.condensed .btn{ height:44px; min-height:44px; padding-block:0 }

/* ── footer colophon ─────────────────────────────────────────────────────── */
.site-foot{ border-block-start:1px solid var(--line); background:var(--field-3);
  margin-block-start:var(--s8) }
/* auto-fit rather than a fixed 3, because the colophon carries three columns on
   some pages and four on the landing — one rule, no per-page column maths. */
.site-foot .frame{ display:grid; gap:var(--s5); padding-block:var(--s6);
  grid-template-columns:repeat(auto-fit,minmax(13rem,1fr)) }
@media (max-width:700px){ .site-foot .frame{ grid-template-columns:1fr } }
.site-foot p{ font-size:var(--t-caption); color:var(--ink-soft); line-height:1.7 }
.site-foot .eyebrow{ margin-block-end:var(--s2) }
.site-foot a{ border-block-end:1px solid transparent; transition:border-color var(--dur-fast) var(--ease) }
.site-foot a:hover{ border-block-end-color:var(--ink-soft) }

/* colophon nav — a short list of rows, not a sitemap grid */
.foot-nav{ list-style:none; margin:0; padding:0 }
.foot-nav li + li{ margin-block-start:var(--s1) }
.foot-nav a{ display:inline-flex; align-items:center; min-height:32px;
  font-size:var(--t-caption); color:var(--ink-soft) }
.foot-nav a:hover{ color:var(--ink) }

/* the closing rule — the wordmark's own mark, and the locked tagline */
.foot-bottom{ border-block-start:1px solid var(--line); }
.foot-bottom .frame{ display:flex; align-items:center; gap:var(--s4);
  flex-wrap:wrap; padding-block:var(--s4) }
.foot-bottom .wordmark{ font-size:.95rem }
.foot-bottom .wordmark .rule{ margin-block-start:.3rem }
.foot-bottom .tag{ font-family:var(--serif); font-size:var(--t-caption);
  color:var(--ink-soft) }
/* --ink-soft, not --muted: at --t-micro this line was 3.97:1 on the board in
   light mode. It is small permanent type, so it takes the 4.5:1 rule. */
.foot-bottom .foot-end{ margin-inline-start:auto; font-family:var(--sans);
  font-size:var(--t-micro); letter-spacing:.06em; color:var(--ink-soft) }

/* ════════════════════════════════════════════════════════════════════════════
   COMPONENT VOCABULARY — §3. Eight things.
   ════════════════════════════════════════════════════════════════════════════ */

/* 1 · RULE */
.rule{ height:1px; background:var(--line-soft); border:0; margin:0 }
.rule-ink{ height:1.5px; width:2.6rem; background:var(--ink); border:0; margin:0 }

/* 2 · EYEBROW — no uppercase (§2e.4) */
.eyebrow{ font-family:var(--sans); font-weight:500; font-size:var(--t-micro);
  letter-spacing:.08em; color:var(--muted); line-height:1.4 }

/* 3 · FOLIO */
.folio{ font-family:var(--sans); font-size:var(--t-micro); color:var(--muted);
  font-variant-numeric:tabular-nums; line-height:1.4 }

/* 4 · PAPER OBJECT + 5 · TRIM MARKS */
.paper{
  position:relative; background:var(--paper); color:var(--ink-paper);
  padding:clamp(1.15rem,4vw,1.9rem); box-shadow:var(--lift); border:0;
  transition:box-shadow var(--dur) var(--ease);
}
/* a sheet you can pick up. Shadow only — no translate, no scale, no radius. */
.shelf > li:hover .paper{ box-shadow:var(--lift-2) }
.paper .eyebrow,.paper .folio{ color:var(--ink-paper-muted) }
.trim::before,.trim::after,
.trim > .trim-b::before,.trim > .trim-b::after{
  content:""; position:absolute; width:10px; height:10px; pointer-events:none;
  border-color:var(--line); border-style:solid; border-width:0;
}
.trim::before{ inset-block-start:5px; inset-inline-start:5px; border-block-start-width:1px; border-inline-start-width:1px }
.trim::after{ inset-block-start:5px; inset-inline-end:5px; border-block-start-width:1px; border-inline-end-width:1px }
.trim > .trim-b::before{ inset-block-end:5px; inset-inline-start:5px; border-block-end-width:1px; border-inline-start-width:1px }
.trim > .trim-b::after{ inset-block-end:5px; inset-inline-end:5px; border-block-end-width:1px; border-inline-end-width:1px }
.paper.trim::before,.paper.trim::after,
.paper.trim > .trim-b::before,.paper.trim > .trim-b::after{ border-color:var(--paper-edge) }

/* 6 · RULED INPUT — text on a hairline. No box, no fill, no radius. */
.ruled{
  display:block; width:100%; background:transparent; border:0;
  border-block-end:1px solid var(--line-soft);
  font-family:var(--serif); font-size:var(--t-lead); color:inherit;
  caret-color:var(--ink); padding:.85rem .1rem; min-height:48px;
  transition:border-color var(--dur-fast) var(--ease);
  resize:none; line-height:1.6;
}
.ruled::placeholder{ color:var(--muted); opacity:1 }
.ruled:hover{ border-block-end-color:var(--line) }
.ruled:focus{ border-block-end-width:1.5px; border-block-end-color:var(--ink); outline:1.5px solid var(--ink); outline-offset:2px }
.ruled.filled{ border-block-end-color:var(--ink) }

/* 7 · BUTTON — lifted from the reader's .cta */
.btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-height:44px; padding:.85rem 1.5rem; border:0; border-radius:0;
  font-family:var(--sans); font-size:.75rem; letter-spacing:.02em; font-weight:500;
  background:var(--ink); color:var(--field); cursor:pointer;
  transition:opacity var(--dur-fast) var(--ease);
}
.btn:hover{ opacity:.86 }
.btn:active{ opacity:.7 }
.btn-2{
  background:transparent; color:var(--ink);
  box-shadow:inset 0 0 0 1px var(--line);
}
.btn-2:hover{ box-shadow:inset 0 0 0 1px var(--ink); opacity:1 }
.btn[disabled]{ opacity:.4; cursor:default }
.paper .btn{ background:var(--ink-paper); color:var(--paper) }
.paper .btn-2{ background:transparent; color:var(--ink-paper); box-shadow:inset 0 0 0 1px var(--paper-edge) }

/* 8 · REGISTER MARK — a square, never a circle */
.reg{ display:inline-block; width:7px; height:7px; box-shadow:inset 0 0 0 1.5px var(--proof);
  vertical-align:baseline; flex:0 0 auto }
.paper .reg{ box-shadow:inset 0 0 0 1.5px var(--proof-on-paper) }
.reg.live{ animation:reg-pulse 3s var(--ease) infinite }
@keyframes reg-pulse{ 0%,100%{ opacity:1 } 50%{ opacity:.55 } }

/* ── prose blocks ────────────────────────────────────────────────────────── */
.prose{ max-width:var(--measure) }
.prose p + p{ margin-block-start:var(--s4) }
.lead{ font-size:var(--t-lead); line-height:1.7 }
.h1{ font-family:var(--display); font-weight:700; font-size:var(--t-h1);
  line-height:1.08; letter-spacing:-.015em }
.h2{ font-family:var(--display); font-weight:700; font-size:var(--t-h2);
  line-height:1.15; letter-spacing:-.015em }
.h3{ font-family:var(--sans); font-weight:500; font-size:var(--t-h3); line-height:1.3 }
.muted{ color:var(--muted) }
.soft{ color:var(--ink-soft) }

/* the reader's rule-bounded statement (.cover .promise) */
.statement{
  border-inline-start:1.5px solid var(--ink);
  padding-inline-start:1.15rem;
  font-size:var(--t-lead); line-height:1.7; max-width:var(--measure-lead);
}

section.band{ padding-block:var(--s7) }
section.band > * + *{ margin-block-start:var(--s4) }
.stack-5 > * + *{ margin-block-start:var(--s5) }
.stack-4 > * + *{ margin-block-start:var(--s4) }
.stack-3 > * + *{ margin-block-start:var(--s3) }

/* ── ruled rows (source wall / ticket / toc parity) ──────────────────────── */
.rows{ list-style:none; margin:0; padding:0 }
.rows > li{
  display:flex; gap:var(--s3); align-items:baseline;
  padding-block:var(--s3); border-block-end:1px solid var(--line-soft);
  transition:padding var(--dur-fast) var(--ease);
}
.rows > li:hover{ padding-inline-start:.5rem }
.rows .folio{ flex:0 0 2.2em }

/* ── motion policy ───────────────────────────────────────────────────────── */
.fade-in{ animation:fade var(--dur) var(--ease) both }
@keyframes fade{ from{ opacity:0 } to{ opacity:1 } }

/* Scroll reveal — OPACITY ONLY. §1e/§6 refuse translate-in reveals by name:
   they are the clearest tell of a generated site. The hidden state is gated on
   `html.js`, which is set as the FIRST STATEMENT OF kerekh.js — never inline in
   <head>, because an inline setter asserts "js is on" while the file that does
   the revealing may be blocked, and then the page below the hero never appears.
   kerekh.js also arms a 1500ms watchdog that drops the class if its reveal
   wiring never completes. The whole rule is off under reduced motion. */
@media (prefers-reduced-motion:no-preference){
  html.js [data-reveal]{ opacity:0 }
  html.js [data-reveal].fade-in{ opacity:1 }
}

@media (prefers-reduced-motion:reduce){
  *{ transition-duration:0ms !important; animation:none !important }
  .reg.live{ opacity:1 }
  [data-reveal]{ opacity:1 !important }
}

/* skip link */
.skip{ position:absolute; inset-block-start:-100px; inset-inline-start:0; background:var(--ink);
  color:var(--field); padding:.6rem 1rem; z-index:99 }
.skip:focus{ inset-block-start:0 }
