Something went wrong. Try again.
Original-language reader for Kant, Aristotle & more: select any passage to gloss, translate, or hear it read aloud, with exact citations.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773@import "tailwindcss";@import "tw-animate-css";@import "shadcn/tailwind.css";@import "@fontsource-variable/noto-sans";@import "@fontsource-variable/playfair-display";
@custom-variant dark (&:is(.dark *));
:root { --background: oklch(1 0 0); --foreground: oklch(0.147 0.004 49.3); --card: oklch(1 0 0); --card-foreground: oklch(0.147 0.004 49.3); --popover: oklch(1 0 0); --popover-foreground: oklch(0.147 0.004 49.3); --primary: oklch(0.214 0.009 43.1); --primary-foreground: oklch(0.986 0.002 67.8); --secondary: oklch(0.96 0.002 17.2); --secondary-foreground: oklch(0.214 0.009 43.1); --muted: oklch(0.96 0.002 17.2); --muted-foreground: oklch(0.547 0.021 43.1); --accent: oklch(0.96 0.002 17.2); --accent-foreground: oklch(0.214 0.009 43.1); --destructive: oklch(0.577 0.245 27.325); --border: oklch(0.922 0.005 34.3); --input: oklch(0.922 0.005 34.3); --ring: oklch(0.714 0.014 41.2); --chart-1: oklch(0.868 0.007 39.5); --chart-2: oklch(0.547 0.021 43.1); --chart-3: oklch(0.438 0.017 39.3); --chart-4: oklch(0.367 0.016 35.7); --chart-5: oklch(0.268 0.011 36.5); --radius: 0.625rem; --sidebar: oklch(0.986 0.002 67.8); --sidebar-foreground: oklch(0.147 0.004 49.3); --sidebar-primary: oklch(0.214 0.009 43.1); --sidebar-primary-foreground: oklch(0.986 0.002 67.8); --sidebar-accent: oklch(0.96 0.002 17.2); --sidebar-accent-foreground: oklch(0.214 0.009 43.1); --sidebar-border: oklch(0.922 0.005 34.3); --sidebar-ring: oklch(0.714 0.014 41.2);}
.dark { --background: oklch(0.147 0.004 49.3); --foreground: oklch(0.986 0.002 67.8); --card: oklch(0.214 0.009 43.1); --card-foreground: oklch(0.986 0.002 67.8); --popover: oklch(0.214 0.009 43.1); --popover-foreground: oklch(0.986 0.002 67.8); --primary: oklch(0.922 0.005 34.3); --primary-foreground: oklch(0.214 0.009 43.1); --secondary: oklch(0.268 0.011 36.5); --secondary-foreground: oklch(0.986 0.002 67.8); --muted: oklch(0.268 0.011 36.5); --muted-foreground: oklch(0.714 0.014 41.2); --accent: oklch(0.268 0.011 36.5); --accent-foreground: oklch(0.986 0.002 67.8); --destructive: oklch(0.704 0.191 22.216); --border: oklch(1 0 0 / 10%); --input: oklch(1 0 0 / 15%); --ring: oklch(0.547 0.021 43.1); --chart-1: oklch(0.868 0.007 39.5); --chart-2: oklch(0.547 0.021 43.1); --chart-3: oklch(0.438 0.017 39.3); --chart-4: oklch(0.367 0.016 35.7); --chart-5: oklch(0.268 0.011 36.5); --sidebar: oklch(0.214 0.009 43.1); --sidebar-foreground: oklch(0.986 0.002 67.8); --sidebar-primary: oklch(0.488 0.243 264.376); --sidebar-primary-foreground: oklch(0.986 0.002 67.8); --sidebar-accent: oklch(0.268 0.011 36.5); --sidebar-accent-foreground: oklch(0.986 0.002 67.8); --sidebar-border: oklch(1 0 0 / 10%); --sidebar-ring: oklch(0.547 0.021 43.1);}
@theme inline { --font-sans: "Noto Sans Variable", sans-serif; --font-heading: "Playfair Display Variable", serif; --color-sidebar-ring: var(--sidebar-ring); --color-sidebar-border: var(--sidebar-border); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-accent: var(--sidebar-accent); --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); --color-sidebar-primary: var(--sidebar-primary); --color-sidebar-foreground: var(--sidebar-foreground); --color-sidebar: var(--sidebar); --color-chart-5: var(--chart-5); --color-chart-4: var(--chart-4); --color-chart-3: var(--chart-3); --color-chart-2: var(--chart-2); --color-chart-1: var(--chart-1); --color-ring: var(--ring); --color-input: var(--input); --color-border: var(--border); --color-destructive: var(--destructive); --color-accent-foreground: var(--accent-foreground); --color-accent: var(--accent); --color-muted-foreground: var(--muted-foreground); --color-muted: var(--muted); --color-secondary-foreground: var(--secondary-foreground); --color-secondary: var(--secondary); --color-primary-foreground: var(--primary-foreground); --color-primary: var(--primary); --color-popover-foreground: var(--popover-foreground); --color-popover: var(--popover); --color-card-foreground: var(--card-foreground); --color-card: var(--card); --color-foreground: var(--foreground); --color-background: var(--background); --radius-sm: calc(var(--radius) * 0.6); --radius-md: calc(var(--radius) * 0.8); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) * 1.4); --radius-2xl: calc(var(--radius) * 1.8); --radius-3xl: calc(var(--radius) * 2.2); --radius-4xl: calc(var(--radius) * 2.6);}
@layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } html { @apply font-sans; }}
/* * lekterion — editorial / critical-edition typography. * Warm paper ground + warm ink, a narrow justified measure, Playfair Display * for the apparatus and marginalia over the polytonic-capable Noto Sans body. */:root { --paper: oklch(0.986 0.007 83); --paper-raised: oklch(0.998 0.004 83); --ink: oklch(0.247 0.012 55); --ink-soft: oklch(0.46 0.018 50); --ink-faint: oklch(0.62 0.02 50); --rule: oklch(0.86 0.012 60); --accent-ink: oklch(0.49 0.1 38); --selection: oklch(0.9 0.066 75); /* Where a jump target comes to rest, clear of the sticky running head. Footnote returns land deeper (20% down) so the referring line is in view; locus + heading/TOC jumps land higher (10% down) to maximize reading space. */ --jump-offset: 20vh; --jump-offset-nav: 10vh;}.dark { --paper: oklch(0.168 0.006 58); --paper-raised: oklch(0.205 0.008 55); --ink: oklch(0.9 0.01 80); --ink-soft: oklch(0.74 0.014 70); --ink-faint: oklch(0.58 0.014 65); --rule: oklch(0.34 0.01 55); --accent-ink: oklch(0.78 0.09 55); --selection: oklch(0.42 0.06 60);}
@layer components { /* ---- shared shells ------------------------------------------------ */ .lib-shell, .reader-shell { min-height: 100svh; background: var(--paper); color: var(--ink); }
/* ---- library index ------------------------------------------------ */ .lib-shell { display: flex; flex-direction: column; } .lib-column { flex: 1; width: 100%; max-width: 46rem; margin-inline: auto; padding: clamp(2.5rem, 6vw, 5.5rem) 1.5rem 4rem; } .lib-masthead { margin-bottom: 3.5rem; } .lib-kicker { font-size: 0.72rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.9rem; } .lib-wordmark { font-family: var(--font-heading); font-style: italic; font-weight: 600; font-size: clamp(3rem, 9vw, 4.75rem); line-height: 0.95; letter-spacing: -0.01em; color: var(--ink); } .lib-tagline { margin-top: 1.1rem; max-width: 34rem; color: var(--ink-soft); font-size: 1.02rem; line-height: 1.6; } .lib-grid { display: flex; flex-direction: column; gap: 2.75rem; } .lib-author { border-top: 1px solid var(--rule); padding-top: 1.5rem; } .lib-author-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1.1rem; } .lib-author-name { font-family: var(--font-heading); font-weight: 600; font-size: 1.65rem; color: var(--ink); } .lib-author-meta { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; } .lib-work { margin-top: 1.25rem; } .lib-work-title { font-family: var(--font-heading); font-style: italic; font-size: 1.05rem; color: var(--ink-soft); margin-bottom: 0.35rem; } .lib-text-list { list-style: none; margin: 0; padding: 0; } .lib-text-row { display: flex; align-items: baseline; gap: 0.6rem; padding: 0.32rem 0.4rem; margin-inline: -0.4rem; border-radius: var(--radius-sm); color: var(--ink); text-decoration: none; transition: background-color 120ms ease, color 120ms ease; } .lib-text-row:hover { background: var(--paper-raised); color: var(--accent-ink); } .lib-text-title { font-variant-numeric: oldstyle-nums; } .lib-leader { flex: 1 1 auto; align-self: stretch; margin-bottom: 0.35em; border-bottom: 1px dotted var(--rule); } .lib-text-scheme { font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; } .lib-footer { border-top: 1px solid var(--rule); padding: 1.1rem 1.5rem; text-align: center; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
/* ---- reader: running head ----------------------------------------- */ .reader-head { position: sticky; top: 0; z-index: 20; backdrop-filter: blur(8px); background: color-mix(in oklab, var(--paper) 82%, transparent); border-bottom: 1px solid var(--rule); } .reader-head-inner { max-width: 76rem; margin-inline: auto; height: 3.25rem; padding-inline: 1.25rem; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem; } .reader-head-left { display: flex; align-items: center; gap: 0.85rem; justify-self: start; min-width: 0; } .reader-head-right { display: flex; align-items: center; gap: 0.85rem; justify-self: end; } .reader-citation { font-family: var(--font-heading); font-size: 1rem; color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums oldstyle-nums; } .reader-head-action { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; color: var(--ink-soft); padding: 0.3rem 0.55rem; border-radius: var(--radius-sm); cursor: pointer; transition: background-color 120ms ease, color 120ms ease; } .reader-head-action:hover { background: var(--paper-raised); color: var(--accent-ink); } .reader-head-back { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.82rem; color: var(--ink-soft); text-decoration: none; transition: color 120ms ease; } .reader-head-back:hover { color: var(--accent-ink); } .reader-head-meta { display: inline-flex; align-items: center; gap: 0.6rem; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); } .reader-head-dot { width: 3px; height: 3px; border-radius: 9999px; background: var(--ink-faint); }
/* ---- reader: column + prose --------------------------------------- */ .reader-main { padding: clamp(2.25rem, 5vw, 4.5rem) 1.5rem 6rem; } .reader-column { max-width: 38rem; margin-inline: auto; } .reading { color: var(--ink); font-size: 1.155rem; line-height: 1.82; text-rendering: optimizeLegibility; font-feature-settings: "liga" 1, "calt" 1; hanging-punctuation: first allow-end; /* Tap-to-word drives our own menu (§9): suppress iOS's duplicate callout and the grey tap flash, but keep text selectable so drag-to-quote still works. */ -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; } .reading ::selection { background: var(--selection); } .reader-para { margin: 0; text-align: justify; text-justify: inter-word; hyphens: auto; } .reader-para + .reader-para { text-indent: 1.5em; } .reader-para + .reader-heading, .reader-heading + .reader-para { text-indent: 0; } /* A drop-cap paragraph is never first-line indented — even when it follows another paragraph (e.g. the lead lands after a non-letter epigraph). */ .reader-para.reader-lead { text-indent: 0; display: flow-root; /* contain the floated cap so it can't bleed into the next block */ } .reader-lead::first-letter { float: left; font-family: var(--font-heading), var(--font-sans), serif; font-weight: 600; font-size: 3.1em; line-height: 0.82; padding-right: 0.08em; margin-top: 0.06em; color: var(--accent-ink); } .reading em { font-style: italic; }
/* ---- reader: headings --------------------------------------------- */ .reader-heading { font-family: var(--font-heading); color: var(--ink); text-wrap: balance; scroll-margin-top: var(--jump-offset-nav); line-height: 1.2; } .reader-heading[data-heading-level="2"] { font-size: 1.7rem; font-weight: 600; margin: 2.75rem 0 1.1rem; } .reader-heading[data-heading-level="3"] { font-size: 1.24rem; font-weight: 600; margin: 2.1rem 0 0.85rem; } .reader-heading[data-heading-level="4"] { font-size: 1.02rem; font-weight: 600; font-style: italic; color: var(--ink-soft); margin: 1.6rem 0 0.7rem; } .reader-column > .reading > .reader-heading:first-child { margin-top: 0; }
/* ---- reader: locus anchors (invisible) ---------------------------- */ .reader-anchor { display: inline; width: 0; scroll-margin-top: var(--jump-offset-nav); }
/* ---- reader: footnotes -------------------------------------------- */ .reader-fnref { font-size: 0.66em; line-height: 0; vertical-align: super; } .reader-fnref a { color: var(--accent-ink); text-decoration: none; padding-inline: 0.12em; scroll-margin-top: var(--jump-offset); } .reader-fnref a:hover { text-decoration: underline; } .reader-apparatus { margin-top: 3.5rem; } .reader-apparatus-rule { width: 8rem; margin: 0 0 1.4rem; border: 0; border-top: 1px solid var(--rule); } .reader-footnotes { list-style: none; margin: 0; padding: 0; font-size: 0.92rem; line-height: 1.6; color: var(--ink-soft); } .reader-footnote { display: flex; gap: 0.7rem; margin-bottom: 0.7rem; scroll-margin-top: var(--jump-offset); } .reader-footnote-back { flex: none; min-width: 1.4rem; text-align: right; font-variant-numeric: tabular-nums; color: var(--accent-ink); text-decoration: none; } .reader-footnote-back:hover { text-decoration: underline; } .reader-footnote-body em { font-style: italic; }
/* ---- reader: work navigation (§2 prev/next + contents) ------------ */ .worknav { margin-top: 4rem; padding-top: 1.75rem; border-top: 1px solid var(--rule); } .worknav-pager { display: flex; justify-content: space-between; gap: 1rem; } .worknav-step { display: inline-flex; align-items: center; gap: 0.55rem; max-width: 46%; padding: 0.5rem 0.7rem; border-radius: var(--radius-sm); color: var(--ink-soft); text-decoration: none; transition: background-color 120ms ease, color 120ms ease; } .worknav-step.is-empty { visibility: hidden; } .worknav-next { text-align: end; } .worknav-step:hover { background: var(--paper-raised); color: var(--accent-ink); } .worknav-step svg { flex: none; color: var(--ink-faint); } .worknav-step:hover svg { color: var(--accent-ink); } .worknav-step-text { display: flex; flex-direction: column; min-width: 0; } .worknav-dir { font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); } .worknav-step-title { font-family: var(--font-heading); font-size: 0.96rem; color: inherit; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .worknav-contents { margin-top: 2rem; } .worknav-contents-head { font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.85rem; } .worknav-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: 0.1rem 1.5rem; list-style: none; counter-reset: none; } .worknav-item { display: flex; align-items: baseline; gap: 0.65rem; padding: 0.32rem 0.5rem; border-radius: var(--radius-sm); color: var(--ink-soft); text-decoration: none; transition: background-color 120ms ease, color 120ms ease; } a.worknav-item:hover { background: var(--paper-raised); color: var(--accent-ink); } .worknav-item.is-current { color: var(--accent-ink); font-weight: 600; } .worknav-num { flex: none; width: 1.4rem; font-size: 0.74rem; text-align: end; color: var(--ink-faint); font-variant-numeric: tabular-nums; } .worknav-item.is-current .worknav-num { color: var(--accent-ink); } .worknav-item-title { min-width: 0; }
/* ---- reader: notices (loading / error) ---------------------------- */ .reader-notice-kicker { font-size: 0.72rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.6rem; } .reader-notice-title { font-family: var(--font-heading); font-size: 1.6rem; color: var(--ink); margin-bottom: 0.6rem; } .reader-notice-body { color: var(--ink-soft); line-height: 1.6; } .reader-notice-link { display: inline-flex; align-items: center; gap: 0.4rem; margin-top: 1.4rem; color: var(--accent-ink); text-decoration: none; } .reader-notice-link:hover { text-decoration: underline; }
/* ---- reader: §2 layout (TOC | column | rail) ---------------------- */ .reader-layout { max-width: 76rem; margin-inline: auto; } .reader-aside { display: none; position: sticky; top: 3.25rem; align-self: start; max-height: calc(100svh - 3.25rem); overflow-y: auto; overscroll-behavior: contain; padding-block: 2.5rem 1.5rem; } .reader-toc-trigger { display: inline-flex; } /* collapsible desktop contents sidebar */ .reader-aside-head { display: none; /* only meaningful in the ≥1280 sidebar */ align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.85rem; } .reader-aside-title { font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-faint); } .reader-aside-collapse { display: inline-flex; padding: 0.25rem; border-radius: var(--radius-sm); color: var(--ink-faint); cursor: pointer; transition: color 120ms ease, background-color 120ms ease; } .reader-aside-collapse:hover { color: var(--accent-ink); background: var(--paper-raised); } .reader-toc-expand { display: none; /* shown only when ≥1280 + collapsed */ position: fixed; left: 0; top: 4rem; z-index: 18; align-items: center; gap: 0.4rem; padding: 0.5rem 0.7rem; font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-soft); background: var(--paper-raised); border: 1px solid var(--rule); border-left: none; border-radius: 0 var(--radius-md) var(--radius-md) 0; box-shadow: 2px 2px 14px -10px rgb(0 0 0 / 0.5); cursor: pointer; transition: color 120ms ease, background-color 120ms ease; } .reader-toc-expand:hover { color: var(--accent-ink); background: var(--paper); } @media (min-width: 1280px) { .reader-layout { display: grid; grid-template-columns: 15rem minmax(0, 1fr); column-gap: 1.5rem; } .reader-aside { display: block; } .reader-toc-trigger { display: none; } .reader-aside-head { display: flex; } /* contents collapsed → drop the TOC column, surface the edge tab. Give the reading column real side gutters so it never hugs the left edge (esp. with the side panel open, where the freed width is otherwise all on the left). */ .reader-shell.toc-collapsed .reader-layout { grid-template-columns: minmax(0, 1fr); } .reader-shell.toc-collapsed .reader-main { padding-inline: clamp(2rem, 7vw, 5rem); } .reader-shell.toc-collapsed .reader-aside-toc { display: none; } .reader-shell.toc-collapsed .reader-toc-expand { display: inline-flex; } } /* Running head: the secondary action row (Facsimile · Artifact · Markdown · account) collapses into the ⋯ overflow menu below this breakpoint so the bar stays legible on a phone (§2). Back · Contents · citation · Go to stay. */ .reader-head-inline { display: contents; } .reader-head-overflow { display: none; } @media (max-width: 768px) { .reader-head-inner { padding-inline: 0.85rem; gap: 0.5rem; } .reader-head-left { gap: 0.5rem; } .reader-head-right { gap: 0.2rem; } .reader-head-meta, .reader-head-inline { display: none; } .reader-head-overflow { display: inline-flex; } /* icon-only for the controls that stay in the bar */ .reader-head-back span, .reader-head-action span { display: none; } .reader-head-action { padding: 0.35rem; } .reader-citation { font-size: 0.92rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; } }
/* ---- reader: §4/§12 side panel (facsimile | artifact) ------------- */ .side-panel { position: fixed; top: 3.25rem; right: 0; bottom: 0; width: 100vw; max-width: 32rem; z-index: 15; display: flex; flex-direction: column; background: var(--paper-raised); border-left: 1px solid var(--rule); box-shadow: -8px 0 24px -16px rgb(0 0 0 / 0.4); } .side-panel-resize { display: none; } @media (min-width: 1280px) { /* Offset only the reading body for the side panel — the header stays full-width across the top of the panel (not resized when it opens). */ .reader-shell.has-panel .reader-body { padding-right: var(--panel-w, clamp(20rem, 30vw, 32rem)); } .side-panel { width: var(--panel-w, clamp(20rem, 30vw, 32rem)); max-width: 80vw; } .side-panel-resize { display: block; position: absolute; left: 0; top: 0; bottom: 0; width: 8px; cursor: ew-resize; touch-action: none; } .side-panel-resize::after { content: ""; position: absolute; left: 3px; top: 0; bottom: 0; width: 2px; background: transparent; transition: background-color 120ms ease; } .side-panel-resize:hover::after { background: var(--accent-ink); } } body.is-resizing { cursor: ew-resize; user-select: none; } .side-panel-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--rule); } .side-panel-head-right { display: inline-flex; align-items: center; gap: 0.5rem; } .facsimile-zoom { display: inline-flex; align-items: center; gap: 0.1rem; border: 1px solid var(--rule); border-radius: var(--radius-sm); padding: 0.1rem; } .facsimile-zoom-btn { display: inline-flex; padding: 0.2rem; border-radius: calc(var(--radius-sm) - 1px); color: var(--ink-soft); cursor: pointer; } .facsimile-zoom-btn:hover:not(:disabled) { background: var(--paper); color: var(--accent-ink); } .facsimile-zoom-btn:disabled { opacity: 0.4; cursor: default; } .facsimile-zoom-level { min-width: 3rem; font-size: 0.72rem; font-variant-numeric: tabular-nums; color: var(--ink-soft); cursor: pointer; } .facsimile-zoom-level:hover { color: var(--accent-ink); } .side-panel-title { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); } .side-panel-tabs { display: inline-flex; gap: 0.25rem; } .side-panel-tab { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.78rem; padding: 0.25rem 0.55rem; border-radius: var(--radius-sm); color: var(--ink-soft); cursor: pointer; } .side-panel-tab.is-active { background: var(--paper); color: var(--accent-ink); } .side-panel-close { display: inline-flex; padding: 0.25rem; border-radius: var(--radius-sm); color: var(--ink-soft); cursor: pointer; } .side-panel-close:hover { background: var(--paper); color: var(--accent-ink); } .side-panel-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; } .side-pane-scroll { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding: 1rem; } /* back-to-list link above a single artifact in the pane (§12) */ .artifact-back { display: inline-flex; align-items: center; gap: 0.2rem; margin-bottom: 0.6rem; padding: 0.2rem 0.4rem 0.2rem 0.2rem; border-radius: var(--radius-sm); font-size: 0.78rem; color: var(--ink-faint); cursor: pointer; transition: color 120ms ease, background-color 120ms ease; } .artifact-back:hover { color: var(--accent-ink); background: var(--paper); } .facsimile-viewport { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding: 0.75rem; cursor: grab; } .facsimile-viewport.is-panning { cursor: grabbing; } .facsimile-figure { margin: 0; } .facsimile-img, .facsimile-canvas { display: block; width: 100%; /* Override Tailwind preflight's `img { max-width: 100% }`, which otherwise caps the image at the pane width and makes zoom a no-op. */ max-width: none; height: auto; border-radius: var(--radius-sm); border: 1px solid var(--rule); background: #fff; } .facsimile-canvas[data-ready="false"] { display: none; } .facsimile-caption { margin-top: 0.5rem; text-align: center; font-size: 0.75rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; } .facsimile-pdf { min-height: 6rem; } .facsimile-status { display: flex; align-items: center; gap: 0.4rem; padding: 1rem 0; font-size: 0.85rem; color: var(--ink-soft); }
/* artifact pane (§12) */ .artifact { display: flex; flex-direction: column; gap: 0.85rem; } .artifact-citation { font-family: var(--font-heading); font-size: 0.85rem; color: var(--ink-soft); font-variant-numeric: tabular-nums oldstyle-nums; } .artifact-section { display: flex; flex-direction: column; gap: 0.35rem; padding-bottom: 0.85rem; border-bottom: 1px solid var(--rule); }
/* artifacts-by-locus right-click list (§12) */ .locus-menu { display: flex; flex-direction: column; min-width: 14rem; max-width: 22rem; } .locus-empty { font-size: 0.85rem; color: var(--ink-soft); padding: 0.4rem 0.2rem; } .locus-item { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.4rem 0.5rem; border-radius: var(--radius-sm); cursor: pointer; text-align: start; } .locus-item:hover { background: var(--paper); } .locus-quote { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.9rem; color: var(--ink); } .locus-badges { flex: none; display: inline-flex; gap: 0.3rem; color: var(--ink-faint); }
/* ---- reader: table of contents ------------------------------------ */ .toc-heading { font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 0.75rem; padding-inline-start: 0.5rem; } .toc-list { list-style: none; margin: 0; padding: 0; } .toc-row { display: flex; align-items: flex-start; gap: 0.1rem; } .toc-caret { flex: none; margin-top: 0.34rem; color: var(--ink-faint); cursor: pointer; } .toc-caret svg { transition: transform 150ms ease; } .toc-caret[data-state="open"] svg { transform: rotate(90deg); } .toc-link { width: 100%; text-align: start; font-size: 0.84rem; line-height: 1.35; color: var(--ink-soft); padding: 0.28rem 0.4rem; border-radius: var(--radius-sm); cursor: pointer; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; transition: background-color 120ms ease, color 120ms ease; } .toc-link:hover { color: var(--accent-ink); background: var(--paper-raised); } .toc-active { color: var(--ink); font-weight: 600; }
/* ---- reader: browse bar (§2, perseus-style minimap) --------------- */ /* Nav jumps (loci / headings) and the scroll tracker must clear the sticky header (3.25rem) + this bar, whose height is published as --browse-bar-h. */ .reader-shell { --jump-offset-nav: calc(3.25rem + var(--browse-bar-h, 0px) + 0.85rem); } .browse-bar { position: sticky; top: 3.25rem; z-index: 12; max-width: 76rem; margin-inline: auto; padding: 0.5rem 1.25rem 0.6rem; display: flex; flex-direction: column; gap: 0.3rem; background: color-mix(in oklab, var(--paper) 85%, transparent); backdrop-filter: blur(8px); border-bottom: 1px solid var(--rule); } .browse-readout { margin: 0 0 0.1rem; min-height: 1rem; font-size: 0.68rem; letter-spacing: 0.02em; color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .browse-readout-strong { color: var(--accent-ink); font-weight: 600; } .browse-tier { display: grid; grid-template-columns: 4.8rem minmax(0, 1fr); align-items: center; gap: 0.6rem; } .browse-tier-label { font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .browse-track { display: flex; height: 0.85rem; border-radius: var(--radius-sm); overflow: hidden; } .browse-seg { flex: 0 1 0; min-width: 2px; height: 100%; border: 0; padding: 0; cursor: pointer; background: color-mix(in oklab, var(--ink) 13%, var(--paper)); transition: background-color 100ms ease; } .browse-seg.is-odd { background: color-mix(in oklab, var(--ink) 22%, var(--paper)); } .browse-seg:hover { background: color-mix(in oklab, var(--accent-ink) 45%, var(--paper)); } .browse-seg.is-active { background: var(--accent-ink); }
/* ---- reader: Go To ------------------------------------------------- */ .reader-goto-label { font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); } .reader-goto-error { margin-top: 0.45rem; font-size: 0.78rem; color: var(--destructive); }
/* ---- reader: selection menu (§9) ---------------------------------- */ .sel-pop { width: auto; padding: 0; gap: 0; } .sel-pop-actions { min-width: 18rem; max-width: 27rem; } .sel-pop-gloss { width: 24rem; max-width: 92vw; max-height: var(--radix-popover-content-available-height); overflow-y: auto; overscroll-behavior: contain; } .sel-menu { display: flex; flex-direction: column; padding: 0.3rem; } .sel-item { display: flex; align-items: center; gap: 0.6rem; width: 100%; padding: 0.5rem 0.6rem; border-radius: var(--radius-sm); font-size: 0.86rem; color: var(--ink); cursor: pointer; text-align: start; transition: background-color 110ms ease, color 110ms ease; } .sel-item:hover:not(:disabled), .sel-item:focus-visible:not(:disabled) { background: var(--paper-raised); color: var(--accent-ink); outline: none; } .sel-item:disabled { color: var(--ink-faint); cursor: not-allowed; opacity: 0.65; } .sel-item svg { flex: none; color: var(--ink-faint); } .sel-item:hover:not(:disabled) svg { color: var(--accent-ink); } .sel-item-label { flex: 1 1 auto; } .sel-item-key { flex: none; font-size: 0.7rem; letter-spacing: 0.04em; color: var(--ink-faint); font-variant-numeric: tabular-nums; } .sel-sep { height: 1px; margin: 0.3rem 0.4rem; background: var(--rule); } /* arg-max translation hint, below Read aloud (§5+). A single word sits inline (Welt → world); a long phrase wraps so the translation drops to its own full-width line instead of collapsing into a one-word-per-line column. */ .sel-xlate { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.45rem; margin: 0.35rem 0.3rem 0.1rem; padding: 0.6rem 0.6rem 0.35rem; border-top: 1px solid var(--rule); font-size: 0.92rem; line-height: 1.4; } .sel-xlate-lang { flex: none; font-size: 0.78rem; font-style: italic; color: var(--accent-ink); } .sel-xlate-word { flex: 0 1 auto; min-width: 0; color: var(--ink-soft); } .sel-xlate-arrow { flex: none; color: var(--ink-faint); } .sel-xlate-value { flex: 1 1 auto; min-width: 0; color: var(--ink); } .sel-xlate-count { flex: none; font-size: 0.68rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
/* engagement gate — match the word to reveal the consensus gloss (§13) */ .sel-gate { margin: 0.35rem 0.3rem 0.1rem; padding: 0.6rem 0.6rem 0.5rem; border-top: 1px solid var(--rule); } .sel-gate-prompt { font-size: 0.76rem; color: var(--ink-faint); margin-bottom: 0.45rem; } .sel-gate-options { display: flex; flex-wrap: wrap; gap: 0.4rem; } .sel-gate-chip { padding: 0.3rem 0.55rem; border: 1px solid var(--rule); border-radius: var(--radius-sm); font-size: 0.9rem; color: var(--ink); cursor: pointer; /* Each chip fades up on mount — and again on every reshuffle, since the new round re-keys them into fresh elements (§13). */ animation: wd-fade-up 0.34s cubic-bezier(0.34, 1.56, 0.64, 1) both; transition: background-color 110ms ease, color 110ms ease, border-color 110ms ease; } .sel-gate-chip:hover:not(:disabled), .sel-gate-chip:focus-visible:not(:disabled) { background: var(--paper-raised); color: var(--accent-ink); border-color: var(--accent-ink); outline: none; } /* Wrong pick: shake the row (light first, harder on repeats), then fade it out before the fresh set fades back in — sara-drawer style (§13). */ .sel-gate-options.shake-light { animation: wd-shake-light 0.5s ease; } .sel-gate-options.shake-hard { animation: wd-shake-hard 0.5s ease; } .sel-gate-options.is-fading { opacity: 0; transition: opacity 0.26s ease; } @keyframes wd-shake-light { 0%, 100% { transform: translateX(0); } 15% { transform: translateX(-6px); } 30% { transform: translateX(6px); } 45% { transform: translateX(-4px); } 60% { transform: translateX(4px); } 75% { transform: translateX(-2px); } 90% { transform: translateX(2px); } } @keyframes wd-shake-hard { 0%, 100% { transform: translateX(0) rotate(0deg); } 12% { transform: translateX(-10px) rotate(-1deg); } 25% { transform: translateX(10px) rotate(1deg); } 37% { transform: translateX(-8px) rotate(-1deg); } 50% { transform: translateX(8px) rotate(1deg); } 62% { transform: translateX(-5px) rotate(0deg); } 75% { transform: translateX(5px) rotate(0deg); } 87% { transform: translateX(-2px) rotate(0deg); } } @keyframes wd-fade-up { 0% { opacity: 0; transform: translateY(10px); } 100% { opacity: 1; transform: translateY(0); } } @media (prefers-reduced-motion: reduce) { .sel-gate-chip, .sel-gate-options.shake-light, .sel-gate-options.shake-hard { animation: none; } }
/* ---- reader: gloss / translate / read-aloud popover (§5/§10) ------ */ .gloss { display: flex; flex-direction: column; gap: 0.6rem; padding: 0.85rem 1rem 0.95rem; } .gloss-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; } .gloss-tabs { display: flex; gap: 0.1rem; margin-inline-start: -0.25rem; } .gloss-tab { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.25rem 0.45rem; border-radius: var(--radius-sm); font-size: 0.74rem; color: var(--ink-faint); cursor: pointer; transition: background-color 110ms ease, color 110ms ease; } .gloss-tab svg { color: currentColor; } .gloss-tab > span { display: none; } .gloss-tab.is-active > span { display: inline; } .gloss-tab:hover:not(.is-active) { color: var(--ink-soft); } .gloss-tab.is-active { background: var(--paper-raised); color: var(--accent-ink); } .gloss-citation { font-family: var(--font-heading); font-size: 0.82rem; color: var(--ink-soft); font-variant-numeric: tabular-nums oldstyle-nums; white-space: nowrap; } .gloss-quote { font-size: 1.05rem; line-height: 1.5; color: var(--ink); } .gloss-body { display: flex; flex-direction: column; gap: 0.4rem; min-height: 1.6rem; } .gloss-result-row { display: flex; align-items: start; justify-content: space-between; gap: 0.5rem; } .gloss-result { font-size: 0.92rem; line-height: 1.55; color: var(--ink); } .gloss-copy { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 1.6rem; height: 1.6rem; margin-top: -0.1rem; border-radius: var(--radius-sm); color: var(--ink-faint); cursor: pointer; transition: background-color 110ms ease, color 110ms ease; } .gloss-copy:hover { background: var(--paper-raised); color: var(--accent-ink); } .gloss-literal { font-size: 0.84rem; line-height: 1.7; font-style: italic; color: var(--ink-soft); } .gloss-tok { border-bottom: 1px dotted var(--ink-faint); cursor: help; outline: none; transition: color 110ms ease, border-color 110ms ease; } .gloss-tok:hover, .gloss-tok:focus-visible { color: var(--accent-ink); border-bottom-color: var(--accent-ink); } .gloss-tip { font-size: 0.9rem; font-style: normal; } .gloss-pos { font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-faint); } .gloss-status { display: inline-flex; align-items: center; gap: 0.45rem; font-size: 0.84rem; color: var(--ink-soft); } .gloss-error { display: flex; flex-direction: column; align-items: start; gap: 0.4rem; font-size: 0.82rem; color: var(--destructive); } .gloss-error-line { font-size: 0.78rem; color: var(--destructive); } .gloss-retry { padding: 0.25rem 0.6rem; border: 1px solid var(--rule); border-radius: var(--radius-sm); font-size: 0.8rem; color: var(--ink); cursor: pointer; } .gloss-retry:hover { background: var(--paper-raised); color: var(--accent-ink); } .gloss-tts { display: inline-flex; align-items: center; gap: 0.45rem; align-self: start; padding: 0.4rem 0.7rem; border: 1px solid var(--rule); border-radius: var(--radius-sm); font-size: 0.84rem; color: var(--ink-soft); cursor: pointer; transition: background-color 110ms ease, color 110ms ease; } .gloss-tts:hover:not(:disabled) { background: var(--paper-raised); color: var(--accent-ink); } .gloss-tts[data-state="playing"] { border-color: var(--accent-ink); color: var(--accent-ink); } .gloss-tts:disabled { cursor: default; } .gloss-pending { font-size: 0.78rem; line-height: 1.5; color: var(--ink-faint); } .gloss-key-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; } .gloss-key { font-size: 0.68rem; letter-spacing: 0.06em; color: var(--ink-faint); font-variant-numeric: tabular-nums; } .gloss-sharelink { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.7rem; color: var(--ink-soft); padding: 0.15rem 0.35rem; border-radius: var(--radius-sm); cursor: pointer; } .gloss-sharelink:hover { color: var(--accent-ink); background: var(--paper-raised); } .gloss-xlate { margin-top: 0.5rem; font-size: 0.92rem; color: var(--ink); } .gloss-xlate-label { font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); margin-inline-end: 0.4rem; } .gloss-xlate-consensus { color: var(--ink-soft); } .gloss-xlate-note { display: block; margin-top: 0.15rem; font-size: 0.68rem; color: var(--ink-faint); }
/* ---- reader: §7 correction editor --------------------------------- */ .correction { display: flex; flex-direction: column; gap: 0.6rem; min-width: 16rem; } .correction-head { font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); } .correction-before { font-size: 0.95rem; color: var(--ink-soft); text-decoration: line-through; text-decoration-color: var(--ink-faint); } .correction-input { width: 100%; resize: vertical; font: inherit; font-size: 0.95rem; color: var(--ink); background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-sm); padding: 0.45rem 0.55rem; } .correction-input:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; } .correction-actions { display: flex; justify-content: flex-end; gap: 0.5rem; } .correction-cancel, .correction-save { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; padding: 0.3rem 0.7rem; border-radius: var(--radius-sm); cursor: pointer; } .correction-cancel { color: var(--ink-soft); } .correction-cancel:hover { color: var(--accent-ink); } .correction-save { background: var(--accent-ink); color: var(--paper); } .correction-save:disabled { opacity: 0.5; cursor: default; }}