diff --git a/404.html b/404.html index c61b0ce..8c8ecc1 100644 --- a/404.html +++ b/404.html @@ -1,5 +1,5 @@ - +
diff --git a/README.md b/README.md index afd3ac9..80fda40 100644 --- a/README.md +++ b/README.md @@ -24,52 +24,39 @@ ## 🇮🇱 עברית ### 📖 אודות האתר והקונספט -ריפו זה מכיל את קוד המקור של אתר התדמית וההדגמה הרשמי של **TypesetOK (TOK)** — מפרט ארכיטקטוני ותשתית מחקר בקוד פתוח לעימוד ופרסום שולחני (DTP) לטיפוגרפיה עברית מתקדמת, ספרי קודש (ש"ס, מקראות גדולות ושו"ת) ומסמכי ענק. -פותח ומוביל: **[Amlaach](https://amlaach.github.io/personal-site/)**. +ריפו זה מכיל את קוד המקור של אתר התדמית וההורדה הרשמי של **TypesetOK (TOK)** — מפרט ארכיטקטוני ותוכנת עימוד שולחני (DTP) בקוד פתוח לטיפוגרפיה עברית מתקדמת, ספרי קודש (ש"ס, מקראות גדולות ושו"ת) ומסמכי ענק. -האתר עוצב ותוכנת לפי קונספט **Editorial Technology** — ממשק אינטראקטיבי המעביר את תחושת הטיפוגרפיה והעימוד החי דרך החוויה עצמה, ללא הסתמכות על דפי נחיתה שיווקיים גנריים. האתר מותאם להרצה מלאה כאתר סטטי ב-**GitHub Pages**, כולל תמיכה ב-4 שפות (עברית, אנגלית, ספרדית, צרפתית), מצב כהה כברירת מחדל, וסרגל נגישות מקיף (WCAG 2.2 AA). +האתר עוצב ותוכנת לפי קונספט **Editorial Technology** — ממשק ענייני ומדויק עבור מעמדים ומוציאים לאור, המתמקד בפרקטיקה של עולם העימוד (נייר, רשתות קווי בסיס, תקני דפוס וייצוא PDF/X-1a). האתר מותאם להרצה מלאה כאתר סטטי ב-**GitHub Pages**, כולל תמיכה ב-4 שפות (עברית, אנגלית, ספרדית, צרפתית), מצב יום (נייר) כברירת מחדל יחד עם תמיכה במצב מערכת ומצב לילה, וכפתור הורדה צף ונגיש. --- -### 🌟 רכיבים אינטראקטיביים מרכזיים +### 🌟 רכיבים מרכזיים באתר -1. **לוח הגהה מונוגרפי ב-Hero (Editorial Monograph Specimen):** - * תצוגת מופת דפוס חיה של פרק א' במשנה (ברכות), משולבת קווי ייחוס טיפוגרפיים, נרמול ת"י 6100 ואיזון שורות. - * מתג גריד ייעודי לבחינת קווי היסוד הדפוסאיים. +1. **מרכז הורדות ראשי וכפתור צף (Download Hub):** + * הורדה ישירה של הגרסה העדכנית ביותר (v0.6.0) מ-GitHub Releases: גרסה ניידת ללא התקנה (Portable ZIP), מתקין שולחני וכלי שורת פקודה (CLI). + * כפתור הורדה חכם ההופך לרכיב צף (Sticky Widget) בצד המסך בעת גלילה מעבר לחלק העליון. -2. **גלילת סיפור טיפוגרפי (Scroll Storytelling):** - * **סצנה 1:** נרמול קפדני לפי תקן ישראלי ת"י 6100 וגימטריה דטרמיניסטית (15 $\rightarrow$ ט״ו, 16 $\rightarrow$ ט״ז). - * **סצנה 2:** פותר אילוצים רב-תזרימי (Talmud Solver) לעמודי ש"ס ומקראות גדולות (גמרא, רש"י ותוספות). - * **סצנה 3:** קדם-דפוס נייטיב ISO 15930 (PDF/X-1a) עם שחור 100% K DeviceCMYK, פרופיל Fogra 39 וטבלאות `/ToUnicode`. +2. **השוואה מעשית מול וורד ואינדיזיין (Head-to-Head Matrix):** + * טבלת השוואה עניינית ומעשית של התמודדות מול מסמכי ענק (500+ עמודים), ניקוד וטעמים, ספרי קודש ומפרשים מרובים, יישור בלוק הטקסט וייצוא קדם-דפוס. -3. **מעבדת עימוד אינטראקטיבית (Typography Playground):** - * שליטה בזמן אמת בגודל אות, רווח שורות (Leading), חלוקת טורים, רווח בין טורים, ומדרג יישור עברי (אהלתר"ם). - * סרגלי מידה מדויקים (מילימטרים / A4) ומתג לרשת קווי בסיס (Baseline Grid). +3. **קולות מהשטח — ציטוטים מפורומי מעמדים:** + * אתגרים אמיתיים ומצוקות מפורומי מעמדים (פרוג, פורום לתורה, איגודי דפוס) והמענה המבני של TypesetOK עבורם. 4. **סליידר השוואה לפני/אחרי (Before / After Comparison):** - * השוואה ויזואלית בין מעבד תמלילים רגיל (וורד) לבין בלוק העימוד המהודק של TypesetOK. - * כפתורי Presets מהירים (Word / 50% / TypesetOK), תמיכה במגע, עכבר ומקלדת (מקשי חצים, Home/End) בשפות RTL ו-LTR. + * השוואה ויזואלית חיה בין פלט מעבד תמלילים פשוט לבין בלוק העימוד המהודק והמאוזן של TypesetOK. -5. **הדמיית סביבת עבודה שולחנית (Product Workbench Preview):** - * עץ צמתים סמנטי (TDM Node Tree) המעדכן מאפייני אלמנטים בזמן אמת. - * סמן וירטואלי ברינדור 120 FPS ופאנל בדיקות קדם-דפוס חי (Live Preflight). +5. **שבעת עמודי התווך (Bento Grid):** + * ליבת Rust עצמאית ווירטואליזציה (3 עמודים פעילים), ת״י 6100, יישור תלת-שלבי (Knuth-Plass), פותר אילוצים רב-תזרימי, קדם-דפוס ISO 15930, ומסד נתונים פנימי עמיד קריסות (ACID WAL). -6. **Bento Grid חכם ליכולות המערכת:** - * 7 כרטיסיות אסימטריות המפרטות את הארכיטקטורה: Rust Core, SI 6100, 3-Tier Justification, Multi-Flow, Prepress, ACID WAL Storage, Holy Name Guardian. - -7. **צינור זרימת העבודה (Pipeline with Progressive Disclosure):** - * 5 שלבי עימוד אינטראקטיביים עם מפרט טכני מתרחב בלחיצה. - -8. **לוח בנצ'מרק ובדיקות אמת מאומתות:** - * נתונים אמיתיים מתוך ריפו ה-Rust (58/58 בדיקות עוברות, Clippy 0 אזהרות, דטרמיניזם ביט-אחר-ביט, עמידה במבחן עומס של 1,000 עמודים). +6. **שקיפות הנדסית ואימות נתונים:** + * תוצאות בדיקות אמת במאגר הקוד של הליבה (58/58 בדיקות עוברות, 0 אזהרות Clippy, דטרמיניזם ביט-אחר-ביט, עמידה במבחן עומס של 1,000 עמודים). --- ### ♿ נגישות (WCAG 2.2 AA) וביצועים (Core Web Vitals) -* **ניווט מקלדת מלא:** קישור Skip Link, חיווי `:focus-visible` בולט, וסמנטיקת ARIA מלאה. -* **הפחתת תנועה (Reduced Motion):** תמיכה בהעדפת מערכת הפעלה (`prefers-reduced-motion`) לצד מתג ידני עליון באתר הנשמר ב-`localStorage`. -* **מתג רשת גריד טיפוגרפית:** אפשרות להפעיל/לכבות שכבת גריד ועזרי מדידה בכל רחבי האתר. +* **מצבי תצוגה מורחבים:** ברירת מחדל של מצב יום (Editorial Paper), עם אפשרות למצב לילה ומצב מערכת אוטומטי (Auto/System). +* **ניווט מקלדת מלא:** תמיכה מלאה בתקני נגישות, דילוג לתוכן מרכזי (Skip Link), ופוקוס ברור. * **אפס תלויות כבדות:** קוד Vanilla JS ו-CSS מודולרי ללא ספריות ענק (LCP $\le$ 1.2s, INP $\le$ 50ms, CLS = 0). --- @@ -91,10 +78,9 @@ python -m http.server 8000 ## 🇺🇸 English ### 📖 About -This repository contains the source code for the official website and interactive showcase of **TypesetOK (TOK)** — an open-source architectural specification and research foundation for desktop publishing (DTP) dedicated to advanced Hebrew typography, sacred texts (Talmud, Mikraot Gedolot, Responsa), and large-scale manuscripts. -Lead Developer: **[Amlaach](https://amlaach.github.io/personal-site/)**. +This repository contains the source code for the official website and download portal of **TypesetOK (TOK)** — an open-source desktop publishing system (DTP) dedicated to advanced Hebrew typography, sacred texts (Talmud, Mikraot Gedolot, Responsa), and large-scale manuscripts. -The site is designed under the **Editorial Technology** concept, turning the physical world of typography, baseline grids, and pre-press standards into an interactive, accessible digital surface. It is fully static, deployed directly to **GitHub Pages**, with dark mode as default, 4 languages (Hebrew, US English, Spanish, French), and an accessible toolbar (WCAG 2.2 AA). +The site is designed under the **Editorial Technology** concept, turning the physical world of typography, baseline grids, and pre-press standards into an accessible digital surface. It is fully static, deployed directly to **GitHub Pages**, with editorial light mode as default (with System and Dark options), 4 languages (Hebrew, US English, Spanish, French), an accessible toolbar (WCAG 2.2 AA), and a smooth floating download widget. --- @@ -115,7 +101,7 @@ The site is designed under the **Editorial Technology** concept, turning the phy ``` website/ ├── index.html # Semantic HTML5 Master Document (i18n & Schema.org) -├── 404.html # Custom Accessible 404 Page (Dark mode default) +├── 404.html # Custom Accessible 404 Page (Light mode default) ├── .nojekyll # Disables Jekyll processing on GitHub Pages ├── site.webmanifest # Web App Manifest ├── robots.txt # Search Engine Crawler Directives @@ -132,21 +118,19 @@ website/ │ └── assets/ ├── images/ - │ ├── logo.jpg # TypesetOK Brand Logo (Open Book + OK) - │ └── favicon.svg # Crisp Vector Favicon + │ ├── logo.jpg # TypesetOK Brand Logo + │ └── favicon.svg # Vector Favicon ├── css/ - │ ├── tokens.css # Design Tokens (Colors, Typography, Dark Default) + │ ├── tokens.css # Design Tokens (Colors, Typography, Light Default) │ ├── reset.css # Accessible RTL Reset │ ├── main.css # Editorial Grid & Layout Primitives │ ├── components.css # Interactive Modules & Demos (Fluid mobile-safe) │ └── a11y-motion.css # WCAG 2.2 AA Toolbar & Reduced Motion Overrides └── js/ - ├── main.js # Navigation, Observers & Modals + ├── main.js # Navigation, Observers, Downloads & Modals ├── i18n.js # Multi-lingual Engine (HE, EN, ES, FR) - ├── a11y.js # Universal Accessibility Controller (12 features) - ├── playground.js # Interactive Typography Playground - ├── before-after.js # Accessible Fluid Comparison Slider & Presets - └── workbench.js # Desktop Workbench & TDM Inspector + ├── a11y.js # Universal Accessibility Controller & Theme Engine + └── before-after.js # Accessible Fluid Comparison Slider & Presets ``` --- diff --git a/assets/css/components.css b/assets/css/components.css index 969ba89..8f01d3a 100644 --- a/assets/css/components.css +++ b/assets/css/components.css @@ -87,107 +87,324 @@ } /* -------------------------------------------------------------------------- - HERO ARCHITECTURAL MONOGRAPH PLATE (Authentic & Professional) + THEME SELECTOR DROPDOWN (Light, Dark, System) -------------------------------------------------------------------------- */ -.hero-monograph-plate { +.theme-selector-wrapper { + position: relative; + display: inline-block; +} + +.theme-menu-popover { + position: absolute; + top: calc(100% + 8px); + right: 0; + background-color: var(--color-bg-elevated); + border: 1px solid var(--color-border-medium); + border-radius: var(--radius-md); + box-shadow: var(--shadow-floating); + min-width: 180px; + padding: 6px; + display: none; + flex-direction: column; + gap: 2px; + z-index: var(--z-sticky); +} + +[dir="ltr"] .theme-menu-popover { + right: auto; + left: 0; +} + +.theme-menu-popover.open { + display: flex; +} + +.theme-menu-item { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 12px; + font-size: 13px; + font-weight: 500; + color: var(--color-ink-primary); + border-radius: var(--radius-xs); + background: transparent; + border: none; + cursor: pointer; + width: 100%; + text-align: right; + transition: all var(--motion-fast); +} + +[dir="ltr"] .theme-menu-item { + text-align: left; +} + +.theme-menu-item:hover { + background-color: var(--color-brand-blue-light); + color: var(--color-brand-blue-hover); +} + +.theme-menu-item.active { + background-color: var(--color-brand-blue-light); + color: var(--color-brand-blue-hover); + font-weight: 700; +} + +.theme-menu-item .theme-check-icon { + margin-right: auto; + opacity: 0; +} + +[dir="ltr"] .theme-menu-item .theme-check-icon { + margin-right: 0; + margin-left: auto; +} + +.theme-menu-item.active .theme-check-icon { + opacity: 1; +} + +/* -------------------------------------------------------------------------- + HERO DOWNLOAD HUB (Centerpiece for Typesetters) + -------------------------------------------------------------------------- */ +.hero-download-card { background-color: var(--color-bg-paper); border: 1px solid var(--color-border-medium); border-radius: var(--radius-lg); box-shadow: var(--shadow-floating); - position: relative; - overflow: hidden; padding: var(--space-6); display: flex; flex-direction: column; + gap: var(--space-5); + position: relative; + overflow: hidden; } -.monograph-header { +.hero-download-header { display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--color-border-subtle); padding-bottom: var(--space-3); - margin-bottom: var(--space-4); +} + +.hero-download-badge { + display: inline-flex; + align-items: center; + gap: 6px; font-family: var(--font-mono); font-size: 11px; - color: var(--color-ink-muted); + font-weight: 700; + color: var(--color-brand-blue-hover); + background: var(--color-brand-blue-light); + padding: 4px 10px; + border-radius: var(--radius-pill); + border: 1px solid rgba(29, 99, 237, 0.2); } -.monograph-logo-wrap { +.hero-download-os { display: flex; align-items: center; - gap: var(--space-2); + gap: 6px; + font-size: 13px; + font-weight: 700; + color: var(--color-ink-primary); } -.monograph-page-sheet { - background: var(--color-bg-surface); - border: 1px solid var(--color-border-subtle); - border-radius: var(--radius-sm); - padding: var(--space-6); - position: relative; - box-shadow: var(--shadow-subtle); - transition: all var(--motion-normal); +.download-cta-stack { + display: flex; + flex-direction: column; + gap: var(--space-3); } -.monograph-page-sheet.show-grid { - background-image: linear-gradient(to bottom, rgba(59, 130, 246, 0.08) 1px, transparent 1px); - background-size: 100% 22px; +.btn-download-primary { + display: flex; + align-items: center; + justify-content: center; + gap: 14px; + background: linear-gradient(135deg, #1D63ED, #1551CA); + color: #FFFFFF !important; + padding: 16px 22px; + border-radius: var(--radius-md); + font-size: 16px; + font-weight: 700; + text-decoration: none; + box-shadow: 0 4px 16px rgba(29, 99, 237, 0.35); + transition: all var(--motion-fast); + border: 1px solid rgba(255, 255, 255, 0.15); + cursor: pointer; + text-align: right; } -.monograph-sheet-header { - text-align: center; - font-family: var(--font-serif); - font-size: var(--font-size-base); +[dir="ltr"] .btn-download-primary { + text-align: left; +} + +.btn-download-primary:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(29, 99, 237, 0.45); + background: linear-gradient(135deg, #256DF5, #1757D8); +} + +.btn-download-text-group { + display: flex; + flex-direction: column; +} + +.btn-download-title { + font-size: 17px; font-weight: 800; - color: var(--color-brand-blue-hover); - margin-bottom: var(--space-4); - border-bottom: 2px solid var(--color-brand-blue); - padding-bottom: var(--space-2); + line-height: 1.2; } -.monograph-sheet-body { - font-family: var(--font-serif); - font-size: 16px; - line-height: 1.65; +.btn-download-subtitle { + font-size: 12px; + font-weight: 400; + opacity: 0.9; + margin-top: 2px; +} + +.btn-download-secondary { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + background-color: var(--color-bg-subtle); color: var(--color-ink-primary); - text-align: justify; - text-justify: inter-word; + border: 1px solid var(--color-border-medium); + padding: 12px 18px; + border-radius: var(--radius-md); + font-size: 14px; + font-weight: 600; + text-decoration: none; + transition: all var(--motion-fast); + cursor: pointer; } -.monograph-sheet-body .expand-letter { - color: var(--color-accent-gold); - font-weight: 700; - letter-spacing: 0.1em; +.btn-download-secondary:hover { + background-color: var(--color-bg-elevated); + border-color: var(--color-brand-blue); + color: var(--color-brand-blue-hover); } -.monograph-sheet-footer { - margin-top: var(--space-4); - padding-top: var(--space-3); +.download-extra-options { border-top: 1px solid var(--color-border-subtle); + padding-top: var(--space-3); display: flex; + flex-direction: column; + gap: 8px; + font-size: 12px; + color: var(--color-ink-secondary); +} + +.download-extra-links { + display: flex; + flex-wrap: wrap; align-items: center; - justify-content: space-between; - font-family: var(--font-mono); + gap: 10px; + font-size: 12px; +} + +.download-extra-link { + color: var(--color-brand-blue-hover); + text-decoration: none; + font-weight: 500; + display: inline-flex; + align-items: center; + gap: 4px; + transition: color var(--motion-fast); +} + +.download-extra-link:hover { + text-decoration: underline; +} + +.download-meta-notes { + display: flex; + align-items: center; + gap: 12px; font-size: 11px; color: var(--color-ink-muted); + font-family: var(--font-mono); + flex-wrap: wrap; } -.monograph-toggle-grid { - font-size: 11px; - padding: 4px 10px; - border-radius: var(--radius-xs); +/* -------------------------------------------------------------------------- + FLOATING STICKY DOWNLOAD BUTTON (Smooth Transition on Scroll) + -------------------------------------------------------------------------- */ +.floating-download-widget { + position: fixed; + bottom: 24px; + left: 24px; + z-index: var(--z-sticky); + display: flex; + align-items: center; + gap: 8px; + background-color: var(--color-bg-paper); border: 1px solid var(--color-border-medium); - background: var(--color-bg-subtle); - color: var(--color-ink-secondary); - cursor: pointer; - transition: all var(--motion-fast); + border-radius: var(--radius-pill); + padding: 6px 16px 6px 6px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.22); + backdrop-filter: blur(12px); + opacity: 0; + transform: translateY(24px) scale(0.95); + pointer-events: none; + transition: opacity 320ms cubic-bezier(0.16, 1, 0.3, 1), + transform 320ms cubic-bezier(0.16, 1, 0.3, 1); } -.monograph-toggle-grid:hover, -.monograph-toggle-grid.active { - background: var(--color-brand-blue-light); +[dir="ltr"] .floating-download-widget { + left: auto; + right: 24px; + padding: 6px 6px 6px 16px; +} + +.floating-download-widget.active { + opacity: 1; + transform: translateY(0) scale(1); + pointer-events: auto; +} + +.floating-download-widget:hover { + box-shadow: 0 12px 36px rgba(29, 99, 237, 0.28); border-color: var(--color-brand-blue); - color: var(--color-brand-blue-hover); +} + +.floating-dl-btn { + display: inline-flex; + align-items: center; + gap: 8px; + background: var(--color-brand-blue); + color: #FFFFFF !important; + padding: 8px 16px; + border-radius: var(--radius-pill); + font-size: 13px; + font-weight: 700; + text-decoration: none; + transition: background var(--motion-fast); +} + +.floating-dl-btn:hover { + background: var(--color-brand-blue-hover); +} + +.floating-dl-info { + display: flex; + flex-direction: column; +} + +.floating-dl-title { + font-size: 13px; + font-weight: 700; + color: var(--color-ink-primary); + line-height: 1.1; +} + +.floating-dl-version { + font-family: var(--font-mono); + font-size: 10px; + color: var(--color-ink-muted); } /* -------------------------------------------------------------------------- @@ -499,306 +716,212 @@ } /* -------------------------------------------------------------------------- - 4. TYPOGRAPHY PRINCIPLES PLAYGROUND + 4. PRACTICAL COMPARISON MATRIX (Word vs InDesign vs TypesetOK) -------------------------------------------------------------------------- */ -.playground-card { - display: grid; - grid-template-columns: 310px 1fr; - gap: var(--space-6); - background-color: var(--color-bg-paper); - border: 1px solid var(--color-border-medium); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-paper); - overflow: hidden; - box-sizing: border-box; +.matrix-section { + margin-top: var(--space-12); } -.playground-controls-sidebar { - background-color: var(--color-bg-subtle); - border-left: 1px solid var(--color-border-subtle); - padding: var(--space-5); - display: flex; - flex-direction: column; - gap: var(--space-4); - box-sizing: border-box; +.matrix-table-wrapper { + overflow-x: auto; + border-radius: var(--radius-lg); + border: 1px solid var(--color-border-medium); + box-shadow: var(--shadow-paper); + background-color: var(--color-bg-paper); + margin-top: var(--space-6); } -[dir="ltr"] .playground-controls-sidebar { - border-left: none; - border-right: 1px solid var(--color-border-subtle); +.matrix-table { + width: 100%; + border-collapse: collapse; + text-align: right; + font-size: 13px; } -.control-group { - display: flex; - flex-direction: column; - gap: var(--space-2); +[dir="ltr"] .matrix-table { + text-align: left; } -.control-header { - display: flex; - justify-content: space-between; - align-items: center; - font-size: 12px; - font-weight: 600; +.matrix-table th { + background-color: var(--color-bg-subtle); + padding: 16px 18px; + font-weight: 800; + font-size: 14px; color: var(--color-ink-primary); + border-bottom: 2px solid var(--color-border-subtle); } -.control-value-badge { - font-family: var(--font-mono); - font-size: 11px; +.matrix-table th.col-highlight { + background-color: var(--color-brand-blue-light); color: var(--color-brand-blue-hover); - background: var(--color-brand-blue-light); - padding: 1px 6px; - border-radius: var(--radius-xs); + border-bottom: 2px solid var(--color-brand-blue); } -.range-slider { - width: 100%; - accent-color: var(--color-brand-blue); - height: 6px; - cursor: pointer; +.matrix-table td { + padding: 16px 18px; + border-bottom: 1px solid var(--color-border-subtle); + vertical-align: top; + line-height: 1.5; + color: var(--color-ink-secondary); } -.button-segmented { - display: flex; - background-color: var(--color-bg-surface); - border: 1px solid var(--color-border-subtle); - border-radius: var(--radius-sm); - padding: 2px; +.matrix-table td.col-highlight { + background-color: rgba(29, 99, 237, 0.03); + color: var(--color-ink-primary); + font-weight: 500; + border-inline: 1px solid rgba(29, 99, 237, 0.15); } -.segment-btn { - flex: 1; - padding: 4px 6px; - font-size: 11px; - font-family: var(--font-sans); - font-weight: 600; - border-radius: var(--radius-xs); - color: var(--color-ink-muted); - transition: all var(--motion-fast); - text-align: center; - min-height: 30px; +.matrix-table tr:hover td { + background-color: rgba(0, 0, 0, 0.02); } -.segment-btn.active { - background-color: var(--color-brand-blue); - color: #FFFFFF; +.matrix-table tr:hover td.col-highlight { + background-color: rgba(29, 99, 237, 0.06); } -.toggle-row { - display: flex; - align-items: center; - justify-content: space-between; - font-size: 12px; +.feature-title { + font-weight: 700; color: var(--color-ink-primary); - font-weight: 500; - cursor: pointer; + display: block; + margin-bottom: 4px; } -.switch-toggle { - position: relative; - width: 36px; - height: 20px; - background-color: var(--color-border-medium); - border-radius: 20px; - transition: background-color var(--motion-fast); +.badge-tag-pass { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 11px; + font-weight: 700; + color: #15803D; + background: rgba(34, 197, 94, 0.12); + padding: 2px 8px; + border-radius: var(--radius-xs); + margin-bottom: 6px; } -.switch-toggle.active { - background-color: var(--color-brand-blue); +.badge-tag-warn { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 11px; + font-weight: 700; + color: #B45309; + background: rgba(245, 158, 11, 0.12); + padding: 2px 8px; + border-radius: var(--radius-xs); + margin-bottom: 6px; } -.switch-thumb { - position: absolute; - top: 2px; - right: 2px; - width: 16px; - height: 16px; - background-color: #FFFFFF; - border-radius: 50%; - transition: transform var(--motion-fast); +.badge-tag-fail { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 11px; + font-weight: 700; + color: #DC2626; + background: rgba(239, 68, 68, 0.12); + padding: 2px 8px; + border-radius: var(--radius-xs); + margin-bottom: 6px; } -.switch-toggle.active .switch-thumb { - transform: translateX(-16px); +/* -------------------------------------------------------------------------- + 5. FORUM QUOTES & REAL-WORLD TYPESETTING PAIN POINTS + -------------------------------------------------------------------------- */ +.forum-quotes-section { + margin-top: var(--space-12); } -[dir="ltr"] .switch-thumb { - right: auto; - left: 2px; -} -[dir="ltr"] .switch-toggle.active .switch-thumb { - transform: translateX(16px); +.forum-quotes-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: var(--space-6); + margin-top: var(--space-6); } -.playground-stage-wrapper { +.forum-quote-card { + background-color: var(--color-bg-paper); + border: 1px solid var(--color-border-medium); + border-radius: var(--radius-lg); padding: var(--space-6); + box-shadow: var(--shadow-paper); display: flex; flex-direction: column; - position: relative; - background-color: var(--color-bg-paper); - overflow-x: auto; - box-sizing: border-box; -} - -.playground-specimen-page { - background: var(--color-bg-surface); - border: 1px solid var(--color-border-subtle); - box-shadow: var(--shadow-subtle); - padding: var(--space-6); - border-radius: var(--radius-xs); - position: relative; - min-height: 380px; - box-sizing: border-box; -} - -.playground-specimen-page.show-baseline { - background-image: linear-gradient(to bottom, rgba(59, 130, 246, 0.08) 1px, transparent 1px); - background-size: 100% 24px; + gap: var(--space-4); + transition: transform var(--motion-fast), box-shadow var(--motion-fast); } -/* -------------------------------------------------------------------------- - 5. PRODUCT WORKBENCH CONCEPT - -------------------------------------------------------------------------- */ -.workbench-frame { - background-color: #0E121A; - border-radius: var(--radius-lg); - border: 1px solid #1F283C; +.forum-quote-card:hover { + transform: translateY(-2px); box-shadow: var(--shadow-floating); - overflow: hidden; - color: #E2E8F0; } -.wb-window-header { +.quote-header { display: flex; align-items: center; justify-content: space-between; - padding: var(--space-2) var(--space-4); - background-color: #07090E; - border-bottom: 1px solid #1A2234; } -.wb-dots { - display: flex; - gap: 6px; -} -.wb-dot { width: 10px; height: 10px; border-radius: 50%; } -.wb-dot-red { background: #FF5F56; } -.wb-dot-yellow { background: #FFBD2E; } -.wb-dot-green { background: #27C93F; } - -.wb-title { +.quote-source { + font-size: 12px; + font-weight: 700; + color: var(--color-ink-muted); font-family: var(--font-mono); - font-size: 11px; - color: #8B96AA; -} - -.wb-menubar { display: flex; - gap: var(--space-4); - padding: var(--space-2) var(--space-4); - background-color: #121722; - font-size: 12px; - border-bottom: 1px solid #1F283C; - flex-wrap: wrap; -} - -.wb-menu-item { color: #A0AEC0; cursor: pointer; } -.wb-menu-item:hover, .wb-menu-item.active { color: #FFFFFF; } - -.wb-body { - display: grid; - grid-template-columns: 220px 1fr 260px; - min-height: 420px; + align-items: center; + gap: 6px; } -.wb-sidebar-left { - background-color: #0B0E14; - border-left: 1px solid #1A2234; - padding: var(--space-4); +.quote-target-tag { font-size: 11px; + font-weight: 700; + padding: 2px 8px; + border-radius: var(--radius-xs); + background: var(--color-bg-subtle); + color: var(--color-ink-secondary); } -[dir="ltr"] .wb-sidebar-left { - border-left: none; - border-right: 1px solid #1A2234; +.quote-body { + font-family: var(--font-serif); + font-size: 15px; + line-height: 1.6; + color: var(--color-ink-primary); + font-style: italic; + padding-right: 12px; + border-right: 3px solid var(--color-accent-gold); } -.wb-panel-title { - font-family: var(--font-mono); - font-size: 10px; - color: #718096; - text-transform: uppercase; - margin-bottom: var(--space-3); - letter-spacing: 0.05em; +[dir="ltr"] .quote-body { + padding-right: 0; + padding-left: 12px; + border-right: none; + border-left: 3px solid var(--color-accent-gold); } -.wb-tree-item { - display: flex; - align-items: center; - gap: var(--space-2); - padding: 4px 8px; - border-radius: var(--radius-xs); - color: #CBD5E1; - font-family: var(--font-mono); - cursor: pointer; -} -.wb-tree-item.selected { - background-color: rgba(37, 99, 235, 0.25); - color: #60A5FA; +.quote-solution { + background-color: var(--color-bg-surface); + border: 1px solid var(--color-border-subtle); + border-radius: var(--radius-sm); + padding: 12px 14px; + margin-top: auto; } -.wb-canvas-center { - background-color: #161D2A; +.solution-label { display: flex; align-items: center; - justify-content: center; - padding: var(--space-5); - position: relative; - overflow: hidden; -} - -.wb-rendered-page { - background: #FCFBF9; - color: #111827; - width: 340px; - max-width: 100%; - height: 460px; - padding: var(--space-5); - box-shadow: 0 10px 30px rgba(0,0,0,0.5); - font-family: var(--font-serif); + gap: 6px; font-size: 12px; - position: relative; - line-height: 1.45; - transform: scale(0.92); -} - -.wb-sidebar-right { - background-color: #0B0E14; - border-right: 1px solid #1A2234; - padding: var(--space-4); - font-size: 11px; - display: flex; - flex-direction: column; - gap: var(--space-4); -} - -[dir="ltr"] .wb-sidebar-right { - border-right: none; - border-left: 1px solid #1A2234; + font-weight: 800; + color: var(--color-brand-blue-hover); + margin-bottom: 4px; } -.wb-prop-row { - display: flex; - justify-content: space-between; - padding: 4px 0; - border-bottom: 1px solid #171E2D; - font-family: var(--font-mono); - font-size: 11px; +.solution-desc { + font-size: 13px; + color: var(--color-ink-secondary); + line-height: 1.5; } -.wb-prop-label { color: #718096; } -.wb-prop-val { color: #E2E8F0; font-weight: 600; } -.wb-prop-val.green { color: #34D399; } /* -------------------------------------------------------------------------- 6. BENTO GRID (ARCHITECTURAL PILLARS) @@ -1135,17 +1258,9 @@ grid-column: span 2; } - .playground-card { - grid-template-columns: 1fr; - } - - .wb-body { + .forum-quotes-grid { grid-template-columns: 1fr; } - - .wb-sidebar-left, .wb-sidebar-right { - display: none; - } .pipeline-track { grid-template-columns: repeat(2, 1fr); diff --git a/assets/css/tokens.css b/assets/css/tokens.css index f48562f..f5437a9 100644 --- a/assets/css/tokens.css +++ b/assets/css/tokens.css @@ -1,48 +1,50 @@ /* ========================================================================== TypesetOK (TOK) — Design Tokens (Editorial Technology) - Default: Dark Mode (מצב לילה כברירת מחדל) + Default: Light Mode (מצב יום כברירת מחדל עבור מעמדים) + Supports: Light, Dark, System ========================================================================== */ -:root { - /* Color Palette — Premium Dark Editorial Mode (DEFAULT) */ - --color-bg-base: #0B0E14; - --color-bg-paper: #111622; - --color-bg-surface: #171E2E; - --color-bg-subtle: #1D263A; - --color-bg-elevated: #242F46; - - --color-ink-primary: #F0F4FA; - --color-ink-secondary: #CBD5E1; - --color-ink-muted: #8E9BB0; - --color-ink-faint: #5B6880; +:root, +[data-theme="light"] { + /* Color Palette — Editorial Paper Light Mode (Default for Typesetters) */ + --color-bg-base: #F8F6F0; + --color-bg-paper: #FCFBF9; + --color-bg-surface: #FFFFFF; + --color-bg-subtle: #F1EEE6; + --color-bg-elevated: #FFFFFF; + + --color-ink-primary: #12161F; + --color-ink-secondary: #3D4554; + --color-ink-muted: #647087; + --color-ink-faint: #9AA4B5; /* Brand Palette from TypesetOK Identity */ - --color-brand-blue: #2563EB; - --color-brand-blue-hover: #3B82F6; - --color-brand-blue-light: rgba(37, 99, 235, 0.16); - --color-brand-blue-glow: rgba(37, 99, 235, 0.25); - - --color-brand-navy: #E2E8F0; - --color-brand-navy-dark: #07090D; - --color-brand-navy-light: #60A5FA; - - --color-accent-gold: #D9A04B; - --color-accent-gold-light: rgba(217, 160, 75, 0.15); - --color-accent-gold-hover: #F59E0B; + --color-brand-blue: #1D63ED; + --color-brand-blue-hover: #1551CA; + --color-brand-blue-light: #EFF5FF; + --color-brand-blue-glow: rgba(29, 99, 237, 0.15); + + --color-brand-navy: #16234B; + --color-brand-navy-dark: #0D1527; + --color-brand-navy-light: #233468; + + --color-accent-gold: #B4833E; + --color-accent-gold-light: #FBF6EB; + --color-accent-gold-hover: #976B2C; /* Prepress Ink Separations (Fogra 39 / ISO 15930) */ - --color-cmyk-cyan: #00B4D8; - --color-cmyk-magenta: #F72585; - --color-cmyk-yellow: #FFD166; - --color-cmyk-black: #06080C; + --color-cmyk-cyan: #0098BA; + --color-cmyk-magenta: #D9106A; + --color-cmyk-yellow: #E5B300; + --color-cmyk-black: #0E121A; /* Borders & Editorial Rule Lines */ - --color-border-subtle: #1F283C; - --color-border-medium: #2C3852; - --color-border-strong: #4B5E82; - --color-guide-line: rgba(255, 255, 255, 0.08); - --color-guide-active: #3B82F6; - --color-grid-overlay: rgba(59, 130, 246, 0.05); + --color-border-subtle: #E5E1D6; + --color-border-medium: #D1CCBF; + --color-border-strong: #16234B; + --color-guide-line: rgba(22, 35, 75, 0.12); + --color-guide-active: #1D63ED; + --color-grid-overlay: rgba(29, 99, 237, 0.04); /* Typography Families */ --font-serif: 'Frank Ruhl Libre', 'David Libre', 'David', 'Times New Roman', serif; @@ -90,10 +92,10 @@ --radius-pill: 9999px; /* Paper Shadows */ - --shadow-subtle: 0 1px 2px rgba(0, 0, 0, 0.4); - --shadow-paper: 0 4px 16px rgba(0, 0, 0, 0.45); - --shadow-floating: 0 16px 48px rgba(0, 0, 0, 0.65); - --shadow-glow: 0 0 24px rgba(37, 99, 235, 0.35); + --shadow-subtle: 0 1px 2px rgba(22, 35, 75, 0.05); + --shadow-paper: 0 2px 8px -2px rgba(22, 35, 75, 0.06), 0 10px 24px -4px rgba(22, 35, 75, 0.07); + --shadow-floating: 0 4px 12px rgba(22, 35, 75, 0.06), 0 20px 48px -10px rgba(22, 35, 75, 0.14); + --shadow-glow: 0 0 24px rgba(29, 99, 237, 0.2); /* Motion Timing & Easing */ --motion-fast: 160ms cubic-bezier(0.16, 1, 0.3, 1); @@ -118,36 +120,46 @@ --z-toast: 1000; } -/* Light Mode Variant (Active when user clicks Day/Night toggle) */ -[data-theme="light"] { - --color-bg-base: #F8F6F0; - --color-bg-paper: #FCFBF9; - --color-bg-surface: #FFFFFF; - --color-bg-subtle: #F1EEE6; - --color-bg-elevated: #FFFFFF; +/* Dark Mode Variant */ +[data-theme="dark"] { + --color-bg-base: #0B0E14; + --color-bg-paper: #111622; + --color-bg-surface: #171E2E; + --color-bg-subtle: #1D263A; + --color-bg-elevated: #242F46; - --color-ink-primary: #12161F; - --color-ink-secondary: #3D4554; - --color-ink-muted: #647087; - --color-ink-faint: #9AA4B5; + --color-ink-primary: #F0F4FA; + --color-ink-secondary: #CBD5E1; + --color-ink-muted: #8E9BB0; + --color-ink-faint: #5B6880; - --color-brand-blue: #1D63ED; - --color-brand-blue-hover: #1551CA; - --color-brand-blue-light: #EFF5FF; - --color-brand-blue-glow: rgba(29, 99, 237, 0.15); + --color-brand-blue: #2563EB; + --color-brand-blue-hover: #3B82F6; + --color-brand-blue-light: rgba(37, 99, 235, 0.16); + --color-brand-blue-glow: rgba(37, 99, 235, 0.25); - --color-brand-navy: #16234B; - --color-brand-navy-dark: #0D1527; - --color-brand-navy-light: #233468; + --color-brand-navy: #E2E8F0; + --color-brand-navy-dark: #07090D; + --color-brand-navy-light: #60A5FA; - --color-accent-gold: #B4833E; - --color-accent-gold-light: #FBF6EB; + --color-accent-gold: #D9A04B; + --color-accent-gold-light: rgba(217, 160, 75, 0.15); + --color-accent-gold-hover: #F59E0B; - --color-border-subtle: #E5E1D6; - --color-border-medium: #D1CCBF; - --color-border-strong: #16234B; - --color-guide-line: rgba(22, 35, 75, 0.12); + --color-cmyk-cyan: #00B4D8; + --color-cmyk-magenta: #F72585; + --color-cmyk-yellow: #FFD166; + --color-cmyk-black: #06080C; - --shadow-paper: 0 2px 8px -2px rgba(22, 35, 75, 0.06), 0 10px 24px -4px rgba(22, 35, 75, 0.07); - --shadow-floating: 0 4px 12px rgba(22, 35, 75, 0.06), 0 20px 48px -10px rgba(22, 35, 75, 0.14); + --color-border-subtle: #1F283C; + --color-border-medium: #2C3852; + --color-border-strong: #4B5E82; + --color-guide-line: rgba(255, 255, 255, 0.08); + --color-guide-active: #3B82F6; + --color-grid-overlay: rgba(59, 130, 246, 0.05); + + --shadow-subtle: 0 1px 2px rgba(0, 0, 0, 0.4); + --shadow-paper: 0 4px 16px rgba(0, 0, 0, 0.45); + --shadow-floating: 0 16px 48px rgba(0, 0, 0, 0.65); + --shadow-glow: 0 0 24px rgba(37, 99, 235, 0.35); } diff --git a/assets/js/a11y.js b/assets/js/a11y.js index e01d90e..e26de48 100644 --- a/assets/js/a11y.js +++ b/assets/js/a11y.js @@ -220,34 +220,102 @@ document.addEventListener('DOMContentLoaded', () => { }); } - // Theme Toggle in Header & A11y (Default: Dark mode, toggle to light) + // Theme Engine (Supports: Light, Dark, System — Default for Typesetters: Light/System) const themeToggle = document.getElementById('toggleThemeBtn'); + const themePopover = document.getElementById('themeMenuPopover'); const a11yThemeToggle = document.getElementById('btnA11yTheme'); + const systemMedia = window.matchMedia('(prefers-color-scheme: dark)'); + + const ICONS = { + light: '', + dark: '', + system: '' + }; + + function applyThemeMode(mode) { + let effectiveTheme = mode; + if (mode === 'system') { + effectiveTheme = systemMedia.matches ? 'dark' : 'light'; + } + + root.setAttribute('data-theme', effectiveTheme); + root.setAttribute('data-theme-setting', mode); + localStorage.setItem('tok_theme', mode); - function toggleTheme() { - const currentTheme = root.getAttribute('data-theme') || 'dark'; - const newTheme = currentTheme === 'light' ? 'dark' : 'light'; - root.setAttribute('data-theme', newTheme); - localStorage.setItem('tok_theme', newTheme); if (themeToggle) { - themeToggle.classList.toggle('active', newTheme === 'light'); - themeToggle.setAttribute('aria-label', newTheme === 'light' ? 'Switch to Dark Mode' : 'Switch to Light Mode'); + themeToggle.innerHTML = ICONS[mode] || ICONS.light; + const labelMap = { + light: 'ערכת נושא: מצב יום (בהיר)', + dark: 'ערכת נושא: מצב לילה (כהה)', + system: 'ערכת נושא: לפי המערכת (אוטומטי)' + }; + themeToggle.setAttribute('aria-label', labelMap[mode] || 'ערכת נושא'); + themeToggle.setAttribute('title', labelMap[mode] || 'ערכת נושא'); + } + + if (themePopover) { + themePopover.querySelectorAll('.theme-menu-item').forEach(btn => { + const isCurrent = btn.getAttribute('data-theme-opt') === mode; + btn.classList.toggle('active', isCurrent); + btn.setAttribute('aria-checked', isCurrent ? 'true' : 'false'); + }); } } - if (themeToggle) { - themeToggle.addEventListener('click', toggleTheme); + // Handle system color scheme change in real time + systemMedia.addEventListener('change', () => { + const saved = localStorage.getItem('tok_theme') || 'system'; + if (saved === 'system') { + applyThemeMode('system'); + } + }); + + // Toggle dropdown on header button click + if (themeToggle && themePopover) { + themeToggle.addEventListener('click', (e) => { + e.stopPropagation(); + const isOpen = themePopover.classList.toggle('open'); + themeToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); + }); + + themePopover.querySelectorAll('.theme-menu-item').forEach(btn => { + btn.addEventListener('click', () => { + const selectedMode = btn.getAttribute('data-theme-opt') || 'system'; + applyThemeMode(selectedMode); + themePopover.classList.remove('open'); + themeToggle.setAttribute('aria-expanded', 'false'); + }); + }); + + document.addEventListener('click', (e) => { + if (!themePopover.contains(e.target) && e.target !== themeToggle) { + themePopover.classList.remove('open'); + themeToggle.setAttribute('aria-expanded', 'false'); + } + }); + + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape' && themePopover.classList.contains('open')) { + themePopover.classList.remove('open'); + themeToggle.setAttribute('aria-expanded', 'false'); + themeToggle.focus(); + } + }); } + + // Accessibility panel theme button (cycles: light -> dark -> system) if (a11yThemeToggle) { - a11yThemeToggle.addEventListener('click', toggleTheme); + a11yThemeToggle.addEventListener('click', () => { + const current = localStorage.getItem('tok_theme') || 'system'; + const order = ['light', 'dark', 'system']; + const next = order[(order.indexOf(current) + 1) % order.length]; + applyThemeMode(next); + }); } - // Set default theme to dark if not set - const savedTheme = localStorage.getItem('tok_theme') || 'dark'; - root.setAttribute('data-theme', savedTheme); - if (themeToggle) { - themeToggle.classList.toggle('active', savedTheme === 'light'); - } + // Initial theme initialization: default to 'system' (or 'light' for typesetters) + const initialTheme = localStorage.getItem('tok_theme') || 'system'; + applyThemeMode(initialTheme); // Initial application of accessibility state applyA11yState(); diff --git a/assets/js/i18n.js b/assets/js/i18n.js index ecd0e77..9877f35 100644 --- a/assets/js/i18n.js +++ b/assets/js/i18n.js @@ -1,33 +1,32 @@ /** * TypesetOK (TOK) — Multilingual Translation Engine * Supports: Hebrew (he), US English (en), Spanish (es), French (fr). - * Colloquial, natural, and professional terminology in all languages. + * Natural, professional, typesetter-oriented terminology without emojis. */ const TOK_TRANSLATIONS = { he: { // Navigation nav_home: "ראשי", - nav_story: "ארכיטקטורה", - nav_principles: "עקרונות עימוד", - nav_comparison: "השוואה", - nav_workbench: "קונספט ממשק", + nav_comparison: "השוואה למעמדים", + nav_matrix: "השוואת וורד ואינדיזיין", + nav_quotes: "קולות מהשטח", nav_features: "יכולות", - nav_pipeline: "צינור עבודה", + nav_story: "ארכיטקטורה", nav_engineering: "בנצ'מרק", - nav_developer: "אתר המפתח", - btn_github: "פרויקט ב-GitHub", - btn_architecture: "דו״ח ארכיטקטורה", + btn_download: "הורדה", + btn_github: "מאגר GitHub", + btn_architecture: "מפרט טכני", btn_source_guide: "מדריך פיתוח", // Hero - hero_badge: "מחקר, ארכיטקטורה וקוד פתוח • שפת Rust 1.85+ • תקן ת״י 6100", - hero_title_1: "החזון לעימוד עברי מקצועי.", - hero_title_2: "דיוק של דפוס, מהירות של Rust.", - hero_desc: "TypesetOK (TOK) היא מערכת עימוד ופרסום שולחני (DTP) מודרנית בקוד פתוח הנמצאת במחקר ופיתוח עבור טיפוגרפיה עברית מתקדמת, ספרי קודש (ש״ס, מקראות גדולות ושו״ת), ומסמכי ענק בני אלפי עמודים — במפרט הנדסי קפדני ללא פשרות.", - hero_cta_github: "צפה בקוד ב-GitHub", + hero_badge: "תוכנת עימוד שולחנית מקצועית בקוד פתוח • ללא עלות וללא נעילה", + hero_title_1: "עימוד ספרים אמיתי.", + hero_title_2: "חופשי, פתוח ומדויק לדפוס.", + hero_desc: "TypesetOK נבנתה במיוחד עבור מעמדים, מעצבי ספרים ומוציאים לאור. טיפול טבעי באות העברית, ניקוד וטעמים מדויקים ללא שיבושים, עמודי ש״ס ומקראות גדולות עם ריבוי מפרשים, ועמידה מלאה בתקני דפוס.", + hero_cta_download: "הורד את התוכנה", + hero_cta_github: "מאגר הקוד ב-GitHub", hero_cta_arch: "מפרט ארכיטקטוני מלא", - hero_cta_dev: "אתר המפתח (Amlaach)", metric_tests: "58 / 58", metric_tests_label: "בדיקות ליבה ב-Rust עוברות", metric_clippy: "0 אזהרות", @@ -35,11 +34,18 @@ const TOK_TRANSLATIONS = { metric_standards: "ת״י 6100 & ISO 15930", metric_standards_label: "עמידה מלאה בתקני דפוס ויוניקוד", - // Hero Specimen Plate - plate_badge: "גליון הוכחה ארכיטקטוני • TypesetOK Monograph", - plate_title: "סֵפֶר תְּהִלִּים — מִזְמוֹר כ״ג", - plate_text: "מִזְמ֥וֹר לְדָוִ֑ד יְהוָ֥ה רֹ֝עִ֗י לֹ֣א אֶחְסָֽר׃ בִּנְא֣וֹת דֶּ֭שֶׁא יַרְבִּיצֵ֑נִי עַל־מֵ֖י מְנֻח֣וֹת יְנַהֲלֵֽנִי׃ נַפְשִׁ֥י יְשׁוֹבֵ֑ב יַֽנְחֵ֥נִי בְמַעְגְּלֵי־צֶ֝֗דֶק לְמַ֣עַן שְׁמֽוֹ׃ גַּ֤ם כִּֽי־אֵלֵ֨ךְ בְּגֵ֪יא צַלְמָ֡וֶת לֹא־אִ֘ירָ֤א רָ֗ע כִּי־אַתָּ֥ה עִמָּדִ֑י שִׁבְטְךָ֥ וּ֝מִשְׁעַנְתֶּ֗ךָ הֵ֣מָּה יְנַֽחֲמֻֽנִי׃", - plate_caption: "עימוד מבוסס יחס הזהב, אותיות מתרחבות אהלתר״ם וסנכרון קווי בסיס", + // Download Center + dl_card_badge: "מהדורה רשמית ל-Windows", + dl_card_os: "Windows 10 / 11 (x64)", + dl_btn_portable_title: "הורדה ישירה (ללא התקנה)", + dl_btn_portable_sub: "קובץ ZIP נייד — לחלץ ולהפעיל מיד", + dl_btn_installer_title: "הורדה עם מתקין (Windows Setup)", + dl_btn_installer_sub: "התקנה מסודרת לשולחן העבודה", + dl_cli_label: "אפשרויות נוספות:", + dl_cli_windows: "CLI ל-Windows", + dl_cli_linux: "Linux CLI", + dl_cli_macos: "macOS CLI", + dl_floating_btn: "הורדת TypesetOK", // Storytelling story_pretitle: "פרק א׳: עמודי התווך של הארכיטקטורה", @@ -56,37 +62,24 @@ const TOK_TRANSLATIONS = { scene3_desc: "ללא הסתמכות על מנועי הדפסת דפדפן המוגבלים ל-sRGB. מנוע ה-Rust מתוכנן לייצר ישירות קובצי דפוס מובהקים: שחור 100% K (DeviceCMYK), צלבי רישום וסימני חיתוך וקטוריים, תיבות BleedBox ו-TrimBox של 3 מ\"מ, ופרופילי Fogra 39.", // Comparison - comp_pretitle: "פרק ב׳: השוואה טיפוגרפית מעמיקה", - comp_title: "מעבד תמלילים רגיל מול אופטימיזציית TypesetOK", - comp_subtitle: "גררו את הסליידר או לחצו על הלחצנים המהירים כדי להשוות בין תוצר שבירת שורות פרימיטיבית בוורד לבין בלוק העימוד המהודק עם Knuth-Plass ואותיות התפשטות.", + comp_pretitle: "פרק ב׳: השוואה מעשית למעמדים", + comp_title: "שבירת שורות בוורד מול דיוק של TypesetOK", + comp_subtitle: "הזיזו את הסליידר או לחצו על הלחצנים כדי להשוות בין אופן פעולת מעבד תמלילים רגיל לבין בלוק העימוד המאוזן של TypesetOK.", comp_preset_before: "וורד (לפני)", comp_preset_half: "חצי-חצי (50%)", comp_preset_after: "TypesetOK (אחרי)", comp_before_label: "מעבד תמלילים מסורתי (וורד)", - comp_before_note: "⚠️ שורות רפויות, 'נהרות' לבנים פעורים, היעדר התאמת אותיות התפשטות ואי-אחידות בצפיפות.", + comp_before_note: "בוורד: שורות מתוחות, חללים לבנים בולטים, היעדר אותיות התפשטות ואי-אחידות בצפיפות העמוד.", comp_after_label: "מפרט TypesetOK (Knuth-Plass + אהלתר״ם)", - comp_after_note: "✓ בלוק טיפוגרפי אחיד, שבירת שורות גלובלית, אותיות מתרחבות אהלתר״ם וסנכרון מלא לקווי בסיס.", - - // Playground - pg_pretitle: "פרק ג׳: הדגמת עקרונות טיפוגרפיים", - pg_title: "מעבדת שליטה במאפייני הטיפוגרפיה", - pg_subtitle: "התנסו בפרמטרים הטיפוגרפיים וראו כיצד משפיעים רווחי השורות, חלוקת הטורים ומדרגי היישור העבריים על שטף הקריאה.", - pg_disclaimer: "הדגמה אינטראקטיבית של עקרונות שבירת שורות, קווי בסיס ואותיות התפשטות (אהלתר״ם)", - - // Developer Section - dev_pretitle: "פרק ד׳: אודות הפרויקט והמפתח", - dev_title: "חזון הקוד הפתוח של Amlaach", - dev_desc: "פרויקט TypesetOK הוקם מתוך צורך אמיתי של עולם הדפוס העברי והספרות התורנית בכלי עימוד מודרני, אמין, מהיר וחופשי ממנעולים מסחריים מיושנים. הפרויקט מנוהל ומפותח על ידי Amlaach.", - dev_btn_portfolio: "בקרו באתר האישי של Amlaach", - dev_btn_github: "מאגר TypesetOK ב-GitHub", + comp_after_note: "ב-TypesetOK: בלוק טיפוגרפי מאוזן, חלוקת שורות מותאמת לפסקה כולה, אותיות מתרחבות אהלתר״ם וסנכרון מלא לקווי בסיס.", // A11y Panel a11y_panel_title: "תפריט נגישות מורחב", a11y_font_inc: "הגדל גופן (+)", a11y_font_dec: "הקטן גופן (-)", a11y_contrast: "ניגודיות גבוהה", - a11y_theme: "מצב יום / לילה", - a11y_readable_font: "גופן קריא / פשוט", + a11y_theme: "ערכת נושא (יום / לילה / מערכת)", + a11y_readable_font: "גופן קריא ופשוט", a11y_links: "הדגשת קישורים", a11y_headings: "הדגשת כותרות", a11y_big_cursor: "סמן עכבר מוגדל", @@ -100,26 +93,25 @@ const TOK_TRANSLATIONS = { en: { // Navigation nav_home: "Home", - nav_story: "Architecture", - nav_principles: "Typography", nav_comparison: "Comparison", - nav_workbench: "UI Concept", + nav_matrix: "Word vs InDesign", + nav_quotes: "Typesetter Voices", nav_features: "Features", - nav_pipeline: "Pipeline", + nav_story: "Architecture", nav_engineering: "Benchmarks", - nav_developer: "Developer Site", - btn_github: "GitHub Project", - btn_architecture: "Architecture Spec", + btn_download: "Download", + btn_github: "GitHub Repo", + btn_architecture: "Tech Spec", btn_source_guide: "Dev Guide", // Hero - hero_badge: "Open-Source Research & Spec • Rust 1.85+ Engine • SI 6100 Standard", - hero_title_1: "The Future of Hebrew Typesetting.", - hero_title_2: "Press-Ready Precision. Rust-Fast Speed.", - hero_desc: "TypesetOK (TOK) is an open-source Desktop Publishing (DTP) research and development project crafted from scratch for advanced Hebrew typography, sacred texts (Talmud, Mikraot Gedolot, Responsa), and thousand-page manuscripts — with uncompromising engineering integrity.", + hero_badge: "Open-Source Professional Desktop Typesetting • Free & Unlocked", + hero_title_1: "Real Book Typesetting.", + hero_title_2: "Free, Open, and Press-Ready.", + hero_desc: "TypesetOK is purpose-built for typesetters, book designers, and publishers. Native Hebrew typography, flawless vocalization and cantillation, multi-commentary Talmud layouts, and complete print-standard compliance.", + hero_cta_download: "Download Software", hero_cta_github: "View on GitHub", - hero_cta_arch: "Read Architecture Spec", - hero_cta_dev: "Developer Site (Amlaach)", + hero_cta_arch: "Architecture Spec", metric_tests: "58 / 58", metric_tests_label: "Core Rust unit tests passing", metric_clippy: "0 Warnings", @@ -127,11 +119,18 @@ const TOK_TRANSLATIONS = { metric_standards: "SI 6100 & ISO 15930", metric_standards_label: "Full Unicode & Pre-press standards", - // Hero Specimen Plate - plate_badge: "Architectural Proof Sheet • TypesetOK Monograph", - plate_title: "BOOK OF PSALMS — CHAPTER XXIII", - plate_text: "The Lord is my shepherd; I shall not want. He maketh me to lie down in green pastures: he leadeth me beside the still waters. He restoreth my soul: he leadeth me in the paths of righteousness for his name's sake. Yea, though I walk through the valley of the shadow of death, I will fear no evil: for thou art with me; thy rod and thy staff they comfort me.", - plate_caption: "Golden ratio page geometry, classical Hebrew typography, and baseline grid lock", + // Download Center + dl_card_badge: "Official Windows Release", + dl_card_os: "Windows 10 / 11 (x64)", + dl_btn_portable_title: "Direct Download (Portable)", + dl_btn_portable_sub: "Standalone ZIP — Extract and run immediately", + dl_btn_installer_title: "Download Installer (Windows Setup)", + dl_btn_installer_sub: "Standard desktop installation", + dl_cli_label: "Additional options:", + dl_cli_windows: "Windows CLI", + dl_cli_linux: "Linux CLI", + dl_cli_macos: "macOS CLI", + dl_floating_btn: "Download TypesetOK", // Storytelling story_pretitle: "Chapter I: Architectural Pillars", @@ -148,37 +147,24 @@ const TOK_TRANSLATIONS = { scene3_desc: "No relying on browser print engines crippled by sRGB. The Rust engine directly targets pure DeviceCMYK 100% K black, vector crop marks, 3mm BleedBox, Fogra 39 profiles, and PostScript /ToUnicode mapping for pristine text search.", // Comparison - comp_pretitle: "Chapter II: Deep Typographic Comparison", - comp_title: "Office Word Processor vs TypesetOK Optimization", - comp_subtitle: "Drag the slider or click presets to see the difference between primitive line breaking (loose word rivers) and TypesetOK's Knuth-Plass global line-breaking with authentic Hebrew expanding letters.", + comp_pretitle: "Chapter II: Practical Typesetting Comparison", + comp_title: "Word Processing vs TypesetOK Precision", + comp_subtitle: "Drag the slider or click presets to see the difference between primitive word stretching and TypesetOK's balanced paragraph line breaking with authentic Hebrew expanding letters.", comp_preset_before: "Word (Before)", comp_preset_half: "Split (50%)", comp_preset_after: "TypesetOK (After)", comp_before_label: "Standard Word Processor (MS Word)", - comp_before_note: "⚠️ Gaping white rivers, loose line breaks, stretched inter-word spaces, and inconsistent gray typographic density.", + comp_before_note: "In Word: loose stretched lines, gaping white rivers, missing extending letters, and uneven page density.", comp_after_label: "TypesetOK Specification (Knuth-Plass + Expanding Glyphs)", - comp_after_note: "✓ Harmonious typographic block, global paragraph demerit minimization, extending letters (אהלתר״ם), and strict baseline sync.", - - // Playground - pg_pretitle: "Chapter III: Typographic Demonstration", - pg_title: "Typography & Layout Playground", - pg_subtitle: "Explore how leading, column counts, and Hebrew multi-tier justification affect readability.", - pg_disclaimer: "Interactive demonstration of line-breaking, baseline grids, and extending Hebrew letters (Otiyot Hitpashtut)", - - // Developer Section - dev_pretitle: "Chapter IV: About the Creator", - dev_title: "Open Source Vision by Amlaach", - dev_desc: "TypesetOK was founded to liberate Hebrew typesetting from proprietary decades-old legacy lock-ins. Built and spearheaded by Amlaach.", - dev_btn_portfolio: "Visit Amlaach's Personal Portfolio", - dev_btn_github: "TypesetOK GitHub Organization", + comp_after_note: "In TypesetOK: harmonious typographic block, global paragraph optimization, authentic expanding letters, and strict baseline synchronization.", // A11y Panel a11y_panel_title: "Accessibility Preferences", a11y_font_inc: "Increase Text (+)", a11y_font_dec: "Decrease Text (-)", a11y_contrast: "High Contrast", - a11y_theme: "Day / Night Mode", - a11y_readable_font: "Dyslexia Font", + a11y_theme: "Theme (Light / Dark / System)", + a11y_readable_font: "Simple Dyslexia Font", a11y_links: "Highlight Links", a11y_headings: "Highlight Headings", a11y_big_cursor: "Large Cursor", @@ -192,26 +178,25 @@ const TOK_TRANSLATIONS = { es: { // Navigation nav_home: "Inicio", - nav_story: "Arquitectura", - nav_principles: "Tipografía", - nav_comparison: "Comparación", - nav_workbench: "Concepto UI", + nav_comparison: "Comparativa", + nav_matrix: "Word vs InDesign", + nav_quotes: "Voces del Sector", nav_features: "Capacidades", - nav_pipeline: "Flujo", + nav_story: "Arquitectura", nav_engineering: "Métricas", - nav_developer: "Sitio del Desarrollador", - btn_github: "Proyecto en GitHub", + btn_download: "Descargar", + btn_github: "Repositorio GitHub", btn_architecture: "Especificación", - btn_source_guide: "Guía de Desarrollo", + btn_source_guide: "Guía Dev", // Hero - hero_badge: "Investigación y Código Abierto • Motor Rust 1.85+ • Estándar SI 6100", - hero_title_1: "El futuro de la tipografía hebrea.", - hero_title_2: "Precisión editorial. Velocidad Rust.", - hero_desc: "TypesetOK (TOK) es un proyecto de investigación y desarrollo de autoedición (DTP) de código abierto diseñado desde cero para tipografía hebrea avanzada, textos sagrados (Talmud, responsa) y libros masivos de miles de páginas.", + hero_badge: "Autoedición profesional de código abierto • Gratuita y sin ataduras", + hero_title_1: "Composición tipográfica real.", + hero_title_2: "Libre, abierta y lista para imprenta.", + hero_desc: "TypesetOK está diseñada específicamente para maquetadores, diseñadores de libros y editores. Soporte nativo para hebreo, vocalización precisa sin desajustes, diseño de páginas rabínicas complejas y pleno cumplimiento de estándares de impresión.", + hero_cta_download: "Descargar Programa", hero_cta_github: "Ver en GitHub", - hero_cta_arch: "Leer Informe Técnico", - hero_cta_dev: "Sitio del Desarrollador (Amlaach)", + hero_cta_arch: "Especificación Técnica", metric_tests: "58 / 58", metric_tests_label: "Pruebas unitarias superadas en Rust", metric_clippy: "0 Advertencias", @@ -219,11 +204,18 @@ const TOK_TRANSLATIONS = { metric_standards: "SI 6100 & ISO 15930", metric_standards_label: "Cumplimiento normativo total", - // Hero Specimen Plate - plate_badge: "Pliego Arquitectónico • TypesetOK Monograph", - plate_title: "LIBRO DE LOS SALMOS — CAPÍTULO XXIII", - plate_text: "El Señor es mi pastor; nada me faltará. En lugares de delicados pastos me hará descansar; junto a aguas de reposo me pastoreará. Confortará mi alma; me guiará por sendas de justicia por amor de su nombre.", - plate_caption: "Geometría áurea, tipografía hebrea clásica y sincronización de rejilla base", + // Download Center + dl_card_badge: "Versión Oficial para Windows", + dl_card_os: "Windows 10 / 11 (x64)", + dl_btn_portable_title: "Descarga Directa (Portable)", + dl_btn_portable_sub: "Archivo ZIP — Descomprimir y ejecutar", + dl_btn_installer_title: "Descargar Instalador (Windows Setup)", + dl_btn_installer_sub: "Instalación estándar de escritorio", + dl_cli_label: "Otras opciones:", + dl_cli_windows: "Windows CLI", + dl_cli_linux: "Linux CLI", + dl_cli_macos: "macOS CLI", + dl_floating_btn: "Descargar TypesetOK", // Storytelling story_pretitle: "Capítulo I: Pilares de Arquitectura", @@ -240,36 +232,23 @@ const TOK_TRANSLATIONS = { scene3_desc: "Sin depender de motores de navegador. Salida directa con 100% K negro puro (DeviceCMYK), sangrado de 3 mm y perfiles Fogra 39.", // Comparison - comp_pretitle: "Capítulo II: Comparativa Tipográfica", - comp_title: "Procesador Común vs Optimización TypesetOK", + comp_pretitle: "Capítulo II: Comparativa Práctica", + comp_title: "Procesador Común vs Precisión TypesetOK", comp_subtitle: "Mueva el control deslizante para comparar el espaciado deficiente con la justificación óptima Knuth-Plass.", comp_preset_before: "Word (Antes)", comp_preset_half: "Mitad (50%)", comp_preset_after: "TypesetOK (Después)", comp_before_label: "Procesador de Texto Común (Word)", - comp_before_note: "⚠️ Espacios irregulares, 'ríos' blancos y deformación del ritmo visual.", + comp_before_note: "En Word: espaciado irregular, 'ríos' blancos y falta de regularidad en la mancha tipográfica.", comp_after_label: "Especificación TypesetOK (Knuth-Plass + Letras Expansibles)", - comp_after_note: "✓ Mancha tipográfica armónica, minimización global de demerits y rejilla base alineada.", - - // Playground - pg_pretitle: "Capítulo III: Demostración Tipográfica", - pg_title: "Laboratorio de Parámetros Tipográficos", - pg_subtitle: "Compruebe en tiempo real cómo influyen el interlineado y el número de columnas.", - pg_disclaimer: "Demostración interactiva de principios de diseño y letras hebreas expansibles", - - // Developer Section - dev_pretitle: "Capítulo IV: Acerca del Desarrollador", - dev_title: "Visión de Código Abierto por Amlaach", - dev_desc: "TypesetOK fue iniciado para dar a la edición hebrea una herramienta moderna y libre. Liderado por Amlaach.", - dev_btn_portfolio: "Visitar Portafolio de Amlaach", - dev_btn_github: "Organización en GitHub", + comp_after_note: "En TypesetOK: mancha tipográfica armónica, minimización global de demerits y rejilla base alineada.", // A11y Panel a11y_panel_title: "Opciones de Accesibilidad", a11y_font_inc: "Aumentar Letra (+)", a11y_font_dec: "Reducir Letra (-)", a11y_contrast: "Alto Contraste", - a11y_theme: "Modo Día / Noche", + a11y_theme: "Tema (Día / Noche / Sistema)", a11y_readable_font: "Fuente Dislexia", a11y_links: "Resaltar Enlaces", a11y_headings: "Resaltar Títulos", @@ -284,26 +263,25 @@ const TOK_TRANSLATIONS = { fr: { // Navigation nav_home: "Accueil", - nav_story: "Architecture", - nav_principles: "Typographie", nav_comparison: "Comparaison", - nav_workbench: "Concept UI", + nav_matrix: "Word vs InDesign", + nav_quotes: "Retours d'Expérience", nav_features: "Fonctions", - nav_pipeline: "Pipeline", + nav_story: "Architecture", nav_engineering: "Performances", - nav_developer: "Site du Développeur", - btn_github: "Projet GitHub", + btn_download: "Télécharger", + btn_github: "Dépôt GitHub", btn_architecture: "Spécification", btn_source_guide: "Guide Dev", // Hero - hero_badge: "Recherche Open Source • Moteur Rust 1.85+ • Norme SI 6100", - hero_title_1: "L'Avenir de la Composition Hébraïque.", - hero_title_2: "Rigueur Éditoriale. Vitesse Rust.", - hero_desc: "TypesetOK (TOK) est un projet open source de publication assistée par ordinateur (PAO) conçu dès le départ pour la typographie hébraïque avancée, les textes sacrés (Talmud, Mikraot Gedolot) et les manuscrits massifs de milliers de pages.", + hero_badge: "PAO professionnelle open source • Gratuite et sans verrouillage", + hero_title_1: "La vraie composition de livres.", + hero_title_2: "Libre, ouverte et prête pour l'impression.", + hero_desc: "TypesetOK est spécialement conçue pour les typographes, maquettistes et éditeurs. Typographie hébraïque native, vocalisation sans bavure, mise en page du Talmud à commentaires multiples et conformité prépresse totale.", + hero_cta_download: "Télécharger le Logiciel", hero_cta_github: "Voir sur GitHub", - hero_cta_arch: "Spécification d'Architecture", - hero_cta_dev: "Site du Développeur (Amlaach)", + hero_cta_arch: "Spécification Technique", metric_tests: "58 / 58", metric_tests_label: "Tests unitaires validés en Rust", metric_clippy: "0 Avertissement", @@ -311,11 +289,18 @@ const TOK_TRANSLATIONS = { metric_standards: "SI 6100 & ISO 15930", metric_standards_label: "Normes d'impression et Unicode", - // Hero Specimen Plate - plate_badge: "Feuille d'Épreuve Architecturale • TypesetOK", - plate_title: "LIVRE DES PSAUMES — CHAPITRE XXIII", - plate_text: "L'Éternel est mon berger : je ne manquerai de rien. Il me fait reposer dans de verts pâturages, il me dirige près des eaux paisibles. Il restaure mon âme, il me conduit dans les sentiers de la justice, à cause de son nom.", - plate_caption: "Proportions dorées, typographie hébraïque classique et grille de justification", + // Download Center + dl_card_badge: "Version Officielle pour Windows", + dl_card_os: "Windows 10 / 11 (x64)", + dl_btn_portable_title: "Téléchargement Direct (Portable)", + dl_btn_portable_sub: "Fichier ZIP — Extraire et lancer", + dl_btn_installer_title: "Télécharger l'Installateur (Setup)", + dl_btn_installer_sub: "Installation bureau classique", + dl_cli_label: "Options complémentaires :", + dl_cli_windows: "CLI Windows", + dl_cli_linux: "CLI Linux", + dl_cli_macos: "CLI macOS", + dl_floating_btn: "Télécharger TypesetOK", // Storytelling story_pretitle: "Chapitre I: Piliers d'Architecture", @@ -324,7 +309,7 @@ const TOK_TRANSLATIONS = { scene1_num: "Pilier 01", scene1_title: "Normalisation stricte selon la norme SI 6100", scene1_desc: "Les logiciels de traitement de texte altèrent souvent l'ordre des voyelles et signes diacritiques. TypesetOK impose un ordre canonique déterministe.", - scene2_num: "Pilar 02", + scene2_num: "Pilier 02", scene2_title: "Résolveur de contraintes multiflux (Talmud)", scene2_desc: "Le sommet de la mise en page : texte central et commentaires périphériques synchronisés de façon fluide sur chaque page.", scene3_num: "Pilier 03", @@ -332,36 +317,23 @@ const TOK_TRANSLATIONS = { scene3_desc: "Sortie directe sans intermédiaire web : 100% noir K (DeviceCMYK), repères de coupe vectoriels et profils Fogra 39.", // Comparison - comp_pretitle: "Chapitre II: Comparaison Typographique", - comp_title: "Traitement de Texte vs Optimisation TypesetOK", + comp_pretitle: "Chapitre II: Comparaison Pratique", + comp_title: "Traitement de Texte vs Rigueur TypesetOK", comp_subtitle: "Glissez le curseur pour comparer les césures approximatives de Word avec l'optimisation Knuth-Plass de TypesetOK.", comp_preset_before: "Word (Avant)", comp_preset_half: "Partage (50%)", comp_preset_after: "TypesetOK (Après)", comp_before_label: "Traitement de Texte Standard (Word)", - comp_before_note: "⚠️ Espaces anarchiques, 'lézardes' blanches et manque de régularité.", + comp_before_note: "Sous Word: espacements anarchiques, 'lézardes' blanches et manque de régularité.", comp_after_label: "Spécification TypesetOK (Knuth-Plass + Lettres Étirables)", - comp_after_note: "✓ Bloc typographique homogène, minimisation des défauts et alignement sur la grille.", - - // Playground - pg_pretitle: "Chapitre III: Démonstration Typographique", - pg_title: "Atelier de Principes Typographiques", - pg_subtitle: "Testez l'impact de l'interlignage et du nombre de colonnes sur le confort de lecture.", - pg_disclaimer: "Démonstration interactive des principes de composition et de lettres extensibles", - - // Developer Section - dev_pretitle: "Chapitre IV: À Propos du Développeur", - dev_title: "Vision Open Source par Amlaach", - dev_desc: "TypesetOK a été fondé pour libérer l'édition hébraïque des outils propriétaires désuets. Mené par Amlaach.", - dev_btn_portfolio: "Consulter le Portfolio d'Amlaach", - dev_btn_github: "Organisation sur GitHub", + comp_after_note: "Sous TypesetOK: bloc typographique homogène, minimisation des défauts et alignement sur la grille.", // A11y Panel a11y_panel_title: "Options d'Accessibilité", a11y_font_inc: "Agrandir le Texte (+)", a11y_font_dec: "Réduire le Texte (-)", a11y_contrast: "Contraste Élevé", - a11y_theme: "Mode Jour / Nuit", + a11y_theme: "Thème (Jour / Nuit / Système)", a11y_readable_font: "Police Lisible", a11y_links: "Surligner les Liens", a11y_headings: "Surligner les Titres", diff --git a/assets/js/main.js b/assets/js/main.js index 38cbc56..4c06021 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -69,17 +69,83 @@ document.addEventListener('DOMContentLoaded', () => { }); } - // 4. Hero Monograph Plate Local Grid Toggle (Non-intrusive) - const monographGridBtn = document.getElementById('monographGridBtn'); - const monographSheet = document.getElementById('monographSheet'); - if (monographGridBtn && monographSheet) { - monographGridBtn.addEventListener('click', () => { - const active = monographSheet.classList.toggle('show-grid'); - monographGridBtn.classList.toggle('active', active); - monographGridBtn.setAttribute('aria-pressed', active ? 'true' : 'false'); - }); + // 4. Floating Download Button Glide (Scroll Observer) + const floatingDownload = document.getElementById('floatingDownloadWidget'); + const heroDownloadCard = document.getElementById('heroDownloadCard'); + + if (floatingDownload) { + if (heroDownloadCard && 'IntersectionObserver' in window) { + const dlObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + // If hero download card is NOT intersecting (user scrolled past it), show floating button + floatingDownload.classList.toggle('active', !entry.isIntersecting); + }); + }, { threshold: 0.1 }); + dlObserver.observe(heroDownloadCard); + } else { + window.addEventListener('scroll', () => { + const scrolled = window.scrollY > 350; + floatingDownload.classList.toggle('active', scrolled); + }, { passive: true }); + } } + // 5. Dynamic GitHub Latest Release Assets Fetcher + async function fetchLatestReleaseAssets() { + try { + const res = await fetch('https://api.github.com/repos/TypesetOK/typesetok/releases/latest', { + headers: { 'Accept': 'application/vnd.github.v3+json' } + }); + if (!res.ok) return; + const data = await res.json(); + if (!data || !data.assets) return; + + const tagName = data.tag_name || 'v0.6.0'; + document.querySelectorAll('.release-version-tag').forEach(el => { + el.textContent = tagName; + }); + + // Find Windows desktop portable zip + const portableAsset = data.assets.find(a => + a.name.toLowerCase().includes('windows') && + a.name.toLowerCase().includes('desktop') && + a.name.endsWith('.zip') + ); + if (portableAsset && portableAsset.browser_download_url) { + document.querySelectorAll('.download-link-portable').forEach(a => { + a.href = portableAsset.browser_download_url; + }); + } + + // Find Windows CLI zip + const cliAsset = data.assets.find(a => + a.name.toLowerCase().includes('cli') && + a.name.toLowerCase().includes('windows') && + a.name.endsWith('.zip') + ); + if (cliAsset && cliAsset.browser_download_url) { + document.querySelectorAll('.download-link-cli').forEach(a => { + a.href = cliAsset.browser_download_url; + }); + } + + // Find Installer if available + const installerAsset = data.assets.find(a => + a.name.toLowerCase().endsWith('.exe') || + a.name.toLowerCase().endsWith('.msi') + ); + if (installerAsset && installerAsset.browser_download_url) { + document.querySelectorAll('.download-link-installer').forEach(a => { + a.href = installerAsset.browser_download_url; + }); + } + } catch (e) { + // Offline or rate-limited; fallback static links already in HTML + } + } + + fetchLatestReleaseAssets(); + // 5. Scroll Reveal Observer const reveals = document.querySelectorAll('.reveal-on-scroll'); if (reveals.length && 'IntersectionObserver' in window) { @@ -206,19 +272,5 @@ document.addEventListener('DOMContentLoaded', () => { } }); - // 8. Newsletter Form - const newsletterForm = document.getElementById('newsletterForm'); - const newsletterMsg = document.getElementById('newsletterMsg'); - if (newsletterForm && newsletterMsg) { - newsletterForm.addEventListener('submit', (e) => { - e.preventDefault(); - const emailInput = document.getElementById('newsletterEmail'); - if (emailInput && emailInput.value) { - localStorage.setItem('tok_newsletter_subscribed', emailInput.value); - newsletterMsg.textContent = 'תודה רבה! נרשמת בהצלחה לעדכוני המחקר והקוד של TypesetOK.'; - newsletterMsg.style.display = 'block'; - emailInput.value = ''; - } - }); - } }); + diff --git a/assets/js/playground.js b/assets/js/playground.js deleted file mode 100644 index 7e5b76e..0000000 --- a/assets/js/playground.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * TypesetOK — Interactive Typography & Layout Playground - * Provides real-time parameter tweaking for Hebrew typesetting demonstration. - */ -document.addEventListener('DOMContentLoaded', () => { - const specimenPage = document.getElementById('playgroundSpecimenPage'); - const specimenText = document.getElementById('playgroundSpecimenText'); - - if (!specimenPage || !specimenText) return; - - // Sliders & Value Badges - const fontSizeSlider = document.getElementById('pgFontSize'); - const fontSizeVal = document.getElementById('pgFontSizeVal'); - - const lineHeightSlider = document.getElementById('pgLineHeight'); - const lineHeightVal = document.getElementById('pgLineHeightVal'); - - const colGapSlider = document.getElementById('pgColGap'); - const colGapVal = document.getElementById('pgColGapVal'); - - // Segmented Buttons - const colButtons = document.querySelectorAll('.pg-col-btn'); - const tierButtons = document.querySelectorAll('.pg-tier-btn'); - - // Toggles - const toggleNikud = document.getElementById('pgToggleNikud'); - const toggleBaseline = document.getElementById('pgToggleBaseline'); - const resetBtn = document.getElementById('pgResetBtn'); - - // Text Datasets - const textWithNikud = ` -- דֵּעוֹת הַרְבֵּה יֵשׁ לְכָל אֶחָד וְאֶחָד מִבְּנֵי אָדָם, וְזוֹ מְשֻׁנָּה מִזּוֹ וּרְחוֹקָה מִמֶּנָּה בְּיוֹתֵר: - יֵשׁ אָדָם שֶׁהוּא בַּעַל חֵמָה כּוֹעֵס תָּמִיד, וְיֵשׁ אָדָם שֶׁדַּעְתּוֹ מְיוּשֶׁבֶת עָלָיו וְאֵינוֹ כּוֹעֵס כְּלָל; - וְיֵשׁ אָדָם שֶׁהוּא גְּבַהּ לֵב בְּיוֹתֵר, וְיֵשׁ שֶׁהוּא שְׁפַל רוּחַ בְּתַכְלִית. - וְעַל דֶּרֶךְ זוֹ שְׁאָר כָּל הַדֵּעוֹת כֻּלָּן. - וְהַדֶּרֶךְ הַיְשָׁרָה הִיא מִדָּה בֵּינוֹנִית שֶׁבְּכָל דֵּעָה וְדֵעָה מִכָּל הַדֵּעוֹת שֶׁיֵּשׁ לוֹ לָאָדָם, - וְהִיא הַדֵּעָה שֶׁהִיא רְחוֹקָה מִשְּׁנֵי הַקְּצָווֹת רִחוּק שָׁוֶה, וְאֵינָהּ קְרוֹבָה לֹא לָזוֹ וְלֹא לָזוֹ. - לְפִיכָךְ צִוּוּ חֲכָמִים הָרִאשׁוֹנִים שֶׁיְּהֵא אָדָם שָׁם דֵּעוֹתָיו תָּמִיד וּמְשַׁעֵר אוֹתָן וּמְכַוֵּן אוֹתָן - בַּדֶּרֶךְ הָאֶמְצָעִית כְּדֵי שֶׁיְּהֵא שָׁלֵם בְּגוּפוֹ וּבְנַפְשׁוֹ. -
-- וּמְצֻוִּין אָנוּ לָלֶכֶת בִּדְרָכָיו אֵלּוּ, שֶׁנֶּאֱמַר "וְהָלַכְתָּ בִּדְרָכָיו". - וְכָךְ לִמְּדוּ בְּפֵרוּשׁ מִצְוָה זוֹ: מָה הוּא נִקְרָא חַנּוּן, אַף אַתָּה הֱיֵה חַנּוּן; - מָה הוּא נִקְרָא רַחוּם, אַף אַתָּה הֱיֵה רַחוּם; מָה הוּא נִקְרָא קָדוֹשׁ, אַף אַתָּה הֱיֵה קָדוֹשׁ. -
- `; - - const textWithoutNikud = ` -- דעות הרבה יש לכל אחד ואחד מבני אדם, וזו משונה מזו ורחוקה ממנה ביותר: - יש אדם שהוא בעל חמה כועס תמיד, ויש אדם שדעתו מיושבת עליו ואינו כועס כלל; - ויש אדם שהוא גבה לב ביותר, ויש שהוא שפל רוח בתכלית. - ועל דרך זו שאר כל הדעות כולן. - והדרך הישרה היא מידה בינונית שבכל דעה ודעה מכל הדעות שיש לו לאדם, - והיא הדעה שהיא רחוקה משני הקצוות ריחוק שווה, ואינה קרובה לא לזו ולא לזו. - לפיכך ציוו חכמים הראשונים שיהא אדם שם דעותיו תמיד ומשער אותן ומכוון אותן - בדרך האמצעית כדי שיהא שלם בגופו ובנפשו. -
-- ומצווין אנו ללכת בדרכיו אלו, שנאמר "והלכת בדרכיו". - וכך לימדו בפירוש מצווה זו: מה הוא נקרא חנון, אף אתה היה חנון; - מה הוא נקרא רחום, אף אתה היה רחום; מה הוא נקרא קדוש, אף אתה היה קדוש. -
- `; - - let currentNikud = true; - let currentTier = 'tier-2'; - - function applyTierStyles() { - specimenText.classList.remove('tier-1-style', 'tier-2-style', 'tier-3-style'); - specimenText.classList.add(`${currentTier}-style`); - - if (currentTier === 'tier-2') { - // Highlight extending letters in Tier 2 - const paragraphs = specimenText.querySelectorAll('p'); - paragraphs.forEach(p => { - // Wrap instances of expanding letters (אהלתר"ם) in end-of-line candidates - p.innerHTML = p.innerHTML.replace(/(תָּמִיד|בְּיוֹתֵר|לָאָדָם|בַּדֶּרֶךְ|בְּגוּפוֹ|בִּדְרָכָיו)/g, - ''); - }); - } - } - - // Font Size - if (fontSizeSlider && fontSizeVal) { - fontSizeSlider.addEventListener('input', (e) => { - const val = e.target.value; - specimenText.style.fontSize = `${val}px`; - fontSizeVal.textContent = `${val}px`; - }); - } - - // Line Height - if (lineHeightSlider && lineHeightVal) { - lineHeightSlider.addEventListener('input', (e) => { - const val = e.target.value; - specimenText.style.lineHeight = val; - lineHeightVal.textContent = val; - }); - } - - // Column Gap - if (colGapSlider && colGapVal) { - colGapSlider.addEventListener('input', (e) => { - const val = e.target.value; - specimenText.style.columnGap = `${val}px`; - colGapVal.textContent = `${val}px`; - }); - } - - // Column Count Buttons - colButtons.forEach(btn => { - btn.addEventListener('click', () => { - colButtons.forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - const cols = btn.dataset.cols; - specimenText.style.columnCount = cols; - }); - }); - - // Justification Tier Buttons - tierButtons.forEach(btn => { - btn.addEventListener('click', () => { - tierButtons.forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - currentTier = btn.dataset.tier; - renderText(); - }); - }); - - // Nikud Toggle - if (toggleNikud) { - toggleNikud.addEventListener('click', () => { - currentNikud = !currentNikud; - toggleNikud.classList.toggle('active', currentNikud); - toggleNikud.setAttribute('aria-checked', currentNikud ? 'true' : 'false'); - renderText(); - }); - } - - // Baseline Grid Toggle - if (toggleBaseline) { - toggleBaseline.addEventListener('click', () => { - const isActive = specimenPage.classList.toggle('show-baseline'); - toggleBaseline.classList.toggle('active', isActive); - toggleBaseline.setAttribute('aria-checked', isActive ? 'true' : 'false'); - }); - } - - function renderText() { - specimenText.innerHTML = currentNikud ? textWithNikud : textWithoutNikud; - applyTierStyles(); - } - - // Reset to default - if (resetBtn) { - resetBtn.addEventListener('click', () => { - if (fontSizeSlider) { fontSizeSlider.value = 18; specimenText.style.fontSize = '18px'; fontSizeVal.textContent = '18px'; } - if (lineHeightSlider) { lineHeightSlider.value = 1.65; specimenText.style.lineHeight = '1.65'; lineHeightVal.textContent = '1.65'; } - if (colGapSlider) { colGapSlider.value = 24; specimenText.style.columnGap = '24px'; colGapVal.textContent = '24px'; } - - colButtons.forEach(b => b.classList.toggle('active', b.dataset.cols === '2')); - specimenText.style.columnCount = 2; - - tierButtons.forEach(b => b.classList.toggle('active', b.dataset.tier === 'tier-2')); - currentTier = 'tier-2'; - - currentNikud = true; - if (toggleNikud) toggleNikud.classList.add('active'); - - if (toggleBaseline) { - toggleBaseline.classList.remove('active'); - specimenPage.classList.remove('show-baseline'); - } - - renderText(); - }); - } - - // Initial render - renderText(); -}); diff --git a/assets/js/workbench.js b/assets/js/workbench.js deleted file mode 100644 index c316648..0000000 --- a/assets/js/workbench.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * TypesetOK — Desktop Workbench Interactive Preview - * Allows exploring the real architecture and panels of TypesetOK. - */ -document.addEventListener('DOMContentLoaded', () => { - const treeItems = document.querySelectorAll('.wb-tree-item'); - const propNodeName = document.getElementById('wbPropNodeName'); - const propUlid = document.getElementById('wbPropUlid'); - const propFracIndex = document.getElementById('wbPropFracIndex'); - const propDemerits = document.getElementById('wbPropDemerits'); - const propStatus = document.getElementById('wbPropStatus'); - - const menuItems = document.querySelectorAll('.wb-menu-item'); - const renderedPage = document.getElementById('wbRenderedPage'); - const zoomSelect = document.getElementById('wbZoomSelect'); - - if (!treeItems.length) return; - - // Tree Node Data Map - const nodeData = { - 'doc-root': { - name: 'DocumentRoot', - ulid: '01HX5K3T9R0000000000000001', - frac: '1.0', - demerits: '0 (Optimal)', - status: 'Clean (Valid)' - }, - 'sec-1': { - name: 'SectionNode [הלכות דעות]', - ulid: '01HX5K3T9R9Z9435K7J1M8P2Q4', - frac: '1.25', - demerits: '0', - status: 'Active Section' - }, - 'flow-main': { - name: 'Flow [TextFlow::Main]', - ulid: '01HX5K3T9R88A123BCDEFGHJKL', - frac: '1.2501', - demerits: '12 (Target: <50)', - status: 'typeset (120 FPS)' - }, - 'p-1': { - name: 'Paragraph [דעות הרבה...]', - ulid: '01HX5K3T9R77B987XYZWVUTSRQ', - frac: '1.2501005', - demerits: '4 (Balanced)', - status: 'אהלתר"ם Expanded' - }, - 'p-2': { - name: 'Paragraph [ומצווין אנו...]', - ulid: '01HX5K3T9R66C543MNBVCXZLKJ', - frac: '1.2501010', - demerits: '0', - status: 'typeset' - } - }; - - // Node Click Selection - treeItems.forEach(item => { - item.addEventListener('click', () => { - treeItems.forEach(i => i.classList.remove('selected')); - item.classList.add('selected'); - - const key = item.dataset.nodeKey; - const data = nodeData[key]; - if (data && propNodeName) { - propNodeName.textContent = data.name; - propUlid.textContent = data.ulid; - propFracIndex.textContent = data.frac; - propDemerits.textContent = data.demerits; - propStatus.textContent = data.status; - } - }); - }); - - // Top Menubar Item Click - menuItems.forEach(item => { - item.addEventListener('click', () => { - menuItems.forEach(m => m.classList.remove('active')); - item.classList.add('active'); - }); - }); - - // Zoom control - if (zoomSelect && renderedPage) { - zoomSelect.addEventListener('change', (e) => { - const zoom = e.target.value; - if (zoom === 'fit') { - renderedPage.style.transform = 'scale(0.88)'; - } else if (zoom === '100') { - renderedPage.style.transform = 'scale(1.0)'; - } else if (zoom === '125') { - renderedPage.style.transform = 'scale(1.15)'; - } - }); - } -}); diff --git a/index.html b/index.html index 31d5f4f..c224732 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + @@ -8,9 +8,8 @@