@charset "utf-8";
/* ═══════════════════════════════════════════════════════════════════════════
   HISTORY ATLAS — reading system + card engine
   Values in the token block are fixed by the build brief §9. Every one of them
   is a deliberate legibility choice; change them there, not here.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── self-hosted faces: the CDN cannot be reached in airplane mode ────────── */
/* latin-ext */
@font-face{font-family:'Fraunces';font-style:normal;font-weight:400 900;font-display:swap;
  src:url(fonts/fraunces-latin-ext-400-900.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:'Fraunces';font-style:normal;font-weight:400 900;font-display:swap;
  src:url(fonts/fraunces-latin-400-900.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}
/* latin-ext */
@font-face{font-family:'Literata';font-style:normal;font-weight:300 600;font-display:swap;
  src:url(fonts/literata-latin-ext-300-600.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:'Literata';font-style:normal;font-weight:300 600;font-display:swap;
  src:url(fonts/literata-latin-300-600.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}
/* greek */
@font-face{font-family:'Literata';font-style:normal;font-weight:300 600;font-display:swap;
  src:url(fonts/literata-greek-300-600.woff2) format('woff2');
  unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}
/* latin-ext */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/ibm-plex-mono-latin-ext-400.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/ibm-plex-mono-latin-400.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}
/* latin-ext */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url(fonts/ibm-plex-mono-latin-ext-500.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url(fonts/ibm-plex-mono-latin-500.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}
/* latin-ext */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;
  src:url(fonts/ibm-plex-mono-latin-ext-600.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;
  src:url(fonts/ibm-plex-mono-latin-600.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}

/* ── tokens (§9) ──────────────────────────────────────────────────────────── */
:root{
  --ground:#E9EAE3; --card:#F3F4EE; --sheet:#F7F8F3;
  --ink:#22261F;              /* softened from #1A1D19 — pure near-black on warm
                                 paper haloes on OLED at night */
  --ink-2:#565D53; --ink-3:#7C8373;
  --rule:#C7CABC; --hair:#D6D8CC;
  --oxide:#7A3B1F; --verdigris:#2E6B5E; --slate:#4A5D6B; --gold:#8C6F1E;
  --scrim:rgba(10,12,10,.42);

  --p1:#8C7A55; --p2:#7A3B1F; --p3:#4A5D6B; --p4:#2E6B5E; --p5:#3A3F44;
  --part:var(--p1);           /* overwritten per lesson from the day's Part */

  /* Diagram fills. Deliberately NOT lightened in dark mode: lesson SVGs put
     --band-ink text on these, and that pairing has to hold in both themes. */
  --band-a:#3A3F44; --band-b:#4A5D6B; --band-c:#8C7A55; --band-ink:#F3F4EE;

  --measure:66ch;
  --fs-body:clamp(1.0625rem, 1.0rem + 0.35vw, 1.1875rem);   /* 17 → 19px */
  --lh-body:1.68;
  --sp-para:1.15em;
  --pad:1.35rem;

  --display:'Fraunces',Georgia,serif;
  --body:'Literata',Georgia,serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,monospace;
  --wt-body:400;

  --bar:3.05rem;
  --day-h:3.5px;              /* one day in the core sample; 112 × this is the
                                 column height, so parts stay proportional.
                                 The floor is set by the shortest part: Part I
                                 is 14 days, and its legend row has to hold two
                                 lines of text without clipping. */
  --day-rest:26%;             /* how much part colour an unread day keeps */
  --safe-b:env(safe-area-inset-bottom,0px);
  color-scheme:light;
}
@media(min-width:700px){ :root{--day-h:4px} }

/* ── dark palette ─────────────────────────────────────────────────────────
   Keyed on an explicit `data-theme` rather than on `prefers-color-scheme`.
   The reader can choose system, dark or light (§9), and the choice is resolved
   to a concrete value — by the inline script in index.html before first paint,
   then kept current by app.js — so there is exactly ONE dark block here.

   The obvious alternative, a media query plus a manual override, needs the dark
   values written twice and the light values written twice (to win back inside
   the media query). Four blocks that must agree forever is how a palette drifts.
   Resolving in JS costs nothing: the entire app is rendered by app.js, so there
   is no no-JS case to degrade to.                                          */
:root[data-theme="dark"]{
  --ground:#15171A; --card:#1D2024; --sheet:#232830;
  --ink:#E2E2DA; --ink-2:#A6ABA0; --ink-3:#7C8377;
  --rule:#343A38; --hair:#2A2F2D;
  --oxide:#C97A50; --verdigris:#68B39F; --slate:#8AA5B8; --gold:#C9A94E;
  --scrim:rgba(0,0,0,.58);
  --p1:#B4A075; --p2:#C97A50; --p3:#8AA5B8; --p4:#68B39F; --p5:#8C949B;
  --wt-body:370;            /* light-on-dark renders optically bolder;
                               dropping ~30 units restores apparent weight */
  --day-rest:52%;           /* a 26% mix vanishes against the dark ground */
  color-scheme:dark;
}

/* ── base ─────────────────────────────────────────────────────────────────── */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; height:100%}
body{
  margin:0; min-height:100%;
  background:var(--ground); color:var(--ink);
  font-family:var(--body); font-size:var(--fs-body); font-weight:var(--wt-body);
  line-height:var(--lh-body);
  font-optical-sizing:auto; font-kerning:normal;
  font-variant-numeric:oldstyle-nums;    /* dates sit in the line, don't shout */
  text-rendering:optimizeLegibility;
  overscroll-behavior-y:none;
  -webkit-tap-highlight-color:transparent;
}
h1,h2,h3,h4{font-family:var(--display); font-weight:600; letter-spacing:-.012em;
  line-height:1.16; text-wrap:balance; margin:0}
p{margin:0 0 var(--sp-para); text-wrap:pretty; overflow-wrap:break-word}
p:last-child{margin-bottom:0}
@media(max-width:600px){
  .prose p,.orient p,.co-body p{hyphens:auto; -webkit-hyphens:auto}
}
a{color:inherit; text-decoration-color:var(--rule); text-underline-offset:2px}
em{font-style:italic}
strong,b{font-weight:600}
:focus-visible{outline:2px solid var(--part); outline-offset:2px; border-radius:2px}
[hidden]{display:none!important}

.mono,.kicker,.lbl,.tag{font-family:var(--mono);
  font-variant-numeric:lining-nums tabular-nums; letter-spacing:.16em;
  text-transform:uppercase}
.kicker{font-size:.7rem; letter-spacing:.18em; color:var(--part); margin:0 0 .6rem}
.lbl{font-size:.63rem; color:var(--ink-3); margin:0 0 .55rem}

button{font:inherit; color:inherit; -webkit-tap-highlight-color:transparent}

/* generic pill / ghost button — 44px min target throughout (§5) */
.btn{
  font-family:var(--mono); font-size:.72rem; letter-spacing:.14em;
  text-transform:uppercase; font-variant-numeric:lining-nums;
  background:none; border:1px solid var(--rule); color:var(--ink-2);
  padding:.55rem .9rem; border-radius:4px; cursor:pointer; min-height:44px;
  display:inline-flex; align-items:center; justify-content:center; gap:.45rem;
}
.btn:hover{border-color:var(--part); color:var(--ink)}
.btn-primary{
  background:var(--part); border-color:var(--part); color:var(--ground);
  font-weight:500;
}
.btn-primary:hover{filter:brightness(1.08); color:var(--ground)}
.btn:disabled{opacity:.45; cursor:default}

/* ═══ APP FRAME ═══════════════════════════════════════════════════════════ */
.app{display:flex; flex-direction:column; min-height:100svh}

/* ── top bar: progress pinned (§5) ───────────────────────────────────────── */
.topbar{
  position:sticky; top:0; z-index:30;
  display:flex; align-items:center; gap:.85rem;
  min-height:var(--bar); padding:.55rem var(--pad);
  background:color-mix(in srgb, var(--ground) 92%, transparent);
  backdrop-filter:saturate(1.4) blur(8px);
  border-bottom:1px solid var(--hair);
  font-family:var(--mono); font-size:.66rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-3);
  font-variant-numeric:lining-nums tabular-nums;
}
.topbar .prog{flex:1; height:3px; background:var(--hair); border-radius:2px; overflow:hidden}
.topbar .prog i{display:block; height:100%; width:0; background:var(--part);
  transition:width .3s cubic-bezier(.32,.72,0,1)}
.topbar .count{font-variant-numeric:lining-nums tabular-nums; white-space:nowrap}
.iconbtn{
  background:none; border:0; padding:0; cursor:pointer; color:var(--ink-3);
  min-width:44px; min-height:44px; margin:-.5rem -.55rem -.5rem 0;
  display:inline-flex; align-items:center; justify-content:center;
}
.iconbtn:hover{color:var(--ink)}
.iconbtn svg{width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.6}
.iconbtn{position:relative}
.iconbtn.is-marked{color:var(--slate)}
.iconbtn .badge{
  position:absolute; top:.35rem; right:.1rem;
  font-family:var(--mono); font-size:.5rem; line-height:1; letter-spacing:0;
  background:var(--slate); color:var(--ground);
  min-width:13px; height:13px; border-radius:7px;
  display:flex; align-items:center; justify-content:center; padding:0 3px;
  font-variant-numeric:lining-nums;
}

/* ── margin notes sheet ──────────────────────────────────────────────────── */
.sheet .note{
  margin:1.3rem 0 0; padding-top:1.1rem; border-top:1px solid var(--hair);
}
.sheet .note:first-of-type{border-top:0; padding-top:0}
.note-anchor{
  margin:0 0 .5rem; font-family:var(--mono); font-size:.58rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--slate);
}
.sheet .note textarea{
  display:block; width:100%; min-height:6.5rem; padding:.75rem .85rem; resize:vertical;
  font-family:var(--body); font-size:.97rem; line-height:1.55; font-weight:var(--wt-body);
  color:var(--ink); background:var(--card);
  border:1px solid var(--rule); border-radius:3px;
}
.sheet .note textarea:focus{outline:2px solid var(--slate); outline-offset:1px; border-color:var(--slate)}
.note-foot{
  display:flex; align-items:center; justify-content:space-between; gap:1rem; margin:.6rem 0 0;
}
.note-state{
  font-family:var(--mono); font-size:.58rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-3);
}
.btn.note-save{min-height:40px; padding:.4rem .8rem; font-size:.62rem}
.note-sep{
  margin:1.8rem 0 0; font-family:var(--mono); font-size:.58rem; letter-spacing:.15em;
  text-transform:uppercase; color:var(--ink-3);
}
.sample-flag{
  font-family:var(--mono); font-size:.55rem; letter-spacing:.14em;
  border:1px solid var(--gold); color:var(--gold);
  padding:.12rem .3rem; border-radius:3px; white-space:nowrap;
}

/* ── stage ───────────────────────────────────────────────────────────────── */
.stage{flex:1; display:flex; flex-direction:column; min-height:0}

/* ── bottom action bar, thumb zone (§5) ──────────────────────────────────── */
.actionbar{
  position:sticky; bottom:0; z-index:30;
  display:flex; align-items:center; gap:.6rem;
  padding:.6rem var(--pad) calc(.6rem + var(--safe-b));
  background:color-mix(in srgb, var(--ground) 92%, transparent);
  backdrop-filter:saturate(1.4) blur(8px);
  border-top:1px solid var(--hair);
}
.actionbar .btn-primary{flex:1}
.actionbar .btn-back{flex:0 0 auto; padding-inline:.8rem}

/* ═══ CARDS ═══════════════════════════════════════════════════════════════ */
.card{
  max-width:var(--measure); width:100%; margin:0 auto;
  padding:1.9rem var(--pad) 2.6rem;
}
.card > :last-child{margin-bottom:0}

/* deck mode (phone): one card at a time. The stage is the only scroll
   container — nesting a second one inside the card breaks momentum on iOS. */
.app.deck{height:100svh}
.deck .stage{
  overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch;
  /* the browser keeps the vertical axis; horizontal swipes come to the JS,
     which is what lets a card track the finger without fighting the scroll */
  touch-action:pan-y;
}
.deck .card{display:none}
.deck .card.is-current{display:block; transform-origin:50% 42%; backface-visibility:hidden}
/* --enter-from is set per swipe: the distance the finger left on the table.
   fill-mode stays at the default `none`, so if this never plays the card simply
   renders in place rather than being stranded mid-animation. */
@keyframes card-enter{
  from{opacity:0; transform:translateX(var(--enter-from,30px)) scale(.986)}
  to{opacity:1; transform:none}
}
.deck .card.is-entering{animation:card-enter .34s cubic-bezier(.22,.7,.06,1)}
.deck .spine-rail{display:none}
.app.column{min-height:100svh}

/* ── card furniture ──────────────────────────────────────────────────────── */
.card h2{font-size:1.5rem; margin:0 0 1.05rem}
.card h3{font-size:1.1rem; margin:1.6rem 0 .6rem}
/* Direct child only. `p:first-of-type` is scoped to the parent, so an inline
   figure's own credit line is the first <p> inside its <figure> and would
   otherwise be handed the drop cap meant for the opening paragraph. */
.prose > p:first-of-type::first-letter{
  font-family:var(--display); font-weight:600; font-size:1.32em;
  line-height:1; padding-right:.02em;
}
.type-cold_open .co-body p:first-of-type::first-letter{
  font-family:var(--display); font-weight:600; font-size:2.6em; float:left;
  line-height:.86; padding:.06em .1em 0 0;
}

/* orient */
.type-orient h1{font-size:clamp(1.85rem,1.4rem+2.2vw,2.6rem); margin:0 0 1.1rem}
.type-orient .orient{color:var(--ink-2)}
.type-orient .meta{
  margin:1.6rem 0 0; padding-top:1.1rem; border-top:1px solid var(--hair);
  font-family:var(--mono); font-size:.66rem; letter-spacing:.09em; line-height:2;
  color:var(--ink-3); text-transform:none;
}
.type-orient .meta > div{display:grid; grid-template-columns:5.6rem 1fr; gap:.6rem;
  align-items:baseline}
.type-orient .meta b{color:var(--ink-2); font-weight:500; letter-spacing:.15em;
  text-transform:uppercase; font-size:.6rem}

/* warmup */
.wu{list-style:none; margin:0; padding:0; counter-reset:wu}
.wu > li{
  counter-increment:wu; margin:0 0 1.15rem; padding:0 0 1.15rem;
  border-bottom:1px solid var(--hair);
}
.wu > li:last-child{border-bottom:0; margin-bottom:0; padding-bottom:0}
.wu .q{display:flex; gap:.7rem; margin:0 0 .7rem}
.wu .q::before{
  content:counter(wu,decimal-leading-zero); font-family:var(--mono);
  font-size:.68rem; color:var(--part); letter-spacing:.1em; padding-top:.42em;
  font-variant-numeric:lining-nums;
}
.wu .src{font-family:var(--mono); font-size:.6rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3); margin-top:.5rem; line-height:1.7}
.wu-wait{
  font-family:var(--mono); font-size:.62rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3);
}
.wu-outcome{margin:.9rem 0 .2rem}
.wu-outcome.locked::after{content:'reveal first'}

