claude go reimplement
This commit is contained in:
1 parent
4bcb924158
commit
f523c79618
83 files changed
+3714
-3454
No files matched your search
@@ -0,0 +1 @@
|
||||
{"a": ["A is the first letter of the Alphabet in most of the known languages of the earth; in the Ethiopic, however it is the thirteenth, and in the Runic the tenth. It is naturally the first letter, because it represents the first vocal sound naturally formed by the human organs; being the sound uttered with a mere opening of the mouth without constraint, and without any effort to alter the natural position or configuration of the lips. The A has been proven to be the first natural vocal sound, and entitled to the first place in alphabets.", "A has in English, three sounds; the long or slender, as in place, fate; the broad, as in wall, fall, which is shortened in salt, what; and the open, as in father, glass, which is shortened in rather, fancy. Its primitive sound was probably aw. A is also an abbreviation used before words beginning with an articulation; as a table, instead of an table, or one table. This is a modern change.", "This letter serves as a prefix to many English words, as in asleep; awake; afoot; aground; agoing. In some cases, this is a contraction of Teutonic ge, as in asleep, aware, from the Saxon geslapan, to sleep, to beware. Sometimes it is a corruption of the Saxon on, as again from ongean , awake from onwacian to watch or wake. Before participles, it may be a contraction of the Celtic ag, the sign of the participle of the present tense; as, ag-radh, saying; a saying, a going. Or this may be a contraction of on, or what is equally probable, it may have proceeded from a mere accidental sound produced by negligent utterance. In some words, a may be a contraction of at, of, in, to, or an. In some words of Greek original, a is privative, giving to them a negative sense, as in anonymous.", "Among the ancients, A was a numeral denoting 500, and with a dash A 5000. In the Julian Calendar, A is the first of the seven dominical letters.", "Among logicians, A, as an abbreviation, stands for a universal affirmative proposition. A asserts; E denies. Thus in barbara, a thrice repeated denotes so many of the propositions to be universal.", "The Romans used A to signify a negative or dissent in giving their votes; A standing for antiquo, I oppose or object to the proposed law. Opposed to this letter were U R, uti rogas, be it as you desire - the words used to express assent to a proposition. These letters were marked on wooden ballots, and each voter had an affirmative and a negative put into his hands, one of which at pleasure he gave as his vote, - In criminal trials, A stood for absolvo, I acquit, C for condemno, I condemn; and N L for non liquet, it is not evident; and the judges voted by ballots this marked. In inscriptions, A stands for Augustus; or for ager, aiunt, , aurum, argentum, &c.", "A is also used for anno, or ante; as in Anno Domini, the year of our Lord; anno mundi, the year of the world; ante meridiem, before noon, and for arts, in artium magister, master of arts.", "In algebra, a and first letters of the alphabet represent known quantities - the last letters are sometimes used to represent unknown quantities.", "music, A is the nominal of the sixth note in the natural diatonic scale - called by Guido la. It is also the name of one of the two natural moods; and it is the open note of the 2d string of the violin, by which the other strings are tuned and regulated.", "In pharmacy, a or aa, abbreviations of the Greek ana, signify of each separately, or that the things mentioned should be taken in quantities of the same weight or measure.", "In chimistry, A A A stand for amalgama, or amalgamation.", "In commerce, A stands for accepted, as in case of a bill of exchange. Merchants also number their books by the letters - A,B,C, instead of figures. Public officers number their exhibits in the same manner; as the document A, or B.", "Alpha and Omega, the first and last letters of the Greek Alphabet, are used in Scripture for the beginning and end - representative of Christ.", "In mathematics, letters are used as representatives of numbers, lines, angles and quantities. In arguments, letters are substituted for persons, in cases supposed, or stated for illustration, as A contracts with B to deliver property to D. - In the English phraseology \"a landlord as a hundred a year,\" \" the sum amounted to ten dollars a man,\" a is merely the adjective one, and this mode of expression is idiomatic; a hundred in a year; ten dollars to a man."], "aaronic": ["AARON'IC, a. Pertaining to Aaron, the Jewish High Priest, or to the priesthood of which he was the head."], "abaddon": ["ABAD'DON, n. Heb. Ch. Syr. Sam. to be lost, or destroyed, to perish.", "1. The destroyer, or angel of the bottomless pit. Rev. ix.", "2. The bottomless pit."], "abase": ["ABA'SE, v.t. Fr abaisser, from bas, low, or the bottom; W. bais; Latin and Gr. basis; Eng. base; It. Abbassare; Sp. bare, low. See Abash.", "1. The literal sense of abase is to lower or depress, to throw or cast down, as used by Bacon, \"to abase the eye.\" BLine truncated
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"Genesis": "Creation, the fall, the flood, and the patriarchs Abraham, Isaac, Jacob and Joseph.",
|
||||
"Exodus": "Israel's deliverance from Egypt, the Law at Sinai, and the building of the tabernacle.",
|
||||
"Leviticus": "God's laws for offerings, priests, holiness and the feasts of Israel.",
|
||||
"Numbers": "Israel's census and forty years of wandering in the wilderness.",
|
||||
"Deuteronomy": "Moses' final sermons, restating the Law before Israel enters the promised land.",
|
||||
"Joshua": "Israel crosses the Jordan, conquers Canaan and divides the land.",
|
||||
"Judges": "A cycle of sin and rescue as God raises up judges over Israel.",
|
||||
"Ruth": "A Moabite widow's faithfulness and her redeemer Boaz, an ancestor of David.",
|
||||
"1 Samuel": "Samuel, the rise and failure of King Saul, and David's anointing.",
|
||||
"2 Samuel": "David's reign over Israel, his sin with Bathsheba, and the troubles that followed.",
|
||||
"1 Kings": "Solomon's glory and temple, the divided kingdom, and the prophet Elijah.",
|
||||
"2 Kings": "The decline of Israel and Judah to exile in Assyria and Babylon.",
|
||||
"1 Chronicles": "Genealogies from Adam and the reign of David, with a focus on worship.",
|
||||
"2 Chronicles": "Solomon's temple and the kings of Judah, ending with the exile.",
|
||||
"Ezra": "The return from Babylon and the rebuilding of the temple.",
|
||||
"Nehemiah": "The rebuilding of Jerusalem's walls and the people's renewed covenant.",
|
||||
"Esther": "A Jewish queen in Persia saves her people from Haman's plot.",
|
||||
"Job": "A righteous man suffers loss and questions, and God answers him.",
|
||||
"Psalms": "Songs and prayers of praise, lament, trust and thanksgiving.",
|
||||
"Proverbs": "Short sayings of wisdom for godly living.",
|
||||
"Ecclesiastes": "The Preacher finds life under the sun empty without fearing God.",
|
||||
"Song of Solomon": "A poem of love between a bridegroom and his bride.",
|
||||
"Isaiah": "Prophecies of judgment and comfort, and of the coming Messiah and His kingdom.",
|
||||
"Jeremiah": "The weeping prophet warns Judah of Babylon's coming and promises a new covenant.",
|
||||
"Lamentations": "Poems of grief over the fall of Jerusalem.",
|
||||
"Ezekiel": "Visions of judgment on Jerusalem, and of Israel's restoration and a new temple.",
|
||||
"Daniel": "Faithful Daniel in Babylon, the lions' den, and visions of coming kingdoms.",
|
||||
"Hosea": "God's faithful love for unfaithful Israel, pictured in the prophet's marriage.",
|
||||
"Joel": "A plague of locusts calls Judah to repent and promises the Spirit poured out.",
|
||||
"Amos": "A herdsman prophet condemns injustice and warns Israel of judgment.",
|
||||
"Obadiah": "Judgment on Edom for its pride and its violence against Judah.",
|
||||
"Jonah": "A reluctant prophet flees God, is swallowed by a fish, and preaches to Nineveh.",
|
||||
"Micah": "Judgment on Israel's rulers, and the promise of a ruler born in Bethlehem.",
|
||||
"Nahum": "The coming destruction of Nineveh.",
|
||||
"Habakkuk": "The prophet questions God about evil and learns that the just shall live by faith.",
|
||||
"Zephaniah": "The coming day of the LORD and a promise to restore a remnant.",
|
||||
"Haggai": "A call to the returned exiles to rebuild the temple.",
|
||||
"Zechariah": "Visions and prophecies encouraging the rebuilding, and of the coming King.",
|
||||
"Malachi": "A last warning to a careless people, and the promise of a messenger before the LORD.",
|
||||
"Matthew": "The gospel of Jesus Christ as the promised King of the Jews.",
|
||||
"Mark": "A fast-moving gospel of Jesus as the servant who died and rose again.",
|
||||
"Luke": "A careful account of the life of Jesus, the Son of man who came to seek the lost.",
|
||||
"John": "The gospel of Jesus as the Son of God, written that you might believe and have life.",
|
||||
"Acts": "The apostles spread the gospel from Jerusalem to Rome after Christ's ascension.",
|
||||
"Romans": "Salvation by grace through faith, for Jew and Gentile alike.",
|
||||
"1 Corinthians": "Paul corrects divisions and disorder in the church, and teaches on love and the resurrection.",
|
||||
"2 Corinthians": "Paul defends his ministry and encourages comfort and generosity.",
|
||||
"Galatians": "Freedom in Christ: we are justified by faith, not by the works of the law.",
|
||||
"Ephesians": "The church as Christ's body, saved by grace and called to walk worthy.",
|
||||
"Philippians": "A joyful letter on Christ's humility and rejoicing in all circumstances.",
|
||||
"Colossians": "Christ is supreme over all, and complete in Him.",
|
||||
"1 Thessalonians": "Encouragement to the young church, and the hope of Christ's return.",
|
||||
"2 Thessalonians": "Correction about the day of the Lord, and a call to steadfast work.",
|
||||
"1 Timothy": "Paul's instructions to a young pastor on church order and sound doctrine.",
|
||||
"2 Timothy": "Paul's last letter, urging Timothy to be faithful and preach the word.",
|
||||
"Titus": "Qualifications for elders and good works in the churches of Crete.",
|
||||
"Philemon": "Paul appeals to Philemon to receive back his runaway servant Onesimus as a brother.",
|
||||
"Hebrews": "Christ is better than the angels, Moses and the priests, and faith endures.",
|
||||
"James": "Practical faith: be doers of the word, control the tongue, and pray.",
|
||||
"1 Peter": "Hope and holy living for believers who suffer for Christ.",
|
||||
"2 Peter": "Grow in grace and knowledge, and beware of false teachers and scoffers.",
|
||||
"1 John": "Fellowship with God: walk in light, love one another, and know you have eternal life.",
|
||||
"2 John": "A short warning to walk in truth and love and to avoid deceivers.",
|
||||
"3 John": "Praise for hospitality to travelling believers, and a rebuke of Diotrephes.",
|
||||
"Jude": "A call to contend for the faith against ungodly men.",
|
||||
"Revelation": "Visions of Christ, the churches, coming judgments, and the new heaven and earth."
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,142 @@
|
||||
[
|
||||
{
|
||||
"query": "rapture",
|
||||
"explanation": "The word 'rapture' does not appear in the KJV, but is usually a reference to believers being caught up to meet Christ in the air.",
|
||||
"search_terms": ["caught up", "meet the lord in the air"]
|
||||
},
|
||||
{
|
||||
"query": "trinity",
|
||||
"explanation": "The word 'trinity' does not appear in the KJV, but is usually a reference to the doctrine of the triune God (Father, Son, and Holy Spirit).",
|
||||
"search_terms": ["father son holy ghost", "three that bear record"]
|
||||
},
|
||||
{
|
||||
"query": "missionary",
|
||||
"explanation": "The word 'missionary' does not appear in the KJV, but is usually a reference to being sent to preach the gospel.",
|
||||
"search_terms": ["go ye therefore", "preach the gospel", "sent"]
|
||||
},
|
||||
{
|
||||
"query": "bible",
|
||||
"explanation": "The word 'bible' does not appear in the KJV, but is usually a reference to the scriptures and God's word.",
|
||||
"search_terms": ["scripture", "word of god", "holy scriptures"]
|
||||
},
|
||||
{
|
||||
"query": "inerrancy",
|
||||
"explanation": "The word 'inerrancy' does not appear in the KJV, but is usually a reference to the perfection and preservation of God's word.",
|
||||
"search_terms": ["word of god", "scripture", "thou hast magnified thy word"]
|
||||
},
|
||||
{
|
||||
"query": "antichrist system",
|
||||
"explanation": "The phrase 'antichrist system' is usually a reference to the antichrist and end times deception.",
|
||||
"search_terms": ["antichrist", "man of sin", "son of perdition", "beast"]
|
||||
},
|
||||
{
|
||||
"query": "pre-tribulation",
|
||||
"explanation": "The phrase 'pre-tribulation' does not appear in the KJV, but is usually a reference to Christ's return before the tribulation.",
|
||||
"search_terms": ["caught up", "great tribulation", "day of the lord"]
|
||||
},
|
||||
{
|
||||
"query": "soul winning",
|
||||
"explanation": "The phrase 'soul winning' does not appear in the KJV, but is usually a reference to winning souls and converting sinners.",
|
||||
"search_terms": ["winneth souls", "save souls", "convert"]
|
||||
},
|
||||
{
|
||||
"query": "guardian angel",
|
||||
"explanation": "The phrase 'guardian angel' does not appear in the KJV, but is usually a reference to angels and their protective ministry.",
|
||||
"search_terms": ["angel", "ministering spirits", "charge over thee"]
|
||||
},
|
||||
{
|
||||
"query": "angel wings",
|
||||
"explanation": "The phrase 'angel wings' does not appear in the KJV, but is usually a reference to biblical descriptions of angels.",
|
||||
"search_terms": ["angel", "seraphim", "cherubim", "wings"]
|
||||
},
|
||||
{
|
||||
"query": "7 deadly sins",
|
||||
"explanation": "The phrase '7 deadly sins' does not appear in the KJV (it's a Catholic tradition), but is usually a reference to biblical lists of sins.",
|
||||
"search_terms": ["abomination", "works of the flesh", "evil"]
|
||||
},
|
||||
{
|
||||
"query": "purgatory",
|
||||
"explanation": "The word 'purgatory' does not appear in the KJV. This is a Catholic doctrine not found in scripture.",
|
||||
"search_terms": ["appointed unto men once to die", "after this the judgment", "absent from the body"]
|
||||
},
|
||||
{
|
||||
"query": "christmas",
|
||||
"explanation": "The word 'christmas' does not appear in the KJV, but is usually a reference to the birth of Christ.",
|
||||
"search_terms": ["born in bethlehem", "manger", "wise men", "shepherds"]
|
||||
},
|
||||
{
|
||||
"query": "easter",
|
||||
"explanation": "The word 'easter' appears once in the KJV (Acts 12:4) referring to Passover, but is usually a reference to Christ's resurrection.",
|
||||
"search_terms": ["easter", "resurrection", "rose again", "third day"]
|
||||
},
|
||||
{
|
||||
"query": "lucifer",
|
||||
"explanation": "The name 'Lucifer' appears once in the KJV (Isaiah 14:12), but is usually a reference to Satan and his fall.",
|
||||
"search_terms": ["lucifer", "devil", "satan", "dragon", "serpent"]
|
||||
},
|
||||
{
|
||||
"query": "666",
|
||||
"explanation": "The number '666' is usually a reference to the mark of the beast.",
|
||||
"search_terms": ["six hundred threescore and six", "mark", "number of his name"]
|
||||
},
|
||||
{
|
||||
"query": "four horsemen",
|
||||
"explanation": "The phrase 'four horsemen' does not appear exactly in the KJV, but is usually a reference to the four horsemen of the apocalypse.",
|
||||
"search_terms": ["horse", "seal", "rider"]
|
||||
},
|
||||
{
|
||||
"query": "end of the world",
|
||||
"explanation": "The phrase 'end of the world' is usually a reference to the end times and Christ's return.",
|
||||
"search_terms": ["end of the world", "last days", "coming of the lord"]
|
||||
},
|
||||
{
|
||||
"query": "left behind",
|
||||
"explanation": "The phrase 'left behind' is usually a reference to the rapture and second coming.",
|
||||
"search_terms": ["one shall be taken", "left", "coming of the son of man"]
|
||||
},
|
||||
{
|
||||
"query": "prosperity gospel",
|
||||
"explanation": "The phrase 'prosperity gospel' does not appear in the KJV. This is a false doctrine. Biblical warnings against covetousness and false teachers:",
|
||||
"search_terms": ["love of money", "covetousness", "false prophets", "perverse disputings"]
|
||||
},
|
||||
{
|
||||
"query": "speaking in tongues",
|
||||
"explanation": "The phrase 'speaking in tongues' is usually a reference to tongues and spiritual gifts.",
|
||||
"search_terms": ["tongues", "unknown tongue", "interpretation"]
|
||||
},
|
||||
{
|
||||
"query": "slain in the spirit",
|
||||
"explanation": "The phrase 'slain in the spirit' does not appear in the KJV. This is a charismatic practice not found in scripture.",
|
||||
"search_terms": ["holy ghost", "filled with the spirit", "spirit of god"]
|
||||
},
|
||||
{
|
||||
"query": "original sin",
|
||||
"explanation": "The phrase 'original sin' does not appear in the KJV, but is usually a reference to the doctrine of inherited sin from Adam.",
|
||||
"search_terms": ["all have sinned", "by one man sin entered", "in adam all die"]
|
||||
},
|
||||
{
|
||||
"query": "the chosen",
|
||||
"explanation": "The phrase 'the chosen' is usually a reference to God's elect and chosen people.",
|
||||
"search_terms": ["chosen", "elect", "called"]
|
||||
},
|
||||
{
|
||||
"query": "good samaritan",
|
||||
"explanation": "The phrase 'good samaritan' is usually a reference to the parable of the good Samaritan.",
|
||||
"search_terms": ["certain samaritan", "neighbour", "priest levite"]
|
||||
},
|
||||
{
|
||||
"query": "prodigal son",
|
||||
"explanation": "The phrase 'prodigal son' is usually a reference to the parable of the prodigal son.",
|
||||
"search_terms": ["younger son", "riotous living", "father said", "was lost"]
|
||||
},
|
||||
{
|
||||
"query": "jezebel spirit",
|
||||
"explanation": "The phrase 'jezebel spirit' does not appear in the KJV (it's a charismatic term), but is usually a reference to Jezebel and false prophetesses.",
|
||||
"search_terms": ["jezebel", "that woman", "seduceth"]
|
||||
},
|
||||
{
|
||||
"query": "generational curse",
|
||||
"explanation": "The phrase 'generational curse' does not appear in the KJV (it's a charismatic term), but is usually a reference to visiting iniquity upon children.",
|
||||
"search_terms": ["visiting the iniquity", "fathers", "children"]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
[
|
||||
["you", "ye", "thee", "thou"],
|
||||
["your", "thy", "thine"],
|
||||
["have", "has", "hath", "hast"],
|
||||
["do", "does", "doth", "doest"],
|
||||
["say", "says", "said", "saith"],
|
||||
["are", "art"],
|
||||
["was", "were", "wast", "wert"],
|
||||
["will", "wilt", "shall", "shalt"],
|
||||
["go", "goes", "goeth", "goest"],
|
||||
["know", "knows", "knoweth", "knowest"],
|
||||
["see", "sees", "seeth", "seest"],
|
||||
["give", "gives", "giveth", "givest"],
|
||||
["make", "makes", "maketh", "makest"],
|
||||
["come", "comes", "cometh", "comest"],
|
||||
["take", "takes", "taketh", "takest"],
|
||||
["can", "canst"],
|
||||
["may", "mayest"],
|
||||
["hear", "hears", "heareth", "hearest"],
|
||||
["walk", "walks", "walketh", "walkest"],
|
||||
["speak", "speaks", "speaketh", "speakest"],
|
||||
["live", "lives", "liveth", "livest"],
|
||||
["call", "calls", "calleth", "callest"],
|
||||
["fear", "fears", "feareth", "fearest"],
|
||||
["love", "loves", "loveth", "lovest"],
|
||||
["believe", "believes", "believeth", "believest"],
|
||||
["did", "didst"],
|
||||
["eat", "eats", "eateth", "eatest"],
|
||||
["among", "amongst"],
|
||||
["until", "till", "unto"],
|
||||
["afterward", "afterwards"],
|
||||
["before", "ere"],
|
||||
["also", "moreover", "furthermore"],
|
||||
["therefore", "wherefore", "thus"],
|
||||
["because", "for"],
|
||||
["indeed", "verily"],
|
||||
["behold", "lo"],
|
||||
["ask", "asks", "asketh", "askest"],
|
||||
["find", "finds", "findeth", "findest"],
|
||||
["seek", "seeks", "seeketh", "seekest"],
|
||||
["trust", "trusts", "trusteth", "trustest"],
|
||||
["follow", "follows", "followeth", "followest"],
|
||||
["serve", "serves", "serveth", "servest"],
|
||||
["teach", "teaches", "teacheth", "teachest"],
|
||||
["think", "thinks", "thinketh", "thinkest"],
|
||||
["lead", "leads", "leadeth", "leadest"],
|
||||
["rejoice", "rejoices", "rejoiceth", "rejoicest"],
|
||||
["keep", "keeps", "keepeth", "keepest"],
|
||||
["abide", "abides", "abideth", "abidest"],
|
||||
["judge", "judges", "judgeth", "judgest"],
|
||||
["die", "dies", "dieth", "diest"],
|
||||
["rise", "rises", "riseth", "risest"],
|
||||
["reign", "reigns", "reigneth", "reignest"]
|
||||
]
|
||||
@@ -0,0 +1,109 @@
|
||||
SET UTF-8
|
||||
TRY esiaénrtolcdugmfphbyvkw-'.zqjxSNRTLCGDMFPHBEAUYOIVKWóöâôZQJXÅçèîêàïüäñ
|
||||
ICONV 1
|
||||
ICONV ’ '
|
||||
NOSUGGEST !
|
||||
|
||||
# ordinal numbers
|
||||
COMPOUNDMIN 1
|
||||
# only in compounds: 1th, 2th, 3th
|
||||
ONLYINCOMPOUND c
|
||||
# compound rules:
|
||||
# 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
|
||||
# 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
|
||||
COMPOUNDRULE 2
|
||||
COMPOUNDRULE n*1t
|
||||
COMPOUNDRULE n*mp
|
||||
WORDCHARS 0123456789’
|
||||
|
||||
REP 90
|
||||
REP a ei
|
||||
REP ei a
|
||||
REP a ey
|
||||
REP ey a
|
||||
REP ai ie
|
||||
REP ie ai
|
||||
REP alot a_lot
|
||||
REP are air
|
||||
REP are ear
|
||||
REP are eir
|
||||
REP air are
|
||||
REP air ere
|
||||
REP ere air
|
||||
REP ere ear
|
||||
REP ere eir
|
||||
REP ear are
|
||||
REP ear air
|
||||
REP ear ere
|
||||
REP eir are
|
||||
REP eir ere
|
||||
REP ch te
|
||||
REP te ch
|
||||
REP ch ti
|
||||
REP ti ch
|
||||
REP ch tu
|
||||
REP tu ch
|
||||
REP ch s
|
||||
REP s ch
|
||||
REP ch k
|
||||
REP k ch
|
||||
REP f ph
|
||||
REP ph f
|
||||
REP gh f
|
||||
REP f gh
|
||||
REP i igh
|
||||
REP igh i
|
||||
REP i uy
|
||||
REP uy i
|
||||
REP i ee
|
||||
REP ee i
|
||||
REP j di
|
||||
REP di j
|
||||
REP j gg
|
||||
REP gg j
|
||||
REP j ge
|
||||
REP ge j
|
||||
REP s ti
|
||||
REP ti s
|
||||
REP s ci
|
||||
REP ci s
|
||||
REP k cc
|
||||
REP cc k
|
||||
REP k qu
|
||||
REP qu k
|
||||
REP kw qu
|
||||
REP o eau
|
||||
REP eau o
|
||||
REP o ew
|
||||
REP ew o
|
||||
REP oo ew
|
||||
REP ew oo
|
||||
REP ew ui
|
||||
REP ui ew
|
||||
REP oo ui
|
||||
REP ui oo
|
||||
REP ew u
|
||||
REP u ew
|
||||
REP oo u
|
||||
REP u oo
|
||||
REP u oe
|
||||
REP oe u
|
||||
REP u ieu
|
||||
REP ieu u
|
||||
REP ue ew
|
||||
REP ew ue
|
||||
REP uff ough
|
||||
REP oo ieu
|
||||
REP ieu oo
|
||||
REP ier ear
|
||||
REP ear ier
|
||||
REP ear air
|
||||
REP air ear
|
||||
REP w qu
|
||||
REP qu w
|
||||
REP z ss
|
||||
REP ss z
|
||||
REP shun tion
|
||||
REP shun sion
|
||||
REP shun cion
|
||||
REP size cise
|
||||
+12707
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,104 @@
|
||||
[
|
||||
["charity", "love"],
|
||||
["ghost", "spirit"],
|
||||
["righteousness", "holiness"],
|
||||
["salvation", "redemption"],
|
||||
["faith", "belief"],
|
||||
["sin", "iniquity", "transgression"],
|
||||
["forgive", "pardon"],
|
||||
["anger", "wrath"],
|
||||
["witness", "testify", "testimony"],
|
||||
["heaven", "paradise"],
|
||||
["hell", "damnation"],
|
||||
["pray", "prayer", "supplication"],
|
||||
["bless", "blessed", "blessing"],
|
||||
["promise", "covenant"],
|
||||
["worship", "praise"],
|
||||
["disciple", "apostle"],
|
||||
["eternal", "everlasting"],
|
||||
["demon", "devil"],
|
||||
["miracle", "wonder", "sign"],
|
||||
["prophesy", "prophecy"],
|
||||
["resurrect", "resurrection", "rise", "risen"],
|
||||
["baptize", "baptism"],
|
||||
["tempt", "temptation"],
|
||||
["humble", "meek"],
|
||||
["wise", "wisdom"],
|
||||
["truth", "true"],
|
||||
["glory", "glorify"],
|
||||
["mercy", "compassion"],
|
||||
["grace", "favor"],
|
||||
["judge", "judgment", "condemn", "condemnation"],
|
||||
["command", "commandment"],
|
||||
["rejoice", "joy", "gladness"],
|
||||
["reverence", "fear"],
|
||||
["teach", "doctrine"],
|
||||
["preach", "proclaim"],
|
||||
["suffer", "suffering", "affliction"],
|
||||
["comfort", "console"],
|
||||
["obey", "obedience"],
|
||||
["peace", "rest"],
|
||||
["repent", "repentance", "turn"],
|
||||
["holy", "sanctify", "sanctified"],
|
||||
["nation", "gentile"],
|
||||
["Israel", "Jew", "Hebrew"],
|
||||
["king", "kingdom", "reign"],
|
||||
["priest", "priesthood"],
|
||||
["covenant", "testament"],
|
||||
["temple", "tabernacle", "sanctuary"],
|
||||
["altar", "sacrifice", "offering"],
|
||||
["righteous", "just", "justice"],
|
||||
["wicked", "evil", "ungodly"],
|
||||
["servant", "minister"],
|
||||
["fornication", "whoredom", "adultery"],
|
||||
["sodomite", "abomination"],
|
||||
["pervert", "corrupt"],
|
||||
["destroy", "destruction", "perish"],
|
||||
["harlot", "whore"],
|
||||
["idolater", "idolatry"],
|
||||
["covetous", "covetousness", "greed"],
|
||||
["enemy", "adversary"],
|
||||
["avenge", "vengeance", "recompense"],
|
||||
["tribulation", "trouble", "distress"],
|
||||
["scorn", "mock", "despise"],
|
||||
["proud", "pride", "haughty"],
|
||||
["meek", "lowly", "humble"],
|
||||
["wisdom", "understanding", "knowledge"],
|
||||
["foolish", "fool", "folly"],
|
||||
["strengthen", "strong", "might"],
|
||||
["weary", "faint"],
|
||||
["prevail", "overcome"],
|
||||
["remnant", "residue"],
|
||||
["inheritance", "heir"],
|
||||
["generation", "seed", "offspring"],
|
||||
["pestilence", "plague"],
|
||||
["famine", "hunger"],
|
||||
["captivity", "bondage"],
|
||||
["deliver", "deliverance", "save"],
|
||||
["redeem", "ransom"],
|
||||
["provoke", "anger", "wrath"],
|
||||
["abhor", "hate", "detest"],
|
||||
["trust", "confidence"],
|
||||
["persecute", "persecution"],
|
||||
["blaspheme", "blasphemy"],
|
||||
["stone", "stoning"],
|
||||
["burn", "fire", "flame"],
|
||||
["beloved", "wellbeloved"],
|
||||
["delight", "pleasure"],
|
||||
["kindness", "lovingkindness"],
|
||||
["tender", "tenderness"],
|
||||
["longsuffering", "patience", "forbearance"],
|
||||
["gentleness", "meekness"],
|
||||
["goodness", "kindness"],
|
||||
["brotherly", "brother"],
|
||||
["wrath", "indignation", "fury"],
|
||||
["vengeance", "recompense", "reward"],
|
||||
["end times", "last days", "latter days"],
|
||||
["appearing", "coming", "return"],
|
||||
["trumpet", "shout", "voice"],
|
||||
["watch", "watchful", "vigilant"],
|
||||
["seal", "sealed"],
|
||||
["vial", "bowl"],
|
||||
["scroll", "book"],
|
||||
["lamb", "lion"]
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
<nav class="chapter-nav" aria-label="Chapter">
|
||||
<a class="chapter-prev" href="{prev_chapter_link}" rel="prev" aria-label="Previous chapter: {prev_chapter_name}"><span aria-hidden="true">‹</span><span class="nav-name">{prev_chapter_name}</span></a>
|
||||
<a class="chapter-current" href="{current_chapter_link}" title="Read the whole chapter">{current_chapter_name}</a>
|
||||
<a class="chapter-next" href="{next_chapter_link}" rel="next" aria-label="Next chapter: {next_chapter_name}"><span class="nav-name">{next_chapter_name}</span><span aria-hidden="true">›</span></a>
|
||||
</nav>
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Bible Dictionary - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/define">Dictionary</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>Bible Dictionary</h2>
|
||||
<form action="/define">
|
||||
<label for="kw">Word lookup</label>
|
||||
<input type="text" name="kw" id="kw" autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Enter a word to define...">
|
||||
<div class="form-row"><b>View</b><br>
|
||||
<label class="choice"><input type="radio" name="view" value="rich" checked="checked"> Rich</label>
|
||||
<label class="choice"><input type="radio" name="view" value="plain"> Plain</label>
|
||||
<label class="choice"><input type="radio" name="view" value="json"> JSON</label>
|
||||
</div>
|
||||
<input type="submit" value="Define">
|
||||
</form>
|
||||
<p>This tool uses an abridged 1828 Noah Webster dictionary.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Quick Search - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
<script src="/js/book_suggest.js?v=__V__" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a>
|
||||
<a href="/random?view=rich">Random Verse</a>
|
||||
<a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>Quick Search</h2>
|
||||
<form action="/find">
|
||||
<label for="kw">Query</label>
|
||||
<input type="text" name="kw" id="kw" data-book-suggest autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Enter verse reference or keywords...">
|
||||
<input type="hidden" name="view" value="rich">
|
||||
<input type="submit" value="Search">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>How to Be Saved - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>How to Be Saved</h2>
|
||||
<h3>1. Understand you are a sinner:</h3>
|
||||
<p>No one is good enough to go to Heaven on their own merit. No matter how much good we do, we still come short.</p>
|
||||
<p><b>Romans 3:23</b>(a) For all have sinned, and come short of the glory of God;</p>
|
||||
<p><b>Romans 3:10</b> As it is written, There is none righteous, no, not one:</p>
|
||||
|
||||
|
||||
<h3>2. Realize the penalty for your sin.</h3>
|
||||
<p>There is a payment for our sin, which is eternal death in a place called Hell and the Lake of Fire.</p>
|
||||
<p><b>Romans 6:23</b> For the wages of sin is death; but the gift of God is eternal life through Jesus Christ our Lord.</p>
|
||||
<p><b>Revelation 20:14</b> And death and hell were cast into the lake of fire. This is the second death. And whosoever was not found written in the book of life was cast into the lake of fire.</p>
|
||||
|
||||
<h3>3. Believe that Christ died, was buried and rose from the grave as a payment for your sin.</h3>
|
||||
<p>Salvation is simply putting your faith (or believing) that Jesus Christ paid for your sins.</p>
|
||||
<p><b>Romans 5:8</b> But God commendeth his love toward us, in that, while we were yet sinners, Christ died for us.</p>
|
||||
<p><b>John 3:16</b> For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</p>
|
||||
<p><b>1 Corinthians 15:3-4</b> ...Christ died for our sins according to the scriptures; And that he was buried, and that he rose again the third day according to the scriptures:</p>
|
||||
|
||||
|
||||
<h3>4. Understand that salvation will last forever.</h3>
|
||||
<p>Eternal life is a gift purchased by the blood of Jesus and offered freely to those who call upon Him. Anyone who believes on the Lord Jesus Christ will be saved forever. Being saved is a one time event.</p>
|
||||
<p><b>Titus 1:2</b> In hope of eternal life, which God, that cannot lie, promised before the world began;</p>
|
||||
<p><b>John 3:15-16</b> For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</p>
|
||||
<p>When God saves you he gives you eternal life; in other words, life that will last forever. So, when he saves you, it is forever. No matter what you do after you receive “the gift of eternal life” it can never end. Otherwise God lied, and we know that God “cannot lie”.</p>
|
||||
|
||||
<h3>5. Pray and ask Jesus Christ to save you.</h3>
|
||||
<p><b>Romans 10:9-10</b> That if thou shalt confess with thy mouth the Lord Jesus, and shalt believe in thine heart that God hath raised him from the dead, thou shalt be saved. For with the heart man believeth unto righteousness; and with the mouth confession is made unto salvation. </p>
|
||||
|
||||
<p>Let us help you word a prayer. Realize it is not mere words that save, but your faith in Jesus Christ.</p>
|
||||
<p><i>Dear Jesus, I know that I am a sinner, and I know I deserve to go to Hell. But I believe that you died on the cross, was buried, and rose from the grave to pay for my sins. Please save me and take me to Heaven when I die. Amen.</i></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,384 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KJV API - Legacy Edition</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
<script src="/js/collapsible.js?v=__V__" defer></script>
|
||||
<style>
|
||||
/* Home page layout */
|
||||
.site-title {
|
||||
margin: var(--space-md) 0 0.25rem;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
margin: 0 0 var(--space-lg);
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.search-section {
|
||||
background-color: var(--color-bg-secondary);
|
||||
padding: var(--space-lg);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--color-border);
|
||||
margin-bottom: var(--space-xl);
|
||||
box-shadow: 0 2px 8px var(--color-shadow);
|
||||
}
|
||||
|
||||
.search-section form {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.search-row input[type=text] {
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.quick-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: var(--space-sm);
|
||||
margin-top: var(--space-md);
|
||||
}
|
||||
|
||||
.quick-btn {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-border);
|
||||
padding: 0.7rem 1rem;
|
||||
min-height: 44px;
|
||||
border-radius: var(--border-radius-sm);
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
transition: background-color var(--transition-fast), border-color var(--transition-fast);
|
||||
}
|
||||
|
||||
.quick-btn:hover {
|
||||
background-color: var(--color-accent-primary);
|
||||
border-color: var(--color-accent-primary);
|
||||
color: var(--color-on-accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.testament-header {
|
||||
color: var(--color-accent-primary);
|
||||
font-size: 1.6rem;
|
||||
margin-top: var(--space-2xl);
|
||||
margin-bottom: var(--space-sm);
|
||||
font-weight: 700;
|
||||
border-bottom: 2px solid var(--color-accent-primary);
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.category-header {
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 1.05rem;
|
||||
margin-top: var(--space-lg);
|
||||
margin-bottom: var(--space-sm);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Books: each book is a button; its chapter grid opens full-width underneath
|
||||
the row it sits in (display: contents lets the chapter grid span the
|
||||
book grid, and "dense" back-fills the gap with the following books). */
|
||||
.book-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
grid-auto-flow: row dense;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.book-grid > div {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.book-button {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
padding: 0.7rem 0.9rem;
|
||||
min-height: 44px;
|
||||
text-align: left;
|
||||
color: var(--color-text-primary);
|
||||
cursor: pointer;
|
||||
font-family: var(--font-ui);
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
transition: background-color var(--transition-fast), border-color var(--transition-fast);
|
||||
}
|
||||
|
||||
.book-button:hover,
|
||||
.book-button.active {
|
||||
background-color: var(--color-accent-primary);
|
||||
color: var(--color-on-accent);
|
||||
border-color: var(--color-accent-primary);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.chapter-grid {
|
||||
display: none;
|
||||
grid-column: 1 / -1;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 0.4rem;
|
||||
padding: var(--space-md);
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-accent-primary);
|
||||
border-radius: var(--border-radius-sm);
|
||||
}
|
||||
|
||||
.book-about {
|
||||
grid-column: 1 / -1;
|
||||
margin: 0 0 var(--space-xs);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.chapter-link {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
min-height: 44px;
|
||||
padding: 0.35rem 0.75rem 0.35rem 0.4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
color: var(--color-text-primary);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.35;
|
||||
transition: background-color var(--transition-fast);
|
||||
}
|
||||
|
||||
.chapter-num {
|
||||
flex: 0 0 2.4rem;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.chapter-sum {
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.chapter-link:hover {
|
||||
background-color: var(--color-accent-primary);
|
||||
color: var(--color-on-accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.chapter-link:hover .chapter-num,
|
||||
.chapter-link:hover .chapter-sum {
|
||||
color: var(--color-on-accent);
|
||||
}
|
||||
|
||||
.api-docs {
|
||||
margin-top: var(--space-2xl);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
background-color: var(--color-bg-secondary);
|
||||
}
|
||||
|
||||
.api-docs summary {
|
||||
padding: 0.9rem 1.1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.api-docs pre {
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-top: 1px solid var(--color-border);
|
||||
border-radius: 0 0 var(--border-radius-sm) var(--border-radius-sm);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.book-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.chapter-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.search-row input[type=submit] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="/js/book_suggest.js?v=__V__" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h1 class="site-title">KJV API <small>(Legacy edition)</small></h1>
|
||||
<p class="tagline">King James Bible: search, read, and query by reference.</p>
|
||||
|
||||
<div class="search-section">
|
||||
<form action="/find" role="search">
|
||||
<label for="kw">Search Scripture</label>
|
||||
<div class="search-row">
|
||||
<input type="text" name="kw" id="kw" data-book-suggest autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Verse reference or keywords...">
|
||||
<input type="hidden" name="view" value="rich">
|
||||
<input type="submit" value="Search">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="quick-actions">
|
||||
<a href="/random?view=rich" class="quick-btn">Random Verse</a>
|
||||
<a href="/votd?view=rich" class="quick-btn">Verse of the Day</a>
|
||||
<a href="/plan" class="quick-btn">Make a Bible Reading Plan</a>
|
||||
<a href="/saved" class="quick-btn">Saved Verses & Notes</a>
|
||||
<a href="#" class="quick-btn" id="continue-plan" hidden>Continue My Reading Plan</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OLD TESTAMENT -->
|
||||
<h2 class="testament-header">Old Testament</h2>
|
||||
{% for category, books in testament_data.OT.items() %}
|
||||
<h3 class="category-header">{{ category }}</h3>
|
||||
<div class="book-grid">
|
||||
{% for book in books %}
|
||||
<div>
|
||||
<button class="book-button collapsible" data-book="{{ book.title }}">
|
||||
{{ book.title }}
|
||||
</button>
|
||||
<div class="chapter-grid content">
|
||||
{% if book.about %}<p class="book-about">{{ book.about }}</p>{% endif %}
|
||||
{% for chapter in range(1, book.chapters + 1) %}
|
||||
<a href="/show?kw={{ book.title }} {{ chapter }}&view=rich" class="chapter-link"><span class="chapter-num">{{ chapter }}</span>{% if book.summaries|length >= chapter %}<span class="chapter-sum">{{ book.summaries[chapter - 1] }}</span>{% endif %}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- NEW TESTAMENT -->
|
||||
<h2 class="testament-header">New Testament</h2>
|
||||
{% for category, books in testament_data.NT.items() %}
|
||||
<h3 class="category-header">{{ category }}</h3>
|
||||
<div class="book-grid">
|
||||
{% for book in books %}
|
||||
<div>
|
||||
<button class="book-button collapsible" data-book="{{ book.title }}">
|
||||
{{ book.title }}
|
||||
</button>
|
||||
<div class="chapter-grid content">
|
||||
{% if book.about %}<p class="book-about">{{ book.about }}</p>{% endif %}
|
||||
{% for chapter in range(1, book.chapters + 1) %}
|
||||
<a href="/show?kw={{ book.title }} {{ chapter }}&view=rich" class="chapter-link"><span class="chapter-num">{{ chapter }}</span>{% if book.summaries|length >= chapter %}<span class="chapter-sum">{{ book.summaries[chapter - 1] }}</span>{% endif %}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- API DOCUMENTATION -->
|
||||
<details class="api-docs">
|
||||
<summary>API Documentation</summary>
|
||||
<pre><code>API ENDPOINT SPECIFICATION v 0.3
|
||||
================================
|
||||
|
||||
<a href="/find">/find</a> - Tries to show a verse, if it's not a verse
|
||||
it will try to search your query. If it's a
|
||||
single query it will try to find a definition
|
||||
for the word as well. Only avaliable in "Rich"
|
||||
and meant for interactive use/browsing
|
||||
<a href="/random">/random</a> - outputs a random verse
|
||||
<a href="/votd">/votd</a> - returns verse of the day
|
||||
<a href="/search">/search</a> - returns a keyword search result set
|
||||
<a href="/show">/show</a> - returns a verse or set of verses by name/location
|
||||
<a href="/define">/define</a> - 1828 Noah Webster dictionary search
|
||||
<a href="/seq">/seq</a> - Incremental sequence of Bible verses (per request)
|
||||
|
||||
URL PARAMETERS
|
||||
==============
|
||||
view=
|
||||
- json - json-encoded response
|
||||
- plain - very simple html response
|
||||
- rich - pretty response with css and js
|
||||
Required parameter
|
||||
|
||||
kw=
|
||||
- Used with /search /show/ /define /find
|
||||
- The keyword(s) of your query, separated by commas
|
||||
-- ex ?kw=1cor5:1-5,2Peter2:5
|
||||
|
||||
getuid=
|
||||
- Used only with /seq
|
||||
- Set this to "true" to recieve a new UID for use with /seq?uid=
|
||||
|
||||
start=
|
||||
- Used only with /seq
|
||||
- You can use a ref like "1Cor5:1" to start there
|
||||
instead of Genesis 1:1 as is the default
|
||||
- Only used when creating a new UID
|
||||
- If you want to "start in a new place" - just create a new UID
|
||||
|
||||
uid=
|
||||
- Used only with /seq
|
||||
- Required parameter for normal use of /seq
|
||||
|
||||
num=
|
||||
- Used only with /seq
|
||||
- You can get the "next # verses" in your sequence
|
||||
|
||||
FEATURES
|
||||
========
|
||||
- King James Only. (No heretical commentaries or false Bibles)
|
||||
- High quality source documents
|
||||
- Free
|
||||
- Developer hates the sodomites
|
||||
|
||||
INTERACTIVE ENDPOINTS
|
||||
=====================
|
||||
The following endpoints will present you with a query box and
|
||||
radio selector for choosing your output format.
|
||||
- / (same function as /find)
|
||||
- /search
|
||||
- /define
|
||||
- /show
|
||||
|
||||
EXAMPLES
|
||||
========
|
||||
api.tld/random
|
||||
api.tld/votd?view=rich
|
||||
api.tld/show?kw=john3:16,1john5:7&view=plain
|
||||
|
||||
BUGS
|
||||
====
|
||||
Suggestions, bug reports or improvements can be reported to <a href="https://nicecrew.digital/@tyler">@tyler@nicecrew.digital</a></code></pre>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
try {
|
||||
var plan = JSON.parse(localStorage.getItem('kjv.plan'));
|
||||
if (plan && /^[0-9A-Z]+$/.test(plan.uid)) {
|
||||
var link = document.getElementById('continue-plan');
|
||||
link.href = '/plan/' + plan.uid + '?n=' + (parseInt(plan.n, 10) || 25);
|
||||
link.hidden = false;
|
||||
}
|
||||
} catch (e) {}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
<title>{title} - KJV API</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
{css}
|
||||
<script src="/js/verse_menu.js?v=__V__" defer></script>
|
||||
<script src="/js/book_suggest.js?v=__V__" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="site-bar">
|
||||
<a class="brand" href="/">KJV API</a>
|
||||
<nav class="site-links" aria-label="Site">
|
||||
<a href="/random?view=rich">Random Verse</a>
|
||||
<a href="/votd?view=rich">Verse of the Day</a>
|
||||
<a href="/plan">Reading Plan</a>
|
||||
<a href="/saved">Saved</a>
|
||||
</nav>
|
||||
</div>
|
||||
<form class="search-form" action="/find" role="search">
|
||||
<input type="text" name="kw" value="{query}" id="searchBar" data-book-suggest aria-label="Search scripture" placeholder="Verse reference or keywords..." autocapitalize="off" autocomplete="off" enterkeyhint="search">
|
||||
<input type="hidden" name="view" value="rich">
|
||||
<input type="submit" value="Search">
|
||||
</form>
|
||||
<div class="shortcode">
|
||||
<button type="button" class="btn-small" onclick="make_shortcode()">Get shortcode</button>
|
||||
<a id="context_href" href=""></a>
|
||||
</div>
|
||||
</header>
|
||||
{chapter_nav}
|
||||
<script src="/js/shortcode.js?v=__V__"></script>
|
||||
@@ -0,0 +1,29 @@
|
||||
<h2>On Reading the Holy Bible</h2>
|
||||
|
||||
<p>A common trap when reading the Bible is relying on external lenses
|
||||
to look at the Bible through.</p>
|
||||
<p>By external lense, we mean using an external data source such as
|
||||
a dictionary like the 1828 Websters we provide
|
||||
as a way to interpret the meaning of scripture.</p>
|
||||
<p><b>This is wrong!</b></p>
|
||||
|
||||
<h3>How to read the King James Bible</h3>
|
||||
<p>When we read the King James Bible, we need to as the following questions:</p>
|
||||
<ol>
|
||||
<li>Who is speaking?</li>
|
||||
<li>Who is being spoken to?</li>
|
||||
<li>When is this being spoken?</li>
|
||||
<li>What are the definitions of the words?</li>
|
||||
<li>Is it consistent with the rest of scripture?</li>
|
||||
</ol>
|
||||
|
||||
<style>
|
||||
html{
|
||||
font-family: sans-serif;
|
||||
font-size: 14pt;
|
||||
width: 768px;
|
||||
}
|
||||
a {
|
||||
color: #547720
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Make a Bible Reading Plan - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
<style>
|
||||
.fieldset { border: none; padding: 0; margin: 0 0 var(--space-lg); }
|
||||
.fieldset legend { font-weight: 600; padding: 0; margin-bottom: 0.25rem; }
|
||||
.inline-field { display: inline-block; width: 6rem; margin: 0 0.4rem; }
|
||||
.inline-field input[type=text], input[type=number] {
|
||||
min-height: 44px; padding: 0.4rem 0.6rem; font-size: 1rem; font-family: var(--font-ui);
|
||||
background-color: var(--color-bg-primary); color: var(--color-text-primary);
|
||||
border: 2px solid var(--color-border); border-radius: var(--border-radius-sm);
|
||||
}
|
||||
select {
|
||||
min-height: 44px; font-size: 1rem; font-family: var(--font-ui); margin-left: 0.4rem;
|
||||
background-color: var(--color-bg-primary); color: var(--color-text-primary);
|
||||
border: 2px solid var(--color-border); border-radius: var(--border-radius-sm); padding: 0 0.5rem;
|
||||
}
|
||||
input[type=number] { width: 6rem; margin: 0 0.4rem; }
|
||||
.quick-start { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.5rem; }
|
||||
.quick-start button {
|
||||
min-height: 40px; padding: 0.3rem 1rem; background-color: var(--color-bg-tertiary);
|
||||
color: var(--color-text-primary); border: 1px solid var(--color-border);
|
||||
}
|
||||
.continue-box { display: none; background-color: var(--color-bg-secondary); border: 1px solid var(--color-accent-primary);
|
||||
border-radius: var(--border-radius); padding: var(--space-md) var(--space-lg); margin: var(--space-md) 0; }
|
||||
.continue-box a { font-weight: 600; }
|
||||
</style>
|
||||
<script src="/js/book_suggest.js?v=__V__" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
<a href="/saved">Saved</a>
|
||||
</header>
|
||||
<h2>Make a Bible Reading Plan</h2>
|
||||
|
||||
<div class="continue-box" id="continue-box">
|
||||
You already have a plan in this browser: <a id="continue-link" href="#">continue reading</a>.
|
||||
</div>
|
||||
|
||||
<p>Pick where to start and how much to read each day. You'll get a page to bookmark; open it
|
||||
each day to see today's reading, press <b>Done</b> when you've read it, and the plan moves on.
|
||||
You can always go back to the previous reading or jump to any verse.</p>
|
||||
|
||||
<form action="/plan/new" method="post">
|
||||
<div class="fieldset">
|
||||
<label for="start">Start at</label>
|
||||
<div class="quick-start">
|
||||
<button type="button" data-start="Genesis 1:1">Genesis (whole Bible)</button>
|
||||
<button type="button" data-start="Matthew 1:1">Matthew (New Testament)</button>
|
||||
<button type="button" data-start="Psalms 1:1">Psalms</button>
|
||||
<button type="button" data-start="John 1:1">John</button>
|
||||
</div>
|
||||
<input type="text" name="start" id="start" data-book-suggest placeholder="Genesis 1:1" autocapitalize="off" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<fieldset class="fieldset">
|
||||
<legend>How much each day</legend>
|
||||
<label class="choice"><input type="radio" name="pace" value="days" checked>
|
||||
Finish the Bible in
|
||||
<select name="days" aria-label="Finish in">
|
||||
<option value="365" selected>1 year</option>
|
||||
<option value="180">6 months</option>
|
||||
<option value="90">90 days</option>
|
||||
<option value="30">30 days</option>
|
||||
</select>
|
||||
</label><br>
|
||||
<label class="choice"><input type="radio" name="pace" value="verses">
|
||||
Read <input type="number" name="verses" value="30" min="1" max="500" aria-label="Verses per day"> verses a day
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<input type="submit" value="Create my plan">
|
||||
</form>
|
||||
|
||||
<p>Your plan is saved on this server under a short code in the page address, so the bookmark
|
||||
is all you need. Plans unused for 90 days are removed.</p>
|
||||
|
||||
<script>
|
||||
var startInput = document.getElementById('start');
|
||||
document.querySelectorAll('[data-start]').forEach(function (b) {
|
||||
b.addEventListener('click', function () { startInput.value = b.getAttribute('data-start'); });
|
||||
});
|
||||
try {
|
||||
var plan = JSON.parse(localStorage.getItem('kjv.plan'));
|
||||
if (plan && /^[0-9A-Z]+$/.test(plan.uid)) {
|
||||
document.getElementById('continue-link').href = '/plan/' + plan.uid + '?n=' + (parseInt(plan.n, 10) || 25);
|
||||
document.getElementById('continue-box').style.display = 'block';
|
||||
}
|
||||
} catch (e) {}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<div class="verse-container" data-verse-id="{verse_id}">
|
||||
<div class="verse-reference"><a href="/find?kw={chapter}&view=rich">{passage}</a></div>
|
||||
<div class="verse-text">{text}</div>
|
||||
</div>
|
||||
@@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Saved - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
<style>
|
||||
.item { background-color: var(--color-bg-secondary); border: 1px solid var(--color-border);
|
||||
border-left: 3px solid var(--color-accent-primary); border-radius: var(--border-radius-sm);
|
||||
padding: var(--space-sm) var(--space-md); margin-bottom: var(--space-sm); }
|
||||
.item .ref { font-weight: 700; }
|
||||
.item .text { font-family: var(--font-scripture); margin: 0.25rem 0 0.5rem; color: var(--color-text-primary); }
|
||||
.item p { margin: 0.25rem 0; }
|
||||
.item button { min-height: 36px; padding: 0.2rem 0.9rem; font-size: 0.85rem;
|
||||
background-color: var(--color-bg-tertiary); color: var(--color-text-primary); border: 1px solid var(--color-border); }
|
||||
.item .mynote { white-space: pre-wrap; border-left: 3px solid #d9a93b; padding-left: 0.6rem; color: var(--color-text-secondary); }
|
||||
.file-btn { display: inline-block; padding: 0.6rem 1.2rem; border: 1px solid var(--color-border); border-radius: var(--border-radius-sm);
|
||||
background-color: var(--color-bg-tertiary); font-weight: 600; }
|
||||
.empty { color: var(--color-text-muted); }
|
||||
.note { font-size: 0.9rem; color: var(--color-text-muted); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/plan">Reading Plan</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>Saved</h2>
|
||||
<p class="note">Saved in this browser only. Clearing site data or using another device starts fresh.</p>
|
||||
|
||||
<h3>Notes</h3>
|
||||
<div id="notes"></div>
|
||||
<h3>Favorite verses</h3>
|
||||
<div id="fav"></div>
|
||||
<h3>Definitions</h3>
|
||||
<div id="defs"></div>
|
||||
<h3>Cross references</h3>
|
||||
<div id="xrefs"></div>
|
||||
|
||||
<h3>Backup</h3>
|
||||
<p class="note">Browser storage can be cleared without warning. Download a copy of your notes and saved items, and restore it here or on another device.</p>
|
||||
<p>
|
||||
<button type="button" id="backup">Download backup</button>
|
||||
<label class="choice"><input type="file" id="restore" accept="application/json,.json" hidden>
|
||||
<span class="file-btn">Restore from backup</span></label>
|
||||
</p>
|
||||
<p class="note" id="backup-status" role="status"></p>
|
||||
|
||||
<script>
|
||||
var KEYS = { notes: 'kjv.notes', fav: 'kjv.favorites', defs: 'kjv.definitions', xrefs: 'kjv.crossrefs' };
|
||||
|
||||
function load(key) {
|
||||
try { var v = JSON.parse(localStorage.getItem(key)); return Array.isArray(v) ? v : []; }
|
||||
catch (e) { return []; }
|
||||
}
|
||||
function el(tag, cls, text) {
|
||||
var n = document.createElement(tag);
|
||||
if (cls) n.className = cls;
|
||||
if (text !== undefined) n.textContent = text;
|
||||
return n;
|
||||
}
|
||||
function findUrl(ref) { return '/find?kw=' + encodeURIComponent(ref) + '&view=rich'; }
|
||||
|
||||
function render(key, targetId, emptyText, build) {
|
||||
var target = document.getElementById(targetId);
|
||||
target.textContent = '';
|
||||
var list = load(key);
|
||||
if (!list.length) { target.appendChild(el('p', 'empty', emptyText)); return; }
|
||||
list.forEach(function (item, i) {
|
||||
var box = el('div', 'item');
|
||||
build(box, item);
|
||||
var remove = el('button', '', 'Remove');
|
||||
remove.type = 'button';
|
||||
remove.addEventListener('click', function () {
|
||||
var current = load(key);
|
||||
current.splice(i, 1);
|
||||
try { localStorage.setItem(key, JSON.stringify(current)); } catch (e) {}
|
||||
render(key, targetId, emptyText, build);
|
||||
});
|
||||
box.appendChild(remove);
|
||||
target.appendChild(box);
|
||||
});
|
||||
}
|
||||
|
||||
function refLink(ref) {
|
||||
var a = el('a', 'ref', ref);
|
||||
a.href = findUrl(ref);
|
||||
return a;
|
||||
}
|
||||
|
||||
function draw() {
|
||||
render(KEYS.notes, 'notes', 'No notes yet. Tap a verse (or its \u22ef button) and choose Note.', function (box, n) {
|
||||
box.appendChild(refLink(n.ref));
|
||||
if (n.text) { box.appendChild(el('div', 'text', n.text)); }
|
||||
box.appendChild(el('p', 'mynote', n.note));
|
||||
});
|
||||
render(KEYS.fav, 'fav', 'No favorites yet. Tap a verse and choose Favorite.', function (box, f) {
|
||||
box.appendChild(refLink(f.ref));
|
||||
box.appendChild(el('div', 'text', f.text));
|
||||
});
|
||||
render(KEYS.defs, 'defs', 'No saved definitions. Tap a verse, choose Define words, and save one.', function (box, d) {
|
||||
box.appendChild(el('strong', '', d.word));
|
||||
if (d.ref) { box.appendChild(document.createTextNode(' from ')); box.appendChild(refLink(d.ref)); }
|
||||
(d.defs || []).forEach(function (t) { box.appendChild(el('p', '', t)); });
|
||||
});
|
||||
render(KEYS.xrefs, 'xrefs', 'No saved cross references. Tap a verse, choose Cross references, and save one.', function (box, x) {
|
||||
box.appendChild(refLink(x.ref));
|
||||
box.appendChild(el('span', 'note', ' (cross reference of ' + x.from + ')'));
|
||||
box.appendChild(el('div', 'text', x.text));
|
||||
});
|
||||
}
|
||||
draw();
|
||||
|
||||
document.getElementById('backup').addEventListener('click', function () {
|
||||
var data = { kjv_backup: 1, saved: new Date().toISOString() };
|
||||
Object.keys(KEYS).forEach(function (name) { data[name] = load(KEYS[name]); });
|
||||
var blob = new Blob([JSON.stringify(data, null, 1)], { type: 'application/json' });
|
||||
var link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = 'kjv-saved-' + new Date().toISOString().slice(0, 10) + '.json';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
setTimeout(function () { URL.revokeObjectURL(link.href); }, 1000);
|
||||
});
|
||||
|
||||
document.getElementById('restore').addEventListener('change', function (event) {
|
||||
var file = event.target.files[0];
|
||||
var status = document.getElementById('backup-status');
|
||||
if (!file) { return; }
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
try {
|
||||
var data = JSON.parse(reader.result);
|
||||
if (!data || data.kjv_backup !== 1) { throw new Error('not a backup'); }
|
||||
if (!confirm('Replace the notes and saved items in this browser with this backup?')) { return; }
|
||||
Object.keys(KEYS).forEach(function (name) {
|
||||
if (Array.isArray(data[name])) { localStorage.setItem(KEYS[name], JSON.stringify(data[name])); }
|
||||
});
|
||||
draw();
|
||||
status.textContent = 'Backup restored.';
|
||||
} catch (e) {
|
||||
status.textContent = 'That file is not a valid backup.';
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
event.target.value = '';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Bible Search - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/search">Bible Search</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>Bible Search</h2>
|
||||
<form action="/search">
|
||||
<label for="kw">Key Words</label>
|
||||
<input type="text" name="kw" id="kw" autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Enter search keywords...">
|
||||
<div class="form-row"><b>View</b><br>
|
||||
<label class="choice"><input type="radio" name="view" value="rich" checked="checked"> Rich</label>
|
||||
<label class="choice"><input type="radio" name="view" value="plain"> Plain</label>
|
||||
<label class="choice"><input type="radio" name="view" value="json"> JSON</label>
|
||||
</div>
|
||||
<input type="submit" value="Search">
|
||||
</form>
|
||||
<hr>
|
||||
<p>You can use standard search operators such as <b>AND</b>, <b>OR</b>, and <b>NOT</b>.</p>
|
||||
<p>Such as: "reprobate <b>NOT</b> silver".</p>
|
||||
<p>Multiple word queries without operators will be assumed to be AND.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
<form action="/find">
|
||||
<input type="text" name="kw">
|
||||
<input type="hidden" name="view" value="rich"">
|
||||
<input type="submit">
|
||||
<form>
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Sequential Bible Viewer - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/seq">Sequential Viewer</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>Sequential Bible Viewer</h2>
|
||||
<p>In order to use this, you first need a UID, which you can get by querying <code>/seq?getuid=true</code> and optionally include <code>&start=BIBLEREF</code> (where BIBLEREF is like 1Cor2:1) to set a start position other than Genesis 1:1.</p>
|
||||
<p>After you have your UID, this will keep track of where you are at. Query <code>/seq?uid=YOURUID</code> and optionally include <code>&num=#</code> (where # is an integer of how many verses you want to include from your current position at a time)</p>
|
||||
<p>The <code>&view=</code> argument works with this.</p>
|
||||
<h4>Example Pleroma Bot shell script</h4>
|
||||
<pre><code>#!/bin/sh
|
||||
verse=$(curl -XGET https://bible.nicecrew.digital/seq?uid=MYUID?view=plain);
|
||||
curl -XPOST -u biblebot:MYPASSWORD \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"status": "'"${verse}"'"}' \
|
||||
https://my.fediverse.tld/api/v1/statuses;
|
||||
</code></pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Show Verse - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
<script src="/js/book_suggest.js?v=__V__" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/show">Show Verse</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>Show Verse</h2>
|
||||
<form action="/show">
|
||||
<label for="kw">Verse References</label>
|
||||
<input type="text" name="kw" id="kw" data-book-suggest autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="e.g., 1 John 5:7 or John3:16,2Peter2:1">
|
||||
<div class="form-row"><b>View</b><br>
|
||||
<label class="choice"><input type="radio" name="view" value="rich" checked="checked"> Rich</label>
|
||||
<label class="choice"><input type="radio" name="view" value="plain"> Plain</label>
|
||||
<label class="choice"><input type="radio" name="view" value="json"> JSON</label>
|
||||
</div>
|
||||
<input type="submit" value="Show">
|
||||
</form>
|
||||
<hr>
|
||||
<p>You can search a Bible reference in this box, such as "1 John 5:7".</p>
|
||||
<p>You can use abbreviations, but you may not get the result you are looking for.</p>
|
||||
<p>Use a dash for the verse to get the entire chapter, e.g., "John 3:-"</p>
|
||||
<p>You may return multiple verse groups by using a comma, e.g., "John3:16,2Peter2:1"</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../styles/votd.css">
|
||||
<title style="visibility: hidden;">VOTD</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1 class="verse-title">1 Sneedalonians 4:2</h1>
|
||||
<p class="verse-text">"Thou shalt do good CSS development for the glory of the LORD"</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,160 @@
|
||||
// Book name suggestions for reference/search boxes: type "joh" and get
|
||||
// John, 1 John...; Tab (or tap/click) completes. Only offered while the text
|
||||
// could still be the start of a book name, so keyword searches are unaffected.
|
||||
(function () {
|
||||
var BOOKS = __BOOKS__;
|
||||
var MAX_SHOWN = 8;
|
||||
var list = null;
|
||||
var current = { input: null, matches: [], active: 0, explicit: false };
|
||||
|
||||
function norm(text) {
|
||||
return text.toLowerCase().replace(/[^a-z0-9]/g, "");
|
||||
}
|
||||
|
||||
function injectStyle() {
|
||||
var style = document.createElement("style");
|
||||
style.textContent =
|
||||
".book-suggest{position:absolute;z-index:2000;margin:4px 0 0;padding:4px 0;list-style:none;" +
|
||||
"background:var(--color-bg-secondary,#fff);color:var(--color-text-primary,#111);" +
|
||||
"border:1px solid var(--color-border,#ccc);border-radius:6px;" +
|
||||
"box-shadow:0 6px 18px var(--color-shadow,rgba(0,0,0,.25));font:1rem var(--font-ui,sans-serif)}" +
|
||||
".book-suggest li{padding:10px 14px;cursor:pointer;min-height:44px;display:flex;align-items:center}" +
|
||||
".book-suggest li[aria-selected=true]{background:var(--color-accent-primary,#2b5c94);" +
|
||||
"color:var(--color-on-accent,#fff)}" +
|
||||
".book-suggest .hint{min-height:0;padding:4px 14px;font-size:.8rem;cursor:default;" +
|
||||
"color:var(--color-text-muted,#666);background:none}" +
|
||||
"@media (hover:none){.book-suggest .hint{display:none}}";
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
function ensureList() {
|
||||
if (list) {
|
||||
return list;
|
||||
}
|
||||
injectStyle();
|
||||
list = document.createElement("ul");
|
||||
list.className = "book-suggest";
|
||||
list.id = "book-suggest-list";
|
||||
list.setAttribute("role", "listbox");
|
||||
list.hidden = true;
|
||||
// keep focus in the input while clicking an item
|
||||
list.addEventListener("mousedown", function (event) { event.preventDefault(); });
|
||||
document.body.appendChild(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
function close() {
|
||||
if (list) {
|
||||
list.hidden = true;
|
||||
}
|
||||
if (current.input) {
|
||||
current.input.setAttribute("aria-expanded", "false");
|
||||
current.input.removeAttribute("aria-activedescendant");
|
||||
}
|
||||
current.matches = [];
|
||||
}
|
||||
|
||||
function accept(book) {
|
||||
var input = current.input;
|
||||
input.value = book + " ";
|
||||
input.setSelectionRange(input.value.length, input.value.length);
|
||||
close();
|
||||
input.focus();
|
||||
}
|
||||
|
||||
function paint() {
|
||||
var items = list.querySelectorAll("li[role=option]");
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var selected = i === current.active;
|
||||
items[i].setAttribute("aria-selected", selected ? "true" : "false");
|
||||
if (selected) {
|
||||
current.input.setAttribute("aria-activedescendant", items[i].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function show(input, matches) {
|
||||
var box = input.getBoundingClientRect();
|
||||
ensureList();
|
||||
list.textContent = "";
|
||||
matches.forEach(function (book, i) {
|
||||
var item = document.createElement("li");
|
||||
item.setAttribute("role", "option");
|
||||
item.id = "book-suggest-" + i;
|
||||
item.textContent = book;
|
||||
item.addEventListener("click", function () { accept(book); });
|
||||
list.appendChild(item);
|
||||
});
|
||||
var hint = document.createElement("li");
|
||||
hint.className = "hint";
|
||||
hint.textContent = "Tab to complete";
|
||||
list.appendChild(hint);
|
||||
list.style.left = box.left + window.pageXOffset + "px";
|
||||
list.style.top = box.bottom + window.pageYOffset + "px";
|
||||
list.style.minWidth = Math.min(box.width, 320) + "px";
|
||||
list.hidden = false;
|
||||
input.setAttribute("aria-expanded", "true");
|
||||
paint();
|
||||
}
|
||||
|
||||
function update(input) {
|
||||
current.input = input;
|
||||
var value = input.value.replace(/^\s+/, "");
|
||||
// "1 jo", "song of sol": optional leading book number, then letters only
|
||||
var n = /^[1-3]?\s?[A-Za-z ]*$/.test(value) ? norm(value) : "";
|
||||
var matches = n ? BOOKS.filter(function (b) { return norm(b).indexOf(n) === 0; }) : [];
|
||||
// already typed a whole book name: nothing left to complete
|
||||
if (matches.length === 1 && norm(matches[0]) === n) {
|
||||
matches = [];
|
||||
}
|
||||
matches = matches.slice(0, MAX_SHOWN);
|
||||
current.matches = matches;
|
||||
current.active = 0;
|
||||
current.explicit = false;
|
||||
if (matches.length) {
|
||||
show(input, matches);
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
function onKeydown(event) {
|
||||
var open = list && !list.hidden && current.matches.length;
|
||||
if (!open) {
|
||||
return;
|
||||
}
|
||||
var count = current.matches.length;
|
||||
if (event.key === "Tab" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
accept(current.matches[current.active]);
|
||||
} else if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
||||
event.preventDefault();
|
||||
current.active = (current.active + (event.key === "ArrowDown" ? 1 : count - 1)) % count;
|
||||
current.explicit = true;
|
||||
paint();
|
||||
} else if (event.key === "Enter" && current.explicit) {
|
||||
event.preventDefault(); // pick the highlighted book instead of submitting
|
||||
accept(current.matches[current.active]);
|
||||
} else if (event.key === "Escape") {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
function attach(input) {
|
||||
input.setAttribute("autocomplete", "off");
|
||||
input.setAttribute("aria-autocomplete", "list");
|
||||
input.setAttribute("aria-controls", "book-suggest-list");
|
||||
input.addEventListener("input", function () { update(input); });
|
||||
input.addEventListener("keydown", function (event) {
|
||||
current.input = input;
|
||||
onKeydown(event);
|
||||
});
|
||||
input.addEventListener("blur", close);
|
||||
}
|
||||
|
||||
var inputs = document.querySelectorAll("input[data-book-suggest]");
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
attach(inputs[i]);
|
||||
}
|
||||
window.addEventListener("resize", close);
|
||||
})();
|
||||
@@ -0,0 +1,40 @@
|
||||
var coll = document.getElementsByClassName("collapsible");
|
||||
var i;
|
||||
|
||||
function setOpen(button, open) {
|
||||
var content = button.nextElementSibling;
|
||||
button.classList.toggle("active", open);
|
||||
button.setAttribute("aria-expanded", open ? "true" : "false");
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
if (!open) {
|
||||
content.style.display = "none";
|
||||
} else if (content.classList.contains('chapter-grid')) {
|
||||
content.style.display = "grid";
|
||||
} else {
|
||||
content.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < coll.length; i++) {
|
||||
coll[i].setAttribute("aria-expanded", "false");
|
||||
coll[i].addEventListener("click", function() {
|
||||
var content = this.nextElementSibling;
|
||||
// computed style, so content hidden by a stylesheet counts as closed
|
||||
var isCurrentlyOpen = content && getComputedStyle(content).display !== "none";
|
||||
|
||||
// If this collapsible has a parent with book-grid class, close all siblings in that grid
|
||||
var parentGrid = this.closest('.book-grid');
|
||||
if (parentGrid) {
|
||||
var siblings = parentGrid.querySelectorAll('.collapsible');
|
||||
for (var j = 0; j < siblings.length; j++) {
|
||||
if (siblings[j] !== this) {
|
||||
setOpen(siblings[j], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setOpen(this, !isCurrentlyOpen);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
function make_shortcode(){{
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
const theUrl = "/mksc/" + document.getElementById("searchBar").value;
|
||||
xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
|
||||
xmlHttp.send( null );
|
||||
document.getElementById("context_href").innerHTML = xmlHttp.responseText;
|
||||
document.getElementById('context_href').setAttribute("href", "/" + xmlHttp.responseText);
|
||||
}}
|
||||
@@ -0,0 +1,379 @@
|
||||
// Every verse card gets an actions button (and the card itself is tappable)
|
||||
// that opens a small menu: favorite the verse, write a note on it, look up the
|
||||
// 1828 Webster definition of its words, or see its cross references.
|
||||
// Everything saved lives in this browser's localStorage (see the /saved page).
|
||||
(function () {
|
||||
var KEYS = { fav: "kjv.favorites", defs: "kjv.definitions", xrefs: "kjv.crossrefs", notes: "kjv.notes" };
|
||||
var open = null; // { box, menu }
|
||||
|
||||
function load(key) {
|
||||
try {
|
||||
var value = JSON.parse(localStorage.getItem(key));
|
||||
return Array.isArray(value) ? value : [];
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function save(key, list) {
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(list));
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function indexOf(list, match) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (match(list[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Adds the item if it is not stored yet, removes it if it is. Returns the new "saved" state.
|
||||
function toggle(key, item, match) {
|
||||
var list = load(key);
|
||||
var at = indexOf(list, match);
|
||||
if (at >= 0) {
|
||||
list.splice(at, 1);
|
||||
} else {
|
||||
item.t = Date.now();
|
||||
list.unshift(item);
|
||||
}
|
||||
save(key, list);
|
||||
return at < 0;
|
||||
}
|
||||
|
||||
function el(tag, className, text) {
|
||||
var node = document.createElement(tag);
|
||||
if (className) {
|
||||
node.className = className;
|
||||
}
|
||||
if (text !== undefined) {
|
||||
node.textContent = text;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function verseInfo(box) {
|
||||
var link = box.querySelector(".verse-reference a");
|
||||
var text = box.querySelector(".verse-text");
|
||||
return {
|
||||
ref: link ? link.textContent.trim() : "",
|
||||
text: text ? text.textContent.trim() : "",
|
||||
id: box.getAttribute("data-verse-id") || ""
|
||||
};
|
||||
}
|
||||
|
||||
function findUrl(ref) {
|
||||
return "/find?kw=" + encodeURIComponent(ref) + "&view=rich";
|
||||
}
|
||||
|
||||
function noteFor(ref) {
|
||||
var list = load(KEYS.notes);
|
||||
var at = indexOf(list, function (n) { return n.ref === ref; });
|
||||
return at >= 0 ? list[at].note : "";
|
||||
}
|
||||
|
||||
// Shows the saved note (if any) under the verse text.
|
||||
function renderNote(box) {
|
||||
var old = box.querySelector(".verse-note");
|
||||
if (old) {
|
||||
old.remove();
|
||||
}
|
||||
var info = verseInfo(box);
|
||||
var note = noteFor(info.ref);
|
||||
box.classList.toggle("has-note", !!note);
|
||||
if (!note) {
|
||||
return;
|
||||
}
|
||||
var text = box.querySelector(".verse-text");
|
||||
var node = el("div", "verse-note", note);
|
||||
node.setAttribute("title", "Your note");
|
||||
if (text) {
|
||||
text.after(node);
|
||||
} else {
|
||||
box.appendChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
function markSaved(root) {
|
||||
var favs = load(KEYS.fav);
|
||||
var boxes = (root || document).querySelectorAll(".verse-container");
|
||||
for (var i = 0; i < boxes.length; i++) {
|
||||
var ref = verseInfo(boxes[i]).ref;
|
||||
boxes[i].classList.toggle("is-fav", indexOf(favs, function (f) { return f.ref === ref; }) >= 0);
|
||||
renderNote(boxes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// A visible way in to the menu on every verse, so nobody has to guess that the card is tappable.
|
||||
function addMenuButtons() {
|
||||
var boxes = document.querySelectorAll(".verse-container");
|
||||
for (var i = 0; i < boxes.length; i++) {
|
||||
var header = boxes[i].querySelector(".verse-reference");
|
||||
if (!header || header.querySelector(".vm-more")) {
|
||||
continue;
|
||||
}
|
||||
var button = el("button", "vm-more", "\u22ef");
|
||||
button.type = "button";
|
||||
button.setAttribute("aria-label", "Verse actions: notes, favorite, define, cross references");
|
||||
button.setAttribute("title", "Notes, favorite, define, cross references");
|
||||
button.addEventListener("click", (function (box) {
|
||||
return function () { toggleMenu(box); };
|
||||
})(boxes[i]));
|
||||
header.appendChild(button);
|
||||
}
|
||||
var count = document.querySelector(".results-count");
|
||||
if (count && boxes.length && !document.querySelector(".verse-hint")) {
|
||||
count.after(el("div", "verse-hint", "Tap a verse, or its \u22ef button, to add a note, favorite it, define words or see cross references."));
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMenu(box) {
|
||||
if (open && open.box === box) {
|
||||
closeMenu();
|
||||
} else {
|
||||
openMenu(box);
|
||||
}
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
if (open) {
|
||||
open.box.classList.remove("selected");
|
||||
open.box.removeAttribute("aria-expanded");
|
||||
open.menu.remove();
|
||||
open = null;
|
||||
}
|
||||
}
|
||||
|
||||
function saveButton(isSaved, onToggle) {
|
||||
var button = el("button", "vm-save");
|
||||
button.type = "button";
|
||||
function paint(saved) {
|
||||
button.textContent = saved ? "Saved ✓" : "Save";
|
||||
button.classList.toggle("saved", saved);
|
||||
}
|
||||
paint(isSaved);
|
||||
button.addEventListener("click", function () { paint(onToggle()); });
|
||||
return button;
|
||||
}
|
||||
|
||||
function showDefinitions(info, panel) {
|
||||
panel.textContent = "Looking up words…";
|
||||
var seen = {};
|
||||
var words = (info.text.toLowerCase().match(/[a-z]+/g) || []).filter(function (w) {
|
||||
if (w.length < 3 || seen[w]) {
|
||||
return false;
|
||||
}
|
||||
seen[w] = true;
|
||||
return true;
|
||||
});
|
||||
fetch("/defs?words=" + encodeURIComponent(words.join(",")))
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (defs) {
|
||||
panel.textContent = "";
|
||||
var found = words.filter(function (w) { return defs[w]; });
|
||||
if (!found.length) {
|
||||
panel.textContent = "No definitions found for the words in this verse.";
|
||||
return;
|
||||
}
|
||||
var chips = el("div", "vm-chips");
|
||||
var detail = el("div", "vm-detail");
|
||||
detail.hidden = true;
|
||||
found.forEach(function (word) {
|
||||
var chip = el("button", "vm-chip", word);
|
||||
chip.type = "button";
|
||||
chip.addEventListener("click", function () {
|
||||
detail.hidden = false;
|
||||
detail.textContent = "";
|
||||
detail.appendChild(el("strong", "", word));
|
||||
defs[word].forEach(function (d) { detail.appendChild(el("p", "", d)); });
|
||||
var match = function (s) { return s.word === word; };
|
||||
detail.appendChild(saveButton(
|
||||
indexOf(load(KEYS.defs), match) >= 0,
|
||||
function () {
|
||||
return toggle(KEYS.defs, { word: word, defs: defs[word], ref: info.ref }, match);
|
||||
}
|
||||
));
|
||||
});
|
||||
chips.appendChild(chip);
|
||||
});
|
||||
panel.appendChild(el("div", "vm-hint", "Tap a word for its 1828 Webster definition."));
|
||||
panel.appendChild(chips);
|
||||
panel.appendChild(detail);
|
||||
})
|
||||
.catch(function () { panel.textContent = "Could not load definitions."; });
|
||||
}
|
||||
|
||||
function showCrossRefs(info, panel) {
|
||||
if (!info.id) {
|
||||
panel.textContent = "Cross references are not available here.";
|
||||
return;
|
||||
}
|
||||
panel.textContent = "Loading cross references…";
|
||||
fetch("/xref/" + encodeURIComponent(info.id))
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (refs) {
|
||||
panel.textContent = "";
|
||||
if (!refs.length) {
|
||||
panel.textContent = "No cross references for this verse.";
|
||||
return;
|
||||
}
|
||||
refs.forEach(function (x) {
|
||||
var row = el("div", "vm-xref");
|
||||
var link = el("a", "", x.ref);
|
||||
link.href = findUrl(x.ref);
|
||||
row.appendChild(link);
|
||||
row.appendChild(el("div", "vm-xref-text", x.text));
|
||||
var match = function (s) { return s.from === info.ref && s.ref === x.ref; };
|
||||
row.appendChild(saveButton(
|
||||
indexOf(load(KEYS.xrefs), match) >= 0,
|
||||
function () {
|
||||
return toggle(KEYS.xrefs, { from: info.ref, ref: x.ref, text: x.text }, match);
|
||||
}
|
||||
));
|
||||
panel.appendChild(row);
|
||||
});
|
||||
})
|
||||
.catch(function () { panel.textContent = "Could not load cross references."; });
|
||||
}
|
||||
|
||||
// Notes save as you type; clearing the box deletes the note.
|
||||
function showNote(info, panel, box, onChange) {
|
||||
panel.textContent = "";
|
||||
var area = el("textarea", "vm-note-input");
|
||||
area.rows = 4;
|
||||
area.placeholder = "Your note on " + info.ref + "...";
|
||||
area.setAttribute("aria-label", "Note for " + info.ref);
|
||||
area.value = noteFor(info.ref);
|
||||
var status = el("div", "vm-hint", "Saved in this browser as you type.");
|
||||
var timer = null;
|
||||
function commit() {
|
||||
var value = area.value.trim();
|
||||
var list = load(KEYS.notes);
|
||||
var at = indexOf(list, function (n) { return n.ref === info.ref; });
|
||||
if (!value) {
|
||||
if (at >= 0) {
|
||||
list.splice(at, 1);
|
||||
}
|
||||
} else if (at >= 0) {
|
||||
list[at].note = value;
|
||||
list[at].t = Date.now();
|
||||
} else {
|
||||
list.unshift({ ref: info.ref, text: info.text, note: value, t: Date.now() });
|
||||
}
|
||||
save(KEYS.notes, list);
|
||||
renderNote(box);
|
||||
onChange();
|
||||
status.textContent = value ? "Saved." : "Note removed.";
|
||||
}
|
||||
area.addEventListener("input", function () {
|
||||
status.textContent = "Saving\u2026";
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(commit, 400);
|
||||
});
|
||||
area.addEventListener("blur", function () {
|
||||
clearTimeout(timer);
|
||||
commit();
|
||||
});
|
||||
panel.appendChild(area);
|
||||
panel.appendChild(status);
|
||||
area.focus();
|
||||
}
|
||||
|
||||
function openMenu(box) {
|
||||
closeMenu();
|
||||
var info = verseInfo(box);
|
||||
var menu = el("div", "verse-menu");
|
||||
menu.setAttribute("role", "group");
|
||||
menu.setAttribute("aria-label", "Actions for " + info.ref);
|
||||
var actions = el("div", "vm-actions");
|
||||
var panel = el("div", "vm-panel");
|
||||
panel.hidden = true;
|
||||
|
||||
var favMatch = function (f) { return f.ref === info.ref; };
|
||||
var fav = el("button", "vm-btn");
|
||||
fav.type = "button";
|
||||
function paintFav() {
|
||||
var saved = indexOf(load(KEYS.fav), favMatch) >= 0;
|
||||
fav.textContent = saved ? "★ Favorited" : "☆ Favorite";
|
||||
fav.classList.toggle("saved", saved);
|
||||
box.classList.toggle("is-fav", saved);
|
||||
}
|
||||
paintFav();
|
||||
fav.addEventListener("click", function () {
|
||||
toggle(KEYS.fav, { ref: info.ref, text: info.text }, favMatch);
|
||||
paintFav();
|
||||
});
|
||||
|
||||
var noteBtn = el("button", "vm-btn");
|
||||
noteBtn.type = "button";
|
||||
function paintNote() {
|
||||
var has = !!noteFor(info.ref);
|
||||
noteBtn.textContent = has ? "\u270e Edit note" : "\u270e Note";
|
||||
noteBtn.classList.toggle("saved", has);
|
||||
}
|
||||
paintNote();
|
||||
noteBtn.addEventListener("click", function () {
|
||||
panel.hidden = false;
|
||||
showNote(info, panel, box, paintNote);
|
||||
});
|
||||
|
||||
var define = el("button", "vm-btn", "Define words");
|
||||
define.type = "button";
|
||||
define.addEventListener("click", function () {
|
||||
panel.hidden = false;
|
||||
showDefinitions(info, panel);
|
||||
});
|
||||
|
||||
var xref = el("button", "vm-btn", "Cross references");
|
||||
xref.type = "button";
|
||||
xref.addEventListener("click", function () {
|
||||
panel.hidden = false;
|
||||
showCrossRefs(info, panel);
|
||||
});
|
||||
|
||||
var close = el("button", "vm-btn vm-close", "×");
|
||||
close.type = "button";
|
||||
close.setAttribute("aria-label", "Close menu");
|
||||
close.addEventListener("click", closeMenu);
|
||||
|
||||
[fav, noteBtn, define, xref, close].forEach(function (b) { actions.appendChild(b); });
|
||||
menu.appendChild(actions);
|
||||
menu.appendChild(panel);
|
||||
box.appendChild(menu);
|
||||
box.classList.add("selected");
|
||||
box.setAttribute("aria-expanded", "true");
|
||||
open = { box: box, menu: menu };
|
||||
}
|
||||
|
||||
document.addEventListener("click", function (event) {
|
||||
var box = event.target.closest && event.target.closest(".verse-container");
|
||||
if (!box) {
|
||||
closeMenu();
|
||||
return;
|
||||
}
|
||||
// links, buttons and the open menu keep their own behaviour; so does selecting text
|
||||
if (event.target.closest("a, button, input, textarea, .verse-menu")) {
|
||||
return;
|
||||
}
|
||||
var selection = window.getSelection && window.getSelection().toString();
|
||||
if (selection) {
|
||||
return;
|
||||
}
|
||||
toggleMenu(box);
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.key === "Escape" && !(event.target && event.target.tagName === "TEXTAREA")) {
|
||||
closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
markSaved();
|
||||
addMenuButtons();
|
||||
})();
|
||||
@@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Semantic Search - KJV API</title>
|
||||
<link rel="stylesheet" href="/styles/page.css?v=__V__">
|
||||
<style>
|
||||
.search-row { display: flex; gap: var(--space-sm); }
|
||||
.search-row input[type=text] { margin: 0; flex: 1; min-width: 0; }
|
||||
#results, #last-searched { list-style: none; padding: 0; margin: var(--space-md) 0; }
|
||||
#results li {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-left: 3px solid var(--color-accent-primary);
|
||||
border-radius: var(--border-radius-sm);
|
||||
padding: var(--space-md);
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
#last-searched li { padding: 0.2rem 0; color: var(--color-text-secondary); }
|
||||
@media (max-width: 480px) { .search-row { flex-direction: column; } .search-row button { width: 100%; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="/">Home</a> <a href="/find">Quick Search</a>
|
||||
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
|
||||
</header>
|
||||
<h2>Bible Semantic Search</h2>
|
||||
<p>This is NOT a keyword search. This means searching single words will not have the results you expect. For that, use the normal keyword search at <a href='/'>bible.nicecrew.digital</a></p>
|
||||
<p>Use a sentence like "The Lord will kill his enemies without mercy" - you are supposed to search an idea, not individual words.</p>
|
||||
<h3>Recent searches</h3>
|
||||
<ul id="last-searched"></ul>
|
||||
<div class="search-row">
|
||||
<input type="text" id="search-box" aria-label="Search an idea" enterkeyhint="search" placeholder="The lord god is a man of war, just in all his dealings">
|
||||
<button id="search-button">Search</button>
|
||||
</div>
|
||||
<ul id="results"></ul>
|
||||
|
||||
<script>
|
||||
const searchButton = document.getElementById('search-button');
|
||||
const searchBox = document.getElementById('search-box');
|
||||
const esc = s => String(s).replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
||||
const resultsList = document.getElementById('results');
|
||||
const lastSearched = document.getElementById('last-searched');
|
||||
|
||||
window.addEventListener('DOMContentLoaded', async () => {
|
||||
const lastSearchedURL = `https://bible.nicecrew.digital/natural`;
|
||||
const data = {
|
||||
token: 'testing',
|
||||
query: '__last_searched__'
|
||||
};
|
||||
const response = await fetch(lastSearchedURL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
if (response.ok) {
|
||||
const results = await response.json();
|
||||
lastSearched.innerHTML = ''; // Clear previous results
|
||||
|
||||
results.forEach(result => {
|
||||
const listItem = document.createElement('li');
|
||||
listItem.innerHTML = `
|
||||
${esc(result.query)}<br>
|
||||
`;
|
||||
lastSearched.appendChild(listItem);
|
||||
});
|
||||
} else {
|
||||
console.error('Error fetching data:', response.statusText);
|
||||
}
|
||||
});
|
||||
|
||||
searchButton.addEventListener('click', async () => {
|
||||
const query = searchBox.value;
|
||||
if (query.length >= 100){
|
||||
alert("Query too long");
|
||||
return;}
|
||||
const url = `https://bible.nicecrew.digital/natural`; // Replace with your actual URL
|
||||
|
||||
const data = {
|
||||
token: 'testing',
|
||||
query: query
|
||||
};
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const results = await response.json();
|
||||
resultsList.innerHTML = ''; // Clear previous results
|
||||
|
||||
results.forEach(result => {
|
||||
const listItem = document.createElement('li');
|
||||
const uriRef = encodeURIComponent(result.ref);
|
||||
listItem.innerHTML = `
|
||||
<strong>Verse ID:</strong> ${esc(result.verse_id)}<br>
|
||||
<strong>Text:</strong> ${esc(result.text)}<br>
|
||||
<strong>Ref:</strong> <a href="/find?kw=${uriRef}">${esc(result.ref)}</a><br>
|
||||
<strong>Score:</strong> ${esc(result.score)}
|
||||
`;
|
||||
resultsList.appendChild(listItem);
|
||||
});
|
||||
} else {
|
||||
console.error('Error fetching data:', response.statusText);
|
||||
alert('An error occurred while searching. Please try again later.');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<path fill="#6b9bd1" d="M16 4 C10 4 6 6 4 8 L4 26 C6 24 10 22 16 22 C22 22 26 24 28 26 L28 8 C26 6 22 4 16 4 Z"/>
|
||||
<path fill="#85aede" d="M16 4 L16 22 C22 22 26 24 28 26 L28 8 C26 6 22 4 16 4 Z"/>
|
||||
<line x1="16" y1="4" x2="16" y2="22" stroke="#3a3a3a" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 346 B |
@@ -0,0 +1,64 @@
|
||||
/* Collapsible Styling (dictionary definitions on /find) */
|
||||
|
||||
.collapsible {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
color: var(--color-text-primary);
|
||||
cursor: pointer;
|
||||
padding: 0.85rem 1.1rem;
|
||||
min-height: 44px;
|
||||
width: 100%;
|
||||
max-width: var(--content-max-width);
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
font-family: var(--font-ui);
|
||||
transition: background-color 150ms ease, border-color 150ms ease;
|
||||
margin: 0.5rem auto 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.collapsible::after {
|
||||
content: "+";
|
||||
float: right;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.collapsible.active::after {
|
||||
content: "\2212";
|
||||
}
|
||||
|
||||
.collapsible:hover {
|
||||
border-color: var(--color-accent-primary);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.collapsible:focus-visible {
|
||||
border-color: var(--color-accent-primary);
|
||||
box-shadow: 0 0 0 3px rgba(107, 155, 209, 0.3);
|
||||
}
|
||||
|
||||
.collapsible.active {
|
||||
background-color: var(--color-accent-primary);
|
||||
color: var(--color-on-accent);
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.collapsible.active:hover {
|
||||
background-color: var(--color-accent-hover);
|
||||
border-color: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
/* Collapsible content styling */
|
||||
.content {
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
background-color: var(--color-bg-secondary);
|
||||
max-width: var(--content-max-width);
|
||||
margin: 0 auto 0.5rem;
|
||||
padding: 1rem 1.25rem;
|
||||
border-radius: var(--border-radius-sm);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,861 @@
|
||||
<style>
|
||||
/* KJV API Styling - rich (human readable) pages: header, chapter bar, verses */
|
||||
|
||||
:root {
|
||||
color-scheme: dark light;
|
||||
|
||||
/* Color Palette */
|
||||
--color-bg-primary: #1a1a1a;
|
||||
--color-bg-secondary: #252525;
|
||||
--color-bg-tertiary: #2f2f2f;
|
||||
--color-text-primary: #e8e8e8;
|
||||
--color-text-secondary: #b8b8b8;
|
||||
--color-text-muted: #888888;
|
||||
--color-accent-primary: #6b9bd1;
|
||||
--color-accent-hover: #85aede;
|
||||
--color-on-accent: #121212;
|
||||
--color-link: #6b9bd1;
|
||||
--color-link-hover: #85aede;
|
||||
--color-border: #3a3a3a;
|
||||
--color-shadow: rgba(0, 0, 0, 0.3);
|
||||
|
||||
/* Typography */
|
||||
--font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
--font-scripture: Georgia, "Crimson Text", "Times New Roman", serif;
|
||||
--font-mono: "SF Mono", Monaco, "Cascadia Code", "Courier New", monospace;
|
||||
|
||||
/* Spacing */
|
||||
--space-xs: 0.25rem;
|
||||
--space-sm: 0.5rem;
|
||||
--space-md: 1rem;
|
||||
--space-lg: 1.5rem;
|
||||
--space-xl: 2rem;
|
||||
--space-2xl: 3rem;
|
||||
|
||||
/* Layout */
|
||||
--content-max-width: 820px;
|
||||
--border-radius: 8px;
|
||||
--border-radius-sm: 4px;
|
||||
|
||||
/* Transitions */
|
||||
--transition-fast: 150ms ease;
|
||||
--transition-normal: 250ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--color-bg-primary: #f7f5f0;
|
||||
--color-bg-secondary: #ffffff;
|
||||
--color-bg-tertiary: #ece9e1;
|
||||
--color-text-primary: #1f1f1f;
|
||||
--color-text-secondary: #4a4a4a;
|
||||
--color-text-muted: #6b6b6b;
|
||||
--color-accent-primary: #2b5c94;
|
||||
--color-accent-hover: #1d4574;
|
||||
--color-on-accent: #ffffff;
|
||||
--color-link: #2b5c94;
|
||||
--color-link-hover: #1d4574;
|
||||
--color-border: #d6d1c4;
|
||||
--color-shadow: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text-primary);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: var(--font-ui);
|
||||
line-height: 1.6;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--color-link-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-accent-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* ---- Site header: brand, links, search (scrolls away with the page) ---- */
|
||||
.site-header {
|
||||
background: var(--color-bg-secondary);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
padding: var(--space-sm) max(var(--space-md), env(safe-area-inset-right)) var(--space-sm) max(var(--space-md), env(safe-area-inset-left));
|
||||
}
|
||||
|
||||
.site-bar,
|
||||
.search-form,
|
||||
.shortcode {
|
||||
max-width: var(--content-max-width);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.site-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-xs) var(--space-md);
|
||||
}
|
||||
|
||||
.brand {
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
color: var(--color-text-primary);
|
||||
padding: var(--space-sm) 0;
|
||||
}
|
||||
|
||||
.brand:hover {
|
||||
color: var(--color-accent-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.site-links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0 var(--space-xs);
|
||||
}
|
||||
|
||||
.site-links a {
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 999px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.site-links a:hover {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
gap: var(--space-sm);
|
||||
margin-top: var(--space-xs);
|
||||
}
|
||||
|
||||
.shortcode {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
margin-top: var(--space-sm);
|
||||
font-size: 0.9rem;
|
||||
min-height: 1.5rem;
|
||||
}
|
||||
|
||||
/* ---- Chapter bar: sticks to the top while scrolling a chapter ---- */
|
||||
.chapter-nav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-sm);
|
||||
padding: 0 max(var(--space-md), env(safe-area-inset-right)) 0 max(var(--space-md), env(safe-area-inset-left));
|
||||
background: var(--color-bg-tertiary);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
box-shadow: 0 2px 8px var(--color-shadow);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.chapter-nav > * {
|
||||
min-height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.chapter-nav a {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.chapter-nav a .nav-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.chapter-nav a span[aria-hidden] {
|
||||
font-size: 1.6rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.chapter-prev {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.chapter-next {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.chapter-nav .chapter-current {
|
||||
flex: 0 1 auto;
|
||||
justify-content: center;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-primary);
|
||||
text-align: center;
|
||||
padding: 0 var(--space-sm);
|
||||
text-decoration: underline;
|
||||
text-decoration-color: var(--color-border);
|
||||
text-underline-offset: 4px;
|
||||
}
|
||||
|
||||
.chapter-nav .chapter-current:hover {
|
||||
color: var(--color-accent-primary);
|
||||
text-decoration-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
/* ---- Content column ---- */
|
||||
.responses {
|
||||
font-family: var(--font-scripture);
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.8;
|
||||
max-width: calc(var(--content-max-width) + 2 * var(--space-md));
|
||||
margin: 0 auto;
|
||||
padding: var(--space-lg) max(var(--space-md), env(safe-area-inset-right)) var(--space-2xl) max(var(--space-md), env(safe-area-inset-left));
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
/* Correction & Variant Notices */
|
||||
.correction-notice,
|
||||
.variant-notice,
|
||||
.theological-notice {
|
||||
font-family: var(--font-ui);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
margin-bottom: var(--space-lg);
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border-left: 4px solid var(--color-accent-primary);
|
||||
border-radius: var(--border-radius-sm);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.correction-notice strong,
|
||||
.variant-notice strong,
|
||||
.theological-notice strong {
|
||||
color: var(--color-accent-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.theological-notice em {
|
||||
display: block;
|
||||
margin-top: var(--space-sm);
|
||||
color: var(--color-text-muted);
|
||||
font-style: italic;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Results Count */
|
||||
.results-count {
|
||||
font-family: var(--font-ui);
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-text-muted);
|
||||
margin-bottom: var(--space-md);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Theological Suggestions Section */
|
||||
.theological-suggestions {
|
||||
margin-top: var(--space-2xl);
|
||||
padding: var(--space-lg);
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--color-border);
|
||||
font-family: var(--font-ui);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.theological-suggestions h3 {
|
||||
font-size: 1.25rem;
|
||||
color: var(--color-text-primary);
|
||||
margin: 0 0 var(--space-md) 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.theological-suggestions p {
|
||||
color: var(--color-text-secondary);
|
||||
margin: 0 0 var(--space-md) 0;
|
||||
}
|
||||
|
||||
.suggestion-item {
|
||||
font-family: var(--font-ui);
|
||||
font-size: 1rem;
|
||||
/* whole row is tappable height */
|
||||
padding: var(--space-sm) 0;
|
||||
min-height: 44px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.suggestion-item a {
|
||||
color: var(--color-accent-primary);
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
.suggestion-item a:hover {
|
||||
color: var(--color-accent-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.suggestion-item strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.suggestion-item em {
|
||||
font-style: italic;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
/* Dictionary Section */
|
||||
.dictionary-section {
|
||||
margin: var(--space-2xl) 0 var(--space-sm) 0;
|
||||
font-family: var(--font-ui);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.dictionary-section h3 {
|
||||
font-size: 1.5rem;
|
||||
color: var(--color-text-primary);
|
||||
margin: 0 0 var(--space-xs) 0;
|
||||
}
|
||||
|
||||
.dictionary-section p {
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Form Inputs */
|
||||
input[type=text] {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 44px;
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: 1rem; /* 16px minimum stops iOS zooming into the field */
|
||||
font-family: var(--font-ui);
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text-primary);
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
|
||||
}
|
||||
|
||||
input[type=text]:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-accent-primary);
|
||||
box-shadow: 0 0 0 3px rgba(107, 155, 209, 0.25);
|
||||
}
|
||||
|
||||
input[type=text]::placeholder {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
input[type=button],
|
||||
input[type=submit],
|
||||
input[type=reset],
|
||||
button {
|
||||
font-family: var(--font-ui);
|
||||
font-weight: 600;
|
||||
background-color: var(--color-accent-primary);
|
||||
border: none;
|
||||
color: var(--color-on-accent);
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
min-height: 44px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius-sm);
|
||||
transition: background-color var(--transition-fast);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
input[type=button]:hover,
|
||||
input[type=submit]:hover,
|
||||
input[type=reset]:hover,
|
||||
button:hover {
|
||||
background-color: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
.btn-small {
|
||||
min-height: 36px;
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
font-size: 0.85rem;
|
||||
background-color: var(--color-bg-tertiary);
|
||||
color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.btn-small:hover {
|
||||
background-color: var(--color-bg-primary);
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
/* Definition Styling (collapsed until its word is tapped) */
|
||||
.definition {
|
||||
display: none;
|
||||
padding: var(--space-lg);
|
||||
font-family: var(--font-scripture);
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.7;
|
||||
max-width: var(--content-max-width);
|
||||
margin: 0 auto var(--space-sm);
|
||||
color: var(--color-text-secondary);
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-left: 4px solid var(--color-accent-primary);
|
||||
border-radius: 0 var(--border-radius-sm) var(--border-radius-sm) 0;
|
||||
}
|
||||
|
||||
/* Verse cards */
|
||||
.verse-container {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-left: 3px solid var(--color-accent-primary);
|
||||
border-radius: var(--border-radius-sm);
|
||||
padding: var(--space-sm) var(--space-md) var(--space-md);
|
||||
margin: var(--space-sm) 0;
|
||||
transition: background-color var(--transition-fast), border-color var(--transition-fast);
|
||||
}
|
||||
|
||||
.verse-container:hover {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border-left-color: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
.verse-reference {
|
||||
font-family: var(--font-ui);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.verse-reference a {
|
||||
color: var(--color-accent-primary);
|
||||
/* a roomier hit area than the 0.8rem text alone */
|
||||
display: inline-block;
|
||||
padding: var(--space-xs) 0;
|
||||
}
|
||||
|
||||
.verse-reference a:hover {
|
||||
color: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
.verse-text {
|
||||
font-family: var(--font-scripture);
|
||||
font-size: 1.15rem;
|
||||
line-height: 1.7;
|
||||
color: var(--color-text-primary);
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ---- Verse menu (tap a verse) ---- */
|
||||
.verse-container {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.verse-container.selected {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border-left-color: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
.verse-container.is-fav .verse-reference::after {
|
||||
content: " \2605";
|
||||
color: #d9a93b;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.verse-menu {
|
||||
margin-top: var(--space-sm);
|
||||
padding-top: var(--space-sm);
|
||||
border-top: 1px solid var(--color-border);
|
||||
font-family: var(--font-ui);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.vm-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.vm-btn,
|
||||
.vm-chip,
|
||||
.vm-save {
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-border);
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.vm-btn:hover,
|
||||
.vm-chip:hover,
|
||||
.vm-save:hover {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.vm-btn.saved,
|
||||
.vm-save.saved {
|
||||
background-color: var(--color-accent-primary);
|
||||
border-color: var(--color-accent-primary);
|
||||
color: var(--color-on-accent);
|
||||
}
|
||||
|
||||
.vm-close {
|
||||
margin-left: auto;
|
||||
min-width: 40px;
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
font-size: 1.2rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.vm-panel {
|
||||
margin-top: var(--space-sm);
|
||||
max-height: 22rem;
|
||||
overflow-y: auto;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.vm-hint {
|
||||
font-size: 0.85rem;
|
||||
color: var(--color-text-muted);
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
|
||||
.vm-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-xs) var(--space-sm);
|
||||
}
|
||||
|
||||
.vm-chip {
|
||||
min-height: 36px;
|
||||
border-radius: 999px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.vm-detail {
|
||||
margin-top: var(--space-sm);
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
background-color: var(--color-bg-primary);
|
||||
border-left: 3px solid var(--color-accent-primary);
|
||||
border-radius: var(--border-radius-sm);
|
||||
font-family: var(--font-scripture);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.vm-detail p {
|
||||
margin: var(--space-xs) 0 var(--space-sm);
|
||||
}
|
||||
|
||||
.vm-xref {
|
||||
padding: var(--space-sm) 0;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.vm-xref:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.vm-xref > a {
|
||||
font-weight: 700;
|
||||
display: inline-block;
|
||||
padding: var(--space-xs) 0;
|
||||
}
|
||||
|
||||
.vm-xref-text {
|
||||
font-family: var(--font-scripture);
|
||||
font-size: 1rem;
|
||||
color: var(--color-text-primary);
|
||||
margin-bottom: var(--space-xs);
|
||||
}
|
||||
|
||||
.vm-save {
|
||||
min-height: 36px;
|
||||
margin-top: var(--space-xs);
|
||||
}
|
||||
|
||||
/* Always-visible entry point to the verse menu, hint line, and notes */
|
||||
.vm-more {
|
||||
flex: 0 0 auto;
|
||||
min-height: 40px;
|
||||
min-width: 40px;
|
||||
margin: -6px -8px -6px 0;
|
||||
padding: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 1.4rem;
|
||||
line-height: 1;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.vm-more:hover,
|
||||
.verse-container.selected .vm-more {
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.verse-hint {
|
||||
font-family: var(--font-ui);
|
||||
font-size: 0.85rem;
|
||||
color: var(--color-text-muted);
|
||||
margin: calc(-1 * var(--space-xs)) 0 var(--space-md);
|
||||
}
|
||||
|
||||
.verse-note {
|
||||
margin-top: var(--space-sm);
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
font-family: var(--font-ui);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
color: var(--color-text-secondary);
|
||||
background-color: var(--color-bg-primary);
|
||||
border-left: 3px solid #d9a93b;
|
||||
border-radius: var(--border-radius-sm);
|
||||
}
|
||||
|
||||
.verse-note::before {
|
||||
content: "\270e ";
|
||||
color: #d9a93b;
|
||||
}
|
||||
|
||||
.vm-note-input {
|
||||
width: 100%;
|
||||
min-height: 6rem;
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-family: var(--font-ui);
|
||||
font-size: 1rem; /* 16px minimum stops iOS zooming into the field */
|
||||
line-height: 1.5;
|
||||
color: var(--color-text-primary);
|
||||
background-color: var(--color-bg-primary);
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.vm-note-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
/* ---- Reading plan ---- */
|
||||
.plan-summary {
|
||||
font-family: var(--font-ui);
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
margin-bottom: var(--space-md);
|
||||
background-color: var(--color-bg-tertiary);
|
||||
border-left: 4px solid var(--color-accent-primary);
|
||||
border-radius: var(--border-radius-sm);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.plan-range {
|
||||
font-size: 1.35rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.plan-meta {
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.plan-progress {
|
||||
height: 6px;
|
||||
margin-top: var(--space-sm);
|
||||
background-color: var(--color-border);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.plan-progress span {
|
||||
display: block;
|
||||
height: 100%;
|
||||
min-width: 2px;
|
||||
background-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.plan-controls {
|
||||
font-family: var(--font-ui);
|
||||
margin-top: var(--space-lg);
|
||||
padding: var(--space-lg);
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.plan-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.plan-form + .plan-form {
|
||||
margin-top: var(--space-lg);
|
||||
padding-top: var(--space-md);
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.plan-form label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.plan-primary,
|
||||
.plan-secondary {
|
||||
min-height: 48px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.plan-primary {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.plan-secondary {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.plan-secondary:hover:not(:disabled) {
|
||||
background-color: var(--color-bg-primary);
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.plan-secondary:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.plan-goto-row {
|
||||
display: flex;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.plan-goto-row .plan-secondary {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.plan-note {
|
||||
font-family: var(--font-ui);
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-text-muted);
|
||||
margin-top: var(--space-md);
|
||||
}
|
||||
|
||||
/* ---- Wide screens: more air around the reading column ---- */
|
||||
@media (min-width: 900px) {
|
||||
.site-header {
|
||||
padding-top: var(--space-md);
|
||||
padding-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
.responses {
|
||||
font-size: 1.2rem;
|
||||
padding-top: var(--space-xl);
|
||||
}
|
||||
|
||||
.verse-container {
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
}
|
||||
|
||||
.verse-text {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Phones ---- */
|
||||
@media (max-width: 600px) {
|
||||
.responses {
|
||||
font-size: 1.05rem;
|
||||
padding-top: var(--space-md);
|
||||
}
|
||||
|
||||
.verse-text {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.verse-container {
|
||||
margin: 0.4rem 0;
|
||||
padding: var(--space-xs) var(--space-md) var(--space-sm);
|
||||
}
|
||||
|
||||
.site-links a {
|
||||
padding: 0.5rem 0.6rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.correction-notice,
|
||||
.variant-notice,
|
||||
.theological-notice,
|
||||
.theological-suggestions {
|
||||
padding: var(--space-md);
|
||||
}
|
||||
|
||||
/* the chapter names drop out, leaving big arrow targets either side of the current chapter */
|
||||
.chapter-nav a .nav-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chapter-nav a span[aria-hidden] {
|
||||
font-size: 2rem;
|
||||
padding: 0 var(--space-md);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 380px) {
|
||||
.site-links a {
|
||||
padding: 0.5rem 0.4rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.search-form input[type=submit] {
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
* {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,65 @@
|
||||
<style>
|
||||
/* Dark Theme */
|
||||
|
||||
body {
|
||||
background-color: #222;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Style the header */
|
||||
.responses {
|
||||
font-family: sans-serif;
|
||||
font-size: 14.5pt;
|
||||
width: 768px;
|
||||
padding: 1px;
|
||||
margin-top: 100px;
|
||||
color: #fff; /* Text color */
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff; /* Link color */
|
||||
}
|
||||
|
||||
.header {
|
||||
font-family: sans-serif;
|
||||
padding: 10px 16px;
|
||||
background: #333; /* Dark background */
|
||||
color: #fff; /* Text color */
|
||||
position: fixed;
|
||||
top: 5px;
|
||||
width: 768px;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 75%;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
box-sizing: border-box;
|
||||
text-align: left;
|
||||
font-size: 14.5pt;
|
||||
background-color: #333; /* Dark background */
|
||||
color: #fff; /* Text color */
|
||||
border: 1px solid #555; /* Border color */
|
||||
}
|
||||
|
||||
input[type=button], input[type=submit], input[type=reset] {
|
||||
font-family: sans-serif;
|
||||
background-color: #555; /* Dark button background */
|
||||
border: none;
|
||||
color: #fff; /* Button text color */
|
||||
padding: 16px 32px;
|
||||
text-decoration: none;
|
||||
margin: 4px 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.definition {
|
||||
padding: 8px;
|
||||
font-family: sans-serif;
|
||||
font-size: 14.5pt;
|
||||
width: 768px;
|
||||
padding: 1px;
|
||||
color: #fff; /* Text color */
|
||||
background-color: #222; /* Dark background */
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,55 @@
|
||||
<style>
|
||||
/* Style the header */
|
||||
|
||||
.responses{
|
||||
font-family: sans-serif;
|
||||
font-size: 14.5pt;
|
||||
width: 768px;
|
||||
padding: 1px;
|
||||
margin-top: 100px;
|
||||
}
|
||||
a {
|
||||
color: #547720
|
||||
}
|
||||
|
||||
|
||||
|
||||
.header {
|
||||
font-family: sans-serif;
|
||||
padding: 10px 16px;
|
||||
background: #dbd5d5;
|
||||
color: #1a1919;
|
||||
position: fixed;
|
||||
top: 5px;
|
||||
width: 768px;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 75%;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
box-sizing: border-box;
|
||||
text-align: left;
|
||||
font-size: 14.5pt;
|
||||
}
|
||||
|
||||
input[type=button], input[type=submit], input[type=reset] {
|
||||
font-family: sans-serif;
|
||||
background-color: #afcdc2;
|
||||
border: none;
|
||||
color: rgb(0, 0, 0);
|
||||
padding: 16px 32px;
|
||||
text-decoration: none;
|
||||
margin: 4px 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Page content */
|
||||
.definition {
|
||||
padding: 8px;
|
||||
font-family: sans-serif;
|
||||
font-size: 14.5pt;
|
||||
width: 768px;
|
||||
padding: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,66 @@
|
||||
<style>
|
||||
/* Modern KJV API Styling - Human Readable */
|
||||
|
||||
:root {
|
||||
/* Color Palette */
|
||||
--color-bg-primary: #1a1a1a;
|
||||
--color-bg-secondary: #252525;
|
||||
--color-bg-tertiary: #2f2f2f;
|
||||
--color-text-primary: #e8e8e8;
|
||||
--color-text-secondary: #b8b8b8;
|
||||
--color-text-muted: #888888;
|
||||
--color-accent-primary: #6b9bd1;
|
||||
--color-accent-hover: #85aede;
|
||||
--color-link: #6b9bd1;
|
||||
--color-link-hover: #85aede;
|
||||
--color-border: #3a3a3a;
|
||||
--color-shadow: rgba(0, 0, 0, 0.3);
|
||||
|
||||
/* Typography */
|
||||
--font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
--font-scripture: Georgia, "Crimson Text", "Times New Roman", serif;
|
||||
--font-mono: "SF Mono", Monaco, "Cascadia Code", "Courier New", monospace;
|
||||
|
||||
/* Spacing */
|
||||
--space-xs: 0.25rem;
|
||||
--space-sm: 0.5rem;
|
||||
--space-md: 1rem;
|
||||
--space-lg: 1.5rem;
|
||||
--space-xl: 2rem;
|
||||
--space-2xl: 3rem;
|
||||
|
||||
/* Layout */
|
||||
--content-max-width: 820px;
|
||||
--border-radius: 8px;
|
||||
--border-radius-sm: 4px;
|
||||
|
||||
/* Transitions */
|
||||
--transition-fast: 150ms ease;
|
||||
--transition-normal: 250ms ease;
|
||||
}
|
||||
|
||||
.testhtml {
|
||||
font-family: var(--font-scripture);
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.75;
|
||||
max-width: var(--content-max-width);
|
||||
margin: 0 auto;
|
||||
padding: var(--space-md);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--color-link-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: var(--color-accent-primary);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,273 @@
|
||||
/* Shared Page Styling for Simple Pages (index, forms, static articles) */
|
||||
|
||||
:root {
|
||||
color-scheme: dark light;
|
||||
|
||||
--color-bg-primary: #1a1a1a;
|
||||
--color-bg-secondary: #252525;
|
||||
--color-bg-tertiary: #2f2f2f;
|
||||
--color-text-primary: #e8e8e8;
|
||||
--color-text-secondary: #b8b8b8;
|
||||
--color-text-muted: #888888;
|
||||
--color-accent-primary: #6b9bd1;
|
||||
--color-accent-hover: #85aede;
|
||||
--color-on-accent: #121212;
|
||||
--color-link: #6b9bd1;
|
||||
--color-link-hover: #85aede;
|
||||
--color-border: #3a3a3a;
|
||||
--color-shadow: rgba(0, 0, 0, 0.3);
|
||||
|
||||
--font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
--font-scripture: Georgia, "Crimson Text", "Times New Roman", serif;
|
||||
--font-mono: "SF Mono", Monaco, "Cascadia Code", "Courier New", monospace;
|
||||
|
||||
--space-xs: 0.25rem;
|
||||
--space-sm: 0.5rem;
|
||||
--space-md: 1rem;
|
||||
--space-lg: 1.5rem;
|
||||
--space-xl: 2rem;
|
||||
--space-2xl: 3rem;
|
||||
|
||||
--content-max-width: 820px;
|
||||
--border-radius: 8px;
|
||||
--border-radius-sm: 4px;
|
||||
--transition-fast: 150ms ease;
|
||||
--transition-normal: 250ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--color-bg-primary: #f7f5f0;
|
||||
--color-bg-secondary: #ffffff;
|
||||
--color-bg-tertiary: #ece9e1;
|
||||
--color-text-primary: #1f1f1f;
|
||||
--color-text-secondary: #4a4a4a;
|
||||
--color-text-muted: #6b6b6b;
|
||||
--color-accent-primary: #2b5c94;
|
||||
--color-accent-hover: #1d4574;
|
||||
--color-on-accent: #ffffff;
|
||||
--color-link: #2b5c94;
|
||||
--color-link-hover: #1d4574;
|
||||
--color-border: #d6d1c4;
|
||||
--color-shadow: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text-primary);
|
||||
margin: 0 auto;
|
||||
padding: var(--space-md) max(var(--space-md), env(safe-area-inset-right)) var(--space-2xl) max(var(--space-md), env(safe-area-inset-left));
|
||||
max-width: calc(var(--content-max-width) + 2 * var(--space-md));
|
||||
font-family: var(--font-ui);
|
||||
line-height: 1.6;
|
||||
font-size: 16px;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
color: var(--color-text-primary);
|
||||
line-height: 1.25;
|
||||
margin: 1.5rem 0 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(1.6rem, 5vw + 0.5rem, 2.4rem);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(1.4rem, 4vw + 0.4rem, 2rem);
|
||||
border-bottom: 2px solid var(--color-border);
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-link);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition-fast);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--color-link-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-accent-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Top navigation: a wrapping row of pill links */
|
||||
header {
|
||||
margin-left: -0.75rem; /* pill padding lines the text up with the page edge */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-xs) var(--space-sm);
|
||||
margin-bottom: var(--space-lg);
|
||||
padding-bottom: var(--space-md);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
header a {
|
||||
padding: 0.35rem 0.75rem;
|
||||
border-radius: 999px;
|
||||
font-weight: 500;
|
||||
font-size: 0.95rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
header a:hover {
|
||||
background-color: var(--color-bg-tertiary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
form {
|
||||
background-color: var(--color-bg-secondary);
|
||||
padding: var(--space-lg);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--color-border);
|
||||
margin: var(--space-lg) 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 100%;
|
||||
min-height: 44px;
|
||||
padding: 0.6rem 0.75rem;
|
||||
margin: 0.5rem 0 1rem 0;
|
||||
font-size: 1rem; /* 16px minimum stops iOS zooming into the field */
|
||||
font-family: var(--font-ui);
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text-primary);
|
||||
border: 2px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
transition: border-color var(--transition-fast);
|
||||
}
|
||||
|
||||
input[type=text]:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
/* Radio + text wrapped in a label so the whole pill is the tap target */
|
||||
.choice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
min-height: 44px;
|
||||
margin: 0 var(--space-md) 0 0;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type=radio] {
|
||||
margin: 0;
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
accent-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.form-row {
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
input[type=submit], button {
|
||||
background-color: var(--color-accent-primary);
|
||||
color: var(--color-on-accent);
|
||||
border: none;
|
||||
min-height: 44px;
|
||||
padding: 0.6rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
font-family: var(--font-ui);
|
||||
border-radius: var(--border-radius-sm);
|
||||
cursor: pointer;
|
||||
transition: background-color var(--transition-fast), transform var(--transition-fast);
|
||||
}
|
||||
|
||||
input[type=submit]:hover, button:hover {
|
||||
background-color: var(--color-accent-hover);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid var(--color-border);
|
||||
margin: var(--space-xl) 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1rem 0;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
b, strong {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
padding: var(--space-md);
|
||||
overflow-x: auto; /* scroll the code block, never the page */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.5;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
/* wide tables scroll inside their own box instead of widening the page */
|
||||
.table-wrap {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
text-align: left;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
form {
|
||||
padding: var(--space-md);
|
||||
}
|
||||
|
||||
/* full-width submit buttons are easier to hit with a thumb */
|
||||
input[type=submit] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
* {
|
||||
text-align: left;
|
||||
background-color: rgb(35, 35, 36);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Arizona-Regular;
|
||||
src: url(./fonts/Arizonia-Regular.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Parisienne;
|
||||
src: url(./fonts/Parisienne-Regular.ttf);
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: aqua;
|
||||
font-size: 50px;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
font-family: Parisienne;
|
||||
}
|
||||
|
||||
p {
|
||||
color: bisque;
|
||||
margin-top: 20px;
|
||||
font-size: 20px;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
* {
|
||||
text-align: center;
|
||||
background-color: rgb(35, 35, 36);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Arizona-Regular;
|
||||
src: url(./fonts/Arizonia-Regular.ttf);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Parisienne;
|
||||
src: url(./fonts/Parisienne-Regular.ttf);
|
||||
}
|
||||
|
||||
.verse-title {
|
||||
background-color: aqua;
|
||||
font-size: 50px;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
font-family: Parisienne;
|
||||
}
|
||||
|
||||
.verse-text {
|
||||
color: bisque;
|
||||
margin-top: 20px;
|
||||
font-size: 20px;
|
||||
}
|
||||
Reference in new issue
Block a user