/* reveal — used by warmup and quiz */
.reveal{margin:.55rem 0 0}
.reveal .ans{
  margin:.8rem 0 0; padding:.85rem 1rem; background:var(--card);
  border-left:2px solid var(--verdigris); font-size:.97rem;
}
.reveal .ans p{margin:0 0 .6rem}

/* prose extras */
.pullout{
  border-left:3px solid var(--part); background:var(--card);
  padding:1rem 1.15rem; margin:1.9rem 0;
}
.pullout .t{font-family:var(--display); font-weight:600; font-size:1.08rem; margin:0 0 .25rem}
.pullout .d{font-size:.95rem; color:var(--ink-2); margin:0}
.pull-quote{
  font-family:var(--display); font-weight:400; font-size:1.28rem; line-height:1.4;
  color:var(--ink); border-top:1px solid var(--rule); border-bottom:1px solid var(--rule);
  padding:1.2rem 0; margin:2rem 0; text-wrap:balance;
}
.cost{
  margin:1.8rem 0 0; padding:1rem 1.15rem; background:var(--card);
  border:1px solid var(--hair); border-radius:3px;
}
.cost .lbl{color:var(--gold)}
.cost p{font-size:.97rem; margin:0}

/* visual */
.figure{margin:0}
.figure .frame{
  border:1px solid var(--hair); border-radius:3px; background:var(--card);
  overflow:hidden;
}
.figure svg,.figure img{display:block; width:100%; height:auto}
/* A landscape diagram scaled to a 375px screen renders its labels at about
   6px. Wide figures therefore get a pannable frame at a legible width rather
   than an illegible fit-to-width. Generated SVGs should prefer portrait. */
.figure.wide .frame{overflow-x:auto; overscroll-behavior-x:contain}
@media(max-width:679px){
  .figure.wide .frame svg{width:auto; min-width:540px; height:auto}
}
.figure .pan-hint{
  margin:.5rem 0 0; font-family:var(--mono); font-size:.58rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-3);
}
@media(min-width:680px){ .figure .pan-hint{display:none} }
.figure figcaption{
  margin:.8rem 0 0; font-size:.86rem; line-height:1.6; color:var(--ink-2);
}
.figure figcaption a{color:var(--part)}
/* attribution for a rehosted public-domain image: institution · date · licence.
   Set in mono at label scale so it reads as provenance rather than as more
   caption — the licence claim has to sit visibly under the thing it licenses. */
.figure .credit{
  margin:.45rem 0 0; font-family:var(--mono); font-size:.62rem; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-3); line-height:1.7;
}
.figure .credit a{color:var(--ink-3); text-decoration-color:var(--rule)}

/* inline figures (§14.6) — the same figure at reading scale, sitting between the
   paragraphs it illustrates rather than on a card of its own. A tall manuscript
   page at full column width eats an entire phone screen, so height is capped and
   the image is centred in its frame instead of being stretched to fit. */
.figure.inline{margin:1.75rem 0}
.figure.inline .frame{display:flex; justify-content:center; background:var(--sheet)}
/* `--iw` is the file's own pixel width, set by the renderer, so a 544px scan is
   never stretched to a 728px column. `width:100%` gives the aspect-ratio a basis
   to compute a height from, which is what reserves the box before a lazy image
   loads. The height cap is a guard against a pathological aspect ratio eating
   three screens, not a normal constraint — a portrait manuscript page should be
   allowed to be tall, because being able to see it is the whole point. When the
   cap does engage, `object-fit:contain` letterboxes rather than squashing. */
.figure.inline img{
  width:100%; max-width:min(100%, var(--iw, 100%));
  height:auto; max-height:70svh; object-fit:contain;
}
.figure.inline figcaption{font-size:.8rem; line-height:1.55}
.figure.inline .credit{font-size:.58rem}
@media(min-width:900px){
  /* the desktop column is tall enough not to need the height cap */
  .figure.inline img{max-height:none}
  .figure.inline{margin:2.1rem 0}
}

/* receipt */
.receipt{
  background:var(--card); border:1px solid var(--rule); border-radius:3px;
  padding:1.15rem 1.2rem; margin:0;
}
.receipt .what{font-size:.9rem; color:var(--ink-2); margin:0 0 .9rem;
  padding-bottom:.75rem; border-bottom:1px dashed var(--rule)}
.receipt blockquote{
  margin:0; font-size:1.02rem; line-height:1.62;
  border-left:2px solid var(--part); padding-left:.95rem;
}
.receipt .src{
  margin:1rem 0 0; font-family:var(--mono); font-size:.63rem; letter-spacing:.1em;
  color:var(--ink-3); text-transform:uppercase;
}
.receipt .src a{color:var(--part)}

/* feed — the project's own language, deliberately not a social network's */
.feed{list-style:none; margin:0; padding:0}
.feed li{
  border-left:2px solid var(--hair); padding:0 0 1.3rem 1rem; margin:0;
  position:relative;
}
.feed li:last-child{padding-bottom:0}
.feed .who{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:.4rem .7rem; margin:0 0 .5rem;
}
.feed .handle{font-family:var(--display); font-weight:600; font-size:1rem}
.feed .where{font-family:var(--mono); font-size:.61rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-3); font-variant-numeric:lining-nums}
.feed .att{
  border:1px solid currentColor; border-radius:2px; padding:.05rem .32rem;
  white-space:nowrap; margin-right:.15rem;
}
.feed .att.yes{color:var(--verdigris)}
.feed .att.no{color:var(--gold)}
.feed .said{margin:0; font-size:1rem}
.feed .src{margin:.6rem 0 0; font-family:var(--mono); font-size:.6rem;
  line-height:1.9; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-3)}
.feed .src a{color:var(--part)}
.feed-key{
  margin:1.4rem 0 0; padding-top:1rem; border-top:1px solid var(--hair);
  font-family:var(--mono); font-size:.62rem; line-height:1.9; letter-spacing:.05em;
  color:var(--ink-3);
}

/* compare — the crossroads workhorse */
.cmp{width:100%; border-collapse:collapse; font-size:.95rem}
.cmp th,.cmp td{text-align:left; vertical-align:top; padding:.7rem .6rem;
  border-bottom:1px solid var(--hair)}
.cmp thead th{
  font-family:var(--mono); font-size:.63rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--part); border-bottom:1px solid var(--rule);
  padding-top:0;
}
.cmp tbody th{
  font-family:var(--mono); font-size:.6rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-3); font-weight:400;
}
.cmp th:first-child,.cmp td:first-child{padding-left:0}
.cmp th:last-child,.cmp td:last-child{padding-right:0}
/* narrow: each row becomes a labelled stack, no horizontal scroll */
@media(max-width:559px){
  .cmp,.cmp tbody,.cmp tr,.cmp td,.cmp th{display:block}
  .cmp thead{display:none}
  .cmp tr{margin:0 0 1.4rem; border-bottom:1px solid var(--rule); padding-bottom:.4rem}
  .cmp tbody th{padding:0 0 .4rem; border:0; color:var(--ink-2)}
  .cmp td{padding:0 0 .75rem; border:0; position:relative}
  .cmp td::before{
    content:attr(data-col); display:block;
    font-family:var(--mono); font-size:.58rem; letter-spacing:.14em;
    text-transform:uppercase; color:var(--part); margin-bottom:.2rem;
  }
}

/* timeline — the synthesis workhorse */
.tl{list-style:none; margin:0; padding:0}
.tl li{
  position:relative; padding:0 0 1.35rem 1.4rem;
  border-left:1px solid var(--rule); margin:0;
}
.tl li:last-child{padding-bottom:0; border-left-color:transparent}
.tl li::before{
  content:''; position:absolute; left:-4.5px; top:.52em;
  width:8px; height:8px; border-radius:50%;
  background:var(--ground); border:1.5px solid var(--part);
}
.tl .when{
  font-family:var(--mono); font-size:.63rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--part); margin:0 0 .28rem;
  font-variant-numeric:lining-nums;
}
.tl .what{margin:0; font-size:.98rem}

/* contingency */
.fork,.argue{margin:0 0 1.6rem; padding:1.05rem 1.2rem; border-radius:3px}
.fork{background:var(--card); border-left:3px solid var(--slate)}
.argue{background:var(--card); border-left:3px solid var(--oxide)}
.fork .lbl{color:var(--slate)} .argue .lbl{color:var(--oxide)}
.fork p,.argue p{margin:0; font-size:1rem}

/* machinery — never omitted, even when a lens is thin (§5) */
.mach{margin:0}
.mach > div{
  padding:1rem 0; border-bottom:1px solid var(--hair);
  display:grid; grid-template-columns:1fr; gap:.3rem;
}
.mach > div:last-child{border-bottom:0; padding-bottom:0}
.mach dt{
  font-family:var(--mono); font-size:.63rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--part);
}
.mach dd{margin:0; font-size:.98rem}
@media(min-width:620px){
  .mach > div{grid-template-columns:7.5rem 1fr; gap:1.1rem}
  .mach dt{padding-top:.28em}
}

/* quiz — free recall → reveal → three-way self-grade (§1 #4, #16) */
.quiz{list-style:none; margin:0; padding:0; counter-reset:qz}
.quiz > li{
  counter-increment:qz; padding:0 0 1.3rem; margin:0 0 1.3rem;
  border-bottom:1px solid var(--hair);
}
.quiz > li:last-of-type{border-bottom:0}
.quiz .q{display:flex; gap:.7rem; margin:0 0 .8rem; font-size:1.02rem}
.quiz .q::before{
  content:counter(qz,decimal-leading-zero); font-family:var(--mono);
  font-size:.68rem; color:var(--part); letter-spacing:.1em; padding-top:.45em;
  font-variant-numeric:lining-nums;
}
.grade{display:flex; flex-wrap:wrap; gap:.5rem; margin:.9rem 0 0; position:relative}
/* While locked the buttons are hidden rather than veiled: a translucent overlay
   let their labels bleed through and collide with the hint. */
.grade.locked > .btn{visibility:hidden}
.grade.locked::after{
  content:'reveal first'; position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--mono); font-size:.58rem; letter-spacing:.15em;
  text-transform:uppercase; color:var(--ink-3);
  border:1px dashed var(--hair); border-radius:4px;
}
.grade .btn{flex:1 1 auto; min-width:6.2rem; font-size:.66rem; letter-spacing:.1em}
.grade .btn[aria-pressed="true"]{
  background:var(--g,var(--verdigris)); border-color:var(--g,var(--verdigris));
  color:var(--ground); font-weight:500;
}
.grade .g-got{--g:var(--verdigris)}
.grade .g-partial{--g:var(--gold)}
.grade .g-missed{--g:var(--oxide)}
.quiz-tally{
  margin:1.5rem 0 0; padding:1rem 1.15rem; background:var(--card);
  border-left:3px solid var(--part);
  font-family:var(--mono); font-size:.68rem; letter-spacing:.08em; line-height:2;
  color:var(--ink-2); font-variant-numeric:lining-nums tabular-nums;
}
.quiz-tally b{color:var(--ink); font-weight:600}
.quiz-tally .warn{color:var(--gold)}

/* reflection */
.reflect .prompt{font-size:1.08rem; margin:0 0 .9rem}
.reflect .nudge{font-size:.93rem; color:var(--ink-2)}
.reflect textarea{
  display:block; width:100%; margin:1.2rem 0 0; padding:.9rem 1rem;
  min-height:11rem; resize:vertical;
  font-family:var(--body); font-size:1rem; line-height:1.6; font-weight:var(--wt-body);
  color:var(--ink); background:var(--card);
  border:1px solid var(--rule); border-radius:3px;
}
.reflect textarea:focus{outline:2px solid var(--part); outline-offset:1px; border-color:var(--part)}
.reflect .sharebox{
  margin:1.3rem 0 0; padding:1rem 1.1rem;
  background:var(--card); border-left:3px solid var(--part); border-radius:0 3px 3px 0;
}
.reflect .sharebox .fhint{margin:.6rem 0 0; font-size:.85rem}
.reflect .toggle.is-off{opacity:.55}
.reflect .toggle.is-off .tlabel{text-decoration:line-through}
.reflect-actions{margin:1.2rem 0 0}
.reflect .foot{
  display:flex; flex-wrap:wrap; align-items:center; gap:.7rem 1rem; margin:.8rem 0 0;
  font-family:var(--mono); font-size:.62rem; letter-spacing:.11em;
  text-transform:uppercase; color:var(--ink-3);
}
.reflect .count{font-variant-numeric:lining-nums tabular-nums}
.reflect .saved{color:var(--verdigris)}

/* done */
.type-done .tally{
  list-style:none; margin:1.4rem 0 0; padding:1.2rem 0 0;
  border-top:1px solid var(--hair);
}
.type-done .tally li{
  display:flex; justify-content:space-between; gap:1rem; padding:.42rem 0;
  font-family:var(--mono); font-size:.68rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3);
  font-variant-numeric:lining-nums tabular-nums;
}
.type-done .tally b{color:var(--ink); font-weight:500}
.endnote{
  margin:1.6rem 0 0; padding:1rem 1.15rem; background:var(--card);
  border-left:3px solid var(--ink-3); font-size:.93rem; color:var(--ink-2);
}
.endnote .lbl{color:var(--ink-3)}
.sheet-links{display:flex; flex-wrap:wrap; gap:.6rem; margin:1.5rem 0 0}
/* the bottom bar already provides this on a phone */
.done-actions{margin:2rem 0 0}
.deck .done-actions{display:none}
.btn.subtle{margin-top:.6rem; border-color:transparent; color:var(--ink-3)}
.btn.subtle:hover{border-color:var(--rule)}

/* ── inline annotation (§9) ──────────────────────────────────────────────── */
/* A span, not a button: an atomic inline box cannot break across lines, which
   orphans trailing punctuation ("Thucydides" / ", a generation later"). */
.anno{
  display:inline; cursor:pointer;
  border-bottom:1.5px dotted var(--k);
}
.anno:hover{background:color-mix(in srgb, var(--k) 14%, transparent)}
.anno:focus-visible{outline:2px solid var(--k); outline-offset:2px; border-radius:2px}
.anno[data-kind="person"]{--k:var(--oxide)}
.anno[data-kind="term"]  {--k:var(--verdigris)}
.anno[data-kind="place"] {--k:var(--slate)}
.anno[data-kind="work"]  {--k:var(--gold)}
.anno-key{
  display:flex; flex-wrap:wrap; gap:.45rem 1.05rem; margin:0 0 1.5rem;
  font-family:var(--mono); font-size:.61rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-3);
}
.anno-key span::before{
  content:''; display:inline-block; width:14px; height:0;
  border-bottom:1.5px dotted currentColor; margin-right:.4rem; vertical-align:.25em;
}
.anno-key .p{color:var(--oxide)} .anno-key .t{color:var(--verdigris)}
.anno-key .l{color:var(--slate)} .anno-key .w{color:var(--gold)}

/* ── bottom sheet / popover (§5: never walls of text) ────────────────────── */
.scrim{
  position:fixed; inset:0; background:var(--scrim); opacity:0;
  pointer-events:none; transition:opacity .18s; z-index:40; backdrop-filter:blur(2px);
}
.scrim.on{opacity:1; pointer-events:auto}
.sheet{
  position:fixed; left:0; right:0; bottom:0; z-index:50;
  background:var(--sheet); border-top:3px solid var(--k,var(--part));
  padding:1.35rem var(--pad) calc(1.5rem + var(--safe-b));
  transform:translateY(101%); transition:transform .24s cubic-bezier(.32,.72,0,1);
  max-height:78svh; overflow-y:auto;
  box-shadow:0 -12px 40px rgba(0,0,0,.18);
}
.sheet.on{transform:translateY(0)}
@media(min-width:700px){
  .sheet{
    left:50%; right:auto; bottom:2.5rem; width:min(32rem,90vw);
    transform:translate(-50%,14px) scale(.98); opacity:0; border-radius:6px;
    max-height:70svh; padding:1.5rem 1.6rem;
  }
  .sheet.on{transform:translate(-50%,0) scale(1); opacity:1}
}
/* the grab handle is a real target: pulling anywhere on it starts the dismiss
   gesture even when the sheet's content is scrolled */
.sheet .grab{
  width:34px; height:4px; border-radius:2px; background:var(--rule);
  margin:-.5rem auto 1rem; position:relative;
}
.sheet .grab::after{
  content:''; position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  width:120px; height:34px;      /* invisible 44px-class pull area */
}
@media(min-width:700px){.sheet .grab{display:none}}
.sheet .kind{font-family:var(--mono); font-size:.62rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--k,var(--part)); margin:0 0 .3rem}
.sheet h3{font-size:1.3rem; margin:0}
.sheet .dates{font-family:var(--mono); font-size:.72rem; color:var(--ink-3);
  margin:.25rem 0 0; font-variant-numeric:oldstyle-nums}
.sheet .def{margin:.9rem 0 0; font-size:.97rem}
.sheet .why{
  margin:.85rem 0 0; padding-top:.85rem; border-top:1px solid var(--hair);
  font-size:.92rem; color:var(--ink-2);
}
.sheet .why b{
  font-family:var(--mono); font-size:.6rem; letter-spacing:.17em;
  text-transform:uppercase; color:var(--k,var(--part)); display:block;
  margin-bottom:.3rem; font-weight:600;
}
.sheet .close{margin-top:1.3rem; width:100%}
.sheet dl{margin:0}
.sheet dt{font-family:var(--display); font-weight:600; font-size:1rem; margin:1.1rem 0 .2rem}
.sheet dt:first-child{margin-top:0}
.sheet dd{margin:0; font-size:.93rem; color:var(--ink-2)}
.sheet ol{margin:0; padding-left:1.3rem; font-size:.9rem; color:var(--ink-2)}
.sheet ol li{margin:0 0 .7rem}
.sheet ol a{color:var(--part)}
.sheet .menu{list-style:none; margin:0; padding:0}
.sheet .menu li{border-bottom:1px solid var(--hair)}
.sheet .menu li:last-child{border-bottom:0}
.sheet .menu button,.sheet .menu a{
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  width:100%; min-height:52px; padding:.6rem 0;
  background:none; border:0; cursor:pointer; text-align:left;
  font-family:var(--mono); font-size:.7rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-2); text-decoration:none;
}
.sheet .menu button:hover,.sheet .menu a:hover{color:var(--ink)}
.sheet .menu .hint{
  font-size:.58rem; letter-spacing:.1em; color:var(--ink-3); text-transform:none;
  font-family:var(--mono);
}

/* ═══ HOME ════════════════════════════════════════════════════════════════ */
.home{max-width:var(--measure); margin:0 auto; padding:2.4rem var(--pad) 3rem; width:100%}
.home .eyebrow{font-family:var(--mono); font-size:.65rem; letter-spacing:.2em;
  text-transform:uppercase; color:var(--ink-3); margin:0 0 .7rem}
.home h1{font-size:clamp(2rem,1.5rem+2.6vw,3rem); line-height:1.04; margin:0 0 1rem}
.home .sub{color:var(--ink-2); font-size:.95rem; margin:0 0 1.2rem}
.home .stats{
  display:flex; flex-wrap:wrap; gap:.9rem 2rem;
  border-top:1px solid var(--hair); padding-top:1.6rem; margin:2.4rem 0 1.2rem;
}
.home .stat{display:flex; align-items:baseline; gap:.55rem}
.home .n{font-family:var(--display); font-weight:600; font-size:1.9rem; line-height:1}
.home .of{font-family:var(--mono); font-size:.63rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3)}

/* ── the core sample ──────────────────────────────────────────────────────
   One segment per day, stacked in five parts. Segment height is fixed, so a
   part's depth is literally its number of days and the whole column is exactly
   112 blocks tall. Completed days sit at full strength; the rest are mixed
   toward the page ground, which keeps the contrast right in both themes
   (plain opacity goes almost invisible on the dark ground).                */
.core-wrap{display:flex; gap:1rem; align-items:stretch; margin:0 0 2rem}
.core{
  flex:0 0 40px; display:flex; flex-direction:column;
  border:1px solid var(--hair); border-radius:3px; overflow:hidden;
}
.core .part{display:flex; flex-direction:column; color:var(--pc)}
.core .part + .part{border-top:1.5px solid var(--ground)}
.core .day{
  position:relative; display:block; height:var(--day-h); flex:0 0 var(--day-h);
  background:color-mix(in srgb, currentColor var(--day-rest), var(--ground));
  border-bottom:.5px solid color-mix(in srgb, var(--ground) 55%, transparent);
}
.core .day.is-done{background:currentColor}
/* "You are here" is a rule at the top edge of the next day, not a filled cell.
   A fill would erase the day's own colour — and on a re-read the next day is
   also a completed one, so the marker has to sit on top of it, not replace it. */
.core .day.is-next::before{
  content:''; position:absolute; left:0; right:0; top:0; height:1.5px;
  background:var(--ink); z-index:1;
}

.core-legend{
  list-style:none; margin:0; padding:0; flex:1; min-width:0;
  display:flex; flex-direction:column;
}
.core-legend .leg{
  display:flex; flex-direction:column; justify-content:center;
  min-height:0; overflow:hidden; padding:.15rem 0;
}
.core-legend .leg + .leg{border-top:1px solid var(--hair)}
/* Titles wrap rather than truncate — Part III is 37 characters. The tight rows
   are the short-titled ones (Part I is 7 characters in 14 days of depth), so
   wrapping costs nothing where space is scarce. */
.leg-t{
  margin:0; display:flex; gap:.5rem; align-items:baseline;
  font-family:var(--display); font-weight:600; font-size:.92rem; line-height:1.2;
  text-wrap:balance;
}
.leg-t b{
  font-family:var(--mono); font-size:.6rem; letter-spacing:.1em; font-weight:600;
  color:var(--pc); flex:0 0 1.5rem; font-variant-numeric:lining-nums;
}
.leg-d{
  margin:.12rem 0 0; font-family:var(--mono); font-size:.58rem; letter-spacing:.09em;
  text-transform:uppercase; color:var(--ink-3);
  font-variant-numeric:lining-nums tabular-nums;
}
.core-legend .leg.is-here .leg-d{color:var(--pc)}
/* first block after the title: no rule above it, it is the primary action */
.home .next{margin:1.4rem 0 0}
.home .next .lbl{color:var(--part)}
.home .next h2{font-size:1.35rem; margin:0 0 .5rem}
.home .next .where{font-family:var(--mono); font-size:.63rem; letter-spacing:.11em;
  color:var(--ink-3); text-transform:uppercase; margin:0}
.home .go{margin:1.4rem 0 0; width:100%}
.homenav{
  list-style:none; margin:2.4rem 0 0; padding:1.2rem 0 0;
  border-top:1px solid var(--hair);
}
.homenav li{border-bottom:1px solid var(--hair)}
.homenav a,.homenav button{
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  width:100%; min-height:52px; background:none; border:0; cursor:pointer;
  text-align:left; text-decoration:none;
  font-family:var(--mono); font-size:.7rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-2);
}
.homenav .hint{font-size:.57rem; letter-spacing:.09em; color:var(--ink-3);
  text-transform:none}

/* ═══ REFLECTIONS ARCHIVE ═════════════════════════════════════════════════ */
.arch-search{margin:2rem 0 0}
.arch-search input[type="search"]{
  display:block; width:100%; min-height:48px; padding:.7rem .9rem;
  font-family:var(--body); font-size:1rem; font-weight:var(--wt-body);
  color:var(--ink); background:var(--card);
  border:1px solid var(--rule); border-radius:4px; -webkit-appearance:none;
}
.arch-search input:focus{outline:2px solid var(--part); outline-offset:1px; border-color:var(--part)}
.arch-found:not(:empty){
  margin:.6rem 0 0; font-family:var(--mono); font-size:.6rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-3);
}
.archive{list-style:none; margin:2.2rem 0 0; padding:0}
.archive li{
  border-top:1px solid var(--rule); padding:1.6rem 0 0; margin:0 0 2.4rem;
}
.arch-day{
  display:flex; flex-wrap:wrap; justify-content:space-between; gap:.4rem 1rem;
  margin:0 0 .5rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.12em;
  text-transform:uppercase; font-variant-numeric:lining-nums tabular-nums;
}
.arch-num{color:var(--pc)}
.arch-marks{color:var(--ink-3)}
.arch-title{font-size:1.28rem; margin:0 0 .3rem}
.arch-where{
  margin:0 0 1rem; font-family:var(--mono); font-size:.58rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3);
}
.arch-prompt{
  margin:0 0 1.1rem; padding:.85rem 1rem; background:var(--card);
  border-left:3px solid var(--pc); font-size:.92rem; color:var(--ink-2);
}
.arch-prompt .anno{border-bottom:0}
.arch-text{margin:0; white-space:pre-wrap}
.arch-open{
  display:inline-block; margin:1rem 0 0; font-family:var(--mono); font-size:.6rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--pc);
  text-decoration:none; min-height:44px; line-height:44px;
}

/* margin notes inside an archive entry (§8). Slate, matching the note sheet's own
   accent, and deliberately set apart from the reflection above it: a reflection
   may have been shared with the seminar and a note never is, so the two should not
   read as one block of text. */
.arch-none{
  margin:0; font-family:var(--mono); font-size:.62rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3);
}
.arch-notes{margin:1.35rem 0 0; padding-left:.95rem; border-left:2px solid var(--slate)}
.arch-notes .lbl{color:var(--slate); margin:0 0 .75rem}
.arch-note + .arch-note{
  margin-top:.9rem; padding-top:.9rem; border-top:1px dashed var(--rule);
}
.arch-note-anchor{
  margin:0 0 .3rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3);
}
.arch-note-text{margin:0; font-size:.95rem; line-height:1.6; white-space:pre-wrap}

/* ═══ SEMINAR ═════════════════════════════════════════════════════════════ */
.sem{margin:2.2rem 0 0; padding-top:1.5rem; border-top:1px solid var(--rule)}
.sem .lbl{color:var(--verdigris)}
.sem-note{margin:0; font-size:.92rem; color:var(--ink-2)}
.sem-meta{
  margin:0 0 1.1rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.11em;
  text-transform:uppercase; color:var(--ink-3);
}
.seminar{list-style:none; margin:0; padding:0}
.seminar li{
  border-left:2px solid var(--verdigris); padding:0 0 1.3rem 1rem; margin:0 0 1.3rem;
}
.seminar li:last-child{margin-bottom:0; padding-bottom:0}
.sem-who{display:flex; flex-wrap:wrap; align-items:baseline; gap:.5rem; margin:0 0 .45rem}
.sem-handle{font-family:var(--display); font-weight:600; font-size:1rem}
.sem-edited{
  font-family:var(--mono); font-size:.55rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--ink-3); border:1px solid var(--hair); border-radius:2px; padding:.05rem .3rem;
}
.sem-text{margin:0; font-size:.97rem; white-space:pre-wrap}

/* ═══ MAP ═════════════════════════════════════════════════════════════════ */
.home .pace{
  margin:.9rem 0 0; font-family:var(--mono); font-size:.6rem; line-height:1.8;
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink-3);
}
.mappart{margin:2.6rem 0 0; padding-top:1.4rem; border-top:1px solid var(--rule)}
.mp-h{
  margin:0 0 .2rem; display:flex; gap:.6rem; align-items:baseline;
  font-family:var(--display); font-weight:600; font-size:1.3rem;
}
.mp-h b{
  font-family:var(--mono); font-size:.66rem; letter-spacing:.14em; color:var(--pc);
  font-variant-numeric:lining-nums; flex:0 0 auto;
}
.mp-meta{
  margin:0 0 1.2rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3);
}
.mapunit{margin:0 0 1.5rem}
.mu-h{display:flex; flex-wrap:wrap; gap:.3rem .6rem; align-items:baseline; margin:0 0 .5rem}
.mu-n{font-family:var(--mono); font-size:.58rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--pc); font-variant-numeric:lining-nums}
.mu-t{font-family:var(--display); font-weight:600; font-size:.98rem}
.mu-tag{font-family:var(--mono); font-size:.55rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-3)}
.mapdays{list-style:none; margin:0; padding:0}
.mapdays li{border-top:1px solid var(--hair)}
.mapdays a,.mapdays .dlocked{
  display:flex; gap:.8rem; align-items:baseline; min-height:44px;
  padding:.6rem 0; text-decoration:none; color:var(--ink-2);
}
.mapdays a:hover{color:var(--ink)}
.dnum{
  font-family:var(--mono); font-size:.62rem; letter-spacing:.08em; color:var(--ink-3);
  flex:0 0 2.2rem; font-variant-numeric:lining-nums tabular-nums; padding-top:.2em;
}
.dttl{font-size:.95rem; line-height:1.4}
.mapdays .is-today .dnum{color:var(--ink); font-weight:600}
.mapdays .is-unwritten .dlocked{color:var(--ink-3); opacity:.72; cursor:default}
.mapdays .is-unwritten .dnum::after{content:' ·'; letter-spacing:0}
/* after .is-unwritten on purpose: a finished day is marked finished even in the
   odd case where its lesson file is missing */
.mapdays .is-done .dnum{color:var(--pc)}
.mapdays .is-done a{color:var(--ink)}
.mapdays .is-done .dnum::after{content:' ✓'; letter-spacing:0}

/* ═══ SETTINGS ════════════════════════════════════════════════════════════ */
.setlist{margin:1.6rem 0 0; padding:0}
.setlist dt{
  font-family:var(--mono); font-size:.58rem; letter-spacing:.15em;
  text-transform:uppercase; color:var(--ink-3); margin:1.1rem 0 .2rem;
}
.setlist dt:first-child{margin-top:0}
.setlist dd{margin:0; font-size:1rem; padding-bottom:.7rem; border-bottom:1px solid var(--hair)}
.setactions{margin:1.8rem 0 0}
.sheet .btn.wide{margin-top:1.2rem}

/* ═══ SIGNUP ══════════════════════════════════════════════════════════════ */
.join .sub{margin-bottom:2rem}
.fields{margin:0}
.field{display:block; margin:0 0 1.9rem}
.flabel{
  display:block; font-family:var(--mono); font-size:.62rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink-3); margin:0 0 .5rem;
}
.field input[type="email"],
.field input[type="text"],
.field input[type="date"]{
  display:block; width:100%; min-height:48px; padding:.7rem .9rem;
  font-family:var(--body); font-size:1.02rem; font-weight:var(--wt-body);
  color:var(--ink); background:var(--card);
  border:1px solid var(--rule); border-radius:4px;
}
.field input:focus{outline:2px solid var(--part); outline-offset:1px; border-color:var(--part)}
.fhint{margin:.6rem 0 0; font-size:.86rem; line-height:1.55; color:var(--ink-2)}
.fnote{
  margin:1.4rem 0 0; font-family:var(--mono); font-size:.6rem; line-height:1.9;
  letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3);
}
.fwarn:not(:empty){margin:.55rem 0 0; font-size:.85rem; color:var(--gold)}
.ferr:not(:empty){
  margin:0 0 1.1rem; padding:.75rem .9rem; font-size:.9rem;
  background:var(--card); border-left:3px solid var(--oxide); color:var(--ink);
}
.btn.wide{width:100%; min-height:50px}

/* toggle — 44px target, states legible without relying on colour alone */
.toggle{display:flex; align-items:center; gap:.75rem; min-height:44px; cursor:pointer}
.toggle input{position:absolute; opacity:0; width:1px; height:1px}
.toggle .track{
  flex:0 0 auto; width:46px; height:27px; border-radius:14px;
  background:var(--card); border:1px solid var(--rule);
  transition:background .18s, border-color .18s; position:relative;
}
.toggle .knob{
  position:absolute; top:3px; left:3px; width:19px; height:19px; border-radius:50%;
  background:var(--ink-3); transition:transform .2s cubic-bezier(.32,.72,0,1), background .18s;
}
.toggle input:checked + .track{background:var(--part); border-color:var(--part)}
.toggle input:checked + .track .knob{transform:translateX(19px); background:var(--ground)}
.toggle input:focus-visible + .track{outline:2px solid var(--part); outline-offset:2px}
.toggle .tlabel{font-size:1rem}

/* segmented choice — appearance (§9). Three mutually exclusive options, so it is
   a radiogroup rather than three toggle buttons: arrow keys move the selection,
   which is what a screen reader announces and expects. 44px tall per §5. */
.seg{
  display:flex; margin:.6rem 0 0;
  border:1px solid var(--rule); border-radius:3px; overflow:hidden;
  background:var(--card);
}
.seg button{
  flex:1 1 0; min-height:44px; padding:.5rem .35rem;
  background:transparent; border:0; border-left:1px solid var(--rule);
  font-family:var(--mono); font-size:.63rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--ink-2); cursor:pointer;
  transition:background .16s, color .16s;
}
.seg button:first-child{border-left:0}
.seg button[aria-checked="true"]{background:var(--part); color:var(--ground)}
.seg button:focus-visible{outline:2px solid var(--part); outline-offset:-3px}

/* ═══ DESKTOP (≥900px): one continuous column, spine in the left margin ═══ */
@media(min-width:900px){
  .column .stage{overflow:visible}
  .column .actionbar{display:none}
  .column .reading{
    display:grid; grid-template-columns:86px minmax(0,var(--measure));
    gap:2.6rem; justify-content:center;
    padding:2.6rem 2rem 5rem; margin:0 auto; max-width:calc(86px + 2.6rem + 66ch + 4rem);
  }
  .column .card{
    display:block; max-width:none; padding:0 0 3.4rem;
    border-bottom:1px solid var(--hair); margin:0 0 3.4rem;
  }
  .column .card:last-child{border-bottom:0; margin-bottom:0; padding-bottom:0}
  .column .card.is-current{animation:none}
  /* the part column doubles as position indicator */
  .spine-rail{
    position:sticky; top:calc(var(--bar) + 2.6rem); align-self:start;
    height:calc(100svh - var(--bar) - 6rem); display:flex; gap:.6rem;
  }
  .spine-rail .col{
    flex:0 0 12px; display:flex; flex-direction:column;
    border:1px solid var(--hair); border-radius:2px; overflow:hidden;
  }
  .spine-rail .marks{
    flex:1; position:relative; font-family:var(--mono); font-size:.55rem;
    letter-spacing:.1em; text-transform:uppercase; color:var(--ink-3);
  }
  .spine-rail .mark{
    position:absolute; left:0; right:0; white-space:nowrap; line-height:1.1;
    transform:translateY(-50%);
  }
  .spine-rail .mark.on{color:var(--part); font-weight:500}
  .spine-rail .here{
    position:absolute; left:-.6rem; width:12px; height:0;
    border-top:1.5px solid var(--ink); transition:top .3s;
  }
  .column .type-orient h1{font-size:2.9rem}
  .column .card h2{font-size:1.72rem}
  .column .figure svg{max-height:none}
}
@media(min-width:900px){
  .home{padding:4rem 2rem 5rem}
  .core{flex-basis:44px}
  .core-wrap{gap:1.4rem}
  .leg-t{font-size:1.02rem}
  .leg-d{font-size:.62rem}
}

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

/* ── offline banner ──────────────────────────────────────────────────────── */
.offline{
  display:none; padding:.5rem var(--pad); text-align:center;
  background:var(--card); border-bottom:1px solid var(--hair);
  font-family:var(--mono); font-size:.6rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3);
}
body.is-offline .offline{display:block}
